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;
|
static const uint eeWaitCycles = 3072;
|
||||||
|
|
||||||
bool eeEventTestIsActive = false;
|
bool eeEventTestIsActive = false;
|
||||||
|
EE_intProcessStatus eeRunInterruptScan = INT_NOT_RUNNING;
|
||||||
|
|
||||||
u32 g_eeloadMain = 0, g_eeloadExec = 0, g_osdsys_str = 0;
|
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");
|
//Console.Write("DMAC Disabled or suspended");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eeRunInterruptScan = INT_RUNNING;
|
||||||
|
|
||||||
|
while (eeRunInterruptScan == INT_RUNNING)
|
||||||
|
{
|
||||||
/* These are 'pcsx2 interrupts', they handle asynchronous stuff
|
/* These are 'pcsx2 interrupts', they handle asynchronous stuff
|
||||||
that depends on the cycle timings */
|
that depends on the cycle timings */
|
||||||
TESTINT(VU_MTVU_BUSY, MTVUInterrupt);
|
TESTINT(VU_MTVU_BUSY, MTVUInterrupt);
|
||||||
|
@ -308,6 +314,14 @@ static __fi bool _cpuTestInterrupts()
|
||||||
TESTINT(VIF_VU1_FINISH, vif1VUFinish);
|
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)
|
if ((cpuRegs.interrupt & 0x1FFFF) & ~cpuRegs.dmastall)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -391,6 +405,8 @@ __fi void _cpuEventTest_Shared()
|
||||||
// These are basically just DMAC-related events, which also piggy-back the same bits as
|
// 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.
|
// 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
|
// 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
|
// 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.
|
// so to fix it, we run all the DMA's instantly when in the BIOS.
|
||||||
|
@ -402,6 +418,7 @@ __fi void _cpuEventTest_Shared()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_cpuTestInterrupts();
|
_cpuTestInterrupts();
|
||||||
|
}
|
||||||
|
|
||||||
// ---- IOP -------------
|
// ---- IOP -------------
|
||||||
// * It's important to run a iopEventTest before calling ExecuteBlock. This
|
// * 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)
|
__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.
|
// 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
|
// This can be used on games with PATH3 masking issues for example, or when
|
||||||
// some FMV look bad.
|
// some FMV look bad.
|
||||||
|
|
|
@ -333,6 +333,13 @@ extern R5900cpu *Cpu;
|
||||||
extern R5900cpu intCpu;
|
extern R5900cpu intCpu;
|
||||||
extern R5900cpu recCpu;
|
extern R5900cpu recCpu;
|
||||||
|
|
||||||
|
enum EE_intProcessStatus
|
||||||
|
{
|
||||||
|
INT_NOT_RUNNING = 0,
|
||||||
|
INT_RUNNING,
|
||||||
|
INT_REQ_LOOP
|
||||||
|
};
|
||||||
|
|
||||||
enum EE_EventType
|
enum EE_EventType
|
||||||
{
|
{
|
||||||
DMAC_VIF0 = 0,
|
DMAC_VIF0 = 0,
|
||||||
|
|
|
@ -341,7 +341,10 @@ __fi void vif1Interrupt()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vif1ch.chcr.STR)
|
if (!vif1ch.chcr.STR)
|
||||||
|
{
|
||||||
Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32);
|
Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (vif1.irq && vif1.vifstalled.enabled && vif1.vifstalled.value == VIF_IRQ_STALL)
|
if (vif1.irq && vif1.vifstalled.enabled && vif1.vifstalled.value == VIF_IRQ_STALL)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue