diff --git a/src/frontend/imgui/Window.hpp b/src/frontend/imgui/Window.hpp index 5f2eb2d2..5378dac9 100644 --- a/src/frontend/imgui/Window.hpp +++ b/src/frontend/imgui/Window.hpp @@ -15,7 +15,7 @@ struct Window { [[nodiscard]] bool gotClosed(SDL_Event event); ImFont *uiFont{}, *codeFont{}; u32 windowID{}; - float volumeL = 0.5, volumeR = 0.5; + float volumeL = 0.1, volumeR = 0.1; void LoadROM(n64::Core& core, const std::string& path); private: bool lockVolume = true; diff --git a/src/n64/Scheduler.cpp b/src/n64/Scheduler.cpp index f33e8a05..8ace3658 100644 --- a/src/n64/Scheduler.cpp +++ b/src/n64/Scheduler.cpp @@ -10,13 +10,17 @@ Scheduler::Scheduler() { }}); } -void Scheduler::enqueue(const Event& event) { +void Scheduler::enqueueRelative(const Event& event) { events.push({event.time + ticks, event.event_cb}); } +void Scheduler::enqueueAbsolute(const Event& event) { + events.push({event.time, event.event_cb}); +} + void Scheduler::tick(u64 t, n64::Mem& mem, n64::Registers& regs) { ticks += t; - while(ticks >= events.top().time) { + if(ticks >= events.top().time) { events.top().event_cb(mem, regs); events.pop(); } diff --git a/src/n64/Scheduler.hpp b/src/n64/Scheduler.hpp index 2107e21d..cd440dd7 100644 --- a/src/n64/Scheduler.hpp +++ b/src/n64/Scheduler.hpp @@ -9,7 +9,7 @@ struct Registers; struct Event { u64 time = UINT64_MAX; - void(*event_cb)(n64::Mem&, n64::Registers&); + void(*event_cb)(n64::Mem&, n64::Registers&) = nullptr; friend bool operator<(const Event& rhs, const Event& lhs) { return lhs.time < rhs.time; @@ -18,7 +18,8 @@ struct Event { struct Scheduler { Scheduler(); - void enqueue(const Event&); + void enqueueRelative(const Event&); + void enqueueAbsolute(const Event&); void tick(u64, n64::Mem&, n64::Registers&); std::priority_queue events; u64 ticks = 0; diff --git a/src/n64/core/mmio/SI.cpp b/src/n64/core/mmio/SI.cpp index 5b9b935d..097c9def 100644 --- a/src/n64/core/mmio/SI.cpp +++ b/src/n64/core/mmio/SI.cpp @@ -10,12 +10,14 @@ SI::SI() { void SI::Reset() { status.raw = 0; dramAddr = 0; + pifAddr = 0; memset(&controller, 0, sizeof(Controller)); } auto SI::Read(MI& mi, u32 addr) const -> u32 { switch(addr) { case 0x04800000: return dramAddr; + case 0x04800004: case 0x04800010: return pifAddr; case 0x0480000C: return 0; case 0x04800018: { u32 val = 0; @@ -46,6 +48,7 @@ void DMA(Mem& mem, Registers& regs) { for(int i = 0; i < 64; i++) { mem.pifRam[i] = mem.mmio.rdp.dram[BYTE_ADDRESS(si.dramAddr + i)]; } + util::logdebug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr); ProcessPIFCommands(mem.pifRam, si.controller, mem); } InterruptRaise(mem.mmio.mi, regs, Interrupt::SI); @@ -57,15 +60,16 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { dramAddr = val & RDRAM_DSIZE; break; case 0x04800004: { + pifAddr = val & 0x1FFFFFFF; status.dmaBusy = true; toDram = true; - scheduler.enqueue({SI_DMA_DELAY, DMA}); - util::logdebug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", val & 0x1FFFFFFF, dramAddr); + scheduler.enqueueRelative({SI_DMA_DELAY, DMA}); } break; case 0x04800010: { + pifAddr = val & 0x1FFFFFFF; status.dmaBusy = true; toDram = false; - scheduler.enqueue({SI_DMA_DELAY, DMA}); + scheduler.enqueueRelative({SI_DMA_DELAY, DMA}); util::logdebug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, val & 0x1FFFFFFF); } break; case 0x04800018: diff --git a/src/n64/core/mmio/SI.hpp b/src/n64/core/mmio/SI.hpp index 24546e7b..5adbc8f8 100644 --- a/src/n64/core/mmio/SI.hpp +++ b/src/n64/core/mmio/SI.hpp @@ -25,6 +25,7 @@ struct SI { void Reset(); SIStatus status{}; u32 dramAddr{}; + u32 pifAddr{}; Controller controller{}; bool toDram = false;