|
|
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.