mirror of https://github.com/PCSX2/pcsx2.git
EE/DMA: Try to avoid very small DMA loops
This commit is contained in:
parent
c1c6bde429
commit
7d8d16091e
|
@ -54,6 +54,7 @@ R5900cpu *Cpu = NULL;
|
|||
static const uint eeWaitCycles = 3072;
|
||||
|
||||
bool eeEventTestIsActive = false;
|
||||
EE_intProcessStatus eeRunInterruptScan = INT_NOT_RUNNING;
|
||||
|
||||
u32 g_eeloadMain = 0, g_eeloadExec = 0, g_osdsys_str = 0;
|
||||
|
||||
|
@ -277,6 +278,11 @@ static __fi bool _cpuTestInterrupts()
|
|||
//Console.Write("DMAC Disabled or suspended");
|
||||
return false;
|
||||
}
|
||||
|
||||
eeRunInterruptScan = INT_RUNNING;
|
||||
|
||||
while (eeRunInterruptScan == INT_RUNNING)
|
||||
{
|
||||
/* These are 'pcsx2 interrupts', they handle asynchronous stuff
|
||||
that depends on the cycle timings */
|
||||
TESTINT(VU_MTVU_BUSY, MTVUInterrupt);
|
||||
|
@ -308,6 +314,14 @@ static __fi bool _cpuTestInterrupts()
|
|||
TESTINT(VIF_VU1_FINISH, vif1VUFinish);
|
||||
}
|
||||
|
||||
if (eeRunInterruptScan == INT_REQ_LOOP)
|
||||
eeRunInterruptScan = INT_RUNNING;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
eeRunInterruptScan = INT_NOT_RUNNING;
|
||||
|
||||
if ((cpuRegs.interrupt & 0x1FFFF) & ~cpuRegs.dmastall)
|
||||
return true;
|
||||
else
|
||||
|
@ -391,6 +405,8 @@ __fi void _cpuEventTest_Shared()
|
|||
// These are basically just DMAC-related events, which also piggy-back the same bits as
|
||||
// the PS2's own DMA channel IRQs and IRQ Masks.
|
||||
|
||||
if (cpuRegs.interrupt)
|
||||
{
|
||||
// This is a BIOS hack because the coding in the BIOS is terrible but the bug is masked by Data Cache
|
||||
// where a DMA buffer is overwritten without waiting for the transfer to end, which causes the fonts to get all messed up
|
||||
// so to fix it, we run all the DMA's instantly when in the BIOS.
|
||||
|
@ -402,6 +418,7 @@ __fi void _cpuEventTest_Shared()
|
|||
}
|
||||
else
|
||||
_cpuTestInterrupts();
|
||||
}
|
||||
|
||||
// ---- IOP -------------
|
||||
// * It's important to run a iopEventTest before calling ExecuteBlock. This
|
||||
|
@ -523,6 +540,17 @@ __fi void CPU_SET_DMASTALL(EE_EventType n, bool set)
|
|||
|
||||
__fi void CPU_INT( EE_EventType n, s32 ecycle)
|
||||
{
|
||||
// If it's retunning too quick, just rerun the DMA, there's no point in running the EE for < 4 cycles.
|
||||
// This causes a huge uplift in performance for ONI FMV's.
|
||||
if (ecycle < 4 && !(cpuRegs.dmastall & (1 << n)) && eeRunInterruptScan != INT_NOT_RUNNING)
|
||||
{
|
||||
eeRunInterruptScan = INT_REQ_LOOP;
|
||||
cpuRegs.interrupt |= 1 << n;
|
||||
cpuRegs.sCycle[n] = cpuRegs.cycle;
|
||||
cpuRegs.eCycle[n] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// EE events happen 8 cycles in the future instead of whatever was requested.
|
||||
// This can be used on games with PATH3 masking issues for example, or when
|
||||
// some FMV look bad.
|
||||
|
|
|
@ -333,6 +333,13 @@ extern R5900cpu *Cpu;
|
|||
extern R5900cpu intCpu;
|
||||
extern R5900cpu recCpu;
|
||||
|
||||
enum EE_intProcessStatus
|
||||
{
|
||||
INT_NOT_RUNNING = 0,
|
||||
INT_RUNNING,
|
||||
INT_REQ_LOOP
|
||||
};
|
||||
|
||||
enum EE_EventType
|
||||
{
|
||||
DMAC_VIF0 = 0,
|
||||
|
|
|
@ -341,7 +341,10 @@ __fi void vif1Interrupt()
|
|||
}
|
||||
|
||||
if (!vif1ch.chcr.STR)
|
||||
{
|
||||
Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vif1.irq && vif1.vifstalled.enabled && vif1.vifstalled.value == VIF_IRQ_STALL)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue