1 ;; Originally from GBDK by Pascal Felber.
185 ; Fall through to .div16
196 ;; If divisor is non-zero, carry=0
197 ;; If divisor is 0, carry=1 and both quotient and remainder are 0
199 ;; Register used: AF,BC,DE,HL
202 ;; Determine sign of quotient by xor-ing high bytes of dividend
203 ;; and divisor. Quotient is positive if signs are the same, negative
204 ;; if signs are different
205 ;; Remainder has same sign as dividend
206 ld a,b ; Get high byte of dividend
207 ld (.srem),a ; Save as sign of remainder
208 xor d ; Xor with high byte of divisor
209 ld (.squot),a ; Save sign of quotient
210 ;; Take absolute value of divisor
212 jr Z,.chkde ; Jump if divisor is positive
213 sub a ; Substract divisor from 0
216 sbc a ; Propagate borrow (A=0xFF if borrow)
219 ;; Take absolute value of dividend
222 jr Z,.dodiv ; Jump if dividend is positive
223 sub a ; Substract dividend from 0
226 sbc a ; Propagate borrow (A=0xFF if borrow)
229 ;; Divide absolute values
232 ret C ; Exit if divide by zero
233 ;; Negate quotient if it is negative
236 jr Z,.dorem ; Jump if quotient is positive
237 sub a ; Substract quotient from 0
240 sbc a ; Propagate borrow (A=0xFF if borrow)
244 ;; Negate remainder if it is negative
247 ret Z ; Return if remainder is positive
248 sub a ; Substract remainder from 0
251 sbc a ; Propagate remainder (A=0xFF if borrow)
260 ; Fall through to divu16
264 ;; Check for division by zero
267 jr NZ,.divide ; Branch if divisor is non-zero
268 ld bc,#0x00 ; Divide by zero error
271 scf ; Set carry, invalid result
274 ld l,c ; L = low byte of dividend/quotient
275 ld h,b ; H = high byte of dividend/quotient
276 ld bc,#0x00 ; BC = remainder
277 or a ; Clear carry to start
278 ld a,#16 ; 16 bits in dividend
280 ;; Shift next bit of quotient into bit 0 of dividend
281 ;; Shift next MSB of dividend into LSB of remainder
282 ;; BC holds both dividend and quotient. While we shift a bit from
283 ;; MSB of dividend, we shift next bit of quotient in from carry
284 ;; HL holds remainder
285 ;; Do a 32-bit left shift, shifting carry to L, L to H,
288 rl l ; Carry (next bit of quotient) to bit 0
289 rl h ; Shift remaining bytes
291 rl b ; Clears carry since BC was 0
292 ;; If remainder is >= divisor, next bit of quotient is 1. This
294 push bc ; Save current remainder
295 ld a,c ; Substract divisor from remainder
301 ccf ; Complement borrow so 1 indicates a
302 ; successful substraction (this is the
303 ; next bit of quotient)
304 jr C,.drop ; Jump if remainder is >= dividend
305 pop bc ; Otherwise, restore remainder
312 dec a ; DEC does not affect carry flag
314 ;; Shift last carry bit into quotient
315 ld d,b ; DE = remainder
318 ld c,l ; C = low byte of quotient
320 ld b,h ; B = high byte of quotient
321 or a ; Clear carry, valid result
327 .ds 0x01 ; Sign of quotient
329 .ds 0x01 ; Sign of remainder
331 .ds 0x01 ; Counter for division