Oh s**t, the table should have 17 entries! Or a roll-over... Corrected routine below. ---------------------------------------------------- I found some time to debug the log2 routine. It actually works! Error is very small, less than 0.05%. The whole x^y thing should take about 319*2+160 ~= 800 cycles and 105*2+20=220 words. Not so bad :) Nikolai ;************************************************ ; LOG2 routine for fixed point unsigned ; 16 bit values in 0.16 notation ; ; Input: xhi:xlo unsigned Q0.16 (modified) ; Output: x2hi:x2lo unsigned Q6.10 (implicit minus) ; Temporary: index, templo, temphi ; ; Maximum error: 0.05% ; ; Size: 105 words ; Time: min 2+1+7*1 -1+10+20*2+8+17+10*8-1+4+2=169 ; max 2+1+7*15-1+10+20*2+8+17+17*8-1+4+2=323 ; ; Note: Zero input is illegal! Will result in ; infinite loop. ; ; 28 Sep 2000 by Nikolai Golovchenko ;************************************************ log2 clrf x2hi log2loop clrc rlf xlo, f rlf xhi, f incf x2hi, f skpc goto log2loop ;x2hi contains approximated log (integer part + error) clrc ;normalize x2 rlf x2hi, f ;for 6.10 notation rlf x2hi, f ; clrf x2lo ;clear lower byte ;prepare the index, i.e. shift xh right 3 times (4 bit index ;shifted left once) rrf xhi, w movwf index rrf index, f rrf index, w andlw 0x1E movwf index call log2_table ;read the table entry to temphi:templo ;subtract it from current x2 movf templo, w subwf x2lo, f movf temphi, w skpc incfsz temphi, w subwf x2hi, f ;read next point incf index, f incf index, f call log2_table ;read the table entry to temphi:templo ;find the difference with the previous point movf x2lo, w addwf templo, f movf x2hi, w skpnc incf x2hi, w addwf temphi, w ;leave only two lsb's of temphi (difference is 10 bit long) andlw 0x03 movwf temphi ;now the difference is in temp ;multiply it by next 8 bits of the rotated x and divide by ;2^8=256 ;shift xhi:xlo left by 4 bits to get 8 bits of the multiplier ;in xh. (xlo is garbage) swapf xhi, w andlw 0xF0 movwf xhi swapf xlo, w andlw 0x0F iorwf xhi, f ;we will simultaneously multiply and subtract from x2 clrf xlo ;use xlo as a temp movlw 8 movwf index ;use index as a counter log2loop_mul rrf xhi, f ;shift next multiplier bit to carry bnc log2loop_mul2 ;skip if no carry movf templo, w ;subtract temp from x2hi:x2lo:xlo subwf xlo, f movf temphi, w skpc incfsz temphi, w subwf x2lo, f skpc decf x2hi, f log2loop_mul2 rrf x2hi, f ;x2hi becomes garbage, but we'll ;overwrite it rrf x2lo, f rrf xlo, f decfsz index, f goto log2loop_mul ;multiply x2 by 256 and overwrite x2hi to compensate 8 right ;rotations of x2 during the multiplication above movf x2lo, w movwf x2hi movf xlo, w movwf x2lo ;now x2 contains log2(x)! return log2_table movf index, w andlw 0x1F call log2tableStart movwf templo incf index, w andlw 0x1F call log2tableStart movwf temphi return log2tableStart addwf PCL, f DT 0 & 0xFF, 0 >> 8, 90 & 0xFF, 90 >> 8 DT 174 & 0xFF, 174 >> 8, 254 & 0xFF, 254 >> 8 DT 330 & 0xFF, 330 >> 8, 402 & 0xFF, 402 >> 8 DT 470 & 0xFF, 470 >> 8, 536 & 0xFF, 536 >> 8 DT 599 & 0xFF, 599 >> 8, 659 & 0xFF, 659 >> 8 DT 717 & 0xFF, 717 >> 8, 773 & 0xFF, 773 >> 8 DT 827 & 0xFF, 827 >> 8, 879 & 0xFF, 879 >> 8 DT 929 & 0xFF, 929 >> 8, 977 & 0xFF, 977 >> 8 IF (($ - 1) >> 8) - ((log2tableStart + 1) >> 8) != 0 error 'log2 table crossed 8-bit boundary' ENDIF ;************************************************ -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu