home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
turbopas
/
crc.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-03-05
|
5KB
|
109 lines
(*
The example of how to to CRC a stream of bytes (CRC.ASM)
in <INFO-IBMPC> is relatively worthless. I needed to compute
a running CRC during file encryption to insure the file hadn't
been hit somehow. Figure you all might be able to use a more
practical implementation of the cyclic redundancy check.
And, no, I do NOT know which one this is, and I do NOT know if
it's the "legal", kosher, full-house CRC or not .. and I don't
care! What counts is that this returns a value after a stream
of bytes, and if a single bit in that stream changes, the
crc value changes. And THAT's what I wanted. You want something
else .. you write something else.
I cribbed the following assembler code from a recent MS-DOS
Kermit. Incorporate the various types, constants, etc., into
your code, and just send the procedure a byte. When all
done, grab the resultant crcval integer and use it as you will.
Remember to initialize crcval to 0 when you begin each run.
I just hacked this thing .. it SEEMS to work just fine, and
sure 'nuff, crcval remains consistent when repeatedly fed a long
(100+ Kb) stream of bytes, yet changes with a single bit changed
in that stream.
But if it doesn't .. would appreciate any improvements. I'm VERY
shakey with 8086/8088 assembler right now, and there might be
some silly things in the code! (Like: I KNOW crcval doesn't HAVE
to be in the code segment .. but in my particular application,
I needed it there.)
Released to public domain. I am the author of this particular
translation, but the people who put together MS-DOS Kermit deserve
the credit .. and of course they cribbed the routine from others ..
and on and on in the true Public Domain fashion.
Distribution and copying encouraged (if it works). Use it commercially
even, if the Kermit guys don't care. But leave the Kermit (and my)
credits in it.
Regards,
David Kirschbaum
Toad Hall
ABN.ISCAMS@USC-ISID.ARPA
________ CUT HERE ________
*)
TYPE
CRCTable = ARRAY[1..32] OF BYTE;
{yeah, yeah, it COULD be an array of integers .. but I used
these two tables for something else later in my application.
So I don't KNOW if it'll work as integers. YOU try it. [TH]
}
CONST
crc : INTEGER = 0; {typed constant to force it into code segment}
crctab : CRCTable =
($00,$00, $10,$81, $21,$02, $31,$83,
$42,$04, $52,$85, $63,$06, $73,$87,
$84,$08, $94,$89, $A5,$0A, $B5,$8B,
$C6,$0C, $D6,$8D, $E7,$0E, $F7,$8F);
crctb2 : CRCTable =
($00,$00, $11,$89, $23,$12, $32,$9B,
$46,$24, $57,$AD, $65,$36, $74,$BF,
$8C,$48, $9D,$C1, $AF,$5A, $BE,$D3,
$CA,$6C, $DB,$E5, $E9,$7E, $F8,$F7);
VAR
crcval : INTEGER Absolute crc; {force it into code segment}
PROCEDURE DoCRC(chrval : BYTE);
{courtesy of MS-Kermit and Toad Hall, Nov 85}
{computes ongoing CRC. assumes CRC table has been
established as a typed constant so CS can access it.
Notice we aren't changing chrval at all .. just using
it to modify our running crc value.
}
BEGIN
inline
($2E/$8B/$16/crcval/ {mov dx,CS:crcval ;get current CRC value.}
$8A/$86/chrval/ {mov al,chrval[BP] ; Get char ord }
$32/$C2/ {xor al,dl ; Xor input with lo order
byte of CRC. }
$8A/$E0/ {mov ah,al ; Get a copy. }
$80/$E4/$F0/ {and ah,0F0H ; Get hi 4 bits }
$B1/$04/ {mov cl,4 }
$D2/$EC/ {shr ah,cl ; Right justify }
$24/$0F/ {and al,0FH ; Get lo 4 bits }
$BE/crctb2/ {mov si,offset CS:crctb2 ; Low portion
of CRC factor }
$B7/$00/ {mov bh,0 }
$8A/$D8/ {mov bl,al }
$02/$D8/ {add bl,al ; Get word index }
$2E/$8B/$08/ {mov cx,CS:[si+bx] ; Low portion. }
$BE/crctab/ {mov si,offset CS:crctab ; High portion
of CRC factor. }
$B7/$00/ {mov bh,0 }
$8A/$DC/ {mov bl,ah }
$02/$DC/ {add bl,ah ; Get word index }
$2E/$8B/$18/ {mov bx,CS:[si+bx] }
$33/$D9/ {xor bx,cx ; Add the two. }
$B1/$08/ {mov cl,8 }
$D3/$EA/ {shr dx,cl ; Shift CRC 8 bits to the right.}
$33/$D3/ {xor dx,bx ; XOR table value and CRC.}
$2E/$89/$16/crcval); {mov CS:crcval,dx ; save new value }
END; {of DoCRC}