by Lou Zher
;-[ Div ]-------------------------------------------------------------- ; call w/: Number in f_divhi:f_divlo ; Returns: Quotient in f_divlo, remainder in f_divhi. W preserved. ; Carry set if error. Z if divide by zero, NZ if divide overflow. ; Notes: Works by left shifted subtraction. ; Size = 29, Speed(w/ call&ret) = 9 cycles if div by zero ; Speed = 104 minimum, 142 maximum cycles ; Not compatible with the CARRYX option. Div or W, #0 ; w |= 0 (to test for div by zero) setb C ; set carry in case of error snb Z ; if zero ret ; return (error C,Z) call DivSkipHiShift call DivCode call DivCode call DivCode call DivCode call DivCode call DivCode call DivCode call DivCode rl f_divlo ; C << lo << C ; If the first subtract didn't underflow, and the carry was shifted ; into the quotient, then it will be shifted back off the end by this ; last RLF. This will automatically raise carry to indicate an error. ; The divide will be accurate to quotients of 9-bits, but past that ; the quotient and remainder will be bogus and carry will be set. clrb Z ; NZ (in case of overflow error) ret ; we are done! DivCode rl f_divlo ; C << lo << C rl f_divhi ; C << hi << C sb C ; if Carry jmp DivSkipHiShift ; sub f_divhi, W ; hi-=w setb C ; ignore carry ret ; done ; endif DivSkipHiShift sub f_divhi, W ; hi-=w snb C ; if carry set ret ; done add f_divhi, W ; hi+=w clrb C ; clear carry ret ; done
Comments: