/* V2MemTest - A CLI Tool to test & fix Voodoo² TMU System * Copyright (C) 2026 ChaCha * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _BSD_SOURCE 1 #include #include #include #include #include #include #include "cvg.h" #include #include "sst1init.h" #include "fxpci.h" #include "FaultSources.h" #include "Utils.h" #include "Draw.h" #include "Test_Common.h" #include "Test_Data_Huge.h" #include "Test_Data_NoMem.h" extern const def_sTestPattern ar_sExpectedPattern_Test3[]; extern const unsigned int uNbPattern_Test3; extern const def_sTestPattern ar_sExpectedPattern_Test3_Dither[]; extern const unsigned int uNbPattern_Test3_Dither; extern const def_sFaultSourceLineMap ar_sFaultSourceLineMap[]; void DisplayPattern(const def_sTestPattern * const pREF) { printf("RGB: %04X %04X %04X %04X\n", pREF->data.access.u16Pix[0][0], pREF->data.access.u16Pix[0][1], pREF->data.access.u16Pix[0][2], pREF->data.access.u16Pix[0][3]); printf("RGB: %04X %04X %04X %04X\n", pREF->data.access.u16Pix[1][0], pREF->data.access.u16Pix[1][1], pREF->data.access.u16Pix[1][2], pREF->data.access.u16Pix[1][3]); printf("RGB: %04X %04X %04X %04X\n", pREF->data.access.u16Pix[2][0], pREF->data.access.u16Pix[2][1], pREF->data.access.u16Pix[2][2], pREF->data.access.u16Pix[2][3]); printf("RGB: %04X %04X %04X %04X\n", pREF->data.access.u16Pix[3][0], pREF->data.access.u16Pix[3][1], pREF->data.access.u16Pix[3][2], pREF->data.access.u16Pix[3][3]); printf("Alpha: %02X %02X %02X %02X\n", pREF->data.access.u8APix[0][0], pREF->data.access.u8APix[0][1], pREF->data.access.u8APix[0][2], pREF->data.access.u8APix[0][3]); printf("Alpha: %02X %02X %02X %02X\n", pREF->data.access.u8APix[1][0], pREF->data.access.u8APix[1][1], pREF->data.access.u8APix[1][2], pREF->data.access.u8APix[1][3]); printf("Alpha: %02X %02X %02X %02X\n", pREF->data.access.u8APix[2][0], pREF->data.access.u8APix[2][1], pREF->data.access.u8APix[2][2], pREF->data.access.u8APix[2][3]); printf("Alpha: %02X %02X %02X %02X\n", pREF->data.access.u8APix[3][0], pREF->data.access.u8APix[3][1], pREF->data.access.u8APix[3][2], pREF->data.access.u8APix[3][3]); } // Returns the distance between A & B, normalized between 0 and 1. // 0 means they are perfectly identicals. // 1 means they are entirely diferents. double ComputePatternDistance( const def_sTestPattern * const pA, const def_sTestPattern * const pB) { double dDistance = 0; logT("========================\n"); logT("Compare A|B:\n"); for (unsigned int i = 0; i <12; i=i+4) { logT("%08X\t%08X\n",pA->data.raw[i],pB->data.raw[i]); logT("%08X\t%08X\n",pA->data.raw[i+1],pB->data.raw[i+1]); logT("%08X\t%08X\n",pA->data.raw[i+2],pB->data.raw[i+2]); logT("%08X\t%08X\n",pA->data.raw[i+3],pB->data.raw[i+3]); dDistance += dComputeDistance32(pA->data.raw[i], pB->data.raw[i]); dDistance += dComputeDistance32(pA->data.raw[i+1],pB->data.raw[i+1]); dDistance += dComputeDistance32(pA->data.raw[i+2],pB->data.raw[i+2]); dDistance += dComputeDistance32(pA->data.raw[i+3],pB->data.raw[i+3]); } dDistance /= 12*4*32; logT("dDistance: %f\n",dDistance); return dDistance; } typedef struct _def_sScoreSet{ double dScore; const def_sTestPattern * pREF; }def_sScoreSet; int scoreSetCmp(const void * const first, const void * const second) { const double scoreFirst = ((def_sScoreSet*)first)->dScore; const double scoreSecond = ((def_sScoreSet*)second)->dScore; return scoreFirst > scoreSecond ? -1 : (scoreFirst < scoreSecond ? 1 : 0); } double inline ScaleScore(const double dIn,const double dK) { return (1.0-exp(-dK*dIn))/(1.0-exp(-dK)); //return log(1.0+(dK*dIn))/log(1.0+dK); } /* returns a def_sScoreSet array, containing ordered reference to testPattern * plus the corresponding score. */ void GetNearestIndexes( const def_sTestPattern * const pREF, const def_sTestPattern * const pSet, def_sScoreSet * const ScoreSet, const unsigned int uNbPattern) { for (unsigned int i = 0; i < uNbPattern; i++) { ScoreSet[i].pREF = &pSet[i]; ScoreSet[i].dScore = (1 - ScaleScore(ComputePatternDistance(pREF,pSet+i),100)); logT("ScoreSet[%d].dScore = %f\n",i,ScoreSet[i].dScore); } qsort(ScoreSet,uNbPattern,sizeof(def_sScoreSet),scoreSetCmp); double dFirstScore = -INFINITY; for (unsigned int i = 0; i < uNbPattern; i++) { if(i==0) dFirstScore = ScoreSet[i].dScore; ScoreSet[i].dScore = (ScoreSet[i].dScore / dFirstScore) * 100; } } unsigned char DistributeFaults( const def_sTestPattern * const pREF, const def_sTestPattern * const pREFPatterns, const unsigned int uNbREFPatterns, const unsigned char ucNumTMU, def_sFaultSourceScoreRec* const pFaultSrcCtx) { def_sScoreSet * const ScoreSet = (def_sScoreSet*)malloc(uNbREFPatterns*sizeof(def_sScoreSet)); if(ScoreSet==NULL) { logE("Cannot allocate memory..."); return 1; } GetNearestIndexes(pREF,pREFPatterns,ScoreSet,uNbREFPatterns); for( int i = 0 ; i < uNbREFPatterns ; i++) { if( ScoreSet[i].pREF->bReferenceSet && ScoreSet[i].dScore==100) { //logD("No Fault found\n"); free(ScoreSet); return 0; } } logD("==========================\n"); logD("Read:\n"); if( sOptions.eLogLevel >= E_LOGLEVEL__DEBUG) DisplayPattern(pREF); for( int i = 0 ; i < uNbREFPatterns ; i++) { logD("==========================\n"); if((!ScoreSet[i].pREF->bReferenceSet) && (ScoreSet[i].dScore>=80)) { logD( "%d Score = %f\n", ScoreSet[i].pREF->u8FaultLineIdx,ScoreSet[i].dScore); FaultSource_addScore( pFaultSrcCtx, ar_sFaultSourceLineMap [ScoreSet[i].pREF->u8FaultLineIdx] .eTMUFaultSource_TMU0_RES, ScoreSet[i].dScore); FaultSource_addScore( pFaultSrcCtx, ar_sFaultSourceLineMap [ScoreSet[i].pREF->u8FaultLineIdx] .eTMUFaultSource_FBI, ScoreSet[i].dScore); FaultSource_addScore( pFaultSrcCtx, ar_sFaultSourceLineMap [ScoreSet[i].pREF->u8FaultLineIdx] .eTMUFaultSource_TMU0_FBI, ScoreSet[i].dScore); if(ucNumTMU==1) { FaultSource_addScore( pFaultSrcCtx, ar_sFaultSourceLineMap [ScoreSet[i].pREF->u8FaultLineIdx] .eTMUFaultSource_TMU0_TMU1, ScoreSet[i].dScore); FaultSource_addScore( pFaultSrcCtx, ar_sFaultSourceLineMap [ScoreSet[i].pREF->u8FaultLineIdx] .eTMUFaultSource_TMU1, ScoreSet[i].dScore); } } } free(ScoreSet); return 1; } void TestStep_NoMem(FxU32 * const sst, SstRegs * const sstregs, const unsigned char ucNumTMU, const uint8_t bEnableRGB, const uint8_t bEnbleAlpha, const uint8_t bEnableDitherValues, def_sTestPattern * const psResultPattern) { ISET(SST_TREX(sstregs,ucNumTMU)->texBaseAddr, (0x000000>>3)); volatile const FxU32 * const pLFB1 = sst + (SST_LFB_ADDR>>2); volatile const FxU32 * const pLFB2 = pLFB1 +((2048)>>2) ; volatile const FxU32 * const pLFB3 = pLFB2 +((2048)>>2) ; volatile const FxU32 * const pLFB4 = pLFB3 +((2048)>>2) ; ISET( SST_TREX(sstregs,ucNumTMU)->textureMode, SST_RGB565 | (bEnableRGB ? SST_TC_ONE : SST_TC_ZERO) | (bEnbleAlpha ? SST_TCA_ONE :SST_TCA_ZERO)); if(bEnableDitherValues) { /* We are using dithering to detect lsb Faults. * We need a non-zero original LFB value for dithering to happen. * Drawing a triangle make detection easier.*/ clearScreen(sstregs,(1 << 11) | (0<<5) |(1),8,8); drawTriangle(sstregs, ucNumTMU, 0, 0, 3, 4); } else { clearScreen(sstregs,0x00000000,8,8); drawRect2(sstregs, ucNumTMU, 0, 0, 4, 4); } sst1InitIdle(sst); mmio_fastread32((uint32_t*)psResultPattern->data.access.u16Pix[0], pLFB1, 2); mmio_fastread32((uint32_t*)psResultPattern->data.access.u16Pix[1], pLFB2, 2); mmio_fastread32((uint32_t*)psResultPattern->data.access.u16Pix[2], pLFB3, 2); mmio_fastread32((uint32_t*)psResultPattern->data.access.u16Pix[3], pLFB4, 2); const uint32_t OldlfbMode = IGET(sstregs->lfbMode); ISET(sstregs->lfbMode, (OldlfbMode & ~SST_LFB_READFRONTBUFFER) //SST_LFB_READBACKBUFFER | SST_LFB_READDEPTHABUFFER); psResultPattern->data.access.u8APix[0][0] = pLFB1[0] & 0xFF; psResultPattern->data.access.u8APix[0][1] = (pLFB1[0]>>16) & 0xFF; psResultPattern->data.access.u8APix[0][2] = pLFB1[1] & 0xFF; psResultPattern->data.access.u8APix[0][3] = (pLFB1[1]>>16) & 0xFF; psResultPattern->data.access.u8APix[1][0] = pLFB2[0] & 0xFF; psResultPattern->data.access.u8APix[1][1] = (pLFB2[0]>>16) & 0xFF; psResultPattern->data.access.u8APix[1][2] = pLFB2[1] & 0xFF; psResultPattern->data.access.u8APix[1][3] = (pLFB2[1]>>16) & 0xFF; psResultPattern->data.access.u8APix[2][0] = pLFB3[0] & 0xFF; psResultPattern->data.access.u8APix[2][1] = (pLFB3[0]>>16) & 0xFF; psResultPattern->data.access.u8APix[2][2] = pLFB3[1] & 0xFF; psResultPattern->data.access.u8APix[2][3] = (pLFB3[1]>>16) & 0xFF; psResultPattern->data.access.u8APix[3][0] = pLFB4[0] & 0xFF; psResultPattern->data.access.u8APix[3][1] = (pLFB4[0]>>16) & 0xFF; psResultPattern->data.access.u8APix[3][2] = pLFB4[1] & 0xFF; psResultPattern->data.access.u8APix[3][3] = (pLFB4[1]>>16) & 0xFF; ISET(sstregs->lfbMode, OldlfbMode); ISET( SST_TREX(sstregs,ucNumTMU)->textureMode, SST_RGB565 | SST_TC_REPLACE | SST_TCA_REPLACE); } #define N_LOOP_TEST 100 unsigned long long test_TMU_datalines_NoMem( sst1DeviceInfoStruct * const devInfo, FxU32 * const sst, SstRegs * const sstregs, const unsigned char ucNumTMU, def_sFaultSourceScoreRec* const pFaultSrcCtx) { unsigned long long ullNbErrorAll = 0; static def_sTestPattern ar_ResultPattern[N_LOOP_TEST][8]; sst1InitIdle(sst); const uint32_t OldlfbMode = IGET(sstregs->lfbMode);//SST_LFB_READBACKBUFFER ISET(sstregs->lfbMode, SST_LFB_565 | SST_LFB_READFRONTBUFFER | SST_LFB_RGBALANES_ARGB); const uint32_t OldfbzMode = IGET(sstregs->fbzMode); ISET(sstregs->fbzMode, // SST_DRAWBUFFER_BACK SST_DRAWBUFFER_FRONT | SST_RGBWRMASK | SST_ZAWRMASK | SST_ENALPHABUFFER // <-for NoMEM test ?? Not needed | SST_ENALPHAMASK); // <-for NoMEM test; Needed const uint32_t OldtrexInit0 = IGET(SST_TREX(sstregs,ucNumTMU)->trexInit0); devInfo->tmuInit0[(int)ucNumTMU] = SST_TREXINIT0_DEFAULT ; ISET(SST_TREX(sstregs,ucNumTMU)->trexInit0, devInfo->tmuInit0[(int)ucNumTMU]); sst1InitIdle(sst); /* set downstream TMUs to passthrough */ for (int i=0; i< ucNumTMU; i++) { ISET(SST_TREX(sstregs,i)->textureMode, SST_RGB565 | SST_TC_PASS | SST_TCA_PASS); } /* Testing several time to exclude instabilities */ for(unsigned int i = 0; i < N_LOOP_TEST ; i++) { /* this test is using the only feature I found that can * control TMUs output without using TMU's RAM. Using * textureMode we can force a TMU to output RGB value to * 0xFFFFFF or 0x000000 (only), and A(lpha) to 0xFF or 0x00 (Only). * So we will try these 4 pattern and check what we get on the LFB. * Then eventually we can make "smart" Fault recognition... * * To make things harder, the physical data bus is 16Bit (DDR?). * So [AR] and [GB] or superposed. * */ /***************/ /* RGB: 0, A: 0*/ /***************/ /* Not implemented because the "all on" test should be enough for now TestStep_NoMem( sst, sstregs, ucNumTMU, 0 ,0, 0, &ar_ResultPattern[i][0]);*/ /***************/ /* RGB: 1, A: 0*/ /***************/ /* Not implemented because the "all on" test should be enough for now TestStep_NoMem( sst, sstregs, ucNumTMU, 1, 0, 0, &ar_ResultPattern[i][1]);*/ /***************/ /* RGB: 1, A: 1*/ /***************/ TestStep_NoMem( sst, sstregs, ucNumTMU, 1, 1 , 0, &ar_ResultPattern[i][2]); /***************/ /* RGB: 0, A: 1*/ /***************/ /* Not implemented because the "all on" test should be enough for now TestStep_NoMem( sst, sstregs, ucNumTMU, 0, 1 , 0, &ar_ResultPattern[i][3]);*/ } /* Same test but with dithering enabled to get bit 0-1 values */ ISET(sstregs->fbzMode, // SST_DRAWBUFFER_BACK SST_DRAWBUFFER_FRONT | SST_ENDITHER // <- enabling Dithering for this test | SST_RGBWRMASK | SST_ZAWRMASK | SST_ENALPHABUFFER | SST_ENALPHAMASK); for(unsigned int i = 0; i < N_LOOP_TEST ; i++) { /* this test is using the only feature I found that can * control TMUs output without using TMU's RAM. Using * textureMode we can force a TMU to output RGB value to * 0xFFFFFF or 0x000000 (only), and A(lpha) to 0xFF or 0x00 (Only). * So we will try these 4 pattern and check what we get on the LFB. * Then eventually we can make "smart" Fault recognition... * * To make things harder, the physical data bus is 16Bit (DDR?). * So [AR] and [GB] or superposed. * */ /***************/ /* RGB: 0, A: 0*/ /***************/ /* Not implemented because the "all on" test should be enough for now TestStep_NoMem( sst, sstregs, ucNumTMU, 0 ,0, 1, &ar_ResultPattern[i][4]);*/ /***************/ /* RGB: 1, A: 0*/ /***************/ /* Not implemented because the "all on" test should be enough for now TestStep_NoMem( sst, sstregs, ucNumTMU, 1, 0, 1, &ar_ResultPattern[i][5]);*/ /***************/ /* RGB: 1, A: 1*/ /***************/ TestStep_NoMem( sst, sstregs, ucNumTMU, 1, 1 , 1, &ar_ResultPattern[i][6]); /***************/ /* RGB: 0, A: 1*/ /***************/ /* Not implemented because the "all on" test should be enough for now TestStep_NoMem( sst, sstregs, ucNumTMU, 0, 1 , 1, &ar_ResultPattern[i][7]);*/ } /* Post processing test results */ for(unsigned int i = 0; i < N_LOOP_TEST ; i++) { /* Not implemented because the "all on" test should be enough for now ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][0], ar_sExpectedPattern_Test1, uNbPattern_Test1, ucNumTMU, pFaultSrcCtx);*/ /* Not implemented because the "all on" test should be enough for now ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][1], ar_sExpectedPattern_Test2, uNbPattern_Test2, ucNumTMU, pFaultSrcCtx);*/ ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][2], ar_sExpectedPattern_Test3, uNbPattern_Test3, ucNumTMU, pFaultSrcCtx); /* Not implemented because the "all on" test should be enough for now ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][3], ar_sExpectedPattern_Test4, uNbPattern_Test4, ucNumTMU, pFaultSrcCtx);*/ /* Not implemented because the "all on" test should be enough for now ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][4], ar_sExpectedPattern_Test1_Dither, uNbPattern_Test1_Dither, ucNumTMU, pFaultSrcCtx);*/ /* Not implemented because the "all on" test should be enough for now ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][5], ar_sExpectedPattern_Test2_Dither, uNbPattern_Test2_Dither, ucNumTMU, pFaultSrcCtx);*/ ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][6], ar_sExpectedPattern_Test3_Dither, uNbPattern_Test3_Dither, ucNumTMU, pFaultSrcCtx); /* Not implemented because the "all on" test should be enough for now ullNbErrorAll += DistributeFaults( &ar_ResultPattern[i][7], ar_sExpectedPattern_Test4_Dither, uNbPattern_Test4_Dither, ucNumTMU, pFaultSrcCtx);*/ } /* reset the Init0 register back to its previous value */ ISET(sstregs->lfbMode,OldlfbMode); ISET(sstregs->fbzMode, OldfbzMode); sst1InitIdle(sst); devInfo->tmuInit0[(int)ucNumTMU] = OldtrexInit0; ISET(SST_TREX(sstregs,ucNumTMU)->trexInit0, devInfo->tmuInit0[(int)ucNumTMU]); sst1InitIdle(sst); return ullNbErrorAll; } /* This is an attempt to simulate TMU->FBI->LFB values exchange and * computation. It partially works for normal mode (no dithering, alpha buffer * enabled), with two exception: Alpha bit XX seems to have a special behaviour * that just zeros the output. And the colour mixing hasnt been reverse * enginered. The dithering algorithm hasnt been reversed either. * Then, because we are using pattern distance matching, this function is not * used anymore. I let it here in case one day we want/need to implement a more * accurate test * int simuFault_step( uint8_t bRGB, uint8_t bA, uint16_t u16CurrentPixel, uint8_t u8CurrentAPixel, uint16_t * const pu16RenderedPixel, uint8_t * const pu8RenderedAPixel, uint16_t u16BUSFaultMap ) { // TMU Output force set const uint8_t u8TMU_r8 = bRGB ? 0xFF : 0; const uint8_t u8TMU_g8 = bRGB ? 0xFF : 0; const uint8_t u8TMU_b8 = bRGB ? 0xFF : 0; const uint8_t u8TMU_a8 = bA ? 0xFF : 0; // TMU Output values packing (useless as its only all 0 or 1, but for brain model..) const uint16_t u16Sent_W1 = (u8TMU_g8<<8) + u8TMU_b8; const uint16_t u16Sent_W2 = (u8TMU_a8<<8) + u8TMU_r8; // FBI receiving + Error aplication const uint16_t u16received_W1 = u16Sent_W1 & ~u16BUSFaultMap; const uint16_t u16received_W2 = u16Sent_W2 & ~u16BUSFaultMap; // FBI received colours unpacking (!!! to be checked) uint16_t u16FBI_Input_r8 = (u16received_W2 & 0xFF); uint16_t u16FBI_Input_g8 = (u16received_W1 >> 8); uint16_t u16FBI_Input_b8 = (u16received_W1 & 0xFF); uint16_t u16FBI_Input_a8 = (u16received_W2 >> 8); // FBI LFB current colours unpacking const uint16_t u16FBI_Current_r8 = ((u16CurrentPixel>>11) & 0x1F) << 3; const uint16_t u16FBI_Current_g8 = ((u16CurrentPixel>>5) & 0x3F) << 2; const uint16_t u16FBI_Current_b8 = ((u16CurrentPixel>>0) & 0x1F) << 3; const uint16_t u16FBI_Current_a8 = u8CurrentAPixel; // Mixing current and new colours //u16FBI_Input_r8 *= u16FBI_Input_a8; // This does not work //u16FBI_Input_r8 += u16FBI_Current_r8 * (255-u16FBI_Input_a8); //u16FBI_Input_r8 >>=8; //u16FBI_Input_g8 *= u16FBI_Input_a8; //u16FBI_Input_g8 += u16FBI_Current_g8 * (255-u16FBI_Input_a8); //u16FBI_Input_g8 >>=8; //u16FBI_Input_b8 *= u16FBI_Input_a8; //u16FBI_Input_b8 += u16FBI_Current_b8 * (255-u16FBI_Input_a8); //u16FBI_Input_b8 >>=8; //u16FBI_Input_a8 *= u16FBI_Input_a8; //u16FBI_Input_a8 += u16FBI_Current_a8*(255-u16FBI_Input_a8); //u16FBI_Input_a8 >>=8; const uint16_t u16LFB_R5G6B5_r5 = (u16FBI_Input_r8>>3) & 0x1F; const uint16_t u16LFB_R5G6B5_g6 = (u16FBI_Input_g8>>2) & 0x3F; const uint16_t u16LFB_R5G6B5_b5 = (u16FBI_Input_b8>>3) & 0x1F; const uint16_t u8LFB_R5G6B5_a8 = (u16FBI_Input_a8>>0) & 0xFF; const uint16_t u16LBF_R5G6B5_Pixel = (u16LFB_R5G6B5_r5 <<11) + (u16LFB_R5G6B5_g6<<5) + (u16LFB_R5G6B5_b5); const uint8_t u8LBF_R5G6B5_APixel = u8LFB_R5G6B5_a8; *pu16RenderedPixel = u16LBF_R5G6B5_Pixel; *pu8RenderedAPixel = u8LBF_R5G6B5_APixel; return 0; } */ /* In conjonction to the previous function, the idea here was to precompute all * the possible fault pattern and use them as a comparison to find the actual * one using real measurement. It is now deprecated in favor of the pattern * distance matching. * void simuFault( uint8_t bRGB, uint8_t bA ) { uint16_t u16RenderedPixel; uint8_t u8RenderedAPixel; uint32_t u16PreviousPixel = 0; uint16_t u8PreviousAPixel = 0; //for(char bitPos1 = -1; bitPos1 <= 15 ; ++bitPos1) //for(u8PreviousAPixel= 0; u8PreviousAPixel <= 0xFF ; ++u8PreviousAPixel) { //for(u16PreviousPixel= 0; u16PreviousPixel <= 0xFFFF ; ++u16PreviousPixel) { //u16PreviousPixel += (bitPos1 ==-1) ? 0 : (1u << bitPos1); uint16_t Pattern_OK; uint16_t APattern_OK; for(char bitPos = -1; bitPos <= 15 ; ++bitPos) { const uint16_t u16FaultMap = (bitPos ==-1) ? 0 : (1u << bitPos); simuFault_step( bRGB, bA, u16PreviousPixel, u8PreviousAPixel, &u16RenderedPixel, &u8RenderedAPixel, u16FaultMap); //if(u16FaultMap==0) //{ // Pattern_OK = u16RenderedPixel; // APattern_OK = u8RenderedAPixel; //} //else if(u16FaultMap==0x100) //{ // if((u16RenderedPixel!=Pattern_OK) && (u8RenderedAPixel!=APattern_OK)) // { // printf("bRGB %d\n",bRGB); // printf("bA, %d\n",bA); // printf("u16PreviousPixel %04X\n",u16PreviousPixel); // printf("u8PreviousAPixel %02X\n",u8PreviousAPixel); // printf("SIMU: %04X\n",u16FaultMap); // printf("\t0x%04X | 0x%02X %c\n", // u16RenderedPixel, // u8RenderedAPixel, // (u16RenderedPixel==0xFFFF) // && (u8RenderedAPixel==0xFF) ? '!' : ' '); // } //} printf("bRGB %d\n",bRGB); printf("bA, %d\n",bA); printf("u16PreviousPixel %04X\n",u16PreviousPixel); printf("u8PreviousAPixel %02X\n",u8PreviousAPixel); printf("SIMU: %04X\n",u16FaultMap); printf("\t0x%04X | 0x%02X %c\n", u16RenderedPixel, u8RenderedAPixel, (u16RenderedPixel==0xFFFF) && (u8RenderedAPixel==0xFF) ? '!' : ' '); } } } } */