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