home *** CD-ROM | disk | FTP | other *** search
- # Externe Routinen zu ARILEV1.D
- # Compiler: TURBO-C
- # Parameter-Übergabe: in Registern A0-A1,D0-D2, Rest auf dem Stack.
- # Einstellungen: intCsize=16, intDsize=32.
-
- #ifdef INCLUDED_FROM_C
-
- #define COPY_LOOPS
- #define FILL_LOOPS
- #define CLEAR_LOOPS
- #define LOG_LOOPS
- #define TEST_LOOPS
- #define ADDSUB_LOOPS
- #define SHIFT_LOOPS
- #define MUL_LOOPS
- #define DIV_LOOPS
-
- #else
-
- .text
-
- .xdef mulu32_,divu_6432_3232_
- .xdef copy_loop_up,copy_loop_down,fill_loop_up,fill_loop_down
- .xdef clear_loop_up,clear_loop_down
- .xdef or_loop_up,xor_loop_up,and_loop_up,eqv_loop_up
- .xdef nand_loop_up,nor_loop_up,andc2_loop_up,orc2_loop_up
- .xdef not_loop_up
- .xdef and_test_loop_up,test_loop_up,compare_loop_up
- .xdef add_loop_down,addto_loop_down,inc_loop_down
- .xdef sub_loop_down,subx_loop_down,subfrom_loop_down,dec_loop_down
- .xdef neg_loop_down
- .xdef shift1left_loop_down,shiftleft_loop_down,shiftleftcopy_loop_down
- .xdef shift1right_loop_up,shiftright_loop_up,shiftrightsigned_loop_up,shiftrightcopy_loop_up
- .xdef mulusmall_loop_down,mulu_loop_down,muluadd_loop_down,mulusub_loop_down
- .xdef divu_loop_up,divucopy_loop_up
-
- ; extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
- ; 2^32*hi+lo := arg1*arg2.
- mulu32_: ; Input in D0,D1, Output in D0,mulu32_high
- MULU.L D1,D1:D0
- MOVE.L D1,(mulu32_high) ; Adressierung?? Deklaration??
- RTS
-
- ; extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
- ; x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, daß 0 <= x < 2^32*y .
- divu_6432_3232_: ; Input in D0,D1,D2, Output in D0,divu_32_rest
- DIVU.L D2,D0:D1 ; x = D0|D1 durch y dividieren
- MOVE.L D0,(divu_32_rest) ; Rest ablegen ; Adressierung?? Deklaration??
- MOVE.L D1,D0 ; Quotient als Ergebnis
- RTS
-
- ; extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
- copy_loop_up: ; Input in A0,A1,D0.W, Output in A0
- BRA.S \2
- \1: MOVE.L (A0)+,(A1)+
- \2: DBF D0,\1
- MOVE.L A1,A0
- RTS
-
- ; extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
- copy_loop_down: ; Input in A0,A1,D0.W, Output in A0
- BRA.S \2
- \1: MOVE.L -(A0),-(A1)
- \2: DBF D0,\1
- MOVE.L A1,A0
- RTS
-
- ; extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
- fill_loop_up: ; Input in A0,D0.W,D1, Output in A0
- BRA.S \2
- \1: MOVE.L D1,(A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
- fill_loop_down: ; Input in A0,D0.W,D1, Output in A0
- BRA.S \2
- \1: MOVE.L D1,-(A0)
- \2: DBF D0,\1
- RTS
-
- ; extern uintD* clear_loop_up (uintD* destptr, uintC count);
- clear_loop_up: ; Input in A0,D0.W, Output in A0
- BRA.S \2
- \1: CLR.L (A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern uintD* clear_loop_down (uintD* destptr, uintC count);
- clear_loop_down: ; Input in A0,D0.W, Output in A0
- BRA.S \2
- \1: CLR.L -(A0)
- \2: DBF D0,\1
- RTS
-
- ; extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
- or_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- OR.L D1,(A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
- xor_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- EOR.L D1,(A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
- and_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- AND.L D1,(A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
- eqv_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- EOR.L D1,(A0)
- NOT.L (A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
- nand_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- AND.L D1,(A0)
- NOT.L (A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
- nor_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- OR.L D1,(A0)
- NOT.L (A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
- andc2_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- NOT.L D1
- AND.L D1,(A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
- orc2_loop_up: ; Input in A0,A1,D0.W, verändert D1
- BRA.S \2
- \1: MOVE.L (A1)+,D1
- NOT.L D1
- OR.L D1,(A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern void not_loop_up (uintD* xptr, uintC count);
- not_loop_up: ; Input in A0,D0.W
- BRA.S \2
- \1: NOT.L (A0)+
- \2: DBF D0,\1
- RTS
-
- ; extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
- and_test_loop_up: ; Input in A0,A1,D0.W, verändert D1, Output in D0.W=D0.L
- BRA.S \2
- \1: MOVE.L (A0)+,D1
- AND.L (A1)+,D1
- BNE.S \3
- \2: DBF D0,\1
- CLR.L D0
- RTS
- \3: MOVEQ.L #1,D0
- RTS
-
- ; extern boolean test_loop_up (uintD* ptr, uintC count);
- test_loop_up: ; Input in A0,D0.W, Output in D0.W=D0.L
- BRA.S \2
- \1: TST.L (A0)+
- BNE.S \3
- \2: DBF D0,\1
- CLR.L D0
- RTS
- \3: MOVEQ.L #1,D0
- RTS
-
- ; extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
- compare_loop_up: ; Input in A0,A1,D0.W, Output in D0.W=D0.L
- BRA.S \2
- \1: CMPM.L (A1)+,(A0)+
- BNE.S \3
- \2: DBF D0,\1
- CLR.L D0
- RTS
- \3: BLO.S \4
- MOVEQ.L #1,D0
- RTS
- \4: MOVEQ.L #-1,D0
- RTS
-
- ; extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
- add_loop_down: ; Input in A0,A1,A2,D0.W, verändert D1,D2, Output in D0
- MOVE.L A2,-(SP)
- ANDI #%01110,CCR ; X-Bit löschen
- BRA.S \2
- \1: MOVE.L -(A0),D1
- MOVE.L -(A1),D2
- ADDX.L D2,D1
- MOVE.L D1,-(A2)
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- MOVE.L (SP)+,A2
- RTS
-
- ; extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
- addto_loop_down: ; Input in A0,A1,D0.W, Output in D0
- ANDI #%01110,CCR ; X-Bit löschen
- BRA.S \2
- \1: ADDX.L -(A0),-(A1)
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- RTS
-
- ; extern uintD inc_loop_down (uintD* ptr, uintC count);
- inc_loop_down: ; Input in A0,D0.W, Output in D0
- DBF D0,\1 ; simuliere gesetzten Carry
- MOVEQ.L #-1,D0 ; D0.L=-1 für Übertrag
- RTS
- \1: ADDQ.L #1,-(A0)
- DBCC D0,\1
- SUBX.L D0,D0 ; kein Carry -> D0.L=0, sonst D0.L=-1 für Übertrag
- RTS
-
- ; extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
- sub_loop_down: ; Input in A0,A1,A2,D0.W, verändert D1,D2, Output in D0
- MOVE.L A2,-(SP)
- ANDI #%01110,CCR ; X-Bit löschen
- BRA.S \2
- \1: MOVE.L -(A0),D1
- MOVE.L -(A1),D2
- SUBX.L D2,D1
- MOVE.L D1,-(A2)
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- MOVE.L (SP)+,A2
- RTS
-
- ; extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
- subx_loop_down: ; Input in A0,A1,A2,D0.W,D1, verändert D2, Output in D0
- MOVE.L A2,-(SP)
- ROXR.L #1,D1 ; X-Bit initialisieren
- BRA.S \2
- \1: MOVE.L -(A0),D1
- MOVE.L -(A1),D2
- SUBX.L D2,D1
- MOVE.L D1,-(A2)
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- MOVE.L (SP)+,A2
- RTS
-
- ; extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
- subfrom_loop_down: ; Input in A0,A1,D0.W, Output in D0
- ANDI #%01110,CCR ; X-Bit löschen
- BRA.S \2
- \1: SUBX.L -(A0),-(A1)
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- RTS
-
- ; extern uintD dec_loop_down (uintD* ptr, uintC count);
- dec_loop_down: ; Input in A0,D0.W, Output in D0
- DBF D0,\1 ; simuliere gesetzten Carry
- MOVEQ.L #-1,D0 ; D0.L=-1 als Übertrag
- RTS
- \1: SUBQ.L #1,-(A0)
- DBCC D0,\1 ; kein Carry -> Schleife abbrechen
- SUBX.L D0,D0 ; kein Carry -> D0.L=0, sonst D0.L=-1 als Übertrag
- RTS
-
- ; extern uintD neg_loop_down (uintD* ptr, uintC count);
- neg_loop_down: ; Input in A0,D0.W, Output in D0
- ANDI #%01110,CCR ; X-Bit löschen
- BRA.S \2
- \1: NEGX.L -(A0)
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- RTS
-
- ; extern uintD shift1left_loop_down (uintD* ptr, uintC count);
- shift1left_loop_down: ; Input in A0,D0.W, Output in D0.L
- ANDI #%01110,CCR ; X-Bit löschen
- BRA.S \2
- \1: ROXL.W -(A0) ; Digit -(A0) um 1 Bit links schieben, X-Bit als Buffer
- ROXL.W -(A0)
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- RTS
-
- ; extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
- shiftleft_loop_down: ; Input in A0,D0.W,D1.W,D2, Output in D0
- #if 1
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #32,D5
- SUB.W D1,D5
- ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i,
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; D3.L = neues Digit
- MOVE.L D3,D4
- LSL.L D1,D4 ; um i Bits nach links schieben
- OR.L D2,D4 ; mit vorigem Übertrag kombinieren
- MOVE.L D4,(A0) ; 32 Bits ablegen
- MOVE.L D3,D2
- LSR.L D5,D2 ; neuen Übertrag bilden
- \2: DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #else
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #1,D5
- LSL.L D1,D5
- SUBQ.L #1,D5
- ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^i-1
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; D3.L = neues Digit
- ROL.L D1,D3 ; um i Bits links rotieren
- MOVE.L D3,D4
- AND.L D5,D3 ; untere i Bits in D3
- EOR.L D3,D4 ; obere 32-i Bits in D4
- OR.L D2,D4 ; mit vorigem übertrag kombinieren
- MOVE.L D4,(A0) ; 32 Bits ablegen
- MOVE.L D3,D2 ; neuer Übertrag
- \2: DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #endif
-
- ; extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
- shiftleftcopy_loop_down: ; Input in A0,A1,D0.W,D1.W, Output in D0
- #if 1
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #32,D5
- SUB.W D1,D5
- CLR.L D2
- ; A0 = sourceptr, A1 = destptr, D0.W = count, D1.W = i, D5.W = 32-i,
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; D3.L = neues Digit
- MOVE.L D3,D4
- LSL.L D1,D4 ; um i Bits nach links schieben
- OR.L D2,D4 ; mit vorigem Übertrag kombinieren
- MOVE.L D4,-(A1) ; 32 Bits ablegen
- MOVE.L D3,D2
- LSR.L D5,D2 ; neuen Übertrag bilden
- \2: DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #else
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #1,D5
- LSL.L D1,D5
- SUBQ.L #1,D5
- ; A0 = sourceptr, A1 = destptr, D0.W = count, D1.W = i, D5.L = 2^i-1
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; D3.L = neues Digit
- ROL.L D1,D3 ; um i Bits links rotieren
- MOVE.L D3,D4
- AND.L D5,D3 ; untere i Bits in D3
- EOR.L D3,D4 ; obere 32-i Bits in D4
- OR.L D2,D4 ; mit vorigem übertrag kombinieren
- MOVE.L D4,-(A1) ; 32 Bits ablegen
- MOVE.L D3,D2 ; neuer Übertrag
- \2: DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #endif
-
- ; extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
- shift1right_loop_up: ; Input in A0,D0.W,D1, Output in D0
- ROXR.L #1,D1 ; X-Bit löschen oder setzen, je nach D1
- BRA.S \2
- \1: ROXR.W (A0)+ ; Digit (A0)+ um 1 Bit rechts schieben, X-Bit als Buffer
- ROXR.W (A0)+
- \2: DBF D0,\1
- SUBX.L D0,D0 ; -1 falls X gesetzt, 0 falls X gelöscht
- RTS
-
- ; extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
- shiftright_loop_up: ; Input in A0,D0.W,D1.W, Output in D0
- #if 1
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #32,D5
- SUB.W D1,D5
- ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i,
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- CLR.L D2
- BRA.S \2
- \1: ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.W = 32-i,
- ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
- ; D3.L = Schiebe-Akku
- MOVE.L (A0),D3 ; neue Daten
- MOVE.L D3,D4
- LSR.L D1,D3 ; um i Bits rechts schieben
- OR.L D2,D3 ; und mit vorigem Übertrag kombinieren
- MOVE.L D3,(A0)+ ; ablegen
- LSL.L D5,D4 ; um (32-i) Bits links geschoben
- MOVE.L D4,D2 ; liefert neuen Übertrag
- \2: DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #else
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #-1,D5
- LSR.L D1,D5
- ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^(32-i)-1,
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- CLR.L D2
- BRA.S \2
- \1: ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.L = 2^(32-i)-1,
- ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
- ; D3.L = Schiebe-Akku
- MOVE.L (A0),D3 ; neue Daten
- ROR.L D1,D3 ; um i Bits rechts rotieren
- MOVE.L D3,D4
- AND.L D5,D3 ; untere 32-i Bits
- EOR.L D3,D4 ; obere i Bits
- OR.L D2,D3 ; und mit vorigem Übertrag kombinieren
- MOVE.L D4,D2 ; neuer Übertrag
- MOVE.L D3,(A0)+ ; ablegen
- \2: DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #endif
-
- ; extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
- shiftrightsigned_loop_up: ; Input in A0,D0.W,D1.W, Output in D0
- #if 1
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #32,D5
- SUB.W D1,D5
- ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i,
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- SUBQ.W #1,D0
- MOVE.L (A0),D3 ; erstes Digit
- MOVE.L D3,D4
- ASR.L D1,D3 ; um i Bits rechts schieben
- BRA.S \2
- \1: ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.W = 32-i,
- ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
- ; D3.L = Schiebe-Akku
- MOVE.L (A0),D3 ; neue Daten
- MOVE.L D3,D4
- LSR.L D1,D3 ; um i Bits rechts schieben
- OR.L D2,D3 ; und mit vorigem Übertrag kombinieren
- \2: MOVE.L D3,(A0)+ ; ablegen
- LSL.L D5,D4 ; um (32-i) Bits links geschoben
- MOVE.L D4,D2 ; liefert neuen Übertrag
- DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #else
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #-1,D5
- LSR.L D1,D5
- ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^(32-i)-1,
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- SUBQ.W #1,D0
- MOVE.L (A0),D3 ; erstes Digit
- MOVE.L D3,D4
- ROR.L D1,D4 ; um i Bits rechts rotieren
- MOVE.L D5,D2
- NOT.L D2
- AND.L D4,D2 ; obere 32-i Bits
- ASR.L D1,D3 ; erstes Digit um i Bits rechts shiften
- BRA.S \2
- \1: ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.L = 2^(32-i)-1,
- ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
- ; D3.L = Schiebe-Akku
- MOVE.L (A0),D3 ; neue Daten
- ROR.L D1,D3 ; um i Bits rechts rotieren
- MOVE.L D3,D4
- AND.L D5,D3 ; untere 32-i Bits
- EOR.L D3,D4 ; obere i Bits
- OR.L D2,D3 ; und mit vorigem Übertrag kombinieren
- MOVE.L D4,D2 ; neuer Übertrag
- \2: MOVE.L D3,(A0)+ ; ablegen
- DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #endif
-
- ; extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
- shiftrightcopy_loop_up: ; Input in A0,A1,D0.W,D1.W,D2, Output in D0
- #if 1
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #32,D5
- SUB.W D1,D5
- ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- BRA.S \2
- \1: ; A0,A1 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.W = 32-i
- ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
- ; D3.L = Schiebe-Akku
- MOVE.L (A0)+,D3 ; neue Daten
- MOVE.L D3,D4
- LSR.L D1,D3 ; um i Bits rechts schieben
- OR.L D2,D3 ; und mit vorigem Übertrag kombinieren
- MOVE.L D3,(A1)+ ; ablegen
- MOVE.L D4,D2
- \2: LSL.L D5,D2 ; um (32-i) Bits links geschoben, gibt neuen Übertrag
- DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #else
- MOVEM.L D3-D5,-(SP)
- MOVEQ.L #-1,D5
- LSR.L D1,D5
- ROR.L D1,D2
- ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^(32-i)-1
- ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
- BRA.S \2
- \1: ; A0,A1 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.L = 2^(32-i)-1
- ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
- ; D3.L = Schiebe-Akku
- MOVE.L (A0)+,D3 ; neue Daten
- ROR.L D1,D3 ; um i Bits rechts rotieren
- MOVE.L D3,D4
- AND.L D5,D3 ; untere 32-i Bits
- EOR.L D3,D4 ; obere i Bits
- OR.L D2,D3 ; und mit vorigem Übertrag kombinieren
- MOVE.L D4,D2 ; neuer Übertrag
- MOVE.L D3,(A1)+ ; ablegen
- \2: DBF D0,\1 ; Schleife D0.W mal durchlaufen
- MOVE.L D2,D0
- MOVEM.L (SP)+,D3-D5
- RTS
- #endif
-
- ; extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
- mulusmall_loop_down: # Input in D0,A0,D1.W,D2, Output in D0
- MOVEM.L D3-D4,-(SP)
- ADD.W #0,D1 ; X-Bit löschen
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; nächstes Digit
- MULU.L D0,D4:D3 ; mit digit multiplizieren
- ADDX.L D2,D3 ; und bisherigen Carry und X-Bit addieren
- MOVE.L D3,(A0) ; Low-Digit ablegen
- MOVE.L D4,D2 ; High-Digit gibt neuen Carry
- \2: DBF D1,\1
- CLR.L D0
- ADDX.L D2,D0 ; letzter Carry (incl. X-Bit)
- MOVEM.L (SP)+,D3-D4
- RTS
-
- ; extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- mulu_loop_down: ; Input in D0,A0,A1,D1.W
- #if 1
- MOVEM.L D3-D4,-(SP)
- SUB.L D2,D2 ; carry := 0, X-Bit löschen
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; nächstes Digit
- MULU.L D0,D4:D3 ; mit digit multiplizieren
- ADDX.L D2,D3 ; und bisherigen Carry und X-Bit addieren
- MOVE.L D3,-(A1) ; Low-Digit ablegen
- MOVE.L D4,D2 ; High-Digit gibt neuen Carry
- \2: DBF D1,\1
- CLR.L D3
- ADDX.L D3,D2 ; letztes X-Bit verarbeiten
- MOVE.L D2,-(A1) ; letzten Carry ablegen
- MOVEM.L (SP)+,D3-D4
- RTS
- #else
- MOVEM.L D3-D5,-(SP)
- CLR.L D5 ; 0
- CLR.L D2 ; carry
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; nächstes Digit
- MULU.L D0,D4:D3 ; mit digit multiplizieren
- ADD.L D2,D3 ; und bisherigen Carry addieren
- ADDX.L D5,D4
- MOVE.L D3,-(A1) ; Low-Digit ablegen
- MOVE.L D4,D2 ; High-Digit gibt neuen Carry
- \2: DBF D1,\1
- MOVE.L D2,-(A1) ; letzten Carry ablegen
- MOVEM.L (SP)+,D3-D5
- RTS
- #endif
-
- ; extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- muluadd_loop_down: ; Input in D0,A0,A1,D1.W, Output in D0
- MOVEM.L D3-D5,-(SP)
- CLR.L D5 ; 0
- SUB.L D2,D2 ; carry := 0, X-Bit löschen
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; nächstes Digit
- MULU.L D0,D4:D3 ; mit digit multiplizieren
- ADDX.L D2,D3 ; und bisherigen Carry und X-Bit addieren
- ADDX.L D5,D4
- ADD.L D3,-(A1) ; Low-Digit zum dest-Digit addieren, X als Übertrag
- MOVE.L D4,D2 ; High-Digit gibt neuen Carry
- \2: DBF D1,\1
- ADDX.L D5,D2 ; letztes X-Bit addieren
- MOVE.L D2,D0 ; letzten Carry als Ergebnis
- MOVEM.L (SP)+,D3-D5
- RTS
-
- ; extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- mulusub_loop_down: ; Input in D0,A0,A1,D1.W, Output in D0
- MOVEM.L D3-D5,-(SP)
- CLR.L D5 ; 0
- SUB.L D2,D2 ; carry := 0, X-Bit löschen
- BRA.S \2
- \1: MOVE.L -(A0),D3 ; nächstes Digit
- MULU.L D0,D4:D3 ; mit digit multiplizieren
- ADDX.L D2,D3 ; und bisherigen Carry und X-Bit addieren
- ADDX.L D5,D4
- SUB.L D3,-(A1) ; Low-Digit vom dest-Digit subtrahieren, X als Übertrag
- MOVE.L D4,D2 ; High-Digit gibt neuen Carry
- \2: DBF D1,\1
- CLR.L D0
- ADDX.L D2,D0 ; letzter Carry und letztes X-Bit
- MOVEM.L (SP)+,D3-D5
- RTS
-
- ; extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
- divu_loop_up: # Input in D0,A0,D1.W, Output in D0
- MOVE.L D3,-(SP)
- CLR.L D2 ; Rest := 0
- BRA.S \2
- \1: MOVE.L (A0),D3 ; nächst-niedriges Digit
- DIVU.L D0,D2:D3 ; mit Rest kombinieren und durch digit dividieren
- MOVE.L D3,(A0)+ ; Quotient ablegen, Rest in D2
- \2: DBF D1,\1
- MOVE.L D2,D0 ; Rest
- MOVE.L (SP)+,D3
- RTS
-
- ; extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- divucopy_loop_up: # Input in D0,A0,A1,D1.W, Output in D0
- MOVE.L D3,-(SP)
- CLR.L D2 ; Rest := 0
- BRA.S \2
- \1: MOVE.L (A0)+,D3 ; nächst-niedriges Digit
- DIVU.L D0,D2:D3 ; mit Rest kombinieren und durch digit dividieren
- MOVE.L D3,(A1)+ ; Quotient ablegen, Rest in D2
- \2: DBF D1,\1
- MOVE.L D2,D0 ; Rest
- MOVE.L (SP)+,D3
- RTS
-
- .end
-
- #endif
-
-