Hi Scott and Ashley, nice initiative and somewhat challenging :) *gee* probably to much free time today. Anyway I concluded by reading the original post the same result as Scott did, there were ways one could skip the table and make some parts shorter. However one thing was still bugging me, the double 4 bits shifts, I felt that these should not be needed. Wrapping my head around what exactely was happening ( I never have dealt with CRC or feedback registers before ) made me realise something, kind of an 'aha' experience, so without further ramblings here goes an *really breifly* commented version ( for challenge ). It works with the test vector but don't take it for granted that it's fully operational :) ( although I think so ). It does not save much in regards to Scotts version (unrolled), but I guess it is atleast a few cycles shorther. Ofcource I'll post an more commented version if there is anyone who actually is interested, The snippet is really migrane inducing :) and not for the faint hearted. I needed three temps, and used the 'available' in the original snippet. Executes in around 36 instr./byte, no additional stack or tables are needed (including call/return). But it wouldn't surprise me if Scott,Nikolai or Bob presents an 10 cycle version :) *hint* hint* ;******************************************************************** ; ; CRC_Update: Calculates the CCITT CRC16 checksum for the byte in W ; Updates: CRC16_High and CRC16_Low ; Uses: W,Index,Temp and CRC16_MessageByte ; Executes in around 36 cycles/call/byte (including call/return) ; Remember to initialize CRC16 to 0xFFFF before crc of the message ; Test vector: "123456789" all ASCII without brackets generates 0x29B1 ; CRC_Update: ; calculate xor for the input byte with crc-high register XORWF CRC16_High,W MOVWF Temp ; save ;MOVWF Index SWAPF Temp,W ; swap nibbles to do additional xor with low nibble ANDLW 0x0F XORWF Temp,F ; relating to original crc routine be Ashley temp now contains ; *both* the first table and second table index ( top nibble first index, low nibble second index ) ; referred to as i and i2 ; an observation of the original routine reveals that the crc is rotated 8 bits in total ; for one byte input, hence what once was crc-low becomes crc-high. ; writing down the formula gives that the top nibble of the output crc-high is: ; CRC_High:h = CRC_Low:h XOR TableHigh:l[i] XOR TableHigh:h[i2] ; and for the low nibble ; CRC_High:l = CRC_Low:l XOR TableLow:h[i] XOR TableHigh:l[i2] ; now by using the fact that the tables can be calculated instead ; we will have the following *nibble* tables: ; TableHigh:l = [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1] ; TableHigh:h = [0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F] ; TableLow:l = [0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F] ; TableLow:h = [0,2,4,6,8,A,C,E,0,2,4,6,8,A,C,E] ; these will be hanled one by one below: ; note: remember thet temp holds both i and i2 at entry ; we start by calculating the table entry for the TableLow:h RLF Temp,W ANDLW 0xF0 MOVWF Index SWAPF Index,F SWAPF Temp,W ANDLW 0xF0 IORWF Index,F ; w:h = TableHigh:h[i2], w:l= TableLow:h[i] MOVLW 0x00 ; prepare to do xor with TableHigh:l[i] *and* TableHigh:l[i2] ; for both nibbles at the same time BTFSC Temp,7 IORLW 0x10 ; if i >= 8 do XOR with 1 ( high nibble ) BTFSC Temp,0 IORLW 0x01 ; if i2 >= 8 do xor with 1 ( low nibble ) XORWF Index,W ; w:h = TableHigh:l[i] XOR TableHigh:h[i2] ; w:l = TableLow:h[i] XOR TableHigh:l[i2] XORWF CRC16_Low,W ; finnally done with high(output) byte crc MOVWF CRC16_High ; save as high byte of crc ; further observations can conclude that crc-low will have the following ; content at exit: ; CRC_Low:h = TableLow:l[i] XOR TableLow:h[i2] ; and ; CRC_Low:l = TableLow:l[i2] ; note: remember thet temp holds both i and i2 at entry ; first we calculate TableLow:h[i2] MOVF Temp,W ADDWF Temp,W ANDLW 0x0F ; w = TableLow:h[i2] MOVWF CRC16_MessageByte MOVLW 0x0F ANDWF Temp,W ; w:l = i2 ( = TableLow:l[i2] ) SWAPF CRC16_MessageByte,F IORWF CRC16_MessageByte,F MOVF Temp,W ANDLW 0xF0 ; w = i ( = TableLow:l[i] ) XORWF CRC16_MessageByte,W MOVWF CRC16_Low ; done with low output byte RETLW 0 ; return Finished -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.