home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Utilities / ODMathM.a < prev    next >
Encoding:
Text File  |  1996-04-22  |  7.2 KB  |  331 lines  |  [TEXT/MPS ]

  1. ;
  2. ;    File:        ODMathM.a
  3. ;
  4. ;    Contains:    68k fixed-point and wide math for OpenDoc.
  5. ;
  6. ;    Owned by:    Jens Alfke
  7. ;    Written by:    Cary Clark and Robert Johnson
  8. ;
  9. ;    Copyright:    © 1987-89, 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  10. ;
  11. ;    To Do:
  12. ;        This file defines more routines than we need. For now I'm
  13. ;        leaving the extra ones here in case we need 'em later.
  14. ;        These routines are needed (on the Mac) only for 68k.
  15. ;        PowerPC versions are already in the PowerMac Toolbox.
  16. ;    In Progress:
  17. ;        
  18.  
  19.  
  20.             Machine        MC68020
  21.             MC68881
  22.             Case        On
  23.             Blanks        Off
  24.             
  25. NuRuntime    equ            1
  26.  
  27. negativeInfinity Equ    $80000000
  28. frac1        Equ            $40000000
  29.  
  30.             DataRefs     Relative
  31.             Import        (lastSinCosAngle,lastSine,lastCosine):Data
  32.         
  33. ;    fixed ODFixedMultiply(fixed a, fixed b)
  34. ODFixedMultiply        Func            Export
  35. _$ODFixedMultiply    Func            Export
  36.             move.l        (sp)+,a0
  37.             move.l        (sp),d1
  38.             muls.l         4(sp),d0:d1
  39.             moveq        #0,d2
  40.             add.l        #$00008000,d1
  41.             addx.l        d2,d0
  42.             swap        d1
  43.             swap        d0
  44.             move        d1,d0
  45.             addq.l        #8,sp
  46.             jmp            (a0)
  47.  
  48.  
  49. ;    fixed ODFixedDivide(fixed a, fixed b)
  50. ODFixedDivide        Func            Export
  51. _$ODFixedDivide        Func            Export
  52.             move.l        (sp)+,a0
  53.             move.l        4(sp),d2                get b
  54.             beq.s        @div0
  55.             bpl.s        @1
  56.             neg.l        d2
  57. @1            asr.l        #1,d2
  58.             move.l        (sp),d0                    get a
  59.             bpl.s        @2
  60.             neg.l        d2
  61. @2            swap        d0
  62.             move        d0,d1
  63.             ext.l        d1
  64.             clr.w        d0
  65.             add.l        d2,d0
  66.             bfexts        d2{0:1},d2
  67.             addx.l        d2,d1
  68.             divs.l         4(sp),d1:d0
  69.             bvc.s        @3
  70.             move.l        4(sp),d2                get b
  71. @div0        eor.l        d2,(sp)
  72.             bmi.s        @div1
  73.             move.l        #$7fffffff,d0
  74.             addq.l        #8,sp
  75.             jmp            (a0)
  76. @div1        move.l        #$80000000,d0
  77. @3            addq.l        #8,sp
  78.             jmp            (a0)
  79.  
  80.  
  81. ;    long ODMultiplyDivide(long a, long b, long c)
  82. ODMultiplyDivide        Func            Export
  83. _$ODMultiplyDivide        Func            Export
  84.             move.l        (sp)+,a0
  85.             lea            (sp),a1                    get parameters
  86.             move.l        (a1)+,d0                get a
  87.             move.l        (a1)+,d1                get b
  88.             move.l        (a1),d2                    get c
  89.             beq.s        @div0
  90.             bpl.s            @1
  91.             neg.l            d2
  92. @1            asr.l            #1,d2
  93.             muls.l         d1,d1:d0                compute a*b
  94.             bpl.s            @2
  95.             neg.l            d2
  96. @2            add.l            d2,d0
  97.             bfexts        d2{0:1},d2
  98.             addx.l        d2,d1
  99.             divs.l        (a1),d1:d0            compute a*b/c
  100.             bvc.s        @3
  101.             move.l        (a1),d0
  102. @div0        eor.l            d1,d0
  103.             bmi.s        @div1
  104.             move.l        #$7fffffff,d0
  105.             bra.s        @3
  106. @div1        move.l        #$80000000,d0
  107. @3            lea            12(sp),sp
  108.             jmp            (a0)
  109.  
  110. ;short ODFirstBit(long x)
  111. ODFirstBit    Func            Export
  112. _$ODFirstBit Func            Export
  113.             move.l            (sp)+,a0                get return address
  114.             move.l            (sp),d0                    get x
  115.             bfffo            d0{0:0},d1
  116.             moveq            #31,d0
  117.             sub.w            d1,d0
  118.             addq.l            #4,sp
  119.             jmp                (a0)
  120.  
  121. ;    fract ODFractMultiply(fract a, fract b)
  122. ODFractMultiply        Func            Export
  123. _$ODFractMultiply    Func            Export
  124.             move.l        (sp)+,a0
  125.             move.l        (sp),d1
  126.             muls.l         4(sp),d0:d1
  127.             moveq        #0,d2
  128.             add.l            #$20000000,d1
  129.             addx.l        d2,d0
  130.             lsl.l            #2,d0                     2.30 (toss overflow bits)    
  131.             rol.l            #2,d1
  132.             and            #3,d1                     get high 2 bits of low long
  133.             or            d1,d0
  134.             addq.l        #8,sp
  135.             jmp            (a0)
  136.  
  137.  
  138. ;    fixed ODFractDivide(fract a, fract b)
  139. ODFractDivide        Func        Export
  140. _$ODFractDivide        Func        Export
  141.             move.l        (sp)+,a0
  142.             move.l        4(sp),d2                get b
  143.             beq.s        @div0
  144.             bpl.s            @1
  145.             neg.l            d2
  146. @1            move.l        (sp),d1                    get a
  147.             bpl.s            @2
  148.             neg.l            d2
  149. @2            clr.l            d0
  150.             asr.l            #1,d1
  151.             roxr.l        #1,d0
  152.             add.l            d2,d0
  153.             bfexts        d2{0:1},d2
  154.             addx.l        d2,d1
  155.             asr.l            #1,d1
  156.             roxr.l        #1,d0
  157.             divs.l         4(sp),d1:d0
  158.             bvc.s        @3
  159.             move.l        4(sp),d2                get b
  160. @div0        eor.l            d2,(sp)
  161.             bmi.s        @div1
  162.             move.l        #$7fffffff,d0
  163.             addq.l        #8,sp
  164.             jmp            (a0)
  165. @div1        move.l        #$80000000,d0
  166. @3            addq.l        #8,sp
  167.             jmp            (a0)
  168.  
  169.  
  170. ;    fract ODFractSinCos(fixed radians, fract *b)
  171. ;
  172. ; ODFractSinCos requires the NuRuntime Prolog
  173. ; because it uses xxx(A5) relative references to data constants and so must
  174. ;"switch" A5
  175. ODFractSinCos    Func            Export
  176.     IF    NuRuntime THEN
  177.             MOVE.L    (A1),A5
  178.     ENDIF
  179. _$ODFractSinCos    Func            Export
  180.             move.l        (sp)+,a0
  181.             move.l        (sp),d0                    get degree
  182.             cmp.l        lastSinCosAngle(A5),d0
  183.             beq.s        @useOld
  184.             move.l        d0,lastSinCosAngle(A5)
  185. ;
  186. ; (original code expected input in degrees; remove this)
  187. ;            fmovecr.x    #0,fp0                get π
  188. ;            fdiv.w        #180,fp0                compute 1 degree in radians
  189. ;            fmul.l        d0,fp0                    multiply by angle
  190. ; here's what the above 3 instructions became:
  191.             fmove.l        d0,fp0                    angle already in radians
  192. ; (end fix)
  193.             fscale.w    #-16,fp0                bias by 16
  194.             fsincos.x    fp0,fp1:fp0
  195.             fscale.w    #30,fp0                bias by 30
  196.             fmove.l        fp0,d0    
  197.             fscale.w    #30,fp1                bias by 30
  198.             move.l        4(sp),a1
  199.             fmove.l        fp1,(a1)
  200.             move.l        d0,lastSine(A5)
  201.             move.l        (a1),lastCosine(A5)
  202.             addq.l        #8,sp
  203.             jmp            (a0)
  204. @useOld
  205.             move.l        4(sp),a1                    get b
  206.             move.l        lastSine(A5),d0
  207.             move.l        lastCosine(A5),(a1)
  208.             addq.l        #8,sp
  209.             jmp            (a0)
  210.  
  211.     
  212. ; wide *ODWideMultiply(long src1, long src2, wide *dst)
  213. ODWideMultiply        Func            Export
  214. _$ODWideMultiply    Func            Export
  215.             move.l        4(sp),d0
  216.             muls.l        8(sp), d1:d0
  217.             move.l        12(sp),a0
  218.             move.l        d1,(a0)+
  219.             move.l        d0,(a0)
  220.             move.l        12(sp),d0
  221.             rtd            #12
  222.  
  223.  
  224. ; long ODWideDivide(wide *num, long denom, long *rem)
  225. ODWideDivide    Func            Export
  226. _$ODWideDivide    Func            Export
  227.             link            a6,#-2
  228.             moveq        #-1,d0
  229.             cmp.l        16(a6),d0                if (rem == (void *)-1)
  230.             seq            -1(a6)                    set check
  231.             bne.s        @noCheck
  232.             clr.l            16(a6)                    rem = 0
  233. @noCheck
  234.             move.l        8(a6),a0                get num
  235.             move.l        (a0)+,d1
  236.             move.l        (a0),d0
  237.             move.l        12(a6),d2                get denom
  238.             beq.s        @div0
  239.             bpl.s            @1
  240.             neg.l            d2
  241. @1            tst.l            16(a6)                    check rem
  242.             bne.s        @3
  243.             lsr.l            #1,d2
  244.             tst.l            d1
  245.             bpl.s            @2
  246.             neg.l            d2
  247. @2            add.l            d2,d0
  248.             bfexts        d2{0:1},d2
  249.             addx.l        d2,d1
  250. @3            divs.l        12(a6),d1:d0
  251.             bvc.s        @ok
  252.             move.l        12(a6),d2
  253. @div0        tst.b            -1(a6)                    check check
  254.             bne.s        @div1
  255.             eor.l            d1,d2
  256.             bmi.s        @div1
  257.             move.l        #$7FFFFFFF,d0
  258.             bra.s        @div2
  259. @div1        move.l        #$80000000,d0
  260. @div2        move.l        #$80000000,d1
  261. @ok            move.l        16(a6),d2                get rem
  262.             beq.s        @done
  263.             move.l        d2,a0
  264.             move.l        d1,(a0)
  265. @done        unlk        a6
  266.             rtd            #12
  267.  
  268. ; long ODWideSquareRoot(wide *src)
  269. ODWideSquareRoot    Func            Export
  270. _$ODWideSquareRoot    Func            Export
  271.             move.l        (sp)+,a0
  272.             move.l        #$80000000,d1
  273.             fmove.l        d1,fp1
  274.             move.l        (sp),a1                        Get src
  275.             move.l        (a1)+,d0                    Get hi long
  276.             add.l            d1,d0                        Offset for sign
  277.             fmove.l        d0,fp0                        Move to FP0
  278.             fsub.x        fp1,fp0                        Compensate for offset
  279.             fscale.w    #32,fp0                    Shift by 32
  280.             move.l        (a1),d0                        Get lo long
  281.             add.l            d1,d0                        Offset for sign
  282.             fadd.l        d0,fp0                        Add to FP0
  283.             fsub.x        fp1,fp0                        Compensate for offset
  284.             fsqrt.x        fp0                            The whole point
  285.             fadd.x        fp1,fp0                        Offset for sign
  286.             fmove.l        fp0,d0                        Pass result to D0
  287.             sub.l            d1,d0                        Compensate for offset
  288.             addq.l        #4,sp
  289.             jmp            (a0)
  290.  
  291. ;fract ODFractCubeRoot(fract x)
  292. ODFractCubeRoot        Func        Export
  293. _$ODFractCubeRoot    Func        Export
  294.             move.l        (sp)+,a0            ;get return address
  295.             move.l        (sp),d0                ;get x
  296.             beq.s        @2
  297.             smi            d1                    ;save the sign
  298.             bpl.s            @1
  299.             neg.l            d0
  300. @1            fmove.l        d0,fp0
  301.             flogn            fp0                    ;take its logarithm
  302.             fdiv.w        #3,fp0
  303.             fetox        fp0                    ;exponentiate
  304.             fscale.w    #20,fp0            ;scale for fract
  305.             fmove.l        fp0,d0
  306.             tst.b            d1                    ;check the sign
  307.             beq.s        @2
  308.             neg.l            d0
  309. @2            addq.l        #4,sp
  310.             jmp         (a0)
  311.  
  312.  
  313.     IF NuRuntime THEN
  314.     
  315.         XVector    ODFixedMultiply:0
  316.         XVector    ODFixedDivide:0
  317.         XVector    ODMultiplyDivide:0
  318.         XVector    ODFirstBit:0
  319.         XVector    ODFractMultiply:0
  320.         XVector    ODFractDivide:0
  321.  
  322.         XVector    ODFractSinCos:0
  323.  
  324.          XVector    ODWideMultiply:0
  325.         XVector    ODWideDivide:0
  326.         XVector    ODWideSquareRoot:0
  327.         XVector    ODFractCubeRoot:0
  328.  
  329.     ENDIF
  330.  
  331.             End