From a974cff9bd0dd5cd55770f4890a639c0fa0067dc Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Mon, 18 May 2009 06:24:12 +0000 Subject: [PATCH] microVU: - Raised the run-cycles amount. This fixes FFXII's missing geometry (the game appears perfect now :p) - mVU prints a message to console now if games are exiting early due to infinite loops (I'm interested in games that do this, so post any game you find that does this. Dark Cloud does this for example...) - Added some debug stuff to iVU1micro.cpp. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1216 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/iVU0micro.cpp | 6 ++-- pcsx2/x86/iVU1micro.cpp | 60 +++++++++++++++++++++++++++++++++-- pcsx2/x86/microVU_Compile.inl | 9 ++++-- pcsx2/x86/microVU_Misc.h | 2 +- 4 files changed, 68 insertions(+), 9 deletions(-) diff --git a/pcsx2/x86/iVU0micro.cpp b/pcsx2/x86/iVU0micro.cpp index 8500f60665..ccdfa0580d 100644 --- a/pcsx2/x86/iVU0micro.cpp +++ b/pcsx2/x86/iVU0micro.cpp @@ -80,13 +80,13 @@ namespace VU0micro static void recStep() {} static void recExecuteBlock() { - if((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return; + if ((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return; FreezeXMMRegs(1); //FreezeMMXRegs(1); - runVUrec(VU0.VI[REG_TPC].UL, 5000, 0); - FreezeXMMRegs(0); + runVUrec(VU0.VI[REG_TPC].UL, 50000, 0); //FreezeMMXRegs(0); + FreezeXMMRegs(0); } } diff --git a/pcsx2/x86/iVU1micro.cpp b/pcsx2/x86/iVU1micro.cpp index 4393cf9100..5eba1f8782 100644 --- a/pcsx2/x86/iVU1micro.cpp +++ b/pcsx2/x86/iVU1micro.cpp @@ -29,7 +29,49 @@ #ifdef _DEBUG extern u32 vudump; #endif + +//#define DEBUG_COMPARE +#ifdef DEBUG_COMPARE + +#include +static int runAmount = 0; + +void VUtestPause() { + + runAmount++; + if (runAmount < 100) return; + #ifndef PCSX2_MICROVU_ + SysPrintf("Super VU - Pass %d\n", runAmount); +#else + SysPrintf("Micro VU - Pass %d\n", runAmount); +#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]); + } + + for (int i = 0; i < 16; i++) { + SysPrintf("VI%02d = % 8d ($%08x)\n", i, (s16)VU1.VI[i].UL, (s16)VU1.VI[i].UL); + } + + u32 j = 0; + for (int i = 0; i < (0x4000 / 4); i++) { + j ^= ((u32*)(VU1.Mem))[i]; + } + SysPrintf("VU Mem CRC = 0x%08x\n", j); + SysPrintf("EndPC = 0x%04x\n", VU1.VI[REG_TPC].UL); + + for (int i = 0; i < 10000000; i++) { + Sleep(1000); + } +} +#else +void VUtestPause() {} +#endif + +#ifndef PCSX2_MICROVU_ + namespace VU1micro { void recAlloc() @@ -113,12 +155,17 @@ namespace VU1micro } 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 @@ -129,6 +176,7 @@ 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 { void recAlloc() { initVUrec(&VU1, 1); } @@ -138,14 +186,20 @@ namespace VU1micro static void recStep() {} static void recExecuteBlock() { - if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return; + if ((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) 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); //FreezeMMXRegs(1); - runVUrec(VU1.VI[REG_TPC].UL, 5000, 1); - FreezeXMMRegs(0); + runVUrec(VU1.VI[REG_TPC].UL, 300000 /*0x7fffffff*/, 1); //FreezeMMXRegs(0); + FreezeXMMRegs(0); + + VUtestPause(); } } #endif diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 3af44862f8..8639ace77e 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -160,8 +160,8 @@ microVUt(void) mVUendProgram(int fStatus, int fMac, int fClip) { //memcpy_fast(&pBlock->pStateEnd, &mVUregs, sizeof(microRegInfo)); //MOV32ItoM((uptr)&mVU->prog.lpState, (int)&mVUblock.pState); // Save pipeline state (clipflag instance) - //AND32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, (vuIndex ? ~0x100 : ~0x001)); // VBS0/VBS1 flag - AND32ItoM((uptr)µVU0.regs->VI[REG_VPU_STAT].UL, (vuIndex ? ~0x100 : ~0x001)); // VBS0/VBS1 flag + //AND32ItoM((uptr)µVU0.regs->VI[REG_VPU_STAT].UL, (vuIndex ? ~0x100 : ~0x001)); // VBS0/VBS1 flag + AND32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, (vuIndex ? ~0x100 : ~0x001)); // VBS0/VBS1 flag AND32ItoM((uptr)&mVU->regs->vifRegs->stat, ~0x4); // Clear VU 'is busy' signal for vif MOV32ItoM((uptr)&mVU->regs->VI[REG_TPC].UL, xPC); JMP32((uptr)mVU->exitFunct - ((uptr)x86Ptr + 5)); @@ -170,11 +170,16 @@ microVUt(void) mVUendProgram(int fStatus, int fMac, int fClip) { #define sI ((mVUpBlock->pState.needExactMatch & 0x000f) ? 0 : ((mVUpBlock->pState.flags >> 0) & 3)) #define cI ((mVUpBlock->pState.needExactMatch & 0x0f00) ? 0 : ((mVUpBlock->pState.flags >> 2) & 3)) +void mVUwarning() { Console::Error("microVU Warning: Exiting Execution Early (Possible Infinite Loop)"); } + microVUt(void) mVUtestCycles() { microVU* mVU = mVUx; iPC = mVUstartPC; CMP32ItoM((uptr)&mVU->cycles, 0); u8* jmp8 = JG8(0); + PUSH32R(gprR); + CALLFunc((uptr)mVUwarning); + POP32R(gprR); mVUendProgram(sI, 0, cI); x86SetJ8(jmp8); SUB32ItoM((uptr)&mVU->cycles, mVUcycles); diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index e0c0530713..66d996594a 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -169,7 +169,7 @@ declareAllVariables #define mVUflagInfo mVUregs.needExactMatch #define mVUflagHack (mVUcurProg.sFlagHack) #define xPC ((iPC / 2) * 8) -#define curI ((u32*)mVU->regs->Micro)[iPC]//mVUcurProg.data[iPC] +#define curI ((u32*)mVU->regs->Micro)[iPC] //mVUcurProg.data[iPC] #define setCode() { mVU->code = curI; } #define incPC(x) { iPC = ((iPC + x) & (mVU->progSize-1)); setCode(); } #define incPC2(x) { iPC = ((iPC + x) & (mVU->progSize-1)); }