;gsmath... lots of useful routines & stuff

.model medium, basic
.386
.data
public oldcw, newcw, rnd1, rnd2
rnd1 dd ?
rnd2 dd ?
oldcw dw ?
newcw dw ?

.code
public gsrnd
gsrnd proc
;function gsrnd& ()
add rnd1, 291833782
mov eax, rnd1
mov dx, ax
mov ebx, eax
and ebx, 00000000000000001111111111101100b
add eax, ds:[ebx]
add dx, ds:[ebx+16]
add rnd2, eax
mov eax, rnd2
ror eax, 22
ret
gsrnd endp

public gsmul
gsmul proc
mov di, [esp+4]
mov bx, [esp+8]
mov si, [esp+6]
mov ax, di
fld qword ptr [bx]
fld qword ptr [si]
fmul
fstp qword ptr [di]
ret 6
gsmul endp

public gsdiv
gsdiv proc
mov di, [esp+4]
mov bx, [esp+8]
mov si, [esp+6]
mov ax, di
fld qword ptr [bx]
fld qword ptr [si]
fdiv
fstp qword ptr [di]
ret 6
gsdiv endp

public gstwotothex
gstwotothex proc
fstcw oldcw
fstcw newcw
or word ptr newcw+1, 1100b
fldcw newcw
mov di, [esp+4]
mov si, [esp+6]
fld qword ptr [si]
fld st(0)                 ;st(0) = st(1) = st(2) = [[esp+6]]
frndint                   ;st(0) = int(st(0))
fxch
fsub st(0), st(1)         ;st(0) = frac[[esp+6]]
f2xm1                     ;st(0) = 2^(frac[[esp+6]]-1 : st(1) = [[esp+6]]
fld1                      ;st(0) = 1 : st(1) = 2^frac(x)-1 : st(1) = x
fadd                      ;st(0) = 2^frac(x) : st(1) = x
fxch
fld1
fscale
fstp st(1)
fmul
fldcw oldcw
fstp qword ptr [di]
mov ax, di
ret 4
gstwotothex endp

public gspow
gspow proc
mov si, [esp+8]
mov di, [esp+4]
mov bx, [esp+6]
mov ax, di
fld qword ptr [bx]
fld1
fld qword ptr [si]
fyl2x
fmul
fstcw oldcw
fstcw newcw
or word ptr newcw+1, 1100b
fldcw newcw
fld st(0)                 ;st(0) = st(1) = st(2) = [[esp+6]]
frndint                   ;st(0) = int(st(0))
fxch
fsub st(0), st(1)         ;st(0) = frac[[esp+6]]
f2xm1                     ;st(0) = 2^(frac[[esp+6]]-1 : st(1) = [[esp+6]]
fld1                      ;st(0) = 1 : st(1) = 2^frac(x)-1 : st(1) = x
fadd                      ;st(0) = 2^frac(x) : st(1) = x
fxch
fld1
fscale
fstp st(1)
fmul
fldcw oldcw
fstp qword ptr [di]
ret 6
gspow endp

public gslogxy
gslogxy proc
mov di, [esp+4]
mov si, [esp+8]
mov bx, [esp+6]
mov ax, di
fld1
fld qword ptr [bx]
fyl2x
fld1
fld qword ptr [si]
fyl2x
fdiv
fstp qword ptr [di]
ret 6
gslogxy endp

public gssin
gssin proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fsin
fstp qword ptr [di]
ret 4
gssin endp

public gscos
gscos proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fcos
fstp qword ptr [di]
ret 4
gscos endp

public gstan
gstan proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fsincos
fdiv
fstp qword ptr [di]
ret 4
gstan endp

public gscsc
gscsc proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fsin
fld1
fdivr
fstp qword ptr [di]
ret 4
gscsc endp

public gssec
gssec proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fcos
fld1
fdivr
fstp qword ptr [di]
ret 4
gssec endp

public gscot
gscot proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fsincos
fdivr
fstp qword ptr [di]
ret 4
gscot endp

public gsasin
gsasin proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fld st(0)
fmul
fld st(0)
fld1
fsubr
fdivr
fsqrt
fld1
fpatan
fstp qword ptr [di]
ret 4
gsasin endp

public gsacos
gsacos proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fld st(0)
fmul
fld st(0)
fld1
fsubr
fdiv
fsqrt
fld1
fpatan
fstp qword ptr [di]
ret 4
gsacos endp

public gsatan
gsatan proc
mov di, [esp+4]
mov si, [esp+8]
mov bx, [esp+6]
mov ax, di
fld qword ptr [si]
fld qword ptr [bx]
fpatan
fstp qword ptr [di]
ret 6
gsatan endp

public gsacsc
gsacsc proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fld st(0)
fmul
fld1
fsub
fsqrt
fld1
fxch
fpatan
fstp qword ptr [di]
ret 4
gsacsc endp

public gsasec
gsasec proc
mov di, [esp+4]
mov si, [esp+6]
mov ax, di
fld qword ptr [si]
fld st(0)
fmul
fld1
fsub
fsqrt
fld1
fpatan
fstp qword ptr [di]
ret 4
gsasec endp

public gsacot
gsacot proc
mov di, [esp+4]
mov si, [esp+8]
mov bx, [esp+6]
mov ax, di
fld qword ptr [si]
fld qword ptr [bx]
fpatan
fld1
fdivr
fstp qword ptr [di]
ret 6
gsacot endp

public gssqr
gssqr proc
mov si, [esp+6]
mov di, [esp+4]
mov ax, di
fld qword ptr [si]
fsqrt
fstp qword ptr [di]
ret 4
gssqr endp

public gsangle        
gsangle proc          
mov si, [esp+12]      
mov di, [esp+4]       
mov bx, [esp+8]
fld qword ptr [si]    
fld qword ptr [bx]    
fsubr
ftst
fstsw ax
test ax, 8
jnz dxiszero
test ax, 1
jnz dxisnegative
mov si, [esp+10]
mov bx, [esp+6]
fld qword ptr [si]
fld qword ptr [bx]
fsubr
normal:
fxch
fpatan
fstp qword ptr [di]
mov ax, di
ret 10
dxiszero:
mov si, [esp+10]
mov bx, [esp+6]
fsubr
ftst
fstsw ax
test ax, 1
jnz xzeroyneg
test ax, 8
jz normal  
fstp st(0)
fstp st(0)
fldz
fstp qword ptr [di]
mov ax, di
ret 10
dxisnegative:
mov si, [esp+10]
mov bx, [esp+6]
fsubr
xzeroyneg:
fxch
fpatan
fldpi
fadd
fstp qword ptr [di]
mov ax, di
ret 10
gsangle endp

public gsdist2
gsdist2 proc
mov si, [esp+12]
mov di, [esp+4]
mov bx, [esp+8]
mov ax, di
fld qword ptr [si]
fld qword ptr [bx]
fsub
fld st(0)
fmul
mov si, [esp+10]
mov bx, [esp+6]
fld qword ptr [si]
fld qword ptr [bx]
fsub
fld st(0)
fmul
fadd
fsqrt
fstp qword ptr [di]
ret 10
gsdist2 endp

public gsdist3
gsdist3 proc
mov di, [esp+4]
mov si, [esp+16]
mov bx, [esp+10]
mov ax, di
fld qword ptr [si]
fld qword ptr [bx]
fsub
fld st(0)
fmul
mov si, [esp+14]
mov bx, [esp+8]
fld qword ptr [si]
fld qword ptr [bx]
fsub
fld st(0)
fmul
mov si, [esp+12]
mov bx, [esp+6]
fadd
fld qword ptr [si]
fld qword ptr [bx]
fsub
fld st(0)
fmul
fadd
fsqrt
fstp qword ptr [di]
ret 14
gsdist3 endp
end
