******************************************
*  Extended Arithmetic Package           *
*  Longword integer multiply and divide  *
*                                        *
*  Copyright M.R.King, 26/3/1984         *
*  All rights reserved                   *
*                                        *
******************************************

   dc.b 'Integer Extended Arithmetic Package. '
   dc.b 'Copyright M.R.King, 26/3/1984. '
   dc.b 'All rights reserved.'

*
* 32-bit multiply  d0 = d0*d1
*
mull movem.l d1-d4,-(sp)
   moveq #0,d4
   move.l d0,d2
   bpl.s m1
   neg.l d0
   moveq #1,d4
   move.l d0,d2
m1 swap d2
   move.l d1,d3
   bpl.s m2
   neg.l d1
   eor.w #1,d4
   move.l d1,d3
m2 swap d3
   tst.w d2
   beq.s maz     * A>>16=0 ->
   tst.w d3
   beq.s mbz     * B>>16=0 ->
   mulu d0,d3
   mulu d1,d2
   mulu d1,d0
   add.l d3,d2
   swap d0
   add.w d2,d0
   swap d0
   bra.s mv      * mandatory overflow ->
maz tst.w d3
   beq.s mabz    * A>>16=B>>16=0 ->
   mulu d0,d3
   mulu d1,d0
   swap d0
   add.w d3,d0
   swap d0
   swap d3
   tst.w d3
   bne.s mv      * certain overflow ->
   bra.s mvt     * possible overflow ->
mbz mulu d1,d2
   mulu d1,d0
   swap d0
   add.w d2,d0
   swap d0
   swap d2
   tst.w d2
   bne.s mv
   bra.s mvt
mabz mulu d1,d0
mvt tst.l d0
   bmi.s mv
   btst #0,d4
   beq.s m8
   neg.l d0
m8 tst.l d0
   movem.l (sp)+,d1-d4
   rts
mv btst #0,d4
   beq.s m9
   neg.l d0
m9 tst.l d0
   movem.l (sp)+,d1-d4
   or.b #2,ccr
   rts
*mull     movem.l d1-d4,-(sp)
*         clr     d4
*         move.l  d0,d2
*         bpl.s   posd0l
*         neg.l   d0
*         move.l  d0,d2
*         or      #1,d4
*posd0l   tst.l   d1
*         bpl.s   posd1l
*         neg.l   d1
*         eor     #1,d4
*posd1l   mulu    d1,d0
*         swap    d0
*         swap    d1
*         tst     d1
*         beq.s   nomult1
*         move    d1,d3
*         mulu    d2,d3
*         add     d3,d0
*         swap    d3
*         tst     d3
*         bne.s   ioflow
*         swap    d2
*         tst     d2
*         beq.s   nomult2
*         bra.s   ioflow
*nomult1  swap    d2
*         tst     d2
*         beq.s   nomult2
*         swap    d1
*         mulu    d2,d1
*         add     d1,d0
*         swap    d1
*         tst     d1
*         bne.s   ioflow
*nomult2  swap    d0
*         bmi.s   ioflow
*         bclr    #0,d4
*         beq.s   mulret
*         neg.l   d0
*mulret   movem.l (sp)+,d1-d4
*         tst.l d0
*         rts
*ioflow   movem.l (sp)+,d1-d4
*         moveq #-$11,d0
*         bra signal
*        or.b    #2,sr
*        rts
*
* 32-bit divide  d0 by d1, d0=quot, d1=rem
*
divl     movem.l d2-d4,-(sp)
         clr     d4
         move.l  d1,d2
         beq.s   zdivoflow
         bpl.s   divpos1
         neg.l   d2
         or      #2,d4
divpos1  move.l  d0,d1
         bpl.s   divpos2
         neg.l   d1
         eor.l   #3,d4
divpos2  clr.l   d0
         move.l  #1,d3
         bra.s   divsulps
divsulp  lsl.l   #1,d2
         lsl.l   #1,d3
divsulps cmp.l   d2,d1
         bhi.s   divsulp
divlp    cmp.l   d2,d1
         bcs.s   divnosub
         add.l   d3,d0
         sub.l   d2,d1
divnosub lsr.l   #1,d2
         lsr.l   #1,d3
         bne     divlp
         lsr     #1,d4
         bcc.s   nonegrem
         neg.l   d1
nonegrem tst     d4
         beq.s   nonegquo
         neg.l   d0
nonegquo tst.l   d0
         movem.l (sp)+,d2-d4
         rts
zdivoflow moveq #-$41,d0
         movem.l (sp)+,d2-d4
         bra signal
         end
