EE/IOP Sync: Optimize EE/IOP sync for more intelligent syncing

This commit is contained in:
refractionpcsx2 2023-06-30 19:42:44 +01:00
parent 443adcdd5b
commit 7fbc63b8e8
4 changed files with 17 additions and 13 deletions

View File

@ -438,8 +438,6 @@ void psxRcntUpdate()
{
int i;
psxRegs.iopNextEventCycle = psxRegs.cycle + 32;
psxNextCounter = 0x7fffffff;
psxNextsCounter = psxRegs.cycle;

View File

@ -42,6 +42,8 @@ u32 g_psxHasConstReg, g_psxFlushedConstReg;
// is true, even if it's already running ahead a bit.
bool iopEventAction = false;
static constexpr uint iopWaitCycles = 384; // Keep inline with EE wait cycle max.
bool iopEventTestIsActive = false;
alignas(16) psxRegisters psxRegs;
@ -140,13 +142,13 @@ __fi void PSX_INT( IopEventId n, s32 ecycle )
psxSetNextBranchDelta(ecycle);
if (psxRegs.iopCycleEE < 0)
const s32 iopDelta = (psxRegs.iopNextEventCycle - psxRegs.cycle) * 8;
if (psxRegs.iopCycleEE < iopDelta)
{
// The EE called this int, so inform it to branch as needed:
// fixme - this doesn't take into account EE/IOP sync (the IOP may be running
// ahead or behind the EE as per the EEsCycles value)
const s32 iopDelta = (psxRegs.iopNextEventCycle - psxRegs.cycle) * 8;
cpuSetNextEventDelta(iopDelta);
cpuSetNextEventDelta(iopDelta - psxRegs.iopCycleEE);
}
}
@ -209,6 +211,8 @@ static __fi void _psxTestInterrupts()
__ri void iopEventTest()
{
psxRegs.iopNextEventCycle = psxRegs.cycle + iopWaitCycles;
if (psxTestCycle(psxNextsCounter, psxNextCounter))
{
psxRcntUpdate();
@ -218,7 +222,8 @@ __ri void iopEventTest()
{
// start the next branch at the next counter event by default
// the interrupt code below will assign nearer branches if needed.
psxRegs.iopNextEventCycle = psxNextsCounter + psxNextCounter;
if (psxNextCounter < (psxRegs.iopNextEventCycle - psxNextsCounter))
psxRegs.iopNextEventCycle = psxNextsCounter + psxNextCounter;
}
if (psxRegs.interrupt)

View File

@ -119,7 +119,7 @@ struct psxRegisters {
// cycles can be accounted for later.
s32 iopBreak;
// tracks the IOP's current sync status with the EE. When it dips below zero,
// Tracks current number of cycles IOP can run in EE cycles. When it dips below zero,
// control is returned to the EE.
s32 iopCycleEE;

View File

@ -51,7 +51,7 @@ alignas(16) fpuRegisters fpuRegs;
alignas(16) tlbs tlb[48];
R5900cpu *Cpu = NULL;
static const uint eeWaitCycles = 3072;
static constexpr uint eeWaitCycles = 3072;
bool eeEventTestIsActive = false;
EE_intProcessStatus eeRunInterruptScan = INT_NOT_RUNNING;
@ -453,7 +453,9 @@ __fi void _cpuEventTest_Shared()
// ---- Schedule Next Event Test --------------
if (EEsCycle > 192)
const int nextIopEventDeta = ((psxRegs.iopNextEventCycle - psxRegs.cycle) * 8);
// 8 or more cycles behind and there's an event scheduled
if (EEsCycle >= nextIopEventDeta)
{
// EE's running way ahead of the IOP still, so we should branch quickly to give the
// IOP extra timeslices in short order.
@ -463,8 +465,7 @@ __fi void _cpuEventTest_Shared()
}
else
{
// The IOP could be running ahead/behind of us, so adjust the iop's next branch by its
// relative position to the EE (via EEsCycle)
// Otherwise IOP is caught up/not doing anything so we can wait for the next event.
cpuSetNextEventDelta(((psxRegs.iopNextEventCycle - psxRegs.cycle) * 8) - EEsCycle);
}