I don't how many times I've captured messages with code to calculate a
CRC - both 16-bit and 32-bit. Most of them were awfully s-l-o-w.
I finally cracked a book (actually a CD-ROM) and read up on the
algorithm. This code requires an assembler. But, it was easier to just
plonk the table into the code seg than to mess around with inline asm
and then have to write it all out as DATA statements.
If you need a 32-bit CRC, this code will provide it fast!
;------------------------- START CODE ---------------------------
comment | CRC32.ASM - for PowerBASIC 3.x, plus MASM or TASM
Written by Brian McLaughlin. Released to public domain 5/1/95.
This is a set of three procedures, which together can create a
CCIT 32-bit CRC from any string, or set of strings. By
continuously reading a file into a string buffer, then feeding
the buffer to CRC32Build, you can derive a CRC for any size file.
Here is some example code:
$LINK "CRC32.OBJ"
DECLARE SUB CRC32Init ()
DECLARE SUB CRC32Build (Strng$)
DECLARE FUNCTION CRC32Return??? ()
.
. (calculate a CRC for an entire the string array...)
.
CRC32Init 'initialize the CRC
FOR X = LBOUND(StrArray) TO UBOUND(StrArray)
CRC32Build StrArray$(X) 'pass each string in the array
NEXT X
PRINT HEX$(CRC32Return???) 'print the CRC for the array
----------------------------------------------------------------|
Code Segment Byte
Assume CS:Code
Extrn GETSTRLOC:FAR
Public CRC32Init, CRC32Build, CRC32Return
CRCLow DW 0
CRCHigh DW 0
CRC32Init Proc Far
Mov CS:CRCLow, 0FFFFh
Mov CS:CRCHigh, 0FFFFh
Retf
CRC32Init EndP
CRC32Build Proc Far
Push BP
Mov BP, SP
Push DS
Push DI
Push SI
Les BX, [BP+6] ; ES:BX point at string handle
Mov AX, ES:[BX]
Push AX ; push string handle on stack
Call Far Ptr GetStrLoc ; DX:AX point at string, CX = length
Jcxz CRCExit ; if length zero, exit now
Mov SI, AX
Mov DS, DX ; DS:SI points to string
Mov AX, CS:CRCLow ; AX = low word of crc32
Mov DX, CS:CRCHigh ; DX = high word of crc32
CrcLoop:
Xor BH, BH ; zero out any residue in BH
Mov BL, AL ; save AL before it's destroyed
Lodsb ; load AL with next char from string
Xor AL, BL ; Xor char by CRC low byte
Xchg AL, BL ; DX:AX = CRC value, BX = result of Xor
Shl BX, 1 ; multiply BX * 4
Shl BX, 1
Mov DI, Offset CRCTable
Add BX, DI ; CS:BX points at entry in lookup table
Mov DI, CS:[BX]
Mov BX, CS:[BX+2] ; BX:DI = lookup table value
Mov AL, AH ; shift the CRC value right by 8 bits
Mov AH, DL
Mov DL, DH
Xor DH, DH ; DX:AX = shifted CRC value
Xor AX, DI ; XOR the shifted CRC value with lookup value
Xor DX, BX ; DX:AX = new CRC value
Loop CRCLoop
CRCExit:
Mov CS:CRCLow, AX
Mov CS:CRCHigh, DX
Pop SI ; return value is in DX:AX
Pop DI
Pop DS
Pop BP
Retf 4
CRC32Build EndP
CRC32Return Proc Far
Mov AX, CS:CRCLow
Mov DX, CS:CRCHigh
Not AX
Not DX
Retf
CRC32Return EndP
CRCTable DD 000000000h, 077073096h, 0EE0E612Ch, 0990951BAh
DD 0076DC419h, 0706AF48Fh, 0E963A535h, 09E6495A3h
DD 00EDB8832h, 079DCB8A4h, 0E0D5E91Eh, 097D2D988h
DD 009B64C2Bh, 07EB17CBDh, 0E7B82D07h, 090BF1D91h
DD 01DB71064h, 06AB020F2h, 0F3B97148h, 084BE41DEh
DD 01ADAD47Dh, 06DDDE4EBh, 0F4D4B551h, 083D385C7h
DD 0136C9856h, 0646BA8C0h, 0FD62F97Ah, 08A65C9ECh
DD 014015C4Fh, 063066CD9h, 0FA0F3D63h, 08D080DF5h
DD 03B6E20C8h, 04C69105Eh, 0D56041E4h, 0A2677172h
DD 03C03E4D1h, 04B04D447h, 0D20D85FDh, 0A50AB56Bh
DD 035B5A8FAh, 042B2986Ch, 0DBBBC9D6h, 0ACBCF940h
DD 032D86CE3h, 045DF5C75h, 0DCD60DCFh, 0ABD13D59h
DD 026D930ACh, 051DE003Ah, 0C8D75180h, 0BFD06116h
DD 021B4F4B5h, 056B3C423h, 0CFBA9599h, 0B8BDA50Fh
DD 02802B89Eh, 05F058808h, 0C60CD9B2h, 0B10BE924h
DD 02F6F7C87h, 058684C11h, 0C1611DABh, 0B6662D3Dh
DD 076DC4190h, 001DB7106h, 098D220BCh, 0EFD5102Ah
DD 071B18589h, 006B6B51Fh, 09FBFE4A5h, 0E8B8D433h
DD 07807C9A2h, 00F00F934h, 09609A88Eh, 0E10E9818h
DD 07F6A0DBBh, 0086D3D2Dh, 091646C97h, 0E6635C01h
DD 06B6B51F4h, 01C6C6162h, 0856530D8h, 0F262004Eh
DD 06C0695EDh, 01B01A57Bh, 08208F4C1h, 0F50FC457h
DD 065B0D9C6h, 012B7E950h, 08BBEB8EAh, 0FCB9887Ch
DD 062DD1DDFh, 015DA2D49h, 08CD37CF3h, 0FBD44C65h
DD 04DB26158h, 03AB551CEh, 0A3BC0074h, 0D4BB30E2h
DD 04ADFA541h, 03DD895D7h, 0A4D1C46Dh, 0D3D6F4FBh
DD 04369E96Ah, 0346ED9FCh, 0AD678846h, 0DA60B8D0h
DD 044042D73h, 033031DE5h, 0AA0A4C5Fh, 0DD0D7CC9h
DD 05005713Ch, 0270241AAh, 0BE0B1010h, 0C90C2086h
DD 05768B525h, 0206F85B3h, 0B966D409h, 0CE61E49Fh
DD 05EDEF90Eh, 029D9C998h, 0B0D09822h, 0C7D7A8B4h
DD 059B33D17h, 02EB40D81h, 0B7BD5C3Bh, 0C0BA6CADh
>>> Continued to next message
* SLMR 2.1a * MAXLIB For PB v1.1 - Access arrays and files in EMS/XMS!
--- WILDMAIL!/WC v4.12
---------------
* Origin: Com-Dat BBS - Hillsboro, OR. HST DS (1:105/314.0)
|