Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Cette catégorie traite de développements récents destinés à nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
rendomizer
Messages : 434
Inscription : 17 juin 2016 21:00
Contact :

Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par rendomizer »

J'essaie désespérément de calculer la position d'un point dans une matrice de 8x10 dans un repère x 128, y 150 pixels en assembleur z80... Voici mon code en basic et la "même chose" en assembleur. Merci pour toutes aides.

Code : Tout sélectionner

x = 65
y = 32
tase = 21000
ra = 150 * INT(y / 10) + y
ba = 10 * INT(x / 8)
ma = 2 ^ (7 - (x AND 7))
ad = tase + ra + ba
POKE ad, PEEK(ad) OR ma

780 asm

Code : Tout sélectionner

    ORG 5000h           ; Set the start address of the program

START:
    ; Initialize values
    LD A, 65            ; x = 65
    LD (x), A           ; Store x
    LD A, 32            ; y = 32
    LD (y), A           ; Store y
    LD HL, 21000        ; tase = 21000
    LD (tase), HL       ; Store tase

    ; Calculate ra = 150 * (y / 10) + y
    LD A, (y)           ; Load y into A
    LD B, 10            ; Set divisor to 10
    CALL DIVIDE         ; A = y / 10
    LD B, A             ; Save result in B (y / 10)

    LD A, 150           ; Load 150 into A
    CALL MULTIPLY       ; Multiply 150 * (y / 10)
    LD L, A             ; Store result in L (150 * (y / 10))

    LD A, (y)           ; Load y into A
    ADD A, L            ; ra = 150 * (y / 10) + y
    LD (ra), A          ; Store ra

    ; Calculate ba = 10 * (x / 8)
    LD A, (x)           ; Load x into A
    LD B, 8             ; Set divisor to 8
    CALL DIVIDE         ; A = x / 8
    LD B, A             ; Save result in B (x / 8)

    LD A, 10            ; Load 10 into A
    CALL MULTIPLY       ; Multiply 10 * (x / 8)
    LD (ba), A          ; Store ba

    ; Calculate ma = 2 ^ (7 - (x AND 7))
    LD A, (x)           ; Load x into A
    AND 7               ; x AND 7
    LD B, 7
    SUB B               ; A = 7 - (x AND 7)
    LD B, A             ; Save result in B
    LD A, 1
    CALL POWER_OF_TWO    ; A = 2 ^ B
    LD (ma), A          ; Store ma

    ; Calculate ad = tase + ra + ba
    LD HL, (tase)       ; Load tase into HL
    LD A, (ra)          ; Load ra into A
    CALL ADD_TO_HL      ; HL = HL + ra
    LD A, (ba)          ; Load ba into A
    CALL ADD_TO_HL      ; HL = HL + ba
    LD (ad), HL         ; Store ad

    ; POKE ad, PEEK(ad) OR ma
    LD HL, (ad)         ; Load address (ad)
    LD A, (HL)          ; PEEK(ad)
    LD HL, ma           ; Load address of ma into HL
    LD B, (HL)          ; Load ma into B
    OR B                ; A = A OR B
    LD (HL), A          ; POKE(ad)

    HALT                ; End of the program

; Subroutine to divide A by B
DIVIDE:
    XOR D               ; Clear D
DIV_LOOP:
    SUB B               ; Subtract B from A
    JR C, DIV_END       ; If A < B, we're done
    INC D               ; Increment result
    JR DIV_LOOP
DIV_END:
    ADD A, B            ; Restore A to its value before the last subtraction
    LD A, D             ; Return quotient in A
    RET

; Subroutine to multiply A by B
MULTIPLY:
    LD C, A             ; Save A in C
    LD A, 0             ; Clear A
MULT_LOOP:
    ADD A, C            ; Add C to A
    DEC B               ; Decrement B
    JR NZ, MULT_LOOP    ; If B != 0, continue multiplying
    RET

; Subroutine to calculate 2 ^ B
POWER_OF_TWO:
    LD A, 1             ; Start with 2^0 = 1
POW_LOOP:
    DEC B               ; Decrement B
    JR Z, POW_END       ; If B = 0, we're done
    ADD A, A            ; Double A (shift left)
    JR POW_LOOP         ; Repeat until B = 0
POW_END:
    RET

; Subroutine to add 8-bit A to 16-bit HL
ADD_TO_HL:
    ADD A, L            ; Add A to L
    LD L, A             ; Store result in L
    JR NC, NO_CARRY     ; If no carry, skip next instruction
    INC H               ; Increment H if carry
NO_CARRY:
    RET

; Variables
x:
dw 0
y:
dw 0
ra:
dw 0
ba:
dw 0
ma:
dw 0
ad:
dw 0


Je ne suis qu'un utilisateur pas un pro
Avatar de l’utilisateur
Mokona
Messages : 1091
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par Mokona »

Sans trop aller dans le détail, on peut voir qu'il y aura un soucis au premier appel à MULTIPLY.

C'est en effet une multiplication en 8 bits, et les entrées sont 150 et 3. Le résultat ne sera pas 450 comme attendu, mais 194 (450 mod 256).

Il te faut faire la multiplication sur 16 bits. Tu dois pouvoir garder tes deux entrées sur 8 bits, mais l'accumulateur dans MULTIPLY doit être sur 16 bits.
Avatar de l’utilisateur
hlide
Messages : 3785
Inscription : 29 nov. 2017 10:23
Localisation : Yvelines

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par hlide »

Bon allez je me lance mais pas testé...

Code : Tout sélectionner

start:
	; y = 32, x = 64
	LD HL,32 + 64 * 256

; H = x, L = y
draw_dot:
	PUSH HL

	; ba = 10 * INT(x / 8)
	LD A,H
	AND A,248 ; ba = 8 * INT(x / 8)
	LD C,A ; ba' = ba
	RRCA ; ba = 4 * INT(x / 8)
	RRCA ; ba = 2 * INT(x / 8)
	ADD A,C ; ba = ba + ba' = 10 * INT(x / 8)
	LD (ba),A

	; ra = 150 * INT(y / 10) + y 
	LD A,L
	LD H,0 ; ra' = HL = y
	LD B,H ; BC = y
	LD C,L
	ADD HL,HL ; HL = ra' * 2 
	ADD HL,HL ; HL = ra' * 4
	ADD HL,HL ; HL = ra' * 8
	LD D,H
	LD E,L
	ADD HL,HL ; HL = ra' * 16
	ADD HL,DE ; HL = ra' * 24
	ADD HL,BC ; HL = ra' * 25
	ADD HL,HL ; HL = ra' * 50 
	ADD HL,BC ; HL = ra' * 51
	LD A,H
	RRA
	ADC A,B ; A = HL * 51 / 512 = INT(y / 10)
	LD L,A	; ra' = HL = INT(y / 10)
	LD H,0
	ADD HL,HL ; HL = ra' * 2 
	LD D,H
	LD E,L
	ADD HL,HL ; HL = ra' * 4 
	ADD HL,HL ; HL = ra' * 8 
	EX DE,HL
	ADD HL,DE ; DE = ra' * 10 
	ADD HL,BC ; DE = ra' * 11 
	EX DE,HL
	ADD HL,HL ; HL = ra' * 16 
	ADD HL,HL ; HL = ra' * 32 
	ADD HL,HL ; HL = ra' * 64 
	ADD HL,DE ; HL = ra' * 75 
	ADD HL,HL ; HL = ra' * 150 
	ADD HL,BC ; ra = 150 * INT(y / 10) + y

	; ad = tase + ra + ba
	LD DE,21000 ; tase
	ADD HL,DE
	LD DE,0
ba EQU $-2
	ADD HL,DE

	; ma = 2 ^ (7 - (x AND 7))
	POP BC
	LD A,B
	AND 7
	NEG
	ADD 7
	LD B,A
	LD A,1
power2_loop:
	JR Z,power2_exist
	ADD A,A
	DJNZ power2_loop
power2_exist:

	; POKE ad, PEEK(ad) OR ma
ma EQU $-1
	OR (HL) ; ad

	HALT
Avatar de l’utilisateur
rendomizer
Messages : 434
Inscription : 17 juin 2016 21:00
Contact :

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par rendomizer »

Hilde,( ma EQU $-1 ) n'est pas utilisé dans ce code !
Dernière modification par rendomizer le 09 sept. 2024 00:38, modifié 1 fois.
Je ne suis qu'un utilisateur pas un pro
Avatar de l’utilisateur
rendomizer
Messages : 434
Inscription : 17 juin 2016 21:00
Contact :

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par rendomizer »

sur gemini google code AI j'ai obtenu ceci mais ça ne marche pas les points s'affichent un peu partout:
Gemini new answer algo+full screen bitmap 128x160 .zip
mon bitmap 128x160 format mrx
(16.31 Kio) Téléchargé 4 fois
[/color]

Code : Tout sélectionner


algo:
push hl
push de
push bc
LD HL, 20000 ; HL pointe vers l'adresse de base
LD DE, 10 ; DE contient 10 pour les divisions par 10
LD BC, 8 ; BC contient 8 pour les divisions par 8

; Calcul de ra
LD A, (y)
SRL A ; A = y / 2
SRL A ; A = y / 4
SRL A ; A = y / 8
LD B, A ; B contient la partie entière de y / 10
LD A, (y)
AND 7 ; A = y modulo 10
ADD A, B
LD B, A ; B contient ra
ADD HL, BC ; HL pointe vers tase + ra

; Calcul de ba
LD A, (x)
SRL A ; A = x / 2
SRL A ; A = x / 4
LD B, A ; B contient la partie entière de x / 8
LD A, 10
ADD A, B
LD C, A ; C contient ba
ADD HL, BC ; HL pointe vers tase + ra + ba

; Calcul de ma
LD A, (x)
AND 7 ; A = x modulo 8
LD B, 7
SUB A ; B = 7 - (x modulo 8)
LD A, 1 ; A = 2^0
ADD A, A ; A = 2^1
ADD A, A ; A = 2^2
ADD A, A ; A = 2^3
ADD A, A ; A = 2^4
ADD A, A ; A = 2^5
ADD A, A ; A = 2^6
RRCA ; A = 2^(7 - (x modulo 8))
LD E, A ; E contient ma

; Lecture et écriture en mémoire
LD A, (HL) ; A contient la valeur à l'adresse HL
OR E ; A = A OR ma
LD (HL), A ; Écriture de la nouvelle valeur

pop bc
pop de
pop hl
ret
x:
db 10
y:
db 11
Dernière modification par rendomizer le 09 sept. 2024 01:09, modifié 1 fois.
Je ne suis qu'un utilisateur pas un pro
__sam__
Messages : 8274
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par __sam__ »

Je ne le répèterais jammais assez: les IA ne savent pas ce qu'elles font. Elles ne savent pas programmer au bas niveau car ca nécessite une connaissance exacte de ce qu'on veut faire.

Le code est archi-faux: comment passe-t-on de A = y/8 à B = "partrie entière de y/10" par un simple transfert de registre ? C'est de la pensée magique. Ca ne marche pas comme ca, et ca n'est pas en l'affirmant en commentaire que cela fera cette opération. Elle ne comprends pas non plus l'arithmétique binaire quand le et bit à bit avec 7 se commente par "modulo 10". Quant au calcul de "2^(7-(x mod 8 ))" en doublant "7-(x mod 8 )" plusieurs fois, c'est ridicule. Tout cela est très très mauvais.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
rendomizer
Messages : 434
Inscription : 17 juin 2016 21:00
Contact :

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par rendomizer »

en plus gemini affirmait que ld b,(de) existait en z80 lol. il est pretencieux en plus ! :shock:

bon j'en suis toujours au point mort
Je ne suis qu'un utilisateur pas un pro
Ythunder
Messages : 1040
Inscription : 21 août 2019 10:12

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par Ythunder »

Simple : comment une IA peut-elle connaitre la différence entre l'adressage mémoire d'un TO7 et d'un MO6 ?
Réponse, sans même réfléchir : elle ne peut pas.
Problème : elle donnera quand même un listing qu'elle a généré.

D'ailleurs du coup ou voit un des paramètres manquant à l'IA : quand c'est absurde et impossible pour toi, décrit le, mais surtout, ne le fait pas...
Avatar de l’utilisateur
hlide
Messages : 3785
Inscription : 29 nov. 2017 10:23
Localisation : Yvelines

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par hlide »

rendomizer a écrit : 08 sept. 2024 21:06 Hilde,( ma EQU $-1 ) n'est pas utilisé dans ce code !
En effet, je me suis aperçu que j'avais "ma" déjà dans le registre A, donc cette ligne est à effacer (juste oublié de le faire). Après, ce code, je l'ai fait de tête et n'est pas exempte d'un raté (notamment sur la partie "ra = 150 * INT(y / 10) + y " qui est un poil plus chiant à coder).
Avatar de l’utilisateur
hlide
Messages : 3785
Inscription : 29 nov. 2017 10:23
Localisation : Yvelines

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par hlide »

Concernant ton code Z80 initial, il y a des soucis de taille de registre :

Code : Tout sélectionner

    ; Calculate ra = 150 * (y / 10) + y
    LD A, (y)           ; Load y into A
    LD B, 10            ; Set divisor to 10
    CALL DIVIDE         ; A = y / 10
    LD B, A             ; Save result in B (y / 10)
Je présume que DIVIDE est correct, alors B devrait être aussi correct en étant bien égale à INT(y/10).

Code : Tout sélectionner

    LD A, 150           ; Load 150 into A
    CALL MULTIPLY       ; Multiply 150 * (y / 10)
    LD L, A             ; Store result in L (150 * (y / 10))
Il faut que ce soit une multiplication 16-bit genre :

Code : Tout sélectionner

	LD HL,0
	LD D,H
	LD E,A
    MUL_LOOP:
	ADD HL,DE 
	DJNZ MUL_LOOP  ; Attention, B ne doit jamais être à 0, car il sera pris comme un 256 !
	RET
car le résultat va déborder sur 8-bit ! D'où HL et non A en résultat !
Cet algo de multiplication n'est pas optimal (150 itérations !) mais on va faire avec pour plus de simplicité à faire fonctionner ton code.

Et donc le code qui suit n'est pas bon non plus :

Code : Tout sélectionner

    LD A, (y)           ; Load y into A
    ADD A, L            ; ra = 150 * (y / 10) + y
    LD (ra), A          ; Store ra
Il faut du 16-bit :

Code : Tout sélectionner

    LD DE,(y)            ; Load y into DE
    ADD HL,DE            ; ra = 150 * (y / 10) + y
    LD (ra), HL          ; Store ra
J'ai noté que tu as définis toutes les variables comme "dw 0" donc comme si elles étaient des 16-bit. C'est parfait pour "y" et "ra".

Concernant "ba", même problème avec MULTIPLY à ce niveau :

Code : Tout sélectionner

    LD A, 10            ; Load 10 into A
    CALL MULTIPLY       ; Multiply 10 * (x / 8)
    LD (ba), A          ; Store ba
Il faut :

Code : Tout sélectionner

    LD A, 10            ; Load 10 into A
    CALL MULTIPLY       ; Multiply 10 * (x / 8)
    LD (ba), HL          ; Store ba
Résultat dans HL plutôt que A en cas de débordement. Ça tombe bien, "ba" est défini comme 16-bit aussi.

Le calcul de "ma" n'est pas optimal mais il ne devrait pas poser de problème ici.

Reste le calcul de "ad" :

Code : Tout sélectionner

    ; Calculate ad = tase + ra + ba
    LD HL, (tase)       ; Load tase into HL
    LD A, (ra)          ; Load ra into A
    CALL ADD_TO_HL      ; HL = HL + ra
    LD A, (ba)          ; Load ba into A
    CALL ADD_TO_HL      ; HL = HL + ba
    LD (ad), HL         ; Store ad
On peut faire plus simple :

Code : Tout sélectionner

    ; Calculate ad = tase + ra + ba
    LD HL, (tase)       ; Load tase into HL
    LD DE, (ra)          ; Load ra into DE
    ADD HL,DE      ; HL = HL + ra
    LD DE, (ba)          ; Load ba into DE
    ADD HL,DE      ; HL = HL + ba
    LD (ad), HL         ; Store ad
Concernant mon code, j'ai fait une simplification fausse avec "OR (HL)" en pensant naïvement que ça ferait : "(HL) = (HL) OR A" alors que ça fait "A = A | (HL)".
__sam__
Messages : 8274
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par __sam__ »

Ythunder a écrit : 09 sept. 2024 09:11 Simple : comment une IA peut-elle connaitre la différence entre l'adressage mémoire d'un TO7 et d'un MO6 ?
Ouais et c'est même pas là qu'il y a un problème. C'est dans l'arithmétique de base (division, modulo) et les opérations bits à bits qu'elle écrit n'importe quoi. C'est la compréhension même de la difficulté de l'exercice (ici division et modulo par 10) qu'elle passe à coté. Avec les langages de haut niveau il y a tout ce qu'il faut pour répondre à ca sans réfléchir. Mais en asm, bah ya rien. Il faut réfléchir et par exemple approximer une division par 10 via une multiplication par 51 et une division par 512 (implémentée via 9 décalage à droite) comme on l'a vu proposé plus haut (reste à voir les problèmes de débordements de capacité). Mais cela est bien au dessus de ce qu'elle ne saurait faire avant longtemps.

Perso pour la division par 10, le mieux est une table précalculée. Pour la mulmtipication par 10 il suffit de voir que x*10 = (x*2*2+x)*2 pour l'atteindre avec des décalages et addition. Le modulo s'obtient lui via (x mod 10) = x - 10*(x//10) (// étant la division entière obtenue via la table de précalcul). Idem pour le calcul du bit à allumer une petite table de 8 octets est suffisante.

Enfin, si la mémoire n'est pas un problème, on peut carrément avoir une table de précalcul qui pour chaque y possible contient un pointeur vers le début de ligne correspondant. Ca coute 400 octets, mais c'est fichtrement rapide car il n'est plus besoin de jouer avec les multiplications et les modulos. Idem avec une table pour tous les x possible qui contient l'offset en octet sur la ligne et le bitmask à appliquer pour allumer le bon bit. Ce sera alors la routine la plus compacte et rapide qui soit.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
rendomizer
Messages : 434
Inscription : 17 juin 2016 21:00
Contact :

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par rendomizer »

_sam_ , Hlide, S.O.S codeur en détresse. je suis complètement con je n'arrive a rien
Je ne suis qu'un utilisateur pas un pro
Avatar de l’utilisateur
rendomizer
Messages : 434
Inscription : 17 juin 2016 21:00
Contact :

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par rendomizer »

testé mais erreurs en ADD A,248 et ADD 7

Code : Tout sélectionner

.org 22400
 push hl
start:
	; y = 32, x = 64
	LD HL,32 + 64 * 256

; H = x, L = y
draw_dot:
	PUSH HL

	; ba = 10 * INT(x / 8)
	LD A,H
	 AND A,248 ; ba = 8 * INT(x / 8) 
	LD C,A ; ba' = ba
	RRCA ; ba = 4 * INT(x / 8)
	RRCA ; ba = 2 * INT(x / 8)
	ADD A,C ; ba = ba + ba' = 10 * INT(x / 8)
	LD (ba),A

	; ra = 150 * INT(y / 10) + y
	LD A,L
	LD H,0 ; ra' = HL = y
	LD B,H ; BC = y
	LD C,L
	ADD HL,HL ; HL = ra' * 2
	ADD HL,HL ; HL = ra' * 4
	ADD HL,HL ; HL = ra' * 8
	LD D,H
	LD E,L
	ADD HL,HL ; HL = ra' * 16
	ADD HL,DE ; HL = ra' * 24
	ADD HL,BC ; HL = ra' * 25
	ADD HL,HL ; HL = ra' * 50
	ADD HL,BC ; HL = ra' * 51
	LD A,H
	RRA
	ADC A,B ; A = HL * 51 / 512 = INT(y / 10)
	LD L,A	; ra' = HL = INT(y / 10)
	LD H,0
	ADD HL,HL ; HL = ra' * 2
	LD D,H
	LD E,L
	ADD HL,HL ; HL = ra' * 4
	ADD HL,HL ; HL = ra' * 8
	EX DE,HL
	ADD HL,DE ; DE = ra' * 10
	ADD HL,BC ; DE = ra' * 11
	EX DE,HL
	ADD HL,HL ; HL = ra' * 16
	ADD HL,HL ; HL = ra' * 32
	ADD HL,HL ; HL = ra' * 64
	ADD HL,DE ; HL = ra' * 75
	ADD HL,HL ; HL = ra' * 150
	ADD HL,BC ; ra = 150 * INT(y / 10) + y

	; ad = tase + ra + ba
	LD DE,21000 ; tase
	ADD HL,DE
	LD DE,0
 
	ADD HL,DE

	; ma = 2 ^ (7 - (x AND 7))
	POP BC
	LD A,B
	AND 7
	NEG
     
        ADD 7 
	LD B,A
	LD A,1
power2_loop:
	JR Z,power2_exist
	ADD A,A
	DJNZ power2_loop
power2_exist:

	; POKE ad, PEEK(ad) OR ma

	OR (HL) ; ad

 pop hl
 ret
ba:
 .dw $-2
Je ne suis qu'un utilisateur pas un pro
Avatar de l’utilisateur
Papy.G
Modérateur
Messages : 3122
Inscription : 10 juin 2014 13:40
Localisation : Haute-Garonne/Gers

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par Papy.G »

Essaie de ne pas te tromper dans les chiffres, ce sera plus facile pour simplifier les calculs, c'est bien 125x160 (j'imagine que c'est pour le VG5k).
C'est donc (24+1)x5 par 40x4 avec des matrices 5x4, pas 10x8.
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Avatar de l’utilisateur
hlide
Messages : 3785
Inscription : 29 nov. 2017 10:23
Localisation : Yvelines

Re: Je pose ça la un petit code asm z80. Si quelqu'un peut m'aider

Message par hlide »

Oublie pour le moment le code que je t'avais posté en premier (tu noteras que j'ai indiqué dans mon deuxième message une erreur avec "or (hl)" à la fin du code). Reprends ton code initial et effectue les corrections dont je t'ai fait part dans mon deuxième message (passage de multiplication 8-bit (8b x 8b ->8b) à 16-bit (8b x 8b -> 16b) pour résumé). Je n'ai pas trop idée de ce que ça fait ton code à la base, donc c'est un peu difficile d'anticiper. J'ai juste l'impression que c'est pour dessiner un "point" en calculant l'adresse et le bit à assigner.
Répondre