From bce2cfe5f18077a2c0fc53ecc944c563c80eae7e Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 31 Oct 2008 12:02:52 +0000 Subject: [PATCH] Optimized the IOP's branch test algo a wee bit. git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@252 a6443dda-0b58-4228-96e9-037be469359c --- pcsx2/Misc.c | 5 +++-- pcsx2/R3000A.c | 20 ++++++++++++++------ pcsx2/R3000A.h | 2 +- pcsx2/R5900.c | 4 ++-- pcsx2/R5900.h | 2 +- pcsx2/x86/iR3000A.cpp | 4 +++- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/pcsx2/Misc.c b/pcsx2/Misc.c index 18350aa910..04ccebfe7d 100644 --- a/pcsx2/Misc.c +++ b/pcsx2/Misc.c @@ -547,7 +547,7 @@ int SaveState(char *file) { gzwrite(f, (void*)&tlb, sizeof(tlb)); // tlbs gzwrite(f, &EEsCycle, sizeof(EEsCycle)); gzwrite(f, &EEoCycle, sizeof(EEoCycle)); - gzwrite(f, &IOPoCycle, sizeof(IOPoCycle)); + gzwrite(f, &psxRegs.cycle, sizeof(u32)); // used to be IOPoCycle. This retains compatibility. gzwrite(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle)); gzwrite(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle)); gzwrite(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle)); @@ -610,6 +610,7 @@ int LoadState(char *file) { gzFile f; freezeData fP; int i; + u32 dud; // for loading unused vars. #ifdef PCSX2_VIRTUAL_MEM u32 OldProtect; #endif @@ -678,7 +679,7 @@ int LoadState(char *file) { gzread(f, (void*)&tlb, sizeof(tlb)); // tlbs gzread(f, &EEsCycle, sizeof(EEsCycle)); gzread(f, &EEoCycle, sizeof(EEoCycle)); - gzread(f, &IOPoCycle, sizeof(IOPoCycle)); + gzread(f, &dud, sizeof(u32)); // was IOPoCycle gzread(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle)); gzread(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle)); gzread(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle)); diff --git a/pcsx2/R3000A.c b/pcsx2/R3000A.c index ed9e9fca5d..0cdda2c2ad 100644 --- a/pcsx2/R3000A.c +++ b/pcsx2/R3000A.c @@ -161,16 +161,27 @@ static void _psxTestInterrupts() { PSX_TESTINT(21, usbInterrupt); } -#define IOP_WAIT_CYCLE 64 + +// Since the EEsCycle update now is outside the BranchTest, we can safely +// put a much higher threshold on the IOP wait cycle. We could probably go +// even higher and just let the IRQ/Counter targets adjust it as needed, +// but I'll stick to a conservative value for the time being. + +#define IOP_WAIT_CYCLE 512 // was 64 void psxBranchTest() { - EEsCycle -= (psxRegs.cycle - IOPoCycle) << 3; + // EEsCycle update was moved to outside the psxBranchTest. Since it gets run + // for every branch now, the following code block is obsolete. + + /*EEsCycle -= (psxRegs.cycle - IOPoCycle) << 3; IOPoCycle = psxRegs.cycle; if( EEsCycle > 0 ) g_psxNextBranchCycle = psxRegs.cycle + min(IOP_WAIT_CYCLE, (EEsCycle>>3)); else - g_psxNextBranchCycle = psxRegs.cycle; + g_psxNextBranchCycle = psxRegs.cycle;*/ + + g_psxNextBranchCycle = psxRegs.cycle + IOP_WAIT_CYCLE; if ((int)(psxRegs.cycle - psxNextsCounter) >= psxNextCounter) psxRcntUpdate(); @@ -179,9 +190,6 @@ void psxBranchTest() _psxTestInterrupts(); } -// if( (int)psxRegs.cycle-(int)g_psxNextBranchCycle > 0 ) -// g_psxNextBranchCycle = psxRegs.cycle+1; -// else if( (int)(g_psxNextBranchCycle-psxNextsCounter) >= (u32)psxNextCounter ) g_psxNextBranchCycle = (u32)psxNextsCounter+(u32)psxNextCounter; diff --git a/pcsx2/R3000A.h b/pcsx2/R3000A.h index eca3c1d16d..579fa1f858 100644 --- a/pcsx2/R3000A.h +++ b/pcsx2/R3000A.h @@ -198,7 +198,7 @@ extern u32 g_psxHasConstReg, g_psxFlushedConstReg; #define _SetLink(x) psxRegs.GPR.r[x] = _PC_ + 4; // Sets the return address in the link register extern int EEsCycle; -extern u32 EEoCycle, IOPoCycle; +extern u32 EEoCycle; #endif diff --git a/pcsx2/R5900.c b/pcsx2/R5900.c index 9d43288fd7..1db5fdf4da 100644 --- a/pcsx2/R5900.c +++ b/pcsx2/R5900.c @@ -39,8 +39,8 @@ PCSX2_ALIGNED16(GPR_reg64 g_cpuConstRegs[32]) = {0}; u32 g_cpuHasConstReg = 0, g_cpuFlushedConstReg = 0; R5900cpu *Cpu; -int EEsCycle; -u32 EEoCycle, IOPoCycle; +int EEsCycle; // used to sync the IOP to the EE +u32 EEoCycle; u32 bExecBIOS = 0; // set if the BIOS has already been executed extern u32 dwSaveVersion; diff --git a/pcsx2/R5900.h b/pcsx2/R5900.h index 41ceead513..f620944b25 100644 --- a/pcsx2/R5900.h +++ b/pcsx2/R5900.h @@ -126,7 +126,7 @@ typedef struct { } cpuRegisters; extern int EEsCycle; -extern u32 EEoCycle, IOPoCycle; +extern u32 EEoCycle; extern PCSX2_ALIGNED16_DECL(cpuRegisters cpuRegs); // used for optimization diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp index b393adf8b9..c7ec3f3ce4 100644 --- a/pcsx2/x86/iR3000A.cpp +++ b/pcsx2/x86/iR3000A.cpp @@ -984,9 +984,11 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch) if( !USE_FAST_BRANCHES || cpuBranch ) { MOV32MtoR(ECX, (uptr)&psxRegs.cycle); ADD32ItoR(ECX, s_psxBlockCycles*PSXCYCLE_MULT); // greater mult factor causes nfsmw to crash + SUB32ItoM((uptr)&EEsCycle, s_psxBlockCycles*PSXCYCLE_MULT*8); // 8 EE clocks for every IOP clock. MOV32RtoM((uptr)&psxRegs.cycle, ECX); // update cycles } else { + SUB32ItoM((uptr)&EEsCycle, s_psxBlockCycles*8); // 8 EE clocks for every IOP clock. ADD32ItoM((uptr)&psxRegs.cycle, s_psxBlockCycles*PSXCYCLE_MULT); return; } @@ -1183,7 +1185,7 @@ void iDumpPsxRegisters(u32 startpc, u32 temp) __Log("%spsxreg: %x %x ra:%x k0: %x %x\n", pstr, startpc, psxRegs.cycle, psxRegs.GPR.n.ra, psxRegs.GPR.n.k0, *(int*)PSXM(0x13c128)); for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x\n", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]); - __Log("%scycle: %x %x %x %x; counters %x %x\n", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle, IOPoCycle, + __Log("%scycle: %x %x %x; counters %x %x\n", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle, (uptr)psxNextsCounter, (uptr)psxNextCounter); __Log("psxdma%d c%x b%x m%x t%x\n", 2, HW_DMA2_CHCR, HW_DMA2_BCR, HW_DMA2_MADR, HW_DMA2_TADR);