This commit is contained in:
chacha
2026-02-27 21:44:24 +00:00
parent a0faa8661d
commit 496f032734
7 changed files with 1262 additions and 1015 deletions

111
Draw.c
View File

@@ -25,36 +25,85 @@
#define ST_ONE (1 << SST_ST_FRACBITS)
#define W_ONE (1 << SST_W_FRACBITS)
void
drawSquare( const SstRegs *sst,
const int x,
const int y,
const int tSize)
typedef struct _def_sPoint
{
ISET(sst->vA.x,x);
ISET(sst->vA.y,y);
ISET(sst->vB.x,x+XY_ONE*tSize);
ISET(sst->vB.y,y);
ISET(sst->vC.x,x);
ISET(sst->vC.y,y+XY_ONE*tSize);
ISET(sst->s,0);
ISET(sst->t,0);
ISET(sst->w,W_ONE);
ISET(sst->dsdx,ST_ONE);
ISET(sst->dtdx,0);
ISET(sst->dwdx,0);
ISET(sst->dsdy,0);
ISET(sst->dtdy,ST_ONE);
ISET(sst->dwdy,0);
ISET(sst->triangleCMD,0);
ISET(sst->vA.x,x);
ISET(sst->vA.y,y+XY_ONE*tSize);
ISET(sst->vB.x,x+XY_ONE*tSize);
ISET(sst->vB.y,y);
ISET(sst->vC.x, x+XY_ONE*tSize);
ISET(sst->vC.y, y+XY_ONE*tSize);
ISET(sst->s,0);
ISET(sst->t,ST_ONE*tSize);
ISET(sst->w,W_ONE);
ISET(sst->triangleCMD, 0xFFFFFFFF);
int16_t x;
int16_t y;
}def_sPoint;
typedef struct _def_sTriangle
{
def_sPoint vA;
def_sPoint vB;
def_sPoint vC;
int32_t s;
int32_t t;
int32_t w;
int32_t dsdx;
int32_t dtdx;
int32_t dwdx;
int32_t dsdy;
int32_t dtdy;
int32_t dwdy;
}def_sTriangle;
static inline uint32_t v2_triangle_cmd_from_abc(const def_sPoint A,
const def_sPoint B,
const def_sPoint C)
{
const int32_t abx = (int32_t)B.x - (int32_t)A.x;
const int32_t aby = (int32_t)B.y - (int32_t)A.y;
const int32_t acx = (int32_t)C.x - (int32_t)A.x;
const int32_t acy = (int32_t)C.y - (int32_t)A.y;
const int64_t s = (int64_t )abx * (int64_t )acy - (int64_t )aby * (int64_t )acx;
return (s < 0) ? 0x80000000u : 0u;
}
static void inline drawTriangle(const SstRegs * const sst, const def_sTriangle * const sTri)
{
ISET(sst->vA.x, sTri->vA.x*XY_ONE); ISET(sst->vA.y, sTri->vA.y*XY_ONE);
ISET(sst->vB.x, sTri->vB.x*XY_ONE); ISET(sst->vB.y, sTri->vB.y*XY_ONE);
ISET(sst->vC.x, sTri->vC.x*XY_ONE); ISET(sst->vC.y, sTri->vC.y*XY_ONE);
ISET(sst->s, sTri->s*ST_ONE);
ISET(sst->t, sTri->t*ST_ONE);
ISET(sst->w, sTri->w*W_ONE);
ISET(sst->dsdx, sTri->dsdx*ST_ONE);
ISET(sst->dtdx, sTri->dtdx*ST_ONE);
ISET(sst->dwdx, sTri->dwdx*W_ONE);
ISET(sst->dsdy, sTri->dsdy*ST_ONE);
ISET(sst->dtdy, sTri->dtdy*ST_ONE);
ISET(sst->dwdy, sTri->dwdy*W_ONE);
ISET(sst->triangleCMD,v2_triangle_cmd_from_abc(sTri->vA, sTri->vB, sTri->vC));
}
void
drawSquare( const SstRegs * const sst,
const int16_t x,
const int16_t y,
const int16_t tSize)
{
const def_sTriangle tri1 = {
.vA = {.x= (x+0), .y = (y+0)},
.vB = {.x= (x+tSize), .y = (y+0)},
.vC = {.x= (x+0), .y = (y+tSize)},
.s = 0,
.t = 0,
.w = 1,
.dsdx = 1, .dtdx = 0,
.dwdx = 0
.dsdy = 0, .dtdy = 1,
.dwdy = 0};
drawTriangle(sst, &tri1);
const def_sTriangle tri2 = {
.vA = {.x= (x+0), .y = (y+tSize)},
.vB = {.x= (x+tSize), .y = (y+0)},
.vC = {.x= (x+tSize), .y = (y+tSize)},
.s = 0,
.t = tSize,
.w = 1,
.dsdx = 1, .dtdx = 0,
.dwdx = 0
.dsdy = 0, .dtdy = 1,
.dwdy = 0 };
drawTriangle(sst, &tri2);
}

8
Draw.h
View File

@@ -19,9 +19,9 @@
#define _DEF_DRAW_H_
void
drawSquare( const SstRegs *sst,
const int x,
const int y,
const int tSize);
drawSquare( const SstRegs * const sst,
const int16_t x,
const int16_t y,
const int16_t tSize);
#endif //_DEF_DRAW_H_

View File

@@ -28,7 +28,8 @@ def_sFaultSourceScoreRec ar_dFaultScores[NB_FAULT_SOURCE] =
.szName = "VOODOO_BOARD",
.szLoc = "Main Board",
.eParrentFaultSource = _INVALID_FAULT_SOURCE_,
.dScore = 0.0
.dScore = 0.0,
.dWeight = 1.0,
},
FAULT_SOURCES(GEN_FAULT_SOURCES_ARRAY)
};
@@ -92,6 +93,10 @@ FaultSource_Sort()
unsigned char bSwapped = 1;
memcpy(ar_dFaultScores_sorted,ar_dFaultScores,sizeof(ar_dFaultScores_sorted));
for(long eFaultSourceCurrentComp=0;
eFaultSourceCurrentComp < (NB_FAULT_SOURCE - 1);
eFaultSourceCurrentComp++ )
ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore *= ar_dFaultScores_sorted[eFaultSourceCurrentComp].dWeight;
// shaker sort
while(bSwapped)

File diff suppressed because it is too large Load Diff

32
Utils.h
View File

@@ -20,6 +20,38 @@
#include <stdint.h>
#include "V2MemTest.h"
#define ErrorCheck() \
do{ \
if(Status < 0) \
{ \
if(Status <= E_INVALID_ERROR_CODE) \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__,szErrorMsg[DEF_UNKNOWN_ERROR_IDX]); \
else \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__, \
szErrorMsg[DEF_GET_ERROR_IDX(Status)]); \
return Status; \
} \
}while(0)
#define ErrorCheck_gotoCleanUp() \
do{ \
if(Status < 0) \
{ \
if(Status <= E_INVALID_ERROR_CODE) \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__,szErrorMsg[DEF_UNKNOWN_ERROR_IDX]); \
else \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__, \
szErrorMsg[DEF_GET_ERROR_IDX(Status)]); \
goto cleanUp; \
} \
}while(0)
static inline unsigned char
count_bit32(const uint32_t ulVal)
{

View File

@@ -5,46 +5,60 @@
#define V2MEMTEST__VERSION__MINOR 1
#define V2MEMTEST__VERSION__PATCH 0
typedef enum _def_eTestType {
E_TESTTYPE__ADDRESS,
E_TESTTYPE__DATA__BITMOVE,
E_TESTTYPE__DATA__RANDOM,
E_TESTTYPE__DATA__HUGE,
E_TESTTYPE__DATA__ALL,
}def_eTestType;
typedef enum _def_eTMUTarget {
E_TMUTARGET__0,
E_TMUTARGET__1,
E_TMUTARGET__BOTH,
}def_eTMUTarget;
#include <stdbool.h>
typedef enum _def_eTMURamLimit {
E_TMUTARGET__1MB,
E_TMUTARGET__2MB,
E_TMUTARGET__3MB,
E_TMUTARGET__4MB,
}def_eTMURamLimit;
E_TMU_RAMSIZE__1MB,
E_TMU_RAMSIZE__2MB,
E_TMU_RAMSIZE__3MB,
E_TMU_RAMSIZE__4MB,
E_TMU_RAMSIZE__AUTO,
}def_eTMU_RamLimit;
typedef enum _def_eLogLevel {
E_LOGLEVEL__ERROR,
E_LOGLEVEL__WARNING,
E_LOGLEVEL__INFO,
E_LOGLEVEL__DEBUG,
E_LOGLEVEL__TRACE,
E_LOGLEVEL__ERROR = 0,
E_LOGLEVEL__WARNING = 1,
E_LOGLEVEL__INFO = 2,
E_LOGLEVEL__DEBUG = 3,
E_LOGLEVEL__TRACE = 4,
}def_eLogLevel;
#define DEF_BASE_ERRROR -1000
#define DEF_NO_ERROR_IDX 0
#define DEF_UNKNOWN_ERROR_IDX 1
#define DEF_GET_ERROR_IDX(CODE) -(DEF_BASE_ERRROR-CODE)
typedef enum _def_eErrorCode {
E_ERROR__NO_ERROR = 0,
E_ERROR__UNKNOWN_ERROR = -1,
E_ERROR__UNKNOWN_ARGUMENT = DEF_BASE_ERRROR,
E_ERROR__BAD_ARGUMENT_VALUE,
E_ERROR__SST1_INIT
E_ERROR__SST1_GET_INFO
}def_eErrorCode;
extern const char* szErrorMsg[];
typedef struct _def_sOptions
{
unsigned char bLogStdOut;
def_eLogLevel eLogLevel;
bool bSilent;
char szLogFileName[2048];
char szTSVFile[2048];
unsigned short usNbLoops;
def_eTestType eTestType;
def_eTMUTarget eTMUTarget;
def_eLogLevel eLogLevel;
def_eTMURamLimit eTMURamLimit;
unsigned short usNumLoops;
bool bForceTestTMU0;
def_eTMURamLimit eTMU0RamLimit;
bool bForceTestTMU1;
def_eTMURamLimit eTMU1RamLimit;
bool bForceTestTMUAddress;
bool bForceTestTMUData;
bool bForceTestTMUDataHuge;
bool bOnlyHelp;
} def_sOptions;
extern def_sOptions sOptions;

208
main.c
View File

@@ -21,6 +21,7 @@
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "cvg.h"
#include <glide.h>
@@ -36,6 +37,17 @@
#include "Test_Data.h"
#include "Test_Data_Huge.h"
const char* szErrorMsg[] =
{
"No Error", // E_ERROR__NO_ERROR
"Unknown Error", // E_ERROR__UNKNOWN_ERROR
"Unknown argument found in command line", // E_ERROR__UNKNOWN_ARGUMENT
"Wrong argument value", // E_ERROR__BAD_ARGUMENT_VALUE
"E_ERROR__SST1_INIT", //E_ERROR__SST1_INIT,
"E_ERROR__SST1_GET_INFO", //E_ERROR__SST1_GET_INFO,
"E_ERROR__NOT_ENOUGH_FBI_RAM", //E_ERROR__NOT_ENOUGH_FBI_RAM,
}
const char szTitle[] =
"V2MemTest-%d.%d.%d - A CLI Tool to test & fix Voodoo² TMU System\n"
"Copyright (C) 2026 ChaCha\n";
@@ -51,6 +63,7 @@ const char szHelp[] =
"Usage ./v2memtest <options>\n"
"\n"
"options:\n"
"\t--help:\n"
"\t-h :\tthis output\n"
"\n"
"\t-v <level> :\tset log level to the specified value.\n"
@@ -65,67 +78,198 @@ const char szHelp[] =
def_sOptions sOptions = {
.eLogLevel = E_LOGLEVEL__WARNING,
.bLogStdOut = 1,
.eLogLevel = E_LOGLEVEL__ERROR,
.bSilent = false,
.szLogFileName = {0},
.szTSVFile = {0},
.usNbLoops = 1,
.usNumLoops = 1,
.bTestTMU0 = false;
.eTMU0RamLimit = E_TMU_RAMSIZE__AUTO,
.bTestTMU1 = false;
.eTMU1RamLimit = E_TMU_RAMSIZE__AUTO,
.bTestTMUAddress = false,
.bTestTMUData = false,
.bTestTMUDataHuge = false,
.bQuit = false;
};
static struct option long_args[] = {
/* {<NAME>, <HAS_ARG>, <FLAG>, <VAL> */
{"help", no_argument, NULL, 'h'},
{"num", required_argument, NULL, 'n'},
{"log", required_argument, NULL, 'l'},
{"silent", no_argument, &sOptions.bSilent, true},
{"tsv", required_argument, NULL, 't'},
{"tmu0", no_argument, &sOptions.bTestTMU0, true},
{"tmu1", no_argument, &sOptions.bTestTMU1, true},
{"address", no_argument, &sOptions.bTestTMUAddress, true},
{"data", no_argument, &sOptions.bTestTMUData, true},
{"data-huge", no_argument, &sOptions.bTestTMUDataHuge, true},
{"tmu0-ram", required_argument, NULL, 0},
{"tmu0-ram", required_argument, NULL, 1},
{"version", no_argument, NULL, 2},
};
int main(int argc, char **argv)
{
int Status = 0;
unsigned long long ullNbErrorAll = 0;
const unsigned char boardNum = 0;
int option_index = 0;
int opt;
while((opt=getopt_long(argc,argv,"hvn:e:l:",long_args,&option_index)) != -1)
{
switch(opt)
{
case 2: // Version
printf("%d.%d.%d", V2MEMTEST__VERSION__MAJOR,
V2MEMTEST__VERSION__MINOR,
V2MEMTEST__VERSION__PATCH);
bQuit = true;
break;
case 0: // TMU0 long options
case 1: // TMU1 long options
long memval = strtol(optarg, NULL, 10);
def_eTMU_RamLimit newRAMLimit;
switch(memval)
{
case -1: newRAMLimit = E_TMU_RAMSIZE__AUTO; break;
case 1: newRAMLimit = E_TMU_RAMSIZE__1MB; break;
case 2: newRAMLimit = E_TMU_RAMSIZE__2MB; break;
case 3: newRAMLimit = E_TMU_RAMSIZE__3MB; break;
case 4: newRAMLimit = E_TMU_RAMSIZE__4MB; break;
default:
Status = E_ERROR__BAD_ARGUMENT_VALUE;
ErrorCheck_gotoCleanUp()
break;
}
if(opt==0) sOptions.eTMU0RamLimit = newRAMLimit;
else sOptions.eTMU1RamLimit = newRAMLimit;
break;
case '?':
puts(szHelp);
Status = E_ERROR__UNKNOWN_ARGUMENT;
ErrorCheck_gotoCleanUp();
break;
case 'l':
strcpy_s(sOptions.szLogFileName,optarg,2048);
break;
case 't':
strcpy_s(sOptions.szTSVFile,optarg,2048);
break;
case 'h':
puts(szHelp);
bQuit = true;
break;
case 'n':
sOptions.usNumLoops = strtol(optarg, NULL, 10);
break;
case 'v':
if(sOptions.eLogLevel < E_LOGLEVEL__TRACE)
sOptions.eLogLevel++;
break;
default:
Status = E_ERROR__UNKNOWN_ERROR;
ErrorCheck_gotoCleanUp();
break;
}
}
if(bQuit)
return 0;
if(!bTestTMU0 && !bTestTMU1)
{
bTestTMU0 = true;
bTestTMU1 = true;
}
if(!bTestTMUAddress && !bTestTMUData && !bTestTMUDataHuge)
{
bTestTMUAddress = true;
bTestTMUData = true;
bTestTMUDataHuge = true;
}
sst1DeviceInfoStruct devInfo;
FxU32* sst;
SstRegs *sstregs;
memset(devInfo,0,sizeof(sst1DeviceInfoStruct));
FxU32* sst = NULL;
SstRegs *sstregs = NULL;
printf(szTitle, V2MEMTEST__VERSION__MAJOR,
V2MEMTEST__VERSION__MINOR,
V2MEMTEST__VERSION__PATCH);
putchar('\n');
puts(szLicence);
putchar('\n');
if(!sOptions.bSilent)
{
printf(szTitle, V2MEMTEST__VERSION__MAJOR,
V2MEMTEST__VERSION__MINOR,
V2MEMTEST__VERSION__PATCH);
putchar('\n');
puts(szLicence);
putchar('\n');
}
srandom(time(NULL));
FaultSource_Reset();
for(int j=0; j<100; j++)
{
if ((sst = sst1InitMapBoard(boardNum)) == NULL)
{
fprintf(stderr, "No Voodoo boards found\n");
exit(-1);
Status = E_ERROR__SST1_INIT;
ErrorCheck_gotoCleanUp();
}
sst1InitRegisters(sst);
sstregs = (SstRegs *) sst;
if (sst1InitGetDeviceInfo(sst, &devInfo) == FXFALSE)
{
fprintf(stderr, "Couldn't get info for Voodoo # %d\n", boardNum);
exit(-1);
Status = E_ERROR__SST1_GET_INFO;
ErrorCheck_gotoCleanUp();
}
printf("FBI detected Memory: %lu MB\n", devInfo.fbiMemSize);
if(devInfo.fbiMemSize < 2)
{
fprintf(stderr, "Couldn't test Voodoo2 TMUs without minimum 2MB of FBI memory\n");
Status = E_ERROR__NOT_ENOUGH_FBI_RAM;
ErrorCheck_gotoCleanUp();
}
/*
grGlideInit();
GrHwConfiguration hwconfig;
if(!grSstQueryHardware(&hwconfig))
{
fprintf(stderr, "Couldn't get glide info for Voodoo # %d\n", boardNum);
exit(-1);
}
grSstSelect(boardNum);
*/
sstregs = (SstRegs *) sst;
printf("FBI Memory: %lu MB\n", devInfo.fbiMemSize);
for (int tmu = 0; tmu < devInfo.numberTmus; tmu++)
{
printf("TMU %d RAM: %lu MB\n", tmu, devInfo.tmuMemSize[tmu]);
printf("TMU%d detected Memory: %lu MB\n", tmu, devInfo.tmuMemSize[tmu]);
}
putchar('\n');
/*
bTestTMU0 = true;
bTestTMU1 = true;
*/
const bool bTestTMU0 = (devInfo.numberTmus > 0)
&& (devInfo.tmuMemSize[0] > 0)
&& sOptions.bTestTMU0;
const bool bTestTMU1 = (devInfo.numberTmus > 1)
&& (devInfo.tmuMemSize[1] > 0)
&& sOptions.bTestTMU1;
if(!bTestTMU0 && !bTestTMU1)
{
printf("no testable TMU\n");
goto CleanUp;
}
if(bTestTMU1 && !bTestTMU0)
{
printf("Warning, testing TMU1 without TMU0 is not recommended !\n");
}
ISET(sstregs->lfbMode, SST_LFB_RGBALANES_ARGB | SST_LFB_READFRONTBUFFER);
ISET(sstregs->fbzMode, SST_DRAWBUFFER_FRONT | SST_RGBWRMASK);
@@ -208,7 +352,9 @@ int main(int argc, char **argv)
FaultSource_Display();
printf("Test Complete, ullNbErrorAll = %lld\n",ullNbErrorAll);
//grGlideShutdown();
pciClose();
return 0;
CleanUp:
if(sst)
sst1InitShutdown(sst);
return Status;
}