For those interested, here's another checksum algorithm designed by BT in the UK, called a Frame Check Sequence number (FCS). It's not quite as secure as a CRC, but it is very close and it is much, much easier to calculate. (You can make out the algorithm from the code). I implemented it in Z80 assembly using a Forth cross-compiler (i.e. it's all backwards) for some embedded stuff I was working on. A CRC on the other hand, is much harder to calculate. See the comparable listing at the end. It also shows my start value as 8408. I'm a bit confused myself now, actually, as the CRC code seems to process the whole 16 bit old CRC in one go (or at least it would if the Z80 was a true 16 bit processor), which is a bit different from running 1 bit at a time. I'll hae to do some testing...when I get some time! Phil. \ -------------------------------------------------------------------------- - \ FCS \ \ Descripton: Piece of Z80/H64180 code to implement the FCS algorithm as \ defined by British Telecom New Networks Technical Forum - \ Document CP(83)/12 04/02/83. Call with the old FCS and data \ byte to be FCS'd and a new FCS is returned. Note the 'exx' \ at the start and end of the code - MPE Z80 forth crashes if \ you use the standard BC registers. You should be able to \ remove these if you are using any other compiler. \ To parse a complete buffer of information, you need an \ external loop which calls this function for each data byte. \ FCS = File Check Sequence \ \ Parameters: fcs_c0c1 - Old FCS to modify. \ char - Value to add to FCS. \ \ Returns: new_fcs_c0c1 - New FCS. \ \ -------------------------------------------------------------------------- - Code FCS \ fcs_c0c1 char --- new_fcs_c0c1 ; EXX BC POP \ Contains new data byte in C DE POP \ Contains old FCS, D=c0, E=c1 A, D LD \ Calc new c0, c0=c0+char A, C ADD NC, fcs1 JP \ If result > $ff then A INC \ add 1 to result L: fcs1 D, A LD \ Store back to c0 A, E LD \ Calc new c1, c1=c1+c0 A, D ADD NC, fcs2 JP \ If result > $ff then A INC \ add 1 to result L: fcs2 E, A LD \ Store back to c1 DE PUSH EXX NEXT, End-Code ************ CRC CODE STARTS HERE *********** HEX $8408 equ CRC-Seed \ Good initial value for CRC calculation. Code CRC-16 \ crc char --- new_crc ; EXX BC POP \ Contains new data byte in C DE POP \ Contains old CRC HL, # 0 LD \ Define Work Area A, E LD \ XOR bottom 8 bits of old CRC with data byte A, C XOR E, A LD A, H LD \ Swap bottom 8 bits of CRC with top 8 bits of H, E LD \ Work Area E, A LD A, D LD \ Swap top 8 bits of CRC with bottom 8 bits D, E LD E, A LD PE, L1 JP \ If parity of XOR even, miss out the CRC XOR A, D LD \ XOR the CRC with C001H A, # C0 XOR D, A LD A, E LD A, # 01 XOR E, A LD L: L1 SCF \ Right shift the CRC and then XOR it with work area CCF H RR L RR A, D LD A, H XOR D, A LD A, E LD A, L XOR E, A LD SCF \ Right shift the CRC and then XOR it with work area CCF \ again H RR L RR A, D LD A, H XOR D, A LD A, E LD A, L XOR E, A LD DE PUSH \ Shove the new CRC back on the stack EXX NEXT, End-code