Mul8b:
;Multiplies 2 8bit numbers
;IN: h and e
;OUT: h * e in hl
;DESTROYS: hl, b, d
ld d, 0
ld l, d
ld b, 8
_Mul_8b_loop:
add hl, hl
jr nc, _Mul_8b_skip
add hl, de
_Mul_8b_skip:
djnz _Mul_8b_loop
ret
SqrtA:
LD (Asqr),A
SRL A
JR DataOver
Asqr:
.DB 0
Bsqr:
.DB 0
Csqr:
.DB 0
DataOver:
LD (Bsqr),A
LD B,A
LD (Csqr),A
iterate:
LD A,(Bsqr)
ld b, a
LD a,(Asqr)
LD D,A
LD E,B
divideDbyEreturnA:
RL D
RLA
SUB E
JR nc,$+3
ADD A,E
LD E,A
LD A,D
CPL
push af ;1
LD a,(Bsqr)
ld b, a
pop af ;0
ADD A,B
SRL A
LD (Bsqr),A
LD a,(Bsqr)
ld b, a
LD A,(Csqr)
DEC A
CP B
JR z,done
push af ;1
LD (Csqr),a
ld b, a
pop af ;0
JR iterate
done:
LD A,(Bsqr)
RET
Div16By8:
;divides a 16-bit number by an 8-bit number
;IN: hl and d
;OUT: hl = hl/d, remainder = a
;DESTROYS: a, b, c, d, hl
xor a
ld b, 16
_D16b8Loop:
add hl, hl
rla
jr c, _D16b8Overflow
cp d
jr c, _D16b8Skip
_D16b8Overflow:
sub b
inc l
_D16b8Skip:
djnz _D16b8Loop
ret
SubFP:
;substracts 2 16-bit fixed-point numbers
;IN: bc, de
;OUT: bc - de in de
;DESTROYS: a, de
ld a, b
sub d
ld d, a
ld a, c
sub e
ld a, e
ret
MulFP:
;Multiplies 2 16bit fixed-point numbers
;IN: hl, bc
;OUT: hl * bc in de
;DESTROYS: hl, bc, de
ld e, b
push hl ;1
push bc ;2
call Mul8b
pop bc ;1
pop hl ;0
push de ;1
ld h, l
ld e, c
call Mul8b
pop hl ;0
ld e, d
ld d, l
ret
;adding fixed-point numbers:
;load one of the numbers in hl, and the other in an other 16-bit register.
;then, do: add hl, <register>
DivFP:
;IN: hl, de
;OUT: hl = hl / de
ld a, h
ld h, l
ld l, 0
call Div24by16
ret
Div24by16:
push hl ;INPUTS: ahl = dividend de = divisor ;1
pop ix ;OUTPUTS: ahl = quotient de = divisor ;0
ld hl,0
ld b,24
_Div24by16loop:
add ix,ix
rla
adc hl,hl
jr c,_Div24by16setbit
or a
sbc hl,de
add hl,de
jr c,_Div24by16skip
_Div24by16setbit:
or a
sbc hl,de
inc ix
_Div24by16skip:
djnz _Div24by16loop
push ix ;1
pop hl ;0
ret
SinA:
;calculates the sine of a as a fixed point number
;IN: a
;OUT: hl = sin(a)
LD H, 0
LD L, A
LD DE, sine_table
ADD HL, DE
LD A, (HL)
INC HL
LD H, (HL)
LD L, A
RET
sine_table:
.DW $0000, $0004, $0009, $000D, $0012, $0016, $001B, $001F, $0024
.DW $0028, $002C, $0031, $0035, $003A, $003E, $0042, $0047, $004B
.DW $004F, $0053, $0058, $005C, $0060, $0064, $0068, $006C, $0070
.DW $0074, $0078, $007C, $0080, $0084, $0088, $008B, $008F, $0093
.DW $0096, $009A, $009E, $00A1, $00A5, $00A8, $00AB, $00AF, $00B2
.DW $00B5, $00B8, $00BB, $00BE, $00C1, $00C4, $00C7, $00CA, $00CC
.DW $00CF, $00D2, $00D4, $00D7, $00D9, $00DB, $00DE, $00E0, $00E2
.DW $00E4, $00E6, $00E8, $00EA, $00EC, $00ED, $00EF, $00F1, $00F2
.DW $00F3, $00F5, $00F6, $00F7, $00F8, $00F9, $00FA, $00FB, $00FC
.DW $00FD, $00FE, $00FE, $00FF, $00FF, $00FF, $0100, $0100, $0100
SqrtFP:
;IN: hl
;OUT: hl = sqrt(hl)
ld a, h
call SqrtA
ld h, a
ld a, l
call SqrtA
ld l, a
ret