Remove memory editor

This commit is contained in:
CocoSimone
2022-10-18 12:22:17 +02:00
parent 7305aff4ed
commit 6a42a212c4
23 changed files with 64 additions and 223 deletions

View File

@@ -1,8 +1,6 @@
#include <Window.hpp> #include <Window.hpp>
#include <util.hpp>
#include <nfd.hpp> #include <nfd.hpp>
#include <Core.hpp> #include <Core.hpp>
#include <utility>
#include <Audio.hpp> #include <Audio.hpp>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <filesystem> #include <filesystem>
@@ -49,18 +47,6 @@ static void check_vk_result(VkResult err) {
} }
} }
inline ImU8 readHandler(const ImU8* core_, size_t offset) {
auto* core = reinterpret_cast<n64::Core*>(const_cast<ImU8*>(core_));
auto& mem = core->mem;
return mem.Read8<false, false>(core->cpu.regs, offset, core->cpu.regs.oldPC);
}
inline void writeHandler(ImU8* core_, size_t offset, ImU8 value) {
auto* core = reinterpret_cast<n64::Core*>(const_cast<ImU8*>(core_));
auto& mem = core->mem;
mem.Write8<false, false>(core->cpu.regs, offset, value, core->cpu.regs.oldPC);
}
void Window::InitImgui(const n64::Core& core) { void Window::InitImgui(const n64::Core& core) {
VkResult err; VkResult err;
@@ -135,10 +121,6 @@ void Window::InitImgui(const n64::Core& core) {
ImGui_ImplVulkan_CreateFontsTexture(commandBuffer); ImGui_ImplVulkan_CreateFontsTexture(commandBuffer);
SubmitRequestedVkCommandBuffer(); SubmitRequestedVkCommandBuffer();
} }
memoryEditor.ReadFn = readHandler;
memoryEditor.WriteFn = writeHandler;
memoryEditor.Cols = 32;
} }
Window::~Window() { Window::~Window() {
@@ -187,6 +169,7 @@ void Window::Render(n64::Core& core) {
ImGui::PushFont(uiFont); ImGui::PushFont(uiFont);
u32 ticks = SDL_GetTicks(); u32 ticks = SDL_GetTicks();
static u32 lastFrame = 0;
if(!core.pause && lastFrame < ticks - 1000) { if(!core.pause && lastFrame < ticks - 1000) {
lastFrame = ticks; lastFrame = ticks;
windowTitle += fmt::format(" | {:02d} In-Game FPS", core.mem.mmio.vi.swaps); windowTitle += fmt::format(" | {:02d} In-Game FPS", core.mem.mmio.vi.swaps);
@@ -195,13 +178,7 @@ void Window::Render(n64::Core& core) {
windowTitle = shadowWindowTitle; windowTitle = shadowWindowTitle;
} }
static bool showSettings = false; static bool showSettings = false;
static bool showMemEditor = false;
bool showMainMenuBar = windowID == SDL_GetWindowID(SDL_GetMouseFocus()); bool showMainMenuBar = windowID == SDL_GetWindowID(SDL_GetMouseFocus());
if(showMemEditor) {
ImGui::PushFont(codeFont);
memoryEditor.DrawWindow("Memory viewer", &core, 0x80000000);
ImGui::PopFont();
}
if(showMainMenuBar) { if(showMainMenuBar) {
ImGui::BeginMainMenuBar(); ImGui::BeginMainMenuBar();
if (ImGui::BeginMenu("File")) { if (ImGui::BeginMenu("File")) {
@@ -250,7 +227,6 @@ void Window::Render(n64::Core& core) {
if (ImGui::MenuItem("Settings")) { if (ImGui::MenuItem("Settings")) {
showSettings = true; showSettings = true;
} }
ImGui::Checkbox("Show memory editor", &showMemEditor);
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();

View File

@@ -3,7 +3,6 @@
#include <imgui.h> #include <imgui.h>
#include <imgui_impl_sdl.h> #include <imgui_impl_sdl.h>
#include <imgui_impl_vulkan.h> #include <imgui_impl_vulkan.h>
#include <imgui_memory_editor.h>
#include <SDL.h> #include <SDL.h>
#include <Core.hpp> #include <Core.hpp>
#include <vector> #include <vector>
@@ -14,16 +13,15 @@ struct Window {
ImDrawData* Present(n64::Core& core); ImDrawData* Present(n64::Core& core);
[[nodiscard]] bool gotClosed(SDL_Event event); [[nodiscard]] bool gotClosed(SDL_Event event);
ImFont *uiFont, *codeFont; ImFont *uiFont{}, *codeFont{};
u32 windowID; u32 windowID{};
float volumeL = 0.5, volumeR = 0.5; float volumeL = 0.5, volumeR = 0.5;
void LoadROM(n64::Core& core, const std::string& path); void LoadROM(n64::Core& core, const std::string& path);
private: private:
bool lockVolume = true; bool lockVolume = true;
SDL_Window* window; SDL_Window* window{};
std::string windowTitle; std::string windowTitle;
std::string shadowWindowTitle; std::string shadowWindowTitle;
u32 lastFrame = 0;
void InitSDL(); void InitSDL();
void InitImgui(const n64::Core& core); void InitImgui(const n64::Core& core);
void Render(n64::Core& core); void Render(n64::Core& core);
@@ -36,8 +34,5 @@ private:
VkDescriptorPool descriptorPool{}; VkDescriptorPool descriptorPool{};
VkAllocationCallbacks* allocator{}; VkAllocationCallbacks* allocator{};
MemoryEditor memoryEditor;
u32 minImageCount = 2; u32 minImageCount = 2;
bool rebuildSwapchain = false;
}; };

View File

@@ -19,46 +19,33 @@ void MMIO::Reset() {
si.Reset(); si.Reset();
} }
template <bool crashOnUnimplemented>
u32 MMIO::Read(u32 addr) { u32 MMIO::Read(u32 addr) {
switch (addr) { switch (addr) {
case 0x04040000 ... 0x040FFFFF: return rsp.Read<crashOnUnimplemented>(addr); case 0x04040000 ... 0x040FFFFF: return rsp.Read(addr);
case 0x04100000 ... 0x041FFFFF: return rdp.Read<crashOnUnimplemented>(addr); case 0x04100000 ... 0x041FFFFF: return rdp.Read(addr);
case 0x04300000 ... 0x043FFFFF: return mi.Read<crashOnUnimplemented>(addr); case 0x04300000 ... 0x043FFFFF: return mi.Read(addr);
case 0x04400000 ... 0x044FFFFF: return vi.Read<crashOnUnimplemented>(addr); case 0x04400000 ... 0x044FFFFF: return vi.Read(addr);
case 0x04500000 ... 0x045FFFFF: return ai.Read(addr); case 0x04500000 ... 0x045FFFFF: return ai.Read(addr);
case 0x04600000 ... 0x046FFFFF: return pi.Read<crashOnUnimplemented>(mi, addr); case 0x04600000 ... 0x046FFFFF: return pi.Read(mi, addr);
case 0x04700000 ... 0x047FFFFF: return ri.Read<crashOnUnimplemented>(addr); case 0x04700000 ... 0x047FFFFF: return ri.Read(addr);
case 0x04800000 ... 0x048FFFFF: return si.Read<crashOnUnimplemented>(mi, addr); case 0x04800000 ... 0x048FFFFF: return si.Read(mi, addr);
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unhandled mmio read at addr {:08X}\n", addr);
util::panic("Unhandled mmio read at addr {:08X}\n", addr);
}
return 0;
} }
} }
template u32 MMIO::Read<true>(u32);
template u32 MMIO::Read<false>(u32);
template <bool crashOnUnimplemented>
void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
switch (addr) { switch (addr) {
case 0x04040000 ... 0x040FFFFF: rsp.Write<crashOnUnimplemented>(mem, regs, addr, val); break; case 0x04040000 ... 0x040FFFFF: rsp.Write(mem, regs, addr, val); break;
case 0x04100000 ... 0x041FFFFF: rdp.Write<crashOnUnimplemented>(mi, regs, rsp, addr, val); break; case 0x04100000 ... 0x041FFFFF: rdp.Write(mi, regs, rsp, addr, val); break;
case 0x04300000 ... 0x043FFFFF: mi.Write<crashOnUnimplemented>(regs, addr, val); break; case 0x04300000 ... 0x043FFFFF: mi.Write(regs, addr, val); break;
case 0x04400000 ... 0x044FFFFF: vi.Write<crashOnUnimplemented>(mi, regs, addr, val); break; case 0x04400000 ... 0x044FFFFF: vi.Write(mi, regs, addr, val); break;
case 0x04500000 ... 0x045FFFFF: ai.Write<crashOnUnimplemented>(mem, regs, addr, val); break; case 0x04500000 ... 0x045FFFFF: ai.Write(mem, regs, addr, val); break;
case 0x04600000 ... 0x046FFFFF: pi.Write<crashOnUnimplemented>(mem, regs, addr, val); break; case 0x04600000 ... 0x046FFFFF: pi.Write(mem, regs, addr, val); break;
case 0x04700000 ... 0x047FFFFF: ri.Write<crashOnUnimplemented>(addr, val); break; case 0x04700000 ... 0x047FFFFF: ri.Write(addr, val); break;
case 0x04800000 ... 0x048FFFFF: si.Write<crashOnUnimplemented>(mem, regs, addr, val); break; case 0x04800000 ... 0x048FFFFF: si.Write(mem, regs, addr, val); break;
default: 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<true>(Mem&, Registers&, u32, u32);
template void MMIO::Write<false>(Mem&, Registers&, u32, u32);
} }

View File

@@ -24,9 +24,7 @@ struct MMIO {
RSP rsp; RSP rsp;
RDP rdp; RDP rdp;
template <bool crashOnUnimplemented = true>
u32 Read(u32); u32 Read(u32);
template <bool crashOnUnimplemented = true>
void Write(Mem&, Registers&, u32, u32); void Write(Mem&, Registers&, u32, u32);
}; };
} }

View File

@@ -70,7 +70,7 @@ bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr)
template bool MapVAddr<true>(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); template bool MapVAddr<true>(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr);
template bool MapVAddr<false>(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); template bool MapVAddr<false>(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr);
template <bool tlb, bool crashOnUnimplemented> template <bool tlb>
u8 Mem::Read8(n64::Registers &regs, u64 vaddr, s64 pc) { u8 Mem::Read8(n64::Registers &regs, u64 vaddr, s64 pc) {
u32 paddr = vaddr; u32 paddr = vaddr;
if(!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) { if(!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
@@ -88,7 +88,7 @@ u8 Mem::Read8(n64::Registers &regs, u64 vaddr, s64 pc) {
return mmio.rsp.dmem[BYTE_ADDRESS(paddr) & DMEM_DSIZE]; return mmio.rsp.dmem[BYTE_ADDRESS(paddr) & DMEM_DSIZE];
case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF:
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF:
return mmio.Read<crashOnUnimplemented>(paddr); return mmio.Read(paddr);
case 0x10000000 ... 0x1FBFFFFF: case 0x10000000 ... 0x1FBFFFFF:
paddr = (paddr + 2) & ~2; paddr = (paddr + 2) & ~2;
return cart[BYTE_ADDRESS(paddr) & romMask]; return cart[BYTE_ADDRESS(paddr) & romMask];
@@ -99,10 +99,7 @@ u8 Mem::Read8(n64::Registers &regs, u64 vaddr, s64 pc) {
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0; case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0;
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64)regs.pc);
util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64)regs.pc);
}
return 0;
} }
} }
@@ -201,10 +198,8 @@ u64 Mem::Read64(n64::Registers &regs, u64 vaddr, s64 pc) {
} }
} }
template u8 Mem::Read8<false, false>(n64::Registers &regs, u64 vaddr, s64 pc); template u8 Mem::Read8<false>(n64::Registers &regs, u64 vaddr, s64 pc);
template u8 Mem::Read8<false, true>(n64::Registers &regs, u64 vaddr, s64 pc); template u8 Mem::Read8<true>(n64::Registers &regs, u64 vaddr, s64 pc);
template u8 Mem::Read8<true, false>(n64::Registers &regs, u64 vaddr, s64 pc);
template u8 Mem::Read8<true, true>(n64::Registers &regs, u64 vaddr, s64 pc);
template u16 Mem::Read16<false>(n64::Registers &regs, u64 vaddr, s64 pc); template u16 Mem::Read16<false>(n64::Registers &regs, u64 vaddr, s64 pc);
template u16 Mem::Read16<true>(n64::Registers &regs, u64 vaddr, s64 pc); template u16 Mem::Read16<true>(n64::Registers &regs, u64 vaddr, s64 pc);
template u32 Mem::Read32<false>(n64::Registers &regs, u64 vaddr, s64 pc); template u32 Mem::Read32<false>(n64::Registers &regs, u64 vaddr, s64 pc);
@@ -212,7 +207,7 @@ template u32 Mem::Read32<true>(n64::Registers &regs, u64 vaddr, s64 pc);
template u64 Mem::Read64<false>(n64::Registers &regs, u64 vaddr, s64 pc); template u64 Mem::Read64<false>(n64::Registers &regs, u64 vaddr, s64 pc);
template u64 Mem::Read64<true>(n64::Registers &regs, u64 vaddr, s64 pc); template u64 Mem::Read64<true>(n64::Registers &regs, u64 vaddr, s64 pc);
template <bool tlb, bool crashOnUnimplemented> template <bool tlb>
void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) { void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) {
u32 paddr = vaddr; u32 paddr = vaddr;
if(!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) { if(!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
@@ -233,7 +228,7 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) {
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
break; break;
case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF:
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Write<crashOnUnimplemented>(*this, regs, paddr, val); break; case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Write(*this, regs, paddr, val); break;
case 0x10000000 ... 0x13FFFFFF: break; case 0x10000000 ... 0x13FFFFFF: break;
case 0x1FC007C0 ... 0x1FC007FF: case 0x1FC007C0 ... 0x1FC007FF:
val = val << (8 * (3 - (paddr & 3))); 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 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF:
case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break; case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break;
default: 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<false, false>(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write8<false>(Registers& regs, u64 vaddr, u32 val, s64 pc);
template void Mem::Write8<false, true>(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write8<true>(Registers& regs, u64 vaddr, u32 val, s64 pc);
template void Mem::Write8<true, false>(Registers& regs, u64 vaddr, u32 val, s64 pc);
template void Mem::Write8<true, true>(Registers& regs, u64 vaddr, u32 val, s64 pc);
template void Mem::Write16<false>(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write16<false>(Registers& regs, u64 vaddr, u32 val, s64 pc);
template void Mem::Write16<true>(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write16<true>(Registers& regs, u64 vaddr, u32 val, s64 pc);
template void Mem::Write32<false>(Registers& regs, u64 vaddr, u32 val, s64 pc); template void Mem::Write32<false>(Registers& regs, u64 vaddr, u32 val, s64 pc);

View File

@@ -23,7 +23,7 @@ struct Mem {
return mmio.rdp.dram.data(); return mmio.rdp.dram.data();
} }
template <bool tlb = true, bool crashOnUnimplemented = true> template <bool tlb = true>
u8 Read8(Registers&, u64, s64); u8 Read8(Registers&, u64, s64);
template <bool tlb = true> template <bool tlb = true>
u16 Read16(Registers&, u64, s64); u16 Read16(Registers&, u64, s64);
@@ -31,7 +31,7 @@ struct Mem {
u32 Read32(Registers&, u64, s64); u32 Read32(Registers&, u64, s64);
template <bool tlb = true> template <bool tlb = true>
u64 Read64(Registers&, u64, s64); u64 Read64(Registers&, u64, s64);
template <bool tlb = true, bool crashOnUnimplemented = true> template <bool tlb = true>
void Write8(Registers&, u64, u32, s64); void Write8(Registers&, u64, u32, s64);
template <bool tlb = true> template <bool tlb = true>
void Write16(Registers&, u64, u32, s64); void Write16(Registers&, u64, u32, s64);

View File

@@ -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 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
}; };
template <bool crashOnUnimplemented>
auto RDP::Read(u32 addr) const -> u32 { auto RDP::Read(u32 addr) const -> u32 {
switch(addr) { switch(addr) {
case 0x04100000: return dpc.start; case 0x04100000: return dpc.start;
@@ -36,32 +35,20 @@ auto RDP::Read(u32 addr) const -> u32 {
case 0x04100018: return dpc.status.pipeBusy; case 0x04100018: return dpc.status.pipeBusy;
case 0x0410001C: return dpc.tmem; case 0x0410001C: return dpc.tmem;
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unhandled DP Command Registers read (addr: {:08X})\n", addr);
util::panic("Unhandled DP Command Registers read (addr: {:08X})\n", addr);
}
return 0;
} }
} }
template auto RDP::Read<true>(u32 addr) const -> u32;
template auto RDP::Read<false>(u32 addr) const -> u32;
template <bool crashOnUnimplemented>
void RDP::Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val) { void RDP::Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val) {
switch(addr) { switch(addr) {
case 0x04100000: WriteStart(val); break; case 0x04100000: WriteStart(val); break;
case 0x04100004: WriteEnd(mi, regs, rsp, val); break; case 0x04100004: WriteEnd(mi, regs, rsp, val); break;
case 0x0410000C: WriteStatus(mi, regs, rsp, val); break; case 0x0410000C: WriteStatus(mi, regs, rsp, val); break;
default: 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<true>(MI&, Registers&, RSP&, u32, u32);
template void RDP::Write<false>(MI&, Registers&, RSP&, u32, u32);
void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) { void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) {
DPCStatusWrite temp{}; DPCStatusWrite temp{};
temp.raw = val; temp.raw = val;

View File

@@ -58,9 +58,7 @@ struct RDP {
void Reset(); void Reset();
std::vector<u8> dram; std::vector<u8> dram;
template <bool crashOnUnimplemented = true>
[[nodiscard]] auto Read(u32 addr) const -> u32; [[nodiscard]] auto Read(u32 addr) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val); void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val);
void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val); void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val);
void RunCommand(MI& mi, Registers& regs, RSP& rsp); void RunCommand(MI& mi, Registers& regs, RSP& rsp);

View File

@@ -73,7 +73,6 @@ void RSP::Step(Registers& regs, Mem& mem) {
//logRSP(*this, instr); //logRSP(*this, instr);
} }
template <bool crashOnUnimplemented>
auto RSP::Read(u32 addr) -> u32{ auto RSP::Read(u32 addr) -> u32{
switch (addr) { switch (addr) {
case 0x04040000: return lastSuccessfulSPAddr.raw & 0x1FF8; case 0x04040000: return lastSuccessfulSPAddr.raw & 0x1FF8;
@@ -84,23 +83,13 @@ auto RSP::Read(u32 addr) -> u32{
case 0x04040014: return spStatus.dmaFull; case 0x04040014: return spStatus.dmaFull;
case 0x04040018: return 0; case 0x04040018: return 0;
case 0x0404001C: case 0x0404001C:
if constexpr (crashOnUnimplemented) {
return semaphore;
}
return AcquireSemaphore(); return AcquireSemaphore();
case 0x04080000: return pc & 0xFFC; case 0x04080000: return pc & 0xFFC;
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unimplemented SP register read {:08X}\n", addr);
util::panic("Unimplemented SP register read {:08X}\n", addr);
}
return 0;
} }
} }
template auto RSP::Read<true>(u32 addr) -> u32;
template auto RSP::Read<false>(u32 addr) -> u32;
template <bool crashOnUnimplemented>
void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) {
MI& mi = mem.mmio.mi; MI& mi = mem.mmio.mi;
switch (addr) { switch (addr) {
@@ -121,12 +110,7 @@ void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) {
SetPC(value); SetPC(value);
} break; } break;
default: 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<true>(n64::Mem &mem, n64::Registers &regs, u32 addr, u32 value);
template void RSP::Write<false>(n64::Mem &mem, n64::Registers &regs, u32 addr, u32 value);
} }

View File

@@ -113,9 +113,7 @@ struct RSP {
RSP(); RSP();
void Reset(); void Reset();
void Step(Registers& regs, Mem& mem); void Step(Registers& regs, Mem& mem);
template <bool crashOnUnimplemented = true>
auto Read(u32 addr) -> u32; auto Read(u32 addr) -> u32;
template <bool crashOnUnimplemented = true>
void Write(Mem& mem, Registers& regs, u32 addr, u32 value); void Write(Mem& mem, Registers& regs, u32 addr, u32 value);
void Exec(Registers& regs, Mem& mem, u32 instr); void Exec(Registers& regs, Mem& mem, u32 instr);
SPStatus spStatus; SPStatus spStatus;

View File

@@ -34,7 +34,6 @@ auto AI::Read(u32 addr) const -> u32 {
#define max(x, y) ((x) > (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y))
template <bool crashOnUnimplemented>
void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
switch(addr) { switch(addr) {
case 0x04500000: case 0x04500000:
@@ -70,15 +69,10 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
dac.precision = bitrate + 1; dac.precision = bitrate + 1;
break; break;
default: 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<true>(Mem&, Registers&, u32, u32);
template void AI::Write<false>(Mem&, Registers&, u32, u32);
void AI::Step(Mem& mem, Registers& regs, int cpuCycles, float volumeL, float volumeR) { void AI::Step(Mem& mem, Registers& regs, int cpuCycles, float volumeL, float volumeR) {
cycles += cpuCycles; cycles += cpuCycles;
while(cycles > dac.period) { while(cycles > dac.period) {

View File

@@ -10,7 +10,6 @@ struct AI {
AI() = default; AI() = default;
void Reset(); void Reset();
auto Read(u32) const -> u32; auto Read(u32) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(Mem&, Registers&, u32, u32); void Write(Mem&, Registers&, u32, u32);
void Step(Mem&, Registers&, int, float, float); void Step(Mem&, Registers&, int, float, float);
bool dmaEnable{}; bool dmaEnable{};

View File

@@ -16,7 +16,6 @@ void MI::Reset() {
miMode = 0; miMode = 0;
} }
template <bool crashOnUnimplemented>
auto MI::Read(u32 paddr) const -> u32 { auto MI::Read(u32 paddr) const -> u32 {
switch(paddr & 0xF) { switch(paddr & 0xF) {
case 0x0: return miMode & 0x3FF; case 0x0: return miMode & 0x3FF;
@@ -24,17 +23,10 @@ auto MI::Read(u32 paddr) const -> u32 {
case 0x8: return miIntr.raw & 0x3F; case 0x8: return miIntr.raw & 0x3F;
case 0xC: return miIntrMask.raw & 0x3F; case 0xC: return miIntrMask.raw & 0x3F;
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unhandled MI[{:08X}] read\n", paddr);
util::panic("Unhandled MI[{:08X}] read\n", paddr);
}
return 0;
} }
} }
template auto MI::Read<true>(u32 paddr) const -> u32;
template auto MI::Read<false>(u32 paddr) const -> u32;
template <bool crashOnUnimplemented>
void MI::Write(Registers& regs, u32 paddr, u32 val) { void MI::Write(Registers& regs, u32 paddr, u32 val) {
switch(paddr & 0xF) { switch(paddr & 0xF) {
case 0x0: case 0x0:
@@ -86,12 +78,7 @@ void MI::Write(Registers& regs, u32 paddr, u32 val) {
UpdateInterrupt(*this, regs); UpdateInterrupt(*this, regs);
break; break;
default: 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<true>(Registers&, u32 paddr, u32 val);
template void MI::Write<false>(Registers&, u32 paddr, u32 val);
} }

View File

@@ -21,9 +21,7 @@ struct Registers;
struct MI { struct MI {
MI(); MI();
void Reset(); void Reset();
template <bool crashOnUnimplemented = true>
[[nodiscard]] auto Read(u32) const -> u32; [[nodiscard]] auto Read(u32) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(Registers& regs, u32, u32); void Write(Registers& regs, u32, u32);
u32 miMode; u32 miMode;

View File

@@ -17,7 +17,6 @@ void PI::Reset() {
memset(stub, 0, 8); memset(stub, 0, 8);
} }
template <bool crashOnUnimplemented>
auto PI::Read(MI& mi, u32 addr) const -> u32 { auto PI::Read(MI& mi, u32 addr) const -> u32 {
switch(addr) { switch(addr) {
case 0x04600000: return dramAddr; 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: case 0x04600024: case 0x04600028: case 0x0460002C: case 0x04600030:
return stub[(addr & 0xff) - 5]; return stub[(addr & 0xff) - 5];
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unhandled PI[{:08X}] read\n", addr);
util::panic("Unhandled PI[{:08X}] read\n", addr);
}
return 0;
} }
} }
template auto PI::Read<true>(MI&, u32) const -> u32;
template auto PI::Read<false>(MI&, u32) const -> u32;
template <bool crashOnUnimplemented>
void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
MI& mi = mem.mmio.mi; MI& mi = mem.mmio.mi;
switch(addr) { switch(addr) {
@@ -94,12 +86,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
stub[(addr & 0xff) - 5] = val & 0xff; stub[(addr & 0xff) - 5] = val & 0xff;
break; break;
default: 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<true>(n64::Mem &mem, n64::Registers &regs, u32 addr, u32 val);
template void PI::Write<false>(n64::Mem &mem, n64::Registers &regs, u32 addr, u32 val);
} }

View File

@@ -10,9 +10,7 @@ struct Registers;
struct PI { struct PI {
PI(); PI();
void Reset(); void Reset();
template <bool crashOnUnimplemented = true>
auto Read(MI&, u32) const -> u32; auto Read(MI&, u32) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(Mem&, Registers&, u32, u32); void Write(Mem&, Registers&, u32, u32);
u32 dramAddr{}, cartAddr{}; u32 dramAddr{}, cartAddr{};
u32 rdLen{}, wrLen{}; u32 rdLen{}, wrLen{};

View File

@@ -13,7 +13,6 @@ void RI::Reset() {
refresh = 0x63634; refresh = 0x63634;
} }
template <bool crashOnUnimplemented>
auto RI::Read(u32 addr) const -> u32 { auto RI::Read(u32 addr) const -> u32 {
switch(addr) { switch(addr) {
case 0x04700000: return mode; case 0x04700000: return mode;
@@ -21,17 +20,10 @@ auto RI::Read(u32 addr) const -> u32 {
case 0x0470000C: return select; case 0x0470000C: return select;
case 0x04700010: return refresh; case 0x04700010: return refresh;
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unhandled RI[{:08X}] read\n", addr);
util::panic("Unhandled RI[{:08X}] read\n", addr);
}
return 0;
} }
} }
template auto RI::Read<true>(u32 addr) const -> u32;
template auto RI::Read<false>(u32 addr) const -> u32;
template <bool crashOnUnimplemented>
void RI::Write(u32 addr, u32 val) { void RI::Write(u32 addr, u32 val) {
switch(addr) { switch(addr) {
case 0x04700000: mode = val; break; case 0x04700000: mode = val; break;
@@ -39,12 +31,7 @@ void RI::Write(u32 addr, u32 val) {
case 0x0470000C: select = val; break; case 0x0470000C: select = val; break;
case 0x04700010: refresh = val; break; case 0x04700010: refresh = val; break;
default: 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<true>(u32 addr, u32 val);
template void RI::Write<false>(u32 addr, u32 val);
} }

View File

@@ -6,9 +6,7 @@ namespace n64 {
struct RI { struct RI {
RI(); RI();
void Reset(); void Reset();
template <bool crashOnUnimplemented = true>
auto Read(u32) const -> u32; auto Read(u32) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(u32, u32); void Write(u32, u32);
u32 mode{0xE}, config{0x40}, select{0x14}, refresh{0x63634}; u32 mode{0xE}, config{0x40}, select{0x14}, refresh{0x63634};
}; };

View File

@@ -12,7 +12,6 @@ void SI::Reset() {
controller.raw = 0; controller.raw = 0;
} }
template<bool crashOnUnimplemented>
auto SI::Read(MI& mi, u32 addr) const -> u32 { auto SI::Read(MI& mi, u32 addr) const -> u32 {
switch(addr) { switch(addr) {
case 0x04800000: return dramAddr; case 0x04800000: return dramAddr;
@@ -26,17 +25,10 @@ auto SI::Read(MI& mi, u32 addr) const -> u32 {
return val; return val;
} }
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unhandled SI[{:08X}] read\n", addr);
util::panic("Unhandled SI[{:08X}] read\n", addr);
}
return 0;
} }
} }
template auto SI::Read<true>(MI &mi, u32 addr) const -> u32;
template auto SI::Read<false>(MI &mi, u32 addr) const -> u32;
template<bool crashOnUnimplemented>
void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
switch(addr) { switch(addr) {
case 0x04800000: case 0x04800000:
@@ -66,12 +58,7 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
status.intr = 0; status.intr = 0;
break; break;
default: 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<true>(Mem &mem, Registers &regs, u32 addr, u32 val);
template void SI::Write<false>(Mem &mem, Registers &regs, u32 addr, u32 val);
} }

View File

@@ -27,9 +27,7 @@ struct SI {
u32 dramAddr{}; u32 dramAddr{};
Controller controller{}; Controller controller{};
template<bool crashOnUnimplemented = true>
auto Read(MI&, u32) const -> u32; auto Read(MI&, u32) const -> u32;
template<bool crashOnUnimplemented = true>
void Write(Mem&, Registers&, u32, u32); void Write(Mem&, Registers&, u32, u32);
}; };
} }

View File

@@ -22,7 +22,6 @@ void VI::Reset() {
cyclesPerHalfline = 1000; cyclesPerHalfline = 1000;
} }
template <bool crashOnUnimplemented>
u32 VI::Read(u32 paddr) const { u32 VI::Read(u32 paddr) const {
switch(paddr) { switch(paddr) {
case 0x04400000: return status.raw; case 0x04400000: return status.raw;
@@ -40,17 +39,10 @@ u32 VI::Read(u32 paddr) const {
case 0x04400030: return xscale.raw; case 0x04400030: return xscale.raw;
case 0x04400034: return yscale.raw; case 0x04400034: return yscale.raw;
default: default:
if constexpr (crashOnUnimplemented) { util::panic("Unimplemented VI[%08X] read\n", paddr);
util::panic("Unimplemented VI[%08X] read\n", paddr);
}
return 0;
} }
} }
template u32 VI::Read<true>(u32 paddr) const;
template u32 VI::Read<false>(u32 paddr) const;
template <bool crashOnUnimplemented>
void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) { void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) {
switch(paddr) { switch(paddr) {
case 0x04400000: case 0x04400000:
@@ -89,12 +81,7 @@ void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) {
case 0x04400030: xscale.raw = val; break; case 0x04400030: xscale.raw = val; break;
case 0x04400034: yscale.raw = val; break; case 0x04400034: yscale.raw = val; break;
default: 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<true>(n64::MI &mi, n64::Registers &regs, u32 paddr, u32 val);
template void VI::Write<false>(n64::MI &mi, n64::Registers &regs, u32 paddr, u32 val);
} }

View File

@@ -88,9 +88,7 @@ struct Registers;
struct VI { struct VI {
VI(); VI();
void Reset(); void Reset();
template <bool crashOnUnimplemented = true>
[[nodiscard]] u32 Read(u32) const; [[nodiscard]] u32 Read(u32) const;
template <bool crashOnUnimplemented = true>
void Write(MI&, Registers&, u32, u32); void Write(MI&, Registers&, u32, u32);
AxisScale xscale{}, yscale{}; AxisScale xscale{}, yscale{};
VIHsyncLeap hsyncLeap{}; VIHsyncLeap hsyncLeap{};

View File

@@ -543,13 +543,13 @@ void RSP::sltiu(u32 instr) {
inline s16 signedClamp(s64 val) { inline s16 signedClamp(s64 val) {
if(val < -32768) return -32768; if(val < -32768) return -32768;
else if(val > 32767) return 32767; if(val > 32767) return 32767;
return val; return val;
} }
inline u16 unsignedClamp(s64 val) { inline u16 unsignedClamp(s64 val) {
if(val < 0) return 0; if(val < 0) return 0;
else if(val > 32767) return 65535; if(val > 32767) return 65535;
return val; return val;
} }
@@ -753,11 +753,16 @@ void RSP::vmulf(u32 instr) {
VPR vte = GetVTE(vpr[VT(instr)], e); VPR vte = GetVTE(vpr[VT(instr)], e);
for(int i = 0; i < 8; i++) { 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; vd.element[i] = result;
} }
} }
@@ -769,9 +774,13 @@ void RSP::vmulu(u32 instr) {
VPR vte = GetVTE(vpr[VT(instr)], e); VPR vte = GetVTE(vpr[VT(instr)], e);
for(int i = 0; i < 8; i++) { 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); SetACC(i, accum);
u16 result = unsignedClamp(accum >> 16); u16 result = unsignedClamp(accum >> 16);