title XMODEM CRC Algorithm 8086 / Lattice C Compiler include mc.ash .model small ;* * ;* clrcrc(); * ;* CLRCRC - A call to this entry resets the CRC accumulator. * ;* It must be called at the start of each message. * ;* * ;* Entry Parameters: None. * ;* * ;* Exit Conditions: CRC accumulator cleared. * ;* * ;* udcrc(c); * ;* char c; * ;* UPDCRC - A call to this entry updates the CRC accumulator. * ;* It must be called once for each byte in the * ;* message for which the CRC is being calculated. * ;* * ;* Entry Parameters: a byte to be included * ;* in the CRC calculation. * ;* * ;* Exit Conditions: CRC accumulator updated. * ;* * ;* * ;* crc= fincrc(); * ;* unsigned crc; * ;* FINCRC - A call to this entry finishes the CRC calculation * ;* for a message which is to be TRANSMITTED. It must * ;* be called after the last byte of the message has * ;* been passed thru UPDCRC. It returns the calculated * ;* CRC bytes, which must be transmitted as the final * ;* two bytes of the message. * ;* * ;* Note that this returns a single 16 bit value; * ;* if transmitting bytes, it must be transmitted * ;* upper half first then lower half: * ;* * ;* output (crc >> 8); * ;* output (crc); * ;* * ;* * ;* Entry Parameters: None. * ;* * ;* Exit Conditions: calculated CRC bytes. * ;* * ;* error= chkcrc(); * ;* int error; * ;* CHKCRC - A call to this routine checks the CRC bytes of * ;* a RECEIVED message and returns a code to indicate * ;* whether the message was received correctly. It must * ;* be called after the message AND the two CRC bytes * ;* have been received AND passed thru UPDCRC. * ;* * ;* Entry Parameters: None. * ;* * ;* Exit Conditions: 0 if message ok. * ;* non-zero if message garbled. * ;* * page ; ;Our very own little bit of data space. ; .data crc dw (?) ;calculated CRC, .code ; ;Initialize the CRC. ; func _clrcrc mov crc,0 endf _clrcrc ; ;Update the CRC with the new byte. The method used is ;the CCITT polynomial: ; ; x^16 + x^12 + x^5 + 1 ; ;An alternate method often used in synchronous ;protocols is: ; ; x^16 + x^15 + x^2 + 1 ; ;Which can be generated by changing the XOR pattern ;from 1021 hex to 8005 hex. ; func _updcrc mov bx,crc ;BX == CRC a reg for speed, mov cx,8 ;CX == bits in a byte, mov ax,arg0 ;AL == msg byte, u1: rcl al,1 ;MSB -> carry, rcl bx,1 ; -> CRC LSB, jnc u2 xor bx,1021h u2: loop u1 mov crc,bx endf _updcrc ; ;Finish off the CRC. ; func _fincrc xor ax,ax ;do two zeros push ax call _updcrc call _updcrc pop ax mov ax,crc ;return finished CRC endf _fincrc ; ;Check the calculated CRC. Return 0 if OK. ; func _chkcrc mov ax,crc endf _chkcrc end