TIP: Click on subject to list as thread! ANSI
echo: power_bas
to: ALL
from: BRIAN MCLAUGHLIN
date: 1995-05-01 21:40:00
subject: 32-BIT CRC ASM CODE 1/2

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)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.