;#define ROLL_L
;#define ROLL_R

        USING   0
;
START:
; CRC empty
        MOV     R0,#0
        MOV     R1,#0

; data array: 2 bytes of data + 2 bytes of their CRC
        MOV     A,#0x12
        CALL    CRC_CALC
        MOV     A,#0x34
        CALL    CRC_CALC

#ifdef ROLL_L
        ; Save CRC as it would be appended to data
        ; for most-significant bit first calculation
        MOV     AR2,R1
        MOV     AR3,R0
#endif

#ifdef ROLL_R
        ; Save CRC as it would be appended to data.
        ; for least-significant bit first calculation
        MOV     AR2,R0
        MOV     AR3,R1
#endif

        ; Include appended CRC in calulation.
        MOV     A,R2
        CALL    CRC_CALC
        MOV     A,R3
        CALL    CRC_CALC
        JMP     $

#ifdef ROLL_L
; MSB rotation CRC-16 with 0x1021
; R1 = R1 ^ ACC, then
; C <- R1 <- R0
CRC_CALC:
        XRL     AR1,A
        MOV     R7,#8
CRC_CYC:
        CLR     C
        MOV     A,R0
        RLC     A
        MOV     R0,A
        MOV     A,R1
        RLC     A
        MOV     R1,A
        JNC     CRC_NEXT
        MOV     A,#0x10
        XRL     AR1,A
        MOV     A,#0x21
        XRL     AR0,A
CRC_NEXT:
        DJNZ    R7,CRC_CYC
        RET
#endif

#ifdef ROLL_R
; LSB rotation CRC-16 with 0x8408
; R0 = R0 ^ ACC, then
; R1 -> R0 -> C
CRC_CALC:
        XRL     AR0,A
        MOV     R7,#8
CRC_CYC:
        CLR     C
        MOV     A,R1
        RRC     A
        MOV     R1,A
        MOV     A,R0
        RRC     A
        MOV     R0,A
        JNC     CRC_NEXT
        MOV     A,#0x84
        XRL     AR1,A
        MOV     A,#0x08
        XRL     AR0,A
CRC_NEXT:
        DJNZ    R7,CRC_CYC
        RET
#endif

        END