Article 53683 of comp.sys.cbm:
Xref: undergrad.math.uwaterloo.ca comp.sys.cbm:53683
Newsgroups: comp.sys.cbm
Path: undergrad.math.uwaterloo.ca!csbruce
From: csbruce@ccnga.uwaterloo.ca (Craig Bruce)
Subject: Re: Zmodem send
Sender: news@undergrad.math.uwaterloo.ca (news spool owner)
Message-ID: <Dr4Fxo.263@undergrad.math.uwaterloo.ca>
Date: Thu, 9 May 1996 04:46:36 GMT
References: <cjbr.831303633@gonix> <4mii2g$d4v@news.inforamp.net> <4mnokf$12l@ocean.CAM.ORG> <4morut$ora@news.inforamp.net>
Nntp-Posting-Host: ccnga.uwaterloo.ca
Organization: University of Waterloo, Canada (eh!)

In article <4morut$ora@news.inforamp.net>,
Geoffrey Welsh <crs0794@inforamp.net> wrote:

>Not only did Matt and I port my C64 serial drivers to the 128 for DesTerm, but 
>I wrote a high-speed CRC routine that completely eliminates the delay that 
>most terminal programs experience after they receive a block and have to pass 
>it through the CRC routine; it's so much faster than conventional CRC code 
>(over 20:1, if I remember correctly; the code itself could process over 20,000 
>BYTES - that's 200,000 bps! - if it had the CPU's exclusive attention) that 
>the CRC can be updated 'on the fly' no matter what the baud rate.

I've been there for a couple of years... I implemented a table-driven
CRC32-checking routine in 6502 that basically works as fast as a checksum
does.  The subroutines as extracted from the "crc32" program in ACE appear
below.  It needs three 256-byte tables called "crcTable0" to "crcTable3" and
a 32-bit zero-page variable named "crc".  You call "CrcGen" at the beginning
of your program, "CrcInit" when you start calculating the CRC for a packet,
"CrcByte" for each data byte of the packet, and "CrcFinish" to finish
calculating for a packet and then read the result out of "crc".  On a C64,
my routine will get about 22,000 bytes/sec, less the overhead of fetching
characters (if you wrap a loop around the CrcByte code).  Your code must
be very similar to mine.

Keep on Hackin'!

-Craig Bruce
csbruce@ccnga.uwaterloo.ca
"Why reinvent the wheel?"  -- proverb
-----=-----
;** crc = 0xFFFFFFFF;
;** while( (c=getc(fp)) != EOF ) {
;**     crc = (crc>>8) & 0x00FFFFFF ^ crcTable[ (crc^c) & 0xFF ];
;** }
;** return( crc^0xFFFFFFFF );

CrcInit = *
   ldx #3
-  lda #$ff
   sta crc,x
   dex
   bpl -
   rts

CrcByte = *  ;( .A=byte )
   eor crc+0            ;.X = (crc^c) & 0xFF
   tax
   lda crc+1            ;crc = (crc>>8) & 0x00FFFFFF ^ crcTable[ .X ]
   eor crcTable0,x
   sta crc+0
   lda crc+2
   eor crcTable1,x
   sta crc+1
   lda crc+3
   eor crcTable2,x
   sta crc+2
   lda crcTable3,x
   sta crc+3
   rts

CrcFinish = *
   ldx #3
-  lda crc,x
   eor #$ff
   sta crc,x
   dex
   bpl -
   rts

;** poly = 0xEDB88320L;
;** for (i=0; i<256; i++) {
;**     crc = i;
;**     for (j=8; j>0; j--) {
;**         if (crc&1) {
;**             crc = (crc >> 1) ^ poly;
;**         } else {
;**             crc >>= 1;
;**         }
;**     }
;**     crcTable[i] = crc;
;** }

CrcGen = *
   ;** generate CRC table at runtime
   ldy #0
-  ldx #0
   sty crc+0
   stx crc+1
   stx crc+2
   stx crc+3

   ldx #8
-  lsr crc+3
   ror crc+2
   ror crc+1
   ror crc+0
   bcc +
   lda crc+0
   eor #$20
   sta crc+0
   lda crc+1
   eor #$83
   sta crc+1
   lda crc+2
   eor #$B8
   sta crc+2
   lda crc+3
   eor #$ED
   sta crc+3
+  dex
   bne -

   lda crc+0
   sta crcTable0,y
   lda crc+1
   sta crcTable1,y
   lda crc+2
   sta crcTable2,y
   lda crc+3
   sta crcTable3,y
   iny
   bne --
   rts
-----=-----


