PIC Microcontoller Math Method

16 bits by 8 with result as fraction rather than remainder

from Nikolai Golovchenko

;Division of 16bit by 8 bit with a result in Q16.16 form
;
; X_Int.X_Frac = X_Int / Y
;
; RAM - 6 bytes (1 temp):
; X_Int = X_IntH:X_IntL         16 bit input/ output integer part
; X_Frac = X_FracH:X_FracL      16 bit output fractional part
; Y                             divisor / temporary
; Counter                       counter
;
; Size = 39 instructions
; Execution time = 6+16*14-1+3+16*14-1+3+2(return)
; = 460 instruction cycles
;
; 8-July-2000 by Nikolai Golovchenko
; 16-February-2001 fixed, reduced execution time and temporaries

Div16by8to16_16

        clrf X_FracL
        clrf X_FracH
        movlw 16
        movwf Counter
        movf Y, w       ;keep Y value in accumulator
        clrf Y          ;and use Y register as temporary

;Find integer part
Div16by8to16_16a

        rlf X_IntL, f   ;shift next msb into temporary
        rlf X_IntH, f
        rlf Y, f
        rlf Counter, f  ;carry has 9th bit of temporary
                        ;copy carry to counter

        subwf Y, f      ;substract Y (in w) from temporary

        skpnc           ;if no borrow, set Counter.0
         bsf Counter, 0

        btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary
         addwf Y, f

        clrc            ;restore counter
        rrf Counter, f

;at this point carry is the next bit of result
        decfsz Counter, f ;repeat 16 times to find integer part
         goto Div16by8to16_16a

                        ;shift last integer bit
        rlf X_IntL, f
        rlf X_IntH, f

;Find fractional part
        bsf Counter, 4  ;Counter = 16
Div16by8to16_16b
                        ;Shift zero bit into temporary
        rlf X_FracL, f
        rlf X_FracH, f
        rlf Y, f
        rlf Counter, f  ;carry has 9th bit of temporary
                        ;copy carry to counter

        subwf Y, f      ;substract Y(in w) from temporary

        skpnc           ;if no borrow, set Counter.0
         bsf Counter, 0

        btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary
         addwf Y, f

        clrc            ;restore counter
        rrf Counter, f

        decfsz Counter, f ;repeat 16 times
         goto Div16by8to16_16b
                        ;shift last fractional bit
        rlf X_FracL, f
        rlf X_FracH, f

        movwf Y         ;restore divisor
        return

Questions: