|
|
|
@ -30,7 +30,11 @@
|
|
|
|
|
extern u32 vudump;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//#define DEBUG_COMPARE
|
|
|
|
|
int mVUdebugNow = 0;
|
|
|
|
|
|
|
|
|
|
//#define DEBUG_COMPARE // Run sVU or mVU and print results
|
|
|
|
|
//#define DEBUG_COMPARE2 // Runs both VU recs and breaks when results differ
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_COMPARE
|
|
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
@ -39,7 +43,7 @@ static int runAmount = 0;
|
|
|
|
|
void VUtestPause() {
|
|
|
|
|
|
|
|
|
|
runAmount++;
|
|
|
|
|
if (runAmount < 100) return;
|
|
|
|
|
if (runAmount < 654) return;
|
|
|
|
|
|
|
|
|
|
#ifndef PCSX2_MICROVU_
|
|
|
|
|
SysPrintf("Super VU - Pass %d\n", runAmount);
|
|
|
|
@ -48,13 +52,27 @@ void VUtestPause() {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 32; i++) {
|
|
|
|
|
SysPrintf("VF%02d = {%f, %f, %f, %f}\n", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]);
|
|
|
|
|
SysPrintf("VF%02d = {%f, %f, %f, %f}\n", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SysPrintf("ACC = {%f, %f, %f, %f}\n", VU1.ACC.F[0], VU1.ACC.F[1], VU1.ACC.F[2], VU1.ACC.F[3]);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
SysPrintf("VI%02d = % 8d ($%08x)\n", i, (s16)VU1.VI[i].UL, (s16)VU1.VI[i].UL);
|
|
|
|
|
SysPrintf("VI%02d = % 8d ($%08x)\n", i, (s16)VU1.VI[i].UL, (s16)VU1.VI[i].UL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SysPrintf("Stat = % 8d ($%08x)\n", (s16)VU1.VI[REG_STATUS_FLAG].UL, (s16)VU1.VI[REG_STATUS_FLAG].UL);
|
|
|
|
|
SysPrintf("MAC = % 8d ($%08x)\n", (s16)VU1.VI[REG_MAC_FLAG].UL, (s16)VU1.VI[REG_MAC_FLAG].UL);
|
|
|
|
|
SysPrintf("CLIP = % 8d ($%08x)\n", (s16)VU1.VI[REG_CLIP_FLAG].UL, (s16)VU1.VI[REG_CLIP_FLAG].UL);
|
|
|
|
|
|
|
|
|
|
SysPrintf("Q-reg = %f ($%08x)\n", VU1.VI[REG_Q].F, (s32)VU1.VI[REG_Q].UL);
|
|
|
|
|
SysPrintf("P-reg = %f ($%08x)\n", VU1.VI[REG_P].F, (s32)VU1.VI[REG_P].UL);
|
|
|
|
|
SysPrintf("I-reg = %f ($%08x)\n", VU1.VI[REG_I].F, (s32)VU1.VI[REG_I].UL);
|
|
|
|
|
|
|
|
|
|
SysPrintf("_Stat = % 8d ($%08x)\n", (s16)VU1.statusflag, (s16)VU1.statusflag);
|
|
|
|
|
SysPrintf("_MAC = % 8d ($%08x)\n", (s16)VU1.macflag, (s16)VU1.macflag);
|
|
|
|
|
SysPrintf("_CLIP = % 8d ($%08x)\n", (s16)VU1.clipflag, (s16)VU1.clipflag);
|
|
|
|
|
|
|
|
|
|
u32 j = 0;
|
|
|
|
|
for (int i = 0; i < (0x4000 / 4); i++) {
|
|
|
|
|
j ^= ((u32*)(VU1.Mem))[i];
|
|
|
|
@ -70,112 +88,178 @@ void VUtestPause() {
|
|
|
|
|
void VUtestPause() {}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef PCSX2_MICROVU_
|
|
|
|
|
|
|
|
|
|
namespace VU1micro
|
|
|
|
|
{
|
|
|
|
|
void recAlloc()
|
|
|
|
|
{
|
|
|
|
|
SuperVUAlloc(1);
|
|
|
|
|
}
|
|
|
|
|
#ifdef DEBUG_COMPARE2
|
|
|
|
|
|
|
|
|
|
void __fastcall recClear( u32 Addr, u32 Size )
|
|
|
|
|
{
|
|
|
|
|
assert( (Addr&7) == 0 );
|
|
|
|
|
SuperVUClear(Addr, Size, 1); // Size should be a multiple of 8 bytes!
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void recShutdown()
|
|
|
|
|
{
|
|
|
|
|
SuperVUDestroy( 1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// commented out because I'm not sure it actually works anymore with SuperVU (air)
|
|
|
|
|
/*static void iVU1DumpBlock()
|
|
|
|
|
{
|
|
|
|
|
FILE *f;
|
|
|
|
|
char filename[ g_MaxPath ];
|
|
|
|
|
u32 *mem;
|
|
|
|
|
u32 i;
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
CreateDirectory("dumps", NULL);
|
|
|
|
|
sprintf_s( filename, g_MaxPath, "dumps\\vu%.4X.txt", VU1.VI[ REG_TPC ].UL );
|
|
|
|
|
#else
|
|
|
|
|
mkdir("dumps", 0755);
|
|
|
|
|
sprintf( filename, "dumps/vu%.4X.txt", VU1.VI[ REG_TPC ].UL );
|
|
|
|
|
#endif
|
|
|
|
|
Console::WriteLn( "dump1 %x => %x (%s)", params VU1.VI[ REG_TPC ].UL, pc, filename );
|
|
|
|
|
|
|
|
|
|
f = fopen( filename, "wb" );
|
|
|
|
|
for ( i = VU1.VI[REG_TPC].UL; i < pc; i += 8 ) {
|
|
|
|
|
char* pstr;
|
|
|
|
|
mem = (u32*)&VU1.Micro[i];
|
|
|
|
|
|
|
|
|
|
pstr = disVU1MicroUF( mem[1], i+4 );
|
|
|
|
|
fprintf(f, "%x: %-40s ", i, pstr);
|
|
|
|
|
|
|
|
|
|
pstr = disVU1MicroLF( mem[0], i );
|
|
|
|
|
fprintf(f, "%s\n", pstr);
|
|
|
|
|
}
|
|
|
|
|
fclose( f );
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
static void recReset()
|
|
|
|
|
{
|
|
|
|
|
SuperVUReset(1);
|
|
|
|
|
|
|
|
|
|
// these shouldn't be needed, but shouldn't hurt anything either.
|
|
|
|
|
x86FpuState = FPU_STATE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void recStep()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void recExecuteBlock(void)
|
|
|
|
|
{
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
static u32 vuprogcount = 0;
|
|
|
|
|
vuprogcount++;
|
|
|
|
|
if( vudump & 8 ) __Log("start vu1: %x %x", VU1.VI[ REG_TPC ].UL, vuprogcount);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0){
|
|
|
|
|
//Console::WriteLn("Execute block VU1, VU1 not busy");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (VU1.VI[REG_TPC].UL >= VU1.maxmicro)
|
|
|
|
|
{
|
|
|
|
|
Console::Error("VU1 memory overflow!!: %x", params VU1.VI[REG_TPC].UL);
|
|
|
|
|
/*VU0.VI[REG_VPU_STAT].UL&= ~0x100;
|
|
|
|
|
VU1.cycle++;
|
|
|
|
|
return;*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert( (VU1.VI[ REG_TPC ].UL&7) == 0 );
|
|
|
|
|
#ifdef DEBUG_COMPARE
|
|
|
|
|
SysPrintf("StartPC = 0x%04x\n", VU1.VI[REG_TPC].UL);
|
|
|
|
|
#ifndef DEBUG_COMPARE
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
FreezeXMMRegs(1);
|
|
|
|
|
do { // while loop needed since not always will return finished
|
|
|
|
|
SuperVUExecuteProgram(VU1.VI[ REG_TPC ].UL & 0x3fff, 1);
|
|
|
|
|
} while( VU0.VI[ REG_VPU_STAT ].UL&0x100 );
|
|
|
|
|
FreezeXMMRegs(0);
|
|
|
|
|
|
|
|
|
|
VUtestPause();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
extern void initVUrec(VURegs* vuRegs, const int vuIndex);
|
|
|
|
|
extern void closeVUrec(const int vuIndex);
|
|
|
|
|
extern void resetVUrec(const int vuIndex);
|
|
|
|
|
extern void clearVUrec(u32 addr, u32 size, const int vuIndex);
|
|
|
|
|
extern void runVUrec(u32 startPC, u32 cycles, const int vuIndex);
|
|
|
|
|
|
|
|
|
|
PCSX2_ALIGNED16(u8 backVUregs[sizeof(VURegs)]);
|
|
|
|
|
PCSX2_ALIGNED16(u8 cmpVUregs [sizeof(VURegs)]);
|
|
|
|
|
PCSX2_ALIGNED16(u8 backVUmem [0x4000]);
|
|
|
|
|
PCSX2_ALIGNED16(u8 cmpVUmem [0x4000]);
|
|
|
|
|
static u32 runCount = 0;
|
|
|
|
|
#define VU3 ((VURegs)*((VURegs*)cmpVUregs))
|
|
|
|
|
#define cmpA Console::Error
|
|
|
|
|
#define cmpB Console::WriteLn
|
|
|
|
|
#define cmpPrint(cond) { \
|
|
|
|
|
if (cond) { \
|
|
|
|
|
cmpA("%s", params str1); \
|
|
|
|
|
cmpA("%s", params str2); \
|
|
|
|
|
} \
|
|
|
|
|
else { \
|
|
|
|
|
cmpB("%s", params str1); \
|
|
|
|
|
cmpB("%s", params str2); \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace VU1micro
|
|
|
|
|
{
|
|
|
|
|
void recAlloc() { SuperVUAlloc(1); initVUrec(&VU1, 1); }
|
|
|
|
|
void __fastcall recClear(u32 Addr, u32 Size) { SuperVUClear(Addr, Size, 1); clearVUrec(Addr, Size, 1); }
|
|
|
|
|
void recShutdown() { SuperVUDestroy(1); closeVUrec(1); }
|
|
|
|
|
static void recReset() { SuperVUReset(1); resetVUrec(1); x86FpuState = FPU_STATE; }
|
|
|
|
|
static void recStep() {}
|
|
|
|
|
|
|
|
|
|
static void recExecuteBlock(void)
|
|
|
|
|
{
|
|
|
|
|
if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return;
|
|
|
|
|
assert((VU1.VI[ REG_TPC ].UL&7) == 0);
|
|
|
|
|
if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) { Console::Error("VU1 memory overflow!!: %x", params VU1.VI[REG_TPC].UL); }
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_COMPARE
|
|
|
|
|
SysPrintf("(%08d) StartPC = 0x%04x\n", runAmount, VU1.VI[REG_TPC].UL);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
FreezeXMMRegs(1);
|
|
|
|
|
|
|
|
|
|
runCount++;
|
|
|
|
|
memcpy_fast((u8*)backVUregs, (u8*)&VU1, sizeof(VURegs));
|
|
|
|
|
memcpy_fast((u8*)backVUmem, (u8*)VU1.Mem, 0x4000);
|
|
|
|
|
|
|
|
|
|
do { // while loop needed since not always will return finished
|
|
|
|
|
SuperVUExecuteProgram(VU1.VI[ REG_TPC ].UL & 0x3fff, 1);
|
|
|
|
|
} while( VU0.VI[ REG_VPU_STAT ].UL&0x100 );
|
|
|
|
|
|
|
|
|
|
memcpy_fast((u8*)cmpVUregs, (u8*)&VU1, sizeof(VURegs));
|
|
|
|
|
memcpy_fast((u8*)cmpVUmem, (u8*)VU1.Mem, 0x4000);
|
|
|
|
|
memcpy_fast((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs));
|
|
|
|
|
memcpy_fast((u8*)VU1.Mem, (u8*)backVUmem, 0x4000);
|
|
|
|
|
|
|
|
|
|
runVUrec(VU1.VI[REG_TPC].UL, 300000 /*0x7fffffff*/, 1);
|
|
|
|
|
|
|
|
|
|
if ((memcmp((u8*)cmpVUregs, (u8*)&VU1, (16*32) + (16*16))) || (memcmp((u8*)cmpVUmem, (u8*)VU1.Mem, 0x4000))) {
|
|
|
|
|
char str1[150];
|
|
|
|
|
char str2[150];
|
|
|
|
|
SysPrintf("\n\n");
|
|
|
|
|
SysPrintf("-----------------------------------------------\n");
|
|
|
|
|
Console::Notice("Problem Occurred!");
|
|
|
|
|
SysPrintf("-----------------------------------------------\n");
|
|
|
|
|
SysPrintf("runCount = %d\n", runCount);
|
|
|
|
|
SysPrintf("StartPC [%04x]\n", ((VURegs*)backVUregs)->VI[REG_TPC].UL);
|
|
|
|
|
SysPrintf("-----------------------------------------------\n\n");
|
|
|
|
|
|
|
|
|
|
SysPrintf("-----------------------------------------------\n");
|
|
|
|
|
Console::Notice("Super VU / Micro VU");
|
|
|
|
|
SysPrintf("-----------------------------------------------\n");
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 32; i++) {
|
|
|
|
|
sprintf(str1, "VF%02d = {%f, %f, %f, %f}", i, VU3.VF[i].F[0], VU3.VF[i].F[1], VU3.VF[i].F[2], VU3.VF[i].F[3]);
|
|
|
|
|
sprintf(str2, "VF%02d = {%f, %f, %f, %f}", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]);
|
|
|
|
|
cmpPrint(((VU1.VF[i].UL[0] != VU3.VF[i].UL[0]) || (VU1.VF[i].UL[1] != VU3.VF[i].UL[1]) || (VU1.VF[i].UL[2] != VU3.VF[i].UL[2]) || (VU1.VF[i].UL[3] != VU3.VF[i].UL[3])));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "ACC = {%f, %f, %f, %f}", VU3.ACC.F[0], VU3.ACC.F[1], VU3.ACC.F[2], VU3.ACC.F[3]);
|
|
|
|
|
sprintf(str2, "ACC = {%f, %f, %f, %f}", VU1.ACC.F[0], VU1.ACC.F[1], VU1.ACC.F[2], VU1.ACC.F[3]);
|
|
|
|
|
cmpPrint(((VU1.ACC.F[0] != VU3.ACC.F[0]) || (VU1.ACC.F[1] != VU3.ACC.F[1]) || (VU1.ACC.F[2] != VU3.ACC.F[2]) || (VU1.ACC.F[3] != VU3.ACC.F[3])));
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
sprintf(str1, "VI%02d = % 8d ($%08x)", i, (s16)VU3.VI[i].UL, VU3.VI[i].UL);
|
|
|
|
|
sprintf(str2, "VI%02d = % 8d ($%08x)", i, (s16)VU1.VI[i].UL, VU1.VI[i].UL);
|
|
|
|
|
cmpPrint((VU1.VI[i].UL != VU3.VI[i].UL));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "Stat = % 8d ($%08x)", (s16)VU3.VI[REG_STATUS_FLAG].UL, VU3.VI[REG_STATUS_FLAG].UL);
|
|
|
|
|
sprintf(str2, "Stat = % 8d ($%08x)", (s16)VU1.VI[REG_STATUS_FLAG].UL, VU1.VI[REG_STATUS_FLAG].UL);
|
|
|
|
|
cmpPrint((VU1.VI[REG_STATUS_FLAG].UL != VU3.VI[REG_STATUS_FLAG].UL));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "MAC = % 8d ($%08x)", (s16)VU3.VI[REG_MAC_FLAG].UL, VU3.VI[REG_MAC_FLAG].UL);
|
|
|
|
|
sprintf(str2, "MAC = % 8d ($%08x)", (s16)VU1.VI[REG_MAC_FLAG].UL, VU1.VI[REG_MAC_FLAG].UL);
|
|
|
|
|
cmpPrint((VU1.VI[REG_MAC_FLAG].UL != VU3.VI[REG_MAC_FLAG].UL));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "CLIP = % 8d ($%08x)", (s16)VU3.VI[REG_CLIP_FLAG].UL, VU3.VI[REG_CLIP_FLAG].UL);
|
|
|
|
|
sprintf(str2, "CLIP = % 8d ($%08x)", (s16)VU1.VI[REG_CLIP_FLAG].UL, VU1.VI[REG_CLIP_FLAG].UL);
|
|
|
|
|
cmpPrint((VU1.VI[REG_CLIP_FLAG].UL != VU3.VI[REG_CLIP_FLAG].UL));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "Q-reg = %f ($%08x)", VU3.VI[REG_Q].F, VU3.VI[REG_Q].UL);
|
|
|
|
|
sprintf(str2, "Q-reg = %f ($%08x)", VU1.VI[REG_Q].F, VU1.VI[REG_Q].UL);
|
|
|
|
|
cmpPrint((VU1.VI[REG_Q].UL != VU3.VI[REG_Q].UL));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "P-reg = %f ($%08x)", VU3.VI[REG_P].F, VU3.VI[REG_P].UL);
|
|
|
|
|
sprintf(str2, "P-reg = %f ($%08x)", VU1.VI[REG_P].F, VU1.VI[REG_P].UL);
|
|
|
|
|
cmpPrint((VU1.VI[REG_P].UL != VU3.VI[REG_P].UL));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "I-reg = %f ($%08x)", VU3.VI[REG_I].F, VU3.VI[REG_I].UL);
|
|
|
|
|
sprintf(str2, "I-reg = %f ($%08x)", VU1.VI[REG_I].F, VU1.VI[REG_I].UL);
|
|
|
|
|
cmpPrint((VU1.VI[REG_I].UL != VU3.VI[REG_I].UL));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "_Stat = % 8d ($%08x)", (s16)VU3.statusflag, VU3.statusflag);
|
|
|
|
|
sprintf(str2, "_Stat = % 8d ($%08x)", (s16)VU1.statusflag, VU1.statusflag);
|
|
|
|
|
cmpPrint((VU1.statusflag != VU3.statusflag));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "_MAC = % 8d ($%08x)", (s16)VU3.macflag, VU3.macflag);
|
|
|
|
|
sprintf(str2, "_MAC = % 8d ($%08x)", (s16)VU1.macflag, VU1.macflag);
|
|
|
|
|
cmpPrint((VU1.macflag != VU3.macflag));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "_CLIP = % 8d ($%08x)", (s16)VU3.clipflag, VU3.clipflag);
|
|
|
|
|
sprintf(str2, "_CLIP = % 8d ($%08x)", (s16)VU1.clipflag, VU1.clipflag);
|
|
|
|
|
cmpPrint((VU1.clipflag != VU3.clipflag));
|
|
|
|
|
|
|
|
|
|
u32 j = 0;
|
|
|
|
|
u32 z = 0;
|
|
|
|
|
for (int i = 0; i < (0x4000 / 4); i++) {
|
|
|
|
|
j ^= ((u32*)(cmpVUmem))[i];
|
|
|
|
|
z ^= ((u32*)(VU1.Mem)) [i];
|
|
|
|
|
}
|
|
|
|
|
sprintf(str1, "VU Mem CRC = 0x%08x", j);
|
|
|
|
|
sprintf(str2, "VU Mem CRC = 0x%08x", z);
|
|
|
|
|
cmpPrint((j != z));
|
|
|
|
|
|
|
|
|
|
sprintf(str1, "EndPC = 0x%04x", VU3.VI[REG_TPC].UL);
|
|
|
|
|
sprintf(str2, "EndPC = 0x%04x", VU1.VI[REG_TPC].UL);
|
|
|
|
|
cmpPrint((VU1.VI[REG_TPC].UL != VU3.VI[REG_TPC].UL));
|
|
|
|
|
|
|
|
|
|
SysPrintf("-----------------------------------------------\n\n");
|
|
|
|
|
|
|
|
|
|
mVUdebugNow = 1;
|
|
|
|
|
resetVUrec(1);
|
|
|
|
|
memcpy_fast((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs));
|
|
|
|
|
memcpy_fast((u8*)VU1.Mem, (u8*)backVUmem, 0x4000);
|
|
|
|
|
|
|
|
|
|
runVUrec(VU1.VI[REG_TPC].UL, 300000 /*0x7fffffff*/, 1);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 10000000; i++) {
|
|
|
|
|
Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
VUtestPause();
|
|
|
|
|
FreezeXMMRegs(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
#ifdef PCSX2_MICROVU_
|
|
|
|
|
|
|
|
|
|
extern void initVUrec(VURegs* vuRegs, const int vuIndex);
|
|
|
|
|
extern void closeVUrec(const int vuIndex);
|
|
|
|
|
extern void resetVUrec(const int vuIndex);
|
|
|
|
|
extern void clearVUrec(u32 addr, u32 size, const int vuIndex);
|
|
|
|
|
extern void runVUrec(u32 startPC, u32 cycles, const int vuIndex);
|
|
|
|
|
|
|
|
|
|
namespace VU1micro
|
|
|
|
|
{
|
|
|
|
@ -190,7 +274,7 @@ namespace VU1micro
|
|
|
|
|
assert( (VU1.VI[REG_TPC].UL&7) == 0 );
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_COMPARE
|
|
|
|
|
SysPrintf("StartPC = 0x%04x\n", VU1.VI[REG_TPC].UL);
|
|
|
|
|
SysPrintf("(%08d) StartPC = 0x%04x\n", runAmount, VU1.VI[REG_TPC].UL);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
FreezeXMMRegs(1);
|
|
|
|
@ -202,6 +286,34 @@ namespace VU1micro
|
|
|
|
|
VUtestPause();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
namespace VU1micro
|
|
|
|
|
{
|
|
|
|
|
void recAlloc() { SuperVUAlloc(1); }
|
|
|
|
|
void __fastcall recClear(u32 Addr, u32 Size) { SuperVUClear(Addr, Size, 1); }
|
|
|
|
|
void recShutdown() { SuperVUDestroy(1); }
|
|
|
|
|
static void recReset() { SuperVUReset(1); x86FpuState = FPU_STATE; }
|
|
|
|
|
static void recStep() {}
|
|
|
|
|
|
|
|
|
|
static void recExecuteBlock(void)
|
|
|
|
|
{
|
|
|
|
|
if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return;
|
|
|
|
|
if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) { Console::Error("VU1 memory overflow!!: %x", params VU1.VI[REG_TPC].UL); }
|
|
|
|
|
assert((VU1.VI[ REG_TPC ].UL&7) == 0);
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_COMPARE
|
|
|
|
|
SysPrintf("(%08d) StartPC = 0x%04x\n", runAmount, VU1.VI[REG_TPC].UL);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
FreezeXMMRegs(1);
|
|
|
|
|
do { // while loop needed since not always will return finished
|
|
|
|
|
SuperVUExecuteProgram(VU1.VI[ REG_TPC ].UL & 0x3fff, 1);
|
|
|
|
|
} while( VU0.VI[ REG_VPU_STAT ].UL&0x100 );
|
|
|
|
|
FreezeXMMRegs(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
using namespace VU1micro;
|
|
|
|
|