75 lines
1.9 KiB
C++
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();
|
|
}
|
|
}
|