1 ;; Originally from GBDK by Pascal Felber.
172 ; Fall through to .div16
183 ;; If divisor is non-zero, carry=0
184 ;; If divisor is 0, carry=1 and both quotient and remainder are 0
186 ;; Register used: AF,BC,DE,HL
189 ;; Determine sign of quotient by xor-ing high bytes of dividend
190 ;; and divisor. Quotient is positive if signs are the same, negative
191 ;; if signs are different
192 ;; Remainder has same sign as dividend
193 LD A,B ; Get high byte of dividend
194 LD (.srem),A ; Save as sign of remainder
195 XOR D ; Xor with high byte of divisor
196 LD (.squot),A ; Save sign of quotient
197 ;; Take absolute value of divisor
199 JR Z,.chkde ; Jump if divisor is positive
200 SUB A ; Substract divisor from 0
203 SBC A ; Propagate borrow (A=0xFF if borrow)
206 ;; Take absolute value of dividend
209 JR Z,.dodiv ; Jump if dividend is positive
210 SUB A ; Substract dividend from 0
213 SBC A ; Propagate borrow (A=0xFF if borrow)
216 ;; Divide absolute values
219 RET C ; Exit if divide by zero
220 ;; Negate quotient if it is negative
223 JR Z,.dorem ; Jump if quotient is positive
224 SUB A ; Substract quotient from 0
227 SBC A ; Propagate borrow (A=0xFF if borrow)
231 ;; Negate remainder if it is negative
234 RET Z ; Return if remainder is positive
235 SUB A ; Substract remainder from 0
238 SBC A ; Propagate remainder (A=0xFF if borrow)
247 ; Fall through to divu16
251 ;; Check for division by zero
254 JR NZ,.divide ; Branch if divisor is non-zero
255 LD BC,#0x00 ; Divide by zero error
258 SCF ; Set carry, invalid result
261 LD L,C ; L = low byte of dividend/quotient
262 LD H,B ; H = high byte of dividend/quotient
263 LD BC,#0x00 ; BC = remainder
264 OR A ; Clear carry to start
265 LD A,#16 ; 16 bits in dividend
267 ;; Shift next bit of quotient into bit 0 of dividend
268 ;; Shift next MSB of dividend into LSB of remainder
269 ;; BC holds both dividend and quotient. While we shift a bit from
270 ;; MSB of dividend, we shift next bit of quotient in from carry
271 ;; HL holds remainder
272 ;; Do a 32-bit left shift, shifting carry to L, L to H,
275 RL L ; Carry (next bit of quotient) to bit 0
276 RL H ; Shift remaining bytes
278 RL B ; Clears carry since BC was 0
279 ;; If remainder is >= divisor, next bit of quotient is 1. This
281 PUSH BC ; Save current remainder
282 LD A,C ; Substract divisor from remainder
288 CCF ; Complement borrow so 1 indicates a
289 ; successful substraction (this is the
290 ; next bit of quotient)
291 JR C,.drop ; Jump if remainder is >= dividend
292 POP BC ; Otherwise, restore remainder
299 DEC A ; DEC does not affect carry flag
301 ;; Shift last carry bit into quotient
302 LD D,B ; DE = remainder
305 LD C,L ; C = low byte of quotient
307 LD B,H ; B = high byte of quotient
308 OR A ; Clear carry, valid result
314 .ds 0x01 ; Sign of quotient
316 .ds 0x01 ; Sign of remainder
318 .ds 0x01 ; Counter for division