crcmodel.c
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:5k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  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      */
  23. /* echoed 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. #include "crcmodel.h"
  30. /****************************************************************************/
  31. /* The following definitions make the code more readable.                   */
  32. #define BITMASK(X) (1L << (X))
  33. #define MASK32 0xFFFFFFFFL
  34. #define LOCAL static
  35. /****************************************************************************/
  36. LOCAL ulong reflect P_((ulong v,int b));
  37. LOCAL ulong reflect (v,b)
  38. /* Returns the value v with the bottom b [0,32] bits reflected. */
  39. /* Example: reflect(0x3e23L,3) == 0x3e26                        */
  40. ulong v;
  41. int   b;
  42. {
  43.  int   i;
  44.  ulong t = v;
  45.  for (i=0; i<b; i++)
  46.    {
  47.     if (t & 1L)
  48.        v|=  BITMASK((b-1)-i);
  49.     else
  50.        v&= ~BITMASK((b-1)-i);
  51.     t>>=1;
  52.    }
  53.  return v;
  54. }
  55. /****************************************************************************/
  56. LOCAL ulong widmask P_((p_cm_t));
  57. LOCAL ulong widmask (p_cm)
  58. /* Returns a longword whose value is (2^p_cm->cm_width)-1.     */
  59. /* The trick is to do this portably (e.g. without doing <<32). */
  60. p_cm_t p_cm;
  61. {
  62.  return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L;
  63. }
  64. /****************************************************************************/
  65. void cm_ini (p_cm)
  66. p_cm_t p_cm;
  67. {
  68.  p_cm->cm_reg = p_cm->cm_init;
  69. }
  70. /****************************************************************************/
  71. void cm_nxt (p_cm,ch)
  72. p_cm_t p_cm;
  73. int    ch;
  74. {
  75.  int   i;
  76.  ulong uch  = (ulong) ch;
  77.  ulong topbit = BITMASK(p_cm->cm_width-1);
  78.  if (p_cm->cm_refin) uch = reflect(uch,8);
  79.  p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
  80.  for (i=0; i<8; i++)
  81.    {
  82.     if (p_cm->cm_reg & topbit)
  83.        p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
  84.     else
  85.        p_cm->cm_reg <<= 1;
  86.     p_cm->cm_reg &= widmask(p_cm);
  87.    }
  88. }
  89. /****************************************************************************/
  90. void cm_blk (p_cm,blk_adr,blk_len)
  91. p_cm_t   p_cm;
  92. p_ubyte_ blk_adr;
  93. ulong    blk_len;
  94. {
  95.  while (blk_len--) cm_nxt(p_cm,*blk_adr++);
  96. }
  97. /****************************************************************************/
  98. ulong cm_crc (p_cm)
  99. p_cm_t p_cm;
  100. {
  101.  if (p_cm->cm_refot)
  102.     return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width);
  103.  else
  104.     return p_cm->cm_xorot ^ p_cm->cm_reg;
  105. }
  106. /****************************************************************************/
  107. ulong cm_tab (p_cm,index)
  108. p_cm_t p_cm;
  109. int    index;
  110. {
  111.  int   i;
  112.  ulong r;
  113.  ulong topbit = BITMASK(p_cm->cm_width-1);
  114.  ulong inbyte = (ulong) index;
  115.  if (p_cm->cm_refin) inbyte = reflect(inbyte,8);
  116.  r = inbyte << (p_cm->cm_width-8);
  117.  for (i=0; i<8; i++)
  118.     if (r & topbit)
  119.        r = (r << 1) ^ p_cm->cm_poly;
  120.     else
  121.        r<<=1;
  122.  if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width);
  123.  return r & widmask(p_cm);
  124. }
  125. /****************************************************************************/
  126. /*                             End of crcmodel.c                            */
  127. /****************************************************************************/