home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / sozobon / sozolong.s < prev    next >
Text File  |  1992-05-15  |  3KB  |  118 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 -- separated unsigned routines to sozulong.s to reduce library drag
  8.  
  9.     .text
  10.     .even
  11.     .globl    lmul
  12.     .globl    ldiv
  13.     .globl    lrem
  14.  
  15. ldiv:
  16.     move.l    d2,a0        ; save registers
  17.     move.l    d3,a1
  18.     clr.w    -(sp)        ; sign flag
  19.     clr.l    d0        ; prepare result
  20.     move.l    10(sp),d2    ; get divisor
  21.     beq    L9        ; divisor = 0 causes a division trap
  22.     bpl    J0        ; divisor < 0 ?
  23.     neg.l    d2        ; negate it
  24.     not.w    (sp)        ; remember sign
  25. J0:    move.l    6(sp),d1    ; get dividend
  26.     bpl    J1        ; dividend < 0 ?
  27.     neg.l    d1        ; negate it
  28.     not.w    (sp)        ; remember sign
  29. J1:
  30. ;== case 1) divident < divisor
  31.     cmp.l    d2,d1        ; is divident smaller then divisor ?
  32.     bcs    L8        ; yes, return immediately
  33. ;== case 2) divisor has <= 16 significant bits
  34.     tst.w    10(sp)
  35.     bne    L2        ; divisor has only 16 bits
  36.     move.w    d1,d3        ; save dividend
  37.     clr.w    d1        ; divide dvd.h by dvs
  38.     swap    d1
  39.     beq    J2        ; (no division necessary if dividend zero)
  40.     divu    d2,d1
  41. J2:    move.w    d1,d0        ; save quotient.h
  42.     swap    d0
  43.     move.w    d3,d1        ; (d0.h = remainder of prev divu)
  44.     divu    d2,d1        ; divide dvd.l by dvs
  45.     move.w    d1,d0        ; save quotient.l
  46.     clr.w    d1        ; get remainder
  47.     swap    d1
  48.     bra    L8        ; and return
  49. ;== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
  50. L2:
  51.     moveq    #31,d3        ; loop count
  52. L3:
  53.     add.l    d1,d1        ; shift divident ...
  54.     addx.l    d0,d0        ;  ... into d0
  55.     cmp.l    d2,d0        ; compare with divisor
  56.     bcs    J3
  57.     sub.l    d2,d0        ; big enough, subtract
  58.     add.w    #1,d1        ; and note bit into result
  59. J3:
  60.     dbra    d3,L3
  61.     exg    d0,d1        ; put quotient and remainder in their registers
  62. L8:
  63.     tst.w    6(sp)        ; must the remainder be corrected ?
  64.     bpl    J4
  65.     neg.l    d1        ; yes, apply sign
  66. ; the following line would be correct if modulus is defined as in algebra
  67. ;    add.l    6(sp),d1    ; algebraic correction: modulus can only be >= 0
  68. J4:    tst.w    (sp)+        ; result should be negative ?
  69.     bpl    J5
  70.     neg.l    d0        ; yes, negate it
  71. J5:
  72.     move.l    a1,d3
  73.     move.l    a0,d2
  74.     rts
  75. L9:
  76.     divu    d2,d1        ; cause division trap
  77.     bra    L8        ; back to user
  78.  
  79. lrem:
  80.     move.l    8(sp),-(sp)    ; push divisor
  81.     move.l    8(sp),-(sp)    ; push dividend
  82.     bsr    ldiv
  83.     lea    8(sp),sp
  84.     move.l    d1,d0        ; return the remainder in d0
  85.     rts
  86.  
  87. lmul:
  88.     move.l    d2,a0        ; save registers
  89.     move.l    d3,a1
  90.     movem.w    4(sp),d0-d3    ; get the two longs. u = d0-d1, v = d2-d3
  91.     move.w    d0,-(sp)        ; sign flag
  92.     bpl    J6        ; is u negative ?
  93.     neg.w    d1        ; yes, force it positive
  94.     negx.w    d0
  95. J6:    tst.w    d2        ; is v negative ?
  96.     bpl    J7
  97.     neg.w    d3        ; yes, force it positive ...
  98.     negx.w    d2
  99.     not.w    (sp)        ;  ... and modify flag word
  100. J7:
  101.     ext.l    d0        ; u.h <> 0 ?
  102.     beq    M1
  103.     mulu    d3,d0        ; r  = v.l * u.h
  104. M1:    tst.w    d2        ; v.h <> 0 ?
  105.     beq    M2
  106.     mulu    d1,d2        ; r += v.h * u.l
  107.     add.w    d2,d0
  108. M2:    swap    d0
  109.     clr.w    d0
  110.     mulu    d3,d1        ; r += v.l * u.l
  111.     add.l    d1,d0
  112.     move.l    a1,d3
  113.     move.l    a0,d2
  114.     tst.w    (sp)+        ; should the result be negated ?
  115.     bpl    M3        ; no, just return
  116.     neg.l    d0        ; else r = -r
  117. M3:    rts
  118.