#include #include void Scheduler::EnqueueRelative(const u64 t, const EventType type) { EnqueueAbsolute(t + ticks, type); } void Scheduler::EnqueueAbsolute(const u64 t, const EventType type) { events.push({t, type}); } Event *Scheduler::Find(const EventType eventType) const { for (auto &event : events) { if (event.type == eventType) { const u64 ret = event.time - ticks; return &event; } } return nullptr; } u64 Scheduler::Remove(const EventType eventType) const { auto event = Find(eventType); if (!event) return 0; const u64 ret = event->time - ticks; event->type = NONE; event->time = ticks; return ret; } void Scheduler::SkipToNext() { ticks = events.top().time; } void Scheduler::Tick(const u64 t) { ticks += t; } void Scheduler::HandleEvents() { n64::Core &core = n64::Core::GetInstance(); n64::Mem &mem = core.GetMem(); n64::MI &mi = mem.mmio.mi; n64::SI &si = mem.mmio.si; n64::PI &pi = mem.mmio.pi; while (ticks >= events.top().time) { switch (const auto type = events.top().type) { case PAUSE: core.TogglePause(); break; case STOP: core.Stop(); core.rom = {}; break; case RESET: core.Reset(); break; case SI_DMA: si.DMA(); break; case PI_DMA_COMPLETE: mi.InterruptRaise(n64::MI::Interrupt::PI); pi.dmaBusy = false; break; case PI_BUS_WRITE_COMPLETE: pi.ioBusy = false; break; case NONE: break; case IMPOSSIBLE: panic("Impossible scheduler event happened"); return; default: panic("Unknown scheduler event type {}", static_cast(type)); return; } events.pop(); } }