1 ;; Originally from GBDK by Pascal Felber.
137 ; Fall through to .div16
148 ;; If divisor is non-zero, carry=0
149 ;; If divisor is 0, carry=1 and both quotient and remainder are 0
151 ;; Register used: AF,BC,DE,HL
154 ;; Determine sign of quotient by xor-ing high bytes of dividend
155 ;; and divisor. Quotient is positive if signs are the same, negative
156 ;; if signs are different
157 ;; Remainder has same sign as dividend
158 LD A,B ; Get high byte of dividend
159 LD (.srem),A ; Save as sign of remainder
160 XOR D ; Xor with high byte of divisor
161 LD (.squot),A ; Save sign of quotient
162 ;; Take absolute value of divisor
164 JR Z,.chkde ; Jump if divisor is positive
165 SUB A ; Substract divisor from 0
168 SBC A ; Propagate borrow (A=0xFF if borrow)
171 ;; Take absolute value of dividend
174 JR Z,.dodiv ; Jump if dividend is positive
175 SUB A ; Substract dividend from 0
178 SBC A ; Propagate borrow (A=0xFF if borrow)
181 ;; Divide absolute values
184 RET C ; Exit if divide by zero
185 ;; Negate quotient if it is negative
188 JR Z,.dorem ; Jump if quotient is positive
189 SUB A ; Substract quotient from 0
192 SBC A ; Propagate borrow (A=0xFF if borrow)
196 ;; Negate remainder if it is negative
199 RET Z ; Return if remainder is positive
200 SUB A ; Substract remainder from 0
203 SBC A ; Propagate remainder (A=0xFF if borrow)
212 ; Fall through to divu16
216 ;; Check for division by zero
219 JR NZ,.divide ; Branch if divisor is non-zero
220 LD BC,#0x00 ; Divide by zero error
223 SCF ; Set carry, invalid result
226 LD L,C ; L = low byte of dividend/quotient
227 LD H,B ; H = high byte of dividend/quotient
228 LD BC,#0x00 ; BC = remainder
229 OR A ; Clear carry to start
230 LD A,#16 ; 16 bits in dividend
232 ;; Shift next bit of quotient into bit 0 of dividend
233 ;; Shift next MSB of dividend into LSB of remainder
234 ;; BC holds both dividend and quotient. While we shift a bit from
235 ;; MSB of dividend, we shift next bit of quotient in from carry
236 ;; HL holds remainder
237 ;; Do a 32-bit left shift, shifting carry to L, L to H,
240 RL L ; Carry (next bit of quotient) to bit 0
241 RL H ; Shift remaining bytes
243 RL B ; Clears carry since BC was 0
244 ;; If remainder is >= divisor, next bit of quotient is 1. This
246 PUSH BC ; Save current remainder
247 LD A,C ; Substract divisor from remainder
253 CCF ; Complement borrow so 1 indicates a
254 ; successful substraction (this is the
255 ; next bit of quotient)
256 JR C,.drop ; Jump if remainder is >= dividend
257 POP BC ; Otherwise, restore remainder
264 DEC A ; DEC does not affect carry flag
266 ;; Shift last carry bit into quotient
267 LD D,B ; DE = remainder
270 LD C,L ; C = low byte of quotient
272 LD B,H ; B = high byte of quotient
273 OR A ; Clear carry, valid result
279 .ds 0x01 ; Sign of quotient
281 .ds 0x01 ; Sign of remainder
283 .ds 0x01 ; Counter for division