home *** CD-ROM | disk | FTP | other *** search
- TITLE CRC16 - Cyclic Redundancy Checksum
- ;******************************************************************************
- ;* *
- ;* *
- ;* Improved CRC16 Routine *
- ;* *
- ;* *
- ;* This routine performs CRC16 cyclic redundancy checksum calculations. *
- ;* It makes use of an idea given in the IEEE Micro publication by Aram *
- ;* Perez, and represents a considerable improvement over some of the *
- ;* methods used previously. It receives a 16-bit CRC in BC and *
- ;* the next data byte in E. It returns the updated CRC in BC. *
- ;* *
- ;* The first step is to XOR the data byte into the right half of the *
- ;* the CRC. Let the result of this be denoted by: *
- ;* *
- ;* a b c d e f g h i j k l m n o p *
- ;* *
- ;* After the eight CRC16 steps, with the x^16+x^15+x^2+1 polynomial, this *
- ;* should become: *
- ;* *
- ;* X i j k l m n o p 0 0 0 0 0 0 X *
- ;* + + + + + + + + + + + + + + + + *
- ;* 0 X i j k l m n o p 0 0 0 0 0 0 *
- ;* + + + + + + + + + + + + + + + + *
- ;* 0 0 0 0 0 0 0 0 a b c d e f g h *
- ;* *
- ;* where X represents the parity of the 8 bits i,j,k,l,m,n,o,p, and *
- ;* where + represents the XOR of the respective columns. The code below *
- ;* carries out this process directly, making use of the 8080's parity flag *
- ;* for finding X. [Note that since the routine uses this parity flag *
- ;* after an XRA instruction, the routine will work properly even on a *
- ;* Z80 microprocessor.] *
- ;* *
- ;******************************************************************************
- ;* *
- ;* Entry: *
- ;* BC = old CRC16 *
- ;* E = next data byte *
- ;* *
- ;* CALL CRC16 *
- ;* *
- ;* Exit: *
- ;* BC = new CRC16 *
- ;* A, D, & E also affected *
- ;* *
- ;* *
- ;***************************************** R. Stafford - Aug. 9, 1983 ********
- ;
- RSECT ROM
- INTERN CRC16
-
- CRC16: EQU $
- ; Assume the current 16 bit CRC is in BC and the next data byte in E.
- MOV A,E
- XRA C ;A now has [i j k l m n o p] & parity flag has X
- MOV C,B ;Put [a b c d e f g h] in C
- MOV D,A ;Put [i j k l m n o p] in D
- JPE CRCJ ;The parity flag has X (even on a Z80)
- XRI 2 ;XOR X into A in bit 1
- CRCJ XRA D ;A now has [0 0 0 0 0 0 X 0]
- MOV E,A ;Now E = [0 0 0 0 0 0 X 0]
- RAR
- RAR ;Move X into carry flag
- MOV A,D ;Put [i j k l m n o p] back into A
- RAR
- MOV D,A ;Shift it to [X i j k l m n o] in D
- MOV A,E ;Get [0 0 0 0 0 0 X 0] from E
- RAR ;This sets carry to zero
- MOV E,A ;Put [p 0 0 0 0 0 0 X] back into E
- MOV A,D ;Now proceed with yet another shift
- RAR ;Get [0 X i j k l m n] in A
- MOV B,A ;Save it in B
- MOV A,E ;Then get [p 0 0 0 0 0 0 X]
- RAR ;Shift it to [o p 0 0 0 0 0 0]
- XRA E ;Then XOR in [p 0 0 0 0 0 0 X]
- XRA C ;Finally XOR in [a b c d e f g h]
- MOV C,A ;Establish this as the low byte of new CRC
- MOV A,D ;Now get [X i j k l m n o]
- XRA B ;XOR it with [0 X i j k l m n]
- MOV B,A ;This constitutes the upper byte of new CRC
- RET ;Return with updated CRC in BC
-
- ; End of CRC16