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 saddr, eaddr;
COP0_LOG( "COP0 > WriteTLB" );
tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
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]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TGE\n" );
}
void TGEU() {
if (cpuRegs.GPR.r[_Rs_].UD[0]>= cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TGEU\n" );
}
void TLT() {
if (cpuRegs.GPR.r[_Rs_].SD[0] < cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TLT\n" );
}
void TLTU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TLTU\n" );
}
void TEQ() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TEQ\n" );
}
void TNE() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TNE\n" );
}
/*********************************************************
@ -872,36 +878,42 @@ void TGEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] >= _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TGEIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] >= _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TLTI() {
if(cpuRegs.GPR.r[_Rs_].SD[0] < _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TLTIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TEQI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TNEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != _Imm_) {
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,
// so it's not enabled by default.
#define SIO_INLINE_IRQS
//#define SIO_INLINE_IRQS
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&= ~0xAE;
cpuSetNextBranchDelta( 64 );
if (addr != -1) VU0.VI[REG_TPC].UL = addr;
_vuExecMicroDebug(VU0);
FreezeXMMRegs(1);

View File

@ -322,11 +322,14 @@ static void recCTC2()
#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
break;
}

View File

@ -329,28 +329,14 @@ void recMTC0()
void recERET()
{
// Must branch immediately after 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 );
recBranchCall( ERET );
}
void recEI()
{
// Must branch immediately after enabling ints!
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)EI );
// must branch after enabling interrupts, so that anything
// pending gets triggered properly.
recBranchCall( EI );
}
void recDI()

View File

@ -64,6 +64,8 @@ extern u16 x86FpuState;
extern u16 iCWstate;
extern u32 s_nBlockCycles; // cycles of current block recompiling
void recBranchCall( void (*func)() );
#define REC_FUNC_INLINE( f, delreg ) \
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); \
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
*
@ -103,29 +122,29 @@ static void recMMI( void )
////////////////////////////////////////////////////
//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);
////////////////////////////////////////////////////
@ -133,56 +152,66 @@ REC_SYS(TNEI);
////////////////////////////////////////////////////
REC_SYS(CACHE);
/*
void recTGE( void )
{
recBranchCall( TGE );
}
void recTGEU( void )
{
recBranchCall( TGEU );
}
void recTLT( void )
{
recBranchCall( TLT );
}
void recTLTU( void )
{
recBranchCall( TLTU );
}
void recTEQ( void )
{
recBranchCall( TEQ );
}
void recTNE( void )
{
recBranchCall( TNE );
}
void recTGEI( void )
{
recBranchCall( TGEI );
}
void recTGEIU( void )
{
recBranchCall( TGEIU );
}
void recTLTI( void )
{
recBranchCall( TLTI );
}
void recTLTIU( void )
{
recBranchCall( TLTIU );
}
void recTEQI( void )
{
recBranchCall( TEQI );
}
void recTNEI( void )
{
recBranchCall( TNEI );
}
*/
/////////////////////////////////
// Foward-Prob Function Tables //