Improved EE/VU0 sync -- fixes 'new stage' crash in Naruto Ultimate Ninja 2 (part of Issue 58). Also rolled back some troubleshooting code that made it's way into the previous update.

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@441 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2008-12-16 10:07:39 +00:00 committed by Gregory Hainaut
parent 77f46f454e
commit 41df49b70d
8 changed files with 69 additions and 36 deletions

View File

@ -222,8 +222,6 @@ void WriteTLB(int i) {
u32 mask, addr; u32 mask, addr;
u32 saddr, eaddr; u32 saddr, eaddr;
COP0_LOG( "COP0 > WriteTLB" );
tlb[i].PageMask = cpuRegs.CP0.n.PageMask; tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi; tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0; tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0;

View File

@ -830,36 +830,42 @@ void TGE() {
if (cpuRegs.GPR.r[_Rs_].SD[0]>= cpuRegs.GPR.r[_Rt_].SD[0]) { if (cpuRegs.GPR.r[_Rs_].SD[0]>= cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: TGE\n" );
} }
void TGEU() { void TGEU() {
if (cpuRegs.GPR.r[_Rs_].UD[0]>= cpuRegs.GPR.r[_Rt_].UD[0]) { if (cpuRegs.GPR.r[_Rs_].UD[0]>= cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: TGEU\n" );
} }
void TLT() { void TLT() {
if (cpuRegs.GPR.r[_Rs_].SD[0] < cpuRegs.GPR.r[_Rt_].SD[0]) { if (cpuRegs.GPR.r[_Rs_].SD[0] < cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: TLT\n" );
} }
void TLTU() { void TLTU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < cpuRegs.GPR.r[_Rt_].UD[0]) { if (cpuRegs.GPR.r[_Rs_].UD[0] < cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: TLTU\n" );
} }
void TEQ() { void TEQ() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0]) { if (cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: TEQ\n" );
} }
void TNE() { void TNE() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0]) { if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: TNE\n" );
} }
/********************************************************* /*********************************************************
@ -872,36 +878,42 @@ void TGEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] >= _Imm_) { if (cpuRegs.GPR.r[_Rs_].SD[0] >= _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: Immediate\n" );
} }
void TGEIU() { void TGEIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] >= _ImmU_) { if (cpuRegs.GPR.r[_Rs_].UD[0] >= _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: Immediate\n" );
} }
void TLTI() { void TLTI() {
if(cpuRegs.GPR.r[_Rs_].SD[0] < _Imm_) { if(cpuRegs.GPR.r[_Rs_].SD[0] < _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: Immediate\n" );
} }
void TLTIU() { void TLTIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < _ImmU_) { if (cpuRegs.GPR.r[_Rs_].UD[0] < _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: Immediate\n" );
} }
void TEQI() { void TEQI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == _Imm_) { if (cpuRegs.GPR.r[_Rs_].SD[0] == _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: Immediate\n" );
} }
void TNEI() { void TNEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != _Imm_) { if (cpuRegs.GPR.r[_Rs_].SD[0] != _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch); cpuException(EXC_CODE_Tr, cpuRegs.branch);
} }
//SysPrintf( "TrapInstruction: Immediate\n" );
} }
/********************************************************* /*********************************************************

View File

@ -35,7 +35,7 @@
// chance of saves getting corrupted (untested). But it lacks the purist touch, // chance of saves getting corrupted (untested). But it lacks the purist touch,
// so it's not enabled by default. // so it's not enabled by default.
#define SIO_INLINE_IRQS //#define SIO_INLINE_IRQS
struct _sio { struct _sio {

View File

@ -205,6 +205,9 @@ void vu0ExecMicro(u32 addr) {
} }
VU0.VI[REG_VPU_STAT].UL|= 0x1; VU0.VI[REG_VPU_STAT].UL|= 0x1;
VU0.VI[REG_VPU_STAT].UL&= ~0xAE; VU0.VI[REG_VPU_STAT].UL&= ~0xAE;
cpuSetNextBranchDelta( 64 );
if (addr != -1) VU0.VI[REG_TPC].UL = addr; if (addr != -1) VU0.VI[REG_TPC].UL = addr;
_vuExecMicroDebug(VU0); _vuExecMicroDebug(VU0);
FreezeXMMRegs(1); FreezeXMMRegs(1);

View File

@ -322,11 +322,14 @@ static void recCTC2()
#else #else
MOV32ItoM((uptr)&VU0.VI[_Fs_].UL,g_cpuConstRegs[_Rt_].UL[0]); 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 // 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) // then they modify the register and expect vu0 to stop spinning within 10 cycles (donald duck)
iFlushCall(FLUSH_NOCONST); iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)Cpu->ExecuteVU0Block); CALLFunc((uptr)Cpu->ExecuteVU0Block);
//SysPrintf( "Recompiler Warning > Unstable VU0 opcode used." );
#endif #endif
break; break;
} }

View File

@ -329,28 +329,14 @@ void recMTC0()
void recERET() void recERET()
{ {
// Must branch immediately after ERET! recBranchCall( ERET );
branch = 2;
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
iFlushCall(FLUSH_NOCONST);
CALLFunc( (uptr)ERET );
} }
void recEI() void recEI()
{ {
// Must branch immediately after enabling ints! // must branch after enabling interrupts, so that anything
branch = 2; // pending gets triggered properly.
recBranchCall( EI );
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
iFlushCall(FLUSH_NOCONST);
CALLFunc( (uptr)EI );
} }
void recDI() void recDI()

View File

@ -64,6 +64,8 @@ extern u16 x86FpuState;
extern u16 iCWstate; extern u16 iCWstate;
extern u32 s_nBlockCycles; // cycles of current block recompiling extern u32 s_nBlockCycles; // cycles of current block recompiling
void recBranchCall( void (*func)() );
#define REC_FUNC_INLINE( f, delreg ) \ #define REC_FUNC_INLINE( f, delreg ) \
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); \ MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); \
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \ MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \

View File

@ -91,6 +91,25 @@ static void recMMI( void )
} }
// Use this to call into interpreter functions that require an immediate branchtest
// to be done afterward (anything that throws an exception or enables interrupts, etc).
void recBranchCall( void (*func)() )
{
// In order to make sure a branch test is performed, the nextBranchCycle is set
// to the current cpu cycle.
branch = 2;
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
// Might as well flush everything -- it'll all get flushed when the
// recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func );
}
/********************************************************** /**********************************************************
* UNHANDLED YET OPCODES * UNHANDLED YET OPCODES
* *
@ -103,29 +122,29 @@ static void recMMI( void )
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
//REC_SYS(MTSA); //REC_SYS(MTSA);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TGE); //REC_SYS(TGE);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TGEU); //REC_SYS(TGEU);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TLT); //REC_SYS(TLT);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TLTU); //REC_SYS(TLTU);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TEQ); //REC_SYS(TEQ);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TNE); //REC_SYS(TNE);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TGEI); //REC_SYS(TGEI);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TGEIU); //REC_SYS(TGEIU);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TLTI); //REC_SYS(TLTI);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TLTIU); //REC_SYS(TLTIU);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TEQI); //REC_SYS(TEQI);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(TNEI); //REC_SYS(TNEI);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
//REC_SYS(MTSAB); //REC_SYS(MTSAB);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -133,56 +152,66 @@ REC_SYS(TNEI);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_SYS(CACHE); REC_SYS(CACHE);
/*
void recTGE( void ) void recTGE( void )
{ {
recBranchCall( TGE );
} }
void recTGEU( void ) void recTGEU( void )
{ {
recBranchCall( TGEU );
} }
void recTLT( void ) void recTLT( void )
{ {
recBranchCall( TLT );
} }
void recTLTU( void ) void recTLTU( void )
{ {
recBranchCall( TLTU );
} }
void recTEQ( void ) void recTEQ( void )
{ {
recBranchCall( TEQ );
} }
void recTNE( void ) void recTNE( void )
{ {
recBranchCall( TNE );
} }
void recTGEI( void ) void recTGEI( void )
{ {
recBranchCall( TGEI );
} }
void recTGEIU( void ) void recTGEIU( void )
{ {
recBranchCall( TGEIU );
} }
void recTLTI( void ) void recTLTI( void )
{ {
recBranchCall( TLTI );
} }
void recTLTIU( void ) void recTLTIU( void )
{ {
recBranchCall( TLTIU );
} }
void recTEQI( void ) void recTEQI( void )
{ {
recBranchCall( TEQI );
} }
void recTNEI( void ) void recTNEI( void )
{ {
recBranchCall( TNEI );
} }
*/
///////////////////////////////// /////////////////////////////////
// Foward-Prob Function Tables // // Foward-Prob Function Tables //