ifndef included_xpow2
define included_xpow2
include "../common/pushpop.asm"
include "../common/mov.asm"
include "routines/sla64.asm"
include "routines/normalizexOP1.asm"
include "constantsx.asm"
include "xmul.asm"
include "xadd.asm"
xexp_x=xOP3+42
;use range reduction to get x on [0,1]
;Then use the formula:
;2^x ~ 1+x(p1+x(p2+...+x(p11+x*p12)...))
caseexp:
exp_too_big:
pop de
ret
xpow2:
call pushpop
push bc
ld de,xOP1
call mov10
ld hl,(xOP1+8)
res 7,h
ld a,h
or l
jr z,caseexp
;If HL<3FF3 or HL>=400E, then magnitudes are too high
ld bc,-$3EF3
add hl,bc
dec h
jr nz,exp_too_big
ld a,l
cp 27
jr nc,exp_too_big
;Now we know the exponent isn't too big
;
;Range Reduction phase
;e=int(x+.5)
;x-=e
;now we compute 2^e*2^x, where e is an integer
ld de,0
sub 13
inc a
jr c,xexp_ipart0
ld b,a
;now we need to shift bits in from the mantissa!
xpow2rl0;_:
call sla64_xOP1
rl e : rl d
djnz xpow2rl0;-_
ld a,(xOP1+9)
add a,a
ld hl,$3FFF
jr nc,xpow2p;+_
xor a : sub e : ld e,a
sbc a,a : sub d : ld d,a
ld h,$BF
xpow2p;_:
ld (xOP1+8),hl
call normalizexOP1
xexp_ipart0:
;!!!! Future Zeda, investigate! I think this should actually be fine on (-1,1) :O
;!!!! If not, we'll need to check if the input is negative, add 1, decrement DE
push de
ld hl,xOP1
ld de,xexp_x
call mov10
ld hl,xOP1
ld b,h
ld c,l
ld de,xexp_p12
call xmul
ld de,xexp_p11 : call xpow2addmul;+_
ld de,xexp_p10 : call xpow2addmul;+_
ld de,xexp_p9 : call xpow2addmul;+_
ld de,xexp_p8 : call xpow2addmul;+_
ld de,xexp_p7 : call xpow2addmul;+_
ld de,xexp_p6 : call xpow2addmul;+_
ld de,xexp_p5 : call xpow2addmul;+_
ld de,xexp_p4 : call xpow2addmul;+_
ld de,xexp_p3 : call xpow2addmul;+_
ld de,xexp_p2 : call xpow2addmul;+_
ld de,xexp_p1 : call xpow2addmul;+_
ld de,xconst_1 : call xadd
pop de
;now I need to add DE as a signed integer to the exponent
ld hl,(xOP1+8)
add hl,de
ld (xOP1+8),hl
pop de
ld h,b
ld l,c
jp mov10
xpow2addmul;_:
call xadd
ld de,xexp_x
jp xmul
xexp_p1:
xexp_p2 = xexp_p1+10
xexp_p3 = xexp_p1+20
xexp_p4 = xexp_p1+30
xexp_p5 = xexp_p1+40
xexp_p6 = xexp_p1+50
xexp_p7 = xexp_p1+60
xexp_p8 = xexp_p1+70
xexp_p9 = xexp_p1+80
xexp_p10= xexp_p1+90
xexp_p11= xexp_p1+100
xexp_p12= xexp_p1+110
db $A2,$78,$CF,$D1,$F7,$17,$72,$B1,$FF,$3F ;0.6931471805599452949907356518859092751897692718065
db $99,$67,$2D,$16,$FC,$EF,$FD,$F5,$FD,$3F ;0.240226506959101553103846007431060297021429734606215
db $10,$CD,$AF,$24,$B8,$46,$58,$E3,$FB,$3F ;5.55041086648024431020190322727610690536837023045e-2
db $F8,$78,$4B,$E2,$7D,$5B,$95,$9D,$F9,$3F ;9.6181291078536164406046473880520178751949899000523e-3
db $5B,$9D,$F3,$DF,$38,$FF,$C3,$AE,$F6,$3F ;1.33335581307383609544222238286864444825050937393667e-3
db $A4,$71,$3C,$26,$F7,$89,$84,$A1,$F3,$3F ;1.540353109220040892607797490525175686435054921034e-4
db $BC,$AB,$25,$27,$57,$E7,$E5,$FF,$EF,$3F ;1.5252713038026820986694573437398168701085442050318e-5
db $66,$AE,$E1,$25,$E7,$82,$61,$B1,$EC,$3F ;1.32159071914904607697946887057043728604916889120466e-6
db $FA,$40,$26,$7A,$19,$AD,$72,$DA,$E8,$3F ;1.01722755371157108831058054858407530634720014307972e-7
db $5F,$A3,$56,$C8,$B3,$E2,$40,$F4,$E4,$3F ;7.1087112650916814301740895279260149232576576809875e-9
db $8C,$EE,$B8,$06,$1D,$21,$F6,$E2,$E0,$3F ;4.1284045941236206883307640217911126100813512882446e-10
db $3E,$73,$CA,$31,$87,$36,$5F,$9F,$DD,$3F ;3.6236980527707885031220529305671221862606493025011e-11
;#undefine xexp_x
endif