home *** CD-ROM | disk | FTP | other *** search
- TITLE fpu387.asm (C) 1989, Mark C. Peterson, CompuServe [70441,3353]
- SUBTTL All rights reserved.
- ;
- ; Code may be used in any program provided the author is credited
- ; either during program execution or in the documentation. Source
- ; code may be distributed only in combination with public domain or
- ; shareware source code. Source code may be modified provided the
- ; copyright notice and this message is left unchanged and all
- ; modifications are clearly documented.
- ;
- ; I would appreciate a copy of any work which incorporates this code,
- ; however this is optional.
- ;
- ; Mark C. Peterson
- ; 405-C Queen St., Suite #181
- ; Southington, CT 06489
- ; (203) 276-9721
- ;
- ; Note: Remark statements following floating point commands generally indicate
- ; the FPU stack contents after the command is completed.
- ;
- ; References:
- ; 80386/80286 Assembly Language Programming
- ; by William H. Murray, III and Chris H. Pappas
- ; Published by Osborne McGraw-Hill, 1986
- ;
- ;
- ;
-
-
-
- IFDEF ??version
- MASM51
- QUIRKS
- ENDIF
-
- .model medium, c
-
- .code
-
- .386
- .387
-
- _Loaded387sincos PROC
- fsincos
- fwait
- ret
- _Loaded387sincos ENDP
-
-
- FPU387sin PROC x:word, sin:word
- mov bx, x
- fld QWORD PTR [bx] ; x
- fsin ; sin
- mov bx, sin
- fstp QWORD PTR [bx] ; <empty>
- ret
- FPU387sin ENDP
-
-
- FPU387cos PROC x:word, cos:word
- mov bx, x
- fld QWORD PTR [bx] ; x
- fcos ; cos
- mov bx, cos
- fstp QWORD PTR [bx] ; <empty>
- ret
- FPU387cos ENDP
-
-
- FPUaptan387 PROC x:word, y:word, z:word
- mov bx, y
- fld QWORD PTR [bx] ; y
- mov bx, x
- fld QWORD PTR [bx] ; x, y
- fpatan ; ArtTan
- mov bx, z
- fstp QWORD PTR [bx] ; <empty>
- ret
- FPUaptan387 ENDP
-
-
- FPUcplxexp387 PROC x:word, z:word
- mov bx, x
- fld QWORD PTR [bx+8] ; x.y
- fsincos ; cos, sin
- fldln2 ; ln2, cos, sin
- fdivr QWORD PTR [bx] ; x.x/ln2, cos, sin
- fld1 ; 1, x.x/ln2, cos, sin
- fld st(1) ; x.x/ln2, 1, x.x/ln2, cos, sin
- fprem ; prem, 1, x.x/ln2, cos, sin
- f2xm1 ; e**prem-1, 1, x.x/ln2, cos, sin
- fadd ; e**prem, x.x/ln2, cos, sin
- fscale ; e**x.x, x.x/ln2, cos, sin
- fstp st(1) ; e**x.x, cos, sin
- fmul st(2), st ; e**x.x, cos, z.y
- fmul ; z.x, z.y
- mov bx, z
- fstp QWORD PTR [bx] ; z.y
- fstp QWORD PTR [bx+8] ; <empty>
- ret
- FPUcplxexp387 ENDP
-
-
- .data
-
- extrn TrigOverflow:WORD, TrigLimit:DWORD
-
- PiFg13 dw 6487h
- InvPiFg17 dw 0a2f9h
- InvPiFg33 dd 0a2f9836eh
- InvPiFg65 dq 0a2f9836e4e44152ah
- InvPiFg16 dw 517ch
- Ln2Fg16 dw 0b172h
- Ln2Fg32 dd 0b17217f7h
- One dd ?
- ExpSign dd ?
- Exp dd ?
- SinNeg dd ?
- CosNeg dd ?
-
-
- .code
-
-
- TaylorTerm MACRO
- LOCAL Ratio
- add Factorial, One
- jnc SHORT Ratio
-
- rcr Factorial, 1
- shr Num, 1
- shr One, 1
-
- Ratio:
- mul Num
- div Factorial
- ENDM
-
-
-
- Term equ <eax>
- HiTerm equ <edx>
- Num equ <ebx>
- Factorial equ <ecx>
- Sin equ <esi>
- Cos equ <edi>
- e equ <esi>
- Inve equ <edi>
- LoPtr equ <DWORD PTR [bx]>
- HiPtr equ <DWORD PTR [bx+2]>
-
-
-
- _sincos386 PROC
- xor Factorial, Factorial
- mov SinNeg, Factorial
- mov CosNeg, Factorial
- mov Exp, Factorial
- or HiTerm, HiTerm
- jns AnglePositive
-
- not Term
- not HiTerm
- add Term, 1
- adc HiTerm, Factorial
- mov SinNeg, 1
-
- AnglePositive:
- mov Sin, Term
- mov Cos, HiTerm
- mul DWORD PTR InvPiFg65
- mov Num, HiTerm
- mov Term, Cos
- mul DWORD PTR InvPiFg65
- add Num, Term
- adc Factorial, HiTerm
- mov Term, Sin
- mul InvPiFg33
- add Num, Term
- adc Factorial, HiTerm
- mov Term, Cos
- mul InvPiFg33
- add Term, Factorial
- adc HiTerm, 0
-
- and HiTerm, 3
- mov Exp, HiTerm
-
- mov Num, Term
- mov Factorial, InvPiFg33
- mov One, Factorial
- mov Cos, Factorial ; Cos = 1
- mov Sin, Num ; Sin = Num
-
- LoopIntSinCos:
- TaylorTerm ; Term = Num * (x/2) * (x/3) * (x/4) * . . .
- sub Cos, Term ; Cos = 1 - Num*(x/2) + (x**4)/4! - . . .
- cmp Term, TrigLimit
- jbe SHORT ExitIntSinCos
-
- TaylorTerm
- sub Sin, Term ; Sin = Num - Num*(x/2)*(x/3) + (x**5)/5! - . . .
- cmp Term, TrigLimit
- jbe SHORT ExitIntSinCos
-
- TaylorTerm
- add Cos, Term
- cmp Term, TrigLimit
- jbe SHORT ExitIntSinCos
-
- TaylorTerm ; Term = Num * (x/2) * (x/3) * . . .
- add Sin, Term
- cmp Term, TrigLimit
- jnbe LoopIntSinCos
-
- ExitIntSinCos:
- xor Term, Term
- mov Factorial, Term
- cmp Cos, InvPiFg33
- jb CosDivide ; Cos < 1.0
-
- inc Factorial ; Cos == 1.0
- jmp StoreCos
-
- CosDivide:
- mov HiTerm, Cos
- div InvPiFg33
-
- StoreCos:
- mov Cos, Term ; Factorial:Cos
-
- xor Term, Term
- mov Num, Term
- cmp Sin, InvPiFg33
- jb SinDivide ; Sin < 1.0
-
- inc Num ; Sin == 1.0
- jmp StoreSin
-
- SinDivide:
- mov HiTerm, Sin
- div InvPiFg33
-
- StoreSin:
- mov Sin, Term ; Num:Sin
-
- test Exp, 1
- jz ChkNegCos
-
- xchg Factorial, Num
- xchg Sin, Cos
- mov Term, SinNeg
- xchg Term, CosNeg
- mov CosNeg, Term
-
- ChkNegCos:
- mov Term, Exp
- shr Term, 1
- mov Term, 0
- rcr Term, 1
- xor Term, Exp
- jz ChkNegSin
-
- xor CosNeg, 1
-
- ChkNegSin:
- test Exp, 2
- jz CorrectQuad
-
- xor SinNeg, 1
-
- CorrectQuad:
- ret
- _sincos386 ENDP
-
-
- SinCos386 PROC LoNum:DWORD, HiNum:DWORD, SinAddr:DWORD, CosAddr:DWORD
- mov Term, LoNum
- mov HiTerm, HiNum
-
- call _sincos386
-
- cmp CosNeg, 1
- jne CosPolarized
-
- not Cos
- not Factorial
- add Cos, 1
- adc Factorial, 0
-
- CosPolarized:
- mov HiTerm, Num
- mov Num, CosAddr
- mov LoPtr, Cos
- mov HiPtr, Factorial
-
- cmp SinNeg, 1
- jne SinPolarized
-
- not Sin
- not HiTerm
- add Sin, 1
- adc HiTerm, 0
-
- SinPolarized:
- mov Num, SinAddr
- mov LoPtr, Sin
- mov HiPtr, HiTerm
- ret
- SinCos386 ENDP
-
-
-
- _e2y386 PROC ; eTerm =: Num * 2**16, 0 < Num < Ln2
- mov ExpSign, 0
- or HiTerm, HiTerm
- jns CalcExp
-
- mov ExpSign, 1
- not Term
- not HiTerm
- add Term, 1
- adc HiTerm, 0
-
- CalcExp:
- div Ln2Fg32
- mov Exp, Term
- mov Num, HiTerm
-
- xor Factorial, Factorial
- stc
- rcr Factorial, 1
- mov One, Factorial
- mov e, Num
- mov Term, Num
- shr Num, 1
-
- Loop_e2y386:
- TaylorTerm
- add e, Term ; e = 1 + Num + Num*x/2 + (x**3)/3! + . . .
- cmp Term, TrigLimit
- jnbe SHORT Loop_e2y386
-
- ExitIntSinhCosh:
- stc
- rcr e, 1
- ret ; return e**y * (2**32), 1 < e**y < 2
- _e2y386 ENDP
-
-
-
- Exp386 PROC LoNum:DWORD, HiNum:DWORD
- mov Term, LoNum
- mov HiTerm, HiNum
-
- call _e2y386
-
- cmp Exp, 32
- jae Overflow
-
- cmp ExpSign, 0
- jnz NegNumber
-
- mov Factorial, Exp
- shld HiTerm, Term, cl
- shl Term, cl
- jmp ExitExp386
-
- Overflow:
- xor Term, Term
- xor HiTerm, HiTerm
- mov TrigOverflow, 1
- jmp ExitExp386
-
- NegNumber:
- cmp e, 80000000h
- jne DivideE
-
- mov Term, e
- dec Exp
- jmp ShiftE
-
- DivideE:
- xor Term, Term
- mov HiTerm, Term
- stc
- rcr HiTerm, 1
- div e
-
- ShiftE:
- xor HiTerm, HiTerm
- mov Factorial, Exp
- shr Term, cl
-
- ExitExp386:
- ret
- Exp386 ENDP
-
-
-
- SinhCosh386 PROC LoNum:DWORD, HiNum:DWORD, SinhAddr:DWORD, CoshAddr:DWORD
- mov Term, LoNum
- mov HiTerm, HiNum
-
- call _e2y386
-
- cmp e, 80000000h
- jne InvertE ; e > 1
-
- mov HiTerm, 1
- xor Term, Term
- cmp Exp, 0
- jne ShiftOne
-
- mov e, Term
- mov Factorial, Term
- jmp ChkSinhSign
-
- ShiftOne:
- mov Factorial, Exp
- shl HiTerm, cl
- dec Factorial
- shr e, cl
- shr HiTerm, 1
- shr e, 1
- mov Factorial, HiTerm
- sub Term, e
- sbb HiTerm, 0
- xchg Term, e
- xchg HiTerm, Factorial
- jmp ChkSinhSign
-
- InvertE:
- xor Term, Term ; calc 1/e
- mov HiTerm, 80000000h
- div e
-
- mov Inve, Term
-
- ShiftE:
- mov Factorial, Exp
- shr Inve, cl
- inc cl
- shld HiTerm, e, cl
- mov Factorial, HiTerm ; Factorial:e == e**Exp
-
- mov Term, e ; HiTerm:e == e**Exp
- add Term, Inve
- adc HiTerm, 0
- shr HiTerm, 1
- rcr Term, 1 ; cosh(Num) = (e**Exp + 1/e**Exp) / 2
-
- sub e, Inve
- sbb Factorial, 0
- sar Factorial, 1
- rcr e, 1
-
- ChkSinhSign:
- or HiNum, 0
- jns StoreHyperbolics
-
- not e
- not Factorial
- add e, 1
- adc Factorial, 0
-
- StoreHyperbolics:
- mov Num, CoshAddr
- mov LoPtr, Term
- mov HiPtr, HiTerm
-
- mov Num, SinhAddr
- mov LoPtr, e
- mov HiPtr, Factorial
-
- ret
- SinhCosh386 ENDP
-
-
-
- END
-
-