Logicielsmoto.com http://www.logicielsmoto.com/phpBB/ |
|
Multiplication d'un signé 9bit avec un signé 16bit http://www.logicielsmoto.com/phpBB/viewtopic.php?f=3&t=675 |
Page 1 sur 1 |
Auteur: | Bentoc [ 29 Mai 2022, 06:26 ] |
Sujet du message: | Multiplication d'un signé 9bit avec un signé 16bit |
Hello, En prenant comme base une routine trouvée ici (p168): http://datassette.nyc3.cdn.digitaloceanspaces.com/livros/6809assemblylanguageprogramming.pdf (Que certains d'entre vous connaissent déjà, j'en suis sûr) J'ai fait une routine pour multiplier un nombre sur 9bit (signé) avec un nombre 16bit (signé). Le nombre 9bit représente -1 ($FF00) à 1 ($0100), le résultat est donc un nombre signé sur 16 bits. A quoi ça sert ? A appliquer un cos/sin dont les valeurs sont encodées dans une plage $FF00 à $0100. Seule chose manquante : dans le @neg1 après le bsr je devrait faire un neg sur le résultat 24 bits, même si je n'exploite que les 16 bits hauts. Je ne sais pas faire autre chose que le neg 16 bits ... si qq sait faire sur 24 ? Code: ; Multiply signed 9 bit (multiplier) by signed 16 bit (multiplicand)
; ------------------------------------------------------------------ ; result = (product/256) ; ; input : ; d = signed 9 bit ; x = signed 16 bit ; ; output : ; d = signed 16 bit ; ; (a) 01 } ; (@m) 00 } multiplier (9 bit) ; (@m_h) 20 } ; (@m_l) 00 } multiplicand (16 bit) ; ; Result: ; (a) 20 } ; (b) 00 } 2000 is product/256 SETDP direct_page/256 @m equ direct_page+115 @m_h equ direct_page+116 @m_l equ direct_page+117 @r_h equ direct_page+118 @r_l equ direct_page+119 @r equ direct_page+120 ; Mul9x16 tsta beq @pos ; $0000 <= d <= $00FF bpl @p256 ; d = $0100 tstb bne @neg ; $FF01 >= d >= $FFFF @n256 tfr x,d ; d = $FF00 nega negb sbca #0 ; *-1 rts @p256 tfr x,d ; *1 rts @pos stb @m ; positive multiplier stx @m_h bpl @mul ; positive result @neg2 ldd @m_h ; negative multiplicand nega negb sbca #0 std @m_h ldb @m @neg1 bsr @mul nega ; negative result negb sbca #0 rts @neg negb ; negative multiplier stb @m stx @m_h bpl @neg1 ; positive multiplicand ldd @m_h ; negative multiplicand and positive result nega negb sbca #0 std @m_h ldb @m @mul lda @m_l ; get lsb's of multiplicand mul ; multiply lsb's std @r_l ; save partial product lda @m ; get multiplier ldb @m_h ; get msb's of multiplicand mul ; multiply msb's addb @r_l ; add lsb's to msb's of previous partial product adca #0 ; add carry to msb's ;std @r_h ; save sum of partial products rts |
Auteur: | Samuel Devulder [ 29 Mai 2022, 10:16 ] |
Sujet du message: | Re: Multiplication d'un signé 9bit avec un signé 16bit |
Le neg sur N bits c'est à la base ==> inverser tous les bits et ajouter 1. Donc un truc comme Code: COMA ! inversion des bits A noter: COM suivi d'un INC sur la même adresse c'est juste un NEG. Donc au final on a:COMB ! inversion des bits COM @r_l+1 ! inversion des bits INC @r_l+1 ! ajouter 1 BNE nocarry ADDD #1 ! propagation retenue aux bits supérieurs nocarry suite Code: COMA Si on a pas besoin de précision, on peut ignorer le +1 qui fera rarement propager la retenue au delà de quelques bits de poids faibles, et ne garder que l'inversion des bits sur les poids forts. Dans le cas présent cela revient à ne pas faire le NEG et la propag et ne garder que les COMA/COMB. Le résultat sera faux de 1 unité sur D une fois sur 256 (cas où @r_l+1 est à 0). Ca peut-être un résultat largement acceptable quand on cherche la vitesse et pas la précision.COMB NEG @r_l+1 BNE nocarry ADDD #1 nocarry suite Si on aime pas les sauts, on peut remarquer que si la carry est à 1, on a COMB suivi d'un ADDD #1, c'est à dire (~B+1) = -B, un NEGB. Aussi on pourrait faire un NEGB dès le début, et le transformer en simple COMB quand il y a une carry en la soustrayant après le neg. On peut faire pareil pour A et il vient: Code: NEGA qui est juste la généralisation 24bits du NEGD. Ici les deux SBC coutent 4 cycles, alors que dans le code au dessus, le BNE (qui est vrai 255 fois sur 256) n'en coute que 3. En moyenne la version avec le saut est plus rapide de 255/256=0.996 cycles.
NEGB NEG @r_l+1 SBCB #0 SBCA #0 |
Auteur: | Bentoc [ 29 Mai 2022, 10:34 ] |
Sujet du message: | Re: Multiplication d'un signé 9bit avec un signé 16bit |
merci sam c'est bcp plus clair maintenant. Oui effectivement si pas besoin de précision on peut rester sur des com. je vais quand même garder la version "exacte". Par contre le test bne va pas fonctionner, le neg ne renvoie 0 que quand l'octet est déjà à 0. je pense qu'on doit plutot tester si @r est à 1 (avant le neg) et donc va donner $ff + 1 soit 0 (ce qui déclenche le addd #1 sur la partie supérieure) ? |
Auteur: | Samuel Devulder [ 29 Mai 2022, 10:51 ] |
Sujet du message: | Re: Multiplication d'un signé 9bit avec un signé 16bit |
Citation: Par contre le test bne va pas fonctionner Ben si.Citation: le neg ne renvoie 0 que quand l'octet est déjà à 0. Ben oui. C'est le seul cas où il faut propager la retenue. Comme je l'ai dit plus haut le +1 sur N bits ne perturbe que quelques bits de poids faibles Pour qu'il aille changer les bits de poids fort, il faut que toute la partie "en dessous" soit à 0. Ici c'est à dire ici que l'octet de poids faible soit nul (avant ou après la négation peu importe). Donc on ne teste pas la carry ici (de toute façon INC ne la positionne pas), mais on teste à 0 le résultats avant (==résultat après) le NEG. Tu vois? |
Auteur: | Bentoc [ 29 Mai 2022, 17:11 ] |
Sujet du message: | Re: Multiplication d'un signé 9bit avec un signé 16bit |
Oui effectivement je me suis embrouillé ... la solution : Code: COMA COMB NEG @r_l+1 BNE nocarry ADDD #1 nocarry suite fonctionne a merveille et est bien plus simple que ce que j'avais imaginé ... Thx ! |
Page 1 sur 1 | Heures au format UTC + 1 heure |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |