Hi, On Wed, 22 Jan 2003, Scott Dattalo wrote: >Continuing with the previous post... > >Here's a fairly optimized CRC-32 implementation suitable for a 32-bit >processor. It's been structured so that a compiler can implement the >algorithm with 4 registers (although I haven't looked at the assembly code >generated by a compiler). >It's probably obvious how it works, so I won't bother explaining it. :). > >Scott ;) as always, the boolean exp. turned out pretty 'ugly' i must say, I only had time for whipping up an unomptimized table based version for the 18x series. 128 byte table, execute in around 80 cycles/byte+ one init and final xor / pass. Call CRC_32_INIT first, then add bytes via W with CRC_32_ADD_W, after complete message do final xor with CRC_32_DONE. If nessecary call CRC_REFLECT. I'll see if I get more time this weekend to dwell into your finalized expression and/or optimized table routine. Fun stuff. /Tony Note ignore UPPER pointer in table access, assumed cleared/not used. CRC_32_INIT ; initialize crc MOVLW 0xFF MOVWF CRC32 MOVWF CRC32+1 MOVWF CRC32+2 MOVWF CRC32+3 RETURN CRC_32_DONE ; do final xor for crc MOVLW 0xFF XORWF CRC32,F XORWF CRC32+1,F XORWF CRC32+2,F XORWF CRC32+3,F RETURN=09 CRC32_REFLECT ; reflect intire crc, i.e. msbit>lsbit RLCF CRC32,W =09 RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 RLCF CRC32,F RRCF CRC32+3,F=09 =09 RLCF CRC32+2,W RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RLCF CRC32+2,F RRCF CRC32+1,F RETURN =09 CRC_32_ADD_W=09 XORWF CRC32+3,W ; do xor with lowest byte MOVWF Index ; save ; Index nibbles labelled as i2:i1 ; now, knowing the indexes we can ; by investigating the formula for the output ; we can conclude the following output: ; CRC32 =3D Tab1[i<<2] XOR Tab2[i2>>2] ; CRC32+1 =3D CRC32 XOR Tab1[i<<2]+1 XOR Tab2[i2>>2]+1 ; CRC32+2 =3D CRC32+1 XOR Tab1[i<<2]+2 XOR Tab2[i2>>2]+2 ; CRC32+3 =3D CRC32+2 XOR Tab1[i<<2]+3 XOR Tab2[i2>>2]+3 ; swap bytes in the crc32 ( crc32 =3D crc32>>8 ) MOVFF CRC32+2,CRC32+3 MOVFF CRC32+1,CRC32+2 MOVFF CRC32,CRC32+1 CLRF CRC32 MOVLW HIGH(CRC32_NIBBLE_TABLE); MOVWF TBLPTRH ; setup high adress MOVLW LOW(CRC32_NIBBLE_TABLE) ; MOVWF TBLPTRL ; set low adress ; now we need to access the first nibble table ; and since it's 4 byte wide we must multiply with 4=20 RLCF Index,W ; w=3D i1>>1 (lowest bit unknow) ADDWF WREG,W ; w=3Di1>>1+i1>>1=3Di1>>2 (lowest two bits unknown) ANDLW b'00111100' ; mask out unwanted bits =20 ; add to table pointer ADDWF TBLPTRL,F ; propagate eventual carry BTFSC STATUS,C INCF TBLPTRH,F ; propagate the carry ; calculate number of bytes to tab2 COMF WREG,W ANDLW b'00111100' ; mask out unwanted bits =20 MOVWF Index2 ; save for index 2 access ; read table and xor with crc TBLRD*+ MOVF TABLAT,W XORWF CRC32,F TBLRD*+ MOVF TABLAT,W XORWF CRC32+1,F TBLRD*+ MOVF TABLAT,W XORWF CRC32+2,F TBLRD*+ MOVF TABLAT,W XORWF CRC32+3,F ; prepare index 2 access RRCF Index,F RRCF Index,W ; w =3D i2>>2 (highest two bits unknown) ANDLW b'00111100' ; mask out unwanted bits =20 ADDWF Index2,W ; add offset from tab1 access ; add to table pointer ADDWF TBLPTRL,F ; propagate eventual carry BTFSC STATUS,C INCF TBLPTRH,F ; propagate the carry ; read table and xor with crc TBLRD*+ MOVF TABLAT,W XORWF CRC32,F TBLRD*+ MOVF TABLAT,W XORWF CRC32+1,F TBLRD*+ MOVF TABLAT,W XORWF CRC32+2,F TBLRD*+ MOVF TABLAT,W XORWF CRC32+3,F =09 RETURN =09 =09 CRC32_NIBBLE_TABLE ; table 1 DB 0x00,0x00,0x00,0x00 =20 DB 0x77,0x07,0x30,0x96 =20 DB 0xee,0x0e,0x61,0x2c =20 DB 0x99,0x09,0x51,0xba =20 DB 0x07,0x6d,0xc4,0x19 =20 DB 0x70,0x6a,0xf4,0x8f =20 DB 0xe9,0x63,0xa5,0x35 =20 DB 0x9e,0x64,0x95,0xa3 =20 DB 0x0e,0xdb,0x88,0x32 =20 DB 0x79,0xdc,0xb8,0xa4 =20 DB 0xe0,0xd5,0xe9,0x1e =20 DB 0x97,0xd2,0xd9,0x88 =20 DB 0x09,0xb6,0x4c,0x2b =20 DB 0x7e,0xb1,0x7c,0xbd =20 DB 0xe7,0xb8,0x2d,0x07 =20 DB 0x90,0xbf,0x1d,0x91 =20 ; table 2 DB 0x00,0x00,0x00,0x00 =20 DB 0x1d,0xb7,0x10,0x64 =20 DB 0x3b,0x6e,0x20,0xc8 =20 DB 0x26,0xd9,0x30,0xac =20 DB 0x76,0xdc,0x41,0x90 =20 DB 0x6b,0x6b,0x51,0xf4 =20 DB 0x4d,0xb2,0x61,0x58 =20 DB 0x50,0x05,0x71,0x3c =20 DB 0xed,0xb8,0x83,0x20 =20 DB 0xf0,0x0f,0x93,0x44 =20 DB 0xd6,0xd6,0xa3,0xe8 =20 DB 0xcb,0x61,0xb3,0x8c =20 DB 0x9b,0x64,0xc2,0xb0 =20 DB 0x86,0xd3,0xd2,0xd4 =20 DB 0xa0,0x0a,0xe2,0x78 =20 DB 0xbd,0xbd,0xf2,0x1c =20 =09 -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.