home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / ari68000.atari.d < prev    next >
Encoding:
Text File  |  1993-04-04  |  24.8 KB  |  710 lines

  1. # Externe Routinen zu ARILEV1.D
  2. # Compiler: GNU-C -mshort auf ATARI ST
  3. # Parameter-▄bergabe:
  4. #   auf dem Stack: sp@(4), sp@(8), ... (.W-Gr÷▀en belegen 2 Byte),
  5. #   Rⁿckgabewert in d0.
  6. # Register a0-a1,d0-d1 frei verwendbar,
  7. # Register a2-a4,d2-d7 mⁿssen gerettet werden.
  8. # Einstellungen: intCsize=16, intDsize=16.
  9.  
  10. #ifdef INCLUDED_FROM_C
  11.  
  12.   #define COPY_LOOPS
  13.   #define FILL_LOOPS
  14.   #define CLEAR_LOOPS
  15.   #define LOG_LOOPS
  16.   #define TEST_LOOPS
  17.   #define ADDSUB_LOOPS
  18.   #define SHIFT_LOOPS
  19.   #define MUL_LOOPS
  20.   #define DIV_LOOPS
  21.  
  22. #else
  23.  
  24.            .text
  25.  
  26.            .globl _copy_loop_up,_copy_loop_down,_fill_loop_up,_fill_loop_down
  27.            .globl _clear_loop_up,_clear_loop_down
  28.            .globl _or_loop_up,_xor_loop_up,_and_loop_up,_eqv_loop_up
  29.            .globl _nand_loop_up,_nor_loop_up,_andc2_loop_up,_orc2_loop_up
  30.            .globl _not_loop_up
  31.            .globl _and_test_loop_up,_test_loop_up,_compare_loop_up
  32.            .globl _add_loop_down,_addto_loop_down,_inc_loop_down
  33.            .globl _sub_loop_down,_subx_loop_down,_subfrom_loop_down,_dec_loop_down
  34.            .globl _neg_loop_down
  35.            .globl _shift1left_loop_down,_shiftleft_loop_down,_shiftleftcopy_loop_down
  36.            .globl _shift1right_loop_up,_shiftright_loop_up,_shiftrightsigned_loop_up,_shiftrightcopy_loop_up
  37.            .globl _mulusmall_loop_down,_mulu_loop_down,_muluadd_loop_down,_mulusub_loop_down
  38.            .globl _divu_loop_up,_divucopy_loop_up
  39.  
  40. #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
  41.            .globl _mulu32_
  42. ! extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
  43. ! 2^32*hi+lo := arg1*arg2.
  44. _mulu32_:  ! Input in d0,d1, Output in d0,mulu32_high
  45.            movel sp@(4),d0
  46.            movel sp@(8),d1
  47.            movel d2,a0
  48.            movel d3,a1
  49.            movel d4,sp@-
  50.            ! d0.L = 2^16*a+b, d1.L = 2^16*c+d -> Produkt
  51.            ! (2^16*a+b)*(2^16*c+d) = 2^32*a*c + 2^16*(a*d+b*c) + b*d
  52.            movel d0,d2
  53.            swap d2      ! d2.W = a
  54.            movel d1,d3
  55.            swap d1      ! d1.W = c
  56.            movel d1,d4
  57.            mulu d2,d1   ! d1.L = a*c
  58.            mulu d3,d2   ! d2.L = a*d
  59.            mulu d0,d4   ! d4.L = b*c
  60.            mulu d3,d0   ! d0.L = b*d
  61.            clrl d3      ! Hilfsregister fⁿr Zero-Extend
  62.            swap d2
  63.            movew d2,d3
  64.            addl d3,d1   ! high16(a*d) zu d1.L addieren
  65.            swap d4
  66.            movew d4,d3
  67.            addl d3,d1   ! high16(b*c) zu d1.L addieren
  68.            clrw d2
  69.            addl d2,d0   ! 2^16*low16(a*d) zu d0.L addieren
  70.            bccs 1f
  71.            addql #1,d1
  72.     1:     clrw d4
  73.            addl d4,d0   ! 2^16*low16(b*c) zu d0.L addieren
  74.            bccs 2f
  75.            addql #1,d1
  76.     2:     ! d0.L = lo, d1.L = hi fertig.
  77.            movel d1,(mulu32_high) ! Adressierung?? Deklaration??
  78.            movel sp@+,d4
  79.            movel a1,d3
  80.            movel a0,d2
  81.            rts
  82. #endif
  83.  
  84. | extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
  85. _copy_loop_up: | Input in a0,a1,d0.W, Output in d0
  86.            movel sp@(4),a0
  87.            movel sp@(8),a1
  88.            movew sp@(12),d0
  89.            bras 2f
  90.     1:       movew a0@+,a1@+
  91.     2:       dbra d0,1b
  92.            movel a1,d0
  93.            rts
  94.  
  95. | extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  96. _copy_loop_down: | Input in a0,a1,d0.W, Output in d0
  97.            movel sp@(4),a0
  98.            movel sp@(8),a1
  99.            movew sp@(12),d0
  100.            bras 2f
  101.     1:       movew a0@-,a1@-
  102.     2:       dbra d0,1b
  103.            movel a1,d0
  104.            rts
  105.  
  106. | extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
  107. _fill_loop_up: | Input in a0,d0.W,d1.W, Output in d0
  108.            movel sp@(4),a0
  109.            movew sp@(8),d0
  110.            movew sp@(10),d1
  111.            bras 2f
  112.     1:       movew d1,a0@+
  113.     2:       dbra d0,1b
  114.            movel a0,d0
  115.            rts
  116.  
  117. | extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
  118. _fill_loop_down: | Input in a0,d0.W,d1.W, Output in d0
  119.            movel sp@(4),a0
  120.            movew sp@(8),d0
  121.            movew sp@(10),d1
  122.            bras 2f
  123.     1:       movew d1,a0@-
  124.     2:       dbra d0,1b
  125.            movel a0,d0
  126.            rts
  127.  
  128. | extern uintD* clear_loop_up (uintD* destptr, uintC count);
  129. _clear_loop_up: | Input in a0,d0.W, Output in d0
  130.            movel sp@(4),a0
  131.            movew sp@(8),d0
  132.            bras 2f
  133.     1:       clrw a0@+
  134.     2:       dbra d0,1b
  135.            movel a0,d0
  136.            rts
  137.  
  138. | extern uintD* clear_loop_down (uintD* destptr, uintC count);
  139. _clear_loop_down: | Input in a0,d0.W, Output in d0
  140.            movel sp@(4),a0
  141.            movew sp@(8),d0
  142.            bras 2f
  143.     1:       clrw a0@-
  144.     2:       dbra d0,1b
  145.            movel a0,d0
  146.            rts
  147.  
  148. | extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
  149. _or_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  150.            movel sp@(4),a0
  151.            movel sp@(8),a1
  152.            movew sp@(12),d0
  153.            bras 2f
  154.     1:       movew a1@+,d1
  155.              orw d1,a0@+
  156.     2:       dbra d0,1b
  157.            rts
  158.  
  159. | extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  160. _xor_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  161.            movel sp@(4),a0
  162.            movel sp@(8),a1
  163.            movew sp@(12),d0
  164.            bras 2f
  165.     1:       movew a1@+,d1
  166.              eorw d1,a0@+
  167.     2:       dbra d0,1b
  168.            rts
  169.  
  170. | extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
  171. _and_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  172.            movel sp@(4),a0
  173.            movel sp@(8),a1
  174.            movew sp@(12),d0
  175.            bras 2f
  176.     1:       movew a1@+,d1
  177.              andw d1,a0@+
  178.     2:       dbra d0,1b
  179.            rts
  180.  
  181. | extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
  182. _eqv_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  183.            movel sp@(4),a0
  184.            movel sp@(8),a1
  185.            movew sp@(12),d0
  186.            bras 2f
  187.     1:       movew a1@+,d1
  188.              eorw d1,a0@
  189.              notw a0@+
  190.     2:       dbra d0,1b
  191.            rts
  192.  
  193. | extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
  194. _nand_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  195.            movel sp@(4),a0
  196.            movel sp@(8),a1
  197.            movew sp@(12),d0
  198.            bras 2f
  199.     1:       movew a1@+,d1
  200.              andw d1,a0@
  201.              notw a0@+
  202.     2:       dbra d0,1b
  203.            rts
  204.  
  205. | extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  206. _nor_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  207.            movel sp@(4),a0
  208.            movel sp@(8),a1
  209.            movew sp@(12),d0
  210.            bras 2f
  211.     1:       movew a1@+,d1
  212.              orw d1,a0@
  213.              notw a0@+
  214.     2:       dbra d0,1b
  215.            rts
  216.  
  217. | extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  218. _andc2_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  219.            movel sp@(4),a0
  220.            movel sp@(8),a1
  221.            movew sp@(12),d0
  222.            bras 2f
  223.     1:       movew a1@+,d1
  224.              notw d1
  225.              andw d1,a0@+
  226.     2:       dbra d0,1b
  227.            rts
  228.  
  229. | extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  230. _orc2_loop_up: | Input in a0,a1,d0.W, verΣndert d1
  231.            movel sp@(4),a0
  232.            movel sp@(8),a1
  233.            movew sp@(12),d0
  234.            bras 2f
  235.     1:       movew a1@+,d1
  236.              notw d1
  237.              orw d1,a0@+
  238.     2:       dbra d0,1b
  239.            rts
  240.  
  241. | extern void not_loop_up (uintD* xptr, uintC count);
  242. _not_loop_up: | Input in a0,d0.W
  243.            movel sp@(4),a0
  244.            movew sp@(8),d0
  245.            bras 2f
  246.     1:       notw a0@+
  247.     2:       dbra d0,1b
  248.            rts
  249.  
  250. | extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
  251. _and_test_loop_up: | Input in a0,a1,d0.W, verΣndert d1, Output in d0.W=d0.L
  252.            movel sp@(4),a0
  253.            movel sp@(8),a1
  254.            movew sp@(12),d0
  255.            bras 2f
  256.     1:       movew a0@+,d1
  257.              andw a1@+,d1
  258.              bnes 3f
  259.     2:       dbra d0,1b
  260.            clrl d0
  261.            rts
  262.     3:     moveq #1,d0
  263.            rts
  264.  
  265. | extern boolean test_loop_up (uintD* ptr, uintC count);
  266. _test_loop_up: | Input in a0,d0.W, Output in d0.W=d0.L
  267.            movel sp@(4),a0
  268.            movew sp@(8),d0
  269.            bras 2f
  270.     1:       tstw a0@+
  271.              bnes 3f
  272.     2:       dbra d0,1b
  273.            clrl d0
  274.            rts
  275.     3:     moveq #1,d0
  276.            rts
  277.  
  278. | extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
  279. _compare_loop_up: | Input in a0,a1,d0.W, Output in d0.W=d0.L
  280.            movel sp@(4),a0
  281.            movel sp@(8),a1
  282.            movew sp@(12),d0
  283.            bras 2f
  284.     1:       cmpmw a1@+,a0@+
  285.              bnes 3f
  286.     2:       dbra d0,1b
  287.            clrl d0
  288.            rts
  289.     3:     bcss 4f
  290.            moveq #1,d0
  291.            rts
  292.     4:     moveq #-1,d0
  293.            rts
  294.  
  295. | extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  296. _add_loop_down: | Input in a0,a1,a2,d0.W, verΣndert d1,d2, Output in d0.W
  297.            moveml a2/d2,sp@-
  298.            movel sp@(8+4),a0
  299.            movel sp@(8+8),a1
  300.            movel sp@(8+12),a2
  301.            movew sp@(8+16),d0
  302.            andb #0x0e,ccr   | X-Bit l÷schen
  303.            bras 2f
  304.     1:       movew a0@-,d1
  305.              movew a1@-,d2
  306.              addxw d2,d1
  307.              movew d1,a2@-
  308.     2:       dbra d0,1b
  309.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  310.            moveml sp@+,a2/d2
  311.            rts
  312.  
  313. | extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  314. _addto_loop_down: | Input in a0,a1,d0.W, Output in d0.W
  315.            movel sp@(4),a0
  316.            movel sp@(8),a1
  317.            movew sp@(12),d0
  318.            andb #0x0e,ccr   | X-Bit l÷schen
  319.            bras 2f
  320.     1:       addxw a0@-,a1@-
  321.     2:       dbra d0,1b
  322.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  323.            rts
  324.  
  325. | extern uintD inc_loop_down (uintD* ptr, uintC count);
  326. _inc_loop_down: | Input in a0,d0.W, Output in d0.W
  327.            movel sp@(4),a0
  328.            movew sp@(8),d0
  329.            dbra d0,1f          | simuliere gesetzten Carry
  330.                               | d0.W=-1 fⁿr ▄bertrag
  331.            rts
  332.     1:       addqw #1,a0@-
  333.              dbcc d0,1b       | kein Carry -> Schleife abbrechen
  334.            subxw d0,d0       | kein Carry -> d0.W=0, sonst d0.W=-1 fⁿr ▄bertrag
  335.            rts
  336.  
  337. | extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  338. _sub_loop_down: | Input in a0,a1,a2,d0.W, verΣndert d1,d2, Output in d0.W
  339.            moveml a2/d2,sp@-
  340.            movel sp@(8+4),a0
  341.            movel sp@(8+8),a1
  342.            movel sp@(8+12),a2
  343.            movew sp@(8+16),d0
  344.            andb #0x0e,ccr   | X-Bit l÷schen
  345.            bras 2f
  346.     1:       movew a0@-,d1
  347.              movew a1@-,d2
  348.              subxw d2,d1
  349.              movew d1,a2@-
  350.     2:       dbra d0,1b
  351.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  352.            moveml sp@+,a2/d2
  353.            rts
  354.  
  355. | extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
  356. _subx_loop_down: | Input in a0,a1,a2,d0.W,d1.W, verΣndert d2, Output in d0.W
  357.            moveml a2/d2,sp@-
  358.            movel sp@(8+4),a0
  359.            movel sp@(8+8),a1
  360.            movel sp@(8+12),a2
  361.            movew sp@(8+16),d0
  362.            movew sp@(8+18),d1
  363.            roxrw #1,d1      | X-Bit initialisieren
  364.            bras 2f
  365.     1:       movew a0@-,d1
  366.              movew a1@-,d2
  367.              subxw d2,d1
  368.              movew d1,a2@-
  369.     2:       dbra d0,1b
  370.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  371.            moveml sp@+,a2/d2
  372.            rts
  373.  
  374. | extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  375. _subfrom_loop_down: | Input in a0,a1,d0.W, Output in d0.W
  376.            movel sp@(4),a0
  377.            movel sp@(8),a1
  378.            movew sp@(12),d0
  379.            andb #0x0e,ccr   | X-Bit l÷schen
  380.            bras 2f
  381.     1:       subxw a0@-,a1@-
  382.     2:       dbra d0,1b
  383.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  384.            rts
  385.  
  386. | extern uintD dec_loop_down (uintD* ptr, uintC count);
  387. _dec_loop_down: | Input in a0,d0.W, Output in d0.W
  388.            movel sp@(4),a0
  389.            movew sp@(8),d0
  390.            dbra d0,1f          | simuliere gesetzten Carry
  391.                               | d0.W=-1 als ▄bertrag
  392.            rts
  393.     1:       subqw #1,a0@-
  394.              dbcc d0,1b       | kein Carry -> Schleife abbrechen
  395.            subxw d0,d0       | kein Carry -> d0.W=0, sonst d0.W=-1 als ▄bertrag
  396.            rts
  397.  
  398. | extern uintD neg_loop_down (uintD* ptr, uintC count);
  399. _neg_loop_down: | Input in a0,d0.W, Output in d0.W
  400.            movel sp@(4),a0
  401.            movew sp@(8),d0
  402.            andb #0x0e,ccr   | X-Bit l÷schen
  403.            bras 2f
  404.     1:       negxw a0@-
  405.     2:       dbra d0,1b
  406.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  407.            rts
  408.  
  409. | extern uintD shift1left_loop_down (uintD* ptr, uintC count);
  410. _shift1left_loop_down: | Input in a0,d0.W, Output in d0.W
  411.            movel sp@(4),a0
  412.            movew sp@(8),d0
  413.            andb #0x0e,ccr   | X-Bit l÷schen
  414.            bras 2f
  415.     1:       roxlw a0@-     | Digit a0@- um 1 Bit links schieben, X-Bit als Buffer
  416.     2:       dbra d0,1b
  417.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  418.            rts
  419.  
  420. | extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
  421. _shiftleft_loop_down: | Input in a0,d0.W,d1.W,d2.W, Output in d0.W
  422.            moveml d2-d3,sp@-
  423.            movel sp@(8+4),a0
  424.            movew sp@(8+8),d0
  425.            movew sp@(8+10),d1
  426.            movew sp@(8+12),d2
  427.            | a0 = ptr, d0.W = count, d1.W = i,
  428.            | d2.W = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  429.            bras 2f
  430.     1:       clrl d3
  431.              movew a0@-,d3  | d3.L = d3.W = neues Digit
  432.              lsll d1,d3      | um i Bits nach links schieben
  433.              orw d2,d3       | d3 enthΣlt die letzten 16+i Bits
  434.              movew d3,a0@   | 16 Bits ablegen
  435.              swap d3
  436.              movew d3,d2     | neuen ▄bertrag bilden
  437.     2:       dbra d0,1b        | Schleife d0.W mal durchlaufen
  438.            movew d2,d0
  439.            moveml sp@+,d2-d3
  440.            rts
  441.  
  442. | extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
  443. _shiftleftcopy_loop_down: | Input in a0,a1,d0.W,d1.W, Output in d0.W
  444.            moveml d2-d3,sp@-
  445.            movel sp@(8+4),a0
  446.            movel sp@(8+8),a1
  447.            movew sp@(8+12),d0
  448.            movew sp@(8+14),d1
  449.            clrw d2
  450.            | a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i,
  451.            | d2.W = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  452.            bras 2f
  453.     1:       clrl d3
  454.              movew a0@-,d3  | d3.L = d3.W = neues Digit
  455.              lsll d1,d3      | um i Bits nach links schieben
  456.              orw d2,d3       | d3 enthΣlt die letzten 16+i Bits
  457.              movew d3,a1@-  | 16 Bits ablegen
  458.              swap d3
  459.              movew d3,d2     | neuen ▄bertrag bilden
  460.     2:       dbra d0,1b        | Schleife d0.W mal durchlaufen
  461.            movew d2,d0
  462.            moveml sp@+,d2-d3
  463.            rts
  464.  
  465. | extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
  466. _shift1right_loop_up: | Input in a0,d0.W,d1.W, Output in d0.W
  467.            movel sp@(4),a0
  468.            movew sp@(8),d0
  469.            movew sp@(10),d1
  470.            roxrw #1,d1       | X-Bit l÷schen oder setzen, je nach d1.W
  471.            bras 2f
  472.     1:       roxrw a0@+     | Digit a0@+ um 1 Bit rechts schieben, X-Bit als Buffer
  473.     2:       dbra d0,1b
  474.            subxw d0,d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  475.            rts
  476.  
  477. | extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
  478. _shiftright_loop_up: | Input in a0,d0.W,d1.W, Output in d0.W
  479.            moveml d2-d3,sp@-
  480.            movel sp@(8+4),a0
  481.            movew sp@(8+8),d0
  482.            movew sp@(8+10),d1
  483.            | a0 = ptr, d0.W = count, d1.W = i,
  484.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  485.            clrl d2           | ▄bertrag = 0
  486.            bras 2f
  487.     1:       | a0 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i,
  488.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  489.              | d3.L = Schiebe-Akku
  490.              clrl d3
  491.              movew a0@,d3   | neue Daten
  492.              swap d3          | nach Bit 31..16(d3), d3.W = 0
  493.              lsrl d1,d3      | Bits 31-i..16-i(d3) sind die neuen Daten
  494.              orl d3,d2       | Bits 31..16-i(d3) sind die bisherigen Daten
  495.              swap d2          | untere 16 Bit ergeben neuen ▄bertrag,
  496.              movew d2,a0@+  | obere 16 Bit werden abgespeichert
  497.              clrw d2         | d2.L = neuer ▄bertrag
  498.     2:       dbra d0,1b        | Schleife d0.W mal durchlaufen
  499.            swap d2
  500.            movew d2,d0
  501.            moveml sp@+,d2-d3
  502.            rts
  503.  
  504. | extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
  505. _shiftrightsigned_loop_up: | Input in a0,d0.W,d1.W, Output in d0.W
  506.            moveml d2-d3,sp@-
  507.            movel sp@(8+4),a0
  508.            movew sp@(8+8),d0
  509.            movew sp@(8+10),d1
  510.            | a0 = ptr, d0.W = count, d1.W = i,
  511.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  512.            movew a0@,d2     | erstes Digit
  513.            extl d2           | Vorzeichenbit nach Bit 31..16(d2)
  514.            clrw d2           | Rest von d2.L l÷schen
  515.            lsrl d1,d2        | d2.W enthΣlt in seinen oberen i Bits das Vorzeichen
  516.            swap d2            | ▄bertrag mit i Vorzeichenbits initialisiert
  517.            bras 2f
  518.     1:       | a0 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i,
  519.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  520.              | d3.L = Schiebe-Akku
  521.              clrl d3
  522.              movew a0@,d3   | neue Daten
  523.              swap d3          | nach Bit 31..16(d3), d3.W = 0
  524.              lsrl d1,d3      | Bits 31-i..16-i(d3) sind die neuen Daten
  525.              orl d3,d2       | Bits 31..16-i(d3) sind die bisherigen Daten
  526.              swap d2          | untere 16 Bit ergeben neuen ▄bertrag,
  527.              movew d2,a0@+  | obere 16 Bit werden abgespeichert
  528.     2:       clrw d2         | d2.L = neuer ▄bertrag
  529.              dbra d0,1b        | Schleife d0.W mal durchlaufen
  530.            swap d2
  531.            movew d2,d0
  532.            moveml sp@+,d2-d3
  533.            rts
  534.  
  535. | extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
  536. _shiftrightcopy_loop_up: | Input in a0,a1,d0.W,d1.W,d2.W, Output in d0.W
  537.            moveml d2-d3,sp@-
  538.            movel sp@(8+4),a0
  539.            movel sp@(8+8),a1
  540.            movew sp@(8+12),d0
  541.            movew sp@(8+14),d1
  542.            movew sp@(8+16),d2
  543.            | a0 = ptr, d0.W = count, d1.W = i,
  544.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  545.            swap d2            | carry nach d2.HW
  546.            clrw d2           | Rest von d2.L l÷schen
  547.            lsrl d1,d2        | d2.W enthΣlt in seinen oberen i Bits das Vorzeichen
  548.            swap d2            | ▄bertrag mit i Vorzeichenbits initialisiert
  549.            bras 2f
  550.     1:       | a0,a1 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i,
  551.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  552.              | d3.L = Schiebe-Akku
  553.              clrl d3
  554.              movew a0@+,d3  | neue Daten
  555.              swap d3          | nach Bit 31..16(d3), d3.W = 0
  556.              lsrl d1,d3      | Bits 31-i..16-i(d3) sind die neuen Daten
  557.              orl d3,d2       | Bits 31..16-i(d3) sind die bisherigen Daten
  558.              swap d2          | untere 16 Bit ergeben neuen ▄bertrag,
  559.              movew d2,a1@+  | obere 16 Bit werden abgespeichert
  560.     2:       clrw d2         | d2.L = neuer ▄bertrag
  561.              dbra d0,1b        | Schleife d0.W mal durchlaufen
  562.            swap d2
  563.            movew d2,d0
  564.            moveml sp@+,d2-d3
  565.            rts
  566.  
  567. | extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
  568. _mulusmall_loop_down: # Input in d0.W,a0,d1.W,d2.W, Output in d0.W
  569.            moveml d2-d3,sp@-
  570.            movew sp@(8+4),d0
  571.            movel sp@(8+6),a0
  572.            movew sp@(8+10),d1
  573.            movew sp@(8+12),d2
  574.            extl d2           | carry
  575.            bras 2f
  576.     1:       movew a0@-,d3  | nΣchstes Digit
  577.              mulu d0,d3       | mit digit multiplizieren
  578.              addl d3,d2      | und zum bisherigen Carry addieren. Kein ▄berlauf!
  579.              movew d2,a0@   | Low-Digit ablegen
  580.              clrw d2
  581.              swap d2          | High-Digit gibt neuen Carry
  582.     2:       dbra d1,1b
  583.            movew d2,d0       | letzter Carry
  584.            moveml sp@+,d2-d3
  585.            rts
  586.  
  587. | extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  588. _mulu_loop_down: | Input in d0.W,a0,a1,d1.W
  589.            moveml d2-d3,sp@-
  590.            movew sp@(8+4),d0
  591.            movel sp@(8+6),a0
  592.            movel sp@(8+10),a1
  593.            movew sp@(8+14),d1
  594.            clrl d2           | carry
  595.            bras 2f
  596.     1:       movew a0@-,d3  | nΣchstes Digit
  597.              mulu d0,d3       | mit digit multiplizieren
  598.              addl d3,d2      | und zum bisherigen Carry addieren
  599.              movew d2,a1@-  | Low-Digit ablegen
  600.              clrw d2
  601.              swap d2          | High-Digit gibt neuen Carry
  602.     2:       dbra d1,1b
  603.            movew d2,a1@-    | letzten Carry ablegen
  604.            moveml sp@+,d2-d3
  605.            rts
  606.  
  607. | extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  608. _muluadd_loop_down: | Input in d0.W,a0,a1,d1.W, benutzt d2,d3,d4, Output in d0.W
  609. #if 1
  610.            moveml d2-d3,sp@-
  611.            movew sp@(8+4),d0
  612.            movel sp@(8+6),a0
  613.            movel sp@(8+10),a1
  614.            movew sp@(8+14),d1
  615.            subl d2,d2        | carry := 0, X-Bit l÷schen, d2.HW stets =0
  616.            bras 2f
  617.     1:       movew a0@-,d3  | nΣchstes Digit
  618.              mulu d0,d3       | mit digit multiplizieren
  619.              addxl d2,d3     | und bisherigen Carry und X-Bit addieren
  620.              addw d3,a1@-   | Low-Digit zum dest-Digit addieren, X als ▄bertrag
  621.              swap d3
  622.              movew d3,d2     | High-Digit gibt neuen Carry
  623.     2:       dbra d1,1b
  624.            movew d2,d0       | letzten Carry und
  625.            swap d2            | 0.W und
  626.            addxw d2,d0       | letztes X-Bit addieren
  627.            moveml sp@+,d2-d3
  628.            rts
  629. #else
  630.            moveml d2-d4,sp@-
  631.            movew sp@(12+4),d0
  632.            movel sp@(12+6),a0
  633.            movel sp@(12+10),a1
  634.            movew sp@(12+14),d1
  635.            clrl d2           | carry
  636.            clrl d4           | d4.HW stets =0
  637.            bras 2f
  638.     1:       movew a0@-,d3  | nΣchstes Digit
  639.              mulu d0,d3       | mit digit multiplizieren
  640.              addl d3,d2      | und zum bisherigen Carry addieren
  641.              movew a1@-,d4  | nΣchstes dest-Digit
  642.              addl d4,d2      | dazuaddieren
  643.              movew d2,a1@   | Low-Digit ablegen
  644.              clrw d2
  645.              swap d2          | High-Digit gibt neuen Carry
  646.     2:       dbra d1,1b
  647.            movew d2,d0       | letzten Carry als Ergebnis
  648.            moveml sp@+,d2-d4
  649.            rts
  650. #endif
  651.  
  652. | extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  653. _mulusub_loop_down: | Input in d0.W,a0,a1,d1.W, benutzt d2,d3,d4, Output in d0.W
  654.            moveml d2-d3,sp@-
  655.            movew sp@(8+4),d0
  656.            movel sp@(8+6),a0
  657.            movel sp@(8+10),a1
  658.            movew sp@(8+14),d1
  659.            subl d2,d2        | carry := 0, X-Bit l÷schen, d2.HW stets =0
  660.            bras 2f
  661.     1:       movew a0@-,d3  | nΣchstes Digit
  662.              mulu d0,d3       | mit digit multiplizieren
  663.              addxl d2,d3     | und bisherigen Carry und X-Bit addieren
  664.              subw d3,a1@-   | Low-Digit vom dest-Digit subtrahieren, X als ▄bertrag
  665.              swap d3
  666.              movew d3,d2     | High-Digit gibt neuen Carry
  667.     2:       dbra d1,1b
  668.            clrw d0
  669.            addxw d2,d0       | letzter Carry und letztes X-Bit
  670.            moveml sp@+,d2-d3
  671.            rts
  672.  
  673. | extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
  674. _divu_loop_up: # Input in d0.W,a0,d1.W, Output in d0.W
  675.            movel d2,sp@-
  676.            movew sp@(4+4),d0
  677.            movel sp@(4+6),a0
  678.            movew sp@(4+10),d1
  679.            clrl d2           | Rest d2.HW := 0
  680.            bras 2f
  681.     1:       movew a0@,d2   | nΣchst-niedriges Digit mit Rest kombinieren
  682.              divu d0,d2       | und durch digit dividieren
  683.              movew d2,a0@+  | Quotient ablegen, Rest in d2.HW
  684.     2:       dbra d1,1b
  685.            swap d2
  686.            movew d2,d0       | Rest
  687.            movel sp@+,d2
  688.            rts
  689.  
  690. | extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  691. _divucopy_loop_up: # Input in d0.W,a0,a1,d1.W, Output in d0.W
  692.            movel d2,sp@-
  693.            movew sp@(4+4),d0
  694.            movel sp@(4+6),a0
  695.            movel sp@(4+10),a1
  696.            movew sp@(4+14),d1
  697.            clrl d2           | Rest d2.HW := 0
  698.            bras 2f
  699.     1:       movew a0@+,d2  | nΣchst-niedriges Digit mit Rest kombinieren
  700.              divu d0,d2       | und durch digit dividieren
  701.              movew d2,a1@+  | Quotient ablegen, Rest in d2.HW
  702.     2:       dbra d1,1b
  703.            swap d2
  704.            movew d2,d0       | Rest
  705.            movel sp@+,d2
  706.            rts
  707.  
  708. #endif
  709.  
  710.