144 lines
4.2 KiB
C
144 lines
4.2 KiB
C
/****************************************************************************/
|
|
/* Start of crcmodel.c */
|
|
/****************************************************************************/
|
|
/* */
|
|
/* Author : Ross Williams (ross@guest.adelaide.edu.au.). */
|
|
/* Date : 3 June 1993. */
|
|
/* Status : Public domain. */
|
|
/* */
|
|
/* Description : This is the implementation (.c) file for the reference */
|
|
/* implementation of the Rocksoft^tm Model CRC Algorithm. For more */
|
|
/* information on the Rocksoft^tm Model CRC Algorithm, see the document */
|
|
/* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */
|
|
/* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */
|
|
/* "ftp.adelaide.edu.au/pub/rocksoft". */
|
|
/* */
|
|
/* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */
|
|
/* */
|
|
/****************************************************************************/
|
|
/* */
|
|
/* Implementation Notes */
|
|
/* -------------------- */
|
|
/* To avoid inconsistencies, the specification of each function is not */
|
|
/* echoed here. See the header file for a description of these functions. */
|
|
/* This package is light on checking because I want to keep it short and */
|
|
/* simple and portable (i.e. it would be too messy to distribute my entire */
|
|
/* C culture (e.g. assertions package) with this package. */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
#include "crcmodel.h"
|
|
|
|
/****************************************************************************/
|
|
/* The following definitions make the code more readable. */
|
|
|
|
#define BITMASK(X) (1L << (X))
|
|
#define MASK32 0xFFFFFFFFL
|
|
#define LOCAL static
|
|
|
|
/****************************************************************************/
|
|
|
|
/* Returns the value v with the bottom b [0,32] bits reflected. */
|
|
/* Example: reflect(0x3e23L,3) == 0x3e26 */
|
|
|
|
LOCAL ulong reflect(
|
|
ulong v,
|
|
int b)
|
|
{
|
|
int i;
|
|
ulong t = v;
|
|
for (i=0; i<b; i++)
|
|
{
|
|
if (t & 1L)
|
|
v|= BITMASK((b-1)-i);
|
|
else
|
|
v&= ~BITMASK((b-1)-i);
|
|
|
|
t>>=1;
|
|
|
|
}
|
|
return v;
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
/* Returns a longword whose value is (2^p_cm->cm_width)-1. */
|
|
/* The trick is to do this portably (e.g. without doing <<32). */
|
|
|
|
LOCAL ulong widmask(p_cm_t p_cm)
|
|
{
|
|
return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L;
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
void cm_ini (p_cm_t p_cm)
|
|
{
|
|
p_cm->cm_reg = p_cm->cm_init;
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
void cm_nxt(p_cm_t p_cm, int ch)
|
|
{
|
|
int i;
|
|
ulong uch = (ulong) ch;
|
|
ulong topbit = BITMASK(p_cm->cm_width-1);
|
|
|
|
if (p_cm->cm_refin) uch = reflect(uch,8);
|
|
p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
|
|
for (i=0; i<8; i++)
|
|
{
|
|
if (p_cm->cm_reg & topbit)
|
|
p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
|
|
else
|
|
p_cm->cm_reg <<= 1;
|
|
p_cm->cm_reg &= widmask(p_cm);
|
|
}
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
void cm_blk(
|
|
p_cm_t p_cm,
|
|
p_ubyte_ blk_adr,
|
|
ulong blk_len)
|
|
{
|
|
while (blk_len--) cm_nxt(p_cm,*blk_adr++);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
ulong cm_crc(p_cm_t p_cm)
|
|
{
|
|
if (p_cm->cm_refot)
|
|
return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width);
|
|
else
|
|
return p_cm->cm_xorot ^ p_cm->cm_reg;
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
ulong cm_tab(p_cm_t p_cm, int index)
|
|
{
|
|
int i;
|
|
ulong r;
|
|
ulong topbit = BITMASK(p_cm->cm_width-1);
|
|
ulong inbyte = (ulong) index;
|
|
|
|
if (p_cm->cm_refin) inbyte = reflect(inbyte,8);
|
|
r = inbyte << (p_cm->cm_width-8);
|
|
for (i=0; i<8; i++)
|
|
if (r & topbit)
|
|
r = (r << 1) ^ p_cm->cm_poly;
|
|
else
|
|
r<<=1;
|
|
if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width);
|
|
return r & widmask(p_cm);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* End of crcmodel.c */
|
|
/****************************************************************************/
|
|
|