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
  • ' ON 20041205@11:19:47 PM at page: http://www.piclist.org/techref/microchip/math/div/24by16.htm# James Newton[JMN-EFP-786] edited the page. Difference: http://www.piclist.org/techref/diff.asp?url=H:\techref\microchip\math\div\24by16.htm&version=7