(*
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}
