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
Received on Wed May 08 16:54:23 2002
This archive was generated by hypermail 2.1.8 : Tue Dec 02 2003 - 18:40:44 EST