ref: 6c3ec2d13d30fef17a3e636ef22052d90c61d0b5
parent: e21fc0fad19a4411c613d9caadfe13bc6f438d34
author: yenatch <[email protected]>
date: Fri Mar 29 21:58:22 EDT 2013
Multiply and Divide
--- a/hram.asm
+++ b/hram.asm
@@ -26,6 +26,16 @@
hPastLeadingZeroes EQU $ffb3
+hDividend EQU $ffb3
+hDivisor EQU $ffb7
+hQuotient EQU $ffb4
+
+hMultiplicand EQU $ffb4
+hMultiplier EQU $ffb7
+hProduct EQU $ffb3
+
+hMathBuffer EQU $ffb8
+
hLCDStatCustom EQU $ffc6
hBGMapMode EQU $ffd4
--- a/main.asm
+++ b/main.asm
@@ -2932,34 +2932,49 @@
ret
; 0x3105
-INCBIN "baserom.gbc", $3105, $3119-$3105
-Multiply: ; 0x3119
-; function to do multiplication
-; all values are big endian
-; INPUT
-; ffb4-ffb6 = multiplicand
-; ffb7 = multiplier
-; OUTPUT
-; ffb3-ffb6 = product
- INCBIN "baserom.gbc", $3119, $3124 - $3119
-; 0x3124
+INCBIN "baserom.gbc", $3105, $3119 - $3105
-Divide: ; 0x3124
-; function to do division
-; all values are big endian
-; INPUT
-; ffb3-ffb6 = dividend
-; ffb7 = divisor
-; b = number of bytes in the dividend (starting from ffb3)
-; OUTPUT
-; ffb4-ffb6 = quotient
-; ffb7 = remainder
- INCBIN "baserom.gbc", $3124, $3136 - $3124
-; 0x3136
+Multiply: ; 3119
+; Multiply hMultiplicand (3 bytes) by hMultiplier. Result in hProduct.
+; All values are big endian.
+ push hl
+ push bc
+
+ callab _Multiply
+
+ pop bc
+ pop hl
+ ret
+; 3124
+
+
+Divide: ; 3124
+; Divide hDividend length b (max 4 bytes) by hDivisor. Result in hQuotient.
+; All values are big endian.
+ push hl
+ push de
+ push bc
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(_Divide)
+ rst Bankswitch
+
+ call _Divide
+
+ pop af
+ rst Bankswitch
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3136
+
+
INCBIN "baserom.gbc", $3136, $313d - $3136
+
PrintLetterDelay: ; 313d
; wait some frames before printing the next letter
; the text speed setting in Options is actually a frame count
@@ -4141,7 +4156,207 @@
db $ff ; end
; 66de
-INCBIN "baserom.gbc", $66de, $6eef - $66de
+
+_Multiply: ; 66de
+
+; hMultiplier is one byte.
+ ld a, 8
+ ld b, a
+
+ xor a
+ ld [hMultiplicand - 1], a
+ ld [hMathBuffer + 1], a
+ ld [hMathBuffer + 2], a
+ ld [hMathBuffer + 3], a
+ ld [hMathBuffer + 4], a
+
+
+.loop
+ ld a, [hMultiplier]
+ srl a
+ ld [hMultiplier], a
+ jr nc, .next
+
+ ld a, [hMathBuffer + 4]
+ ld c, a
+ ld a, [hMultiplicand + 2]
+ add c
+ ld [hMathBuffer + 4], a
+
+ ld a, [hMathBuffer + 3]
+ ld c, a
+ ld a, [hMultiplicand + 1]
+ adc c
+ ld [hMathBuffer + 3], a
+
+ ld a, [hMathBuffer + 2]
+ ld c, a
+ ld a, [hMultiplicand + 0]
+ adc c
+ ld [hMathBuffer + 2], a
+
+ ld a, [hMathBuffer + 1]
+ ld c, a
+ ld a, [hMultiplicand - 1]
+ adc c
+ ld [hMathBuffer + 1], a
+
+.next
+ dec b
+ jr z, .done
+
+
+; hMultiplicand <<= 1
+
+ ld a, [hMultiplicand + 2]
+ add a
+ ld [hMultiplicand + 2], a
+
+ ld a, [hMultiplicand + 1]
+ rla
+ ld [hMultiplicand + 1], a
+
+ ld a, [hMultiplicand + 0]
+ rla
+ ld [hMultiplicand + 0], a
+
+ ld a, [hMultiplicand - 1]
+ rla
+ ld [hMultiplicand - 1], a
+
+ jr .loop
+
+
+.done
+ ld a, [hMathBuffer + 4]
+ ld [hProduct + 3], a
+
+ ld a, [hMathBuffer + 3]
+ ld [hProduct + 2], a
+
+ ld a, [hMathBuffer + 2]
+ ld [hProduct + 1], a
+
+ ld a, [hMathBuffer + 1]
+ ld [hProduct + 0], a
+
+ ret
+; 673e
+
+
+_Divide: ; 673e
+ xor a
+ ld [hMathBuffer + 0], a
+ ld [hMathBuffer + 1], a
+ ld [hMathBuffer + 2], a
+ ld [hMathBuffer + 3], a
+ ld [hMathBuffer + 4], a
+
+ ld a, 9
+ ld e, a
+
+.loop
+ ld a, [hMathBuffer + 0]
+ ld c, a
+ ld a, [hDividend + 1]
+ sub c
+ ld d, a
+
+ ld a, [hDivisor]
+ ld c, a
+ ld a, [hDividend + 0]
+ sbc c
+ jr c, .asm_6767
+
+ ld [hDividend + 0], a
+
+ ld a, d
+ ld [hDividend + 1], a
+
+ ld a, [hMathBuffer + 4]
+ inc a
+ ld [hMathBuffer + 4], a
+
+ jr .loop
+
+.asm_6767
+ ld a, b
+ cp 1
+ jr z, .done
+
+ ld a, [hMathBuffer + 4]
+ add a
+ ld [hMathBuffer + 4], a
+
+ ld a, [hMathBuffer + 3]
+ rla
+ ld [hMathBuffer + 3], a
+
+ ld a, [hMathBuffer + 2]
+ rla
+ ld [hMathBuffer + 2], a
+
+ ld a, [hMathBuffer + 1]
+ rla
+ ld [hMathBuffer + 1], a
+
+ dec e
+ jr nz, .asm_6798
+
+ ld e, 8
+ ld a, [hMathBuffer + 0]
+ ld [hDivisor], a
+ xor a
+ ld [hMathBuffer + 0], a
+
+ ld a, [hDividend + 1]
+ ld [hDividend + 0], a
+
+ ld a, [hDividend + 2]
+ ld [hDividend + 1], a
+
+ ld a, [hDividend + 3]
+ ld [hDividend + 2], a
+
+.asm_6798
+ ld a, e
+ cp 1
+ jr nz, .asm_679e
+ dec b
+
+.asm_679e
+ ld a, [hDivisor]
+ srl a
+ ld [hDivisor], a
+
+ ld a, [hMathBuffer + 0]
+ rr a
+ ld [hMathBuffer + 0], a
+
+ jr .loop
+
+.done
+ ld a, [hDividend + 1]
+ ld [hDivisor], a
+
+ ld a, [hMathBuffer + 4]
+ ld [hDividend + 3], a
+
+ ld a, [hMathBuffer + 3]
+ ld [hDividend + 2], a
+
+ ld a, [hMathBuffer + 2]
+ ld [hDividend + 1], a
+
+ ld a, [hMathBuffer + 1]
+ ld [hDividend + 0], a
+
+ ret
+; 67c1
+
+
+INCBIN "baserom.gbc", $67c1, $6eef - $67c1
+
DrawGraphic: ; 6eef
; input: