diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index 927415fa..fff8821a 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -1,8 +1,6 @@ #include -#include #include #include -#include #include #include #include @@ -49,18 +47,6 @@ static void check_vk_result(VkResult err) { } } -inline ImU8 readHandler(const ImU8* core_, size_t offset) { - auto* core = reinterpret_cast(const_cast(core_)); - auto& mem = core->mem; - return mem.Read8(core->cpu.regs, offset, core->cpu.regs.oldPC); -} - -inline void writeHandler(ImU8* core_, size_t offset, ImU8 value) { - auto* core = reinterpret_cast(const_cast(core_)); - auto& mem = core->mem; - mem.Write8(core->cpu.regs, offset, value, core->cpu.regs.oldPC); -} - void Window::InitImgui(const n64::Core& core) { VkResult err; @@ -135,10 +121,6 @@ void Window::InitImgui(const n64::Core& core) { ImGui_ImplVulkan_CreateFontsTexture(commandBuffer); SubmitRequestedVkCommandBuffer(); } - - memoryEditor.ReadFn = readHandler; - memoryEditor.WriteFn = writeHandler; - memoryEditor.Cols = 32; } Window::~Window() { @@ -187,6 +169,7 @@ void Window::Render(n64::Core& core) { ImGui::PushFont(uiFont); u32 ticks = SDL_GetTicks(); + static u32 lastFrame = 0; if(!core.pause && lastFrame < ticks - 1000) { lastFrame = ticks; windowTitle += fmt::format(" | {:02d} In-Game FPS", core.mem.mmio.vi.swaps); @@ -195,13 +178,7 @@ void Window::Render(n64::Core& core) { windowTitle = shadowWindowTitle; } static bool showSettings = false; - static bool showMemEditor = false; bool showMainMenuBar = windowID == SDL_GetWindowID(SDL_GetMouseFocus()); - if(showMemEditor) { - ImGui::PushFont(codeFont); - memoryEditor.DrawWindow("Memory viewer", &core, 0x80000000); - ImGui::PopFont(); - } if(showMainMenuBar) { ImGui::BeginMainMenuBar(); if (ImGui::BeginMenu("File")) { @@ -250,7 +227,6 @@ void Window::Render(n64::Core& core) { if (ImGui::MenuItem("Settings")) { showSettings = true; } - ImGui::Checkbox("Show memory editor", &showMemEditor); ImGui::EndMenu(); } ImGui::EndMainMenuBar(); diff --git a/src/frontend/imgui/Window.hpp b/src/frontend/imgui/Window.hpp index e5b47d5d..5f2eb2d2 100644 --- a/src/frontend/imgui/Window.hpp +++ b/src/frontend/imgui/Window.hpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -14,16 +13,15 @@ struct Window { ImDrawData* Present(n64::Core& core); [[nodiscard]] bool gotClosed(SDL_Event event); - ImFont *uiFont, *codeFont; - u32 windowID; + ImFont *uiFont{}, *codeFont{}; + u32 windowID{}; float volumeL = 0.5, volumeR = 0.5; void LoadROM(n64::Core& core, const std::string& path); private: bool lockVolume = true; - SDL_Window* window; + SDL_Window* window{}; std::string windowTitle; std::string shadowWindowTitle; - u32 lastFrame = 0; void InitSDL(); void InitImgui(const n64::Core& core); void Render(n64::Core& core); @@ -36,8 +34,5 @@ private: VkDescriptorPool descriptorPool{}; VkAllocationCallbacks* allocator{}; - MemoryEditor memoryEditor; - u32 minImageCount = 2; - bool rebuildSwapchain = false; }; diff --git a/src/n64/core/MMIO.cpp b/src/n64/core/MMIO.cpp index 1c1596f7..2563e0e8 100644 --- a/src/n64/core/MMIO.cpp +++ b/src/n64/core/MMIO.cpp @@ -19,46 +19,33 @@ void MMIO::Reset() { si.Reset(); } -template u32 MMIO::Read(u32 addr) { switch (addr) { - case 0x04040000 ... 0x040FFFFF: return rsp.Read(addr); - case 0x04100000 ... 0x041FFFFF: return rdp.Read(addr); - case 0x04300000 ... 0x043FFFFF: return mi.Read(addr); - case 0x04400000 ... 0x044FFFFF: return vi.Read(addr); + case 0x04040000 ... 0x040FFFFF: return rsp.Read(addr); + case 0x04100000 ... 0x041FFFFF: return rdp.Read(addr); + case 0x04300000 ... 0x043FFFFF: return mi.Read(addr); + case 0x04400000 ... 0x044FFFFF: return vi.Read(addr); case 0x04500000 ... 0x045FFFFF: return ai.Read(addr); - case 0x04600000 ... 0x046FFFFF: return pi.Read(mi, addr); - case 0x04700000 ... 0x047FFFFF: return ri.Read(addr); - case 0x04800000 ... 0x048FFFFF: return si.Read(mi, addr); + case 0x04600000 ... 0x046FFFFF: return pi.Read(mi, addr); + case 0x04700000 ... 0x047FFFFF: return ri.Read(addr); + case 0x04800000 ... 0x048FFFFF: return si.Read(mi, addr); default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled mmio read at addr {:08X}\n", addr); - } - return 0; + util::panic("Unhandled mmio read at addr {:08X}\n", addr); } } -template u32 MMIO::Read(u32); -template u32 MMIO::Read(u32); - -template void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { switch (addr) { - case 0x04040000 ... 0x040FFFFF: rsp.Write(mem, regs, addr, val); break; - case 0x04100000 ... 0x041FFFFF: rdp.Write(mi, regs, rsp, addr, val); break; - case 0x04300000 ... 0x043FFFFF: mi.Write(regs, addr, val); break; - case 0x04400000 ... 0x044FFFFF: vi.Write(mi, regs, addr, val); break; - case 0x04500000 ... 0x045FFFFF: ai.Write(mem, regs, addr, val); break; - case 0x04600000 ... 0x046FFFFF: pi.Write(mem, regs, addr, val); break; - case 0x04700000 ... 0x047FFFFF: ri.Write(addr, val); break; - case 0x04800000 ... 0x048FFFFF: si.Write(mem, regs, addr, val); break; + case 0x04040000 ... 0x040FFFFF: rsp.Write(mem, regs, addr, val); break; + case 0x04100000 ... 0x041FFFFF: rdp.Write(mi, regs, rsp, addr, val); break; + case 0x04300000 ... 0x043FFFFF: mi.Write(regs, addr, val); break; + case 0x04400000 ... 0x044FFFFF: vi.Write(mi, regs, addr, val); break; + case 0x04500000 ... 0x045FFFFF: ai.Write(mem, regs, addr, val); break; + case 0x04600000 ... 0x046FFFFF: pi.Write(mem, regs, addr, val); break; + case 0x04700000 ... 0x047FFFFF: ri.Write(addr, val); break; + case 0x04800000 ... 0x048FFFFF: si.Write(mem, regs, addr, val); break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled mmio write at addr {:08X} with val {:08X}\n", addr, val); - } + util::panic("Unhandled mmio write at addr {:08X} with val {:08X}\n", addr, val); } } - -template void MMIO::Write(Mem&, Registers&, u32, u32); -template void MMIO::Write(Mem&, Registers&, u32, u32); } diff --git a/src/n64/core/MMIO.hpp b/src/n64/core/MMIO.hpp index a1b3c385..f102b324 100644 --- a/src/n64/core/MMIO.hpp +++ b/src/n64/core/MMIO.hpp @@ -24,9 +24,7 @@ struct MMIO { RSP rsp; RDP rdp; - template u32 Read(u32); - template void Write(Mem&, Registers&, u32, u32); }; } diff --git a/src/n64/core/Mem.cpp b/src/n64/core/Mem.cpp index 7d511b98..71c7db11 100644 --- a/src/n64/core/Mem.cpp +++ b/src/n64/core/Mem.cpp @@ -70,7 +70,7 @@ bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) template bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); template bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); -template +template u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) { u32 paddr = vaddr; if(!MapVAddr(regs, LOAD, vaddr, paddr)) { @@ -88,7 +88,7 @@ u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) { return mmio.rsp.dmem[BYTE_ADDRESS(paddr) & DMEM_DSIZE]; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: - return mmio.Read(paddr); + return mmio.Read(paddr); case 0x10000000 ... 0x1FBFFFFF: paddr = (paddr + 2) & ~2; return cart[BYTE_ADDRESS(paddr) & romMask]; @@ -99,10 +99,7 @@ u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) { case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64)regs.pc); - } - return 0; + util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64)regs.pc); } } @@ -201,10 +198,8 @@ u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc) { } } -template u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc); -template u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc); -template u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc); -template u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc); +template u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc); +template u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc); template u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc); template u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc); template u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc); @@ -212,7 +207,7 @@ template u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc); template u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc); template u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc); -template +template void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) { u32 paddr = vaddr; if(!MapVAddr(regs, STORE, vaddr, paddr)) { @@ -233,7 +228,7 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) { util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Write(*this, regs, paddr, val); break; + case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Write(*this, regs, paddr, val); break; case 0x10000000 ... 0x13FFFFFF: break; case 0x1FC007C0 ... 0x1FC007FF: val = val << (8 * (3 - (paddr & 3))); @@ -245,9 +240,7 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) { case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unimplemented 8-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64)regs.pc); - } + util::panic("Unimplemented 8-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64)regs.pc); } } @@ -363,10 +356,8 @@ void Mem::Write64(Registers& regs, u64 vaddr, u64 val, s64 pc) { } } -template void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc); -template void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc); -template void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc); -template void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc); +template void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc); +template void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc); diff --git a/src/n64/core/Mem.hpp b/src/n64/core/Mem.hpp index 48b34c58..10f1d0a5 100644 --- a/src/n64/core/Mem.hpp +++ b/src/n64/core/Mem.hpp @@ -23,7 +23,7 @@ struct Mem { return mmio.rdp.dram.data(); } - template + template u8 Read8(Registers&, u64, s64); template u16 Read16(Registers&, u64, s64); @@ -31,7 +31,7 @@ struct Mem { u32 Read32(Registers&, u64, s64); template u64 Read64(Registers&, u64, s64); - template + template void Write8(Registers&, u64, u32, s64); template void Write16(Registers&, u64, u32, s64); diff --git a/src/n64/core/RDP.cpp b/src/n64/core/RDP.cpp index 3b321797..955e8cdf 100644 --- a/src/n64/core/RDP.cpp +++ b/src/n64/core/RDP.cpp @@ -23,7 +23,6 @@ static const int cmd_lens[64] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; -template auto RDP::Read(u32 addr) const -> u32 { switch(addr) { case 0x04100000: return dpc.start; @@ -36,32 +35,20 @@ auto RDP::Read(u32 addr) const -> u32 { case 0x04100018: return dpc.status.pipeBusy; case 0x0410001C: return dpc.tmem; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled DP Command Registers read (addr: {:08X})\n", addr); - } - return 0; + util::panic("Unhandled DP Command Registers read (addr: {:08X})\n", addr); } } -template auto RDP::Read(u32 addr) const -> u32; -template auto RDP::Read(u32 addr) const -> u32; - -template void RDP::Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val) { switch(addr) { case 0x04100000: WriteStart(val); break; case 0x04100004: WriteEnd(mi, regs, rsp, val); break; case 0x0410000C: WriteStatus(mi, regs, rsp, val); break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled DP Command Registers write (addr: {:08X}, val: {:08X})\n", addr, val); - } + util::panic("Unhandled DP Command Registers write (addr: {:08X}, val: {:08X})\n", addr, val); } } -template void RDP::Write(MI&, Registers&, RSP&, u32, u32); -template void RDP::Write(MI&, Registers&, RSP&, u32, u32); - void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) { DPCStatusWrite temp{}; temp.raw = val; diff --git a/src/n64/core/RDP.hpp b/src/n64/core/RDP.hpp index e1ab5014..4fd39dc8 100644 --- a/src/n64/core/RDP.hpp +++ b/src/n64/core/RDP.hpp @@ -58,9 +58,7 @@ struct RDP { void Reset(); std::vector dram; - template [[nodiscard]] auto Read(u32 addr) const -> u32; - template void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val); void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val); void RunCommand(MI& mi, Registers& regs, RSP& rsp); diff --git a/src/n64/core/RSP.cpp b/src/n64/core/RSP.cpp index 5e34c176..01426d35 100644 --- a/src/n64/core/RSP.cpp +++ b/src/n64/core/RSP.cpp @@ -73,7 +73,6 @@ void RSP::Step(Registers& regs, Mem& mem) { //logRSP(*this, instr); } -template auto RSP::Read(u32 addr) -> u32{ switch (addr) { case 0x04040000: return lastSuccessfulSPAddr.raw & 0x1FF8; @@ -84,23 +83,13 @@ auto RSP::Read(u32 addr) -> u32{ case 0x04040014: return spStatus.dmaFull; case 0x04040018: return 0; case 0x0404001C: - if constexpr (crashOnUnimplemented) { - return semaphore; - } return AcquireSemaphore(); case 0x04080000: return pc & 0xFFC; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unimplemented SP register read {:08X}\n", addr); - } - return 0; + util::panic("Unimplemented SP register read {:08X}\n", addr); } } -template auto RSP::Read(u32 addr) -> u32; -template auto RSP::Read(u32 addr) -> u32; - -template void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { MI& mi = mem.mmio.mi; switch (addr) { @@ -121,12 +110,7 @@ void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { SetPC(value); } break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unimplemented SP register write {:08X}, val: {:08X}\n", addr, value); - } + util::panic("Unimplemented SP register write {:08X}, val: {:08X}\n", addr, value); } } - -template void RSP::Write(n64::Mem &mem, n64::Registers ®s, u32 addr, u32 value); -template void RSP::Write(n64::Mem &mem, n64::Registers ®s, u32 addr, u32 value); } diff --git a/src/n64/core/RSP.hpp b/src/n64/core/RSP.hpp index 781f66bf..ccf1b790 100644 --- a/src/n64/core/RSP.hpp +++ b/src/n64/core/RSP.hpp @@ -113,9 +113,7 @@ struct RSP { RSP(); void Reset(); void Step(Registers& regs, Mem& mem); - template auto Read(u32 addr) -> u32; - template void Write(Mem& mem, Registers& regs, u32 addr, u32 value); void Exec(Registers& regs, Mem& mem, u32 instr); SPStatus spStatus; diff --git a/src/n64/core/mmio/AI.cpp b/src/n64/core/mmio/AI.cpp index 23b2dec4..ec5597cc 100644 --- a/src/n64/core/mmio/AI.cpp +++ b/src/n64/core/mmio/AI.cpp @@ -34,7 +34,6 @@ auto AI::Read(u32 addr) const -> u32 { #define max(x, y) ((x) > (y) ? (x) : (y)) -template void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { switch(addr) { case 0x04500000: @@ -70,15 +69,10 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { dac.precision = bitrate + 1; break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled AI write at addr {:08X} with val {:08X}\n", addr, val); - } + util::panic("Unhandled AI write at addr {:08X} with val {:08X}\n", addr, val); } } -template void AI::Write(Mem&, Registers&, u32, u32); -template void AI::Write(Mem&, Registers&, u32, u32); - void AI::Step(Mem& mem, Registers& regs, int cpuCycles, float volumeL, float volumeR) { cycles += cpuCycles; while(cycles > dac.period) { diff --git a/src/n64/core/mmio/AI.hpp b/src/n64/core/mmio/AI.hpp index 5a6f5691..bec1ade8 100644 --- a/src/n64/core/mmio/AI.hpp +++ b/src/n64/core/mmio/AI.hpp @@ -10,7 +10,6 @@ struct AI { AI() = default; void Reset(); auto Read(u32) const -> u32; - template void Write(Mem&, Registers&, u32, u32); void Step(Mem&, Registers&, int, float, float); bool dmaEnable{}; diff --git a/src/n64/core/mmio/MI.cpp b/src/n64/core/mmio/MI.cpp index f79b2106..7ad3f4c3 100644 --- a/src/n64/core/mmio/MI.cpp +++ b/src/n64/core/mmio/MI.cpp @@ -16,7 +16,6 @@ void MI::Reset() { miMode = 0; } -template auto MI::Read(u32 paddr) const -> u32 { switch(paddr & 0xF) { case 0x0: return miMode & 0x3FF; @@ -24,17 +23,10 @@ auto MI::Read(u32 paddr) const -> u32 { case 0x8: return miIntr.raw & 0x3F; case 0xC: return miIntrMask.raw & 0x3F; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled MI[{:08X}] read\n", paddr); - } - return 0; + util::panic("Unhandled MI[{:08X}] read\n", paddr); } } -template auto MI::Read(u32 paddr) const -> u32; -template auto MI::Read(u32 paddr) const -> u32; - -template void MI::Write(Registers& regs, u32 paddr, u32 val) { switch(paddr & 0xF) { case 0x0: @@ -86,12 +78,7 @@ void MI::Write(Registers& regs, u32 paddr, u32 val) { UpdateInterrupt(*this, regs); break; default: - if(crashOnUnimplemented) { - util::panic("Unhandled MI[{:08X}] write ({:08X})\n", val, paddr); - } + util::panic("Unhandled MI[{:08X}] write ({:08X})\n", val, paddr); } } - -template void MI::Write(Registers&, u32 paddr, u32 val); -template void MI::Write(Registers&, u32 paddr, u32 val); } diff --git a/src/n64/core/mmio/MI.hpp b/src/n64/core/mmio/MI.hpp index d6b7b831..c8b5b04a 100644 --- a/src/n64/core/mmio/MI.hpp +++ b/src/n64/core/mmio/MI.hpp @@ -21,9 +21,7 @@ struct Registers; struct MI { MI(); void Reset(); - template [[nodiscard]] auto Read(u32) const -> u32; - template void Write(Registers& regs, u32, u32); u32 miMode; diff --git a/src/n64/core/mmio/PI.cpp b/src/n64/core/mmio/PI.cpp index 3512ede0..e2753d7f 100644 --- a/src/n64/core/mmio/PI.cpp +++ b/src/n64/core/mmio/PI.cpp @@ -17,7 +17,6 @@ void PI::Reset() { memset(stub, 0, 8); } -template auto PI::Read(MI& mi, u32 addr) const -> u32 { switch(addr) { case 0x04600000: return dramAddr; @@ -36,17 +35,10 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 { case 0x04600024: case 0x04600028: case 0x0460002C: case 0x04600030: return stub[(addr & 0xff) - 5]; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled PI[{:08X}] read\n", addr); - } - return 0; + util::panic("Unhandled PI[{:08X}] read\n", addr); } } -template auto PI::Read(MI&, u32) const -> u32; -template auto PI::Read(MI&, u32) const -> u32; - -template void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { MI& mi = mem.mmio.mi; switch(addr) { @@ -94,12 +86,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { stub[(addr & 0xff) - 5] = val & 0xff; break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled PI[{:08X}] write ({:08X})\n", val, addr); - } + util::panic("Unhandled PI[{:08X}] write ({:08X})\n", val, addr); } } - -template void PI::Write(n64::Mem &mem, n64::Registers ®s, u32 addr, u32 val); -template void PI::Write(n64::Mem &mem, n64::Registers ®s, u32 addr, u32 val); } \ No newline at end of file diff --git a/src/n64/core/mmio/PI.hpp b/src/n64/core/mmio/PI.hpp index 9b6ca275..49ac8617 100644 --- a/src/n64/core/mmio/PI.hpp +++ b/src/n64/core/mmio/PI.hpp @@ -10,9 +10,7 @@ struct Registers; struct PI { PI(); void Reset(); - template auto Read(MI&, u32) const -> u32; - template void Write(Mem&, Registers&, u32, u32); u32 dramAddr{}, cartAddr{}; u32 rdLen{}, wrLen{}; diff --git a/src/n64/core/mmio/RI.cpp b/src/n64/core/mmio/RI.cpp index 30586a35..943e3128 100644 --- a/src/n64/core/mmio/RI.cpp +++ b/src/n64/core/mmio/RI.cpp @@ -13,7 +13,6 @@ void RI::Reset() { refresh = 0x63634; } -template auto RI::Read(u32 addr) const -> u32 { switch(addr) { case 0x04700000: return mode; @@ -21,17 +20,10 @@ auto RI::Read(u32 addr) const -> u32 { case 0x0470000C: return select; case 0x04700010: return refresh; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled RI[{:08X}] read\n", addr); - } - return 0; + util::panic("Unhandled RI[{:08X}] read\n", addr); } } -template auto RI::Read(u32 addr) const -> u32; -template auto RI::Read(u32 addr) const -> u32; - -template void RI::Write(u32 addr, u32 val) { switch(addr) { case 0x04700000: mode = val; break; @@ -39,12 +31,7 @@ void RI::Write(u32 addr, u32 val) { case 0x0470000C: select = val; break; case 0x04700010: refresh = val; break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled RI[{:08X}] write with val {:08X}\n", addr, val); - } + util::panic("Unhandled RI[{:08X}] write with val {:08X}\n", addr, val); } } - -template void RI::Write(u32 addr, u32 val); -template void RI::Write(u32 addr, u32 val); } diff --git a/src/n64/core/mmio/RI.hpp b/src/n64/core/mmio/RI.hpp index 0aa687cd..36cd4ee7 100644 --- a/src/n64/core/mmio/RI.hpp +++ b/src/n64/core/mmio/RI.hpp @@ -6,9 +6,7 @@ namespace n64 { struct RI { RI(); void Reset(); - template auto Read(u32) const -> u32; - template void Write(u32, u32); u32 mode{0xE}, config{0x40}, select{0x14}, refresh{0x63634}; }; diff --git a/src/n64/core/mmio/SI.cpp b/src/n64/core/mmio/SI.cpp index c506efae..a779a80a 100644 --- a/src/n64/core/mmio/SI.cpp +++ b/src/n64/core/mmio/SI.cpp @@ -12,7 +12,6 @@ void SI::Reset() { controller.raw = 0; } -template auto SI::Read(MI& mi, u32 addr) const -> u32 { switch(addr) { case 0x04800000: return dramAddr; @@ -26,17 +25,10 @@ auto SI::Read(MI& mi, u32 addr) const -> u32 { return val; } default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled SI[{:08X}] read\n", addr); - } - return 0; + util::panic("Unhandled SI[{:08X}] read\n", addr); } } -template auto SI::Read(MI &mi, u32 addr) const -> u32; -template auto SI::Read(MI &mi, u32 addr) const -> u32; - -template void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { switch(addr) { case 0x04800000: @@ -66,12 +58,7 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { status.intr = 0; break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unhandled SI[%08X] write (%08X)\n", addr, val); - } + util::panic("Unhandled SI[%08X] write (%08X)\n", addr, val); } } - -template void SI::Write(Mem &mem, Registers ®s, u32 addr, u32 val); -template void SI::Write(Mem &mem, Registers ®s, u32 addr, u32 val); } \ No newline at end of file diff --git a/src/n64/core/mmio/SI.hpp b/src/n64/core/mmio/SI.hpp index b21d73e7..1f05236e 100644 --- a/src/n64/core/mmio/SI.hpp +++ b/src/n64/core/mmio/SI.hpp @@ -27,9 +27,7 @@ struct SI { u32 dramAddr{}; Controller controller{}; - template auto Read(MI&, u32) const -> u32; - template void Write(Mem&, Registers&, u32, u32); }; } \ No newline at end of file diff --git a/src/n64/core/mmio/VI.cpp b/src/n64/core/mmio/VI.cpp index f09a66ee..66f68c50 100644 --- a/src/n64/core/mmio/VI.cpp +++ b/src/n64/core/mmio/VI.cpp @@ -22,7 +22,6 @@ void VI::Reset() { cyclesPerHalfline = 1000; } -template u32 VI::Read(u32 paddr) const { switch(paddr) { case 0x04400000: return status.raw; @@ -40,17 +39,10 @@ u32 VI::Read(u32 paddr) const { case 0x04400030: return xscale.raw; case 0x04400034: return yscale.raw; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unimplemented VI[%08X] read\n", paddr); - } - return 0; + util::panic("Unimplemented VI[%08X] read\n", paddr); } } -template u32 VI::Read(u32 paddr) const; -template u32 VI::Read(u32 paddr) const; - -template void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) { switch(paddr) { case 0x04400000: @@ -89,12 +81,7 @@ void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) { case 0x04400030: xscale.raw = val; break; case 0x04400034: yscale.raw = val; break; default: - if constexpr (crashOnUnimplemented) { - util::panic("Unimplemented VI[%08X] write (%08X)\n", paddr, val); - } + util::panic("Unimplemented VI[%08X] write (%08X)\n", paddr, val); } } - -template void VI::Write(n64::MI &mi, n64::Registers ®s, u32 paddr, u32 val); -template void VI::Write(n64::MI &mi, n64::Registers ®s, u32 paddr, u32 val); } \ No newline at end of file diff --git a/src/n64/core/mmio/VI.hpp b/src/n64/core/mmio/VI.hpp index b3100dbc..caf7fef3 100644 --- a/src/n64/core/mmio/VI.hpp +++ b/src/n64/core/mmio/VI.hpp @@ -88,9 +88,7 @@ struct Registers; struct VI { VI(); void Reset(); - template [[nodiscard]] u32 Read(u32) const; - template void Write(MI&, Registers&, u32, u32); AxisScale xscale{}, yscale{}; VIHsyncLeap hsyncLeap{}; diff --git a/src/n64/core/rsp/instructions.cpp b/src/n64/core/rsp/instructions.cpp index 4dde3718..49ae0b49 100644 --- a/src/n64/core/rsp/instructions.cpp +++ b/src/n64/core/rsp/instructions.cpp @@ -543,13 +543,13 @@ void RSP::sltiu(u32 instr) { inline s16 signedClamp(s64 val) { if(val < -32768) return -32768; - else if(val > 32767) return 32767; + if(val > 32767) return 32767; return val; } inline u16 unsignedClamp(s64 val) { if(val < 0) return 0; - else if(val > 32767) return 65535; + if(val > 32767) return 65535; return val; } @@ -753,11 +753,16 @@ void RSP::vmulf(u32 instr) { VPR vte = GetVTE(vpr[VT(instr)], e); for(int i = 0; i < 8; i++) { - s64 prod = (vs.selement[i] * vte.selement[i]) * 2 + 0x8000; + s16 op1 = vte.element[i]; + s16 op2 = vs.element[i]; + s32 prod = op1 * op2; - SetACC(i, prod); + s64 accum = prod; + accum = (accum * 2) + 0x8000; - s16 result = signedClamp(prod >> 16); + SetACC(i, accum); + + s16 result = signedClamp(accum >> 16); vd.element[i] = result; } } @@ -769,9 +774,13 @@ void RSP::vmulu(u32 instr) { VPR vte = GetVTE(vpr[VT(instr)], e); for(int i = 0; i < 8; i++) { - s32 prod = vs.selement[i] * vte.selement[i]; + s16 op1 = vte.element[i]; + s16 op2 = vs.element[i]; + s32 prod = op1 * op2; + + s64 accum = prod; + accum = (accum * 2) + 0x8000; - s64 accum = prod * 2 + 0x8000; SetACC(i, accum); u16 result = unsignedClamp(accum >> 16);