From e4c6217fd00398d2714a60baeb5df972c7cae768 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Fri, 12 Aug 2022 14:49:35 +0200 Subject: [PATCH] fix PI DMA not firing due to opy-paste error + disassembly --- .gitignore | 3 +- .gitmodules | 4 ++ external/capstone | 1 + external/parallel-rdp/CMakeLists.txt | 1 + src/common.hpp | 12 ++-- src/frontend/App.cpp | 10 ++- src/frontend/CMakeLists.txt | 1 + src/frontend/imgui/CMakeLists.txt | 1 + src/frontend/imgui/Window.cpp | 1 + src/n64/CMakeLists.txt | 3 +- src/n64/Core.cpp | 8 +-- src/n64/Core.hpp | 5 +- src/n64/core/CMakeLists.txt | 4 +- src/n64/core/Cpu.cpp | 53 +++++++++++++--- src/n64/core/Cpu.hpp | 15 ++++- src/n64/core/Mem.cpp | 2 +- src/n64/core/cpu/CMakeLists.txt | 1 + src/n64/core/cpu/instructions.cpp | 14 ++--- src/n64/core/cpu/registers/Cop0.hpp | 2 +- src/n64/core/mmio/PI.cpp | 6 +- src/n64/core/rsp/decode.cpp | 92 ++++++++++++++-------------- src/util.hpp | 11 +++- 22 files changed, 159 insertions(+), 91 deletions(-) create mode 160000 external/capstone diff --git a/.gitignore b/.gitignore index 2281c2fb..d9bda124 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ roms/ *.sh .cache/ .vscode/ -vgcore.* \ No newline at end of file +vgcore.* +*.txt \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 74c0e53d..2c486888 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,7 @@ [submodule "external/imgui/imgui"] path = external/imgui/imgui url = https://github.com/ocornut/imgui +[submodule "external/capstone"] + path = external/capstone + url = https://github.com/capstone-engine/capstone + branch = next diff --git a/external/capstone b/external/capstone new file mode 160000 index 00000000..0d0e6843 --- /dev/null +++ b/external/capstone @@ -0,0 +1 @@ +Subproject commit 0d0e684358afd0889b98deaf3941caa9c6855cae diff --git a/external/parallel-rdp/CMakeLists.txt b/external/parallel-rdp/CMakeLists.txt index 1646390c..44d08b3b 100644 --- a/external/parallel-rdp/CMakeLists.txt +++ b/external/parallel-rdp/CMakeLists.txt @@ -66,6 +66,7 @@ target_include_directories(parallel-rdp PUBLIC ../imgui ../imgui/imgui ../imgui/imgui/backends + ../capstone/include . ) diff --git a/src/common.hpp b/src/common.hpp index 0deae8f3..52edf2ad 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -17,12 +17,12 @@ using u128 = __uint128_t; using s128 = __int128_t; using m128 = __m128i; -#define UINT128_MAX ((u128)0xFFFF'FFFF'FFFF'FFFF << 64) | 0xFFFF'FFFF'FFFF'FFFF +#define UINT128_MAX (((u128)0xFFFF'FFFF'FFFF'FFFF << 64) | 0xFFFF'FFFF'FFFF'FFFF) #define UINT128_MIN 0 -#define INT128_MAX ((u128)0x7FFF'FFFF'FFFF'FFFF << 64) | 0xFFFF'FFFF'FFFF'FFFF -#define INT128_MIN (-INT128_MAX - 1LL) +#define INT128_MAX (((u128)0x7FFF'FFFF'FFFF'FFFF << 64) | 0xFFFF'FFFF'FFFF'FFFF) +#define INT128_MIN (-(INT128_MAX) - 1LL) #define KiB * 1024 -#define MiB (KiB * 1024) -#define GiB (MiB * 1024) +#define MiB ((KiB) * 1024) +#define GiB ((MiB) * 1024) #define N64_CPU_FREQ 93750000 -#define N64_CYCLES_PER_FRAME (N64_CPU_FREQ / 60) \ No newline at end of file +#define N64_CYCLES_PER_FRAME ((N64_CPU_FREQ) / 60) \ No newline at end of file diff --git a/src/frontend/App.cpp b/src/frontend/App.cpp index cc4edfd2..955d4915 100644 --- a/src/frontend/App.cpp +++ b/src/frontend/App.cpp @@ -26,13 +26,17 @@ void App::Run() { } break; } } + + core.PollInputs(event); } - if(core.initialized) + if(core.romLoaded) core.Run(); - if(core.initialized) UpdateScreenParallelRdp(window, core.GetVI()); - else UpdateScreenParallelRdpNoGame(window); + if(core.romLoaded) + UpdateScreenParallelRdp(window, core.GetVI()); + else + UpdateScreenParallelRdpNoGame(window); SDL_Delay(16); } diff --git a/src/frontend/CMakeLists.txt b/src/frontend/CMakeLists.txt index 6a5e8fe9..c31ce6c2 100644 --- a/src/frontend/CMakeLists.txt +++ b/src/frontend/CMakeLists.txt @@ -11,6 +11,7 @@ target_include_directories(frontend PUBLIC . .. ../../external + ../../external/capstone/include ../../external/parallel-rdp ../../external/parallel-rdp/parallel-rdp-standalone/vulkan ../../external/parallel-rdp/parallel-rdp-standalone/util diff --git a/src/frontend/imgui/CMakeLists.txt b/src/frontend/imgui/CMakeLists.txt index d3ab60fa..30ed6267 100644 --- a/src/frontend/imgui/CMakeLists.txt +++ b/src/frontend/imgui/CMakeLists.txt @@ -18,6 +18,7 @@ target_include_directories(frontend-imgui PUBLIC ../../n64/core/cpu ../../n64/core/cpu/registers ../../../external + ../../../external/capstone/include ../../../external/parallel-rdp/parallel-rdp-standalone ../../../external/parallel-rdp/parallel-rdp-standalone/vulkan ../../../external/parallel-rdp/parallel-rdp-standalone/util diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index 03b66870..b9da6eb6 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -8,6 +8,7 @@ Window::Window(const n64::Core& core) { InitSDL(); InitParallelRDP(core.GetRDRAM(), window); //InitImgui(); + NFD::Init(); } [[nodiscard]] bool Window::gotClosed(SDL_Event event) { diff --git a/src/n64/CMakeLists.txt b/src/n64/CMakeLists.txt index 5065b9de..1dec52be 100644 --- a/src/n64/CMakeLists.txt +++ b/src/n64/CMakeLists.txt @@ -14,4 +14,5 @@ target_include_directories(n64 PUBLIC .. ../../external ../../external/imgui/imgui - ../../external/imgui/imgui/backends) \ No newline at end of file + ../../external/imgui/imgui/backends + ../../external/capstone/include) diff --git a/src/n64/Core.cpp b/src/n64/Core.cpp index c12d8ec3..c5257cad 100644 --- a/src/n64/Core.cpp +++ b/src/n64/Core.cpp @@ -1,10 +1,9 @@ #include -#include namespace n64 { void Core::LoadROM(const std::string& rom) { mem.LoadROM(rom); - initialized = true; + romLoaded = true; } void Core::Run() { @@ -24,8 +23,7 @@ void Core::Run() { } } -void Core::PollInputs(u32 windowID) { - SDL_Event event; - SDL_PollEvent(&event); +void Core::PollInputs(SDL_Event e) { + } } diff --git a/src/n64/Core.hpp b/src/n64/Core.hpp index def143e7..f0bd0a3c 100644 --- a/src/n64/Core.hpp +++ b/src/n64/Core.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -9,10 +10,10 @@ struct Core { Core() = default; void LoadROM(const std::string&); void Run(); - void PollInputs(u32); + void PollInputs(SDL_Event); VI& GetVI() { return mem.mmio.vi; } const u8* GetRDRAM() const { return mem.rdram.data(); } - bool initialized = false; + bool romLoaded = false; private: Mem mem; Cpu cpu; diff --git a/src/n64/core/CMakeLists.txt b/src/n64/core/CMakeLists.txt index a7d96c59..f915537a 100644 --- a/src/n64/core/CMakeLists.txt +++ b/src/n64/core/CMakeLists.txt @@ -4,6 +4,7 @@ project(core) add_subdirectory(cpu) add_subdirectory(../../../external/parallel-rdp temp) +add_subdirectory(../../../external/capstone temp1) add_library(core Cpu.hpp @@ -44,6 +45,7 @@ target_include_directories(core PUBLIC ../../../external ../../../external/imgui/imgui ../../../external/imgui/imgui/backends + ../../../external/capstone/include mmio) -target_link_libraries(core PUBLIC cpu parallel-rdp) +target_link_libraries(core PUBLIC cpu parallel-rdp capstone) diff --git a/src/n64/core/Cpu.cpp b/src/n64/core/Cpu.cpp index ef73a3dc..3fb7aa73 100644 --- a/src/n64/core/Cpu.cpp +++ b/src/n64/core/Cpu.cpp @@ -4,6 +4,20 @@ #include namespace n64 { +Cpu::Cpu() { +#ifndef NDEBUG + if (cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle)) { + util::panic("Could not initialize capstone!\n"); + } +#endif +} + +Cpu::~Cpu() { +#ifndef NDEBUG + cs_close(&handle); +#endif +} + inline bool ShouldServiceInterrupt(Registers& regs) { bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; bool interrupts_enabled = regs.cop0.status.ie == 1; @@ -49,22 +63,22 @@ void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc) { regs.cop0.status.exl = true; regs.cop0.cause.copError = cop; - regs.cop0.cause.exceptionCode = static_cast(code); + regs.cop0.cause.exceptionCode = code; if(regs.cop0.status.bev) { util::panic("BEV bit set!\n"); } else { switch(code) { - case ExceptionCode::Interrupt: case ExceptionCode::TLBModification: - case ExceptionCode::AddressErrorLoad: case ExceptionCode::AddressErrorStore: - case ExceptionCode::InstructionBusError: case ExceptionCode::DataBusError: - case ExceptionCode::Syscall: case ExceptionCode::Breakpoint: - case ExceptionCode::ReservedInstruction: case ExceptionCode::CoprocessorUnusable: - case ExceptionCode::Overflow: case ExceptionCode::Trap: - case ExceptionCode::FloatingPointError: case ExceptionCode::Watch: + case Interrupt: case TLBModification: + case AddressErrorLoad: case AddressErrorStore: + case InstructionBusError: case DataBusError: + case Syscall: case Breakpoint: + case ReservedInstruction: case CoprocessorUnusable: + case Overflow: case Trap: + case FloatingPointError: case Watch: regs.SetPC((s64)((s32)0x80000180)); break; - case ExceptionCode::TLBLoad: case ExceptionCode::TLBStore: + case TLBLoad: case TLBStore: if(old_exl || regs.cop0.tlbError == INVALID) { regs.SetPC((s64)((s32)0x80000180)); } else if(Is64BitAddressing(regs.cop0, regs.cop0.badVaddr)) { @@ -73,7 +87,7 @@ void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc) { regs.SetPC((s64)((s32)0x80000000)); } break; - default: util::panic("Unhandled exception! {}\n", static_cast(code)); + default: util::panic("Unhandled exception! {}\n", code); } } } @@ -84,6 +98,24 @@ inline void HandleInterrupt(Registers& regs) { } } +void Cpu::LogInstruction(u32 instruction) { +#ifndef NDEBUG + u8 code[4]{}; + u32 bswapped = be32toh(instruction); + memcpy(code, &instruction, 4); + count = cs_disasm(handle, code, 4, regs.pc, 0, &insn); + + if (count > 0) { + for(auto j = 0; j < count; j++) { + printf("%016lX:\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + } + cs_free(insn, count); + } else { + util::panic("Failed to disassemble {:08X}!", instruction); + } +#endif +} + void Cpu::Step(Mem& mem) { regs.gpr[0] = 0; regs.prevDelaySlot = regs.delaySlot; @@ -92,6 +124,7 @@ void Cpu::Step(Mem& mem) { CheckCompareInterrupt(mem.mmio.mi, regs); u32 instruction = mem.Read(regs, regs.pc, regs.pc); + LogInstruction(instruction); HandleInterrupt(regs); diff --git a/src/n64/core/Cpu.hpp b/src/n64/core/Cpu.hpp index 1b95abd8..9c02645c 100644 --- a/src/n64/core/Cpu.hpp +++ b/src/n64/core/Cpu.hpp @@ -1,14 +1,25 @@ #pragma once #include #include +#ifndef NDEBUG +#include +#endif namespace n64 { struct Cpu { - Cpu() = default; + Cpu(); + ~Cpu(); void Step(Mem&); Registers regs; private: +#ifndef NDEBUG + csh handle{}; + cs_insn *insn = nullptr; + size_t count{}; +#endif friend struct Cop1; + + void LogInstruction(u32); void special(Mem&, u32); void regimm(u32); void Exec(Mem&, u32); @@ -99,7 +110,7 @@ private: void xori(u32); }; -enum class ExceptionCode : u8 { +enum ExceptionCode : u8 { Interrupt, TLBModification, TLBLoad, diff --git a/src/n64/core/Mem.cpp b/src/n64/core/Mem.cpp index fc499478..0f882bdb 100644 --- a/src/n64/core/Mem.cpp +++ b/src/n64/core/Mem.cpp @@ -106,7 +106,7 @@ void Mem::Write(Registers& regs, u32 vaddr, T val, s64 pc) { case 0x04000000 ... 0x04000FFF: util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; case 0x04001000 ... 0x04001FFF: util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); break; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: - case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Read(paddr); break; + case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Write(*this, regs, paddr, val); break; case 0x10000000 ... 0x1FBFFFFF: util::WriteAccess(cart.data(), paddr & romMask, val); break; case 0x1FC00000 ... 0x1FC007BF: util::WriteAccess(pifBootrom, paddr & PIF_BOOTROM_DSIZE, val); break; case 0x1FC007C0 ... 0x1FC007FF: util::WriteAccess(pifRam, paddr & PIF_RAM_DSIZE, val); break; diff --git a/src/n64/core/cpu/CMakeLists.txt b/src/n64/core/cpu/CMakeLists.txt index e8065672..d3356ab0 100644 --- a/src/n64/core/cpu/CMakeLists.txt +++ b/src/n64/core/cpu/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(cpu target_include_directories(cpu PUBLIC registers . .. ../../../../external + ../../../../external/capstone/include ../../../../src ../../ ) diff --git a/src/n64/core/cpu/instructions.cpp b/src/n64/core/cpu/instructions.cpp index 75f43da8..0c1498b9 100644 --- a/src/n64/core/cpu/instructions.cpp +++ b/src/n64/core/cpu/instructions.cpp @@ -175,28 +175,27 @@ void Cpu::lui(u32 instr) { void Cpu::lb(Mem& mem, u32 instr) { u32 address = regs.gpr[RS(instr)] + (s16)instr; - regs.gpr[RT(instr)] = s64(mem.Read(regs, address, regs.oldPC)); + regs.gpr[RT(instr)] = mem.Read(regs, address, regs.oldPC); } void Cpu::lh(Mem& mem, u32 instr) { u32 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 1) != 0) { - HandleTLBException(regs, (s64)((s32)address)); + HandleTLBException(regs, s64(s32(address))); FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); } - regs.gpr[RT(instr)] = (s64)(s16)mem.Read(regs, address, regs.oldPC); + regs.gpr[RT(instr)] = mem.Read(regs, address, regs.oldPC); } void Cpu::lw(Mem& mem, u32 instr) { u32 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 3) != 0) { - HandleTLBException(regs, (s64)((s32)address)); + HandleTLBException(regs, s64(s32(address))); FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); } - s32 value = mem.Read(regs, address, regs.oldPC); - regs.gpr[RT(instr)] = value; + regs.gpr[RT(instr)] = mem.Read(regs, address, regs.oldPC); } void Cpu::ll(Mem& mem, u32 instr) { @@ -209,8 +208,7 @@ void Cpu::ll(Mem& mem, u32 instr) { regs.LLBit = true; regs.cop0.LLAddr = address; - s32 value = mem.Read(regs, address, regs.oldPC); - regs.gpr[RT(instr)] = value; + regs.gpr[RT(instr)] = mem.Read(regs, address, regs.oldPC); } void Cpu::lwl(Mem& mem, u32 instr) { diff --git a/src/n64/core/cpu/registers/Cop0.hpp b/src/n64/core/cpu/registers/Cop0.hpp index a0a3c0d6..1652f716 100644 --- a/src/n64/core/cpu/registers/Cop0.hpp +++ b/src/n64/core/cpu/registers/Cop0.hpp @@ -191,7 +191,7 @@ private: }; struct Registers; -enum class ExceptionCode : u8; +enum ExceptionCode : u8; TLBEntry* TLBTryMatch(Registers& regs, u32 vaddr, int* match); bool ProbeTLB(Registers& regs, TLBAccessType access_type, u32 vaddr, u32& paddr, int* match); diff --git a/src/n64/core/mmio/PI.cpp b/src/n64/core/mmio/PI.cpp index cc463a72..65aa9341 100644 --- a/src/n64/core/mmio/PI.cpp +++ b/src/n64/core/mmio/PI.cpp @@ -21,7 +21,8 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 { case 0x04600014: case 0x04600018: case 0x0460001C: case 0x04600020: case 0x04600024: case 0x04600028: case 0x0460002C: case 0x04600030: return stub[(addr & 0xff) - 5]; - default: util::panic("Unhandled PI[{:08X}] read\n", addr); return 0; + default: + util::panic("Unhandled PI[{:08X}] read\n", addr); return 0; } } @@ -68,7 +69,8 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { case 0x04600024: case 0x04600028: case 0x0460002C: case 0x04600030: stub[(addr & 0xff) - 5] = val & 0xff; break; - default: util::panic("Unhandled PI[{:08X}] write ({:08X})\n", val, addr); + default: + util::panic("Unhandled PI[{:08X}] write ({:08X})\n", val, addr); } } diff --git a/src/n64/core/rsp/decode.cpp b/src/n64/core/rsp/decode.cpp index 0f4ec022..f1783f59 100644 --- a/src/n64/core/rsp/decode.cpp +++ b/src/n64/core/rsp/decode.cpp @@ -6,20 +6,20 @@ namespace n64 { inline void special(RSP& rsp, u32 instr) { u8 mask = instr & 0x3f; switch(mask) { - case 0x00: rsp.sll(instr); break; - case 0x04: rsp.sllv(instr); break; - case 0x08: rsp.jr(instr); break; - case 0x0C: - case 0x0D: - rsp.spStatus.halt = true; - rsp.spStatus.broke = true; - break; - case 0x20: case 0x21: - rsp.add(instr); - break; - case 0x24: rsp.and_(instr); break; - case 0x25: rsp.or_(instr); break; - case 0x27: rsp.nor(instr); break; + //case 0x00: rsp.sll(instr); break; + //case 0x04: rsp.sllv(instr); break; + //case 0x08: rsp.jr(instr); break; + //case 0x0C: + //case 0x0D: + // rsp.spStatus.halt = true; + // rsp.spStatus.broke = true; + // break; + //case 0x20: case 0x21: + // rsp.add(instr); + // break; + //case 0x24: rsp.and_(instr); break; + //case 0x25: rsp.or_(instr); break; + //case 0x27: rsp.nor(instr); break; default: util::panic("Unhandled RSP special instruction %d %d\n", (mask >> 3) & 7, mask & 7); } } @@ -27,8 +27,8 @@ inline void special(RSP& rsp, u32 instr) { inline void regimm(RSP& rsp, u32 instr) { u8 mask = ((instr >> 16) & 0x1F); switch(mask) { - case 0x00: rsp.b(instr, (s32)rsp.gpr[RS(instr)] < 0); break; - case 0x01: rsp.b(instr, (s32)rsp.gpr[RS(instr)] >= 0); break; + //case 0x00: rsp.b(instr, (s32)rsp.gpr[RS(instr)] < 0); break; + //case 0x01: rsp.b(instr, (s32)rsp.gpr[RS(instr)] >= 0); break; default: util::panic("Unhandled RSP regimm instruction %d %d\n", (mask >> 3) & 3, mask & 7); } } @@ -36,7 +36,7 @@ inline void regimm(RSP& rsp, u32 instr) { inline void lwc2(RSP& rsp, u32 instr) { u8 mask = (instr >> 11) & 0x1F; switch(mask) { - case 0x04: rsp.lqv(instr); break; + //case 0x04: rsp.lqv(instr); break; default: util::panic("Unhandled RSP LWC2 %d %d\n", (mask >> 3) & 3, mask & 7); } } @@ -44,7 +44,7 @@ inline void lwc2(RSP& rsp, u32 instr) { inline void swc2(RSP& rsp, u32 instr) { u8 mask = (instr >> 11) & 0x1F; switch(mask) { - case 0x04: rsp.sqv(instr); break; + //case 0x04: rsp.sqv(instr); break; default: util::panic("Unhandled RSP SWC2 %d %d\n", (mask >> 3) & 3, mask & 7); } } @@ -55,15 +55,15 @@ inline void cop2(RSP& rsp, u32 instr) { switch(mask) { case 0x00: switch(mask_sub) { - case 0x02: rsp.cfc2(instr); break; + //case 0x02: rsp.cfc2(instr); break; default: util::panic("Unhandled RSP COP2 sub %d %d\n", (mask_sub >> 3) & 3, mask_sub & 3); } break; - case 0x13: rsp.vabs(instr); break; - case 0x1D: rsp.vsar(instr); break; - case 0x21: rsp.veq(instr); break; - case 0x22: rsp.vne(instr); break; - case 0x33: rsp.vmov(instr); break; + //case 0x13: rsp.vabs(instr); break; + //case 0x1D: rsp.vsar(instr); break; + //case 0x21: rsp.veq(instr); break; + //case 0x22: rsp.vne(instr); break; + //case 0x33: rsp.vmov(instr); break; default: util::panic("Unhandled RSP COP2 %d %d\n", (mask >> 3) & 7, mask & 7); } } @@ -71,8 +71,8 @@ inline void cop2(RSP& rsp, u32 instr) { inline void cop0(MI& mi, Registers& regs, RSP& rsp, RDP& rdp, u32 instr) { u8 mask = (instr >> 21) & 0x1F; switch(mask) { - case 0x00: rsp.mfc0(rdp, instr); break; - case 0x04: rsp.mtc0(mi, regs, rdp, instr); break; + //case 0x00: rsp.mfc0(rdp, instr); break; + //case 0x04: rsp.mtc0(mi, regs, rdp, instr); break; default: util::panic("Unhandled RSP COP0 %d %d\n", (mask >> 3) & 3, mask & 7); } } @@ -80,26 +80,26 @@ inline void cop0(MI& mi, Registers& regs, RSP& rsp, RDP& rdp, u32 instr) { void RSP::Exec(MI &mi, Registers ®s, RDP &rdp, u32 instr) { u8 mask = (instr >> 26) & 0x3F; switch(mask) { - case 0x00: special(*this, instr); break; - case 0x01: regimm(*this, instr); break; - case 0x02: j(instr); break; - case 0x03: jal(instr); break; - case 0x04: b(instr, gpr[RT(instr)] == gpr[RS(instr)]); break; - case 0x05: b(instr, gpr[RT(instr)] != gpr[RS(instr)]); break; - case 0x07: b(instr, gpr[RS(instr)] > 0); break; - case 0x08: case 0x09: addi(instr); break; - case 0x0C: andi(instr); break; - case 0x0D: ori(instr); break; - case 0x0F: lui(instr); break; - case 0x10: cop0(mi, regs, *this, rdp, instr); break; - case 0x12: cop2(*this, instr); break; - case 0x21: lh(instr); break; - case 0x23: lw(instr); break; - case 0x28: sb(instr); break; - case 0x29: sh(instr); break; - case 0x2B: sw(instr); break; - case 0x32: lwc2(*this, instr); break; - case 0x3A: swc2(*this, instr); break; + //case 0x00: special(*this, instr); break; + //case 0x01: regimm(*this, instr); break; + //case 0x02: j(instr); break; + //case 0x03: jal(instr); break; + //case 0x04: b(instr, gpr[RT(instr)] == gpr[RS(instr)]); break; + //case 0x05: b(instr, gpr[RT(instr)] != gpr[RS(instr)]); break; + //case 0x07: b(instr, gpr[RS(instr)] > 0); break; + //case 0x08: case 0x09: addi(instr); break; + //case 0x0C: andi(instr); break; + //case 0x0D: ori(instr); break; + //case 0x0F: lui(instr); break; + //case 0x10: cop0(mi, regs, *this, rdp, instr); break; + //case 0x12: cop2(*this, instr); break; + //case 0x21: lh(instr); break; + //case 0x23: lw(instr); break; + //case 0x28: sb(instr); break; + //case 0x29: sh(instr); break; + //case 0x2B: sw(instr); break; + //case 0x32: lwc2(*this, instr); break; + //case 0x3A: swc2(*this, instr); break; default: util::panic("Unhandled RSP instruction %d %d\n", (mask >> 3) & 7, mask & 7); } } diff --git a/src/util.hpp b/src/util.hpp index 5427ca00..18062484 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -8,7 +8,7 @@ namespace util { enum MessageType : u8 { - Info, Warn, Error + Info, Warn, Error, Debug }; template @@ -18,7 +18,7 @@ constexpr void print(const std::string& fmt, Args... args) { exit(-1); } else if constexpr(messageType == Warn) { fmt::print(fg(fmt::color::yellow), fmt, args...); - } else if constexpr(messageType == Info) { + } else if constexpr(messageType == Info || messageType == Debug) { fmt::print(fmt, args...); } } @@ -38,6 +38,13 @@ constexpr void info(const std::string& fmt, Args... args) { print(fmt, args...); } +template +constexpr void logdebug(const std::string& fmt, Args... args) { +#ifndef NDEBUG + print(fmt, args...); +#endif +} + template auto GetSwapFunc(T num) -> T { static_assert(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "GetSwapFunc used with invalid size!");