; Constant definitions ; CRC_MASK_LSB EQU 001H ;CRC-16 poloynomial CRC_MASK_MSB EQU 0A0H ; ; ; Note: the CRC accumulator bytes are being stored in ; ram bytes 0DH and 0EH; these correspond to registers ; R5 and R6 in bank 1, which are not used by the ; communications interrupt ; ; CRC_ACCUM_LOW EQU 0DH ;register bank 1 R5 CRC_ACCUM_HI EQU 0EH ;register bank 1 R6 ; ACALL MSG_LENGTH ;find the message length ACALL CALC_CRC ;calculate the CRC ; ; Now, CRC_ACCUM contains the computed CRC of the message. Are ; they the same as contained in the message itself? ; ADD A,#COMBUF ;add to buffer address to from pointer ;to the first byte of the CRC MOV R1,A ;R0 will point MOV A,@R1 CJNE A,CRC_ACCUM_LOW,COMINT_03 ;abandon if not equal INC R1 MOV A,@R1 CJNE A,CRC_ACCUM_HI,COMINT_03 ;abandon if not equal ; ;--------------------------------------------------------------------------- ; CRC calculation routine -- this routine calculates ; the CRC polynomial for the contents of the communications ; buffer, based upon the desired length of computation (passed ; in the A register). R1 serves as the comm buffer pointer. ; CALC_CRC: MOV R0,A ;save the accum MOV R7,A ;save the count MOV R1,#COMBUF ;and point to the combuf CLR A MOV CRC_ACCUM_LOW,A ;clear the crc accum before we start MOV CRC_ACCUM_HI,A ; ; First we XOR the incoming byte with the contents of ; the least significant byte of the CRC accumulator ; CC10: MOV A,CRC_ACCUM_LOW ;xor the byte with the LSbyte of the CRC_accum XRL A,@R1 MOV CRC_ACCUM_LOW,A ; ; now we commence shifting the crc accumulator right ; one bit, testing the bit that pops out to see if we ; need to xor the crc accumulator with the crc mask. We ; do this eight times (once for each bit of the byte) ; MOV R4,#8 ;R4 will serve as the eight state counter CC20: MOV A,CRC_ACCUM_HI ;get the high byte CLR C ;filled with 0's RRC A ;shift it right MOV CRC_ACCUM_HI,A MOV A,CRC_ACCUM_LOW ;and the low byte RRC A ;shift it right MOV CRC_ACCUM_LOW,A ; ; if the carry is set, we must XOR the crc accumulator ; with the crc mask ; JNC CC30 MOV A,CRC_ACCUM_LOW XRL A,#CRC_MASK_LSB MOV CRC_ACCUM_LOW,A MOV A,CRC_ACCUM_HI XRL A,#CRC_MASK_MSB MOV CRC_ACCUM_HI,A ; CC30: DJNZ R4,CC20 ;do it eight times ; ; the process is repeated for each character ; in the message, according to the length passed ; when the routine was called ; ; INC R1 ;rdy for next byte in the message DJNZ R7,CC10 ;one less byte to do ; MOV A,R0 ;restore the accum RET ; ;