ON 20041205@5:30:37 PM at page: http://www.piclist.org/techref/microchip/math/div/24by16.htm#38326.7295949074 Nikolai Golovchenko [NG--944] Code:
Well, the routine can be made even simpler! This version is 5 instructions shorter and 48 cycles faster. Thanks to <a href="mailto:zpetkov at developer.bg">Zlatko Petkov</a> for an idea of removing the extra shifts after the loop. Nikolai Golovchenko. 5-Dec-2004.
FXD2416U:
CLRF REMB0
CLRF REMB1
MOVLW .24
MOVWF LOOPCOUNT
LOOPU2416
RLF AARGB2, W ;shift dividend left to move next bit to remainder
RLF AARGB1, F ;
RLF AARGB0, F ;
RLF REMB1, F ;shift carry (next dividend bit) into remainder
RLF REMB0, F
RLF AARGB2, F ;finish shifting the dividend and save carry in AARGB2.0,
;since remainder can be 17 bit long in some cases
;(e.g. 0x800000/0xFFFF). This bit will also serve
;as the next result bit.
MOVF BARGB1, W ;substract divisor from 16-bit remainder
SUBWF REMB1, F ;
MOVF BARGB0, W ;
BTFSS STATUS, C ;
INCFSZ BARGB0, W ;
SUBWF REMB0, F ;
;here we also need to take into account the 17th bit of remainder, which
;is in AARGB2.0. If we don't have a borrow after subtracting from lower
;16 bits of remainder, then there is no borrow regardless of 17th bit
;value. But, if we have the borrow, then that will depend on 17th bit
;value. If it is 1, then no final borrow will occur. If it is 0, borrow
;will occur. These values match the borrow flag polarity.
SKPNC ;if no borrow after 16 bit subtraction
BSF AARGB2, 0 ;then there is no borrow in result. Overwrite
;AARGB2.0 with 1 to indicate no
;borrow.
;if borrow did occur, AARGB2.0 already
;holds the final borrow value (0-borrow,
;1-no borrow)
BTFSC AARGB2, 0 ;if no borrow after 17-bit subtraction
GOTO UOK46LL ;skip remainder restoration.
ADDWF REMB0, F ;restore higher byte of remainder. (w
;contains the value subtracted from it
;previously)
MOVF BARGB1, W ;restore lower byte of remainder
ADDWF REMB1, F ;
UOK46LL
DECFSZ LOOPCOUNT, f ;decrement counter
GOTO LOOPU2416 ;and repeat the loop if not zero.
RETURN
ON 20041205@11:16:36 PM at page:
http://www.piclist.org/techref/microchip/math/div/24by16.htm#38326.7283449074
James Newton[JMN-EFP-786] removed post 38326.7283449074
|Delete '
Well, the routine can be made even simpler! This version is 5 instructions shorter and 48 cycles faster. Thanks to <a href="mailto:zpetkov at developer.bg">Zlatko Petkov</a> for an idea of removing the extra shifts after the loop. Nikolai Golovchenko. 5-Dec-2004.
FXD2416U:
CLRF REMB0
CLRF REMB1
MOVLW .24
MOVWF LOOPCOUNT
LOOPU2416
RLF AARGB2, W ;shift dividend left to move next bit to remainder
RLF AARGB1, F ;
RLF AARGB0, F ;
RLF REMB1, F ;shift carry (next dividend bit) into remainder
RLF REMB0, F
RLF AARGB2, F ;finish shifting the dividend and save carry in AARGB2.0,
;since remainder can be 17 bit long in some cases
;(e.g. 0x800000/0xFFFF). This bit will also serve
;as the next result bit.
MOVF BARGB1, W ;substract divisor from 16-bit remainder
SUBWF REMB1, F ;
MOVF BARGB0, W ;
BTFSS STATUS, C ;
INCFSZ BARGB0, W ;
SUBWF REMB0, F ;
;here we also need to take into account the 17th bit of remainder, which
;is in AARGB2.0. If we don't have a borrow after subtracting from lower
;16 bits of remainder, then there is no borrow regardless of 17th bit
;value. But, if we have the borrow, then that will depend on 17th bit
;value. If it is 1, then no final borrow will occur. If it is 0, borrow
;will occur. These values match the borrow flag polarity.
SKPNC ;if no borrow after 16 bit subtraction
BSF AARGB2, 0 ;then there is no borrow in result. Overwrite
;AARGB2.0 with 1 to indicate no
;borrow.
;if borrow did occur, AARGB2.0 already
;holds the final borrow value (0-borrow,
;1-no borrow)
BTFSC AARGB2, 0 ;if no borrow after 17-bit subtraction
GOTO UOK46LL ;skip remainder restoration.
ADDWF REMB0, F ;restore higher byte of remainder. (w
;contains the value subtracted from it
;previously)
MOVF BARGB1, W ;restore lower byte of remainder
ADDWF REMB1, F ;
UOK46LL
DECFSZ LOOPCOUNT, f ;decrement counter
GOTO LOOPU2416 ;and repeat the loop if not zero.
RETURN