mirror of https://github.com/PCSX2/pcsx2.git
microVU:
- Properly fixed problems from r1254, a lot of games should be fixed. pcsx2/microVU: - Added some debug code that runs sVU and mVU, and compares their results. If they differ, then the game is halted, and debug info is given. (this can be enabled in iVU1micro.cpp with the DEBUG_COMPARE2 macro)... the code is a bit messy, but it gets the job done for now. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1265 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
0900ef5420
commit
22535ad886
|
@ -30,7 +30,11 @@
|
||||||
extern u32 vudump;
|
extern u32 vudump;
|
||||||
#endif
|
#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
|
#ifdef DEBUG_COMPARE
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -39,7 +43,7 @@ static int runAmount = 0;
|
||||||
void VUtestPause() {
|
void VUtestPause() {
|
||||||
|
|
||||||
runAmount++;
|
runAmount++;
|
||||||
if (runAmount < 100) return;
|
if (runAmount < 654) return;
|
||||||
|
|
||||||
#ifndef PCSX2_MICROVU_
|
#ifndef PCSX2_MICROVU_
|
||||||
SysPrintf("Super VU - Pass %d\n", runAmount);
|
SysPrintf("Super VU - Pass %d\n", runAmount);
|
||||||
|
@ -51,10 +55,24 @@ void VUtestPause() {
|
||||||
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++) {
|
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;
|
u32 j = 0;
|
||||||
for (int i = 0; i < (0x4000 / 4); i++) {
|
for (int i = 0; i < (0x4000 / 4); i++) {
|
||||||
j ^= ((u32*)(VU1.Mem))[i];
|
j ^= ((u32*)(VU1.Mem))[i];
|
||||||
|
@ -70,112 +88,178 @@ void VUtestPause() {
|
||||||
void VUtestPause() {}
|
void VUtestPause() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PCSX2_MICROVU_
|
|
||||||
|
|
||||||
namespace VU1micro
|
#ifdef DEBUG_COMPARE2
|
||||||
{
|
|
||||||
void recAlloc()
|
|
||||||
{
|
|
||||||
SuperVUAlloc(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __fastcall recClear( u32 Addr, u32 Size )
|
#ifndef DEBUG_COMPARE
|
||||||
{
|
#include <windows.h>
|
||||||
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
|
#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);
|
|
||||||
#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 initVUrec(VURegs* vuRegs, const int vuIndex);
|
||||||
extern void closeVUrec(const int vuIndex);
|
extern void closeVUrec(const int vuIndex);
|
||||||
extern void resetVUrec(const int vuIndex);
|
extern void resetVUrec(const int vuIndex);
|
||||||
extern void clearVUrec(u32 addr, u32 size, const int vuIndex);
|
extern void clearVUrec(u32 addr, u32 size, const int vuIndex);
|
||||||
extern void runVUrec(u32 startPC, u32 cycles, 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
|
namespace VU1micro
|
||||||
{
|
{
|
||||||
|
@ -190,7 +274,7 @@ namespace VU1micro
|
||||||
assert( (VU1.VI[REG_TPC].UL&7) == 0 );
|
assert( (VU1.VI[REG_TPC].UL&7) == 0 );
|
||||||
|
|
||||||
#ifdef DEBUG_COMPARE
|
#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
|
#endif
|
||||||
|
|
||||||
FreezeXMMRegs(1);
|
FreezeXMMRegs(1);
|
||||||
|
@ -202,6 +286,34 @@ namespace VU1micro
|
||||||
VUtestPause();
|
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
|
#endif
|
||||||
|
|
||||||
using namespace VU1micro;
|
using namespace VU1micro;
|
||||||
|
|
|
@ -132,6 +132,9 @@ extern PCSX2_ALIGNED16(microVU microVU1);
|
||||||
extern void (*mVU_UPPER_OPCODE[64])( VURegs* VU, s32 info );
|
extern void (*mVU_UPPER_OPCODE[64])( VURegs* VU, s32 info );
|
||||||
extern void (*mVU_LOWER_OPCODE[128])( VURegs* VU, s32 info );
|
extern void (*mVU_LOWER_OPCODE[128])( VURegs* VU, s32 info );
|
||||||
|
|
||||||
|
// Debug Helper
|
||||||
|
extern int mVUdebugNow;
|
||||||
|
|
||||||
// Main Functions
|
// Main Functions
|
||||||
microVUt(void) mVUinit(VURegs*);
|
microVUt(void) mVUinit(VURegs*);
|
||||||
microVUx(void) mVUreset();
|
microVUx(void) mVUreset();
|
||||||
|
|
|
@ -731,7 +731,7 @@ microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
|
||||||
}
|
}
|
||||||
if (_reg_ == 0) { return; }
|
if (_reg_ == 0) { return; }
|
||||||
else if (isMMX(_reg_)) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); }
|
else if (isMMX(_reg_)) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); }
|
||||||
else if (_reg_ < 16) { MOV32RtoRm(gprR, GPRreg, (_reg_ - 9) * 16); }
|
else if (_reg_ < 16) { MOV16RtoRm(gprR, GPRreg, (_reg_ - 9) * 16); }
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -184,10 +184,13 @@ microVUt(void) mVUendProgram(int qInst, int pInst, int fStatus, int fMac, int fC
|
||||||
|
|
||||||
void __fastcall mVUwarning0(u32 PC) { Console::Error("microVU0 Warning: Exiting from Possible Infinite Loop [%04x]", params PC); }
|
void __fastcall mVUwarning0(u32 PC) { Console::Error("microVU0 Warning: Exiting from Possible Infinite Loop [%04x]", params PC); }
|
||||||
void __fastcall mVUwarning1(u32 PC) { Console::Error("microVU1 Warning: Exiting from Possible Infinite Loop [%04x]", params PC); }
|
void __fastcall mVUwarning1(u32 PC) { Console::Error("microVU1 Warning: Exiting from Possible Infinite Loop [%04x]", params PC); }
|
||||||
|
void __fastcall mVUprintPC1(u32 PC) { Console::WriteLn("Block startPC [%04x]", params PC); }
|
||||||
|
void __fastcall mVUprintPC2(u32 PC) { Console::WriteLn("Block endPC [%04x]\n", params PC); }
|
||||||
|
|
||||||
microVUt(void) mVUtestCycles() {
|
microVUt(void) mVUtestCycles() {
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
iPC = mVUstartPC;
|
iPC = mVUstartPC;
|
||||||
|
mVUdebugNOW(0);
|
||||||
CMP32ItoM((uptr)&mVU->cycles, 0);
|
CMP32ItoM((uptr)&mVU->cycles, 0);
|
||||||
u8* jmp8 = JG8(0);
|
u8* jmp8 = JG8(0);
|
||||||
MOV32ItoR(gprT2, xPC);
|
MOV32ItoR(gprT2, xPC);
|
||||||
|
@ -280,6 +283,7 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
|
||||||
microBlock* bBlock = NULL;
|
microBlock* bBlock = NULL;
|
||||||
u32* ajmp = 0;
|
u32* ajmp = 0;
|
||||||
mVUsetupRange<vuIndex>(xPC);
|
mVUsetupRange<vuIndex>(xPC);
|
||||||
|
mVUdebugNOW(1);
|
||||||
|
|
||||||
switch (mVUbranch) {
|
switch (mVUbranch) {
|
||||||
case 3: branchCase(JE32, JNE32); // IBEQ
|
case 3: branchCase(JE32, JNE32); // IBEQ
|
||||||
|
|
|
@ -203,7 +203,7 @@ microVUt(void) mVUflagPass(int startPC) {
|
||||||
if (mVUbranch) { branch = 3; mVUbranch = 0; }
|
if (mVUbranch) { branch = 3; mVUbranch = 0; }
|
||||||
incPC(1);
|
incPC(1);
|
||||||
}
|
}
|
||||||
//if (mVUcount < 4) { mVUflagInfo |= 0xfff; } // Is this Too Slow? 99% of games probably don't need this.
|
if (mVUcount < 4) { mVUflagInfo |= 0xfff; }
|
||||||
iPC = oldPC;
|
iPC = oldPC;
|
||||||
mVUcount = oldCount;
|
mVUcount = oldCount;
|
||||||
mVUbranch = oldBranch;
|
mVUbranch = oldBranch;
|
||||||
|
|
|
@ -1131,8 +1131,10 @@ microVUf(void) mVU_XGKICK() {
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
#define setBranchA(x, _x_) { \
|
#define setBranchA(x, _x_) { \
|
||||||
mVUbranch = x; \
|
pass1 { if (_Imm11_ == 1 && !_x_) { mVUinfo |= _isNOP; return; } mVUbranch = x; } \
|
||||||
pass1 { if (_Imm11_ == 1 && !_x_) { mVUinfo |= _isNOP; mVUbranch = 0; return; } } \
|
pass2 { if (_Imm11_ == 1 && !_x_) { return; } mVUbranch = x; } \
|
||||||
|
pass3 { mVUbranch = x; } \
|
||||||
|
pass4 { if (_Imm11_ == 1 && !_x_) { return; } mVUbranch = x; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
microVUf(void) mVU_B() {
|
microVUf(void) mVU_B() {
|
||||||
|
|
|
@ -303,3 +303,12 @@ declareAllVariables
|
||||||
mVUreset<vuIndex>(); \
|
mVUreset<vuIndex>(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define mVUdebugNOW(isEndPC) { \
|
||||||
|
if (mVUdebugNow) { \
|
||||||
|
MOV32ItoR(gprT2, xPC); \
|
||||||
|
if (isEndPC) { CALLFunc((uptr)mVUprintPC2); } \
|
||||||
|
else { CALLFunc((uptr)mVUprintPC1); } \
|
||||||
|
MOV32ItoR(gprR, Roffset); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue