|
|
1.1 root 1: /************************************************************************/
2: /* Copyright (c) 1988, 1989 ARCHIVE Corporation */
3: /* This program is an unpublished work fully protected by the */
4: /* United States Copyright laws and is considered a trade secret */
5: /* belonging to Archive Corporation. */
6: /************************************************************************/
7: /* xl_dec.c ecc for xl.c */
8: /* */
9: /* 13JUL88 14:00 */
10: /* Unix port 05/14/1989 */
11: /************************************************************************/
12: /* file: xl_dec.c */
13: /************************************************************************/
14: #include <sys/coherent.h>
15: #include <sys/types.h>
16: #include <sys/xl.h>
17:
18: static unchar mpy(); /* declare functions */
19: static unchar dvd();
20: extern int xl_chk();
21:
22: extern unchar xl_log2[]; /* ecc tables */
23: extern unchar xl_alg2[];
24: extern unchar xl_mx02[];
25: extern unchar xl_mxc0[];
26: extern unchar xl_mxc3[];
27:
28: static fpchr pbfr; /* adr buffer */
29: static int nbfr; /* num of bfrs in block */
30:
31: static unchar s0, s1, s2; /* syndromes */
32: static int l0, l1, l2; /* locations */
33: static unchar L0, L1, L2; /* 2** locations */
34: static unchar M0, M1, M2; /* c3** locations */
35:
36: static unchar m00, m01, m02; /* inverse matrix */
37: static unchar m10, m11, m12;
38: static unchar m20, m21, m22;
39: static unchar det;
40:
41: static unchar n00, n01, n10, n11; /* 2nd inverse matrix */
42:
43: static unchar e0, e1, e2; /* error values */
44: static unchar c0, c1; /* check error values */
45:
46: /************************************************************************/
47: /* xl_dec correct a block */
48: /************************************************************************/
49: int
50: xl_dec( adr, nb, errc, err0, err1, err2 )
51: fpchr adr; /* adr of bfr */
52: unchar nb; /* # blocks in bfr */
53: unchar errc; /* error count */
54: unchar err0; /* location of errors */
55: unchar err1; /* location of errors */
56: unchar err2; /* location of errors */
57: {
58: fpchr p0;
59: int d0;
60: int i = 0;
61:
62: /* globalize inputs */
63: pbfr = adr;
64: nbfr = (int)nb;
65: l0 = (int)err0;
66: l1 = (int)err1;
67: l2 = (int)err2;
68: switch(errc){
69: case 0:
70: if( !xl_chk( adr, nb ) )
71: return( 1 );
72: return( fix0() );
73: case 1:
74: return( fix1() );
75: case 2:
76: return( fix2() );
77: case 3:
78: return( fix3() );
79: default:
80: break;
81: }
82: return( 0 );
83: }
84:
85: /************************************************************************/
86: /* 3 error case */
87: /************************************************************************/
88: /* */
89: /* syndrome equations */
90: /* */
91: /* | 1 1 1| |e0| |s0| */
92: /* |L0 L1 L2| |e1| = |s1| */
93: /* |M0 M1 M2| |e2| |s2| */
94: /* */
95: /* inversing matrix gives error equations */
96: /* */
97: /* |e0| |L1*M2+M1*L2 M1+M2 L1+L2| |s0| */
98: /* |e1| = |L0*M2+M0*M2 M0+M2 L0+L2| |s1| */
99: /* |e2| |L0*M1+M0*L1 M0+M1 L0+L1| |s2| */
100: /* ----------------------------------- */
101: /* L0*M1+L0*M2+L1*M0+L1*M2+L2*M0+L2*M1 */
102: /************************************************************************/
103:
104: static unchar ae, af, bd, bf, cd, ce; /* temps */
105: static unchar aebd, afcd, bfce;
106:
107: static
108: fix3() /* 3 error case */
109: {
110: fpchr p0;
111: int d0;
112: int d1;
113:
114: L0 = xl_alg2[ 31 - l0 ]; /* generate powers of 2 (Lx) */
115: M0 = xl_alg2[ 224 + l0 ]; /* and C3 (Mx) [ C3 = 1/2 ] */
116: L1 = xl_alg2[ 31 - l1 ];
117: M1 = xl_alg2[ 224 + l1 ];
118: L2 = xl_alg2[ 31 - l2 ];
119: M2 = xl_alg2[ 224 + l2 ];
120:
121: ae = mpy( L0, M1 ); /* generate inverse matrix */
122: af = mpy( L0, M2 );
123: bd = mpy( L1, M0 );
124: bf = mpy( L1, M2 );
125: cd = mpy( L2, M0 );
126: ce = mpy( L2, M1 );
127: aebd = ae ^ bd;
128: afcd = af ^ cd;
129: bfce = bf ^ ce;
130: det = aebd ^ afcd ^ bfce;
131: m00 = dvd( bfce, det );
132: m01 = dvd( M1 ^ M2, det );
133: m02 = dvd( L1 ^ L2, det );
134: m10 = dvd( afcd, det );
135: m11 = dvd( M0 ^ M2, det );
136: m12 = dvd( L0 ^ L2, det );
137: m20 = dvd( aebd, det );
138: m21 = dvd( M0 ^ M1, det );
139: m22 = dvd( L0 ^ L1, det );
140:
141: for ( d1 = 0; d1 < 1024; ++d1 ){
142: p0 = pbfr; /* generate syndromes */
143: s2 = s1 = s0 = 0;
144: for ( d0 = 0; d0 < nbfr; ++d0 ){
145: s0 ^= *p0;
146: s1 = xl_mx02[ s1 ] ^ *p0;
147: s2 = xl_mxc3[ s2 ] ^ *p0;
148: p0 += 1024;
149: }
150:
151: /* generate error values */
152: e0 = mpy( m00, s0 ) ^ mpy( m01, s1 ) ^ mpy( m02, s2 );
153: e1 = mpy( m10, s0 ) ^ mpy( m11, s1 ) ^ mpy( m12, s2 );
154: e2 = mpy( m20, s0 ) ^ mpy( m21, s1 ) ^ mpy( m22, s2 );
155:
156: /* correct errors */
157: *( pbfr + l0 * 1024 ) ^= e0;
158: *( pbfr + l1 * 1024 ) ^= e1;
159: *( pbfr + l2 * 1024 ) ^= e2;
160:
161: pbfr++;
162: /* bump to next column */
163: }
164: /* indicate ok */
165: return( 1 );
166: }
167:
168: /************************************************************************/
169: /* 2 error case */
170: /************************************************************************/
171: /* */
172: /* syndrome equations */
173: /* */
174: /* | 1 1| |e0| |s0| */
175: /* |L0 L1| |e1| = |s1| */
176: /* |M0 M1| |s2| */
177: /* */
178: /* using 2 of the 3 possible inverses: */
179: /* */
180: /* |e0| |L1 1| |s0| |M1 1| |s0| */
181: /* |e1| = |L0 1| |s1| = |M0 1| |s2| */
182: /* ------------- ------------- */
183: /* L0+L1 M0+M1 */
184: /************************************************************************/
185:
186: static
187: fix2()
188: {
189: fpchr p0;
190: int d0;
191: int d1;
192:
193: L0 = xl_alg2[ 31 - l0 ]; /* generate powers of 2 (Lx) & */
194: M0 = xl_alg2[ 224 + l0 ]; /* and C3 (Mx) [C3 = 1/2] */
195: L1 = xl_alg2[ 31 - l1 ];
196: M1 = xl_alg2[ 224 + l1 ];
197:
198: det = L0 ^ L1; /* generate inverse matrix */
199: m00 = dvd( L1, det );
200: m01 = dvd( 1, det );
201: m10 = dvd( L0, det );
202: m11 = m01;
203:
204: det = M0 ^ M1; /* generate check inv matrix */
205: n00 = dvd( M1, det );
206: n01 = dvd( 1, det );
207: n10 = dvd( M0, det );
208: n11 = n01;
209:
210: for( d1 = 0; d1 < 1024; ++d1 ){
211: /* generate syndromes */
212: p0 = pbfr;
213: s2 = s1 = s0 = 0;
214: for( d0 = 0; d0 < nbfr; ++d0 ){
215: s0 ^= *p0;
216: s1 = xl_mx02[ s1 ] ^ *p0;
217: s2 = xl_mxc3[ s2 ] ^ *p0;
218: p0 += 1024;
219: }
220:
221: /* generate error values */
222: e0 = mpy( m00, s0) ^ mpy( m01, s1 );
223: e1 = mpy( m10, s0) ^ mpy( m11, s1 );
224:
225: /* generate check values */
226: c0 = mpy( n00, s0) ^ mpy( n01, s2 );
227: c1 = mpy( n10, s0) ^ mpy( n11, s2 );
228:
229: /* exit if uncorrectable */
230: if ( e0 != c0 || e1 != c1 )
231: return( 0 );
232:
233: /* correct errors */
234: *( pbfr + l0 * 1024 ) ^= e0;
235: *( pbfr + l1 * 1024 ) ^= e1;
236:
237: pbfr++;
238: /* bump to next column */
239: }
240: /* indicate ok */
241: return( 1 );
242: }
243:
244: /************************************************************************/
245: /* 1 error case */
246: /* also could be 2 errors, 1 known location */
247: /************************************************************************/
248: /* */
249: /* syndrome equations */
250: /* */
251: /* | 1| |s0| */
252: /* |L0| |e0| = |s1| */
253: /* |M0| |s2| */
254: /* */
255: /* e0 = s0 = s1/L0 = s2/M0 */
256: /************************************************************************/
257:
258: static unchar a, b, c; /* temps */
259:
260: static
261: fix1()
262: {
263: fpchr p0;
264: int d0;
265: int d1;
266:
267: /* generate powers of 2 (Lx) and */
268: L0 = xl_alg2[ 31 - l0 ];
269: /* and C3 (Mx) [C3 = 1/2] */
270: M0 = xl_alg2[ 224 + l0 ];
271:
272: for( d1 = 0; d1 < 1024; ++d1 ){
273: /* generate syndromes */
274: p0 = pbfr;
275: s2 = s1 = s0 = 0;
276: for( d0 = 0; d0 < nbfr; ++d0 ){
277: s0 ^= *p0;
278: s1 = xl_mx02[ s1 ] ^ *p0;
279: s2 = xl_mxc3[ s2 ] ^ *p0;
280: p0 += 1024;
281: }
282:
283: /* generate error value */
284: e0 = s0;
285: /* generate check values */
286: c0 = dvd( s1, L0 );
287: c1 = dvd( s2, M0 );
288:
289: /* if not 1 error case */
290: if( e0 != c0 || e0 != c1 ){
291: /* test for 2 error case */
292: a = mpy( M0, s0 ) ^ s2;
293: /* and generate l1 */
294: b = mpy( M0, s1 ) ^ mpy( L0, s2 );
295: c = mpy( L0, s0 ) ^ s1;
296: if( !a )
297: return( 0 );
298: L1 = dvd( b, a ) ^ L0;
299: L2 = dvd( dvd( c, a ), L0 );
300: if( L1 != L2 )
301: return( 0 );
302: l1 = xl_log2[ L1 ];
303: if( l1 > 31 )
304: return( 0 );
305: l1 = 31 - l1;
306: /* handle as 2 error case */
307: return( fix2() );
308: }
309:
310: /* correct error */
311: *( pbfr + l0 * 1024 ) ^= e0;
312:
313: /* bump to next column */
314: pbfr++;
315: }
316: /* indicate ok */
317: return( 1 );
318: }
319:
320: /************************************************************************/
321: /* 1 error case, location unknown */
322: /************************************************************************/
323: /* */
324: /* syndrome equations */
325: /* */
326: /* | 1| |s0| */
327: /* |L0| |e0| = |s1| */
328: /* |M0| |s2| */
329: /* */
330: /* location equations */
331: /* */
332: /* L0 = s1/s0 = s0/s2 */
333: /* l0 = log2[L0] */
334: /* */
335: /* error equation */
336: /* */
337: /* e0 = s0 */
338: /************************************************************************/
339:
340: static
341: fix0()
342: {
343: fpchr p0;
344: int d0;
345: int d1;
346:
347: for ( d1 = 0; d1 < 1024; ++d1 ){
348: /* generate syndromes */
349: p0 = pbfr;
350: s2 = s1 = s0 = 0;
351: for( d0 = 0; d0 < nbfr; ++d0 ){
352: s0 ^= *p0;
353: s1 = xl_mx02[ s1 ] ^ *p0;
354: s2 = xl_mxc3[ s2 ] ^ *p0;
355: p0 += 1024;
356: }
357:
358: /* br if no error */
359: if( ( s0 | s1 | s2 ) ){
360: /* generate l0 or fail */
361: L0 = dvd( s1, s0 );
362: L1 = dvd( s0, s2 );
363: if ( L0 != L1 )
364: return( 0 );
365: l0 = xl_log2[ L0 ];
366: if( l0 > 31 )
367: return( 0 );
368: l0 = 31 - l0;
369:
370: /* generate error value */
371: e0 = s0;
372:
373: /* correct error */
374: *( pbfr + l0 * 1024 ) ^= e0;
375: }
376:
377: /* bump to next column */
378: pbfr++;
379: }
380: /* indicate ok */
381: return( 1 );
382: }
383:
384: /************************************************************************/
385: /* multiply */
386: /************************************************************************/
387: static unchar
388: mpy( m0, m1 )
389: unchar m0;
390: unchar m1;
391: {
392: register int m2;
393:
394: if ( m0 == 0 || m1 == 0 )
395: return( 0 );
396: m2 = xl_log2[ m0 ] + xl_log2[ m1 ];
397: if ( m2 >= 255 )
398: m2 -= 255;
399: return( xl_alg2[ m2 ] );
400: }
401:
402: /************************************************************************/
403: /* divide */
404: /************************************************************************/
405: static unchar
406: dvd( m0, m1 )
407: unchar m0;
408: unchar m1;
409: {
410: register int m2;
411:
412: if( m0 == 0 )
413: return( 0 );
414: m2 = xl_log2[ m0 ] - xl_log2[ m1 ];
415: if( m2 < 0 )
416: m2 += 255;
417: return( xl_alg2[ m2 ] );
418: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.