;-[ Div ]-------------------------------------------------------------- ; Call w/: Number in f_divhi:f_divlo, divisor in W. ; 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) = 7 cycles if div by zero ; Speed = 94 minimum, 129 maximum cycles Div iorlw 0 ; w |= 0 (to test for div by zero) setc ; set carry in case of error skpnz ; if zero return ; return (error C,Z) call DivSkipHiShift call DivCode call DivCode call DivCode call DivCode call DivCode call DivCode call DivCode rlf f_divlo, f ; 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. clrz ; NZ (in case of overflow error) return ; we are done! DivCode rlf f_divlo, f ; C << lo << C rlf f_divhi, f ; C << hi << C skpc ; if Carry goto DivSkipHiShift ; subwf f_divhi, f ; hi-=w setc ; ignore carry return ; done ; endif DivSkipHiShift subwf f_divhi, f ; hi-=w skpnc ; if carry set return ; done addwf f_divhi, f ; hi+=w clrc ; clear carry return ; done
Questions: