📄 doc_ecc.c
字号:
/*---------------------------------------------------------------------*/
/* DiskOnchip 2000 & Millenium - Boot Developers Kit */
/*---------------------------------------------------------------------*/
/*
* $Log: V:/Flite/archives/BDK/doc_ecc.c_V $
*
* Rev 1.2 22 Dec 1999 13:26:52 dimitrys
* Fix Error only in Data Area (first 512 bytes)
*
* Rev 1.1 22 Dec 1999 13:24:20 dimitrys
* Added Copyright warning and #ifdef EDC_MODE
*/
/*---------------------------------------------------------------------*/
/* Copyright 1999, M-Systems Flash Disk Pioneers. */
/* ALL RIGHTS RESERVED */
/* */
/* Permission is hereby granted to licensees of M-Systems */
/* products to use or abstract this computer program for the */
/* sole purpose of implementing a product based on M-Systems */
/* products. No other rights to reproduce, use or disseminate */
/* this computer program, whether in part or in whole, are granted. */
/* M-systems makes no representation or warranties with respect */
/* to the performance of this computer program, and specifically */
/* disclaims any responsibility for any damages, special or */
/* consequential, connected with the use of this program. */
/*---------------------------------------------------------------------*/
#include "doc_api.h"
#include "doc_def.h"
#include "doc_ecc.h"
#ifdef EDC_MODE
#define T 2 /* Number of recoverable errors */
#define SYND_LEN (T*2) /* length of syndrom vector */
#define K512 (((512+1)*8+6)/10) /* number of inf symbols for record
of 512 bytes (K512=411) */
#define N512 (K512 + SYND_LEN) /* code word length for record of 512 bytes */
#define INIT_DEG 510
#define MOD 1023
static short gfi(short val);
static short gfmul( short f, short s );
static short gfdiv( short f, short s );
static short flog(short val);
static short alog(short val);
/*------------------------------------------------------------------------------*/
/* Function Name: RTLeightToTen */
/* Purpose......: convert an array of five 8-bit values into an array of */
/* four 10-bit values, from right to left. */
/* Returns......: Nothing */
/*------------------------------------------------------------------------------*/
static void RTLeightToTen(char *reg8, unsigned short reg10[])
{
reg10[0] = (reg8[0] & 0xFF) | ((reg8[1] & 0x03) << 8);
reg10[1] = ((reg8[1] & 0xFC) >> 2) | ((reg8[2] & 0x0F) << 6);
reg10[2] = ((reg8[2] & 0xF0) >> 4) | ((reg8[3] & 0x3F) << 4);
reg10[3] = ((reg8[3] & 0xC0) >> 6) | ((reg8[4] & 0xFF) << 2);
}
/*----------------------------------------------------------------------------*/
static void unpack( short word1, short length, short vector[] )
/* */
/* Function unpacks word into vector */
/* */
/* Parameters: */
/* word - word to be unpacked */
/* vector - array to be filled */
/* length - number of bits in word */
{
short i, *ptr;
ptr = vector + length - 1;
for( i = 0; i < length; i++ )
{
*ptr-- = word1 & 1;
word1 >>= 1;
}
}
/*----------------------------------------------------------------------------*/
static short pack( short *vector, short length )
/* */
/* Function packs vector into word */
/* */
/* Parameters: */
/* vector - array to be packed */
/* length - number of bits in word */
{
short tmp, i;
vector += length - 1;
tmp = 0;
i = 1;
while( length-- > 0 )
{
if( *vector-- )
tmp |= i;
i <<= 1;
}
return( tmp );
}
/*----------------------------------------------------------------------------*/
static short gfi( short val) /* GF inverse */
{
return alog((short)(MOD-flog(val)));
}
/*----------------------------------------------------------------------------*/
static short gfmul( short f, short s ) /* GF multiplication */
{
short i;
if( f==0 || s==0 )
return 0;
else
{
i = flog(f) + flog(s);
if( i > MOD ) i -= MOD;
return( alog(i) );
}
}
/*----------------------------------------------------------------------------*/
static short gfdiv( short f, short s ) /* GF division */
{
return gfmul(f,gfi(s));
}
/*----------------------------------------------------------------------------*/
static void residue_to_syndrom( short reg[], short realsynd[] )
{
short i,l,alpha,x,s,x4;
short deg,deg4;
for(i=0,deg=INIT_DEG;i<SYND_LEN;i++,deg++)
{
s = reg[0];
alpha = x = alog(deg);
deg4 = deg+deg;
if( deg4 >= MOD ) deg4 -= MOD;
deg4 += deg4;
if( deg4 >= MOD ) deg4 -= MOD;
x4 = alog(deg4);
for(l=1;l<SYND_LEN;l++)
{
s ^= gfmul( reg[l], x );
x = gfmul( alpha, x );
}
realsynd[i] = gfdiv( s, x4 );
}
}
/*----------------------------------------------------------------------------*/
static short alog(short i)
{
short j=0, val=1;
for( ; j < i ; j++ )
{
val <<= 1 ;
if ( val > 0x3FF )
{
if ( val & 8 ) val -= (0x400+7);
else val -= (0x400-9);
}
}
return val ;
}
static short flog(short val)
{
short j, val1;
if (val == 0)
return (short)0xFFFF;
j=0;
val1=1;
for( ; j <= MOD ; j++ )
{
if (val1 == val)
return j;
val1 <<= 1 ;
if ( val1 > 0x3FF )
{
if ( val1 & 8 ) val1 -= (0x400+7);
else val1 -= (0x400-9);
}
}
return 0;
}
/*----------------------------------------------------------------------------*/
static short convert_to_byte_patterns( short *locators, short *values,
short noferr, short *blocs, short *bvals )
{
static short mask[] = { 0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
short i,j,n, n0, n1, tmp;
short n_bit, n_byte, k_bit, nb;
for( i = 0, nb = 0; i< noferr; i++)
{
n = locators[i];
tmp = values[i];
n_bit = n *10 - 6 ;
n_byte = n_bit >> 3;
k_bit = n_bit - (n_byte<<3);
n_byte++;
if( k_bit == 7 )
{
/* 3 corrupted bytes */
blocs[nb] = n_byte+1;
bvals[nb++] = tmp & 1 ? 0x80 : 0;
tmp >>= 1;
blocs[nb] = n_byte;
bvals[nb++] = tmp & 0xff;
tmp >>= 8;
bvals[nb++] = tmp & 0xff;
}
else
{
n0 = 8 - k_bit;
n1 = 10 - n0;
blocs[nb] = n_byte;
bvals[nb++] = (tmp & mask[n1]) << (8 - n1);
tmp >>= n1;
blocs[nb] = n_byte - 1;
bvals[nb++] = (tmp & mask[n0]);
}
}
for( i = 0, j = -1; i < nb; i++ )
{
if( bvals[i] == 0 ) continue;
if( (blocs[i] == blocs[j]) && ( j>= 0 ) )
{
bvals[j] |= bvals[i];
}
else
{
j++;
blocs[j] = blocs[i];
bvals[j] = bvals[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -