Full Version : 16-by-8 Divide with Fraction Remainder (PIC ASM)
avr >>PIC 8051 ZILOG ARM TI H8 ETC >>16-by-8 Divide with Fraction Remainder (PIC ASM)


Admin3- 04-18-2006
16 bits by 8 with result as fraction rather than remainder
from Nikolai Golovchenko

CODE
;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



Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.