;------------------------------------------------------------;
; m68k ASM by Marco "Ninja Killer" Benvegnu' Gen 2002 ;
; www.benve.org hiforce@gmx.it ;
;------------------------------------------------------------;
; ;
; Ecco alcuni algoritmi di divisione e moltiplicazione a ;
; precisione multipla per il Motorola M68000. ;
; ;
; NOTE: ;
; - MDIV16 divisione interi senza segno (divisore a 16 bit) ;
; Metodo tradizionale (semplice, veloce, espandibile) ;
; - MSDIV16 divisione interi con segno (metodo diretto) ;
; Questo e' molto interessante: in genere (v. MSDDIV) si ;
; effettua la divisione fra i valori assoluti e solo ;
; alla fine si tiene conto dei segni. ;
; Qui propongo una tecnica per valutare il segno ;
; direttamente all'interno del (potente) metodo ;
; tradizionale (MDIV16). ;
; - MSDDIV divisione interi con segno (divisore a 32 bit) ;
; - DDIV divisione interi senza segno (FIX) ;
; L'autore di DDIV e' Moro (unipd). ;
; - MDMUL moltiplicazione a 32 bit senza segno ;
; Metodo di scomposizione degli operandi in due parti ;
; da 16 bit (di interesse puramente accademico). ;
; ;
; PS: '' La divisione e' mia amica! '' ;
; ;
;------------------------------------------------------------;
;------------------------------------------------------------;
; NOME ;
; MDIV16 divisione interi senza segno (divisore di 16 bit) ;
; DESCRIZIONE ;
; Effettua la divisione tra interi senza segno, dividendo ;
; di 64 bit e divisore di 16 bit, fornendo quoziente di 64 ;
; bit e resto di 16 bit. Mai overflow. ;
; Estendibile a dividendo di dim. qualunque. ;
; INTERFACCIA ;
; A0 input puntatore dividendo ;
; A1 input puntatore quoziente ;
; QW[A0] input dividendo (64 bit) ;
; D1.W input divisore (16 bit) ;
; output resto (16 bit) ;
; QW[A1] output quoziente (64 bit) ;
; USA ;
; -- ;
;------------------------------------------------------------;
MDIV16:
MOVEM.L D0, -(SP) ; salva il registro
CLR.L D0
MOVE.W (A0), D0 ; MSW
DIVU.W D1, D0
MOVE.W D0, (A1) ; salva MSW quoziente
MOVE.W 2(A0), D0 ; il precedente resto in D0.H
DIVU.W D1, D0
MOVE.W D0, 2(A1)
MOVE.W 4(A0), D0 ; il precedente resto in D0.H
DIVU.W D1, D0
MOVE.W D0, 4(A1)
MOVE.W 6(A0), D0 ; il precedente resto in D0.H
DIVU.W D1, D0
MOVE.W D0, 6(A1)
SWAP.W D0 ; sposta il resto in D0.W
MOVE.W D0, D1
MOVEM.L (SP)+, D0 ; ripr. il registro
RTS
;------------------------------------------------------------;
; NOME ;
; MSDIV16 divisione interi con segno (metodo diretto) ;
; DESCRIZIONE ;
; Effettua la divisione tra interi con segno, dividendo ;
; di 64 bit e divisore di 16 bit, fornendo quoziente di 64 ;
; bit e resto di 16 bit. Mai overflow (non segnalato se si ;
; calcola -2^63 / -1 ). ;
; Troncamento floor anche per risultati negativi! ;
; INTERFACCIA ;
; A0 input puntatore dividendo (64 bit) ;
; A1 input puntatore quoziente (64 bit) ;
; QW[A0] input dividendo (64 bit) ;
; D1.W input divisore (16 bit) ;
; output resto (16 bit) ;
; QW[A1] output quoziente (64 bit) ;
; USA ;
; -- ;
;------------------------------------------------------------;
; NOTA: nel simulatore di Shaban, DIVS puo' segnalare,
; erroneamente, N=1, Z=1; se lo usi, aggiungi le 3 istruzioni
; commentate (BEQ)
MSDIV16:
MOVEM.L D0, -(SP) ; salva il registro
CLR.W D2
MOVE.W (A0), D0 ; MSW
EXT.L D0
DIVS.W D1, D0
MOVE.W D0, (A1) ; salva MSW quoziente
MOVE.W 2(A0), D0 ; il precedente resto in D0.H
DIVS.W D1, D0
BPL MSD161
;BEQ MSD161
SUBQ.W #1, (A1) ; riporto
MSD161: MOVE.W D0, 2(A1)
MOVE.W 4(A0), D0 ; il precedente resto in D0.H
DIVS.W D1, D0
BPL MSD162
;BEQ MSD162
SUBQ.W #1, 2(A1) ; riporto
MSD162: MOVE.W D0, 4(A1)
MOVE.W 6(A0), D0 ; il precedente resto in D0.H
DIVS.W D1, D0 ; LSW, no riporto
BPL MSD163
;BEQ MSD163
SUBQ.W #1, 4(A1) ; riporto
MSD163: MOVE.W D0, 6(A1)
SWAP.W D0 ; sposta il resto in D0.L
MOVE.W D0, D1
MOVEM.L (SP)+, D0 ; ripr. il registro
RTS
;------------------------------------------------------------;
; NOME ;
; MSDDIV divisione interi con segno (FIX) ;
; DESCRIZIONE ;
; Effettua la divisione tra interi con segno, dividendo ;
; di 64 bit e divisore di 32 bit, fornendo quoziente e ;
; resto. ;
; INTERFACCIA ;
; D0 input dividendo (parte meno significativa) ;
; D1 input dividendo (parte piu` significativa) ;
; D2 input divisore ;
; D0 output resto ;
; D1 output quoziente ;
; C, X output = 1 se overflow ;
; USA ;
; Subr: DDIV ;
; ;
; TEST IT WITH C ;
; #include