home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-1.LHA / CLISP960530-sr.lha / src / ari68020.mot.d < prev    next >
Encoding:
Text File  |  1996-04-15  |  24.7 KB  |  675 lines

  1. # Externe Routinen zu ARILEV1.D
  2. # Compiler: TURBO-C
  3. # Parameter-Übergabe: in Registern A0-A1,D0-D2, Rest auf dem Stack.
  4. # Einstellungen: intCsize=16, intDsize=32.
  5.  
  6. #ifdef INCLUDED_FROM_C
  7.  
  8.   #define COPY_LOOPS
  9.   #define FILL_LOOPS
  10.   #define CLEAR_LOOPS
  11.   #define LOG_LOOPS
  12.   #define TEST_LOOPS
  13.   #define ADDSUB_LOOPS
  14.   #define SHIFT_LOOPS
  15.   #define MUL_LOOPS
  16.   #define DIV_LOOPS
  17.  
  18. #else
  19.  
  20.            .text
  21.  
  22.            .xdef mulu32_,divu_6432_3232_
  23.            .xdef copy_loop_up,copy_loop_down,fill_loop_up,fill_loop_down
  24.            .xdef clear_loop_up,clear_loop_down
  25.            .xdef or_loop_up,xor_loop_up,and_loop_up,eqv_loop_up
  26.            .xdef nand_loop_up,nor_loop_up,andc2_loop_up,orc2_loop_up
  27.            .xdef not_loop_up
  28.            .xdef and_test_loop_up,test_loop_up,compare_loop_up
  29.            .xdef add_loop_down,addto_loop_down,inc_loop_down
  30.            .xdef sub_loop_down,subx_loop_down,subfrom_loop_down,dec_loop_down
  31.            .xdef neg_loop_down
  32.            .xdef shift1left_loop_down,shiftleft_loop_down,shiftleftcopy_loop_down
  33.            .xdef shift1right_loop_up,shiftright_loop_up,shiftrightsigned_loop_up,shiftrightcopy_loop_up
  34.            .xdef mulusmall_loop_down,mulu_loop_down,muluadd_loop_down,mulusub_loop_down
  35.            .xdef divu_loop_up,divucopy_loop_up
  36.  
  37. ; extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
  38. ; 2^32*hi+lo := arg1*arg2.
  39. mulu32_:   ; Input in D0,D1, Output in D0,mulu32_high
  40.            MULU.L D1,D1:D0
  41.            MOVE.L D1,(mulu32_high) ; Adressierung?? Deklaration??
  42.            RTS
  43.  
  44. ; extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
  45. ; x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, daß 0 <= x < 2^32*y .
  46. divu_6432_3232_: ; Input in D0,D1,D2, Output in D0,divu_32_rest
  47.            DIVU.L D2,D0:D1 ; x = D0|D1 durch y dividieren
  48.            MOVE.L D0,(divu_32_rest) ; Rest ablegen ; Adressierung?? Deklaration??
  49.            MOVE.L D1,D0 ; Quotient als Ergebnis
  50.            RTS
  51.  
  52. ; extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
  53. copy_loop_up: ; Input in A0,A1,D0.W, Output in A0
  54.            BRA.S \2
  55.     \1:      MOVE.L (A0)+,(A1)+
  56.     \2:      DBF D0,\1
  57.            MOVE.L A1,A0
  58.            RTS
  59.  
  60. ; extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  61. copy_loop_down: ; Input in A0,A1,D0.W, Output in A0
  62.            BRA.S \2
  63.     \1:      MOVE.L -(A0),-(A1)
  64.     \2:      DBF D0,\1
  65.            MOVE.L A1,A0
  66.            RTS
  67.  
  68. ; extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
  69. fill_loop_up: ; Input in A0,D0.W,D1, Output in A0
  70.            BRA.S \2
  71.     \1:      MOVE.L D1,(A0)+
  72.     \2:      DBF D0,\1
  73.            RTS
  74.  
  75. ; extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
  76. fill_loop_down: ; Input in A0,D0.W,D1, Output in A0
  77.            BRA.S \2
  78.     \1:      MOVE.L D1,-(A0)
  79.     \2:      DBF D0,\1
  80.            RTS
  81.  
  82. ; extern uintD* clear_loop_up (uintD* destptr, uintC count);
  83. clear_loop_up: ; Input in A0,D0.W, Output in A0
  84.            BRA.S \2
  85.     \1:      CLR.L (A0)+
  86.     \2:      DBF D0,\1
  87.            RTS
  88.  
  89. ; extern uintD* clear_loop_down (uintD* destptr, uintC count);
  90. clear_loop_down: ; Input in A0,D0.W, Output in A0
  91.            BRA.S \2
  92.     \1:      CLR.L -(A0)
  93.     \2:      DBF D0,\1
  94.            RTS
  95.  
  96. ; extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
  97. or_loop_up: ; Input in A0,A1,D0.W, verändert D1
  98.            BRA.S \2
  99.     \1:      MOVE.L (A1)+,D1
  100.              OR.L D1,(A0)+
  101.     \2:      DBF D0,\1
  102.            RTS
  103.  
  104. ; extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  105. xor_loop_up: ; Input in A0,A1,D0.W, verändert D1
  106.            BRA.S \2
  107.     \1:      MOVE.L (A1)+,D1
  108.              EOR.L D1,(A0)+
  109.     \2:      DBF D0,\1
  110.            RTS
  111.  
  112. ; extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
  113. and_loop_up: ; Input in A0,A1,D0.W, verändert D1
  114.            BRA.S \2
  115.     \1:      MOVE.L (A1)+,D1
  116.              AND.L D1,(A0)+
  117.     \2:      DBF D0,\1
  118.            RTS
  119.  
  120. ; extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
  121. eqv_loop_up: ; Input in A0,A1,D0.W, verändert D1
  122.            BRA.S \2
  123.     \1:      MOVE.L (A1)+,D1
  124.              EOR.L D1,(A0)
  125.              NOT.L (A0)+
  126.     \2:      DBF D0,\1
  127.            RTS
  128.  
  129. ; extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
  130. nand_loop_up: ; Input in A0,A1,D0.W, verändert D1
  131.            BRA.S \2
  132.     \1:      MOVE.L (A1)+,D1
  133.              AND.L D1,(A0)
  134.              NOT.L (A0)+
  135.     \2:      DBF D0,\1
  136.            RTS
  137.  
  138. ; extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  139. nor_loop_up: ; Input in A0,A1,D0.W, verändert D1
  140.            BRA.S \2
  141.     \1:      MOVE.L (A1)+,D1
  142.              OR.L D1,(A0)
  143.              NOT.L (A0)+
  144.     \2:      DBF D0,\1
  145.            RTS
  146.  
  147. ; extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  148. andc2_loop_up: ; Input in A0,A1,D0.W, verändert D1
  149.            BRA.S \2
  150.     \1:      MOVE.L (A1)+,D1
  151.              NOT.L D1
  152.              AND.L D1,(A0)+
  153.     \2:      DBF D0,\1
  154.            RTS
  155.  
  156. ; extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  157. orc2_loop_up: ; Input in A0,A1,D0.W, verändert D1
  158.            BRA.S \2
  159.     \1:      MOVE.L (A1)+,D1
  160.              NOT.L D1
  161.              OR.L D1,(A0)+
  162.     \2:      DBF D0,\1
  163.            RTS
  164.  
  165. ; extern void not_loop_up (uintD* xptr, uintC count);
  166. not_loop_up: ; Input in A0,D0.W
  167.            BRA.S \2
  168.     \1:      NOT.L (A0)+
  169.     \2:      DBF D0,\1
  170.            RTS
  171.  
  172. ; extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
  173. and_test_loop_up: ; Input in A0,A1,D0.W, verändert D1, Output in D0.W=D0.L
  174.            BRA.S \2
  175.     \1:      MOVE.L (A0)+,D1
  176.              AND.L (A1)+,D1
  177.              BNE.S \3
  178.     \2:      DBF D0,\1
  179.            CLR.L D0
  180.            RTS
  181.     \3:    MOVEQ.L #1,D0
  182.            RTS
  183.  
  184. ; extern boolean test_loop_up (uintD* ptr, uintC count);
  185. test_loop_up: ; Input in A0,D0.W, Output in D0.W=D0.L
  186.            BRA.S \2
  187.     \1:      TST.L (A0)+
  188.              BNE.S \3
  189.     \2:      DBF D0,\1
  190.            CLR.L D0
  191.            RTS
  192.     \3:    MOVEQ.L #1,D0
  193.            RTS
  194.  
  195. ; extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
  196. compare_loop_up: ; Input in A0,A1,D0.W, Output in D0.W=D0.L
  197.            BRA.S \2
  198.     \1:      CMPM.L (A1)+,(A0)+
  199.              BNE.S \3
  200.     \2:      DBF D0,\1
  201.            CLR.L D0
  202.            RTS
  203.     \3:    BLO.S \4
  204.            MOVEQ.L #1,D0
  205.            RTS
  206.     \4:    MOVEQ.L #-1,D0
  207.            RTS
  208.  
  209. ; extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  210. add_loop_down: ; Input in A0,A1,A2,D0.W, verändert D1,D2, Output in D0
  211.            MOVE.L A2,-(SP)
  212.            ANDI #%01110,CCR   ; X-Bit löschen
  213.            BRA.S \2
  214.     \1:      MOVE.L -(A0),D1
  215.              MOVE.L -(A1),D2
  216.              ADDX.L D2,D1
  217.              MOVE.L D1,-(A2)
  218.     \2:      DBF D0,\1
  219.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  220.            MOVE.L (SP)+,A2
  221.            RTS
  222.  
  223. ; extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  224. addto_loop_down: ; Input in A0,A1,D0.W, Output in D0
  225.            ANDI #%01110,CCR   ; X-Bit löschen
  226.            BRA.S \2
  227.     \1:      ADDX.L -(A0),-(A1)
  228.     \2:      DBF D0,\1
  229.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  230.            RTS
  231.  
  232. ; extern uintD inc_loop_down (uintD* ptr, uintC count);
  233. inc_loop_down: ; Input in A0,D0.W, Output in D0
  234.            DBF D0,\1          ; simuliere gesetzten Carry
  235.            MOVEQ.L #-1,D0     ; D0.L=-1 für Übertrag
  236.            RTS
  237.     \1:      ADDQ.L #1,-(A0)
  238.              DBCC D0,\1
  239.            SUBX.L D0,D0       ; kein Carry -> D0.L=0, sonst D0.L=-1 für Übertrag
  240.            RTS
  241.  
  242. ; extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  243. sub_loop_down: ; Input in A0,A1,A2,D0.W, verändert D1,D2, Output in D0
  244.            MOVE.L A2,-(SP)
  245.            ANDI #%01110,CCR   ; X-Bit löschen
  246.            BRA.S \2
  247.     \1:      MOVE.L -(A0),D1
  248.              MOVE.L -(A1),D2
  249.              SUBX.L D2,D1
  250.              MOVE.L D1,-(A2)
  251.     \2:      DBF D0,\1
  252.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  253.            MOVE.L (SP)+,A2
  254.            RTS
  255.  
  256. ; extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
  257. subx_loop_down: ; Input in A0,A1,A2,D0.W,D1, verändert D2, Output in D0
  258.            MOVE.L A2,-(SP)
  259.            ROXR.L #1,D1       ; X-Bit initialisieren
  260.            BRA.S \2
  261.     \1:      MOVE.L -(A0),D1
  262.              MOVE.L -(A1),D2
  263.              SUBX.L D2,D1
  264.              MOVE.L D1,-(A2)
  265.     \2:      DBF D0,\1
  266.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  267.            MOVE.L (SP)+,A2
  268.            RTS
  269.  
  270. ; extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  271. subfrom_loop_down: ; Input in A0,A1,D0.W, Output in D0
  272.            ANDI #%01110,CCR   ; X-Bit löschen
  273.            BRA.S \2
  274.     \1:      SUBX.L -(A0),-(A1)
  275.     \2:      DBF D0,\1
  276.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  277.            RTS
  278.  
  279. ; extern uintD dec_loop_down (uintD* ptr, uintC count);
  280. dec_loop_down: ; Input in A0,D0.W, Output in D0
  281.            DBF D0,\1          ; simuliere gesetzten Carry
  282.            MOVEQ.L #-1,D0     ; D0.L=-1 als Übertrag
  283.            RTS
  284.     \1:      SUBQ.L #1,-(A0)
  285.              DBCC D0,\1       ; kein Carry -> Schleife abbrechen
  286.            SUBX.L D0,D0       ; kein Carry -> D0.L=0, sonst D0.L=-1 als Übertrag
  287.            RTS
  288.  
  289. ; extern uintD neg_loop_down (uintD* ptr, uintC count);
  290. neg_loop_down: ; Input in A0,D0.W, Output in D0
  291.            ANDI #%01110,CCR   ; X-Bit löschen
  292.            BRA.S \2
  293.     \1:      NEGX.L -(A0)
  294.     \2:      DBF D0,\1
  295.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  296.            RTS
  297.  
  298. ; extern uintD shift1left_loop_down (uintD* ptr, uintC count);
  299. shift1left_loop_down: ; Input in A0,D0.W, Output in D0.L
  300.            ANDI #%01110,CCR   ; X-Bit löschen
  301.            BRA.S \2
  302.     \1:      ROXL.W -(A0)     ; Digit -(A0) um 1 Bit links schieben, X-Bit als Buffer
  303.              ROXL.W -(A0)
  304.     \2:      DBF D0,\1
  305.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  306.            RTS
  307.  
  308. ; extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
  309. shiftleft_loop_down: ; Input in A0,D0.W,D1.W,D2, Output in D0
  310. #if 1
  311.            MOVEM.L D3-D5,-(SP)
  312.            MOVEQ.L #32,D5
  313.            SUB.W D1,D5
  314.            ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i,
  315.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  316.            BRA.S \2
  317.     \1:      MOVE.L -(A0),D3  ; D3.L = neues Digit
  318.              MOVE.L D3,D4
  319.              LSL.L D1,D4      ; um i Bits nach links schieben
  320.              OR.L D2,D4       ; mit vorigem Übertrag kombinieren
  321.              MOVE.L D4,(A0)   ; 32 Bits ablegen
  322.              MOVE.L D3,D2
  323.              LSR.L D5,D2      ; neuen Übertrag bilden
  324.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  325.            MOVE.L D2,D0
  326.            MOVEM.L (SP)+,D3-D5
  327.            RTS
  328. #else
  329.            MOVEM.L D3-D5,-(SP)
  330.            MOVEQ.L #1,D5
  331.            LSL.L D1,D5
  332.            SUBQ.L #1,D5
  333.            ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^i-1
  334.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  335.            BRA.S \2
  336.     \1:      MOVE.L -(A0),D3  ; D3.L = neues Digit
  337.              ROL.L D1,D3      ; um i Bits links rotieren
  338.              MOVE.L D3,D4
  339.              AND.L D5,D3      ; untere i Bits in D3
  340.              EOR.L D3,D4      ; obere 32-i Bits in D4
  341.              OR.L D2,D4       ; mit vorigem übertrag kombinieren
  342.              MOVE.L D4,(A0)   ; 32 Bits ablegen
  343.              MOVE.L D3,D2     ; neuer Übertrag
  344.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  345.            MOVE.L D2,D0
  346.            MOVEM.L (SP)+,D3-D5
  347.            RTS
  348. #endif
  349.  
  350. ; extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
  351. shiftleftcopy_loop_down: ; Input in A0,A1,D0.W,D1.W, Output in D0
  352. #if 1
  353.            MOVEM.L D3-D5,-(SP)
  354.            MOVEQ.L #32,D5
  355.            SUB.W D1,D5
  356.            CLR.L D2
  357.            ; A0 = sourceptr, A1 = destptr, D0.W = count, D1.W = i, D5.W = 32-i,
  358.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  359.            BRA.S \2
  360.     \1:      MOVE.L -(A0),D3  ; D3.L = neues Digit
  361.              MOVE.L D3,D4
  362.              LSL.L D1,D4      ; um i Bits nach links schieben
  363.              OR.L D2,D4       ; mit vorigem Übertrag kombinieren
  364.              MOVE.L D4,-(A1)  ; 32 Bits ablegen
  365.              MOVE.L D3,D2
  366.              LSR.L D5,D2      ; neuen Übertrag bilden
  367.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  368.            MOVE.L D2,D0
  369.            MOVEM.L (SP)+,D3-D5
  370.            RTS
  371. #else
  372.            MOVEM.L D3-D5,-(SP)
  373.            MOVEQ.L #1,D5
  374.            LSL.L D1,D5
  375.            SUBQ.L #1,D5
  376.            ; A0 = sourceptr, A1 = destptr, D0.W = count, D1.W = i, D5.L = 2^i-1
  377.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  378.            BRA.S \2
  379.     \1:      MOVE.L -(A0),D3  ; D3.L = neues Digit
  380.              ROL.L D1,D3      ; um i Bits links rotieren
  381.              MOVE.L D3,D4
  382.              AND.L D5,D3      ; untere i Bits in D3
  383.              EOR.L D3,D4      ; obere 32-i Bits in D4
  384.              OR.L D2,D4       ; mit vorigem übertrag kombinieren
  385.              MOVE.L D4,-(A1)  ; 32 Bits ablegen
  386.              MOVE.L D3,D2     ; neuer Übertrag
  387.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  388.            MOVE.L D2,D0
  389.            MOVEM.L (SP)+,D3-D5
  390.            RTS
  391. #endif
  392.  
  393. ; extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
  394. shift1right_loop_up: ; Input in A0,D0.W,D1, Output in D0
  395.            ROXR.L #1,D1       ; X-Bit löschen oder setzen, je nach D1
  396.            BRA.S \2
  397.     \1:      ROXR.W (A0)+     ; Digit (A0)+ um 1 Bit rechts schieben, X-Bit als Buffer
  398.              ROXR.W (A0)+
  399.     \2:      DBF D0,\1
  400.            SUBX.L D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  401.            RTS
  402.  
  403. ; extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
  404. shiftright_loop_up: ; Input in A0,D0.W,D1.W, Output in D0
  405. #if 1
  406.            MOVEM.L D3-D5,-(SP)
  407.            MOVEQ.L #32,D5
  408.            SUB.W D1,D5
  409.            ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i,
  410.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  411.            CLR.L D2
  412.            BRA.S \2
  413.     \1:      ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.W = 32-i,
  414.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  415.              ; D3.L = Schiebe-Akku
  416.              MOVE.L (A0),D3   ; neue Daten
  417.              MOVE.L D3,D4
  418.              LSR.L D1,D3      ; um i Bits rechts schieben
  419.              OR.L D2,D3       ; und mit vorigem Übertrag kombinieren
  420.              MOVE.L D3,(A0)+  ; ablegen
  421.              LSL.L D5,D4      ; um (32-i) Bits links geschoben
  422.              MOVE.L D4,D2     ; liefert neuen Übertrag
  423.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  424.            MOVE.L D2,D0
  425.            MOVEM.L (SP)+,D3-D5
  426.            RTS
  427. #else
  428.            MOVEM.L D3-D5,-(SP)
  429.            MOVEQ.L #-1,D5
  430.            LSR.L D1,D5
  431.            ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^(32-i)-1,
  432.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  433.            CLR.L D2
  434.            BRA.S \2
  435.     \1:      ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.L = 2^(32-i)-1,
  436.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  437.              ; D3.L = Schiebe-Akku
  438.              MOVE.L (A0),D3   ; neue Daten
  439.              ROR.L D1,D3      ; um i Bits rechts rotieren
  440.              MOVE.L D3,D4
  441.              AND.L D5,D3      ; untere 32-i Bits
  442.              EOR.L D3,D4      ; obere i Bits
  443.              OR.L D2,D3       ; und mit vorigem Übertrag kombinieren
  444.              MOVE.L D4,D2     ; neuer Übertrag
  445.              MOVE.L D3,(A0)+  ; ablegen
  446.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  447.            MOVE.L D2,D0
  448.            MOVEM.L (SP)+,D3-D5
  449.            RTS
  450. #endif
  451.  
  452. ; extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
  453. shiftrightsigned_loop_up: ; Input in A0,D0.W,D1.W, Output in D0
  454. #if 1
  455.            MOVEM.L D3-D5,-(SP)
  456.            MOVEQ.L #32,D5
  457.            SUB.W D1,D5
  458.            ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i,
  459.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  460.            SUBQ.W #1,D0
  461.            MOVE.L (A0),D3     ; erstes Digit
  462.            MOVE.L D3,D4
  463.            ASR.L D1,D3        ; um i Bits rechts schieben
  464.            BRA.S \2
  465.     \1:      ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.W = 32-i,
  466.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  467.              ; D3.L = Schiebe-Akku
  468.              MOVE.L (A0),D3   ; neue Daten
  469.              MOVE.L D3,D4
  470.              LSR.L D1,D3      ; um i Bits rechts schieben
  471.              OR.L D2,D3       ; und mit vorigem Übertrag kombinieren
  472.     \2:      MOVE.L D3,(A0)+  ; ablegen
  473.              LSL.L D5,D4      ; um (32-i) Bits links geschoben
  474.              MOVE.L D4,D2     ; liefert neuen Übertrag
  475.              DBF D0,\1        ; Schleife D0.W mal durchlaufen
  476.            MOVE.L D2,D0
  477.            MOVEM.L (SP)+,D3-D5
  478.            RTS
  479. #else
  480.            MOVEM.L D3-D5,-(SP)
  481.            MOVEQ.L #-1,D5
  482.            LSR.L D1,D5
  483.            ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^(32-i)-1,
  484.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  485.            SUBQ.W #1,D0
  486.            MOVE.L (A0),D3     ; erstes Digit
  487.            MOVE.L D3,D4
  488.            ROR.L D1,D4        ; um i Bits rechts rotieren
  489.            MOVE.L D5,D2
  490.            NOT.L D2
  491.            AND.L D4,D2        ; obere 32-i Bits
  492.            ASR.L D1,D3        ; erstes Digit um i Bits rechts shiften
  493.            BRA.S \2
  494.     \1:      ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.L = 2^(32-i)-1,
  495.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  496.              ; D3.L = Schiebe-Akku
  497.              MOVE.L (A0),D3   ; neue Daten
  498.              ROR.L D1,D3      ; um i Bits rechts rotieren
  499.              MOVE.L D3,D4
  500.              AND.L D5,D3      ; untere 32-i Bits
  501.              EOR.L D3,D4      ; obere i Bits
  502.              OR.L D2,D3       ; und mit vorigem Übertrag kombinieren
  503.              MOVE.L D4,D2     ; neuer Übertrag
  504.     \2:      MOVE.L D3,(A0)+  ; ablegen
  505.              DBF D0,\1        ; Schleife D0.W mal durchlaufen
  506.            MOVE.L D2,D0
  507.            MOVEM.L (SP)+,D3-D5
  508.            RTS
  509. #endif
  510.  
  511. ; extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
  512. shiftrightcopy_loop_up: ; Input in A0,A1,D0.W,D1.W,D2, Output in D0
  513. #if 1
  514.            MOVEM.L D3-D5,-(SP)
  515.            MOVEQ.L #32,D5
  516.            SUB.W D1,D5
  517.            ; A0 = ptr, D0.W = count, D1.W = i, D5.W = 32-i
  518.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  519.            BRA.S \2
  520.     \1:      ; A0,A1 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.W = 32-i
  521.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  522.              ; D3.L = Schiebe-Akku
  523.              MOVE.L (A0)+,D3  ; neue Daten
  524.              MOVE.L D3,D4
  525.              LSR.L D1,D3      ; um i Bits rechts schieben
  526.              OR.L D2,D3       ; und mit vorigem Übertrag kombinieren
  527.              MOVE.L D3,(A1)+  ; ablegen
  528.              MOVE.L D4,D2
  529.     \2:      LSL.L D5,D2      ; um (32-i) Bits links geschoben, gibt neuen Übertrag
  530.              DBF D0,\1        ; Schleife D0.W mal durchlaufen
  531.            MOVE.L D2,D0
  532.            MOVEM.L (SP)+,D3-D5
  533.            RTS
  534. #else
  535.            MOVEM.L D3-D5,-(SP)
  536.            MOVEQ.L #-1,D5
  537.            LSR.L D1,D5
  538.            ROR.L D1,D2
  539.            ; A0 = ptr, D0.W = count, D1.W = i, D5.L = 2^(32-i)-1
  540.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  541.            BRA.S \2
  542.     \1:      ; A0,A1 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i, D5.L = 2^(32-i)-1
  543.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  544.              ; D3.L = Schiebe-Akku
  545.              MOVE.L (A0)+,D3  ; neue Daten
  546.              ROR.L D1,D3      ; um i Bits rechts rotieren
  547.              MOVE.L D3,D4
  548.              AND.L D5,D3      ; untere 32-i Bits
  549.              EOR.L D3,D4      ; obere i Bits
  550.              OR.L D2,D3       ; und mit vorigem Übertrag kombinieren
  551.              MOVE.L D4,D2     ; neuer Übertrag
  552.              MOVE.L D3,(A1)+  ; ablegen
  553.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  554.            MOVE.L D2,D0
  555.            MOVEM.L (SP)+,D3-D5
  556.            RTS
  557. #endif
  558.  
  559. ; extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
  560. mulusmall_loop_down: # Input in D0,A0,D1.W,D2, Output in D0
  561.            MOVEM.L D3-D4,-(SP)
  562.            ADD.W #0,D1        ; X-Bit löschen
  563.            BRA.S \2
  564.     \1:      MOVE.L -(A0),D3  ; nächstes Digit
  565.              MULU.L D0,D4:D3  ; mit digit multiplizieren
  566.              ADDX.L D2,D3     ; und bisherigen Carry und X-Bit addieren
  567.              MOVE.L D3,(A0)   ; Low-Digit ablegen
  568.              MOVE.L D4,D2     ; High-Digit gibt neuen Carry
  569.     \2:      DBF D1,\1
  570.            CLR.L D0
  571.            ADDX.L D2,D0       ; letzter Carry (incl. X-Bit)
  572.            MOVEM.L (SP)+,D3-D4
  573.            RTS
  574.  
  575. ; extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  576. mulu_loop_down: ; Input in D0,A0,A1,D1.W
  577. #if 1
  578.            MOVEM.L D3-D4,-(SP)
  579.            SUB.L D2,D2        ; carry := 0, X-Bit löschen
  580.            BRA.S \2
  581.     \1:      MOVE.L -(A0),D3  ; nächstes Digit
  582.              MULU.L D0,D4:D3  ; mit digit multiplizieren
  583.              ADDX.L D2,D3     ; und bisherigen Carry und X-Bit addieren
  584.              MOVE.L D3,-(A1)  ; Low-Digit ablegen
  585.              MOVE.L D4,D2     ; High-Digit gibt neuen Carry
  586.     \2:      DBF D1,\1
  587.            CLR.L D3
  588.            ADDX.L D3,D2       ; letztes X-Bit verarbeiten
  589.            MOVE.L D2,-(A1)    ; letzten Carry ablegen
  590.            MOVEM.L (SP)+,D3-D4
  591.            RTS
  592. #else
  593.            MOVEM.L D3-D5,-(SP)
  594.            CLR.L D5           ; 0
  595.            CLR.L D2           ; carry
  596.            BRA.S \2
  597.     \1:      MOVE.L -(A0),D3  ; nächstes Digit
  598.              MULU.L D0,D4:D3  ; mit digit multiplizieren
  599.              ADD.L D2,D3      ; und bisherigen Carry addieren
  600.              ADDX.L D5,D4
  601.              MOVE.L D3,-(A1)  ; Low-Digit ablegen
  602.              MOVE.L D4,D2     ; High-Digit gibt neuen Carry
  603.     \2:      DBF D1,\1
  604.            MOVE.L D2,-(A1)    ; letzten Carry ablegen
  605.            MOVEM.L (SP)+,D3-D5
  606.            RTS
  607. #endif
  608.  
  609. ; extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  610. muluadd_loop_down: ; Input in D0,A0,A1,D1.W, Output in D0
  611.            MOVEM.L D3-D5,-(SP)
  612.            CLR.L D5           ; 0
  613.            SUB.L D2,D2        ; carry := 0, X-Bit löschen
  614.            BRA.S \2
  615.     \1:      MOVE.L -(A0),D3  ; nächstes Digit
  616.              MULU.L D0,D4:D3  ; mit digit multiplizieren
  617.              ADDX.L D2,D3     ; und bisherigen Carry und X-Bit addieren
  618.              ADDX.L D5,D4
  619.              ADD.L D3,-(A1)   ; Low-Digit zum dest-Digit addieren, X als Übertrag
  620.              MOVE.L D4,D2     ; High-Digit gibt neuen Carry
  621.     \2:      DBF D1,\1
  622.            ADDX.L D5,D2       ; letztes X-Bit addieren
  623.            MOVE.L D2,D0       ; letzten Carry als Ergebnis
  624.            MOVEM.L (SP)+,D3-D5
  625.            RTS
  626.  
  627. ; extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  628. mulusub_loop_down: ; Input in D0,A0,A1,D1.W, Output in D0
  629.            MOVEM.L D3-D5,-(SP)
  630.            CLR.L D5           ; 0
  631.            SUB.L D2,D2        ; carry := 0, X-Bit löschen
  632.            BRA.S \2
  633.     \1:      MOVE.L -(A0),D3  ; nächstes Digit
  634.              MULU.L D0,D4:D3  ; mit digit multiplizieren
  635.              ADDX.L D2,D3     ; und bisherigen Carry und X-Bit addieren
  636.              ADDX.L D5,D4
  637.              SUB.L D3,-(A1)   ; Low-Digit vom dest-Digit subtrahieren, X als Übertrag
  638.              MOVE.L D4,D2     ; High-Digit gibt neuen Carry
  639.     \2:      DBF D1,\1
  640.            CLR.L D0
  641.            ADDX.L D2,D0       ; letzter Carry und letztes X-Bit
  642.            MOVEM.L (SP)+,D3-D5
  643.            RTS
  644.  
  645. ; extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
  646. divu_loop_up: # Input in D0,A0,D1.W, Output in D0
  647.            MOVE.L D3,-(SP)
  648.            CLR.L D2           ; Rest := 0
  649.            BRA.S \2
  650.     \1:      MOVE.L (A0),D3   ; nächst-niedriges Digit
  651.              DIVU.L D0,D2:D3  ; mit Rest kombinieren und durch digit dividieren
  652.              MOVE.L D3,(A0)+  ; Quotient ablegen, Rest in D2
  653.     \2:      DBF D1,\1
  654.            MOVE.L D2,D0       ; Rest
  655.            MOVE.L (SP)+,D3
  656.            RTS
  657.  
  658. ; extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  659. divucopy_loop_up: # Input in D0,A0,A1,D1.W, Output in D0
  660.            MOVE.L D3,-(SP)
  661.            CLR.L D2           ; Rest := 0
  662.            BRA.S \2
  663.     \1:      MOVE.L (A0)+,D3  ; nächst-niedriges Digit
  664.              DIVU.L D0,D2:D3  ; mit Rest kombinieren und durch digit dividieren
  665.              MOVE.L D3,(A1)+  ; Quotient ablegen, Rest in D2
  666.     \2:      DBF D1,\1
  667.            MOVE.L D2,D0       ; Rest
  668.            MOVE.L (SP)+,D3
  669.            RTS
  670.  
  671.           .end
  672.  
  673. #endif
  674.  
  675.