UPDCRC
Author      : Scott Murphy (CIS address 70156,263)

Purpose     : used to compute the cyclic redundancy check (CRC)
              for XMODEM protocol communications programs.

Environment : Turbo Pascal for 8086/88/186/286 based computers.

External
Requirements: UPDCRC requires one integer variable inherited from the
              block to which it belongs. The name of this variable
              is assumed to be CRCVAL. If you wish to use a different
              name, change the references to CRCVAL to the name of your
              choice.

Usage       : A file sent or recieved in XMODEM-CRC format consists of blocks
              of 133 bytes as follows: <SOH><BLK#><1-BLK#><128 bytes of data>
              <hi byte of CRC><lo byte of CRC>.  A reciever tests for a
              valid block by initializing CRCVAL to 0, then passes each
              of the 128 data bytes, and the two CRC bytes through UPDCRC.
              If CRCVAL = 0 at the end of this cycle, the data block is
              valid and should be accepted.  A sender prepares a block
              by setting CRCVAL to 0 and passing all 128 data bytes, and two
              zero bytes through UPDCRC. The two bytes of the CRCVAL generated
              replace the final two bytes of the block to be sent.

Example     :  Type block = array[1..133] of byte;
               Function BlockCRC(Var sector : block) : integer;
               (* Assumes a block as described in 'Usage' above has
                  been stored verbatim in an array of type block *)
               Var
                 crcval, i : integer;

                 (*$I updcrc.inc*)

               begin
                 crcval := 0;
                 for i := 4 to 133 do
                   updcrc(sector[i]);
                 BlockCRC := crcval
               end;

Acknowledment : This routine is a translation of equivalent code
                from the CP/M public domain utility XMODEM.ASM,
                Ver. 10.3.
}
procedure updcrc(a : byte);
begin
   inline( $8A/$46/$04/        {MOV     AL,[BP+04]}
           $8B/$1E/crcval/     {MOV     BX,crcval}
           $B9/$08/$00/        {MOV     CX,0008}
{loop0}    $D0/$E0/            {SHL     AL,1}
           $D1/$D3/            {RCL     BX,1}
           $73/$04/            {JNC     loop1}
           $81/$F3/$21/$10/    {XOR     BX,$1021}
{loop1}    $E2/$F4/            {LOOP    loop0}
           $89/$1E/crcval)     {MOV     crcval,BX}
end;
