> Well yes, a table is generally the fastest way to do it, but do you have
> the space for a table?  It's been a long time since I coded CRC routines,
> but a fast version would need (as I remember) a 64Kx16 table which is the
> ENTIRE memory of the 8051.  I can do it with no table, 40 bytes of code,
> and 28 cycles.  I'd be curious to see if (and how) you can do it faster,
> and still fit in the 64K program space.  I'll post my code if people are
> interested, otherwise it's by email request at jonb@metronet.com

        XRL     A, CRCL         ;This bit of code updates the CRC-16 accumula-
        MOV     CRCL, A         ;  tion in registers CRCH:CRCL using the data
        MOV     DPTR, #CRCTBL   ;  byte in the A register.
        MOVC    A, @A + DPTR
        XRL     A, CRCH         ;The nice table-driven algorithm comes out of
        XCH     A, CRCL         ;  Jack Crenshaw's article _Implementing_CRCs_
        INC     DPH             ;  in the January 1992 issue of _Embedded_
        MOVC    A, @A + DPTR    ;  _Systems_Programming_ magazine.
        MOV     CRCH, A
                                ;Burns registers A, DPTR, CRCH, CRCL.  Runs in
                                ;  12 machine cycles.  Costs 8 more if you have
                                ;  to PUSH/POP DPH and DPL, though.  No extra
                                ;  cost for using internal data RAM for CRCH
                                ;  CRCL.

;
; This 512-byte table is used to implement a CCITT CRC-16 error detection code.
;
CRCTBL  DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      000H, 0C1H, 081H, 040H, 001H, 0C0H, 080H, 041H
        DB      001H, 0C0H, 080H, 041H, 000H, 0C1H, 081H, 040H

        DB      000H, 0C0H, 0C1H, 001H, 0C3H, 003H, 002H, 0C2H
        DB      0C6H, 006H, 007H, 0C7H, 005H, 0C5H, 0C4H, 004H
        DB      0CCH, 00CH, 00DH, 0CDH, 00FH, 0CFH, 0CEH, 00EH
        DB      00AH, 0CAH, 0CBH, 00BH, 0C9H, 009H, 008H, 0C8H
        DB      0D8H, 018H, 019H, 0D9H, 01BH, 0DBH, 0DAH, 01AH
        DB      01EH, 0DEH, 0DFH, 01FH, 0DDH, 01DH, 01CH, 0DCH
        DB      014H, 0D4H, 0D5H, 015H, 0D7H, 017H, 016H, 0D6H
        DB      0D2H, 012H, 013H, 0D3H, 011H, 0D1H, 0D0H, 010H
        DB      0F0H, 030H, 031H, 0F1H, 033H, 0F3H, 0F2H, 032H
        DB      036H, 0F6H, 0F7H, 037H, 0F5H, 035H, 034H, 0F4H
        DB      03CH, 0FCH, 0FDH, 03DH, 0FFH, 03FH, 03EH, 0FEH
        DB      0FAH, 03AH, 03BH, 0FBH, 039H, 0F9H, 0F8H, 038H
        DB      028H, 0E8H, 0E9H, 029H, 0EBH, 02BH, 02AH, 0EAH
        DB      0EEH, 02EH, 02FH, 0EFH, 02DH, 0EDH, 0ECH, 02CH
        DB      0E4H, 024H, 025H, 0E5H, 027H, 0E7H, 0E6H, 026H
        DB      022H, 0E2H, 0E3H, 023H, 0E1H, 021H, 020H, 0E0H
        DB      0A0H, 060H, 061H, 0A1H, 063H, 0A3H, 0A2H, 062H
        DB      066H, 0A6H, 0A7H, 067H, 0A5H, 065H, 064H, 0A4H
        DB      06CH, 0ACH, 0ADH, 06DH, 0AFH, 06FH, 06EH, 0AEH
        DB      0AAH, 06AH, 06BH, 0ABH, 069H, 0A9H, 0A8H, 068H
        DB      078H, 0B8H, 0B9H, 079H, 0BBH, 07BH, 07AH, 0BAH
        DB      0BEH, 07EH, 07FH, 0BFH, 07DH, 0BDH, 0BCH, 07CH
        DB      0B4H, 074H, 075H, 0B5H, 077H, 0B7H, 0B6H, 076H
        DB      072H, 0B2H, 0B3H, 073H, 0B1H, 071H, 070H, 0B0H
        DB      050H, 090H, 091H, 051H, 093H, 053H, 052H, 092H
        DB      096H, 056H, 057H, 097H, 055H, 095H, 094H, 054H
        DB      09CH, 05CH, 05DH, 09DH, 05FH, 09FH, 09EH, 05EH
        DB      05AH, 09AH, 09BH, 05BH, 099H, 059H, 058H, 098H
        DB      088H, 048H, 049H, 089H, 04BH, 08BH, 08AH, 04AH
        DB      04EH, 08EH, 08FH, 04FH, 08DH, 04DH, 04CH, 08CH
        DB      044H, 084H, 085H, 045H, 087H, 047H, 046H, 086H
        DB      082H, 042H, 043H, 083H, 041H, 081H, 080H, 040H

Works for me!  Check out Crenshaw's article.  It even made a hardware
body like me understand and be able to use CRCs very easily, indeed.

Will
