Added comments for my previous VU0 sync fix, along with some other code cleanups.

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@444 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2008-12-16 19:18:41 +00:00 committed by Gregory Hainaut
parent 1b8cd7c055
commit 8ebcc4c442
5 changed files with 54 additions and 56 deletions

View File

@ -549,6 +549,11 @@ void cpuBranchTest()
// We're in a BranchTest. All dynarec registers are flushed
// so there is no need to freeze registers here.
Cpu->ExecuteVU0Block();
// This might be needed to keep the EE and VU0 in sync.
// A better fix will require hefty changes to the VU recs. -_-
if(VU0.VI[REG_VPU_STAT].UL & 0x1)
cpuSetNextBranchDelta( 768 );
}
assert( !g_globalXMMSaved X86_32CODE(&& !g_globalMMXSaved) );

View File

@ -206,13 +206,16 @@ void vu0ExecMicro(u32 addr) {
VU0.VI[REG_VPU_STAT].UL|= 0x1;
VU0.VI[REG_VPU_STAT].UL&= ~0xAE;
cpuSetNextBranchDelta( 64 );
if (addr != -1) VU0.VI[REG_TPC].UL = addr;
_vuExecMicroDebug(VU0);
FreezeXMMRegs(1);
Cpu->ExecuteVU0Block();
FreezeXMMRegs(0);
// If the VU0 program didn't finish then we'll want to finish it up
// pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
if(VU0.VI[REG_VPU_STAT].UL & 0x1)
cpuSetNextBranchDelta( 128 );
}
void _vu0ExecUpper(VURegs* VU, u32 *ptr) {

View File

@ -146,11 +146,9 @@ void vu1ExecMicro(u32 addr)
if(VU0.VI[REG_VPU_STAT].UL & 0x100) {
SysPrintf("Previous Microprogram still running on VU1\n");
if( VU0.VI[REG_VPU_STAT].UL & 0x100 ) {
do {
Cpu->ExecuteVU1Block();
} while(VU0.VI[REG_VPU_STAT].UL & 0x100);
}
do {
Cpu->ExecuteVU1Block();
} while(VU0.VI[REG_VPU_STAT].UL & 0x100);
}
VUM_LOG("vu1ExecMicro %x\n", addr);
VUM_LOG("vu1ExecMicro %x (count=%d)\n", addr, count++);
@ -161,7 +159,6 @@ void vu1ExecMicro(u32 addr)
if (addr != -1) VU1.VI[REG_TPC].UL = addr;
_vuExecMicroDebug(VU1);
//do {
FreezeXMMRegs(1);
Cpu->ExecuteVU1Block();
@ -169,6 +166,12 @@ void vu1ExecMicro(u32 addr)
//} while(VU0.VI[REG_VPU_STAT].UL & 0x100);
// rec can call vu1ExecMicro
// VU1 isn't handled by branch tests right now, so this isn't needed.
// although maybe it should be? VU1 is updated in the intBranchTest, but not the
// recompiler one. Why? No clue. (air)
//if( VU1.VI[REG_VPU_STAT].UL & 0x1 )
// cpuSetNextBranchDelta( 256 );
}
void _vu1ExecUpper(VURegs* VU, u32 *ptr) {

View File

@ -55,19 +55,21 @@ _vuopinfo g_cop2info = {0, 0, 1, 1, 1, 0, 0};
#define _Ftf_ ((cpuRegs.code >> 23) & 0x03)
#define _Cc_ (cpuRegs.code & 0x03)
#define REC_COP2_FUNC(f, delreg) \
void f(); \
void rec##f() { \
SysPrintf("cop2 "#f" called\n"); \
X86_32CODE(SetFPUstate()); \
MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \
MOV32ItoM((uptr)&cpuRegs.pc, pc); \
iFlushCall(FLUSH_NOCONST); \
CALLFunc((uptr)f); \
_freeX86regs(); \
branch = 2; \
void recCop2BranchCall( void (*func)() )
{
X86_32CODE(SetFPUstate());
recBranchCall( func );
_freeX86regs();
}
#define REC_COP2_FUNC( f ) \
void f(); \
void rec##f() \
{ \
SysPrintf("Warning > cop2 "#f" called\n"); \
recCop2BranchCall( f ); \
}
#define INTERPRETATE_COP2_FUNC(f) \
void recV##f() { \
MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \
@ -250,9 +252,6 @@ static void recCFC2()
static void recCTC2()
{
#ifdef __x86_64__
int mmreg;
#endif
if (cpuRegs.code & 1) {
#ifdef __x86_64__
iFlushCall(FLUSH_FREE_VU0|FLUSH_FREE_TEMPX86);
@ -289,49 +288,37 @@ static void recCTC2()
assert( _checkX86reg(X86TYPE_VI, REG_VPU_STAT, 0) < 0 &&
_checkX86reg(X86TYPE_VI, REG_TPC, 0) < 0 );
// Execute VU1 Micro SubRoutine
_callFunctionArg1((uptr)FreezeXMMRegs_, MEM_CONSTTAG, 1);
_callFunctionArg1((uptr)vu1ExecMicro, MEM_CONSTTAG, g_cpuConstRegs[_Rt_].UL[0]&0xffff);
_callFunctionArg1((uptr)FreezeXMMRegs_, MEM_CONSTTAG, 0);
#else
iFlushCall(FLUSH_NOCONST);// since CALLFunc
assert( _checkX86reg(X86TYPE_VI, REG_VPU_STAT, 0) < 0 &&
_checkX86reg(X86TYPE_VI, REG_TPC, 0) < 0 );
#endif
// Execute VU1 Micro SubRoutine
_callFunctionArg1((uptr)vu1ExecMicro, MEM_CONSTTAG, g_cpuConstRegs[_Rt_].UL[0]&0xffff);
#endif
break;
default:
{
if( _Fs_ < 16 )
assert( (g_cpuConstRegs[_Rt_].UL[0]&0xffff0000)==0);
#ifdef __x86_64__
mmreg = _checkX86reg(X86TYPE_VI, _Fs_, MODE_WRITE);
if( mmreg >= 0 ) MOV32ItoR(mmreg, g_cpuConstRegs[_Rt_].UL[0]);
// a lot of games have vu0 spinning on some integer
// then they modify the register and expect vu0 to stop spinning within 10 cycles (donald duck)
iFlushCall(FLUSH_FREE_TEMPX86|FLUSH_FREE_VU0);
_callFunctionArg1((uptr)FreezeXMMRegs_, MEM_CONSTTAG, 1);
CALLFunc((uptr)Cpu->ExecuteVU0Block);
_callFunctionArg1((uptr)FreezeXMMRegs_, MEM_CONSTTAG, 0);
#ifdef __x86_64__
int mmreg = _checkX86reg(X86TYPE_VI, _Fs_, MODE_WRITE);
if( mmreg >= 0 ) MOV32ItoR(mmreg, g_cpuConstRegs[_Rt_].UL[0]);
iFlushCall(FLUSH_FREE_TEMPX86|FLUSH_FREE_VU0);
#else
MOV32ItoM((uptr)&VU0.VI[_Fs_].UL,g_cpuConstRegs[_Rt_].UL[0]);
// fixme: this code should issue a BranchTest instead of calling the VU0Block directly.
// It would be a lot safter and would get rid of the 64 bit mess above too.
// a lot of games have vu0 spinning on some integer
// then they modify the register and expect vu0 to stop spinning within 10 cycles (donald duck)
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)Cpu->ExecuteVU0Block);
//SysPrintf( "Recompiler Warning > Unstable VU0 opcode used." );
#endif
CALLFunc((uptr)Cpu->ExecuteVU0Block);
// fixme: if the VU0 stat&1 is still enabled, then we should probably set a cpuBranchTest
// for 128 cycles from now. It would be the safest thing to do to make sure the VU0
// responds in a timely matter to the game's register write.
break;
}
}
}
else
@ -613,10 +600,10 @@ void _cop2AnalyzeOp(EEINST* pinst, int dostalls)
//////////////////////////////////////////////////////////////////////////
// BC2: Instructions
//////////////////////////////////////////////////////////////////////////
REC_COP2_FUNC(BC2F, 0);
REC_COP2_FUNC(BC2T, 0);
REC_COP2_FUNC(BC2FL, 0);
REC_COP2_FUNC(BC2TL, 0);
REC_COP2_FUNC(BC2F);
REC_COP2_FUNC(BC2T);
REC_COP2_FUNC(BC2FL);
REC_COP2_FUNC(BC2TL);
//////////////////////////////////////////////////////////////////////////
// Special1 instructions