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 <util.hpp>
#include <nfd.hpp>
#include <Core.hpp>
#include <utility>
#include <Audio.hpp>
#include <nlohmann/json.hpp>
#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) {
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();

View File

@@ -3,7 +3,6 @@
#include <imgui.h>
#include <imgui_impl_sdl.h>
#include <imgui_impl_vulkan.h>
#include <imgui_memory_editor.h>
#include <SDL.h>
#include <Core.hpp>
#include <vector>
@@ -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;
};

View File

@@ -19,46 +19,33 @@ void MMIO::Reset() {
si.Reset();
}
template <bool crashOnUnimplemented>
u32 MMIO::Read(u32 addr) {
switch (addr) {
case 0x04040000 ... 0x040FFFFF: return rsp.Read<crashOnUnimplemented>(addr);
case 0x04100000 ... 0x041FFFFF: return rdp.Read<crashOnUnimplemented>(addr);
case 0x04300000 ... 0x043FFFFF: return mi.Read<crashOnUnimplemented>(addr);
case 0x04400000 ... 0x044FFFFF: return vi.Read<crashOnUnimplemented>(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<crashOnUnimplemented>(mi, addr);
case 0x04700000 ... 0x047FFFFF: return ri.Read<crashOnUnimplemented>(addr);
case 0x04800000 ... 0x048FFFFF: return si.Read<crashOnUnimplemented>(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;
}
}
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) {
switch (addr) {
case 0x04040000 ... 0x040FFFFF: rsp.Write<crashOnUnimplemented>(mem, regs, addr, val); break;
case 0x04100000 ... 0x041FFFFF: rdp.Write<crashOnUnimplemented>(mi, regs, rsp, addr, val); break;
case 0x04300000 ... 0x043FFFFF: mi.Write<crashOnUnimplemented>(regs, addr, val); break;
case 0x04400000 ... 0x044FFFFF: vi.Write<crashOnUnimplemented>(mi, regs, addr, val); break;
case 0x04500000 ... 0x045FFFFF: ai.Write<crashOnUnimplemented>(mem, regs, addr, val); break;
case 0x04600000 ... 0x046FFFFF: pi.Write<crashOnUnimplemented>(mem, regs, addr, val); break;
case 0x04700000 ... 0x047FFFFF: ri.Write<crashOnUnimplemented>(addr, val); break;
case 0x04800000 ... 0x048FFFFF: si.Write<crashOnUnimplemented>(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);
}
}
}
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;
RDP rdp;
template <bool crashOnUnimplemented = true>
u32 Read(u32);
template <bool crashOnUnimplemented = true>
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<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) {
u32 paddr = vaddr;
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];
case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF:
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF:
return mmio.Read<crashOnUnimplemented>(paddr);
return mmio.Read(paddr);
case 0x10000000 ... 0x1FBFFFFF:
paddr = (paddr + 2) & ~2;
return cart[BYTE_ADDRESS(paddr) & romMask];
@@ -99,11 +99,8 @@ u8 Mem::Read8(n64::Registers &regs, 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;
}
}
template <bool tlb>
@@ -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, 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 u8 Mem::Read8<false>(n64::Registers &regs, u64 vaddr, s64 pc);
template u8 Mem::Read8<true>(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 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<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) {
u32 paddr = vaddr;
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);
break;
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 0x1FC007C0 ... 0x1FC007FF:
val = val << (8 * (3 - (paddr & 3)));
@@ -245,11 +240,9 @@ 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);
}
}
}
template <bool tlb>
void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 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, 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::Write8<false>(Registers& regs, u64 vaddr, u32 val, s64 pc);
template void Mem::Write8<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<true>(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();
}
template <bool tlb = true, bool crashOnUnimplemented = true>
template <bool tlb = true>
u8 Read8(Registers&, u64, s64);
template <bool tlb = true>
u16 Read16(Registers&, u64, s64);
@@ -31,7 +31,7 @@ struct Mem {
u32 Read32(Registers&, u64, s64);
template <bool tlb = true>
u64 Read64(Registers&, u64, s64);
template <bool tlb = true, bool crashOnUnimplemented = true>
template <bool tlb = true>
void Write8(Registers&, u64, u32, s64);
template <bool tlb = true>
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
};
template <bool crashOnUnimplemented>
auto RDP::Read(u32 addr) const -> u32 {
switch(addr) {
case 0x04100000: return dpc.start;
@@ -36,31 +35,19 @@ 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;
}
}
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) {
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);
}
}
}
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) {
DPCStatusWrite temp{};

View File

@@ -58,9 +58,7 @@ struct RDP {
void Reset();
std::vector<u8> dram;
template <bool crashOnUnimplemented = true>
[[nodiscard]] auto Read(u32 addr) const -> u32;
template <bool crashOnUnimplemented = true>
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);

View File

@@ -73,7 +73,6 @@ void RSP::Step(Registers& regs, Mem& mem) {
//logRSP(*this, instr);
}
template <bool crashOnUnimplemented>
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;
}
}
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) {
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);
}
}
}
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();
void Reset();
void Step(Registers& regs, Mem& mem);
template <bool crashOnUnimplemented = true>
auto Read(u32 addr) -> u32;
template <bool crashOnUnimplemented = true>
void Write(Mem& mem, Registers& regs, u32 addr, u32 value);
void Exec(Registers& regs, Mem& mem, u32 instr);
SPStatus spStatus;

View File

@@ -34,7 +34,6 @@ auto AI::Read(u32 addr) const -> u32 {
#define max(x, y) ((x) > (y) ? (x) : (y))
template <bool crashOnUnimplemented>
void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
switch(addr) {
case 0x04500000:
@@ -70,14 +69,9 @@ 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);
}
}
}
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) {
cycles += cpuCycles;

View File

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

View File

@@ -16,7 +16,6 @@ void MI::Reset() {
miMode = 0;
}
template <bool crashOnUnimplemented>
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;
}
}
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) {
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);
}
}
}
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 {
MI();
void Reset();
template <bool crashOnUnimplemented = true>
[[nodiscard]] auto Read(u32) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(Registers& regs, u32, u32);
u32 miMode;

View File

@@ -17,7 +17,6 @@ void PI::Reset() {
memset(stub, 0, 8);
}
template <bool crashOnUnimplemented>
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;
}
}
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) {
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);
}
}
}
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 {
PI();
void Reset();
template <bool crashOnUnimplemented = true>
auto Read(MI&, u32) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(Mem&, Registers&, u32, u32);
u32 dramAddr{}, cartAddr{};
u32 rdLen{}, wrLen{};

View File

@@ -13,7 +13,6 @@ void RI::Reset() {
refresh = 0x63634;
}
template <bool crashOnUnimplemented>
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;
}
}
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) {
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);
}
}
}
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 {
RI();
void Reset();
template <bool crashOnUnimplemented = true>
auto Read(u32) const -> u32;
template <bool crashOnUnimplemented = true>
void Write(u32, u32);
u32 mode{0xE}, config{0x40}, select{0x14}, refresh{0x63634};
};

View File

@@ -12,7 +12,6 @@ void SI::Reset() {
controller.raw = 0;
}
template<bool crashOnUnimplemented>
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;
}
}
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) {
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);
}
}
}
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{};
Controller controller{};
template<bool crashOnUnimplemented = true>
auto Read(MI&, u32) const -> u32;
template<bool crashOnUnimplemented = true>
void Write(Mem&, Registers&, u32, u32);
};
}

View File

@@ -22,7 +22,6 @@ void VI::Reset() {
cyclesPerHalfline = 1000;
}
template <bool crashOnUnimplemented>
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;
}
}
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) {
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);
}
}
}
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 {
VI();
void Reset();
template <bool crashOnUnimplemented = true>
[[nodiscard]] u32 Read(u32) const;
template <bool crashOnUnimplemented = true>
void Write(MI&, Registers&, u32, u32);
AxisScale xscale{}, yscale{};
VIHsyncLeap hsyncLeap{};

View File

@@ -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);