;
; SYSLIB Module Name:  SCRC2
; Author:  Richard Conn
; SYSLIB Version Number:  2.3
; Module Version Number:  1.0
; Module Entry Points:
;	CRC2CLR		CRC2DONE	CRC2UPD
; Module External References:
;	None
; Author Credits:  As Given in the Source Code
;

;
;     	These subroutines will compute and check a true 16-bit
;	Cyclic Redundancy Code for a message of arbitrary length.
;
;	The  use  of this scheme will guarantee detection of all
;	single and double bit errors, all  errors  with  an  odd
;	number  of  error bits, all burst errors of length 16 or
;	less, 99.9969% of all 17-bit error bursts, and  99.9984%
;	of  all  possible  longer  error bursts.  (Ref: Computer
;	Networks, Andrew S.  Tanenbaum, Prentiss-Hall, 1981)
;
;	These routines are typically used as follows:
;	  CRC$MAKE:		; ROUTINE TO ESTABLISH CRC VALUE
;		CALL	CRC2CLR	; CLEAR CRC
;		<loop CALLing CRC2UPD>	; ACQUIRE VALUES
;		CALL	CRC2DONE	; GET VALUE
;		SHLD	CRCVAL	; SAVE VALUE
;	  CRC$CHECK:		; ROUTINE TO CHECK CRC VALUE
;		CALL	CRC2CLR	; CLEAR CRC
;		<loop CALLing CRC2UPD>	; ACQUIRE VALUES
;		CALL	CRC2DONE	; NOW DONE
;		XCHG		; DE=RETURNED CRC
;		LHLD	CRCVAL	; FROM BEFORE
;		CALL	COMPHD	; COMPARE HL TO DE FOR EQUALITY
;		JNZ	ERROR	; ERROR IF NOT EQUAL
;

;
; CRC2CLR - Clear the CRC accumulator
;	 This routine must be called at the start of each byte stream.
;
;	 Input Parameters: None
;
;	 Output Parameters: None
;
CRC2CLR::
	PUSH	H
	LXI	H,0	;SET CRC TO ZERO
	SHLD	CRCVAL
	POP	H
	RET

;
;  BUFFER FOR CRC VALUE
;
CRCVAL:	DS	2

;
; CRC2UPD - Update the CRC accumulator
;	 This routine must be called once for each byte in the
;	 byte stream for which the CRC is being calculated.
;
;	 Input Parameters: A = byte to be included in CRC
;
;	 Output Parameters: None
;
;	Adapted from Keith Petersen's CRCK 4.2 program.
;	Routine Originally By Fred Gutman.
;	From 'EDN' magazine, June 5, 1979 issue, page 84.
;
CRC2UPD::
	PUSH	H	;SAVE HL
	PUSH	B	;SAVE BC
	PUSH	PSW	;SAVE BYTE TO UPDATE
	MOV	B,A	;SAVE BYTE IN B
	LHLD	CRCVAL	;GET REMAINDER
	MOV	A,H
	ANI	128	;Q-BIT MASK
	PUSH	PSW	;SAVE STATUS
	DAD	H	;2 X R(X)
	MOV	A,B	;GET BYTE
	ADD	L
	MOV	L,A
	POP	PSW
	JZ	CRCU1	;IF Q-BIT IS ZERO
;
	MOV	A,H
	XRI	0A0H	;MS HALF OF GEN. POLY
	MOV	H,A
	MOV	A,L
	XRI	97H	;LS HALF OF GEN. POLY
	MOV	L,A
;
CRCU1:
	SHLD	CRCVAL	;SAVE RESULT
	POP	PSW	;RESTORE REGS
	POP	B
	POP	H
	RET

;
; CRC2DONE - Complete the CRC calculation
;	This routine is called after the last byte of the byte stream
;	has passed thru CRCUPD, and it returns the calculated
;	CRC bytes, which must be transmitted as the final
;	two bytes of the message (first H, then L).
;
;	 Input Parameters: None
;
;	 Output Parameters:  HL = calculated CRC bytes
;
CRC2DONE::
	LHLD	CRCVAL	;RETURN CRC VALUE IN HL
	RET

	END
