pop bc
ret
-div_hl_de:
- push bc
-divu: ld a,h
- ld c,l
- ld hl,0
- call div0
- ld b,a
- ld a,c
- ld c,b
- call div
- jr nc,1$
- add hl,de
-1$: ld d,c
- ld e,a
- pop bc
- ret
-
div_hl_de_signed:
push bc
ld a,h
or a
ld a,d
rla
- jr c,4$ ; negative divisor
+ jp p,4$ ; positive dividend
- ; positive divisor
- jp p,divu ; positive dividend, positive divisor
-
- ; negative dividend, positive divisor
+ ; negative dividend
dec hl ; reduces remainder by 1 (we inc later)
ld a,h
ld c,l
ld hl,-1
+ jr c,2$ ; negative dividend, negative divisor
+
+ ; negative dividend, positive divisor
call div1
ld b,a
ld a,c
pop bc
ret
-2$: ; positive dividend, negative divisor
+2$: ; negative dividend, negative divisor
+ call divn0
+ ld b,a
+ ld a,c
+ ld c,b
+ call divn
+ jr nc,3$
+ add hl,de
+3$: inc hl ; get into range divisor+1..0
+ ld d,c
+ ld e,a
+ pop bc
+ ret
+
+4$: ; positive dividend
ld a,h
ld c,l
ld hl,0
+ jr nc,divu ; positive dividend, positive divisor
+
+ ; positive dividend, negative divisor
call divn1
ld b,a
ld a,c
ld c,b
call divn
inc a
- jr c,3$
+ jr c,5$
sbc hl,de
-3$: ld d,c
+5$: ld d,c
ld e,a
pop bc
ret
-4$: ; negative divisor
- jp p,2$
-
- ; negative dividend, negative divisor
- dec hl ; reduces remainder by 1 (we inc later)
+div_hl_de:
+ push bc
ld a,h
ld c,l
- ld hl,-1
- call divn0
+ ld hl,0
+
+divu: ; positive dividend, positive divisor
+ call div0
ld b,a
ld a,c
ld c,b
- call divn
- jr nc,5$
+ call div
+ jr nc,1$
add hl,de
-5$: inc hl ; get into range divisor+1..0
- ld d,c
+1$: ld d,c
ld e,a
pop bc
ret
; now optimized to only inc/dec a when doing zero-crossing, fix above analysis
div: jr c,div1
-div0:
- ;push af
- ;ld a,'A
- ;call print_char
- ;pop af
- ;call print_word
- ;push af
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,'/
- ;call print_char
- ;pop af
- ;ex de,hl
- ;call print_word
- ;ex de,hl
- ld b,8
+div0: ld b,8
scf
rla
div00: adc hl,hl
djnz div00
dec a
or a
- ;push af
- ;ld a,'B
- ;call print_char
- ;pop af
- ;push af
- ;ld a,'0
- ;adc a,0
- ;call print_char
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,',
- ;call print_char
- ;pop af
- ;call print_word
- ;call print_crlf
ret
div1: ; enter with cf=0
- ;push af
- ;ld a,'C
- ;call print_char
- ;pop af
- ;call print_word
- ;push af
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,'/
- ;call print_char
- ;pop af
- ;ex de,hl
- ;call print_word
- ;ex de,hl
ld b,8
add a,a
div10: adc hl,hl
;inc a
;dec a ; compensation
scf
- ;push af
- ;ld a,'D
- ;call print_char
- ;pop af
- ;push af
- ;ld a,'0
- ;adc a,0
- ;call print_char
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,',
- ;call print_char
- ;pop af
- ;call print_word
- ;call print_crlf
ret
-; divn0/3 are the same as div0/1 but carry reversed after add/subtract divisor
+; divn0/1 are the same as div0/1 but carry reversed after add/subtract divisor
+; this is for negative divisors where we expect carry (means no zero crossing)
+
+; when divisor negated, remainder also negated, so we expect to do subtraction
+; when remainder negative and vice versa, need to clear carry after add hl,hl
divn: jr c,divn1
-divn0:
- ;push af
- ;ld a,'A
- ;call print_char
- ;pop af
- ;call print_word
- ;push af
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,'/
- ;call print_char
- ;pop af
- ;ex de,hl
- ;call print_word
- ;ex de,hl
- ld b,8
+divn0: ld b,8
scf
rla
divn00: adc hl,hl
djnz divn00
dec a
or a
- ;push af
- ;ld a,'B
- ;call print_char
- ;pop af
- ;push af
- ;ld a,'0
- ;adc a,0
- ;call print_char
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,',
- ;call print_char
- ;pop af
- ;call print_word
- ;call print_crlf
ret
-divn1:
- ;push af
- ;ld a,'C
- ;call print_char
- ;pop af
- ;call print_word
- ;push af
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,'/
- ;call print_char
- ;pop af
- ;ex de,hl
- ;call print_word
- ;ex de,hl
- ld b,8
+divn1: ld b,8
add a,a
divn10: adc hl,hl
add hl,de
;inc a
;dec a ; compensation
scf
- ;push af
- ;ld a,'D
- ;call print_char
- ;pop af
- ;push af
- ;ld a,'0
- ;adc a,0
- ;call print_char
- ;ld a,':
- ;call print_char
- ;pop af
- ;call print_byte
- ;push af
- ;ld a,',
- ;call print_char
- ;pop af
- ;call print_word
- ;call print_crlf
ret