1 ;; Originally from GBDK by Pascal Felber.
76 ; Fall through to __div16
78 ;; signed 16-bit division
87 ;; If divisor is non-zero, carry=0
88 ;; If divisor is 0, carry=1 and both quotient and remainder are 0
90 ;; Register used: AF,BC,DE,HL
93 ;; Determine sign of quotient by xor-ing high bytes of dividend
94 ;; and divisor. Quotient is positive if signs are the same, negative
95 ;; if signs are different
96 ;; Remainder has same sign as dividend
97 ld a,h ; Get high byte of dividend
98 xor d ; Xor with high byte of divisor
99 rla ; Sign of quotient goes into the carry
100 ld a,h ; Get high byte of dividend
101 push af ; Save sign of both quotient and reminder
103 ;; Take absolute value of dividend
105 jr NC,.chkde ; Jump if dividend is positive
106 sub a ; Substract dividend from 0
109 sbc a ; Propagate borrow (A=0xFF if borrow)
112 ;; Take absolute value of divisor
115 jr Z,.dodiv ; Jump if divisor is positive
116 sub a ; Substract divisor from 0
119 sbc a ; Propagate borrow (A=0xFF if borrow)
122 ;; Divide absolute values
125 jr C,.exit ; Exit if divide by zero
126 ;; Negate quotient if it is negative
127 pop af ; recover sign of quotient
128 jr NC,.dorem ; Jump if quotient is positive
130 sub a ; Substract quotient from 0
133 sbc a ; Propagate borrow (A=0xFF if borrow)
138 ;; Negate remainder if it is negative
140 ret NC ; Return if remainder is positive
141 sub a ; Substract remainder from 0
144 sbc a ; Propagate remainder (A=0xFF if borrow)
152 ld h,d ; Divide by zero error: D=E=0
154 scf ; Set carry, invalid result
171 ; Fall through to divu16
173 ;; unsigned 16-bit division
174 ;; Restructured on April 2009 by Marco Bodrato(http://bodrato.it/ )
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,B,DE,HL
189 ;; Check for division by zero
192 jr Z,.dividebyzero ; Branch if divisor is non-zero
196 ;; Carry was cleared by OR, this "0" bit will pass trough AC.[*]
197 ld b,#16 ; 16 bits in dividend
199 ;; Cleaned up on April 2009 by Marco Bodrato(http://bodrato.it/ )
200 ;; Shift next bit of quotient into bit 0 of dividend
201 ;; Shift next MSB of dividend into LSB of remainder
202 ;; AC holds both dividend and quotient. While we shift a bit from
203 ;; MSB of dividend, we shift next bit of quotient in from carry
204 ;; HL holds remainder
205 ;; Do a 32-bit left shift, shifting carry to C, C to A,
207 rl c ; Carry (next bit of quotient) to bit 0
209 adc hl,hl ; HL < 32768 before, no carry, ever.
211 ;; If remainder is >= divisor, next bit of quotient is 1. We try
212 ;; to compute the difference.
214 jr NC,.nodrop ; Jump if remainder is >= dividend
215 add hl,de ; Otherwise, restore remainder
216 ;; The add above sets the carry, because sbc hl,de did set it.
218 ccf ; Complement borrow so 1 indicates a
219 ; successful substraction (this is the
220 ; next bit of quotient)
222 ;; Shift last carry bit into quotient
225 ;; Carry now contains the same value it contained before
226 ;; entering .dvloop[*]: "0" = valid result.
228 ld e,c ; DE = quotient, HL = remainder
229 ex de,hl ; HL = quotient, DE = remainder