> juha tuomi wrote: > > > > Hi all ! > > Where could I get a 16 bit square root routine for PIC 17C43 ? > > > > Juha > > Check out: > > http://www.interstice.com/~sdattalo/technical/software/pic/picsqrt.html > > This was written for the midrange core, but it should work (or be > adaptable to the 16-bit core). Andy David has written a square root > routine specifically for the 17Cxx family. Maybe he'll post it? Or you > can try contacting him: > > "Andy David" ... and as if by magic, Andy David appeared. Sorry I haven't replied until now, I've been on holiday :-) Here's my 24-bit and 32-bit sqrt routines as written for the 17c43 taken from a mail I sent Scott just after I wrote them, hence the comments about the implementations I used. I've added a 16-bit square root routine (again for the 17c43) that uses successive approximation to find the square root, the binary restoring method I'm fairly sure would be quicker. This is the only 16-bit sqrt routine I have specifically for the 17cxx PICs, I've only included it as the original poster requested a 16-bit routine. If you really want speed speed speed, I'd rewrite the 32-bit routine to be 16-bit. Standard disclaimer applies to all 3 routines. ########################################################################## TWENTYFOUR bit sqrt. I did a few pencil-and-paper runs through the algorithm to be sure I understood the steps involved. This 24-bit resembles these 'manual' steps of shifting along the input string 2 bits at a time and subtracting - as the result is 12-bit, the final subtraction isn't awkward as in the 32-bit sqrt. I can't remember the performance figures for this routine, but I've just counted 348 min, 406 max (inc. call & return). A downside of this method is that the loop counter has to be a seperate variable, so it uses the same amount of ram as the 32-bit sqrt. This one is easier to follow and compare to an example on paper than the method I've used for the 32-bit sqrt. ;========================================================================== ; brSQRT24 ; ; Calculates the square root of a twentyfour bit number using the ; binary restoring method. ; ; Result in ACCaHI:ACCaLO ; Input in ACCcLO:ACCdHI:ACCdLO ; Test ACCbLO:ACCcHI ; Counter in ACCbHI ; ; 40 words long, uses 8 bytes RAM (inc. 3 holding 24-bit input). ; ;-------------------------------------------------------------------------- brSQRT24: clrf ACCaHI,f ; clrf ACCaLO,f ; clrf ACCcHI,f ; clrf ACCbLO,w ; movlw .12 ; movwf ACCbHI ; (6 cycle intro, 8 incl. call) ShftUp:rlcf ACCdLO,f ; Shift input up 2 places. rlcf ACCdHI,f ; (33 cycles per loop if bit is 0) rlcf ACCcLO,f ; (29 cycles per loop if bit is 1) rlcf ACCcHI,f ; rlcf ACCbLO,f ; rlcf ACCdLO,f ; rlcf ACCdHI,f ; rlcf ACCcLO,f ; rlcf ACCcHI,f ; rlcf ACCbLO,f ; rlcf ACCaLO,f ; Shift root-so-far up by two and append rlcf ACCaHI,f ; ... '01'. rlcf ACCaLO,f ; rlcf ACCaHI,f ; bcf ACCaLO,1 ; bsf ACCaLO,0 ; SubTest:movfp ACCaLO,WREG ; subwf ACCcHI,f ; movfp ACCaHI,WREG ; subwfb ACCbLO,f ; btfsc ALUSTA,C ; goto Set1 movfp ACCaLO,WREG ; Restore the remainder. addwf ACCcHI,f ; ... (the current bit is 0). movfp ACCaHI,WREG ; addwfc ACCbLO,f ; goto Set0 ; Set1: bsf ACCaLO,1 ; Set0: rrcf ACCaHI,f ; rrcf ACCaLO,f ; bcf ACCaHI,7 ; BitLoop:decfsz ACCbHI,f ; goto ShftUp return ########################################################################## THIRTYTWO bit sqrt. Looks a lot like Scott's original 16-bit sqrt. As the root is going to be a 16 bit number the last subtract is awkward, so the 24-bit sqrt method wasn't appropriate. I did actually write this myself rather than automatically converting Scott's code to 32 bit. I DID, however, consciously and unashamedly steal two parts - how to carry out the final 17-bit subtraction and how to count iterations - the extra 'counting' bit in the mask was quite a devious idea. This one took a little longer to write than the 24-bit, probably because it needs to iterate more times... ;========================================================================= ; brSQRT32 ; ; Calculates the square root of a thirtytwo bit number using the ; binary restoring method. ; ; Result in ACCaHI:ACCaLO ; Mask in ACCbHI:ACCbLO ; Input in ACCcHI:ACCcLO:ACCdHI:ACCdLO ; ; Takes between 392 and 439 cycles (incl. call and return). ; Uses 58 words ROM, 8 bytes RAM including 4 holding the input. ; ;------------------------------------------------------------------------- brSQRT32: movlw 0x40 ; Initial value for Result is... movwf ACCaHI ; ... 01000000 00000000 clrf ACCaLO,f ; movlw 0xC0 ; Initial value for mask is... movwf ACCbHI ; ... 11000000 00000000 clrf ACCbLO,f ; (second '1' is loop counter). Sub_Cmp:movfp ACCaLO,WREG ; Compare root-so-far with current subwf ACCcLO,f ; ... remainder. movfp ACCaHI,WREG ; subwfb ACCcHI,f ; btfss ALUSTA,C ; goto brstr ; (result is -ve, need to restore). In1: movfp ACCbLO,WREG ; set the current bit in the result. iorwf ACCaLO,f ; movfp ACCbHI,WREG ; iorwf ACCaHI,f ; ShftUp:rlcf ACCdLO,f ; rlcf ACCdHI,f ; rlcf ACCcLO,f ; rlcf ACCcHI,f ; rrcf ACCbHI,f ; Shift mask right for next bit, whilst rrcf ACCbLO,f ; ... shifting IN MSB from remainder. btfsc ACCbHI,7 ; If MSB is set, unconditionally set the goto USet1 ; ... next bit. movfp ACCbLO,WREG ; Append '01' to root-so-far xorwf ACCaLO,f ; movfp ACCbHI,WREG ; xorwf ACCaHI,f ; btfss ALUSTA,C ; If second '1' in mask is shifted out, goto Sub_Cmp ; ... then that was the last normal iteration. movfp ACCaLO,WREG ; Last bit Generation. subwf ACCcLO,f ; ... The final subtract is 17-bit (15-bit root movfp ACCaHI,WREG ; ... plus '01'). Subtract 16-bits: if result subwfb ACCcHI,f ; ... generates a carry, last bit is 0. btfss ALUSTA,C ; return movlw 1 ; If result is 0 AND msb of is '0', result bit btfsc ALUSTA,Z ; ... is 0, otherwise '1'. btfsc ACCdHI,7 ; xorwf ACCaLO,f ; return USet1: btfsc ALUSTA,C ; If mask has shifted out, leave. final bit return ; ... has been set by iorwf at in1. bcf ACCbHI,7 ; clear bit shifted in from input. movfp ACCbLO,WREG ; Append '01' to root-so-far xorwf ACCaLO,f ; movfp ACCbHI,WREG ; xorwf ACCaHI,f ; movfp ACCaLO,WREG ; This subtraction is guaranteed not to subwf ACCcLO,f ; ... cause a borrow, so subtract and movfp ACCaHI,WREG ; ... jump back to insert a '1' in the subwfb ACCcHI,f ; ... root. goto In1 ; brstr: movfp ACCaLO,WREG ; A subtract above at Sub_Cmp was -ve, so addwf ACCcLO,f ; ... restore the remainder by adding. movfp ACCaHI,WREG ; The current bit of the root is zero. addwfc ACCcHI,f ; goto ShftUp ; ########################################################################## ;========================================================================== ; SQRT16 ; ; Calculates the square root of a sixteen bit number by successive ; approximation. ; ; ; Input in ACCaHI:ACCaLO ; ; Output in ACCbHI ; ; Also uses ACCbLO and ACCcHI. ; ;-------------------------------------------------------------------------- SQRT16: movlw 0x80 ; movpf WREG,ACCbLO ; set up walking tester bit. clrf ACCbHI,w ; movlw 0x08 ; movpf WREG,ACCcHI ; tstest:movfp ACCbLO,WREG ; set bit for testing. iorwf ACCbHI,WREG ; movpf WREG,ACCbHI ; mulwf ACCbHI ; square the current estimate. movfp ACCaLO,WREG ; compare PRODH:PRODL with ACCaHI:ACCaLO subwf PRODL,WREG ; movfp ACCaHI,WREG ; subwfb PRODH,WREG ; btfss ALUSTA,C ; If the result is <= input, goto nxtbit ; ... keep this bit set. movfp ACCbLO,WREG ; Result was > input, so reset xorwf ACCbHI,f ; ... bit to zero. nxtbit:rrncf ACCbLO,f ; rotate tester bit right. decfsz ACCcHI,f ; goto tstest ; return - Andy. ---------------------------------------------------------- Andrew David, Software Manager, Ultronics Ltd, Cheltenham. akdavid@Ultronics.co.uk http:\\www.ultronics.com ----------------------------------------------------------