SX Specific Cyclic Redundancy Check

16 Bit - Super Fast

By Nikolai Golovchenko

        DEVICE  SX28L, OSCHS2, TURBO, STACKX, OPTIONX
        RESET start


        ORG $08         ;global bank

temp    DS 1
crc_hi  DS 1
crc_lo  DS 1
count	DS 1


;x^16+x^15+x^2+x^0
;CRC_POLY_HIGH   EQU $80
;CRC_POLY_LOW    EQU $05

;X^16+X^12+X^5+1   (CCITT polynomial)
CRC_POLY_HIGH   EQU $10
CRC_POLY_LOW    EQU $21


;************************************************************************

start

        ;initialize CRC 
        call    crc_init        ;CRC = 0000        

	;calculate CRC for data example:
	;01,75,8A,0B,2E,B4
        mov     w, #$01
        call    crc_update      ;CRC = 1021
        mov     w, #$75
        call    crc_update      ;CRC = 1D03
        mov     w, #$8A
        call    crc_update      ;CRC = F05E
        mov     w, #$0B
        call    crc_update      ;CRC = 0074
        mov     w, #$2E
        call    crc_update      ;CRC = B1AC
        mov     w, #$B4
        call    crc_update      ;CRC = FCA5
        ;final CRC value is FCA5
	
	;check the following CRC - result should be zero
        mov     w, #$FC
        call    crc_update      ;CRC = A500
        mov     w, #$A5
        call    crc_update      ;CRC = 0000
	;check passed!

	jmp 	$
 
;************************************************************************
;
; Initialize CRC checksum (to zero)
;
;************************************************************************
crc_init
        clr 	crc_lo
        clr 	crc_hi
        retp

;************************************************************************
;
; Update CRC checksum with new data in W. MSb goes first.
;
;************************************************************************
crc_update
        mov     temp, w         ;save data in temp
        mov     w, #8           ;init counter
        mov     count, w        ;
crc_loop
        ;XOR the carry (MSb of CRC) and the next bit of data (starting from
        ;MSb). If result is zero, don't invert any bits in the checksum.
        ;If result is one, invert the checksum bits as determined by the
        ;polynomial.

        mov     w, temp
        and	w, #$80
        xor     crc_hi, w
	
        clc                     ;Rotate CRC one place left and
        rl      crc_lo          ;move the MSb to carry
        rl      crc_hi          ;

        sc                      ;check the result
         jmp    crc_next        ;skip inversion if result is zero

        mov     w, #CRC_POLY_HIGH       ;higher byte of polynomial
        xor     crc_hi, w
        mov     w, #CRC_POLY_LOW        ;lower byte of polynomial
        xor     crc_lo, w
crc_next
        rl      temp            ;prepare next bit
        decsz   count
         jmp    crc_loop
        ret
;************************************************************************