home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / graf / fract3.zip / FPU087.ASM < prev    next >
Assembly Source File  |  1989-12-20  |  28KB  |  1,256 lines

  1. TITLE fpu087.asm (C) 1989, Mark C. Peterson, CompuServe [70441,3353]
  2. SUBTTL All rights reserved.
  3. ;
  4. ;  Code may be used in any program provided the author is credited
  5. ;    either during program execution or in the documentation.  Source
  6. ;    code may be distributed only in combination with public domain or
  7. ;    shareware source code.  Source code may be modified provided the
  8. ;    copyright notice and this message is left unchanged and all
  9. ;    modifications are clearly documented.
  10. ;
  11. ;    I would appreciate a copy of any work which incorporates this code,
  12. ;    however this is optional.
  13. ;
  14. ;    Mark C. Peterson
  15. ;    128 Hamden Ave., F
  16. ;    Waterbury, CT 06704
  17. ;    (203) 754-1162
  18. ;
  19. ;  Note: Remark statements following floating point commands generally indicate
  20. ;     the FPU stack contents after the command is completed.
  21. ;
  22. ;  References:
  23. ;     80386/80286 Assembly Language Programming
  24. ;        by William H. Murray, III and Chris H. Pappas
  25. ;        Published by Osborne McGraw-Hill, 1986
  26. ;        
  27. ;
  28. ;
  29.  
  30.  
  31. IFDEF ??version
  32. MASM51
  33. QUIRKS
  34. EMUL
  35. ENDIF
  36.  
  37. .model medium, c
  38.  
  39. extrn cos:far
  40. extrn _Loaded387sincos:far
  41. extrn compiled_by_turboc:word
  42.  
  43.  
  44. .data
  45.  
  46. extrn cpu:WORD
  47.  
  48. PUBLIC TrigLimit, TrigOverflow
  49.  
  50. PiFg13         dw       6487h
  51. InvPiFg17      dw       0a2f9h
  52. InvPiFg33      dd       0a2f9836eh
  53. InvPiFg16      dw       517ch
  54. Ln2Fg16        dw       0b172h
  55. TrigOverflow   dw       0
  56. TrigLimit      dd       0
  57. one            dw       ?
  58. expSign        dw       ?
  59. exp            dw       ?
  60. SinNeg         dw       ?
  61. CosNeg         dw       ?
  62.  
  63.  
  64. MP STRUC
  65.    Exp   DW    0
  66.    Mant  DD    0
  67. MP ENDS
  68.  
  69. Ans         MP       <?>
  70.  
  71. Four        dq    4.0
  72. Two         dq    2.0
  73. One         dq    1.0
  74. PointFive   dq    0.5
  75. temp        dq     ?
  76. Sign        dw     ?
  77.  
  78. extrn fpu:word
  79.  
  80. .code
  81.  
  82.  
  83. FPUcplxmul     PROC     x:word, y:word, z:word
  84.    mov   bx, x
  85.    fld   QWORD PTR [bx]       ; x.x
  86.    fld   QWORD PTR [bx+8]     ; x.y, x.x
  87.    mov   bx, y
  88.    fld   QWORD PTR [bx]       ; y.x, x.y, x.x
  89.    fld   QWORD PTR [bx+8]     ; y.y, y.x, x.y, x.x
  90.    mov   bx, z
  91.    fld   st                   ; y.y, y.y, y.x, x.y, x.x
  92.    fmul  st, st(3)            ; y.y*x.y, y.y. y.x, x.y, x.x
  93.    fld   st(2)                ; y.x, y.y*x.y, y.y, y.x, x.y, x.x
  94.    fmul  st, st(5)            ; y.x*x.x, y.y*x.y, y.y, y.x, x.y, x.x
  95.    fsubr                      ; y.x*x.x - y.y*x.y, y.y, y.x, x.y, x.x
  96.    fstp  QWORD PTR [bx]       ; y.y, y.x, x.y, x.x
  97.    fmulp st(3), st            ; y.x, x.y, x.x*y.y
  98.    fmul                       ; y.x*x.y, x.x*y.y
  99.    fadd                       ; y.x*x.y + x.x*y.y
  100.    fstp  QWORD PTR [bx+8]
  101.    ret
  102. FPUcplxmul     ENDP
  103.  
  104.  
  105.  
  106.  
  107.  
  108. FPUcplxdiv     PROC     x:word, y:word, z:word
  109.    mov   bx, x
  110.    fld   QWORD PTR [bx]       ; x.x
  111.    fld   QWORD PTR [bx+8]     ; x.y, x.x
  112.    mov   bx, y
  113.    fld   QWORD PTR [bx]       ; y.x, x.y, x.x
  114.    fld   QWORD PTR [bx+8]     ; y.y, y.x, x.y, x.x
  115.    fld   st                   ; y.y, y.y, y.x, x.y, x.x
  116.    fmul  st, st               ; y.y*y.y, y.y, y.x, x.y, x.x
  117.    fld   st(2)                ; y.x, y.y*y.y, y.y, y.x, x.y, x.x
  118.    fmul  st, st               ; y.x*y.x, y.y*y.y, y.y, y.x, x.y, x.x
  119.    fadd                       ; mod, y.y, y.x, x.y, x.x
  120.    fdiv  st(1), st            ; mod, y.y=y.y/mod, y.x, x.y, x.x
  121.    fdivp st(2), st            ; y.y, y.x=y.x/mod, x.y, x.x
  122.    mov   bx, z
  123.    fld   st                   ; y.y, y.y, y.x, x.y, x.x
  124.    fmul  st, st(3)            ; y.y*x.y, y.y. y.x, x.y, x.x
  125.    fld   st(2)                ; y.x, y.y*x.y, y.y, y.x, x.y, x.x
  126.    fmul  st, st(5)            ; y.x*x.x, y.y*x.y, y.y, y.x, x.y, x.x
  127.    fadd                       ; y.x*x.x - y.y*x.y, y.y, y.x, x.y, x.x
  128.    fstp  QWORD PTR [bx]       ; y.y, y.x, x.y, x.x
  129.    fmulp st(3), st            ; y.x, x.y, x.x*y.y
  130.    fmul                       ; y.x*x.y, x.x*y.y
  131.    fsubr                      ; y.x*x.y + x.x*y.y
  132.    fstp  QWORD PTR [bx+8]
  133.    ret
  134. FPUcplxdiv     ENDP
  135.  
  136.  
  137.  
  138. FPUcplxlog     PROC     x:word, z:word
  139. LOCAL Status:word
  140.    mov   bx, x
  141.    fld   QWORD PTR [bx+8]        ; x.y
  142.    fld   QWORD PTR [bx]          ; x.x, x.y
  143.    mov   bx, z
  144.    fldln2                        ; ln2, x.x, x.y
  145.    fdiv  Two                     ; ln2/2, x.x, x.y
  146.    fld   st(2)                   ; x.y, ln2/2, x.x, x.y
  147.    fmul  st, st                  ; sqr(x.y), ln2/2, x.x, x.y
  148.    fld   st(2)                   ; x.x, sqr(x.y), ln2/2, x.x, x.y
  149.    fmul  st, st                  ; sqr(x.x), sqr(x.y), ln2/2, x.x, x.y
  150.    fadd                          ; mod, ln2/2, x.x, x.y
  151.    fyl2x                         ; z.x, x.x, x.y
  152.    fstp  QWORD PTR [bx]          ; x.x, x.y
  153.    cmp   fpu, 387
  154.    jne   Restricted
  155.  
  156.    fpatan
  157.    jmp   StoreZX
  158.  
  159. Restricted:
  160.    mov   bx, x
  161.    mov   dh, BYTE PTR [bx+7]
  162.    or    dh, dh
  163.    jns   ChkYSign
  164.  
  165.    fchs                          ; |x.x|, x.y
  166.  
  167. ChkYSign:
  168.    mov   dl, BYTE PTR [bx+8+7]
  169.    or    dl, dl
  170.    jns   ChkMagnitudes
  171.  
  172.    fxch                          ; x.y, |x.x|
  173.    fchs                          ; |x.y|, |x.x|
  174.    fxch                          ; |x.x|, |x.y|
  175.  
  176. ChkMagnitudes:
  177.    fcom  st(1)                   ; x.x, x.y
  178.    fstsw Status                  ; x.x, x.y
  179.    test  Status, 4500h
  180.    jz    XisGTY
  181.  
  182.    test  Status, 4000h
  183.    jz    XneY
  184.  
  185.    fstp  st                      ; x.y
  186.    fstp  st                      ; <empty>
  187.    fldpi                         ; Pi
  188.    fdiv  Four                    ; Pi/4
  189.    jmp   ChkSignZ
  190.  
  191. XneY:
  192.    fxch                          ; x.y, x.x
  193.    fpatan                        ; Pi/2 - Angle
  194.    fldpi                         ; Pi, Pi/2 - Angle
  195.    fdiv  Two                     ; Pi/2, Pi/2 - Angle
  196.    fsubr                         ; Angle
  197.    jmp   ChkSignZ
  198.  
  199. XisGTY:
  200.    fpatan
  201.  
  202. ChkSignZ:
  203.    or    dh, dh
  204.    js    NegX
  205.  
  206.    or    dl, dl
  207.    jns   StoreZX
  208.  
  209.    fchs
  210.    jmp   StoreZX
  211.  
  212. NegX:
  213.    or    dl, dl
  214.    js    QuadIII
  215.  
  216.    fldpi
  217.    fsubr
  218.    jmp   StoreZX
  219.  
  220. QuadIII:
  221.    fldpi
  222.    fsubr
  223.    fchs
  224.  
  225. StoreZX:
  226.    mov   bx, z
  227.    fstp  QWORD PTR [bx+8]        ; <empty>
  228.    ret
  229. FPUcplxlog     ENDP
  230.  
  231.  
  232.  
  233.  
  234. FPUsinhcosh    PROC     x:word, sinh:word, cosh:word
  235. LOCAL Control:word
  236.    fstcw Control
  237.    push  Control                       ; Save control word on the stack
  238.    or    Control, 0000110000000000b 
  239.    fldcw Control                       ; Set control to round towards zero
  240.  
  241.    mov   Sign, 0              ; Assume the sign is positive
  242.    mov   bx, x
  243.  
  244.    fldln2                     ; ln(2)
  245.    fdivr QWORD PTR [bx]       ; x/ln(2)
  246.  
  247.    cmp   BYTE PTR [bx+7], 0
  248.    jns   DuplicateX
  249.  
  250.    fchs                       ; x = |x|
  251.  
  252. DuplicateX:   
  253.    fld   st                   ; x/ln(2), x/ln(2)
  254.    frndint                    ; int = integer(|x|/ln(2)), x/ln(2)
  255.    fxch                       ; x/ln(2), int
  256.    fsub  st, st(1)            ; rem < 1.0, int
  257.    fdiv  Two                  ; rem/2 < 0.5, int
  258.    f2xm1                      ; (2**rem/2)-1, int
  259.    fadd  One                  ; 2**rem/2, int
  260.    fmul  st, st               ; 2**rem, int
  261.    fscale                     ; e**|x|, int
  262.    fstp  st(1)                ; e**|x|
  263.  
  264.    cmp   BYTE PTR [bx+7], 0
  265.    jns   ExitFexp
  266.  
  267.    fdivr One                  ; e**x      
  268.  
  269. ExitFexp:
  270.    fld   st                   ; e**x, e**x
  271.    fdivr PointFive            ; e**-x/2, e**x
  272.    fld   st                   ; e**-x/2, e**-x/2, e**x
  273.    fxch  st(2)                ; e**x, e**-x/2, e**-x/2
  274.    fdiv  Two                  ; e**x/2,  e**-x/2, e**-x/2
  275.    fadd  st(2), st            ; e**x/2,  e**-x/2, cosh(x)
  276.    fsubr                      ; sinh(x), cosh(x)
  277.  
  278.    mov   bx, sinh             ; sinh, cosh
  279.    fstp  QWORD PTR [bx]       ; cosh
  280.    mov   bx, cosh
  281.    fstp  QWORD PTR [bx]       ; <empty>
  282.  
  283.    pop   Control
  284.    fldcw Control              ; Restore control word
  285.    ret
  286. FPUsinhcosh    ENDP
  287.  
  288.  
  289. FPUsincos  PROC  x:word, sinx:word, cosx:word
  290. LOCAL Status:word
  291.    mov   bx, x
  292.    fld   QWORD PTR [bx]       ; x
  293.  
  294.    cmp   fpu, 387
  295.    jne   Use387FPUsincos
  296.  
  297.    call  _Loaded387sincos     ; cos(x), sin(x)
  298.    mov   bx, cosx
  299.    fstp  QWORD PTR [bx]       ; sin(x)
  300.    mov   bx, sinx
  301.    fstp  QWORD PTR [bx]       ; <empty>
  302.    ret
  303.  
  304. Use387FPUsincos:
  305.  
  306.    sub   sp, 8                ; save 'x' on the CPU stack
  307.    mov   bx, sp
  308.    fstp  QWORD PTR [bx]       ; FPU stack:  <empty>
  309.  
  310.    call  cos
  311.  
  312.    add   sp, 8                ; take 'cos(x)' off the CPU stack
  313.    mov   bx, ax
  314.    cmp   compiled_by_turboc,0
  315.    jne   turbo_c1
  316.  
  317.    fld   QWORD PTR [bx]       ; FPU stack:  cos(x)
  318.  
  319. turbo_c1:
  320.    fld   st                   ; FPU stack:  cos(x), cos(x)
  321.    fmul  st, st               ; cos(x)**2, cos(x)
  322.    fsubr One                  ; sin(x)**2, cos(x)
  323.    fsqrt                      ; +/-sin(x), cos(x)
  324.  
  325.    mov   bx, x
  326.    fld   QWORD PTR [bx]       ; x, +/-sin(x), cos(x)
  327.    fldpi                      ; Pi, x, +/-sin(x), cos(x)
  328.    fadd  st, st               ; 2Pi, x, +/-sin(x), cos(x)
  329.    fxch                       ; |x|, 2Pi, +/-sin(x), cos(x)
  330.    fprem                      ; Angle, 2Pi, +/-sin(x), cos(x)
  331.    fstp  st(1)                ; Angle, +/-sin(x), cos(x)
  332.    fldpi                      ; Pi, Angle, +/-sin(x), cos(x)
  333.  
  334.    cmp   BYTE PTR [bx+7], 0
  335.    jns   SignAlignedPi
  336.  
  337.    fchs                       ; -Pi, Angle, +/-sin(x), cos(x)
  338.  
  339. SignAlignedPi:
  340.    fcompp                     ; +/-sin(x), cos(x)
  341.    fstsw Status               ; +/-sin(x), cos(x)
  342.  
  343.    mov   ax, Status
  344.    and   ah, 1
  345.    jz    StoreSinCos          ; Angle <= Pi
  346.  
  347.    fchs                       ; sin(x), cos(x)
  348.  
  349. StoreSinCos:
  350.    mov   bx, sinx
  351.    fstp  QWORD PTR [bx]       ; cos(x)
  352.    mov   bx, cosx
  353.    fstp  QWORD PTR [bx]       ; <empty>
  354.    ret
  355. FPUsincos   ENDP
  356.  
  357.  
  358. PUBLIC r16Mul
  359. r16Mul     PROC    uses si di, x1:word, x2:word, y1:word, y2:word
  360.       mov   si, x1
  361.       mov   bx, x2
  362.       mov   di, y1
  363.       mov   cx, y2
  364.  
  365.       xor   ax, ax
  366.       shl   bx, 1
  367.       jz    Exitr16Mult          ; Destination is zero
  368.  
  369.       rcl   ah, 1
  370.       shl   cx, 1
  371.       jnz   Chkr16Exp
  372.       xor   bx, bx               ; Source is zero
  373.       xor   si, si
  374.       jmp   Exitr16Mult
  375.  
  376.    Chkr16Exp:
  377.       rcl   al, 1
  378.       xor   ah, al               ; Resulting sign in ah
  379.       stc                        ; Put 'one' bit back into number
  380.       rcr   bl, 1
  381.       stc
  382.       rcr   cl, 1
  383.  
  384.       sub   ch, 127              ; Determine resulting exponent
  385.       add   bh, ch
  386.       mov   al, bh
  387.       mov   es, ax               ; es has the resulting exponent and sign
  388.  
  389.       mov   ax, di
  390.       mov   al, ah
  391.       mov   ah, cl
  392.  
  393.       mov   dx, si
  394.       mov   dl, dh
  395.       mov   dh, bl
  396.  
  397.       mul   dx
  398.       mov   cx, es
  399.  
  400.       shl   ax, 1
  401.       rcl   dx, 1
  402.       jnc   Remr16MulOneBit      ; 'One' bit is the next bit over
  403.  
  404.       inc   cl                   ; 'One' bit removed with previous shift
  405.       jmp   Afterr16MulNorm
  406.  
  407.    Remr16MulOneBit:
  408.       shl   ax, 1
  409.       rcl   dx, 1
  410.  
  411.    Afterr16MulNorm:
  412.       mov   bl, dh               ; Perform remaining 8 bit shift
  413.       mov   dh, dl
  414.       mov   dl, ah
  415.       mov   si, dx
  416.       mov   bh, cl               ; Put in the exponent
  417.       rcr   ch, 1                ; Get the sign
  418.       rcr   bx, 1                ; Normalize the result
  419.       rcr   si, 1
  420.    Exitr16Mult:
  421.       mov   ax, si
  422.       mov   dx, bx
  423.       ret
  424. r16Mul      ENDP
  425.  
  426.  
  427. PUBLIC RegFloat2Fg
  428. RegFloat2Fg     PROC    x1:word, x2:word, Fudge:word
  429.       mov   ax, WORD PTR x1
  430.       mov   dx, WORD PTR x2
  431.       mov   bx, ax
  432.       or    bx, dx
  433.       jz    ExitRegFloat2Fg
  434.  
  435.       xor   bx, bx
  436.       mov   cx, bx
  437.  
  438.       shl   ax, 1
  439.       rcl   dx, 1
  440.       rcl   bx, 1                   ; bx contains the sign
  441.  
  442.       xchg  cl, dh                  ; cx contains the exponent
  443.  
  444.       stc                           ; Put in the One bit
  445.       rcr   dl, 1
  446.       rcr   ax, 1
  447.  
  448.       sub   cx, 127 + 23
  449.       add   cx, Fudge
  450.       jz    ChkFgSign
  451.       jns   ShiftFgLeft
  452.  
  453.       neg   cx
  454.    ShiftFgRight:
  455.       shr   dx, 1
  456.       rcr   ax, 1
  457.       loop  ShiftFgRight
  458.       jmp   ChkFgSign
  459.  
  460.    ShiftFgLeft:
  461.       shl   ax, 1
  462.       rcl   dx, 1
  463.       loop  ShiftFgLeft
  464.  
  465.    ChkFgSign:
  466.       or    bx, bx
  467.       jz    ExitRegFloat2Fg
  468.  
  469.       not   ax
  470.       not   dx
  471.       add   ax, 1
  472.       adc   dx, 0
  473.  
  474.    ExitRegFloat2Fg:
  475.       ret
  476. RegFloat2Fg    ENDP
  477.  
  478.  
  479.  
  480. PUBLIC ExpFudged
  481. ExpFudged      PROC     uses si, x_low:word, x_high:word, Fudge:word
  482.       xor   ax, ax
  483.       mov   WORD PTR Ans, ax
  484.       mov   WORD PTR Ans + 2, ax
  485.       mov   ax, WORD PTR x_low
  486.       mov   dx, WORD PTR x_high
  487.       or    dx, dx
  488.       js    NegativeExp
  489.  
  490.       div   Ln2Fg16
  491.       mov   exp, ax
  492.       or    dx, dx
  493.       jz    Raiseexp
  494.  
  495.       mov   ax, dx
  496.       mov   si, dx
  497.       mov   bx, 1
  498.  
  499.    PosExpLoop:
  500.       add   WORD PTR Ans, ax
  501.       adc   WORD PTR Ans + 2, 0
  502.       inc   bx
  503.       mul   si
  504.       mov   ax, dx
  505.       xor   dx, dx
  506.       div   bx
  507.       or    ax, ax
  508.       jnz   PosExpLoop
  509.  
  510.    Raiseexp:
  511.       inc   WORD PTR Ans + 2
  512.       mov   ax, WORD PTR Ans
  513.       mov   dx, WORD PTR Ans + 2
  514.       mov   cx, -16
  515.       add   cx, Fudge
  516.       add   cx, exp
  517.       or    cx, cx
  518.       jz    ExitExpFudged
  519.       jns   LeftShift
  520.       neg   cx
  521.  
  522.    RightShift:
  523.       shr   dx, 1
  524.       rcr   ax, 1
  525.       loop  RightShift
  526.       jmp   ExitExpFudged
  527.  
  528.    NegativeExp:
  529.       not   ax
  530.       not   dx
  531.       add   ax, 1
  532.       adc   dx, 0
  533.       div   Ln2Fg16
  534.       neg   ax
  535.       mov   exp, ax
  536.  
  537.       or    dx, dx
  538.       jz    Raiseexp
  539.  
  540.       mov   ax, dx
  541.       mov   si, dx
  542.       mov   bx, 1
  543.  
  544.    NegExpLoop:
  545.       sub   WORD PTR Ans, ax
  546.       sbb   WORD PTR Ans + 2, 0
  547.       inc   bx
  548.       mul   si
  549.       mov   ax, dx
  550.       xor   dx, dx
  551.       div   bx
  552.       or    ax, ax
  553.       jz    Raiseexp
  554.  
  555.       add   WORD PTR Ans, ax
  556.       adc   WORD PTR Ans + 2, 0
  557.       inc   bx
  558.       mul   si
  559.       mov   ax, dx
  560.       xor   dx, dx
  561.       div   bx
  562.       or    ax, ax
  563.       jnz   NegExpLoop
  564.       jmp   Raiseexp
  565.  
  566.    LeftShift:
  567.       shl   ax, 1
  568.       rcl   dx, 1
  569.       loop  LeftShift
  570.  
  571.    ExitExpFudged:
  572.       ret
  573. ExpFudged      ENDP
  574.  
  575.  
  576.  
  577. PUBLIC   LogFudged
  578. LogFudged      PROC     uses si di es, x_low:word, x_high:word, Fudge:word
  579.       xor   bx, bx
  580.       mov   cx, 16
  581.       sub   cx, Fudge
  582.       mov   ax, x_low
  583.       mov   dx, x_high
  584.  
  585.       or    dx, dx
  586.       jz    ChkLowWord
  587.  
  588.    Incexp:
  589.       shr   dx, 1
  590.       jz    DetermineOper
  591.       rcr   ax, 1
  592.       inc   cx
  593.       jmp   Incexp
  594.  
  595.    ChkLowWord:
  596.       or    ax, ax
  597.       jnz   Decexp
  598.       jmp   ExitLogFudged
  599.  
  600.    Decexp:
  601.       dec   cx                      ; Determine power of two
  602.       shl   ax, 1
  603.       jnc   Decexp
  604.  
  605.    DetermineOper:
  606.       mov   exp, cx
  607.       mov   si, ax                  ; si =: x + 1
  608.       shr   si, 1
  609.       stc
  610.       rcr   si, 1
  611.       mov   dx, ax
  612.       xor   ax, ax
  613.       shr   dx, 1
  614.       rcr   ax, 1
  615.       shr   dx, 1
  616.       rcr   ax, 1                   ; dx:ax = x - 1
  617.       div   si
  618.  
  619.       mov   bx, ax                  ; ax, Fudged 16, max of 0.3333333
  620.       shl   ax, 1                   ; x = (x - 1) / (x + 1), Fudged 16
  621.       mul   ax
  622.       shl   ax, 1
  623.       rcl   dx, 1
  624.       mov   ax, dx                  ; dx:ax, Fudged 35, max = 0.1111111
  625.       mov   si, ax                  ; si = (ax * ax), Fudged 19
  626.  
  627.       mov   ax, bx
  628.    ; bx is the accumulator, First term is x
  629.       mul   si                      ; dx:ax, Fudged 35, max of 0.037037
  630.       mov   es, dx                  ; Save high word, Fudged (35 - 16) = 19
  631.       mov   di, 0c000h              ; di, 3 Fudged 14
  632.       div   di                      ; ax, Fudged (36 - 14) = 21
  633.       or    ax, ax
  634.       jz    Addexp
  635.  
  636.       mov   cl, 5
  637.       shr   ax, cl
  638.       add   bx, ax                  ; bx, max of 0.345679
  639.    ; x = x + x**3/3
  640.  
  641.       mov   ax, es                  ; ax, Fudged 19
  642.       mul   si                      ; dx:ax, Fudged 38, max of 0.004115
  643.       mov   es, dx                  ; Save high word, Fudged (38 - 16) = 22
  644.       mov   di, 0a000h              ; di, 5 Fudged 13
  645.       div   di                      ; ax, Fudged (38 - 13) = 25
  646.       or    ax, ax
  647.       jz    Addexp
  648.  
  649.       mov   cl, 9
  650.       shr   ax, cl
  651.       add   bx, ax
  652.    ; x = x + x**3/3 + x**5/5
  653.  
  654.       mov   ax, es                  ; ax, Fudged 22
  655.       mul   si                      ; dx:ax, Fudged 41, max of 0.0004572
  656.       mov   di, 0e000h              ; di, 7 Fudged 13
  657.       div   di                      ; ax, Fudged (41 - 13) = 28
  658.       mov   cl, 12
  659.       shr   ax, cl
  660.       add   bx, ax
  661.  
  662.    Addexp:
  663.       shl   bx, 1                   ; bx *= 2, Fudged 16, max of 0.693147
  664.    ; x = 2 * (x + x**3/3 + x**5/5 + x**7/7)
  665.       mov   cx, exp
  666.       mov   ax, Ln2Fg16            ; Answer += exp * Ln2Fg16
  667.       or    cx, cx
  668.       js    SubFromAns
  669.  
  670.       mul   cx
  671.       add   ax, bx
  672.       adc   dx, 0
  673.       jmp   ExitLogFudged
  674.  
  675.    SubFromAns:
  676.       neg   cx
  677.       mul   cx
  678.       xor   cx, cx
  679.       xchg  cx, dx
  680.       xchg  bx, ax
  681.       sub   ax, bx
  682.       sbb   dx, cx
  683.  
  684.    ExitLogFudged:
  685.    ; x = 2 * (x + x**3/3 + x**5/5 + x**7/7) + (exp * Ln2Fg16)
  686.       ret
  687. LogFudged      ENDP
  688.  
  689.  
  690.  
  691.  
  692. PUBLIC LogFloat14
  693. LogFloat14     PROC     x1:word, x2:word
  694.       mov   ax, WORD PTR x1
  695.       mov   dx, WORD PTR x2
  696.       shl   ax, 1
  697.       rcl   dx, 1
  698.       xor   cx, cx
  699.       xchg  cl, dh
  700.  
  701.       stc
  702.         rcr   dl, 1
  703.         rcr   ax, 1
  704.  
  705.       sub   cx, 127 + 23
  706.       neg   cx
  707.       push  cx
  708.       push  dx
  709.       push  ax
  710.       call  LogFudged
  711.       add   sp, 6
  712.       ret
  713. LogFloat14     ENDP
  714.  
  715.  
  716. PUBLIC RegFg2Float
  717. RegFg2Float     PROC   x1:word, x2:word, FudgeFact:byte
  718.       mov   ax, x1
  719.       mov   dx, x2
  720.  
  721.       mov   cx, ax
  722.       or    cx, dx
  723.       jz    ExitFudgedToRegFloat
  724.  
  725.       mov   ch, 127 + 32
  726.       sub   ch, FudgeFact
  727.       xor   cl, cl
  728.       shl   ax, 1       ; Get the sign bit
  729.       rcl   dx, 1
  730.       jnc   FindOneBit
  731.  
  732.       inc   cl          ; Fudged < 0, convert to postive
  733.       not   ax
  734.       not   dx
  735.       add   ax, 1
  736.       adc   dx, 0
  737.  
  738.    FindOneBit:
  739.       shl   ax, 1
  740.       rcl   dx, 1
  741.       dec   ch
  742.       jnc   FindOneBit
  743.       dec   ch
  744.  
  745.       mov   al, ah
  746.       mov   ah, dl
  747.       mov   dl, dh
  748.       mov   dh, ch
  749.  
  750.       shr   cl, 1       ; Put sign bit in
  751.       rcr   dx, 1
  752.       rcr   ax, 1
  753.  
  754.    ExitFudgedToRegFloat:
  755.       ret
  756. RegFg2Float      ENDP
  757.  
  758.  
  759. PUBLIC RegSftFloat
  760. RegSftFloat     PROC   x1:word, x2:word, Shift:byte
  761.       mov   ax, x1
  762.       mov   dx, x2
  763.  
  764.       shl   dx, 1
  765.       rcl   cl, 1
  766.  
  767.       add   dh, Shift
  768.  
  769.       shr   cl, 1
  770.       rcr   dx, 1
  771.  
  772.       ret
  773. RegSftFloat      ENDP
  774.  
  775.  
  776.  
  777.  
  778. PUBLIC RegDivFloat
  779. RegDivFloat     PROC  uses si di, x1:word, x2:word, y1:word, y2:word
  780.       mov   si, x1
  781.       mov   bx, x2
  782.       mov   di, y1
  783.       mov   cx, y2
  784.  
  785.       xor   ax, ax
  786.       shl   bx, 1
  787.       jnz   ChkOtherOp
  788.       jmp   ExitRegDiv           ; Destination is zero
  789.  
  790.    ChkOtherOp:
  791.       rcl   ah, 1
  792.       shl   cx, 1
  793.       jnz   ChkDivExp
  794.       xor   bx, bx               ; Source is zero
  795.       xor   si, si
  796.       jmp   ExitRegDiv
  797.  
  798.    ChkDivExp:
  799.       rcl   al, 1
  800.       xor   ah, al               ; Resulting sign in ah
  801.       stc                        ; Put 'one' bit back into number
  802.       rcr   bl, 1
  803.       stc
  804.       rcr   cl, 1
  805.  
  806.       sub   ch, 127              ; Determine resulting exponent
  807.       sub   bh, ch
  808.       mov   al, bh
  809.       mov   es, ax               ; es has the resulting exponent and sign
  810.  
  811.       mov   ax, si               ; 8 bit shift, bx:si moved to dx:ax
  812.       mov   dh, bl
  813.       mov   dl, ah
  814.       mov   ah, al
  815.       xor   al, al
  816.  
  817.       mov   bh, cl               ; 8 bit shift, cx:di moved to bx:cx
  818.       mov   cx, di
  819.       mov   bl, ch
  820.       mov   ch, cl
  821.       xor   cl, cl
  822.  
  823.       shr   dx, 1
  824.       rcr   ax, 1
  825.  
  826.       div   bx
  827.       mov   si, dx               ; Save (and shift) remainder
  828.       mov   dx, cx               ; Save the quess
  829.       mov   cx, ax
  830.       mul   dx                   ; Mult quess times low word
  831.       xor   di, di
  832.       sub   di, ax               ; Determine remainder
  833.       sbb   si, dx
  834.       mov   ax, di
  835.       mov   dx, si
  836.       jc    RemainderNeg
  837.  
  838.       xor   di, di
  839.       jmp   GetNextDigit
  840.  
  841.    RemainderNeg:
  842.       mov   di, 1                ; Flag digit as negative
  843.       not   ax                   ; Convert remainder to positive
  844.       not   dx
  845.       add   ax, 1
  846.       adc   dx, 0
  847.  
  848.    GetNextDigit:
  849.       shr   dx, 1
  850.       rcr   ax, 1
  851.       div   bx
  852.       xor   bx, bx
  853.       shl   dx, 1
  854.       rcl   ax, 1
  855.       rcl   bl, 1                ; Save high bit
  856.  
  857.       mov   dx, cx               ; Retrieve first digit
  858.       or    di, di
  859.       jz    RemoveDivOneBit
  860.  
  861.       neg   ax                   ; Digit was negative
  862.       neg   bx
  863.       dec   dx
  864.  
  865.    RemoveDivOneBit:
  866.       add   dx, bx
  867.       mov   cx, es
  868.       shl   ax, 1
  869.       rcl   dx, 1
  870.       jc    AfterDivNorm
  871.  
  872.       dec   cl
  873.       shl   ax, 1
  874.       rcl   dx, 1
  875.  
  876.    AfterDivNorm:
  877.       mov   bl, dh               ; Perform remaining 8 bit shift
  878.       mov   dh, dl
  879.       mov   dl, ah
  880.       mov   si, dx
  881.       mov   bh, cl               ; Put in the exponent
  882.       shr   ch, 1                ; Get the sign
  883.       rcr   bx, 1                ; Normalize the result
  884.       rcr   si, 1
  885.  
  886.    ExitRegDiv:
  887.       mov   ax, si
  888.       mov   dx, bx
  889.       ret
  890. RegDivFloat      ENDP
  891.  
  892.  
  893.  
  894. TaylorTerm  MACRO
  895. LOCAL Ratio
  896.    add   Factorial, one
  897.    jnc   SHORT Ratio
  898.  
  899.    rcr   Factorial, 1
  900.    shr   Num, 1
  901.    shr   one, 1
  902.  
  903. Ratio:
  904.    mul   Num
  905.    div   Factorial
  906. ENDM
  907.  
  908.  
  909.  
  910.  
  911. Term        equ      <ax>
  912. Num         equ      <bx>
  913. Factorial   equ      <cx>
  914. Sin         equ      <si>
  915. Cos         equ      <di>
  916. e           equ      <si>
  917. Inve        equ      <di>
  918.          
  919. _sincos   PROC                   ; edx:eax =: Num * 2**32
  920.    xor   cx, cx
  921.    mov   SinNeg, cx
  922.    mov   CosNeg, cx
  923.    mov   exp, cx
  924.    or    dx, dx
  925.    jns   AnglePositive
  926.    
  927.    not   ax
  928.    not   dx
  929.    add   ax, 1
  930.     adc   dx, cx
  931.    mov   SinNeg, 1
  932.       
  933. AnglePositive:
  934.    mov   si, ax
  935.    mov   di, dx
  936.    mul   WORD PTR InvPiFg33
  937.    mov   bx, dx
  938.    mov   ax, di
  939.    mul   WORD PTR InvPiFg33
  940.    add   bx, ax
  941.    adc   cx, dx
  942.    mov   ax, si
  943.    mul   InvPiFg17
  944.    add   bx, ax
  945.    adc   cx, dx
  946.    mov   ax, di
  947.     mul   InvPiFg17
  948.     add   ax, cx
  949.     adc   dx, 0
  950.  
  951.    and   dx, 3
  952.    mov   exp, dx
  953.  
  954.    mov   Num, ax
  955.    mov   Factorial, InvPiFg17
  956.    mov   one, Factorial
  957.    mov   Cos, Factorial          ; Cos = 1
  958.    mov   Sin, Num                  ; Sin = Num
  959.       
  960. LoopIntSinCos:
  961.    TaylorTerm                    ; Term = Num * (x/2) * (x/3) * (x/4) * . . .
  962.    sub   Cos, Term               ; Cos = 1 - Num*(x/2) + (x**4)/4! - . . .
  963.    cmp   Term, WORD PTR TrigLimit
  964.    jbe   SHORT ExitIntSinCos
  965.  
  966.    TaylorTerm
  967.    sub   Sin, Term               ; Sin = Num - Num*(x/2)*(x/3) + (x**5)/5! - . . .
  968.    cmp   Term, WORD PTR TrigLimit
  969.    jbe   SHORT ExitIntSinCos
  970.       
  971.    TaylorTerm
  972.    add   Cos, Term
  973.    cmp   Term, WORD PTR TrigLimit
  974.    jbe   SHORT ExitIntSinCos
  975.       
  976.    TaylorTerm                    ; Term = Num * (x/2) * (x/3) * . . .
  977.    add   Sin, Term
  978.    cmp   Term, WORD PTR TrigLimit
  979.    jnbe  LoopIntSinCos
  980.       
  981. ExitIntSinCos:
  982.    xor   ax, ax
  983.    mov   cx, ax
  984.    cmp   Cos, InvPiFg17
  985.     jb    CosDivide               ; Cos < 1.0
  986.       
  987.    inc   cx                      ; Cos == 1.0
  988.    jmp   StoreCos
  989.       
  990. CosDivide:
  991.    mov   dx, Cos
  992.    div   InvPiFg17
  993.       
  994. StoreCos:
  995.    mov   Cos, ax                 ; cx:Cos
  996.  
  997.    xor   ax, ax
  998.    mov   bx, ax
  999.    cmp   Sin, InvPiFg17
  1000.     jb    SinDivide               ; Sin < 1.0
  1001.    
  1002.    inc   bx                      ; Sin == 1.0
  1003.    jmp   StoreSin
  1004.       
  1005. SinDivide:
  1006.    mov   dx, Sin
  1007.    div   InvPiFg17
  1008.       
  1009. StoreSin:
  1010.    mov   Sin, ax                 ; bx:Sin
  1011.  
  1012.    test  exp, 1
  1013.    jz    ChkNegCos
  1014.  
  1015.    xchg  cx, bx
  1016.    xchg  Sin, Cos
  1017.    mov   ax, SinNeg
  1018.    xchg  ax, CosNeg
  1019.    mov   CosNeg, ax
  1020.  
  1021. ChkNegCos:
  1022.    mov   ax, exp
  1023.    shr   al, 1
  1024.    rcl   ah, 1
  1025.    xor   ah, al
  1026.    jz    ChkNegSin
  1027.  
  1028.    xor   CosNeg, 1
  1029.  
  1030. ChkNegSin:
  1031.    test  exp, 2
  1032.    jz    CorrectQuad
  1033.  
  1034.    xor   SinNeg, 1
  1035.  
  1036. CorrectQuad:
  1037.    ret
  1038. _sincos     ENDP
  1039.       
  1040.       
  1041. SinCos086   PROC     LoNum:WORD, HiNum:WORD, SinAddr:WORD, CosAddr:WORD
  1042.    mov   ax, LoNum 
  1043.    mov   dx, HiNum
  1044.    
  1045.    call  _sincos
  1046.  
  1047.    cmp   CosNeg, 1
  1048.    jne   CosPolarized
  1049.  
  1050.    not   Cos
  1051.    not   cx 
  1052.    add   Cos, 1
  1053.    adc   cx, 0
  1054.  
  1055. CosPolarized:     
  1056.    mov   dx, bx
  1057.    mov   bx, CosAddr
  1058.    mov   WORD PTR [bx], Cos
  1059.    mov   WORD PTR [bx+2], cx
  1060.  
  1061.    cmp   SinNeg, 1
  1062.    jne   SinPolarized
  1063.  
  1064.    not   Sin
  1065.    not   dx
  1066.    add   Sin, 1
  1067.    adc   dx, 0
  1068.  
  1069. SinPolarized:
  1070.    mov   bx, SinAddr
  1071.    mov   WORD PTR [bx], Sin
  1072.    mov   WORD PTR [bx+2], dx
  1073.    ret
  1074. SinCos086      ENDP
  1075.       
  1076.       
  1077.       
  1078. _e2y   PROC                 ; eax =: Num * 2**16, 0 < Num < Ln2
  1079.    mov   expSign, 0
  1080.    or    dx, dx
  1081.    jns   CalcExp
  1082.       
  1083.    mov   expSign, 1
  1084.    not   ax
  1085.    not   dx
  1086.    add   ax, 1
  1087.    adc   dx, 0
  1088.    
  1089. CalcExp:
  1090.    div   Ln2Fg16
  1091.    mov   exp, ax
  1092.    mov   Num, dx
  1093.       
  1094.    xor   Factorial, Factorial
  1095.    stc
  1096.    rcr   Factorial, 1
  1097.    mov   one, Factorial
  1098.    mov   e, Num
  1099.    mov   Term, Num
  1100.    shr   Num, 1
  1101.       
  1102. Loop_e2y:
  1103.    TaylorTerm
  1104.    add   e, Term                 ; e = 1 + x + x*x/2 + (x**3)/3! + . . .
  1105.    cmp   Term, WORD PTR TrigLimit
  1106.    jnbe  SHORT Loop_e2y
  1107.       
  1108. ExitIntSinhCosh:
  1109.    stc
  1110.    rcr   e, 1
  1111.    ret                           ; return e**y * (2**32), 1 < e**y < 2
  1112. _e2y   ENDP
  1113.       
  1114.       
  1115.       
  1116. Exp086    PROC     LoNum:WORD, HiNum:WORD
  1117.    mov   ax, LoNum 
  1118.    mov   dx, HiNum
  1119.    
  1120.    call  _e2y
  1121.       
  1122.    cmp   exp, 16
  1123.    jae   Overflow
  1124.       
  1125.    cmp   expSign, 0
  1126.    jnz   NegNumber
  1127.       
  1128.    mov   ax, e
  1129.    mov   dx, ax
  1130.    inc   exp
  1131.    mov   cx, 16
  1132.    sub   cx, exp
  1133.    shr   dx, cl
  1134.    mov   cx, exp
  1135.    shl   ax, cl
  1136.    jmp   ExitExp086
  1137.       
  1138. Overflow:
  1139.    xor   ax, ax
  1140.    xor   dx, dx
  1141.    mov   TrigOverflow, 1
  1142.    jmp   ExitExp086
  1143.       
  1144. NegNumber:
  1145.    cmp   e, 8000h
  1146.    jne   DivideE
  1147.       
  1148.    mov   ax, e
  1149.    dec   exp
  1150.    jmp   ShiftE
  1151.       
  1152. DivideE:
  1153.    xor   ax, ax
  1154.    mov   dx, ax
  1155.    stc
  1156.    rcr   dx, 1
  1157.    div   e
  1158.       
  1159. ShiftE:
  1160.    xor   dx, dx
  1161.    mov   cx, exp
  1162.    shr   ax, cl
  1163.       
  1164. ExitExp086:
  1165.    ret
  1166. Exp086    ENDP
  1167.  
  1168.  
  1169.  
  1170. SinhCosh086    PROC     LoNum:WORD, HiNum:WORD, SinhAddr:WORD, CoshAddr:WORD
  1171.    mov   ax, LoNum
  1172.    mov   dx, HiNum
  1173.  
  1174.    call  _e2y
  1175.  
  1176.    cmp   e, 8000h
  1177.    jne   InvertE              ; e > 1
  1178.  
  1179.    mov   dx, 1
  1180.    xor   ax, ax
  1181.    cmp   exp, 0
  1182.    jne   Shiftone
  1183.  
  1184.    mov   e, ax
  1185.    mov   cx, ax
  1186.    jmp   ChkSinhSign
  1187.  
  1188. Shiftone:
  1189.    mov   cx, exp
  1190.    shl   dx, cl
  1191.    dec   cx
  1192.     shr   e, cl
  1193.    shr   dx, 1
  1194.    shr   e, 1
  1195.     mov   cx, dx
  1196.     sub   ax, e
  1197.     sbb   dx, 0
  1198.     xchg  ax, e
  1199.     xchg  dx, cx
  1200.    jmp   ChkSinhSign
  1201.  
  1202. InvertE:
  1203.    xor   ax, ax               ; calc 1/e
  1204.    mov   dx, 8000h
  1205.    div   e
  1206.  
  1207.    mov   Inve, ax
  1208.  
  1209. ShiftE:
  1210.    mov   cx, exp
  1211.     shr   Inve, cl
  1212.     inc   cl
  1213.    mov   dx, e
  1214.    shl   e, cl
  1215.    neg   cl
  1216.    add   cl, 16
  1217.    shr   dx, cl
  1218.    mov   cx, dx               ; cx:e == e**Exp
  1219.  
  1220.    mov   ax, e                ; dx:e == e**Exp
  1221.    add   ax, Inve
  1222.    adc   dx, 0
  1223.    shr   dx, 1
  1224.    rcr   ax, 1                ; cosh(Num) = (e**Exp + 1/e**Exp) / 2
  1225.  
  1226.    sub   e, Inve
  1227.    sbb   cx, 0
  1228.    sar   cx, 1
  1229.    rcr   e, 1
  1230.  
  1231. ChkSinhSign:
  1232.    or    HiNum, 0
  1233.    jns   StoreHyperbolics
  1234.  
  1235.    not   e
  1236.    not   cx
  1237.    add   e, 1
  1238.    adc   cx, 0
  1239.  
  1240. StoreHyperbolics:
  1241.    mov   bx, CoshAddr
  1242.    mov   WORD PTR [bx], ax
  1243.    mov   WORD PTR [bx+2], dx
  1244.  
  1245.    mov   bx, SinhAddr
  1246.    mov   WORD PTR [bx], e
  1247.    mov   WORD PTR [bx+2], cx
  1248.  
  1249.    ret
  1250. SinhCosh086    ENDP
  1251.  
  1252.  
  1253.  
  1254. END
  1255.  
  1256.