#include #include #include Scheduler scheduler; void Scheduler::enqueueRelative(u64 t, const EventType type) { enqueueAbsolute(t + ticks, type); } void Scheduler::enqueueAbsolute(u64 t, const EventType type) { events.push({t, type}); } u64 Scheduler::remove(EventType type) { for (auto& e : events) { if(e.type == type) { u64 ret = e.time - ticks; e.type = NONE; e.time = ticks; return ret; } } return 0; } void Scheduler::tick(u64 t, n64::Mem& mem, n64::Registers& regs) { ticks += t; n64::MI& mi = mem.mmio.mi; n64::SI& si = mem.mmio.si; n64::PI& pi = mem.mmio.pi; while(ticks >= events.top().time) { switch(auto type = events.top().type) { case SI_DMA: si.DMA(mem, regs); break; case PI_DMA_COMPLETE: InterruptRaise(mi, regs, n64::Interrupt::PI); pi.dmaBusy = false; break; case PI_BUS_WRITE_COMPLETE: pi.ioBusy = false; break; case NONE: break; case IMPOSSIBLE: Util::panic("Congratulations on keeping the emulator on for about 5 billion years, I guess, nerd."); default: Util::panic("Unknown scheduler event type {}", static_cast(type)); } events.pop(); } }