home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib32.zoo / sozobon / sozulong.s < prev    next >
Text File  |  1992-05-15  |  2KB  |  88 lines

  1. ; long arithmetic routines
  2. ;
  3. ; written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  4. ;
  5. ; Names changed and converted from MIT to Motorola syntax by Dave Gymer for SC
  6. ;
  7. ; 5/5/92 sb -- unsigned routines separated out to reduce library drag
  8.  
  9.     .text
  10.     .even
  11.     .globl    lmulu
  12.     .globl    ldivu
  13.     .globl    lremu
  14.  
  15. ldivu:
  16.     move.l    d2,a0        ; save registers
  17.     move.l    d3,a1
  18.     clr.l    d0        ; prepare result
  19.     move.l    8(sp),d2    ; get divisor
  20.     beq    N9        ; divisor = 0 causes a division trap
  21.     move.l    4(sp),d1    ; get dividend
  22. ;== case 1) divident < divisor
  23.     cmp.l    d2,d1        ; is divident smaller then divisor ?
  24.     bcs    N8        ; yes, return immediately
  25. ;== case 2) divisor has <= 16 significant bits
  26.     tst.w    8(sp)
  27.     bne    N2        ; divisor has only 16 bits
  28.     move.w    d1,d3        ; save dividend
  29.     clr.w    d1        ; divide dvd.h by dvs
  30.     swap    d1
  31.     beq    K0        ; (no division necessary if dividend zero)
  32.     divu    d2,d1
  33. K0:    move.w    d1,d0        ; save quotient.h
  34.     swap    d0
  35.     move.w    d3,d1        ; (d1.h = remainder of prev divu)
  36.     divu    d2,d1        ; divide dvd.l by dvs
  37.     move.w    d1,d0        ; save quotient.l
  38.     clr.w    d1        ; get remainder
  39.     swap    d1
  40.     bra    N8        ; and return
  41. ;== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
  42. N2:
  43.     moveq    #31,d3        ; loop count
  44. N3:
  45.     add.l    d1,d1        ; shift divident ...
  46.     addx.l    d0,d0        ;  ... into d0
  47.     cmp.l    d2,d0        ; compare with divisor
  48.     bcs    K1
  49.     sub.l    d2,d0        ; big enough, subtract
  50.     add.w    #1,d1        ; and note bit in result
  51. K1:
  52.     dbra    d3,N3
  53.     exg    d0,d1        ; put quotient and remainder in their registers
  54. N8:
  55.     move.l    a1,d3
  56.     move.l    a0,d2
  57.     rts
  58. N9:
  59.     divu    d2,d1        ; cause division trap
  60.     bra    N8        ; back to user
  61.  
  62. lremu:
  63.     move.l    8(sp),-(sp)    ; push divisor
  64.     move.l    8(sp),-(sp)    ; push dividend
  65.     bsr    ldivu
  66.     lea    8(sp),sp
  67.     move.l    d1,d0        ; return the remainder in d0
  68.     rts
  69.  
  70. lmulu:
  71.     move.l    d2,a0        ; save registers
  72.     move.l    d3,a1
  73.     movem.w    4(sp),d0-d3    ; get the two longs. u = d0-d1, v = d2-d3
  74.     ext.l    d0        ; u.h <> 0 ?
  75.     beq    O1
  76.     mulu    d3,d0        ; r  = v.l * u.h
  77. O1:    tst.w    d2        ; v.h <> 0 ?
  78.     beq    O2
  79.     mulu    d1,d2        ; r += v.h * u.l
  80.     add.w    d2,d0
  81. O2:    swap    d0
  82.     clr.w    d0
  83.     mulu    d3,d1        ; r += v.l * u.l
  84.     add.l    d1,d0
  85.     move.l    a1,d3
  86.     move.l    a0,d2
  87.     rts
  88.