>Hi all ! >Where could I get a 16 bit square root routine for PIC 17C43 ? > >Juha The following is a C version to provide a 16-bit input with 8-bits of output. This uses perfect rounding. It is not difficult to expand this to provide more bits of output, ie. fixed point results. unsigned byte Sqrt16(unsigned int X) { unsigned int Test = 0xFF00; unsigned int Bit = 0x8000; if (X == 0) return 0; X = X - 1; do { Test = (Test ^ Bit) >> 1; if (X >= Test) { X -= Test; Test |= Bit; } } while ((Bit >>= 2) != 0); return (unsigned byte)(Test >> 1); } Convertion to PIC assembly language is not difficult. The following is this same code for the 14-bit midrange PIC code. I have never tried to write it for the 16-bit versions. ; Routine : Sqrt16 ; Purpose : Takes a squareroot of a 16-bit number, result is an 8-bit ; number. Rounds results, inputs between (n*(n+1)) ; and (n*(n-1))-1 are returned as n. The algorithm is a ; optimized binary search algorithm, creating the results a ; bit per loop. ; Inputs : Acc -- word accumulater. 16-bit input. ; Returns : w -- results of the square root, rounded. ; Acc -- value in here is trashed. ; Globals : sqrt_tst -- temp word variable. ; sqrt_bit -- temp word variable. ; Timing : 219 to 227 cycles including short call and return. Sqrt16 movf Acc+1,w iorwf Acc,w skpnz retlw 0x00 ; exit if 0. ; decrease input by 1 step, to change compare direction. incf Acc+1,f decfsz Acc,f decf Acc+1,f ; set up bit value and partial for testing. clrf sqrt_bit ; clear bit pattern, want 0x8000 clrf sqrt_bit+1 ; high byte, first clear. bsf sqrt_bit+1,7 ; set the highest bit. clrf sqrt_tst movlw high ((256*255)) ; sqrt_tst == 0xFF00 movwf sqrt_tst+1 ; loop, we do this until all bits are shifted out of sqrt_bit. ; This is done a total of 8 loops. clrc ; clear carry Sqrt16_loop ; set test value to (test - bit) / 2, can use XOR to subtract. movf sqrt_bit,w ; start with low byte. xorwf sqrt_tst,f movf sqrt_bit+1,w ; high byte, deal with borrow. xorwf sqrt_tst+1,f ; do /2 rrf sqrt_tst+1,f rrf sqrt_tst,f ; check if accumulator is greater than test value. movf sqrt_tst,w subwf Acc,f movf sqrt_tst+1,w skpc ; skip if not borrow. incfsz sqrt_tst+1,w subwf Acc+1,f ; carry set if borrow bc Sqrt16_c ; branch if no borrow Sqrt16_a ; on borrow we want to undo the subtract. Undo high byte. addwf Acc+1,f ; reverse high byte. movf sqrt_tst,w ; get low byte. addwf Acc,f ; all undone, can ignore carry. ; test value is left unchanged, clear carry for later code. clrc goto Sqrt16_d ; down to end of loop test. Sqrt16_c ; set test to test + bit, can use OR instead. movf sqrt_bit,w addwf sqrt_tst,f ; carry is not possible movf sqrt_bit+1,w ; using ADD to clear carry. addwf sqrt_tst+1,f ; carry is not possible here. Sqrt16_d ; shift bit pattern down by 2 bits, carry is already clear. rrf sqrt_bit+1,f ; shift down by 2. rrf sqrt_bit,f ; first bit out always is 0. rrf sqrt_bit+1,f ; shift down by 2 again. rrf sqrt_bit,f ; if carry out if this bit then done. bnc Sqrt16_loop ; loop until done. ; return results, test value / 2. rrf sqrt_tst+1,w rrf sqrt_tst,w ; results are in w, return them. return