;
; 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