I give you, teh codez.
Code: Select all
div_h_l: ;returns e = h/l
;c if error, nc if OK
;kills af, e, hl
;A/B (just names, will be used in comments)
ld a,l
or a
ccf
ret z ;return C if dividing by 0
ld a,h
cp l
jr nc,{+}
;divisor > dividend, return 0 but no error
xor a
ld e,a
ret
+: ;all normal, divide
ld h,1 ;index, that's a one, a bit hard to see in this font
;there is only 1 one in this code, namely this one.
;MSbit line-up
-: cp l ;that's an L
jr c,_shiftdone_goback
bit 7,l
jr nz,_shiftdone
;shift
add hl,hl ;L+L can never carry
jr {-}
_shiftdone_goback:
srl l
srl h
_shiftdone:
sub l
ld e,h ;result = 0 + index
ld d,a
-: ld a,h
or a
ret z
rra ;index >> 1
ld h,a
srl l ;B >> 1
;if A>=B
ld a,d
cp l
jr c,{-} ;A<B
sub l
ld d,a
ld a,e
add a,h
ld e,a
jr {-}
What I also know, is that for 128bit numbers, this way is on average 10 times as fast as the usual restoring division. Which says nothing about 8bit number but at least it has a chance.
Also, I'm kinda braindead at the moment (had a test today + it's half past midnight) so there may be terrible mistakes/bugs/inefficiencies..
Edit:
I also made a 16bit version.. well, I tried to. It doesn't really work..
Could someone have a look at it?
Code: Select all
div_hl_de: ;returns hl = hl / de
;c if error
ld a,d
or e
ccf
ret z
ld a,d
cp h
jr c,{+}
ld a,e
cp l
jr c,{+}
ld hl,0
ret
+: ;MSbit line-up
ld bc,1
-: ld a,h
cp d
jr c,_goback
ld a,l
cp e
jr c,_goback
bit 7,h
jr nz,_continue
sla c
rl b
sla e
rl d
jr {-}
_goback:
srl d
rr e
srl b
rr c
_continue:
or a
sbc hl,de
;hl = A
;de = B
;bc = index
push hl
ld h,b
ld l,c ;hl = result, stacktop = A
-: ld a,b
or c
jr nz,{+}
pop de
ret
+: srl d
rr e
srl b
rr c
ex (sp),hl ;I don't see this one a lot - maybe it's proof of how braindead I am..
;hl = A, stacktop = result
or a
sbc hl,de
jr c,_wassmaller
ex (sp),hl
add hl,bc
jr {-}
_wassmaller:
adc hl,de
ex (sp),hl
jr {-}