Code:
ASM
Sqrt tstfsz ARGA3,0 ; determine if the number is 16-bit
bra Sqrt32 ; or 32-bit and call the best function
tstfsz ARGA2, 0
bra Sqrt32
clrf RES1, 0
bra Sqrt16
Sqrt16 clrf TEMP0, 0 ; clear the temp solution
movlw 0x80 ; setup the first bit
movwf BITLOC0, 0
movwf RES0, 0
Square8 movf RES0, W, 0 ; square the guess
mulwf RES0, 0
movf PRODL, W, 0 ; ARGA - PROD test
subwf ARGA0, W, 0
movf PRODH, W, 0
subwfb ARGA1, W, 0
btfsc STATUS, C, 0
bra NextBit ; if positive then next bit
; if negative then rotate right
movff TEMP0, RES0 ; move last good value back into RES0
rrncf BITLOC0, F, 0 ; then rotote the bit and put it
movf BITLOC0, W, 0 ; back into RES0
iorwf RES0, F, 0
btfsc BITLOC0, 7, 0; if last value was tested then get
bra Done ; out
bra Square8 ; elso go back for another test
NextBit movff RES0, TEMP0 ; copy the last good approximation
rrncf BITLOC0, F, 0 ; rotate the bit location register
movf BITLOC0, W, 0
iorwf RES0, F, 0
btfsc BITLOC0, 7, 0 ; if last value was tested then get
bra Done ; out
bra Square8
Done movff TEMP0,RES0 ; put the final result in RES0
bra TotallyDone
Sqrt32 clrf TEMP0, 0 ; clear the temp solution
clrf TEMP1,
clrf BITLOC0, 0 ; setup the first bit
clrf RES0, 0
movlw 0x80
movwf BITLOC1, 0 ; BitLoc = 0x8000
movwf RES1, 0 ; RES = 0x8000
Squar16 movff RES0, ARG1L ; square the guess
movff RES1, ARG1H
call Sq16
movf SQRES0, W, 0 ; ARGA - PROD test
subwf ARGA0, W, 0
movf SQRES1, W, 0
subwfb ARGA1, W, 0
movf SQRES2, W, 0
subwfb ARGA2, W, 0
movf SQRES3, W, 0
subwfb ARGA3, W, 0
btfsc STATUS, C, 0
bra NxtBt16 ; if positive then next bit
; if negative then rotate right
addlw 0x00 ; clear carry
movff TEMP0, RES0 ; move last good value back into RES0
movff TEMP1, RES1
rrcf BITLOC1, F, 0 ; then rotote the bit and put it
rrcf BITLOC0, F, 0
movf BITLOC1, W, 0 ; back into RES1:RES0
iorwf RES1, F, 0
movf BITLOC0, W, 0
iorwf RES0, F, 0
btfsc STATUS, C, 0 ; if last value was tested then get
bra Done32 ; out
bra Squar16 ; elso go back for another test
NxtBt16 addlw 0x00 ; clear carry
movff RES0, TEMP0 ; copy the last good approximation
movff RES1, TEMP1
rrcf BITLOC1, F, 0 ; rotate the bit location register
rrcf BITLOC0, F, 0
movf BITLOC1, W, 0 ; and put back into RES1:RES0
iorwf RES1, F, 0
movf BITLOC0, W, 0
iorwf RES0, F, 0
btfsc STATUS, C, 0 ; if last value was tested then get
bra Done32 ; out
bra Squar16
Done32 movff TEMP0,RES0 ; put the final result in RES1:RES0
movff TEMP1,RES1
bra TotallyDone
Sq16 movf ARG1L, W, 0
mulwf ARG1L ; ARG1L * ARG2L ->
; PRODH:PRODL
movff PRODH, SQRES1 ;
movff PRODL, SQRES0 ;
movf ARG1H, W, 0
mulwf ARG1H ; ARG1H * ARG2H ->
; PRODH:PRODL
movff PRODH, SQRES3 ;
movff PRODL, SQRES2 ;
movf ARG1L, W, 0
mulwf ARG1H ; ARG1L * ARG2H ->
; PRODH:PRODL
movf PRODL, W, 0 ;
addwf SQRES1, F, 0 ; Add cross
movf PRODH, W, 0 ; products
addwfc SQRES2, F, 0 ;
clrf WREG, 0 ;
addwfc SQRES3, F, 0 ;
movf ARG1H, W, 0 ;
mulwf ARG1L ; ARG1H * ARG2L ->
; PRODH:PRODL
movf PRODL, W, 0 ;
addwf SQRES1, F, 0 ; Add cross
movf PRODH, W, 0 ; products
addwfc SQRES2, F, 0 ;
clrf WREG, W ;
addwfc SQRES3, F, 0 ;
return
TotallyDone
ENDASM
Bookmarks