File: dos\fpu387.asm

    1 TITLE fpu387.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 ;    405-C Queen St., Suite #181
   16 ;    Southington, CT 06489
   17 ;    (203) 276-9721
   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 
   32 IFDEF ??version
   33 MASM51
   34 QUIRKS
   35 ENDIF
   36 
   37 .model medium, c
   38 
   39 .code
   40 
   41 .386
   42 .387
   43 
   44 _Loaded387sincos   PROC
   45    fsincos
   46    fwait
   47    ret
   48 _Loaded387sincos   ENDP
   49 
   50 
   51 FPU387sin      PROC     x:word, sin:word
   52    mov   bx, x
   53    fld   QWORD PTR [bx]    ; x
   54    fsin                    ; sin
   55    mov   bx, sin
   56    fstp  QWORD PTR [bx]    ; 
   57    ret
   58 FPU387sin      ENDP
   59 
   60 
   61 FPU387cos      PROC     x:word, cos:word
   62    mov   bx, x
   63    fld   QWORD PTR [bx]    ; x
   64    fcos                    ; cos
   65    mov   bx, cos
   66    fstp  QWORD PTR [bx]    ; 
   67    ret
   68 FPU387cos      ENDP
   69 
   70 
   71 FPUaptan387    PROC     x:word, y:word, z:word
   72    mov   bx, y
   73    fld   QWORD PTR [bx]    ; y
   74    mov   bx, x
   75    fld   QWORD PTR [bx]    ; x, y
   76    fpatan                  ; ArtTan
   77    mov   bx, z
   78    fstp  QWORD PTR [bx]    ; 
   79    ret
   80 FPUaptan387    ENDP
   81 
   82 
   83 FPUcplxexp387  PROC     x:word, z:word
   84    mov   bx, x
   85    fld   QWORD PTR [bx+8]  ; x.y
   86    fsincos                 ; cos, sin
   87    fldln2                  ; ln2, cos, sin
   88    fdivr QWORD PTR [bx]    ; x.x/ln2, cos, sin
   89    fld1                    ; 1, x.x/ln2, cos, sin
   90    fld   st(1)             ; x.x/ln2, 1, x.x/ln2, cos, sin
   91    fprem                   ; prem, 1, x.x/ln2, cos, sin
   92    f2xm1                   ; e**prem-1, 1, x.x/ln2, cos, sin
   93    fadd                    ; e**prem, x.x/ln2, cos, sin
   94    fscale                  ; e**x.x, x.x/ln2, cos, sin
   95    fstp  st(1)             ; e**x.x, cos, sin
   96    fmul  st(2), st         ; e**x.x, cos, z.y
   97    fmul                    ; z.x, z.y
   98    mov   bx, z
   99    fstp  QWORD PTR [bx]    ; z.y
  100    fstp  QWORD PTR [bx+8]  ; 
  101    ret
  102 FPUcplxexp387  ENDP
  103 
  104 
  105 .data
  106 
  107 extrn overflow:WORD, TrigLimit:DWORD
  108 
  109 PiFg13         dw       6487h
  110 InvPiFg17      dw       0a2f9h
  111 InvPiFg33      dd       0a2f9836eh
  112 InvPiFg65      dq       0a2f9836e4e44152ah
  113 InvPiFg16      dw       517ch
  114 Ln2Fg16        dw       0b172h
  115 Ln2Fg32        dd       0b17217f7h
  116 One            dd       ?
  117 ExpSign        dd       ?
  118 Exp            dd       ?
  119 SinNeg         dd       ?
  120 CosNeg         dd       ?
  121 
  122 
  123 .code
  124 
  125 
  126 TaylorTerm  MACRO
  127 LOCAL Ratio
  128    add   Factorial, One
  129    jnc   SHORT Ratio
  130 
  131    rcr   Factorial, 1
  132    shr   Num, 1
  133    shr   One, 1
  134 
  135 Ratio:
  136    mul   Num
  137    div   Factorial
  138 ENDM
  139 
  140 
  141 
  142 Term           equ      
  143 HiTerm         equ      
  144 Num            equ      
  145 Factorial      equ      
  146 Sin            equ      
  147 Cos            equ      
  148 e              equ      
  149 Inve           equ      
  150 LoPtr          equ      
  151 HiPtr          equ      2]>
  152 
  153 
  154 
  155 _sincos386   PROC
  156    xor   Factorial, Factorial
  157    mov   SinNeg, Factorial
  158    mov   CosNeg, Factorial
  159    mov   Exp, Factorial
  160    or    HiTerm, HiTerm
  161    jns   AnglePositive
  162 
  163    not   Term
  164    not   HiTerm
  165    add   Term, 1
  166    adc   HiTerm, Factorial
  167    mov   SinNeg, 1
  168 
  169 AnglePositive:
  170    mov   Sin, Term
  171    mov   Cos, HiTerm
  172    mul   DWORD PTR InvPiFg65
  173    mov   Num, HiTerm
  174    mov   Term, Cos
  175    mul   DWORD PTR InvPiFg65
  176    add   Num, Term
  177    adc   Factorial, HiTerm
  178    mov   Term, Sin
  179    mul   InvPiFg33
  180    add   Num, Term
  181    adc   Factorial, HiTerm
  182    mov   Term, Cos
  183    mul   InvPiFg33
  184    add   Term, Factorial
  185    adc   HiTerm, 0
  186 
  187    and   HiTerm, 3
  188    mov   Exp, HiTerm
  189 
  190    mov   Num, Term
  191    mov   Factorial, InvPiFg33
  192    mov   One, Factorial
  193    mov   Cos, Factorial          ; Cos = 1
  194    mov   Sin, Num                  ; Sin = Num
  195 
  196 LoopIntSinCos:
  197    TaylorTerm                    ; Term = Num * (x/2) * (x/3) * (x/4) * . . .
  198    sub   Cos, Term               ; Cos = 1 - Num*(x/2) + (x**4)/4! - . . .
  199    cmp   Term, TrigLimit
  200    jbe   SHORT ExitIntSinCos
  201 
  202    TaylorTerm
  203    sub   Sin, Term               ; Sin = Num - Num*(x/2)*(x/3) + (x**5)/5! - . . .
  204    cmp   Term, TrigLimit
  205    jbe   SHORT ExitIntSinCos
  206 
  207    TaylorTerm
  208    add   Cos, Term
  209    cmp   Term, TrigLimit
  210    jbe   SHORT ExitIntSinCos
  211 
  212    TaylorTerm                    ; Term = Num * (x/2) * (x/3) * . . .
  213    add   Sin, Term
  214    cmp   Term, TrigLimit
  215    jnbe  LoopIntSinCos
  216 
  217 ExitIntSinCos:
  218    xor   Term, Term
  219    mov   Factorial, Term
  220    cmp   Cos, InvPiFg33
  221    jb    CosDivide               ; Cos < 1.0
  222 
  223    inc   Factorial                      ; Cos == 1.0
  224    jmp   StoreCos
  225 
  226 CosDivide:
  227    mov   HiTerm, Cos
  228    div   InvPiFg33
  229 
  230 StoreCos:
  231    mov   Cos, Term                 ; Factorial:Cos
  232 
  233    xor   Term, Term
  234    mov   Num, Term
  235    cmp   Sin, InvPiFg33
  236    jb    SinDivide               ; Sin < 1.0
  237 
  238    inc   Num                      ; Sin == 1.0
  239    jmp   StoreSin
  240 
  241 SinDivide:
  242    mov   HiTerm, Sin
  243    div   InvPiFg33
  244 
  245 StoreSin:
  246    mov   Sin, Term                 ; Num:Sin
  247 
  248    test  Exp, 1
  249    jz    ChkNegCos
  250 
  251    xchg  Factorial, Num
  252    xchg  Sin, Cos
  253    mov   Term, SinNeg
  254    xchg  Term, CosNeg
  255    mov   CosNeg, Term
  256 
  257 ChkNegCos:
  258    mov   Term, Exp
  259    shr   Term, 1
  260    mov   Term, 0
  261    rcr   Term, 1
  262    xor   Term, Exp
  263    jz    ChkNegSin
  264 
  265    xor   CosNeg, 1
  266 
  267 ChkNegSin:
  268    test  Exp, 2
  269    jz    CorrectQuad
  270 
  271    xor   SinNeg, 1
  272 
  273 CorrectQuad:
  274    ret
  275 _sincos386     ENDP
  276 
  277 
  278 SinCos386   PROC     LoNum:DWORD, HiNum:DWORD, SinAddr:DWORD, CosAddr:DWORD
  279    mov   Term, LoNum
  280    mov   HiTerm, HiNum
  281 
  282    call  _sincos386
  283 
  284    cmp   CosNeg, 1
  285    jne   CosPolarized
  286 
  287    not   Cos
  288    not   Factorial
  289    add   Cos, 1
  290    adc   Factorial, 0
  291 
  292 CosPolarized:
  293    mov   HiTerm, Num
  294    mov   Num, CosAddr
  295    mov   LoPtr, Cos
  296    mov   HiPtr, Factorial
  297 
  298    cmp   SinNeg, 1
  299    jne   SinPolarized
  300 
  301    not   Sin
  302    not   HiTerm
  303    add   Sin, 1
  304    adc   HiTerm, 0
  305 
  306 SinPolarized:
  307    mov   Num, SinAddr
  308    mov   LoPtr, Sin
  309    mov   HiPtr, HiTerm
  310    ret
  311 SinCos386      ENDP
  312 
  313 
  314 
  315 _e2y386   PROC                 ; eTerm =: Num * 2**16, 0 < Num < Ln2
  316    mov   ExpSign, 0
  317    or    HiTerm, HiTerm
  318    jns   CalcExp
  319 
  320    mov   ExpSign, 1
  321    not   Term
  322    not   HiTerm
  323    add   Term, 1
  324    adc   HiTerm, 0
  325 
  326 CalcExp:
  327    div   Ln2Fg32
  328    mov   Exp, Term
  329    mov   Num, HiTerm
  330 
  331    xor   Factorial, Factorial
  332    stc
  333    rcr   Factorial, 1
  334    mov   One, Factorial
  335    mov   e, Num
  336    mov   Term, Num
  337    shr   Num, 1
  338 
  339 Loop_e2y386:
  340    TaylorTerm
  341    add   e, Term                 ; e = 1 + Num + Num*x/2 + (x**3)/3! + . . .
  342    cmp   Term, TrigLimit
  343    jnbe  SHORT Loop_e2y386
  344 
  345 ExitIntSinhCosh:
  346    stc
  347    rcr   e, 1
  348    ret                           ; return e**y * (2**32), 1 < e**y < 2
  349 _e2y386   ENDP
  350 
  351 
  352 
  353 Exp386    PROC     LoNum:DWORD, HiNum:DWORD
  354    mov   Term, LoNum
  355    mov   HiTerm, HiNum
  356 
  357    call  _e2y386
  358 
  359    cmp   Exp, 32
  360    jae   Overflow
  361 
  362    cmp   ExpSign, 0
  363    jnz   NegNumber
  364 
  365    mov   Factorial, Exp
  366    shld  HiTerm, Term, cl
  367    shl   Term, cl
  368    jmp   ExitExp386
  369 
  370 Overflow:
  371    xor   Term, Term
  372    xor   HiTerm, HiTerm
  373    mov   overflow, 1
  374    jmp   ExitExp386
  375 
  376 NegNumber:
  377    cmp   e, 80000000h
  378    jne   DivideE
  379 
  380    mov   Term, e
  381    dec   Exp
  382    jmp   ShiftE
  383 
  384 DivideE:
  385    xor   Term, Term
  386    mov   HiTerm, Term
  387    stc
  388    rcr   HiTerm, 1
  389    div   e
  390 
  391 ShiftE:
  392    xor   HiTerm, HiTerm
  393    mov   Factorial, Exp
  394    shr   Term, cl
  395 
  396 ExitExp386:
  397    ret
  398 Exp386    ENDP
  399 
  400 
  401 
  402 SinhCosh386 PROC  LoNum:DWORD, HiNum:DWORD, SinhAddr:DWORD, CoshAddr:DWORD
  403    mov   Term, LoNum
  404    mov   HiTerm, HiNum
  405 
  406    call  _e2y386
  407 
  408    cmp   e, 80000000h
  409    jne   InvertE              ; e > 1
  410 
  411    mov   HiTerm, 1
  412    xor   Term, Term
  413    cmp   Exp, 0
  414    jne   ShiftOne
  415 
  416    mov   e, Term
  417    mov   Factorial, Term
  418    jmp   ChkSinhSign
  419 
  420 ShiftOne:
  421    mov   Factorial, Exp
  422    shl   HiTerm, cl
  423    dec   Factorial
  424    shr   e, cl
  425    shr   HiTerm, 1
  426    shr   e, 1
  427    mov   Factorial, HiTerm
  428    sub   Term, e
  429    sbb   HiTerm, 0
  430    xchg  Term, e
  431    xchg  HiTerm, Factorial
  432    jmp   ChkSinhSign
  433 
  434 InvertE:
  435    xor   Term, Term               ; calc 1/e
  436    mov   HiTerm, 80000000h
  437    div   e
  438 
  439    mov   Inve, Term
  440 
  441 ShiftE:
  442    mov   Factorial, Exp
  443    shr   Inve, cl
  444    inc   cl
  445    shld  HiTerm, e, cl
  446    mov   Factorial, HiTerm      ; Factorial:e == e**Exp
  447 
  448    mov   Term, e                ; HiTerm:e == e**Exp
  449    add   Term, Inve
  450    adc   HiTerm, 0
  451    shr   HiTerm, 1
  452    rcr   Term, 1                ; cosh(Num) = (e**Exp + 1/e**Exp) / 2
  453 
  454    sub   e, Inve
  455    sbb   Factorial, 0
  456    sar   Factorial, 1
  457    rcr   e, 1
  458 
  459 ChkSinhSign:
  460    or    HiNum, 0
  461    jns   StoreHyperbolics
  462 
  463    not   e
  464    not   Factorial
  465    add   e, 1
  466    adc   Factorial, 0
  467 
  468 StoreHyperbolics:
  469    mov   Num, CoshAddr
  470    mov   LoPtr, Term
  471    mov   HiPtr, HiTerm
  472 
  473    mov   Num, SinhAddr
  474    mov   LoPtr, e
  475    mov   HiPtr, Factorial
  476 
  477    ret
  478 SinhCosh386    ENDP
  479 
  480 
  481 
  482 END
  483 
  484