home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_01_05
/
1n05071a
< prev
next >
Wrap
Text File
|
1990-09-13
|
11KB
|
535 lines
TITLE inttran.asm (C) 1989, Mark C. Peterson
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.
;
; Mark C. Peterson
; 253 West St., H
; Plantsville, CT 06579
; (203) 276-9474
;
; References:
; The VNR Concise Encyclopedia of Mathematics
; by W. Gellert, H. Hustner, M. Hellwich,
; and H. Kastner; Van Nostrand Reinhold Co.,
; 1975.
;
; 80386/80286 Assembly Language Programming
; by William H. Murray, III and Chris H.
; Pappas; Osborne McGraw-Hill, 1986.
;
;
;
.model medium, c
.data
PUBLIC TrigLimit, TrigOverflow, Ln2Fg16
PiFg13 dw 6487h
InvPiFg33 dd 0a2f9836eh
InvPiFg16 dw 517ch
Ln2Fg16 dw 0b172h
TrigOverflow dw 0
TrigLimit dd 0
one dw ?
expSign dw ?
a dw ?
SinNeg dw ?
CosNeg dw ?
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 <ax>
Num equ <bx>
Factorial equ <cx>
Sin equ <si>
Cos equ <di>
e equ <si>
Inve equ <di>
.code
SinCos086 PROC uses si di, LoNum:WORD, HiNum:WORD, \
SinAddr:WORD, CosAddr:WORD
mov ax, LoNum
mov dx, HiNum
xor cx, cx
mov SinNeg, cx
mov CosNeg, cx
mov a, cx
or dx, dx
jns AnglePositive
not ax
not dx
add ax, 1
adc dx, cx
mov SinNeg, 1
AnglePositive:
mov si, ax
mov di, dx
mul WORD PTR InvPiFg33
mov bx, dx
mov ax, di
mul WORD PTR InvPiFg33
add bx, ax
adc cx, dx
mov ax, si
mul WORD PTR InvPiFg33 + 2
add bx, ax
adc cx, dx
mov ax, di
mul WORD PTR InvPiFg33 + 2
add ax, cx
adc dx, 0
and dx, 3
mov a, dx
mov Num, ax
mov Factorial, WORD PTR InvPiFg33 + 2
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, WORD PTR TrigLimit
jbe SHORT ExitIntSinCos
TaylorTerm
sub Sin, Term ; Sin = Num - Num*(x/2)*(x/3) + (x**5)/5! - . . .
cmp Term, WORD PTR TrigLimit
jbe SHORT ExitIntSinCos
TaylorTerm
add Cos, Term
cmp Term, WORD PTR TrigLimit
jbe SHORT ExitIntSinCos
TaylorTerm ; Term = Num * (x/2) * (x/3) * . . .
add Sin, Term
cmp Term, WORD PTR TrigLimit
jnbe LoopIntSinCos
ExitIntSinCos:
xor ax, ax
mov cx, ax
cmp Cos, WORD PTR InvPiFg33 + 2
jb CosDivide ; Cos < 1.0
inc cx ; Cos == 1.0
jmp StoreCos
CosDivide:
mov dx, Cos
div WORD PTR InvPiFg33 + 2
StoreCos:
mov Cos, ax ; cx:Cos
xor ax, ax
mov bx, ax
cmp Sin, WORD PTR InvPiFg33 + 2
jb SinDivide ; Sin < 1.0
inc bx ; Sin == 1.0
jmp StoreSin
SinDivide:
mov dx, Sin
div WORD PTR InvPiFg33 + 2
StoreSin:
mov Sin, ax ; bx:Sin
test a, 1
jz ChkNegCos
xchg cx, bx
xchg Sin, Cos
mov ax, SinNeg
xchg ax, CosNeg
mov CosNeg, ax
ChkNegCos:
mov ax, a
shr al, 1
rcl ah, 1
xor ah, al
jz ChkNegSin
xor CosNeg, 1
ChkNegSin:
test a, 2
jz CorrectQuad
xor SinNeg, 1
CorrectQuad:
cmp CosNeg, 1
jne CosPolarized
not Cos
not cx
add Cos, 1
adc cx, 0
CosPolarized:
mov dx, bx
mov bx, CosAddr
mov WORD PTR [bx], Cos
mov WORD PTR [bx+2], cx
cmp SinNeg, 1
jne SinPolarized
not Sin
not dx
add Sin, 1
adc dx, 0
SinPolarized:
mov bx, SinAddr
mov WORD PTR [bx], Sin
mov WORD PTR [bx+2], dx
ret
SinCos086 ENDP
_e2x PROC
mov expSign, 0
or dx, dx
jns CalcExp
mov expSign, 1
not ax
not dx
add ax, 1
adc dx, 0
CalcExp:
div Ln2Fg16
mov a, ax
mov Num, dx ; 0 <= Num < Ln(2)
xor Factorial, Factorial
stc
rcr Factorial, 1
mov one, Factorial
mov e, Num
mov Term, Num
shr Num, 1
Loop_e2x:
TaylorTerm
add e, Term ; e = x + x*x/2 + (x**3)/3! + . . .
cmp Term, WORD PTR TrigLimit
jnbe SHORT Loop_e2x
ExitIntSinhCosh:
stc
rcr e, 1 ; e = e + 1, fg 15
ret ; return e**x * (2**15), 1 < e**x < 2
_e2x ENDP
Exp086 PROC uses si di, LoNum:WORD, HiNum:WORD
mov ax, LoNum
mov dx, HiNum
call _e2x
cmp a, 16
jae Overflow
cmp expSign, 0
jnz NegNumber
mov ax, e
mov dx, ax
inc a
mov cx, 16
sub cx, a
shr dx, cl
mov cx, a
shl ax, cl
jmp ExitExp086
Overflow:
xor ax, ax
xor dx, dx
mov TrigOverflow, 1
jmp ExitExp086
NegNumber:
cmp e, 8000h
jne DivideE
mov ax, e
dec a
jmp ShiftE
DivideE:
xor ax, ax
mov dx, ax
stc
rcr dx, 1
div e
ShiftE:
xor dx, dx
mov cx, a
shr ax, cl
ExitExp086:
ret
Exp086 ENDP
SinhCosh086 PROC uses si di, LoNum:WORD, HiNum:WORD, \
SinhAddr:WORD, CoshAddr:WORD
mov ax, LoNum
mov dx, HiNum
call _e2x
cmp e, 8000h
jne InvertE ; e > 1
mov dx, 1
xor ax, ax
cmp a, 0
jne Shiftone
mov e, ax
mov cx, ax
jmp ChkSinhSign
Shiftone:
mov cx, a
shl dx, cl
dec cx
shr e, cl
shr dx, 1
shr e, 1
mov cx, dx
sub ax, e
sbb dx, 0
xchg ax, e
xchg dx, cx
jmp ChkSinhSign
InvertE:
xor ax, ax ; calc 1/e
mov dx, 8000h
div e
mov Inve, ax
ShiftE:
mov cx, a
shr Inve, cl
inc cl
mov dx, e
shl e, cl
neg cl
add cl, 16
shr dx, cl
mov cx, dx ; cx:e == e**Exp
mov ax, e ; dx:e == e**Exp
add ax, Inve
adc dx, 0
shr dx, 1
rcr ax, 1 ; cosh(Num) = (e**Exp + 1/e**Exp) / 2
sub e, Inve
sbb cx, 0
sar cx, 1
rcr e, 1
ChkSinhSign:
or HiNum, 0
jns StoreHyperbolics
not e
not cx
add e, 1
adc cx, 0
StoreHyperbolics:
mov bx, CoshAddr
mov WORD PTR [bx], ax
mov WORD PTR [bx+2], dx
mov bx, SinhAddr
mov WORD PTR [bx], e
mov WORD PTR [bx+2], cx
ret
SinhCosh086 ENDP
Numerator equ <bx>
Denominator equ <di>
Counter equ <si>
Log086 PROC uses si di, LoNum:WORD, HiNum:WORD, \
Fudge:WORD
LOCAL Exp:WORD, Accum:WORD, LoAns:WORD, HiAns:WORD
xor bx, bx
mov Accum, bx
mov LoAns, bx
mov HiAns, bx
mov cx, Fudge
mov ax, LoNum
mov dx, HiNum
or dx, dx
js Overflow
jnz ShiftUp
or ax, ax
jnz ShiftUp
Overflow:
mov TrigOverflow, 1
jmp ExitLog086
ShiftUp:
inc cx ; cx = Exp
shl ax, 1
rcl dx, 1
or dx, dx
jns ShiftUp
neg cx
add cx, 31
mov Exp, cx
mov di, dx ; dx = x, 1 <= x < 2, fg 15
add di, 8000h
rcr di, 1 ; di = x + 1, fg 14
shl ax, 1
rcl dx, 1
push ax
push dx
mov ax, dx
mul dx
mov Numerator, dx ; Numerator = (x - 1)**2, fg 16
; 0 <= cx < 1
mov ax, di
mul di
mov si, dx ; Save (x + 1)**2, fg 12
pop dx
pop ax
shr dx, 1
rcr ax, 1
div di
mov LoAns, ax
push ax ; Rem = (x-1)/(x+1), fg 17
mov Denominator, si ; Denominator = (x + 1)**2, fg 12
; 1 <= Denominator < 8
mov Counter, 3
mov cl, 3
mov ch, 13
LogLoop:
pop ax ; ax = Rem, fg 13+cl
mul Numerator ; dx:ax = Rem * (x-1)**2, fg 29+cl
shr dx, 1
rcr ax, 1
div Denominator
push ax ; Rem = [Rem*(x-1)**2]/(x+1)**2, fg 17+cl
xor dx, dx
div Counter ; ax = Rem / Counter, fg 17+cl
mov dx, ax
shr ax, cl ; ax = Rem / Counter, fg 17
cmp ax, WORD PTR TrigLimit
jbe SHORT MultExp
xchg cl, ch
shl dx, cl
add Accum, dx
adc LoAns, ax
adc HiAns, 0
inc Counter
inc Counter
xchg cl, ch
add cl, 3
sub ch, 3
jmp LogLoop
MultExp:
pop cx ; Discard Rem
mov cx, Exp
mov ax, Ln2Fg16
or cx, cx
js SubFromAns
mul cx ; cx = Exp * Lg2Fg16, fg 16
add LoAns, ax
adc HiAns, dx
jmp ExitLog086
SubFromAns:
neg cx
mul cx
sub LoAns, ax
sbb HiAns, dx
ExitLog086:
; r = (x-1)/(x+1)
; Ans = 2 * (r + r**3/3 + r**5/5 +
; . . .) + (Exp * Ln2Fg16), fg 16
mov ax, LoAns
mov dx, HiAns
ret
Log086 ENDP
END