home *** CD-ROM | disk | FTP | other *** search
- {$A-}
- unit ShCrcChk;
- {
- ShCrcChk
-
- A File CRC16 Calculation Unit
-
- by
-
- Bill Madison
-
- W. G. Madison and Associates, Ltd.
- 13819 Shavano Downs
- P.O. Box 780956
- San Antonio, TX 78278-0956
- (512)492-2777
- CIS 73240,342
-
- Copyright 1991 Madison & Associates
- All Rights Reserved
-
- This file may be used and distributed only in accord-
- ance with the provisions described on the title page of
- the accompanying documentation file
- SKYHAWK.DOC
- }
-
- Interface
-
- Uses
- DOS;
-
- Function CrcCalc(FileName : String) : word;
- {
- Calculates the CCITT asynch CRC16 value for file = FileName.
- }
-
- Function CrcCopy(InFileName, OutFileName : String) : word;
- {
- Calculates the CCITT asynch CRC16 value for file=InFileName. If
- OutFileName is specified, InFileName is copied to OutFileName. In either
- case, the CRC16 value is returned.
- }
-
- Implementation
-
- var
- Buff : array[1..16384] of Byte; {The data buffer}
- {Note: Extensive testing has determined that only a slight
- speed-up can be achieved by increasing the buffer size
- further. }
-
- const
- CrcTab : array[0..255] of Word =
- ($0000,$1021,$2042,$3063,$4084,$50A5,$60C6,$70E7,
- $8108,$9129,$A14A,$B16B,$C18C,$D1AD,$E1CE,$F1EF,
- $1231,$0210,$3273,$2252,$52B5,$4294,$72F7,$62D6,
- $9339,$8318,$B37B,$A35A,$D3BD,$C39C,$F3FF,$E3DE,
- $2462,$3443,$0420,$1401,$64E6,$74C7,$44A4,$5485,
- $A56A,$B54B,$8528,$9509,$E5EE,$F5CF,$C5AC,$D58D,
- $3653,$2672,$1611,$0630,$76D7,$66F6,$5695,$46B4,
- $B75B,$A77A,$9719,$8738,$F7DF,$E7FE,$D79D,$C7BC,
- $48C4,$58E5,$6886,$78A7,$0840,$1861,$2802,$3823,
- $C9CC,$D9ED,$E98E,$F9AF,$8948,$9969,$A90A,$B92B,
- $5AF5,$4AD4,$7AB7,$6A96,$1A71,$0A50,$3A33,$2A12,
- $DBFD,$CBDC,$FBBF,$EB9E,$9B79,$8B58,$BB3B,$AB1A,
- $6CA6,$7C87,$4CE4,$5CC5,$2C22,$3C03,$0C60,$1C41,
- $EDAE,$FD8F,$CDEC,$DDCD,$AD2A,$BD0B,$8D68,$9D49,
- $7E97,$6EB6,$5ED5,$4EF4,$3E13,$2E32,$1E51,$0E70,
- $FF9F,$EFBE,$DFDD,$CFFC,$BF1B,$AF3A,$9F59,$8F78,
- $9188,$81A9,$B1CA,$A1EB,$D10C,$C12D,$F14E,$E16F,
- $1080,$00A1,$30C2,$20E3,$5004,$4025,$7046,$6067,
- $83B9,$9398,$A3FB,$B3DA,$C33D,$D31C,$E37F,$F35E,
- $02B1,$1290,$22F3,$32D2,$4235,$5214,$6277,$7256,
- $B5EA,$A5CB,$95A8,$8589,$F56E,$E54F,$D52C,$C50D,
- $34E2,$24C3,$14A0,$0481,$7466,$6447,$5424,$4405,
- $A7DB,$B7FA,$8799,$97B8,$E75F,$F77E,$C71D,$D73C,
- $26D3,$36F2,$0691,$16B0,$6657,$7676,$4615,$5634,
- $D94C,$C96D,$F90E,$E92F,$99C8,$89E9,$B98A,$A9AB,
- $5844,$4865,$7806,$6827,$18C0,$08E1,$3882,$28A3,
- $CB7D,$DB5C,$EB3F,$FB1E,$8BF9,$9BD8,$ABBB,$BB9A,
- $4A75,$5A54,$6A37,$7A16,$0AF1,$1AD0,$2AB3,$3A92,
- $FD2E,$ED0F,$DD6C,$CD4D,$BDAA,$AD8B,$9DE8,$8DC9,
- $7C26,$6C07,$5C64,$4C45,$3CA2,$2C83,$1CE0,$0CC1,
- $EF1F,$FF3E,$CF5D,$DF7C,$AF9B,$BFBA,$8FD9,$9FF8,
- $6E17,$7E36,$4E55,$5E74,$2E93,$3EB2,$0ED1,$1EF0);
-
- Function CRCResult(Var Table, Buffer; CrcVal, count : integer) : integer;
- var temp : integer;
- begin
- Inline(
- {For I := 1 to Full do
- CRCval := Crctab[hi(CRCval) xor Buff[I]] xor (lo(CRCval) shl 8);}
- $1E/ { push ds ;save ds}
- $06/ { push es ;save es}
- $C5/$B6/>TABLE/ { lds si, [bp+>Table] ;ds:si points to the table}
- $C4/$BE/>BUFFER/ { les di, [bp+>buffer] ;es:si points to the buffer}
- $8B/$8E/>COUNT/ { mov cx,[bp+>count] ;cx has the buffer size}
- $8B/$9E/>CRCVAL/ { mov bx,[bp+>CRCVal] ;bx = start CRC value}
- $E3/$25/ { jcxz Done}
- $89/$D8/ { mov ax,bx ;ax = start CRC value}
- { LooPit:}
- $86/$C4/ { xchg ah,al ;al = hi byte}
- $30/$E4/ { xor ah,ah ;ax = hi(CRCVal)}
- $31/$D2/ { xor dx,dx ;dx = 0}
- $26/ { es:}
- $8A/$15/ { mov dl,[di] ;dx = buffer[i] A BYTE value!!}
- $47/ { inc di ;bump di (inc(i))}
- $31/$D0/ { xor ax,dx ;ax = hi(CRCVal) xor Buffer[i]}
- $89/$DA/ { mov dx,bx ;dx = CRCVal}
- $89/$C3/ { mov bx,ax ;bx = hi(CRCVal) xor Buffer[i]}
- $30/$F6/ { xor dh,dh ;dx = lo(CRCVal)}
- $51/ { push cx ;save counter}
- $B1/$08/ { mov cl,8 ;need 8 shifts}
- $D3/$E2/ { shl dx,cl ;dx = lo(CRCVal) shl 8}
- $59/ { pop cx ;restore the counter}
- $D1/$E3/ { shl bx,1 ;need to mult by 2}
- $3E/ { ds:}
- $8B/$00/ { mov ax,[bx+si] ;ax = CRCTAbl[hi(CRCVal xor Buffer[i]]}
- $31/$D0/ { xor ax,dx ;ax = CRCTab[hi(CRCVal) xor Buffer[i]]}
- { ; xor (lo(CRCVal) shl 8)}
- $89/$C3/ { mov bx,ax ;bx = new CRCVal}
- $E2/$DD/ { loop loopit ;go do it all again}
- { Done:}
- $89/$9E/>TEMP/ { mov [bp+>temp],bx ;bx has the final CRC value}
- $07/ { pop es ;restore es}
- $1F); { pop ds ;restore ds}
- CRCResult := temp{ ;pass it back}
- end; {CrcResult}
-
- Function CrcCalc(FileName : String) : word;
- var
- FI : File;
- Full : Integer; {How full is the buffer on a block read?}
- CRCval : Integer;
- FileAttr: word;
-
- begin {CrcCalc}
- CrcVal := 0;
- Assign(FI, FileName);
- GetFAttr(FI, FileAttr);
- SetFAttr(FI, 0); {can now open any file}
- Reset(FI, 1);
- repeat
- BlockRead(FI, Buff, 16384, Full);
- CrcVal := CrcResult(CrcTab, Buff, CrcVal, Full);
- until Full <= 0;
- Close(FI);
- SetFAttr(FI, FileAttr); {restore original filemode}
- CrcCalc := CRCval;
- end; {CrcCalc}
-
- Function CrcCopy(InFileName, OutFileName : String) : word;
- {
- Calculates the CCITT asynch CRC16 value for file=InFileName. If
- OutFileName is specified, InFileName is copied to OutFileName. In either
- case, the CRC16 value is returned. The DateTime stamp of the input file
- is preserved.
- }
-
- var
- FI,
- FO : File;
- Full : Integer; {Number of bytes transferred in BlockRead}
- T1 : Integer;
- CRCval : Integer;
- DTStamp: LongInt;
- FileAttr: word;
-
- begin {CrcCopy}
- CrcVal := 0;
- Assign(FI, InFileName);
- GetFattr(FI, FileAttr);
- SetFAttr(FI, 0); {can now open any file}
- Reset(FI, 1);
- If OutFileName[0] > #0 then begin
- Assign(FO, OutFileName);
- {$I-}Rewrite(FO, 1);{$I+}
- If IOresult <> 0 then begin
- WriteLn;
- WriteLn('Can''t open file ',OutFileName,' Aborting...');
- Halt(1);
- end;
- end;
- repeat
- BlockRead(FI, Buff, 16384, Full);
- CrcVal := CrcResult(CrcTab, Buff, CrcVal, Full);
- If (OutFileName[0] > #0) and (Full > 0) then
- {$I-}BlockWrite(FO, Buff, Full);{$I+}
- T1 := IOresult;
- If T1 <> 0 then begin
- WriteLn;
- WriteLn('I/O error ',T1,' writing file. Aborting...');
- Close(FO);
- Erase(FO);
- Halt(1);
- end;
- until Full <= 0;
- GetFTime(FI, DTstamp);
- Close(FI);
- SetFAttr(FI, FileAttr); {restore original filemode}
- If OutFileName[0] > #0 then begin
- SetFTime(FO, DTstamp);
- Close(FO);
- end;
- CrcCopy := CRCval;
- end; {CrcCopy}
- end.
-
-