;; if signs are different
;; Remainder has same sign as dividend
ld a,b ; Get high byte of dividend
- ld (.srem),a ; Save as sign of remainder
+ push af ; Save as sign of remainder
xor d ; Xor with high byte of divisor
- ld (.squot),a ; Save sign of quotient
+ push af ; Save sign of quotient
+
;; Take absolute value of divisor
bit 7,d
jr Z,.chkde ; Jump if divisor is positive
;; Divide absolute values
.dodiv:
call .divu16
- ret C ; Exit if divide by zero
+ jr C,.exit ; Exit if divide by zero
;; Negate quotient if it is negative
- ld a,(.squot)
+ pop af ; recover sign of quotient
and #0x80
jr Z,.dorem ; Jump if quotient is positive
sub a ; Substract quotient from 0
ld b,a
.dorem:
;; Negate remainder if it is negative
- ld a,(.srem)
+ pop af ; recover sign of remainder
and #0x80
ret Z ; Return if remainder is positive
sub a ; Substract remainder from 0
sub d
ld d,a
ret
+.exit:
+ pop af
+ pop af
+ ret
.divu8::
.modu8::
;; HL holds remainder
;; Do a 32-bit left shift, shifting carry to L, L to H,
;; H to C, C to B
- ld (.dcnt),a
+ push af ; save number of bits remaining
rl l ; Carry (next bit of quotient) to bit 0
rl h ; Shift remaining bytes
rl c
; next bit of quotient)
jr C,.drop ; Jump if remainder is >= dividend
pop bc ; Otherwise, restore remainder
+ pop af ; recover # bits remaining, carry flag destroyed
+ dec a
+ or a ; restore (clear) the carry flag
+ jr NZ,.dvloop
jr .nodrop
.drop:
inc sp
inc sp
-.nodrop:
- ld a,(.dcnt)
- dec a ; DEC does not affect carry flag
+ pop af ; recover # bits remaining, carry flag destroyed
+ dec a
+ scf ; restore (set) the carry flag
jr NZ,.dvloop
+ jr .nodrop
+.nodrop:
;; Shift last carry bit into quotient
ld d,b ; DE = remainder
ld e,c
ld b,h ; B = high byte of quotient
or a ; Clear carry, valid result
ret
-
- .area _BSS
-
-.srem:
- .ds 0x01 ; Sign of quotient
-.squot:
- .ds 0x01 ; Sign of remainder
-.dcnt:
- .ds 0x01 ; Counter for division
;; if signs are different
;; Remainder has same sign as dividend
ld a,b ; Get high byte of dividend
- ld (.srem),a ; Save as sign of remainder
+ push af ; Save as sign of remainder
xor d ; Xor with high byte of divisor
- ld (.squot),a ; Save sign of quotient
+ push af ; Save sign of quotient
+
;; Take absolute value of divisor
bit 7,d
- jp Z,.chkde ; Jump if divisor is positive
+ jr Z,.chkde ; Jump if divisor is positive
sub a ; Substract divisor from 0
sub e
ld e,a
;; Take absolute value of dividend
.chkde:
bit 7,b
- jp Z,.dodiv ; Jump if dividend is positive
+ jr Z,.dodiv ; Jump if dividend is positive
sub a ; Substract dividend from 0
sub c
ld c,a
;; Divide absolute values
.dodiv:
call .divu16
- ret C ; Exit if divide by zero
+ jr C,.exit ; Exit if divide by zero
;; Negate quotient if it is negative
- ld a,(.squot)
+ pop af ; recover sign of quotient
and #0x80
- jp Z,.dorem ; Jump if quotient is positive
+ jr Z,.dorem ; Jump if quotient is positive
sub a ; Substract quotient from 0
sub c
ld c,a
ld b,a
.dorem:
;; Negate remainder if it is negative
- ld a,(.srem)
+ pop af ; recover sign of remainder
and #0x80
ret Z ; Return if remainder is positive
sub a ; Substract remainder from 0
sub d
ld d,a
ret
+.exit:
+ pop af
+ pop af
+ ret
.divu8::
.modu8::
;; Check for division by zero
ld a,e
or d
- jp NZ,.divide ; Branch if divisor is non-zero
+ jr NZ,.divide ; Branch if divisor is non-zero
ld bc,#0x00 ; Divide by zero error
ld d,b
ld e,c
; ld h,b ; H = high byte of dividend/quotient
; ld bc,#0x00 ; BC = remainder
or a ; Clear carry to start
- ex af,af
+ ex af,af'
ld a,#16 ; 16 bits in dividend
.dvloop:
;; Shift next bit of quotient into bit 0 of dividend
ccf ; Complement borrow so 1 indicates a
; successful substraction (this is the
; next bit of quotient)
- jp C,.drop ; Jump if remainder is >= dividend
+ jr C,.drop ; Jump if remainder is >= dividend
pop hl ; Otherwise, restore remainder
- jp .nodrop
+ jr .nodrop
.drop:
inc sp
inc sp
; ld b,h ; B = high byte of quotient
or a ; Clear carry, valid result
ret
-
- .area _BSS
-
-.srem:
- .ds 0x01 ; Sign of quotient
-.squot:
- .ds 0x01 ; Sign of remainder
-.dcnt:
- .ds 0x01 ; Counter for division