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

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