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 push af ; Save as sign of remainder
208 xor d ; Xor with high byte of divisor
209 push af ; Save sign of quotient
211 ;; Take absolute value of divisor
213 jr Z,.chkde ; Jump if divisor is positive
214 sub a ; Substract divisor from 0
217 sbc a ; Propagate borrow (A=0xFF if borrow)
220 ;; Take absolute value of dividend
223 jr Z,.dodiv ; Jump if dividend is positive
224 sub a ; Substract dividend from 0
227 sbc a ; Propagate borrow (A=0xFF if borrow)
230 ;; Divide absolute values
233 jr C,.exit ; Exit if divide by zero
234 ;; Negate quotient if it is negative
235 pop af ; recover sign of quotient
237 jr Z,.dorem ; Jump if quotient is positive
238 sub a ; Substract quotient from 0
241 sbc a ; Propagate borrow (A=0xFF if borrow)
245 ;; Negate remainder if it is negative
246 pop af ; recover sign of remainder
248 ret Z ; Return if remainder is positive
249 sub a ; Substract remainder from 0
252 sbc a ; Propagate remainder (A=0xFF if borrow)
265 ; Fall through to divu16
269 ;; Check for division by zero
272 jr NZ,.divide ; Branch if divisor is non-zero
273 ld bc,#0x00 ; Divide by zero error
276 scf ; Set carry, invalid result
279 ld l,c ; L = low byte of dividend/quotient
280 ld h,b ; H = high byte of dividend/quotient
281 ld bc,#0x00 ; BC = remainder
282 or a ; Clear carry to start
283 ld a,#16 ; 16 bits in dividend
285 ;; Shift next bit of quotient into bit 0 of dividend
286 ;; Shift next MSB of dividend into LSB of remainder
287 ;; BC holds both dividend and quotient. While we shift a bit from
288 ;; MSB of dividend, we shift next bit of quotient in from carry
289 ;; HL holds remainder
290 ;; Do a 32-bit left shift, shifting carry to L, L to H,
292 push af ; save number of bits remaining
293 rl l ; Carry (next bit of quotient) to bit 0
294 rl h ; Shift remaining bytes
296 rl b ; Clears carry since BC was 0
297 ;; If remainder is >= divisor, next bit of quotient is 1. This
299 push bc ; Save current remainder
300 ld a,c ; Substract divisor from remainder
306 ccf ; Complement borrow so 1 indicates a
307 ; successful substraction (this is the
308 ; next bit of quotient)
309 jr C,.drop ; Jump if remainder is >= dividend
310 pop bc ; Otherwise, restore remainder
311 pop af ; recover # bits remaining, carry flag destroyed
313 or a ; restore (clear) the carry flag
319 pop af ; recover # bits remaining, carry flag destroyed
321 scf ; restore (set) the carry flag
325 ;; Shift last carry bit into quotient
326 ld d,b ; DE = remainder
329 ld c,l ; C = low byte of quotient
331 ld b,h ; B = high byte of quotient
332 or a ; Clear carry, valid result