diff options
Diffstat (limited to 'engine/math/multiply_divide.asm')
-rwxr-xr-x | engine/math/multiply_divide.asm | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/engine/math/multiply_divide.asm b/engine/math/multiply_divide.asm new file mode 100755 index 00000000..2fcda158 --- /dev/null +++ b/engine/math/multiply_divide.asm @@ -0,0 +1,143 @@ +_Multiply:: + ld a, $8 + ld b, a + xor a + ldh [hProduct], a + ldh [hMultiplyBuffer], a + ldh [hMultiplyBuffer+1], a + ldh [hMultiplyBuffer+2], a + ldh [hMultiplyBuffer+3], a +.loop + ldh a, [hMultiplier] + srl a + ldh [hMultiplier], a ; (aliases: hDivisor, hMultiplier, hPowerOf10) + jr nc, .smallMultiplier + ldh a, [hMultiplyBuffer+3] + ld c, a + ldh a, [hMultiplicand+2] + add c + ldh [hMultiplyBuffer+3], a + ldh a, [hMultiplyBuffer+2] + ld c, a + ldh a, [hMultiplicand+1] + adc c + ldh [hMultiplyBuffer+2], a + ldh a, [hMultiplyBuffer+1] + ld c, a + ldh a, [hMultiplicand] ; (aliases: hMultiplicand) + adc c + ldh [hMultiplyBuffer+1], a + ldh a, [hMultiplyBuffer] + ld c, a + ldh a, [hProduct] ; (aliases: hProduct, hPastLeadingZeros, hQuotient) + adc c + ldh [hMultiplyBuffer], a +.smallMultiplier + dec b + jr z, .done + ldh a, [hMultiplicand+2] + sla a + ldh [hMultiplicand+2], a + ldh a, [hMultiplicand+1] + rl a + ldh [hMultiplicand+1], a + ldh a, [hMultiplicand] + rl a + ldh [hMultiplicand], a + ldh a, [hProduct] + rl a + ldh [hProduct], a + jr .loop +.done + ldh a, [hMultiplyBuffer+3] + ldh [hProduct+3], a + ldh a, [hMultiplyBuffer+2] + ldh [hProduct+2], a + ldh a, [hMultiplyBuffer+1] + ldh [hProduct+1], a + ldh a, [hMultiplyBuffer] + ldh [hProduct], a + ret + +_Divide:: + xor a + ldh [hDivideBuffer], a + ldh [hDivideBuffer+1], a + ldh [hDivideBuffer+2], a + ldh [hDivideBuffer+3], a + ldh [hDivideBuffer+4], a + ld a, $9 + ld e, a +.asm_37db3 + ldh a, [hDivideBuffer] + ld c, a + ldh a, [hDividend+1] ; (aliases: hMultiplicand) + sub c + ld d, a + ldh a, [hDivisor] ; (aliases: hDivisor, hMultiplier, hPowerOf10) + ld c, a + ldh a, [hDividend] ; (aliases: hProduct, hPastLeadingZeros, hQuotient) + sbc c + jr c, .asm_37dce + ldh [hDividend], a ; (aliases: hProduct, hPastLeadingZeros, hQuotient) + ld a, d + ldh [hDividend+1], a ; (aliases: hMultiplicand) + ldh a, [hDivideBuffer+4] + inc a + ldh [hDivideBuffer+4], a + jr .asm_37db3 +.asm_37dce + ld a, b + cp $1 + jr z, .asm_37e18 + ldh a, [hDivideBuffer+4] + sla a + ldh [hDivideBuffer+4], a + ldh a, [hDivideBuffer+3] + rl a + ldh [hDivideBuffer+3], a + ldh a, [hDivideBuffer+2] + rl a + ldh [hDivideBuffer+2], a + ldh a, [hDivideBuffer+1] + rl a + ldh [hDivideBuffer+1], a + dec e + jr nz, .asm_37e04 + ld a, $8 + ld e, a + ldh a, [hDivideBuffer] + ldh [hDivisor], a ; (aliases: hDivisor, hMultiplier, hPowerOf10) + xor a + ldh [hDivideBuffer], a + ldh a, [hDividend+1] ; (aliases: hMultiplicand) + ldh [hDividend], a ; (aliases: hProduct, hPastLeadingZeros, hQuotient) + ldh a, [hDividend+2] + ldh [hDividend+1], a ; (aliases: hMultiplicand) + ldh a, [hDividend+3] + ldh [hDividend+2], a +.asm_37e04 + ld a, e + cp $1 + jr nz, .asm_37e0a + dec b +.asm_37e0a + ldh a, [hDivisor] ; (aliases: hDivisor, hMultiplier, hPowerOf10) + srl a + ldh [hDivisor], a ; (aliases: hDivisor, hMultiplier, hPowerOf10) + ldh a, [hDivideBuffer] + rr a + ldh [hDivideBuffer], a + jr .asm_37db3 +.asm_37e18 + ldh a, [hDividend+1] ; (aliases: hMultiplicand) + ldh [hRemainder], a ; (aliases: hDivisor, hMultiplier, hPowerOf10) + ldh a, [hDivideBuffer+4] + ldh [hQuotient+3], a + ldh a, [hDivideBuffer+3] + ldh [hQuotient+2], a + ldh a, [hDivideBuffer+2] + ldh [hQuotient+1], a ; (aliases: hMultiplicand) + ldh a, [hDivideBuffer+1] + ldh [hDividend], a ; (aliases: hProduct, hPastLeadingZeros, hQuotient) + ret |