Annotation of ntddk/src/scsi/qic117/reedsolo.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993 - Colorado Memory Systems,  Inc.
                      4: All Rights Reserved
                      5: 
                      6: Module Name:
                      7: 
                      8:     reedsolo.c
                      9: 
                     10: Abstract:
                     11: 
                     12:     These routines perform the Reed-Solomon Error correction
                     13:     required for QIC-40 rev D. Spec.
                     14: 
                     15: Revision History:
                     16: 
                     17: 
                     18: 
                     19: 
                     20: --*/
                     21: 
                     22: //
                     23: // Includes
                     24: //
                     25: 
                     26: #include <ntddk.h>
                     27: #include <ntddtape.h>
                     28: #include "common.h"
                     29: #include "q117.h"
                     30: #include "protos.h"
                     31: 
                     32: //
                     33: // Protos for entry points
                     34: //
                     35: 
                     36: 
                     37: UCHAR
                     38: q117RdsMultiplyTuples (
                     39:     IN UCHAR tup1,
                     40:     IN UCHAR tup2
                     41:     );
                     42: 
                     43: UCHAR
                     44: q117RdsDivideTuples (
                     45:     IN UCHAR tup1,
                     46:     IN UCHAR tup2
                     47:     );
                     48: 
                     49: UCHAR
                     50: q117RdsExpTuple (
                     51:     IN UCHAR tup1,
                     52:     IN UCHAR xpnt
                     53:     );
                     54: 
                     55: VOID
                     56: q117RdsGetSyndromes (
                     57:     IN OUT UCHAR *Array,        // pointer to 32K data area (segment)
                     58:     IN UCHAR Count,             // number of good sectors in segment (4-32)
                     59:     IN UCHAR *ps1,
                     60:     IN UCHAR *ps2,
                     61:     IN UCHAR *ps3
                     62:     );
                     63: 
                     64: BOOLEAN
                     65: q117RdsCorrectFailure (
                     66:     IN OUT UCHAR *Array,         // pointer to 32K data area (segment)
                     67:     IN UCHAR Count,              // number of good sectors in segment (4-32)
                     68:     IN UCHAR s1,
                     69:     IN UCHAR s2,
                     70:     IN UCHAR s3
                     71:     );
                     72: 
                     73: BOOLEAN
                     74: q117RdsCorrectOneError (
                     75:     IN OUT UCHAR *Array,             // pointer to 32K data area (segment)
                     76:     IN UCHAR Count,                  // number of good sectors in segment (4-32)
                     77:     IN UCHAR ErrorLocation,
                     78:     IN UCHAR s1,
                     79:     IN UCHAR s2,
                     80:     IN UCHAR s3
                     81:     );
                     82: 
                     83: BOOLEAN
                     84: q117RdsCorrectTwoErrors (
                     85:     IN OUT UCHAR *Array,             // pointer to 32K data area (segment)
                     86:     IN UCHAR Count,                  // number of good sectors in segment (4-32)
                     87:     IN UCHAR ErrorLocation1,
                     88:     IN UCHAR ErrorLocation2,
                     89:     IN UCHAR s1,
                     90:     IN UCHAR s2,
                     91:     IN UCHAR s3
                     92:     );
                     93: 
                     94: BOOLEAN
                     95: q117RdsCorrectThreeErrors (
                     96:     IN OUT UCHAR *Array,             // pointer to 32K data area (segment)
                     97:     IN UCHAR Count,                  // number of good sectors in segment (4-32)
                     98:     IN UCHAR ErrorLocation1,
                     99:     IN UCHAR ErrorLocation2,
                    100:     IN UCHAR ErrorLocation3,
                    101:     IN UCHAR s1,
                    102:     IN UCHAR s2,
                    103:     UCHAR s3
                    104:     );
                    105: 
                    106: BOOLEAN
                    107: q117RdsCorrectOneErrorAndOneFailure (
                    108:     IN OUT UCHAR *Array,              // pointer to 32K data area (segment)
                    109:     IN UCHAR Count,                   // number of good sectors in segment (4-32)
                    110:     IN UCHAR ErrorLocation1,
                    111:     IN UCHAR s1,
                    112:     IN UCHAR s2,
                    113:     IN UCHAR s3
                    114:     );
                    115: 
                    116: 
                    117: UCHAR  rds_exptup[255*2+2];
                    118: UCHAR  rds_tupexp[256];
                    119: UCHAR  rds_xC0[256];
                    120: 
                    121: #define PASS 0
                    122: #define FAIL 1
                    123: 
                    124: #define ADD_TUPLES(a, b) ((UCHAR) ( (a) ^ (b) ))
                    125: 
                    126: 
                    127: VOID
                    128: q117RdsInitReed (
                    129:     VOID
                    130:     )
                    131: 
                    132: /*++
                    133: 
                    134: Routine Description:
                    135: 
                    136: 
                    137: Arguments:
                    138: 
                    139:     Context - Current context of driver
                    140: 
                    141: Return Value:
                    142: 
                    143:     NONE
                    144: 
                    145: --*/
                    146: 
                    147: {
                    148:     ULONG i;
                    149:     ULONG tuple = 1, alpha_8 = 0x87;
                    150: 
                    151:     for (i = 0; i <= 254; ++i)  {
                    152:         rds_exptup[i] = (UCHAR)tuple;
                    153:         rds_tupexp[tuple] = (UCHAR)i;
                    154:         if (tuple & 0x80) {
                    155:             tuple = ((tuple << 1) ^ alpha_8) & 0xff;
                    156:         } else {
                    157:             tuple <<= 1;
                    158:         }
                    159:     }
                    160:     for (i=0;i<255;++i) {
                    161:         rds_exptup[i+255] = rds_exptup[i];
                    162:         if (i<2) {
                    163:             rds_exptup[i+255+255] = rds_exptup[i];
                    164:         }
                    165:     }
                    166:     for (i = 0; i<=255; ++i) {
                    167:         rds_xC0[i] = q117RdsMultiplyTuples((UCHAR)i,0xc0);
                    168:     }
                    169: }
                    170: 
                    171: UCHAR
                    172: q117RdsMultiplyTuples (
                    173:     IN UCHAR tup1,
                    174:     IN UCHAR tup2
                    175:     )
                    176: 
                    177: /*++
                    178: 
                    179: Routine Description:
                    180: 
                    181:     8-tuples to be multiplied.
                    182: 
                    183: Arguments:
                    184: 
                    185: 
                    186: Return Value:
                    187: 
                    188:     Result of multiply
                    189: 
                    190: --*/
                    191: 
                    192: {
                    193: 
                    194:     if ( (tup1 == 0) || (tup2 == 0) ) {
                    195: 
                    196:         return(0);
                    197: 
                    198:     }
                    199: 
                    200:     return ( rds_exptup[rds_tupexp[tup1] + rds_tupexp[tup2]] );
                    201: }
                    202: 
                    203: UCHAR
                    204: q117RdsDivideTuples (
                    205:     IN UCHAR tup1,
                    206:     IN UCHAR tup2
                    207:     )
                    208: 
                    209: /*++
                    210: 
                    211: Routine Description:
                    212: 
                    213:     8-tuples to be devided
                    214: 
                    215: Arguments:
                    216: 
                    217: 
                    218: Return Value:
                    219: 
                    220:     Result of divide
                    221: 
                    222: --*/
                    223: 
                    224: {
                    225:     if (tup2 == 0) {
                    226:         return(0);
                    227:     }
                    228:     if (tup1 == 0) {
                    229:         return(0);
                    230:     }
                    231: 
                    232:     return (UCHAR)((ULONG)rds_exptup[rds_tupexp[tup1] + 255 - rds_tupexp[tup2]]);
                    233: }
                    234: 
                    235: UCHAR
                    236: q117RdsExpTuple (
                    237:     IN UCHAR tup1,
                    238:     IN UCHAR xpnt
                    239:     )
                    240: 
                    241: /*++
                    242: 
                    243: Routine Description:
                    244: 
                    245:     Exponent routine.
                    246: 
                    247: Arguments:
                    248: 
                    249: 
                    250: Return Value:
                    251: 
                    252:     Result of tup1^xpnt
                    253: 
                    254: --*/
                    255: 
                    256: {
                    257:     if (tup1 == 0)
                    258:         return(0);
                    259: 
                    260:     return (UCHAR)((ULONG)rds_exptup[(rds_tupexp[tup1] * xpnt ) % 255]);
                    261: }
                    262: 
                    263: VOID
                    264: q117RdsMakeCRC (
                    265:     IN OUT UCHAR *Array,      // pointer to 32K data area (segment)
                    266:     IN UCHAR Count            // number of sectors (1K blocks)(1-32)
                    267:     )
                    268: 
                    269: /*++
                    270: 
                    271: Routine Description:
                    272: 
                    273:     Add Reed Solomon codes to buffer
                    274: 
                    275: Arguments:
                    276: 
                    277: 
                    278: Return Value:
                    279: 
                    280: 
                    281: --*/
                    282: 
                    283: {
                    284:     ULONG num;
                    285:     UCHAR i,j,k,p0,p1,p2;
                    286: 
                    287: 
                    288:     for ( num = 0;num < BYTES_PER_SECTOR;++num ) {
                    289:         p0 = p1 = p2 = 0;
                    290: 
                    291:         for ( i = 0; i < (UCHAR)(Count-3); ++i ) {
                    292: 
                    293:             j = rds_xC0[k = (p2 ^ Array[i * BYTES_PER_SECTOR + num])];
                    294:             p2 = j ^ p1;
                    295:             p1 = j ^ p0;
                    296:             p0 = k;
                    297: 
                    298:         }
                    299: 
                    300:         Array[i * BYTES_PER_SECTOR + num] = p2;
                    301:         i++;
                    302:         Array[i * BYTES_PER_SECTOR + num] = p1;
                    303:         i++;
                    304:         Array[i * BYTES_PER_SECTOR + num] = p0;
                    305:         i++;
                    306:     }
                    307: }
                    308: 
                    309: BOOLEAN
                    310: q117RdsReadCheck (
                    311:     IN UCHAR *Array,         // pointer to 32K data area (segment)
                    312:     IN UCHAR Count           // number of sectors (1K blocks)(1-32)
                    313:     )
                    314: 
                    315: /*++
                    316: 
                    317: Routine Description:
                    318: 
                    319:     perform read check on buffer (fast check for CRC failures)
                    320: 
                    321: Arguments:
                    322: 
                    323: 
                    324: Return Value:
                    325: 
                    326:     1 - Success
                    327: 
                    328:     0 - Failure
                    329: 
                    330: --*/
                    331: 
                    332: 
                    333: {
                    334:     LONG num;
                    335:     UCHAR i,sum;
                    336: 
                    337:     for ( num = 0; num < BYTES_PER_SECTOR; ++num ) {
                    338: 
                    339:         sum = 0;
                    340:         for ( i = 0; i < Count; ++i ) {
                    341: 
                    342:             sum ^= Array[i * BYTES_PER_SECTOR + num];
                    343: 
                    344:         }
                    345:         if ( sum != 0 ) {
                    346: 
                    347:             return FAIL;
                    348: 
                    349:         }
                    350:     }
                    351: 
                    352:     return PASS;
                    353: }
                    354: 
                    355: BOOLEAN
                    356: q117RdsCorrect(
                    357:     IN OUT UCHAR *Array,    // pointer to 32K data area (segment)
                    358:     IN UCHAR Count,         // number of good sectors in segment (4-32)
                    359:     IN UCHAR CRCErrors,     // number of crc errors
                    360:     IN UCHAR e1,
                    361:     IN UCHAR e2,
                    362:     IN UCHAR e3             // sectors where errors occurred
                    363:     )
                    364: 
                    365: /*++
                    366: 
                    367: Routine Description:
                    368: 
                    369:     perform error Reed-Solomon error correction on segment
                    370: 
                    371: Arguments:
                    372: 
                    373: 
                    374: Return Value:
                    375: 
                    376:     1 - Success
                    377: 
                    378:     0 - Failure
                    379: 
                    380: --*/
                    381: 
                    382: {
                    383:     USHORT num;
                    384:     BOOLEAN ret;
                    385:     UCHAR s1,s2,s3;
                    386: 
                    387:     ret = PASS;
                    388:     Count--;
                    389:     e1 = Count-e1;
                    390:     e2 = Count-e2;
                    391:     e3 = Count-e3;
                    392: 
                    393:     for ( num = 0; num < BYTES_PER_SECTOR; ++num ) {
                    394:         q117RdsGetSyndromes(&Array[num],Count,&s1,&s2,&s3);
                    395:         if ( s1 || s2 || s3 ) {
                    396: 
                    397:             switch( CRCErrors ) {
                    398: 
                    399:                 case 0:
                    400:                     ret = q117RdsCorrectFailure(&Array[num],Count,s1,s2,s3);
                    401:                     break;
                    402: 
                    403:                 case 1:
                    404:                     ret = q117RdsCorrectOneError(&Array[num],Count,e1,s1,s2,s3);
                    405:                     break;
                    406: 
                    407:                 case 2:
                    408:                    ret = q117RdsCorrectTwoErrors(&Array[num],Count,e1,e2,s1,s2,s3);
                    409:                     break;
                    410: 
                    411:                 case 3:
                    412:                     ret = q117RdsCorrectThreeErrors(&Array[num],Count,e1,e2,e3,s1,s2,s3);
                    413:                     break;
                    414: 
                    415:                 default:
                    416:                     ret = FAIL;
                    417:                     break;
                    418:             }
                    419:         }
                    420:         if (ret)
                    421:             return ret;
                    422:     }
                    423:     return ret;
                    424: }
                    425: 
                    426: 
                    427: //
                    428: // Due to bug in CL386 version 0.00.45,  turn off optimization
                    429: //
                    430: #if i386
                    431: #pragma optimize("",off)
                    432: #endif
                    433: 
                    434: 
                    435: VOID
                    436: q117RdsGetSyndromes (
                    437:     IN OUT UCHAR *Array,       // pointer to 32K data area (segment)
                    438:     IN UCHAR Count,            // number of good sectors in segment (4-32)
                    439:     IN UCHAR *ps1,
                    440:     IN UCHAR *ps2,
                    441:     IN UCHAR *ps3
                    442:     )
                    443: 
                    444: /*++
                    445: 
                    446: Routine Description:
                    447: 
                    448:     8-tuples to be multiplied.
                    449: 
                    450: Arguments:
                    451: 
                    452: 
                    453: Return Value:
                    454: 
                    455: 
                    456: --*/
                    457: 
                    458: {
                    459:     UCHAR q,r,s,s1,s2,s3,cx,al,ah;
                    460: 
                    461:     q = r = s = 0;
                    462: 
                    463:     for ( cx = 0; cx <= Count; ++cx ) {
                    464: 
                    465:         al = rds_xC0[ah = q];
                    466:         q = r ^ al;
                    467:         r = s ^ al;
                    468:         s = ah ^ Array[cx * BYTES_PER_SECTOR];
                    469: 
                    470:     }
                    471: 
                    472:     s1 = q117RdsMultiplyTuples(q,0xa2) ^ q117RdsMultiplyTuples(r,0xc3) ^ s;
                    473:     s2 = q ^ r ^ s;
                    474:     s3 = q117RdsMultiplyTuples(q,0x4) ^ q117RdsMultiplyTuples(r,2) ^ s;
                    475:     *ps1 = s1;
                    476:     *ps2 = s2;
                    477:     *ps3 = s3;
                    478: }
                    479: #if i386
                    480: #pragma optimize("",on)
                    481: #endif
                    482: 
                    483: 
                    484: BOOLEAN
                    485: q117RdsCorrectFailure (
                    486:     IN OUT UCHAR *Array,     // pointer to 32K data area (segment)
                    487:     IN UCHAR Count,          // number of good sectors in segment (4-32)
                    488:     IN UCHAR s1,
                    489:     IN UCHAR s2,
                    490:     IN UCHAR s3
                    491:     )
                    492: 
                    493: /*++
                    494: 
                    495: Routine Description:
                    496: 
                    497:     Correct one failure
                    498: 
                    499: Arguments:
                    500: 
                    501: 
                    502: Return Value:
                    503: 
                    504:     1 - Success
                    505: 
                    506:     0 - Failure
                    507: 
                    508: --*/
                    509: 
                    510: {
                    511:     UCHAR errorloc,c1,y1,x1,ck;
                    512: 
                    513:     //
                    514:     // check for divide by zero
                    515:     //
                    516:     if (s1 == 0) {
                    517:         return FAIL;
                    518:     }
                    519:     errorloc = rds_tupexp[q117RdsDivideTuples(s2,s1)];
                    520:     if (errorloc > Count) {
                    521:         return FAIL;
                    522:     }
                    523:     y1 = s2;
                    524:     x1 = rds_exptup[errorloc];
                    525:     c1 = ADD_TUPLES(s2,Array[(Count-errorloc) * BYTES_PER_SECTOR]);
                    526:     ck = q117RdsMultiplyTuples(y1,x1);
                    527:     if (ck != s3) {
                    528:         return FAIL;
                    529:     } else {
                    530:         Array[(Count-errorloc) * BYTES_PER_SECTOR] = c1;
                    531:     }
                    532:     return PASS;
                    533: }
                    534: 
                    535: BOOLEAN
                    536: q117RdsCorrectOneError (
                    537:     IN OUT UCHAR *Array,      // pointer to 32K data area (segment)
                    538:     IN UCHAR Count,           // number of good sectors in segment (4-32)
                    539:     IN UCHAR ErrorLocation,
                    540:     IN UCHAR s1,
                    541:     IN UCHAR s2,
                    542:     IN UCHAR s3
                    543:     )
                    544: 
                    545: /*++
                    546: 
                    547: Routine Description:
                    548: 
                    549:     Correct one error.
                    550: 
                    551: Arguments:
                    552: 
                    553: 
                    554: Return Value:
                    555: 
                    556:     1 - Success
                    557: 
                    558:     0 - Failure
                    559: 
                    560: --*/
                    561: 
                    562: {
                    563:     UCHAR x1,y1,c1,ck;
                    564: 
                    565:     x1 = rds_exptup[ErrorLocation];
                    566:     y1 = s2;
                    567:     c1 = ADD_TUPLES(s2,Array[(Count-ErrorLocation) * BYTES_PER_SECTOR]);
                    568:     ck = q117RdsMultiplyTuples(y1,x1);
                    569: 
                    570:     if ( ck != s3 ) {
                    571: 
                    572:         return q117RdsCorrectOneErrorAndOneFailure(Array,Count,ErrorLocation,s1,s2,s3);
                    573: 
                    574:     } else {
                    575: 
                    576:         Array[(Count-ErrorLocation) * BYTES_PER_SECTOR] = c1;
                    577: 
                    578:     }
                    579:     return PASS;
                    580: }
                    581: 
                    582: BOOLEAN
                    583: q117RdsCorrectTwoErrors (
                    584:     IN OUT UCHAR *Array,       // pointer to 32K data area (segment)
                    585:     IN UCHAR Count,            // number of good sectors in segment (4-32)
                    586:     IN UCHAR ErrorLocation1,
                    587:     IN UCHAR ErrorLocation2,
                    588:     IN UCHAR s1,
                    589:     IN UCHAR s2,
                    590:     IN UCHAR s3
                    591:     )
                    592: 
                    593: /*++
                    594: 
                    595: Routine Description:
                    596: 
                    597:     Correct two errors.
                    598: 
                    599: Arguments:
                    600: 
                    601: 
                    602: Return Value:
                    603: 
                    604:     1 - Success
                    605: 
                    606:     0 - Failure
                    607: 
                    608: --*/
                    609: 
                    610: {
                    611:     UCHAR y1,y2,x1,x2,c1,c2,ck;
                    612: 
                    613:     x1 = rds_exptup[ErrorLocation1];
                    614:     x2 = rds_exptup[ErrorLocation2];
                    615: 
                    616:     y2 = q117RdsDivideTuples(
                    617:             ADD_TUPLES(
                    618:                 q117RdsMultiplyTuples(s2, x1), s3 ), ADD_TUPLES(x1,x2)
                    619:             );
                    620: 
                    621:     y1 = ADD_TUPLES(y2,s2);
                    622: 
                    623:     c1 = ADD_TUPLES( y1, Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] );
                    624:     c2 = ADD_TUPLES( y2, Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR] );
                    625: 
                    626:     ck =x1 = q117RdsDivideTuples(
                    627:                 ADD_TUPLES(
                    628:                     q117RdsMultiplyTuples(y1,x2),
                    629:                     q117RdsMultiplyTuples(y2,x1)
                    630:                 ), q117RdsMultiplyTuples(x1,x2));
                    631: 
                    632:     if ( ck != s1 ) {
                    633: 
                    634:         return FAIL;
                    635: 
                    636:     } else {
                    637: 
                    638:         Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] = c1;
                    639:         Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR] = c2;
                    640: 
                    641:     }
                    642: 
                    643:     return PASS;
                    644: }
                    645: 
                    646: BOOLEAN
                    647: q117RdsCorrectThreeErrors (
                    648:     IN OUT UCHAR *Array,       // pointer to 32K data area (segment)
                    649:     IN UCHAR Count,            // number of good sectors in segment (4-32)
                    650:     IN UCHAR ErrorLocation1,
                    651:     IN UCHAR ErrorLocation2,
                    652:     IN UCHAR ErrorLocation3,
                    653:     IN UCHAR s1,
                    654:     IN UCHAR s2,
                    655:     UCHAR s3
                    656:     )
                    657: 
                    658: /*++
                    659: 
                    660: Routine Description:
                    661: 
                    662:     Correct three errors.
                    663: 
                    664: Arguments:
                    665: 
                    666: 
                    667: Return Value:
                    668: 
                    669:     1 - Success
                    670: 
                    671:     0 - Failure
                    672: 
                    673: --*/
                    674: 
                    675: {
                    676:     UCHAR y1,y2,y3,z1,z2,z3,x1,x2,x3,c1,c2,c3,q1,q2,q3,q4;
                    677: 
                    678:     x1 = rds_exptup[ErrorLocation1];
                    679:     x2 = rds_exptup[ErrorLocation2];
                    680:     x3 = rds_exptup[ErrorLocation3];
                    681:     z1 = q117RdsDivideTuples(1,x1);
                    682:     z2 = q117RdsDivideTuples(1,x2);
                    683:     z3 = q117RdsDivideTuples(1,x3);
                    684:     q1 = q117RdsDivideTuples(
                    685:             ADD_TUPLES(q117RdsMultiplyTuples(x1,s2),s3),
                    686:             ADD_TUPLES(x1,x2)
                    687:             );
                    688:     q2 = q117RdsDivideTuples(
                    689:             ADD_TUPLES(q117RdsMultiplyTuples(z1,s2),s1),
                    690:             ADD_TUPLES(z1,z2)
                    691:             );
                    692:     q3 = q117RdsDivideTuples(ADD_TUPLES(x1,x3),ADD_TUPLES(x1,x2));
                    693:     q4 = q117RdsDivideTuples(ADD_TUPLES(z1,z3),ADD_TUPLES(z1,z2));
                    694:     y3 = q117RdsDivideTuples(ADD_TUPLES(q1,q2),ADD_TUPLES(q3,q4));
                    695:     y2 = ADD_TUPLES(q2,q117RdsMultiplyTuples(q4,y3));
                    696:     y1 = ADD_TUPLES(ADD_TUPLES(y3,y2),s2);
                    697:     c1 = ADD_TUPLES(y1,Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR]);
                    698:     c2 = ADD_TUPLES(y2,Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR]);
                    699:     c3 = ADD_TUPLES(y3,Array[(Count-ErrorLocation3) * BYTES_PER_SECTOR]);
                    700: 
                    701:     Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] = c1;
                    702:     Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR] = c2;
                    703:     Array[(Count-ErrorLocation3) * BYTES_PER_SECTOR] = c3;
                    704: 
                    705:     return PASS;
                    706: }
                    707: 
                    708: BOOLEAN
                    709: q117RdsCorrectOneErrorAndOneFailure (
                    710:     IN OUT UCHAR *Array,        // pointer to 32K data area (segment)
                    711:     IN UCHAR Count,             // number of good sectors in segment (4-32)
                    712:     IN UCHAR ErrorLocation1,
                    713:     IN UCHAR s1,
                    714:     IN UCHAR s2,
                    715:     IN UCHAR s3
                    716:     )
                    717: 
                    718: /*++
                    719: 
                    720: Routine Description:
                    721: 
                    722:     Correct one error and one failure.
                    723: 
                    724: Arguments:
                    725: 
                    726: 
                    727: Return Value:
                    728: 
                    729:     1 - Success
                    730: 
                    731:     0 - Failure
                    732: 
                    733: --*/
                    734: 
                    735: {
                    736:     UCHAR y1,y2,x1,x2,c1,c2;
                    737:     UCHAR errorLoc2;
                    738: 
                    739:     x1 = rds_exptup[ErrorLocation1];
                    740: 
                    741:     y1 = q117RdsDivideTuples(
                    742:             q117RdsMultiplyTuples(
                    743:                 ADD_TUPLES(
                    744:                     q117RdsMultiplyTuples(s1,s3),
                    745:                     q117RdsExpTuple(s2,2)
                    746:                 ),x1),
                    747:             ADD_TUPLES(s3,
                    748:                 q117RdsMultiplyTuples(s1,q117RdsExpTuple(x1,2)))
                    749:             );
                    750: 
                    751:     y2 = ADD_TUPLES(y1,s2);
                    752: 
                    753:     x2 = q117RdsDivideTuples(
                    754:             q117RdsMultiplyTuples(y2,x1),
                    755:             ADD_TUPLES(y1,q117RdsMultiplyTuples(s1,x1))
                    756:             );
                    757: 
                    758:     errorLoc2 = rds_tupexp[x2];
                    759: 
                    760:     if ( errorLoc2 > Count ) {
                    761: 
                    762:         return FAIL;
                    763: 
                    764:     }
                    765: 
                    766:     c1 = ADD_TUPLES(y1,Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR]);
                    767:     c2 = ADD_TUPLES(y2,Array[(Count-errorLoc2) * BYTES_PER_SECTOR]);
                    768: 
                    769:     Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] = c1;
                    770:     Array[(Count-errorLoc2) * BYTES_PER_SECTOR] = c2;
                    771: 
                    772:     return PASS;
                    773: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.