38
|
1 /******************************************************************************/
|
|
2 /* Start of crcmodel.c */
|
|
3 /******************************************************************************/
|
|
4 /* */
|
|
5 /* Author : Ross Williams (ross@guest.adelaide.edu.au.). */
|
|
6 /* Date : 3 June 1993. */
|
|
7 /* Status : Public domain. */
|
|
8 /* */
|
|
9 /* Description : This is the implementation (.c) file for the reference */
|
|
10 /* implementation of the Rocksoft^tm Model CRC Algorithm. For more */
|
|
11 /* information on the Rocksoft^tm Model CRC Algorithm, see the document */
|
|
12 /* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */
|
|
13 /* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */
|
|
14 /* "ftp.adelaide.edu.au/pub/rocksoft". */
|
|
15 /* */
|
|
16 /* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */
|
|
17 /* */
|
|
18 /******************************************************************************/
|
|
19 /* */
|
|
20 /* Implementation Notes */
|
|
21 /* -------------------- */
|
|
22 /* To avoid inconsistencies, the specification of each function is not echoed */
|
|
23 /* here. See the header file for a description of these functions. */
|
|
24 /* This package is light on checking because I want to keep it short and */
|
|
25 /* simple and portable (i.e. it would be too messy to distribute my entire */
|
|
26 /* C culture (e.g. assertions package) with this package. */
|
|
27 /* */
|
|
28 /******************************************************************************/
|
|
29
|
|
30 #include "crcmodel.h"
|
|
31
|
|
32 /******************************************************************************/
|
|
33
|
|
34 /* The following definitions make the code more readable. */
|
|
35
|
|
36 #define BITMASK(X) (1L << (X))
|
|
37 #define MASK32 0xFFFFFFFFL
|
|
38 #define LOCAL static
|
|
39
|
|
40 /******************************************************************************/
|
|
41
|
|
42 LOCAL ulong reflect P_((ulong v,int b));
|
|
43 LOCAL ulong reflect (ulong v,int b)
|
|
44 /* Returns the value v with the bottom b [0,32] bits reflected. */
|
|
45 /* Example: reflect(0x3e23L,3) == 0x3e26 */
|
|
46 {
|
|
47 int i;
|
|
48 ulong t = v;
|
|
49 for (i=0; i<b; i++)
|
|
50 {
|
|
51 if (t & 1L)
|
|
52 v|= BITMASK((b-1)-i);
|
|
53 else
|
|
54 v&= ~BITMASK((b-1)-i);
|
|
55 t>>=1;
|
|
56 }
|
|
57 return v;
|
|
58 }
|
|
59
|
|
60 /******************************************************************************/
|
|
61
|
|
62 LOCAL ulong widmask P_((p_cm_t));
|
|
63 LOCAL ulong widmask (p_cm_t p_cm)
|
|
64 /* Returns a longword whose value is (2^p_cm->cm_width)-1. */
|
|
65 /* The trick is to do this portably (e.g. without doing <<32). */
|
|
66 {
|
|
67 return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L;
|
|
68 }
|
|
69
|
|
70 /******************************************************************************/
|
|
71
|
|
72 void cm_ini (p_cm_t p_cm)
|
|
73 {
|
|
74 p_cm->cm_reg = p_cm->cm_init;
|
|
75 }
|
|
76
|
|
77 /******************************************************************************/
|
|
78
|
|
79 void cm_nxt (p_cm_t p_cm, int ch)
|
|
80 {
|
|
81 int i;
|
|
82 ulong uch = (ulong) ch;
|
|
83 ulong topbit = BITMASK(p_cm->cm_width-1);
|
|
84
|
|
85 if (p_cm->cm_refin) uch = reflect(uch,8);
|
|
86 p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
|
|
87 for (i=0; i<8; i++)
|
|
88 {
|
|
89 if (p_cm->cm_reg & topbit)
|
|
90 p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
|
|
91 else
|
|
92 p_cm->cm_reg <<= 1;
|
|
93 p_cm->cm_reg &= widmask(p_cm);
|
|
94 }
|
|
95 }
|
|
96
|
|
97 /******************************************************************************/
|
|
98
|
|
99 void cm_blk (p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len)
|
|
100 {
|
|
101 while (blk_len--) cm_nxt(p_cm,*blk_adr++);
|
|
102 }
|
|
103
|
|
104 /******************************************************************************/
|
|
105
|
|
106 ulong cm_crc (p_cm_t p_cm)
|
|
107 {
|
|
108 if (p_cm->cm_refot)
|
|
109 return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width);
|
|
110 else
|
|
111 return p_cm->cm_xorot ^ p_cm->cm_reg;
|
|
112 }
|
|
113
|
|
114 /******************************************************************************/
|
|
115
|
|
116 ulong cm_tab (p_cm_t p_cm, int index)
|
|
117 {
|
|
118 int i;
|
|
119 ulong r;
|
|
120 ulong topbit = BITMASK(p_cm->cm_width-1);
|
|
121 ulong inbyte = (ulong) index;
|
|
122
|
|
123 if (p_cm->cm_refin) inbyte = reflect(inbyte,8);
|
|
124 r = inbyte << (p_cm->cm_width-8);
|
|
125 for (i=0; i<8; i++)
|
|
126 if (r & topbit)
|
|
127 r = (r << 1) ^ p_cm->cm_poly;
|
|
128 else
|
|
129 r<<=1;
|
|
130 if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width);
|
|
131 return r & widmask(p_cm);
|
|
132 }
|
|
133
|
|
134 /******************************************************************************/
|
|
135 /* End of crcmodel.c */
|
|
136 /******************************************************************************/
|
|
137
|