Andy - Here is the CRC generation function from the version of C-Kermit I'm working on now (5A). /* CRC generation tables */ /* LONG means "unsigned long" */ static LONG crcta[16] = { 0L, 010201L, 020402L, 030603L, 041004L, 051205L, 061406L, 071607L, 0102010L, 0112211L, 0122412L, 0132613L, 0143014L, 0153215L, 0163416L, 0173617L }; static LONG crctb[16] = { 0L, 010611L, 021422L, 031233L, 043044L, 053655L, 062466L, 072277L, 0106110L, 0116701L, 0127532L, 0137323L, 0145154L, 0155745L, 0164576L, 0174367L }; /* C H K 3 -- Compute a type-3 Kermit block check. */ /* Calculate the 16-bit CRC-CCITT of a null-terminated string using a lookup table. Assumes the argument string contains no embedded nulls. */ unsigned int chk3(pkt) register CHAR *pkt; { register LONG c, crc; register unsigned int m; m = (parity) ? 0177 : 0377; for (crc = 0; *pkt != '\0'; pkt++) { c = crc ^ (LONG)(*pkt & m); crc = (crc >> 8) ^ (crcta[(c & 0xF0) >> 4] ^ crctb[c & 0x0F]); } return((unsigned int) (crc & 0xFFFF)); } And here is a similar routine from DEC-20 Kermit (circa 1985) that shows the tables in octal, in case that's any help. ; This routine calculates the CRC for a string, using the ; CRC-CCITT polynomial x^16+x^12+x^5+1. ; ; The string should be the fields of the packet between but not including ; the and the block check, which is treated as a string of bits with ; the low order bit of the first character first and the high order bit of the ; last character last -- this is how the bits arrive on the transmission line. ; The bit string is divided by the polynomial. ; ; The initial value of the CRC is 0. The result is the remainder of this ; division, used as-is (i.e. not complemented). ; ; Call with ; t1/ length of string ; t2/ 8-bit byte pointer to string ; Returns +1 always, with t1/ 16-bit CRC, t2 unchanged. ; ; AC usage: ; t1/ Accumulated CRC ; q4/ Remaining length ; q3/ Byte pointer to string ; q2/ temp ; q1/ temp ; crcclc: saveac ; Save q1-q4, and t2. dmove q3,t1 ; Get arguments. setz t1, ; Initial CRC is 0. move t2, parity ;[136] Get parity. crcc.1: ildb q1, q4 ; Get a character. caie t2, none ;[136] Parity = NONE? andi q1, ^o177 ;[136] No, doing parity, strip parity bit. xori q1, (t1) ; Add in with current CRC. ldb q2, [point 4,q1,31] ; Get high 4 bits. andi q1, ^o17 ; And low 4 bits. move q1, crctb2(q1) ; Get low portion of CRC factor. xor q1, crctab(q2) ; Plus high portion. lsh t1, -^d8 ; Shift off a byte from previous CRC. xor t1, q1 ; Add in new value. sojg q3, crcc.1 ; Loop for all characters. ret ; Done, return +1 with CRC in t1. ; Data tables for CRC-CCITT generation crctab: oct 0 oct 10201 oct 20402 oct 30603 oct 41004 oct 51205 oct 61406 oct 71607 oct 102010 oct 112211 oct 122412 oct 132613 oct 143014 oct 153215 oct 163416 oct 173617 crctb2: oct 0 oct 10611 oct 21422 oct 31233 oct 43044 oct 53655 oct 62466 oct 72277 oct 106110 oct 116701 oct 127532 oct 137323 oct 145154 oct 155745 oct 164576 oct 174367