Files
kaizen/src/backend/Scheduler.cpp
T

75 lines
1.9 KiB
C++

#include <Scheduler.hpp>
#include <Core.hpp>
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.romPath = {};
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:
ircolib::panic("Impossible scheduler event happened");
return;
default:
ircolib::panic("Unknown scheduler event type {}", static_cast<int>(type));
return;
}
events.pop();
}
}