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: Date: Thu, 9 May 1996 04:46:36 GMT References: <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 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 -----=-----