[Back to CRC SWAG index] [Back to Main SWAG index] [Original]

    {
    RE:     SWAG submission
            This 16-bit CRC function is compatible with those used in Chuck
            Forsberg's X-modem protocol.  It's very fast, because I unrolled
            the "for (i = 0; i < 8; ++i)" loop.  If a 32-bit CRC is not
            necessary, this is a great alternative because of its speed and
            small size.

    {==============================================================}
    FUNCTION Crc16 (var buffer; size, seed: word): word; assembler;

    { Set size parameter to 0 to process 64K.  If processing only one buffer, set
      seed parameter to 0 -- otherwise set to result from previous calculation.
      C code translated by Don Paulsen. }

    (* This routine is a translation of the following C code by Chuck Forsberg.
       The added "seed" parameter allows for finding the CRC value of data spanning
       multiple buffers.  The innermost loop has been unrolled at a cost of 32
       bytes in code, but the speed increase is nearly two-fold.

         int    Crc16 (ptr, count)
         char   *ptr;
         int    count;

         {   int crc, i;

             crc = 0;
             while (--count >= 0) {
                crc = crc ^ (int)*ptr++ << 8;
                for (i = 0; i < 8; ++i)
                    if (crc & 0x8000)
                        crc = crc << 1 ^ 0x1021;
                    else
                        crc = crc << 1;
              }
             return (crc & 0xFFFF);
         }
    *)

    ASM
        les     di, buffer
        mov     dx, size
        mov     ax, seed
        mov     si, 1021h
    @next:
        xor     bl, bl
        mov     bh, es:[di]
        xor     ax, bx

        shl  ax, 1;    jnc  @noXor1;    xor  ax, si
    @noXor1:
        shl  ax, 1;    jnc  @noXor2;    xor  ax, si
    @noXor2:
        shl  ax, 1;    jnc  @noXor3;    xor  ax, si
    @noXor3:
        shl  ax, 1;    jnc  @noXor4;    xor  ax, si
    @noXor4:
        shl  ax, 1;    jnc  @noXor5;    xor  ax, si
    @noXor5:
        shl  ax, 1;    jnc  @noXor6;    xor  ax, si
    @noXor6:
        shl  ax, 1;    jnc  @noXor7;    xor  ax, si
    @noXor7:
        shl  ax, 1;    jnc  @noXor8;    xor  ax, si
    @noXor8:

        inc     di
        dec     dx
        jnz     @next
    END;

[Back to CRC SWAG index] [Back to Main SWAG index] [Original]