TimingEvent: Fix events losing time when rescheduling outside handler

This commit is contained in:
Connor McLaughlin 2020-03-24 00:20:45 +10:00
parent 612b362ae9
commit 9ce63952fb
3 changed files with 11 additions and 29 deletions

View File

@ -523,7 +523,7 @@ TickCount CDROM::GetTicksForSeek() const
void CDROM::BeginCommand(Command command) void CDROM::BeginCommand(Command command)
{ {
m_command = command; m_command = command;
m_command_event->SetDowncount(GetAckDelayForCommand()); m_command_event->Schedule(GetAckDelayForCommand());
UpdateCommandEvent(); UpdateCommandEvent();
UpdateStatusRegister(); UpdateStatusRegister();
} }

View File

@ -28,26 +28,21 @@ TickCount TimingEvent::GetTicksUntilNextExecution() const
void TimingEvent::Schedule(TickCount ticks) void TimingEvent::Schedule(TickCount ticks)
{ {
m_downcount = ticks;
m_time_since_last_run = 0;
// Factor in partial time if this was rescheduled outside of an event handler. Say, an MMIO write.
if (!m_system->m_running_events)
{
const TickCount pending_ticks = m_system->m_cpu->GetPendingTicks(); const TickCount pending_ticks = m_system->m_cpu->GetPendingTicks();
m_downcount += pending_ticks; m_downcount = pending_ticks + ticks;
m_time_since_last_run -= pending_ticks;
}
if (m_active) if (!m_active)
{ {
// If this is a call from an IO handler for example, re-sort the event queue. // Event is going active, so we want it to only execute ticks from the current timestamp.
m_system->SortEvents(); m_time_since_last_run = -pending_ticks;
m_active = true;
m_system->AddActiveEvent(this);
} }
else else
{ {
m_active = true; // Event is already active, so we leave the time since last run alone, and just modify the downcount.
m_system->AddActiveEvent(this); // If this is a call from an IO handler for example, re-sort the event queue.
m_system->SortEvents();
} }
} }
@ -118,13 +113,3 @@ void TimingEvent::Deactivate()
m_active = false; m_active = false;
m_system->RemoveActiveEvent(this); m_system->RemoveActiveEvent(this);
} }
void TimingEvent::SetDowncount(TickCount downcount)
{
const TickCount pending_ticks = m_system->m_running_events ? 0 : m_system->m_cpu->GetPendingTicks();
m_downcount = downcount + pending_ticks;
m_time_since_last_run = -pending_ticks;
if (m_active)
m_system->SortEvents();
}

View File

@ -57,9 +57,6 @@ public:
Deactivate(); Deactivate();
} }
// Directly alters the downcount of the event.
void SetDowncount(TickCount downcount);
// Directly alters the interval of the event. // Directly alters the interval of the event.
void SetInterval(TickCount interval) { m_interval = interval; } void SetInterval(TickCount interval) { m_interval = interval; }
void SetPeriod(TickCount period) { m_period = period; } void SetPeriod(TickCount period) { m_period = period; }