hamming31_26.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #include "logfsos.h"
  2. #include "logfs.h"
  3. #include "nandfs.h"
  4. static unsigned long row4 = 0x001fffc0;
  5. static unsigned long row3 = 0x0fe03fc0;
  6. static unsigned long row2 = 0x71e3c3c0;
  7. static unsigned long row1 = 0xb66cccc0;
  8. static unsigned long row0 = 0xdab55540;
  9. static char map[] = {
  10. -5, -4, 0, -3, 1, 2, 3, -2,
  11. 4, 5, 6, 7, 8, 9, 10, -1, 11,
  12. 12, 13, 14, 15, 16, 17, 18,
  13. 19, 20, 21, 22, 23, 24, 25,
  14. };
  15. #define mashbits(rown) \
  16. c = (in) & (rown); \
  17. c ^= c >> 16; \
  18. c ^= c >> 8; \
  19. c ^= c >> 4; \
  20. c ^= c >> 2; \
  21. c = (c ^ (c >> 1)) & 1; \
  22. static uchar
  23. _nandfshamming31_26calcparity(ulong in)
  24. {
  25. ulong c;
  26. uchar out;
  27. mashbits(row4); out = c;
  28. mashbits(row3); out = (out << 1) | c;
  29. mashbits(row2); out = (out << 1) | c;
  30. mashbits(row1); out = (out << 1) | c;
  31. mashbits(row0); out = (out << 1) | c;
  32. return out;
  33. }
  34. ulong
  35. _nandfshamming31_26calc(ulong in)
  36. {
  37. in &= 0xffffffc0;
  38. return in | _nandfshamming31_26calcparity(in);
  39. }
  40. int
  41. _nandfshamming31_26correct(ulong *in)
  42. {
  43. uchar eparity, parity;
  44. ulong e;
  45. eparity = _nandfshamming31_26calcparity(*in);
  46. parity = (*in) & 0x1f;
  47. e = eparity ^ parity;
  48. if (e == 0)
  49. return 0;
  50. e--;
  51. if (map[e] < 0)
  52. return 1; // error in parity bits
  53. e = map[e];
  54. *in ^= 1 << (31 - e);
  55. return 1;
  56. }