mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
1b8cd7c055
commit
8ebcc4c442
|
@ -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) );
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -146,12 +146,10 @@ 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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -55,17 +55,19 @@ _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 recCop2BranchCall( void (*func)() )
|
||||
{
|
||||
X86_32CODE(SetFPUstate());
|
||||
recBranchCall( func );
|
||||
_freeX86regs();
|
||||
}
|
||||
|
||||
#define REC_COP2_FUNC( f ) \
|
||||
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 rec##f() \
|
||||
{ \
|
||||
SysPrintf("Warning > cop2 "#f" called\n"); \
|
||||
recCop2BranchCall( f ); \
|
||||
}
|
||||
|
||||
#define INTERPRETATE_COP2_FUNC(f) \
|
||||
|
@ -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,51 +288,39 @@ 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
|
||||
{
|
||||
switch(_Fs_) {
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue