home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-1.LHA / CLISP960530-sr.lha / src / ari68000.mot.d < prev    next >
Encoding:
Text File  |  1996-04-15  |  23.3 KB  |  630 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=16.
  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_
  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.            MOVE.L D3,A0
  41.            MOVE.L D4,A1
  42.            ; D0.L = 2^16*a+b, D1.L = 2^16*c+d -> Produkt
  43.            ; (2^16*a+b)*(2^16*c+d) = 2^32*a*c + 2^16*(a*d+b*c) + b*d
  44.            MOVE.L D0,D2
  45.            SWAP D2      ; D2.W = a
  46.            MOVE.L D1,D3
  47.            SWAP D1      ; D1.W = c
  48.            MOVE.L D1,D4
  49.            MULU D2,D1   ; D1.L = a*c
  50.            MULU D3,D2   ; D2.L = a*d
  51.            MULU D0,D4   ; D4.L = b*c
  52.            MULU D3,D0   ; D0.L = b*d
  53.            CLR.L D3     ; Hilfsregister für Zero-Extend
  54.            SWAP D2
  55.            MOVE.W D2,D3
  56.            ADD.L D3,D1  ; high16(a*d) zu D1.L addieren
  57.            SWAP D4
  58.            MOVE.W D4,D3
  59.            ADD.L D3,D1  ; high16(b*c) zu D1.L addieren
  60.            CLR.W D2
  61.            ADD.L D2,D0  ; 2^16*low16(a*d) zu D0.L addieren
  62.            BCC.S \1
  63.            ADDQ.L #1,D1
  64.     \1:    CLR.W D4
  65.            ADD.L D4,D0  ; 2^16*low16(b*c) zu D0.L addieren
  66.            BCC.S \2
  67.            ADDQ.L #1,D1
  68.     \2:    ; D0.L = lo, D1.L = hi fertig.
  69.            MOVE.L D1,(mulu32_high) ; Adressierung?? Deklaration??
  70.            MOVE.L A1,D4
  71.            MOVE.L A0,D3
  72.            RTS
  73.  
  74. ; extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
  75. copy_loop_up: ; Input in A0,A1,D0.W, Output in A0
  76.            BRA.S \2
  77.     \1:      MOVE.W (A0)+,(A1)+
  78.     \2:      DBF D0,\1
  79.            MOVE.L A1,A0
  80.            RTS
  81.  
  82. ; extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  83. copy_loop_down: ; Input in A0,A1,D0.W, Output in A0
  84.            BRA.S \2
  85.     \1:      MOVE.W -(A0),-(A1)
  86.     \2:      DBF D0,\1
  87.            MOVE.L A1,A0
  88.            RTS
  89.  
  90. ; extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
  91. fill_loop_up: ; Input in A0,D0.W,D1.W, Output in A0
  92.            BRA.S \2
  93.     \1:      MOVE.W D1,(A0)+
  94.     \2:      DBF D0,\1
  95.            RTS
  96.  
  97. ; extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
  98. fill_loop_down: ; Input in A0,D0.W,D1.W, Output in A0
  99.            BRA.S \2
  100.     \1:      MOVE.W D1,-(A0)
  101.     \2:      DBF D0,\1
  102.            RTS
  103.  
  104. ; extern uintD* clear_loop_up (uintD* destptr, uintC count);
  105. clear_loop_up: ; Input in A0,D0.W, verändert D1, Output in A0
  106.            MOVEQ.L #0,D1
  107.            BRA.S \2
  108.     \1:      MOVE.W D1,(A0)+
  109.     \2:      DBF D0,\1
  110.            RTS
  111.  
  112. ; extern uintD* clear_loop_down (uintD* destptr, uintC count);
  113. clear_loop_down: ; Input in A0,D0.W, verändert D1, Output in A0
  114.            MOVEQ.L #0,D1
  115.            BRA.S \2
  116.     \1:      MOVE.W D1,-(A0)
  117.     \2:      DBF D0,\1
  118.            RTS
  119.  
  120. ; extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
  121. or_loop_up: ; Input in A0,A1,D0.W, verändert D1
  122.            BRA.S \2
  123.     \1:      MOVE.W (A1)+,D1
  124.              OR.W D1,(A0)+
  125.     \2:      DBF D0,\1
  126.            RTS
  127.  
  128. ; extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  129. xor_loop_up: ; Input in A0,A1,D0.W, verändert D1
  130.            BRA.S \2
  131.     \1:      MOVE.W (A1)+,D1
  132.              EOR.W D1,(A0)+
  133.     \2:      DBF D0,\1
  134.            RTS
  135.  
  136. ; extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
  137. and_loop_up: ; Input in A0,A1,D0.W, verändert D1
  138.            BRA.S \2
  139.     \1:      MOVE.W (A1)+,D1
  140.              AND.W D1,(A0)+
  141.     \2:      DBF D0,\1
  142.            RTS
  143.  
  144. ; extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
  145. eqv_loop_up: ; Input in A0,A1,D0.W, verändert D1
  146.            BRA.S \2
  147.     \1:      MOVE.W (A1)+,D1
  148.              EOR.W D1,(A0)
  149.              NOT.W (A0)+
  150.     \2:      DBF D0,\1
  151.            RTS
  152.  
  153. ; extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
  154. nand_loop_up: ; Input in A0,A1,D0.W, verändert D1
  155.            BRA.S \2
  156.     \1:      MOVE.W (A1)+,D1
  157.              AND.W D1,(A0)
  158.              NOT.W (A0)+
  159.     \2:      DBF D0,\1
  160.            RTS
  161.  
  162. ; extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  163. nor_loop_up: ; Input in A0,A1,D0.W, verändert D1
  164.            BRA.S \2
  165.     \1:      MOVE.W (A1)+,D1
  166.              OR.W D1,(A0)
  167.              NOT.W (A0)+
  168.     \2:      DBF D0,\1
  169.            RTS
  170.  
  171. ; extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  172. andc2_loop_up: ; Input in A0,A1,D0.W, verändert D1
  173.            BRA.S \2
  174.     \1:      MOVE.W (A1)+,D1
  175.              NOT.W D1
  176.              AND.W D1,(A0)+
  177.     \2:      DBF D0,\1
  178.            RTS
  179.  
  180. ; extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  181. orc2_loop_up: ; Input in A0,A1,D0.W, verändert D1
  182.            BRA.S \2
  183.     \1:      MOVE.W (A1)+,D1
  184.              NOT.W D1
  185.              OR.W D1,(A0)+
  186.     \2:      DBF D0,\1
  187.            RTS
  188.  
  189. ; extern void not_loop_up (uintD* xptr, uintC count);
  190. not_loop_up: ; Input in A0,D0.W
  191.            BRA.S \2
  192.     \1:      NOT.W (A0)+
  193.     \2:      DBF D0,\1
  194.            RTS
  195.  
  196. ; extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
  197. and_test_loop_up: ; Input in A0,A1,D0.W, verändert D1, Output in D0.W=D0.L
  198.            BRA.S \2
  199.     \1:      MOVE.W (A0)+,D1
  200.              AND.W (A1)+,D1
  201.              BNE.S \3
  202.     \2:      DBF D0,\1
  203.            CLR.L D0
  204.            RTS
  205.     \3:    MOVEQ.L #1,D0
  206.            RTS
  207.  
  208. ; extern boolean test_loop_up (uintD* ptr, uintC count);
  209. test_loop_up: ; Input in A0,D0.W, Output in D0.W=D0.L
  210.            BRA.S \2
  211.     \1:      TST.W (A0)+
  212.              BNE.S \3
  213.     \2:      DBF D0,\1
  214.            CLR.L D0
  215.            RTS
  216.     \3:    MOVEQ.L #1,D0
  217.            RTS
  218.  
  219. ; extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
  220. compare_loop_up: ; Input in A0,A1,D0.W, Output in D0.W=D0.L
  221.            BRA.S \2
  222.     \1:      CMPM.W (A1)+,(A0)+
  223.              BNE.S \3
  224.     \2:      DBF D0,\1
  225.            CLR.L D0
  226.            RTS
  227.     \3:    BLO.S \4
  228.            MOVEQ.L #1,D0
  229.            RTS
  230.     \4:    MOVEQ.L #-1,D0
  231.            RTS
  232.  
  233. ; extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  234. add_loop_down: ; Input in A0,A1,A2,D0.W, verändert D1,D2, Output in D0.W
  235.            MOVE.L A2,-(SP)
  236.            ANDI #%01110,CCR   ; X-Bit löschen
  237.            BRA.S \2
  238.     \1:      MOVE.W -(A0),D1
  239.              MOVE.W -(A1),D2
  240.              ADDX.W D2,D1
  241.              MOVE.W D1,-(A2)
  242.     \2:      DBF D0,\1
  243.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  244.            MOVE.L (SP)+,A2
  245.            RTS
  246.  
  247. ; extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  248. addto_loop_down: ; Input in A0,A1,D0.W, Output in D0.W
  249.            ANDI #%01110,CCR   ; X-Bit löschen
  250.            BRA.S \2
  251.     \1:      ADDX.W -(A0),-(A1)
  252.     \2:      DBF D0,\1
  253.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  254.            RTS
  255.  
  256. ; extern uintD inc_loop_down (uintD* ptr, uintC count);
  257. inc_loop_down: ; Input in A0,D0.W, Output in D0.W
  258.            DBF D0,\1          ; simuliere gesetzten Carry
  259.                               ; D0.W=-1 für Übertrag
  260.            RTS
  261.     \1:      ADDQ.W #1,-(A0)
  262.              DBCC D0,\1       ; kein Carry -> Schleife abbrechen
  263.            SUBX.W D0,D0       ; kein Carry -> D0.W=0, sonst D0.W=-1 für Übertrag
  264.            RTS
  265.  
  266. ; extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  267. sub_loop_down: ; Input in A0,A1,A2,D0.W, verändert D1,D2, Output in D0.W
  268.            MOVE.L A2,-(SP)
  269.            ANDI #%01110,CCR   ; X-Bit löschen
  270.            BRA.S \2
  271.     \1:      MOVE.W -(A0),D1
  272.              MOVE.W -(A1),D2
  273.              SUBX.W D2,D1
  274.              MOVE.W D1,-(A2)
  275.     \2:      DBF D0,\1
  276.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  277.            MOVE.L (SP)+,A2
  278.            RTS
  279.  
  280. ; extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
  281. subx_loop_down: ; Input in A0,A1,A2,D0.W,D1.W, verändert D2, Output in D0.W
  282.            MOVE.L A2,-(SP)
  283.            ROXR.W #1,D1       ; X-Bit initialisieren
  284.            BRA.S \2
  285.     \1:      MOVE.W -(A0),D1
  286.              MOVE.W -(A1),D2
  287.              SUBX.W D2,D1
  288.              MOVE.W D1,-(A2)
  289.     \2:      DBF D0,\1
  290.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  291.            MOVE.L (SP)+,A2
  292.            RTS
  293.  
  294. ; extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  295. subfrom_loop_down: ; Input in A0,A1,D0.W, Output in D0.W
  296.            ANDI #%01110,CCR   ; X-Bit löschen
  297.            BRA.S \2
  298.     \1:      SUBX.W -(A0),-(A1)
  299.     \2:      DBF D0,\1
  300.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  301.            RTS
  302.  
  303. ; extern uintD dec_loop_down (uintD* ptr, uintC count);
  304. dec_loop_down: ; Input in A0,D0.W, Output in D0.W
  305.            DBF D0,\1          ; simuliere gesetzten Carry
  306.                               ; D0.W=-1 als Übertrag
  307.            RTS
  308.     \1:      SUBQ.W #1,-(A0)
  309.              DBCC D0,\1       ; kein Carry -> Schleife abbrechen
  310.            SUBX.W D0,D0       ; kein Carry -> D0.W=0, sonst D0.W=-1 als Übertrag
  311.            RTS
  312.  
  313. ; extern uintD neg_loop_down (uintD* ptr, uintC count);
  314. neg_loop_down: ; Input in A0,D0.W, Output in D0.W
  315.            ANDI #%01110,CCR   ; X-Bit löschen
  316.            BRA.S \2
  317.     \1:      NEGX.W -(A0)
  318.     \2:      DBF D0,\1
  319.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  320.            RTS
  321.  
  322. ; extern uintD shift1left_loop_down (uintD* ptr, uintC count);
  323. shift1left_loop_down: ; Input in A0,D0.W, Output in D0.W
  324.            ANDI #%01110,CCR   ; X-Bit löschen
  325.            BRA.S \2
  326.     \1:      ROXL.W -(A0)     ; Digit -(A0) um 1 Bit links schieben, X-Bit als Buffer
  327.     \2:      DBF D0,\1
  328.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  329.            RTS
  330.  
  331. ; extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
  332. shiftleft_loop_down: ; Input in A0,D0.W,D1.W,D2.W, Output in D0.W
  333.            MOVE.L D3,-(SP)
  334.            ; A0 = ptr, D0.W = count, D1.W = i,
  335.            ; D2.W = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  336.            BRA.S \2
  337.     \1:      CLR.L D3
  338.              MOVE.W -(A0),D3  ; D3.L = D3.W = neues Digit
  339.              LSL.L D1,D3      ; um i Bits nach links schieben
  340.              OR.W D2,D3       ; D3 enthält die letzten 16+i Bits
  341.              MOVE.W D3,(A0)   ; 16 Bits ablegen
  342.              SWAP D3
  343.              MOVE.W D3,D2     ; neuen Übertrag bilden
  344.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  345.            MOVE.W D2,D0
  346.            MOVE.L (SP)+,D3
  347.            RTS
  348.  
  349. ; extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
  350. shiftleftcopy_loop_down: ; Input in A0,A1,D0.W,D1.W, Output in D0.W
  351.            MOVE.L D3,-(SP)
  352.            CLR.W D2
  353.            ; A0 = sourceptr, A1 = destptr, D0.W = count, D1.W = i,
  354.            ; D2.W = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  355.            BRA.S \2
  356.     \1:      CLR.L D3
  357.              MOVE.W -(A0),D3  ; D3.L = D3.W = neues Digit
  358.              LSL.L D1,D3      ; um i Bits nach links schieben
  359.              OR.W D2,D3       ; D3 enthält die letzten 16+i Bits
  360.              MOVE.W D3,-(A1)  ; 16 Bits ablegen
  361.              SWAP D3
  362.              MOVE.W D3,D2     ; neuen Übertrag bilden
  363.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  364.            MOVE.W D2,D0
  365.            MOVE.L (SP)+,D3
  366.            RTS
  367.  
  368. ; extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
  369. shift1right_loop_up: ; Input in A0,D0.W,D1.W, Output in D0.W
  370.            ROXR.W #1,D1       ; X-Bit löschen oder setzen, je nach D1.W
  371.            BRA.S \2
  372.     \1:      ROXR.W (A0)+     ; Digit (A0)+ um 1 Bit rechts schieben, X-Bit als Buffer
  373.     \2:      DBF D0,\1
  374.            SUBX.W D0,D0       ; -1 falls X gesetzt, 0 falls X gelöscht
  375.            RTS
  376.  
  377. ; extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
  378. shiftright_loop_up: ; Input in A0,D0.W,D1.W, Output in D0.W
  379.            MOVE.L D3,-(SP)
  380.            ; A0 = ptr, D0.W = count, D1.W = i,
  381.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  382.            CLR.L D2           ; Übertrag = 0
  383.            BRA.S \2
  384.     \1:      ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i,
  385.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  386.              ; D3.L = Schiebe-Akku
  387.              CLR.L D3
  388.              MOVE.W (A0),D3   ; neue Daten
  389.              SWAP D3          ; nach Bit 31..16(D3), D3.W = 0
  390.              LSR.L D1,D3      ; Bits 31-i..16-i(D3) sind die neuen Daten
  391.              OR.L D3,D2       ; Bits 31..16-i(D3) sind die bisherigen Daten
  392.              SWAP D2          ; untere 16 Bit ergeben neuen Übertrag,
  393.              MOVE.W D2,(A0)+  ; obere 16 Bit werden abgespeichert
  394.              CLR.W D2         ; D2.L = neuer Übertrag
  395.     \2:      DBF D0,\1        ; Schleife D0.W mal durchlaufen
  396.            SWAP D2
  397.            MOVE.W D2,D0
  398.            MOVE.L (SP)+,D3
  399.            RTS
  400.  
  401. ; extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
  402. shiftrightsigned_loop_up: ; Input in A0,D0.W,D1.W, Output in D0.W
  403.            MOVE.L D3,-(SP)
  404.            ; A0 = ptr, D0.W = count, D1.W = i,
  405.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  406.            MOVE.W (A0),D2     ; erstes Digit
  407.            EXT.L D2           ; Vorzeichenbit nach Bit 31..16(D2)
  408.            CLR.W D2           ; Rest von D2.L löschen
  409.            LSR.L D1,D2        ; D2.W enthält in seinen oberen i Bits das Vorzeichen
  410.            SWAP D2            ; Übertrag mit i Vorzeichenbits initialisiert
  411.            BRA.S \2
  412.     \1:      ; A0 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i,
  413.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  414.              ; D3.L = Schiebe-Akku
  415.              CLR.L D3
  416.              MOVE.W (A0),D3   ; neue Daten
  417.              SWAP D3          ; nach Bit 31..16(D3), D3.W = 0
  418.              LSR.L D1,D3      ; Bits 31-i..16-i(D3) sind die neuen Daten
  419.              OR.L D3,D2       ; Bits 31..16-i(D3) sind die bisherigen Daten
  420.              SWAP D2          ; untere 16 Bit ergeben neuen Übertrag,
  421.              MOVE.W D2,(A0)+  ; obere 16 Bit werden abgespeichert
  422.     \2:      CLR.W D2         ; D2.L = neuer Übertrag
  423.              DBF D0,\1        ; Schleife D0.W mal durchlaufen
  424.            SWAP D2
  425.            MOVE.W D2,D0
  426.            MOVE.L (SP)+,D3
  427.            RTS
  428.  
  429. ; extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
  430. shiftrightcopy_loop_up: ; Input in A0,A1,D0.W,D1.W,D2.W, Output in D0.W
  431.            MOVE.L D3,-(SP)
  432.            ; A0 = ptr, D0.W = count, D1.W = i,
  433.            ; D2.L = Schiebe-Übertrag (i Bits), D3.L = Schiebe-Akku
  434.            SWAP D2            ; carry nach D2.HW
  435.            CLR.W D2           ; Rest von D2.L löschen
  436.            LSR.L D1,D2        ; D2.W enthält in seinen oberen i Bits das Vorzeichen
  437.            SWAP D2            ; Übertrag mit i Vorzeichenbits initialisiert
  438.            BRA.S \2
  439.     \1:      ; A0,A1 = Aufwärtszähler Adresse, D0.W = Herabzähler, D1.W = i,
  440.              ; D2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
  441.              ; D3.L = Schiebe-Akku
  442.              CLR.L D3
  443.              MOVE.W (A0)+,D3  ; neue Daten
  444.              SWAP D3          ; nach Bit 31..16(D3), D3.W = 0
  445.              LSR.L D1,D3      ; Bits 31-i..16-i(D3) sind die neuen Daten
  446.              OR.L D3,D2       ; Bits 31..16-i(D3) sind die bisherigen Daten
  447.              SWAP D2          ; untere 16 Bit ergeben neuen Übertrag,
  448.              MOVE.W D2,(A1)+  ; obere 16 Bit werden abgespeichert
  449.     \2:      CLR.W D2         ; D2.L = neuer Übertrag
  450.              DBF D0,\1        ; Schleife D0.W mal durchlaufen
  451.            SWAP D2
  452.            MOVE.W D2,D0
  453.            MOVE.L (SP)+,D3
  454.            RTS
  455.  
  456. ; extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
  457. mulusmall_loop_down: # Input in D0.W,A0,D1.W,D2.W, Output in D0.W
  458.            MOVE.L D3,-(SP)
  459.            EXT.L D2           ; carry
  460.            BRA.S \2
  461.     \1:      MOVE.W -(A0),D3  ; nächstes Digit
  462.              MULU D0,D3       ; mit digit multiplizieren
  463.              ADD.L D3,D2      ; und zum bisherigen Carry addieren. Kein Überlauf!
  464.              MOVE.W D2,(A0)   ; Low-Digit ablegen
  465.              CLR.W D2
  466.              SWAP D2          ; High-Digit gibt neuen Carry
  467.     \2:      DBF D1,\1
  468.            MOVE.W D2,D0       ; letzter Carry
  469.            MOVE.L (SP)+,D3
  470.            RTS
  471.  
  472. ; extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  473. mulu_loop_down: ; Input in D0.W,A0,A1,D1.W
  474.            MOVE.L D3,-(SP)
  475.            CLR.L D2           ; carry
  476.            BRA.S \2
  477.     \1:      MOVE.W -(A0),D3  ; nächstes Digit
  478.              MULU D0,D3       ; mit digit multiplizieren
  479.              ADD.L D3,D2      ; und zum bisherigen Carry addieren
  480.              MOVE.W D2,-(A1)  ; Low-Digit ablegen
  481.              CLR.W D2
  482.              SWAP D2          ; High-Digit gibt neuen Carry
  483.     \2:      DBF D1,\1
  484.            MOVE.W D2,-(A1)    ; letzten Carry ablegen
  485.            MOVE.L (SP)+,D3
  486.            RTS
  487.  
  488. ; extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  489. muluadd_loop_down: ; Input in D0.W,A0,A1,D1.W, benutzt D2,D3,D4, Output in D0.W
  490. #if 1
  491.            MOVE.L D3,-(SP)
  492.            SUB.L D2,D2        ; carry := 0, X-Bit löschen, D2.HW stets =0
  493.            BRA.S \2
  494.     \1:      MOVE.W -(A0),D3  ; nächstes Digit
  495.              MULU D0,D3       ; mit digit multiplizieren
  496.              ADDX.L D2,D3     ; und bisherigen Carry und X-Bit addieren
  497.              ADD.W D3,-(A1)   ; Low-Digit zum dest-Digit addieren, X als Übertrag
  498.              SWAP D3
  499.              MOVE.W D3,D2     ; High-Digit gibt neuen Carry
  500.     \2:      DBF D1,\1
  501.            MOVE.W D2,D0       ; letzten Carry und
  502.            SWAP D2            ; 0.W und
  503.            ADDX.W D2,D0       ; letztes X-Bit addieren
  504.            MOVE.L (SP)+,D3
  505.            RTS
  506. #else
  507.            MOVEM.L D3-D4,-(SP)
  508.            CLR.L D2           ; carry
  509.            CLR.L D4           ; D4.HW stets =0
  510.            BRA.S \2
  511.     \1:      MOVE.W -(A0),D3  ; nächstes Digit
  512.              MULU D0,D3       ; mit digit multiplizieren
  513.              ADD.L D3,D2      ; und zum bisherigen Carry addieren
  514.              MOVE.W -(A1),D4  ; nächstes dest-Digit
  515.              ADD.L D4,D2      ; dazuaddieren
  516.              MOVE.W D2,(A1)   ; Low-Digit ablegen
  517.              CLR.W D2
  518.              SWAP D2          ; High-Digit gibt neuen Carry
  519.     \2:      DBF D1,\1
  520.            MOVE.W D2,D0       ; letzten Carry als Ergebnis
  521.            MOVEM.L (SP)+,D3-D4
  522.            RTS
  523. #endif
  524.  
  525. #if 0
  526. ; extern void mulu_2loop_down (uintD* sourceptr1, uintC len1,
  527. ;                              uintD* sourceptr2, uintC len2,
  528. ;                              uintD* destptr, uintC len);
  529. mulu2_loop_down: ; Input in A0,D0.W,A1,D1.W,4(SP),D2.W
  530.            MOVEM.L A2-A5/D3-D5,-(SP)
  531.            MOVE.L 32(SP),A2
  532.            ; A0 = sourceptr1, D0.W = len1,
  533.            ; A1 = sourceptr2, D1.W = len2,
  534.            ; A2 = destptr, D2.W = len
  535.            CMP.W D0,D1
  536.            BHS.S \0
  537.            EXG D1,D0
  538.            EXG A1,A0
  539.     \0:    ; jetzt ist len1<=len2
  540.            ; erst D2.W+2 Nulldigits ablegen:
  541.            MOVE.L A2,A3
  542.            MOVE.W D2,D3
  543.            BRA.S \2
  544.     \1:      CLR.W -(A3)
  545.     \2:      DBF D3,\1
  546.            CLR.L -(A3)
  547.            ; A3+4/D2.W/A2 ist die Ergebnis-UDS
  548.            ; Unsigned multiplizieren:
  549.            ; Überträge werden sofort nach dem Erzeugen im Speicher
  550.            ; durchgeschoben. (Das geschieht recht selten - im Durchschnitt nur
  551.            ; jedes vierte Mal - und dauert nicht lang,
  552.            ; beschleunigt aber den inneren Schleifenkern enorm.)
  553.            ; Unverändert bleibt A1 in source2.
  554.            ; Äußere Schleife zählt mit D0.W, A0 in source1, A2 in dest.
  555.            ; Innere Schleife zählt mit D3.W, A3 in source2, A4 in dest.
  556.            ; Ganz innere Schleife zählt mit A5 in dest.
  557.            ; D4, D5 temporäre Daten.
  558.            BRA.S \7
  559.     \3:      MOVE.W D1,D3
  560.              MOVE.L A1,A3
  561.              SUBQ.L #2,A2
  562.              MOVE.L A2,A4
  563.              MOVE.W -(A0),D4
  564.              ; Innere Schleife:
  565.              ; D4 = Multiplikator-Ziffer, D3.W mal wird
  566.              ; jeweils -2(A3).W * D4 zu (A4).W addiert, Überträge darunter.
  567.              ; Benutzt A3,D3,A4,D4, verändert D5,A5
  568.              BRA.S \6
  569.     \4:        MOVE.W D4,D5
  570.                MULU -(A3),D5 ; D5.L := D5.W * -(A3).W
  571.                SUBQ.L #2,A4 ; nächstes Zielwort ansteuern
  572.                ADD.L D5,(A4) ; Wort zu 2(A4).W addieren, Übertrag zu (A4).W
  573.                BCC.S \6
  574.                ; Übertrag nach links propagieren:
  575.                MOVE.L A4,A5
  576.     \5:          ADD.W #1,-(A5)
  577.                  BCS.S \5
  578.     \6:        DBF D3,\4
  579.              ; Innere Schleife beendet.
  580.     \7:      DBF D0,\3
  581.            MOVEM.L (SP)+,A2-A5/D3-D5
  582.            RTS
  583. #endif
  584.  
  585. ; extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  586. mulusub_loop_down: ; Input in D0.W,A0,A1,D1.W, benutzt D2,D3,D4, Output in D0.W
  587.            MOVE.L D3,-(SP)
  588.            SUB.L D2,D2        ; carry := 0, X-Bit löschen, D2.HW stets =0
  589.            BRA.S \2
  590.     \1:      MOVE.W -(A0),D3  ; nächstes Digit
  591.              MULU D0,D3       ; mit digit multiplizieren
  592.              ADDX.L D2,D3     ; und bisherigen Carry und X-Bit addieren
  593.              SUB.W D3,-(A1)   ; Low-Digit vom dest-Digit subtrahieren, X als Übertrag
  594.              SWAP D3
  595.              MOVE.W D3,D2     ; High-Digit gibt neuen Carry
  596.     \2:      DBF D1,\1
  597.            CLR.W D0
  598.            ADDX.W D2,D0       ; letzter Carry und letztes X-Bit
  599.            MOVE.L (SP)+,D3
  600.            RTS
  601.  
  602. ; extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
  603. divu_loop_up: # Input in D0.W,A0,D1.W, Output in D0.W
  604.            CLR.L D2           ; Rest D2.HW := 0
  605.            BRA.S \2
  606.     \1:      MOVE.W (A0),D2   ; nächst-niedriges Digit mit Rest kombinieren
  607.              DIVU D0,D2       ; und durch digit dividieren
  608.              MOVE.W D2,(A0)+  ; Quotient ablegen, Rest in D2.HW
  609.     \2:      DBF D1,\1
  610.            SWAP D2
  611.            MOVE.W D2,D0       ; Rest
  612.            RTS
  613.  
  614. ; extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  615. divucopy_loop_up: # Input in D0.W,A0,A1,D1.W, Output in D0.W
  616.            CLR.L D2           ; Rest D2.HW := 0
  617.            BRA.S \2
  618.     \1:      MOVE.W (A0)+,D2  ; nächst-niedriges Digit mit Rest kombinieren
  619.              DIVU D0,D2       ; und durch digit dividieren
  620.              MOVE.W D2,(A1)+  ; Quotient ablegen, Rest in D2.HW
  621.     \2:      DBF D1,\1
  622.            SWAP D2
  623.            MOVE.W D2,D0       ; Rest
  624.            RTS
  625.  
  626.            .end
  627.  
  628. #endif
  629.  
  630.