reedsol.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:25k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* HOOK. Fixed comments; otherwise impossible to compile */
  2. /*
  3.  * $Log:   P:/user/amir/lite/vcs/reedsol.c_v  $
  4.  * 
  5.  *    Rev 1.8   10 Sep 1997 16:29:44   danig
  6.  * Got rid of generic names
  7.  * 
  8.  *    Rev 1.7   19 Aug 1997 20:08:16   danig
  9.  * Andray's changes
  10.  *
  11.  *    Rev 1.6   07 Jul 1997 15:22:36   amirban
  12.  * Ver 2.0
  13.  *
  14.  *    Rev 1.5   29 May 1997 15:04:52   amirban
  15.  * More comments
  16.  *
  17.  *    Rev 1.4   27 May 1997 11:10:12   danig
  18.  * Changed far to FAR1 & log() to flog()
  19.  *
  20.  *    Rev 1.3   25 May 1997 19:16:38   danig
  21.  * Comments
  22.  *
  23.  *    Rev 1.2   25 May 1997 16:42:34   amirban
  24.  * Up-to-date
  25.  *
  26.  *    Rev 1.1   18 May 1997 17:56:36   danig
  27.  * Changed NO_ERROR to NO_EDC_ERROR
  28.  *
  29.  *    Rev 1.0   08 Apr 1997 18:35:32   danig
  30.  * Initial revision.
  31.  */
  32. /************************************************************************/
  33. /*                                                                      */
  34. /* FAT-FTL Lite Software Development Kit */
  35. /* Copyright (C) M-Systems Ltd. 1995-1997 */
  36. /* */
  37. /************************************************************************/
  38. #include "reedsol.h"
  39. #define T 2  /* Number of recoverable errors */
  40. #define SYND_LEN (T*2)           /* length of syndrom vector */
  41. #define K512  (((512+1)*8+6)/10) /* number of inf symbols for record
  42.     of 512 bytes (K512=411) */
  43. #define N512  (K512 + SYND_LEN)  /* code word length for record of 512 bytes */
  44. #define INIT_DEG 510
  45. #define MOD 1023
  46. static short  gfi(short val);
  47. static short  gfmul( short f, short s );
  48. static short  gfdiv( short f, short s );
  49. static short  flog(short val);
  50. static short  alog(short val);
  51. /*------------------------------------------------------------------------------*/
  52. /* Function Name: RTLeightToTen                                                 */
  53. /* Purpose......: convert an array of five 8-bit values into an array of        */
  54. /*                four 10-bit values, from right to left.                       */
  55. /* Returns......: Nothing                                                       */
  56. /*------------------------------------------------------------------------------*/
  57. static void RTLeightToTen(char *reg8, unsigned short reg10[])
  58. {
  59. reg10[0] =  (reg8[0] & 0xFF)       | ((reg8[1] & 0x03) << 8);
  60. reg10[1] = ((reg8[1] & 0xFC) >> 2) | ((reg8[2] & 0x0F) << 6);
  61. reg10[2] = ((reg8[2] & 0xF0) >> 4) | ((reg8[3] & 0x3F) << 4);
  62. reg10[3] = ((reg8[3] & 0xC0) >> 6) | ((reg8[4] & 0xFF) << 2);
  63. }
  64. #ifdef EDC_IN_SOFTWARE
  65. /*----------------------------------------------------------------------------*/
  66. /* Function Name: RTLtenToEight                                               */
  67. /* Purpose......: convert an array of four 10-bit values into an array of     */
  68. /*                five 8-bit values, from right to left.                      */
  69. /* Returns......: Nothing                                                     */
  70. /*----------------------------------------------------------------------------*/
  71. static void RTLtenToEight(unsigned short reg10[], char reg8[])
  72. {
  73. reg8[0] =                                reg10[0] & 0x00FF;
  74. reg8[1] = ((reg10[0] & 0x0300) >> 8) | ((reg10[1] & 0x003F) << 2);
  75. reg8[2] = ((reg10[1] & 0x03C0) >> 6) | ((reg10[2] & 0x000F) << 4);
  76. reg8[3] = ((reg10[2] & 0x03F0) >> 4) | ((reg10[3] & 0x0003) << 6);
  77. reg8[4] =  (reg10[3] & 0x03FC) >> 2;
  78. }
  79. /*----------------------------------------------------------------------------*/
  80. /* Function Name: LTReightToTen                                               */
  81. /* Purpose......: convert an array of five 8-bit values into an array of      */
  82. /*                four 10-bit values, from left to right.                     */
  83. /* Returns......: Nothing                                                     */
  84. /*----------------------------------------------------------------------------*/
  85. static void LTReightToTen(char reg8[], unsigned short reg10[])
  86. {
  87. reg10[0] = ((reg8[0] & 0xFF) << 2) | ((reg8[1] & 0xC0) >> 6);
  88. reg10[1] = ((reg8[1] & 0x3F) << 4) | ((reg8[2] & 0xF0) >> 4);
  89. reg10[2] = ((reg8[2] & 0x0F) << 6) | ((reg8[3] & 0xFC) >> 2);
  90. reg10[3] = ((reg8[3] & 0x03) << 8) |  (reg8[4] & 0xFF);
  91. }
  92. /*----------------------------------------------------------------------------*/
  93. /* Function Name: LTRtenToEight                                               */
  94. /* Purpose......: convert an array of four 10-bit values into an array of     */
  95. /*                five 8-bit values, from left to right.                      */
  96. /* Returns......: Nothing                                                     */
  97. /*----------------------------------------------------------------------------*/
  98. static void LTRtenToEight(unsigned short reg10[], char reg8[])
  99. {
  100. reg8[0]   =                             (reg10[0] & 0x03FC) >> 2;
  101. reg8[1] = ((reg10[0] & 0x0003) << 6) | ((reg10[1] & 0x03F0) >> 4);
  102. reg8[2] = ((reg10[1] & 0x000F) << 4) | ((reg10[2] & 0x03C0) >> 6);
  103. reg8[3] = ((reg10[2] & 0x003F) << 2) | ((reg10[3] & 0x0300) >> 8);
  104. reg8[4] =  (reg10[3] & 0x00FF);
  105. }
  106. /*----------------------------------------------------------------------------*/
  107. /* Function Name: LTRarrayEightToTen                                          */
  108. /* Purpose......: convert an array of 512 8-bit values into an array of       */
  109. /*                415 10-bit values (from left to right). The 6 msb on the    */
  110. /*                first 10-bit value are zero, an so are the 8 lsb on the     */
  111. /*                411'th 10-bit value. The last four 10-bit values are zeroed.*/
  112. /* Returns......: Nothing                                                     */
  113. /*----------------------------------------------------------------------------*/
  114. static void LTRarrayEightToTen(char FAR1 *reg8, unsigned short *reg10)
  115. {
  116.   short i8;                               /* Index in the 8-bit array */
  117.   short i10;                              /* Index in the 10-bit array */
  118.   short j;
  119.   /* Create the first three 10-bit values */
  120.   /* (the six msb on the first 10-bit */
  121.   /* value are zeroes): */
  122. reg10[0] =                            (reg8[0] & 0xF0) >> 4;
  123. reg10[1] = ((reg8[0] & 0x0F) << 6) | ((reg8[1] & 0xFC) >> 2);
  124. reg10[2] = ((reg8[1] & 0x03) << 8) |  (reg8[2] & 0xFF);
  125.   /* Create the next 101 quadruples of */
  126.   /* 10-bit values: */
  127. for(i10=3, i8=3; i10 < (4*101)+3; i10+=4, i8+=5)
  128. {
  129. reg10[i10]   = ((reg8[i8]   & 0xFF) << 2) | ((reg8[i8+1] & 0xC0) >> 6);
  130. reg10[i10+1] = ((reg8[i8+1] & 0x3F) << 4) | ((reg8[i8+2] & 0xF0) >> 4);
  131. reg10[i10+2] = ((reg8[i8+2] & 0x0F) << 6) | ((reg8[i8+3] & 0xFC) >> 2);
  132. reg10[i10+3] = ((reg8[i8+3] & 0x03) << 8) |  (reg8[i8+4] & 0xFF);
  133. }
  134.   /* Create the last quadruple of 10-bit */
  135.   /* values. The the 8 lsb of the */
  136.   /* last 10-bit value are zeroed: */
  137. reg10[i10]   = ((reg8[i8]   & 0xFF) << 2) | ((reg8[i8+1] & 0xC0) >> 6);
  138. reg10[i10+1] = ((reg8[i8+1] & 0x3F) << 4) | ((reg8[i8+2] & 0xF0) >> 4);
  139. reg10[i10+2] = ((reg8[i8+2] & 0x0F) << 6) | ((reg8[i8+3] & 0xFC) >> 2);
  140. reg10[i10+3] =  (reg8[i8+3] & 0x03) << 8;
  141. /* Zero the last four 10-bit values: */
  142.   i10+=4;
  143.   for(j=i10; j<(i10+4); j++)
  144.     reg10[j] = 0;
  145. }
  146. /*----------------------------------------------------------------------------*/
  147. /* Function Name: resolveParity                                               */
  148. /* Purpose......: find the parity byte for an array of bytes.                 */
  149. /* Returns......: The parity byte                                             */
  150. /*----------------------------------------------------------------------------*/
  151. static char resolveParity(char FAR1 *block, short len)
  152. {
  153.   char par=0;
  154.   short i;
  155.   for(i=0; i<len; i++)
  156.     par ^= block[i];
  157.   return par;
  158. }
  159. #endif   /* EDC_IN_SOFTWARE */
  160. /*----------------------------------------------------------------------------*/
  161. static void unpack( short word, short length, short vector[] )
  162. /*                                                                            */
  163. /*   Function unpacks word into vector                                        */
  164. /*                                                                            */
  165. /*   Parameters:                                                              */
  166. /*     word   - word to be unpacked                                           */
  167. /*     vector - array to be filled                                            */
  168. /*     length - number of bits in word                                        */
  169. {
  170.   short i, *ptr;
  171.   ptr = vector + length - 1;
  172.   for( i = 0; i < length; i++ )
  173.   {
  174.     *ptr-- = word & 1;
  175.     word >>= 1;
  176.   }
  177. }
  178. /*----------------------------------------------------------------------------*/
  179. static short pack( short *vector, short length )
  180. /*                                                                            */
  181. /*   Function packs vector into word                                          */
  182. /*                                                                            */
  183. /*   Parameters:                                                              */
  184. /*     vector - array to be packed                                            */
  185. /*     length - number of bits in word                                        */
  186. {
  187.   short tmp, i;
  188.   vector += length - 1;
  189.   tmp = 0;
  190.   i = 1;
  191.   while( length-- > 0 )
  192.   {
  193.     if( *vector-- )
  194.       tmp |= i;
  195.     i <<= 1;
  196.   }
  197.   return( tmp );
  198. }
  199. /*----------------------------------------------------------------------------*/
  200. static short gfi( short val) /* GF inverse */
  201. {
  202.   return alog(MOD-flog(val));
  203. }
  204. /*----------------------------------------------------------------------------*/
  205. static short gfmul( short f, short s ) /* GF multiplication */
  206. {
  207.   short i;
  208.   if( f==0 || s==0 )
  209.      return 0;
  210.   else
  211.   {
  212.     i = flog(f) + flog(s);
  213.     if( i > MOD ) i -= MOD;
  214.     return( alog(i) );
  215.   }
  216. }
  217. /*----------------------------------------------------------------------------*/
  218. static short gfdiv( short f, short s ) /* GF division */
  219. {
  220.   return gfmul(f,gfi(s));
  221. }
  222. #ifdef EDC_IN_SOFTWARE
  223. /*----------------------------------------------------------------------------*/
  224. static void register_division( short reg[], short input[], short len )
  225. /*                                                                            */
  226. /*  Function emulates hardware division by generator polynom                  */
  227. /*                                                                            */
  228. /*  Parameters:                                                               */
  229. /*    reg   - hardware register with feedback                                 */
  230. /*    input - input sequence ( devidend )                                     */
  231. /*    len   - number of steps for division procedure                          */
  232. {
  233.   short i, j, feedback, tmp0, tmp1, tmp4;
  234. for( i = 0; i < SYND_LEN; i++ )  reg[i] = 0x03ff;
  235. for( i = 0; i < len; i++ )
  236. {
  237. tmp4 = reg[0] ^ input[i];
  238. if( tmp4 == 0 )
  239. {
  240. reg[0] = reg[1];
  241. reg[1] = reg[2];
  242. reg[2] = reg[3];
  243. reg[3] = 0;
  244. }
  245. else
  246. {
  247.       feedback = flog(tmp4);
  248. if( (j = feedback + 741) >= MOD )
  249.       j -= MOD;
  250.       tmp0 = alog(j);
  251. if( (j = feedback +  85) >= MOD )
  252. j -= MOD;
  253.       tmp1 = alog(j);
  254. reg[0] = reg[1] ^ tmp0;
  255. reg[1] = reg[2] ^ tmp1;
  256. reg[2] = reg[3] ^ tmp0;
  257. reg[3] = tmp4;
  258. }
  259. }
  260. }
  261. #endif  /* EDC_IN_SOFTWARE */
  262. /*----------------------------------------------------------------------------*/
  263. static void residue_to_syndrom( short reg[], short realsynd[] )
  264. {
  265.    short i,l,alpha,x,s,x4;
  266.    short deg,deg4;
  267.    for(i=0,deg=INIT_DEG;i<SYND_LEN;i++,deg++)
  268.    {
  269.       s = reg[0];
  270.       alpha = x = alog(deg);
  271.       deg4 = deg+deg;
  272.       if( deg4 >= MOD ) deg4 -= MOD;
  273.       deg4 += deg4;
  274.       if( deg4 >= MOD ) deg4 -= MOD;
  275.       x4 = alog(deg4);
  276.       for(l=1;l<SYND_LEN;l++)
  277.       {
  278. s ^= gfmul( reg[l], x );
  279. x  = gfmul( alpha, x );
  280.       }
  281.       realsynd[i] = gfdiv( s, x4 );
  282.    }
  283. }
  284. /*----------------------------------------------------------------------------*/
  285. static short alog(short i)
  286. {
  287.   short j=0, val=1;
  288.   for( ; j < i ; j++ )
  289.   {
  290.     val <<= 1 ;
  291.     if ( val > 0x3FF )
  292.     {
  293.       if ( val & 8 )   val -= (0x400+7);
  294.       else             val -= (0x400-9);
  295.     }
  296.   }
  297.   return val ;
  298. }
  299. static short flog(short val)
  300. {
  301.   short j, val1;
  302.   if (val == 0)
  303.     return (short)0xFFFF;
  304.   j=0;
  305.   val1=1;
  306.   for( ; j <= MOD ; j++ )
  307.   {
  308.     if (val1 == val)
  309.       return j;
  310.     val1 <<= 1 ;
  311.     if ( val1 > 0x3FF )
  312.     {
  313.       if ( val1 & 8 )   val1 -= (0x400+7);
  314.       else              val1 -= (0x400-9);
  315.     }
  316.   }
  317.   return 0;
  318. }
  319. #ifdef EDC_IN_SOFTWARE
  320. static short packed_symbol[415];/* RS code word packed bit in bit */
  321. /*----------------------------------------------------------------------------*/
  322. /* Function Name: encodeEDC                                                   */
  323. /* Purpose......: Encode 512 bytes of data, given in block[].                 */
  324. /*                Upon returning code[] will contain the EDC code as          */
  325. /*                5 bytes, and one parity byte.                               */
  326. /* Returns......: Nothing                                                     */
  327. /*----------------------------------------------------------------------------*/
  328. static void encodeEDC(char FAR1 *block, char code[6])
  329. {
  330.   short reg[SYND_LEN];         /* register for main division procedure */
  331. /* Convert block[] into a 10-bit values */
  332. /* array: */
  333.   LTRarrayEightToTen(block, (unsigned short *)packed_symbol);
  334. /* Calculate the parity value of the 512 */
  335. /* bytes array, and store it in the 8 */
  336. /* lsb of the 410'th 10-bit value: */
  337.   packed_symbol[410] |= (resolveParity(block, 512) & 0xFF);
  338. /* Calculate the EDC code: */
  339. register_division(reg, packed_symbol, K512);
  340. /* Convert the EDC code from four */
  341. /* 10-bit values, into five bytes: */
  342.   LTRtenToEight((unsigned short *)reg, code);
  343. /* Store the parity byte in the last */
  344. /* element of code[]: */
  345.   code[5] = (char)(packed_symbol[410] & 0xFF);
  346. }
  347. /*------------------------------------------------------------------------------*/
  348. /* Function Name: flCalcEDCSyndrom                                              */
  349. /* Purpose......: Trys to detect errors.                                        */
  350. /*                block[] should contain 512 bytes of data.                     */
  351. /*                code[] should contain the EDC code as 5 bytes, and one        */
  352. /*                parity byte (identical to the output of EDCencode::resolve()).*/
  353. /*                Upon returning errorSyndrom[] will contain the syndrom as     */
  354. /*                5 bytes and one       parity byte (identical to the input of  */
  355. /*                EDCdecode::resolve()).                                        */
  356. /* Returns......: The error status.                                             */
  357. /*                NOTE! If the error status is NO_EDC_ERROR upon return, ignore */
  358. /*                      the value of the arguments.                             */
  359. /*------------------------------------------------------------------------------*/
  360. EDCstatus flCalcEDCSyndrom(char FAR1 *block, char code[6], char errorSyndrom[6])
  361. {
  362.   short nonZero, i;
  363.   short residue[SYND_LEN];
  364.   short reg[SYND_LEN];         /* register for main division procedure */
  365. /* Convert block[] into a 10-bit values */
  366. /* array: */
  367.   LTRarrayEightToTen(block, (unsigned short *)packed_symbol);
  368.   packed_symbol[410] |= code[5] & 0xFF; /* Copy the parity value from code[] */
  369. /* into the 8 lsb of the 410'th */
  370. /* 10-bit value */
  371. /* Copy the EDC code into the last four */
  372. /* 10-bit values of packed_symbol: */
  373.   LTReightToTen(code, (unsigned short *)&packed_symbol[411]);
  374. /* Calculate the syndrom (the result */
  375. /* is in reg[]): */
  376.   register_division( reg, packed_symbol, N512 );
  377.   for(i=nonZero=0; i<SYND_LEN; i++)     /* Chack if reg[] is all zeroes */
  378.     if(reg[i])
  379.       nonZero++;
  380.   if(nonZero == 0)                      /* If reg[] is all zeroes, there is */
  381.   {                                     /* no error */
  382.     return NO_EDC_ERROR;                /* No error found */
  383.   }
  384.   for( i = 0; i < SYND_LEN; i++ )       /* reverse the order of reg[] */
  385.     residue[SYND_LEN-1-i] = reg[ i ];   /* into residue[] */
  386. /* Convert the syndrom (in residue[]) */
  387. /* from four 10-bit values into five */
  388. /* bytes: */
  389.   RTLtenToEight((unsigned short *)residue, errorSyndrom);
  390. /* Calculate the parity byte for the */
  391. /* original 512 bytes plus the parity */
  392. /* byte that was received in code[]: */
  393.   errorSyndrom[5] = resolveParity(block, 512) ^ (code[5] & 0xFF);
  394.   return EDC_ERROR;                     /* An error was detected */
  395. }
  396. #endif  /* EDC_IN_SOFTWARE */
  397. /*----------------------------------------------------------------------------*/
  398. static short convert_to_byte_patterns( short *locators, short *values,
  399. short noferr, short *blocs, short *bvals )
  400. {
  401.   static short mask[] = { 0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
  402.   short i,j,n, n0, n1, tmp;
  403.   short n_bit, n_byte, k_bit, nb;
  404.   for( i = 0, nb = 0; i< noferr; i++)
  405.   {
  406.     n = locators[i];
  407.     tmp = values[i];
  408.     n_bit = n *10 - 6 ;
  409.     n_byte = n_bit >> 3;
  410.     k_bit  = n_bit - (n_byte<<3);
  411.     n_byte++;
  412.     if( k_bit == 7 )
  413.     {
  414.       /* 3 corrupted bytes */
  415.       blocs[nb] = n_byte+1;
  416.       bvals[nb++] = tmp & 1 ? 0x80 : 0;
  417.       tmp >>= 1;
  418.       blocs[nb] = n_byte;
  419.       bvals[nb++] = tmp & 0xff;
  420.       tmp >>= 8;
  421.       bvals[nb++] = tmp & 0xff;
  422.     }
  423.     else
  424.     {
  425.       n0 = 8 - k_bit;
  426.       n1 = 10 - n0;
  427.       blocs[nb] = n_byte;
  428.       bvals[nb++] = (tmp & mask[n1]) << (8 - n1);
  429.       tmp >>= n1;
  430.       blocs[nb] = n_byte - 1;
  431.       bvals[nb++] = (tmp & mask[n0]);
  432.     }
  433.   }
  434.   for( i = 0, j = -1; i < nb; i++ )
  435.   {
  436.     if( bvals[i] == 0 ) continue;
  437.     if( (blocs[i] == blocs[j]) && ( j>= 0 ) )
  438.     {
  439.       bvals[j] |= bvals[i];
  440.     }
  441.     else
  442.     {
  443.       j++;
  444.       blocs[j] = blocs[i];
  445.       bvals[j] = bvals[i];
  446.     }
  447.   }
  448.   return j+1;
  449. }
  450. /*----------------------------------------------------------------------------*/
  451. static short deg512( short x )
  452. {
  453.   short i;
  454.   short l,m;
  455.   l = flog(x);
  456.   for( i=0;i<9;i++)
  457.   {
  458.     m = 0;
  459.     if( (l & 0x200) )
  460.       m = 1;
  461.     l =  ( ( l << 1 ) & 0x3FF  ) | m;
  462.   }
  463.   return alog(l);
  464. }
  465. /*----------------------------------------------------------------------------*/
  466. static short decoder_for_2_errors( short s[], short lerr[], short verr[] )
  467. {
  468.   /* decoder for correcting up to 2 errors */
  469.   short i,j,k,temp,delta;
  470.   short ind, x1, x2;
  471.   short r1, r2, r3, j1, j2;
  472.   short sigma1, sigma2;
  473.   short xu[10], ku[10];
  474.   short yd, yn;
  475.   ind = 0;
  476.   for(i=0;i<SYND_LEN;i++)
  477.     if( s[i] != 0 )
  478.       ind++;                /* ind = number of nonzero syndrom symbols */
  479.   if( ind == 0 ) return 0;  /* no errors */
  480.   if( ind < 4 )
  481.     goto two_or_more_errors;
  482. /* checking s1/s0 = s2/s1 = s3/s2 = alpha**j for some j */
  483.   r1 = gfdiv( s[1], s[0] );
  484.   r2 = gfdiv( s[2], s[1] );
  485.   r3 = gfdiv( s[3], s[2] );
  486.   if( r1 != r2 || r2 != r3)
  487.     goto two_or_more_errors;
  488.   j = flog(r1);
  489.   if( j > 414 )
  490.     goto two_or_more_errors;
  491.   lerr[0] = j;
  492. /*  pattern = (s0/s1)**(510+1) * s1
  493.   or
  494.     pattern = (s0/s1)**(512 - 1 )  * s1 */
  495.   temp = gfi( r1 );
  496.   {
  497.     int i;
  498.     for (i = 0; i < 9; i++)
  499.       temp = gfmul( temp, temp );  /* deg = 512 */
  500.   }
  501.   verr[0] = gfmul( gfmul(temp, r1), s[1] );
  502.   return 1;    /* 1 error */
  503. two_or_more_errors:
  504.   delta = gfmul( s[0], s[2] ) ^ gfmul( s[1], s[1] );
  505.   if( delta == 0 )
  506.     return -1;  /* uncorrectable error */
  507.   temp = gfmul( s[1], s[3] ) ^ gfmul( s[2], s[2] );
  508.   if( temp == 0 )
  509.     return -1;  /* uncorrectable error */
  510.   sigma2 = gfdiv( temp, delta );
  511.   temp = gfmul( s[1], s[2] ) ^ gfmul( s[0], s[3] );
  512.   if( temp == 0 )
  513.     return -1;  /* uncorrectable error */
  514.   sigma1 = gfdiv( temp, delta );
  515.   k = gfdiv( sigma2, gfmul( sigma1, sigma1 ) );
  516.   unpack( k, 10, ku );
  517.   if( ku[2] != 0 )
  518.     return -1;
  519.   xu[4] = ku[9];
  520.   xu[5] = ku[0] ^ ku[1];
  521.   xu[6] = ku[6] ^ ku[9];
  522.   xu[3] = ku[4] ^ ku[9];
  523.   xu[1] = ku[3] ^ ku[4] ^ ku[6];
  524.   xu[0] = ku[0] ^ xu[1];
  525.   xu[8] = ku[8] ^ xu[0];
  526.   xu[7] = ku[7] ^ xu[3] ^ xu[8];
  527.   xu[2] = ku[5] ^ xu[7] ^ xu[5] ^ xu[0];
  528.   xu[9] = 0;
  529.   x1 = pack( xu, 10 );
  530.   x2 = x1 | 1;
  531.   x1 = gfmul( sigma1, x1 );
  532.   x2 = gfmul( sigma1, x2 );
  533.   j1 = flog(x1);
  534.   j2 = flog(x2);
  535.   if( (j1 > 414) || (j2 > 414) )
  536.     return -1;
  537.   r1 = x1 ^ x2;
  538.   r2 = deg512( x1 );
  539.   temp = gfmul( x1, x1 );
  540.   r2 = gfdiv( r2, temp );
  541.   yd = gfmul( r2, r1 );
  542.   if( yd == 0 )
  543.     return -1;
  544.   yn = gfmul( s[0], x2 ) ^ s[1];
  545.   if( yn == 0 )
  546.     return -1;
  547.   verr[0] = gfdiv( yn, yd );
  548.   r2 = deg512( x2 );
  549.   temp = gfmul( x2, x2 );
  550.   r2 = gfdiv( r2, temp );
  551.   yd = gfmul( r2, r1 );
  552.   if( yd == 0 )
  553.     return -1;
  554.   yn = gfmul( s[0], x1 ) ^ s[1];
  555.   if( yn == 0 )
  556.     return -1;
  557.   verr[1] = gfdiv( yn, yd );
  558.   if( j1 > j2 ) {
  559.     lerr[0] = j2;
  560.     lerr[1] = j1;
  561.     temp = verr[0];
  562.     verr[0] = verr[1];
  563.     verr[1] = temp;
  564.   }
  565.   else
  566.   {
  567.     lerr[0] = j1;
  568.     lerr[1] = j2;
  569.   }
  570.   return 2;
  571. }
  572. /*------------------------------------------------------------------------------*/
  573. /* Function Name: flDecodeEDC                                                   */
  574. /* Purpose......: Trys to correct errors.                                       */
  575. /*                errorSyndrom[] should contain the syndrom as 5 bytes and one  */
  576. /*                parity byte. (identical to the output of calcEDCSyndrom()).   */
  577. /*                Upon returning, errorNum will contain the number of errors,   */
  578. /*                errorLocs[] will contain error locations, and                 */
  579. /*                errorVals[] will contain error values (to be XORed with the   */
  580. /*                data).                                                        */
  581. /*                Parity error is relevant only if there are other errors, and  */
  582. /*                the EDC code fails parity check.                              */
  583. /*                NOTE! Only the first errorNum indexes of the above two arrays */
  584. /*                      are relevant. The others contain garbage.               */
  585. /* Returns......: The error status.                                             */
  586. /*                NOTE! If the error status is NO_EDC_ERROR upon return, ignore */
  587. /*                      the value of the arguments.                             */
  588. /*------------------------------------------------------------------------------*/
  589. EDCstatus flDecodeEDC(char *errorSyndrom, char *errorsNum,
  590.     short errorLocs[3*T],  short errorVals[3*T])
  591. {
  592.   short noferr;                         /* number of errors */
  593.   short dec_parity;                     /* parity byte of decoded word */
  594.   short rec_parity;                     /* parity byte of received word */
  595.   short realsynd[SYND_LEN];             /* real syndrom calculated from residue */
  596.   short locators[T],                    /* error locators */
  597.   values[T];                            /* error values */
  598.   short reg[SYND_LEN];                  /* register for main division procedure */
  599.   int i;
  600.   RTLeightToTen(errorSyndrom, (unsigned short *)reg);
  601.   rec_parity = errorSyndrom[5] & 0xFF;  /* The parity byte */
  602.   residue_to_syndrom(reg, realsynd);
  603.   noferr = decoder_for_2_errors(realsynd, locators, values);
  604.   if(noferr == 0)
  605.     return NO_EDC_ERROR;                /* No error found */
  606.   if(noferr < 0)                        /* If an uncorrectable error was found */
  607.     return UNCORRECTABLE_ERROR;
  608.   for (i=0;i<noferr;i++)
  609.     locators[i] = N512 - 1 - locators[i];
  610.   *errorsNum = (char)convert_to_byte_patterns(locators, values, noferr, errorLocs, errorVals);
  611.   for(dec_parity=i=0; i < *errorsNum; i++)/* Calculate the parity for all the */
  612.   {                                       /*   errors found: */
  613.     if(errorLocs[i] <= 512)
  614.       dec_parity ^= errorVals[i];
  615.   }
  616.   if(dec_parity != rec_parity)
  617.     return UNCORRECTABLE_ERROR;         /* Parity error */
  618.   else
  619.     return CORRECTABLE_ERROR;
  620. }
  621. /*------------------------------------------------------------------------------*/
  622. /* Function Name: flCheckAndFixEDC                                              */
  623. /* Purpose......: Decodes the EDC syndrom and fixs the errors if possible.      */
  624. /*                block[] should contain 512 bytes of data.                     */
  625. /*                NOTE! Call this function only if errors where detected by     */
  626. /*                      syndCalc or by the ASIC module.                         */
  627. /* Returns......: The error status.                                             */
  628. /*------------------------------------------------------------------------------*/
  629. EDCstatus flCheckAndFixEDC(char FAR1 *block, char *syndrom, FLBoolean byteSwap)
  630. {
  631.   char errorsNum;
  632.   short errorLocs[3*T];
  633.   short errorVals[3*T];
  634.   EDCstatus status;
  635.   status = flDecodeEDC(syndrom, &errorsNum, errorLocs, errorVals);
  636.   if(status == CORRECTABLE_ERROR)       /* Fix the errors if possible */
  637.   {
  638.     int i;
  639.     for (i=0; i < errorsNum; i++)
  640.       block[errorLocs[i] ^ byteSwap] ^= errorVals[i];
  641.     return NO_EDC_ERROR;                /* All errors are fixed */
  642.   }
  643.   else
  644.     return status;                      /* Uncorrectable error */
  645. }