Code:
ASM
ifdef DIVS_USED
LIST
#DIVS
clrf R3 + 3 ; Clear sign difference indicator
btfss R0 + 3, 7 ; Check for R0 negative
bra #divchkr1 ; Not negative
btg R3 + 3, 7 ; Flip sign indicator
clrf WREG ; Clear W for subtracts
negf R0 ; Flip value to plus
subfwb R0 + 1, F
subfwb R0 + 2, F
subfwb R0 + 3, F
#divchkr1
btfss R1 + 3, 7 ; Check for R1 negative
bra #divdo ; Not negative
btg R3 + 3, 7 ; Flip sign indicator
clrf WREG ; Clear W for subtracts
negf R1 ; Flip value to plus
subfwb R1 + 1, F
subfwb R1 + 2, F
subfwb R1 + 3, F
bra #divdo ; Skip unsigned entry
NOLIST
DIV_USED = 1
endif
ifdef DIV_USED
LIST
#DIV
ifdef DIVS_USED
clrf R3 + 3 ; Clear sign difference indicator
endif
#divdo
clrf R2 ; Do the divide
clrf R2 + 1
clrf R2 + 2
clrf R2 + 3
movlw 32
movwf R3
;added to speed up s-31 divide op's by ignoring zero'd bytes
ifdef SKI_DIV_OPT
if ( SKI_DIV_OPT == 1 | SKI_DIV_OPT == 3 )
SkiOpt
movf R0, W ; IF R0(0)= 0
bnz #divloop
movf R1, W ; AND R1(0)= 0 then
bnz #divloop
movff R0 + 1, R0 + 0 ; and preshift R0
movff R0 + 2, R0 + 1
movff R0 + 3, R0 + 2
clrf R0 + 3
movff R1 + 1, R1 + 0 ; and R1 over 8 bits
movff R1 + 2, R1 + 1
movff R1 + 3, R1 + 2
clrf R1 + 3
movlw 8 ; loops - 8
subwf R3, F
btfss STATUS, Z ; stop if no loop's left (0/0)
bra SkiOpt
endif
endif
;added to speed up s-31 divides by skipping clr'd bits in divisor/dividend lsb
ifdef SKI_DIV_OPT
if ( SKI_DIV_OPT == 2 | SKI_DIV_OPT == 3 )
SkiOpt2
btfsc R0, 0 ; if lowest bit set, goto divloop
bra #divloop
btfsc R1, 0 ; if lowest bit set, goto divloop
bra #divloop
bcf STATUS, C ;clr carry-shift over complete R0
rrcf R0 + 3, F ;shift R0+3, .0 into carry
rrcf R0 + 2, F ;shift R0+2
rrcf R0 + 1, F ;shift R0+1
rrcf R0 + 0, F ;shift R0+0
bcf STATUS, C ;clr carry-shift over complete R1
rrcf R1 + 3, F ;shift R1, .0 into carry
rrcf R1 + 2, F ;shift R1+2
rrcf R1 + 1, F ;shift R1+1
rrcf R1 + 0, F ;shift R1+0
movlw 1 ;subtract one from the loop count
subwf R3, F
btfss STATUS, Z ;stop if no more loops
bra SkiOpt2
endif
endif
;above added to speed divide operations
#divloop
rlcf R0 + 3, W ;NOTE 1
rlcf R2, F
rlcf R2 + 1, F
rlcf R2 + 2, F
rlcf R2 + 3, F
movf R1, W
subwf R2, F
movf R1 + 1, W
subwfb R2 + 1, F
movf R1 + 2, W
subwfb R2 + 2, F
movf R1 + 3, W
subwfb R2 + 3, F
bc #divok
movf R1, W
addwf R2, F
movf R1 + 1, W
addwfc R2 + 1, F
movf R1 + 2, W
addwfc R2 + 2, F
movf R1 + 3, W
addwfc R2 + 3, F
bcf STATUS, C
#divok
rlcf R0, F
rlcf R0 + 1, F
rlcf R0 + 2, F
rlcf R0 + 3, F
decfsz R3, F
bra #divloop
ifdef DIVS_USED
btfss R3 + 3, 7 ; Should result be negative?
bra #divdone ; Not negative
clrf WREG ; Clear W for subtracts
negf R0 ; Flip quotient to minus
subfwb R0 + 1, F
subfwb R0 + 2, F
subfwb R0 + 3, F
negf R2 ; Flip remainder to minus
subfwb R2 + 1, F
subfwb R2 + 2, F
subfwb R2 + 3, F
#divdone
endif
movf R0, W ; Get low byte to W
goto DUNN
NOLIST
DUNN_USED = 1
endif
ENDASM
Any other swell ideas? I've got another idea, but not sure how to implement it...
Bookmarks