From e2313c212ce2f9378b8ea705bc589035d4fff487 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Sat, 13 Aug 2022 11:44:35 +0200 Subject: [PATCH] Fix parallel-rdp integration and reset whole state upon loading rom --- external/parallel-rdp/ParallelRDPWrapper.cpp | 13 +++++- external/parallel-rdp/ParallelRDPWrapper.hpp | 2 - src/CMakeLists.txt | 3 ++ src/frontend/App.cpp | 42 ++++++++++---------- src/frontend/App.hpp | 1 - src/frontend/imgui/Window.cpp | 9 ++--- src/frontend/imgui/Window.hpp | 5 +-- src/main.cpp | 6 +-- src/n64/CMakeLists.txt | 1 + src/n64/Core.cpp | 19 +++++++-- src/n64/Core.hpp | 6 ++- src/n64/core/Cpu.cpp | 29 +++++++------- src/n64/core/Cpu.hpp | 5 +-- src/n64/core/MMIO.cpp | 15 +++++++ src/n64/core/MMIO.hpp | 3 +- src/n64/core/Mem.cpp | 19 ++++++--- src/n64/core/Mem.hpp | 1 + src/n64/core/RDP.cpp | 9 +++++ src/n64/core/RDP.hpp | 5 ++- src/n64/core/RSP.cpp | 25 ++++++++++++ src/n64/core/RSP.hpp | 5 ++- src/n64/core/cpu/Registers.cpp | 6 +++ src/n64/core/cpu/Registers.hpp | 1 + src/n64/core/cpu/instructions.cpp | 2 +- src/n64/core/cpu/registers/Cop0.cpp | 6 ++- src/n64/core/cpu/registers/Cop0.hpp | 2 + src/n64/core/cpu/registers/Cop1.cpp | 10 +++++ src/n64/core/cpu/registers/Cop1.hpp | 8 ++-- src/n64/core/mmio/AI.cpp | 12 ++++++ src/n64/core/mmio/AI.hpp | 1 + src/n64/core/mmio/MI.cpp | 4 ++ src/n64/core/mmio/MI.hpp | 1 + src/n64/core/mmio/PI.cpp | 13 ++++++ src/n64/core/mmio/PI.hpp | 3 +- src/n64/core/mmio/RI.cpp | 11 +++++ src/n64/core/mmio/RI.hpp | 3 +- src/n64/core/mmio/SI.cpp | 9 +++++ src/n64/core/mmio/SI.hpp | 3 +- src/n64/core/mmio/VI.cpp | 18 ++++----- src/n64/core/mmio/VI.hpp | 2 +- src/util.hpp | 4 +- 41 files changed, 250 insertions(+), 92 deletions(-) diff --git a/external/parallel-rdp/ParallelRDPWrapper.cpp b/external/parallel-rdp/ParallelRDPWrapper.cpp index e41119cf..2fbe3bdf 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.cpp +++ b/external/parallel-rdp/ParallelRDPWrapper.cpp @@ -92,11 +92,11 @@ public: } uint32_t get_surface_width() override { - return 800; + return 640; } uint32_t get_surface_height() override { - return 600; + return 480; } bool alive(Vulkan::WSI &wsi_) override { @@ -106,6 +106,15 @@ public: void poll_input() override { } void event_frame_tick(double frame, double elapsed) override { } + + const VkApplicationInfo *get_application_info() override { + return &appInfo; + } + + VkApplicationInfo appInfo { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .apiVersion = VK_API_VERSION_1_1 + }; }; Program* fullscreen_quad_program; diff --git a/external/parallel-rdp/ParallelRDPWrapper.hpp b/external/parallel-rdp/ParallelRDPWrapper.hpp index c2f888c7..24cca27a 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.hpp +++ b/external/parallel-rdp/ParallelRDPWrapper.hpp @@ -1,5 +1,4 @@ #pragma once -#define VULKAN_DEBUG #include #include #include @@ -26,7 +25,6 @@ class SDLParallelRdpWindowInfo : public ParallelRdpWindowInfo { } }; -static u32 windowID; VkQueue GetGraphicsQueue(); VkInstance GetVkInstance(); VkPhysicalDevice GetVkPhysicalDevice(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2b784f86..6c4fad0b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,8 @@ project(natsukashii) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED true) +add_compile_definitions(VULKAN_DEBUG) + add_subdirectory(n64) add_subdirectory(frontend) @@ -12,3 +14,4 @@ add_executable(natsukashii main.cpp) target_link_libraries(natsukashii PUBLIC frontend n64 fmt) target_include_directories(natsukashii PUBLIC . ../external) +target_compile_options(natsukashii PUBLIC -Wpedantic -Wimplicit-fallthrough -Wextra -Wall) diff --git a/src/frontend/App.cpp b/src/frontend/App.cpp index 955d4915..bcbede89 100644 --- a/src/frontend/App.cpp +++ b/src/frontend/App.cpp @@ -9,35 +9,35 @@ void App::Run() { SDL_Event event; while (SDL_PollEvent(&event)) { //ImGui_ImplSDL2_ProcessEvent(&event); - if (event.type == SDL_QUIT) - done = true; - if (window.gotClosed(event)) - done = true; - if(event.type == SDL_KEYDOWN) { - switch(event.key.keysym.sym) { - case SDLK_o: { - nfdchar_t* outpath; - const nfdu8filteritem_t filter {"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"}; - nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr); - if(result == NFD_OKAY) { - core.LoadROM(outpath); - NFD_FreePath(outpath); - } + switch(event.type) { + case SDL_QUIT: done = true; break; + case SDL_WINDOWEVENT: + done = window.gotClosed(event); + break; + case SDL_KEYDOWN: + switch(event.key.keysym.sym) { + case SDLK_o: { + nfdchar_t* outpath; + const nfdu8filteritem_t filter {"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"}; + nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr); + if(result == NFD_OKAY) { + core.LoadROM(outpath); + NFD_FreePath(outpath); + } + } break; } break; - } } core.PollInputs(event); } - if(core.romLoaded) - core.Run(); - - if(core.romLoaded) + if(core.romLoaded) { + core.Run(window); UpdateScreenParallelRdp(window, core.GetVI()); - else + } else { UpdateScreenParallelRdpNoGame(window); + } - SDL_Delay(16); + SDL_Delay(1); } } diff --git a/src/frontend/App.hpp b/src/frontend/App.hpp index 15b24dfd..6e134ddc 100644 --- a/src/frontend/App.hpp +++ b/src/frontend/App.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include struct App { diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index a291df1e..e2c921dc 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -12,8 +12,7 @@ Window::Window(n64::Core& core) { } [[nodiscard]] bool Window::gotClosed(SDL_Event event) { - return event.type == SDL_WINDOWEVENT - && event.window.event == SDL_WINDOWEVENT_CLOSE + return event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window); } @@ -177,18 +176,18 @@ Window::~Window() { vkDestroyInstance(instance, nullptr); } -ImDrawData* Window::Present() { +ImDrawData* Window::Present(n64::Core& core) { //ImGui_ImplVulkan_NewFrame(); //ImGui_ImplSDL2_NewFrame(window); //ImGui::NewFrame(); // - Render(); + Render(core); //ImGui::Render(); return ImGui::GetDrawData(); } -void Window::Render() { +void Window::Render(n64::Core& core) { ImGui::BeginMainMenuBar(); if(ImGui::BeginMenu("File")) { if(ImGui::BeginMenu("Open")) { diff --git a/src/frontend/imgui/Window.hpp b/src/frontend/imgui/Window.hpp index e1344253..fff49984 100644 --- a/src/frontend/imgui/Window.hpp +++ b/src/frontend/imgui/Window.hpp @@ -10,15 +10,14 @@ struct Window { explicit Window(n64::Core& core); ~Window(); - ImDrawData* Present(); + ImDrawData* Present(n64::Core& core); [[nodiscard]] bool gotClosed(SDL_Event event); private: SDL_Window* window; - n64::Core core; void InitSDL(); void InitImgui(); - void Render(); + void Render(n64::Core& core); VkInstance instance{}; VkPhysicalDevice physicalDevice{}; diff --git a/src/main.cpp b/src/main.cpp index 2a4604a3..22d3dcea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,8 @@ #define SDL_MAIN_HANDLED #include -int main() { - App* app = new App; - app->Run(); +int main(int argc, char* argv[]) { + App app; + app.Run(); return 0; } \ No newline at end of file diff --git a/src/n64/CMakeLists.txt b/src/n64/CMakeLists.txt index 1dec52be..7af6c102 100644 --- a/src/n64/CMakeLists.txt +++ b/src/n64/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(n64 PUBLIC core) target_include_directories(n64 PUBLIC . .. + ../frontend/imgui ../../external ../../external/imgui/imgui ../../external/imgui/imgui/backends diff --git a/src/n64/Core.cpp b/src/n64/Core.cpp index c5257cad..e8eb8334 100644 --- a/src/n64/Core.cpp +++ b/src/n64/Core.cpp @@ -1,15 +1,28 @@ #include +#include +#include namespace n64 { +Core::Core() { + Reset(); +} + +void Core::Reset() { + cpu.Reset(); + mem.Reset(); + romLoaded = false; +} + void Core::LoadROM(const std::string& rom) { + Reset(); mem.LoadROM(rom); romLoaded = true; } -void Core::Run() { +void Core::Run(Window& window) { MMIO& mmio = mem.mmio; for(mmio.vi.current = 0; mmio.vi.current < 262; mmio.vi.current++) { - for(int i = 0; i < 6000; i++) { + for (int i = 0; i < 6000; i++) { cpu.Step(mem); mmio.rsp.Step(mmio.mi, cpu.regs, mmio.rdp); mmio.rsp.Step(mmio.mi, cpu.regs, mmio.rdp); @@ -17,7 +30,7 @@ void Core::Run() { mmio.rsp.Step(mmio.mi, cpu.regs, mmio.rdp); } - if((mmio.vi.current & 0x3FE) == mmio.vi.intr) { + if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) { InterruptRaise(mmio.mi, cpu.regs, Interrupt::VI); } } diff --git a/src/n64/Core.hpp b/src/n64/Core.hpp index a818d1b9..9a1db540 100644 --- a/src/n64/Core.hpp +++ b/src/n64/Core.hpp @@ -4,12 +4,14 @@ #include #include +struct Window; namespace n64 { struct Core { ~Core() = default; - Core() = default; + Core(); + void Reset(); void LoadROM(const std::string&); - void Run(); + void Run(Window&); void PollInputs(SDL_Event); VI& GetVI() { return mem.mmio.vi; } u8* GetRDRAM() { return mem.rdram.data(); } diff --git a/src/n64/core/Cpu.cpp b/src/n64/core/Cpu.cpp index c21d91b2..cf58b720 100644 --- a/src/n64/core/Cpu.cpp +++ b/src/n64/core/Cpu.cpp @@ -4,18 +4,18 @@ #include namespace n64 { +void Cpu::Reset() { + regs.Reset(); +} + 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) { @@ -99,21 +99,16 @@ 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); + count = cs_disasm(handle, reinterpret_cast(&instruction), 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); + util::logdebug("0x{:016X}:\t{}\t\t{}\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); } cs_free(insn, count); } else { - util::panic("Failed to disassemble {:08X}!", instruction); - }*/ -#endif + util::logdebug("Failed to disassemble 0x{:08X}!", instruction); + } } void Cpu::Step(Mem& mem) { @@ -123,8 +118,14 @@ void Cpu::Step(Mem& mem) { CheckCompareInterrupt(mem.mmio.mi, regs); + static int count = 0; + if(regs.gpr[30] == -1 && count < 1) { + util::logdebug("Test passed!\n"); + count++; + } + u32 instruction = mem.Read(regs, regs.pc, regs.pc); - LogInstruction(instruction); + //LogInstruction(instruction); HandleInterrupt(regs); diff --git a/src/n64/core/Cpu.hpp b/src/n64/core/Cpu.hpp index 9c02645c..bef8bcac 100644 --- a/src/n64/core/Cpu.hpp +++ b/src/n64/core/Cpu.hpp @@ -1,22 +1,19 @@ #pragma once #include #include -#ifndef NDEBUG #include -#endif namespace n64 { struct Cpu { Cpu(); ~Cpu(); + void Reset(); void Step(Mem&); Registers regs; private: -#ifndef NDEBUG csh handle{}; cs_insn *insn = nullptr; size_t count{}; -#endif friend struct Cop1; void LogInstruction(u32); diff --git a/src/n64/core/MMIO.cpp b/src/n64/core/MMIO.cpp index ee882de6..9decf402 100644 --- a/src/n64/core/MMIO.cpp +++ b/src/n64/core/MMIO.cpp @@ -4,6 +4,21 @@ #include namespace n64 { +MMIO::MMIO () { + Reset(); +} + +void MMIO::Reset() { + rsp.Reset(); + rdp.Reset(); + mi.Reset(); + vi.Reset(); + ai.Reset(); + pi.Reset(); + ri.Reset(); + si.Reset(); +} + u32 MMIO::Read(u32 addr) { switch (addr) { case 0x04040000 ... 0x040FFFFF: return rsp.Read(addr); diff --git a/src/n64/core/MMIO.hpp b/src/n64/core/MMIO.hpp index 55789ff3..fa63cffc 100644 --- a/src/n64/core/MMIO.hpp +++ b/src/n64/core/MMIO.hpp @@ -13,7 +13,8 @@ struct Mem; struct Registers; struct MMIO { - MMIO() = default; + MMIO(); + void Reset(); VI vi; MI mi; AI ai; diff --git a/src/n64/core/Mem.cpp b/src/n64/core/Mem.cpp index 0f882bdb..c268c03e 100644 --- a/src/n64/core/Mem.cpp +++ b/src/n64/core/Mem.cpp @@ -7,8 +7,16 @@ namespace n64 { Mem::Mem() { + Reset(); +} + +void Mem::Reset() { rdram.resize(RDRAM_SIZE); sram.resize(SRAM_SIZE); + std::fill(rdram.begin(), rdram.end(), 0); + std::fill(sram.begin(), sram.end(), 0); + romMask = 0; + mmio.Reset(); } void Mem::LoadROM(const std::string& filename) { @@ -21,12 +29,13 @@ void Mem::LoadROM(const std::string& filename) { file.seekg(0, std::ios::end); auto size = file.tellg(); - auto size_adjusted = util::NextPow2(size); - romMask = size_adjusted - 1; + auto sizeAdjusted = util::NextPow2(size); + romMask = sizeAdjusted - 1; file.seekg(0, std::ios::beg); - cart.resize(size_adjusted); - file.read(reinterpret_cast(cart.data()), size); + std::fill(cart.begin(), cart.end(), 0); + cart.resize(sizeAdjusted); + cart.insert(cart.begin(), std::istream_iterator(file), std::istream_iterator()); file.close(); util::SwapN64Rom(size, cart.data()); @@ -107,8 +116,6 @@ void Mem::Write(Registers& regs, u32 vaddr, T val, s64 pc) { 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.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; case 0x00800000 ... 0x03FFFFFF: case 0x04002000 ... 0x0403FFFF: case 0x04200000 ... 0x042FFFFF: diff --git a/src/n64/core/Mem.hpp b/src/n64/core/Mem.hpp index 8c511eb7..839d96ec 100644 --- a/src/n64/core/Mem.hpp +++ b/src/n64/core/Mem.hpp @@ -9,6 +9,7 @@ struct Registers; struct Mem { ~Mem() = default; Mem(); + void Reset(); void LoadROM(const std::string&); [[nodiscard]] auto GetRDRAM() -> u8* { return rdram.data(); diff --git a/src/n64/core/RDP.cpp b/src/n64/core/RDP.cpp index cb8cd039..a847f5bc 100644 --- a/src/n64/core/RDP.cpp +++ b/src/n64/core/RDP.cpp @@ -5,6 +5,15 @@ #include namespace n64 { +RDP::RDP() { + Reset(); +} + +void RDP::Reset() { + dpc.status.raw = 0x80; + memset(cmd_buf, 0, 0x100000); +} + static const int cmd_lens[64] = { 2, 2, 2, 2, 2, 2, 2, 2, 8, 12, 24, 28, 24, 28, 40, 44, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, diff --git a/src/n64/core/RDP.hpp b/src/n64/core/RDP.hpp index 8ea9f197..c57f608c 100644 --- a/src/n64/core/RDP.hpp +++ b/src/n64/core/RDP.hpp @@ -48,10 +48,11 @@ struct DPC { }; struct RDP { - DPC dpc{.status{.raw = 0x80}}; + DPC dpc; u32 cmd_buf[0xFFFFF]{}; - RDP() = default; + RDP(); + void Reset(); auto Read(u32 addr) const -> u32; void Write(u32 addr, u32 val); diff --git a/src/n64/core/RSP.cpp b/src/n64/core/RSP.cpp index 2938f3a4..dda193d6 100644 --- a/src/n64/core/RSP.cpp +++ b/src/n64/core/RSP.cpp @@ -4,6 +4,31 @@ #include namespace n64 { +RSP::RSP() { + Reset(); +} + +void RSP::Reset() { + spStatus.raw = 0; + spStatus.halt = true; + oldPC = 0; + pc = 0; + nextPC = 0; + spDMASPAddr.raw = 0; + spDMADRAMAddr.raw = 0; + spDMARDLen.raw = 0; + spDMAWRLen.raw = 0; + memset(dmem, 0, DMEM_SIZE); + memset(imem, 0, IMEM_SIZE); + memset(vpr, 0, 32 * sizeof(VPR)); + memset(gpr, 0, 32); + vce = 0; + acc = {.h={}, .m={}, .l={}}; + vcc = {.l = {}, .h = {}}; + vco = {.l = {}, .h = {}}; + semaphore = false; +} + void RSP::Step(MI& mi, Registers& regs, RDP& rdp) { if(!spStatus.halt) { gpr[0] = 0; diff --git a/src/n64/core/RSP.hpp b/src/n64/core/RSP.hpp index 9b1bf7e4..e7645ead 100644 --- a/src/n64/core/RSP.hpp +++ b/src/n64/core/RSP.hpp @@ -105,12 +105,13 @@ struct Registers; } while(0) struct RSP { - RSP() = default; + RSP(); + void Reset(); void Step(MI& mi, Registers& regs, RDP& rdp); auto Read(u32 addr) const -> u32; void Write(Mem& mem, Registers& regs, u32 addr, u32 value); void Exec(MI& mi, Registers& regs, RDP& rdp, u32 instr); - SPStatus spStatus{.raw = 1}; + SPStatus spStatus; u16 oldPC{}, pc{}, nextPC = 4; SPDMASPAddr spDMASPAddr{}; SPDMADRAMAddr spDMADRAMAddr{}; diff --git a/src/n64/core/cpu/Registers.cpp b/src/n64/core/cpu/Registers.cpp index a2b85d3a..f880c7f8 100644 --- a/src/n64/core/cpu/Registers.cpp +++ b/src/n64/core/cpu/Registers.cpp @@ -2,6 +2,10 @@ namespace n64 { Registers::Registers() { + Reset(); +} + +void Registers::Reset() { delaySlot = false; prevDelaySlot = false; memset(gpr, 0, 32*sizeof(s64)); @@ -14,6 +18,8 @@ Registers::Registers() { gpr[20] = 0x0000000000000001; gpr[22] = 0x000000000000003F; gpr[29] = (s64)0xFFFFFFFFA4001FF0; + cop0.Reset(); + cop1.Reset(); } void Registers::SetPC(s64 val) { diff --git a/src/n64/core/cpu/Registers.hpp b/src/n64/core/cpu/Registers.hpp index dccb5b31..ffab217c 100644 --- a/src/n64/core/cpu/Registers.hpp +++ b/src/n64/core/cpu/Registers.hpp @@ -5,6 +5,7 @@ namespace n64 { struct Registers { Registers(); + void Reset(); void SetPC(s64); s64 gpr[32]; Cop0 cop0; diff --git a/src/n64/core/cpu/instructions.cpp b/src/n64/core/cpu/instructions.cpp index 0c1498b9..81d8b25b 100644 --- a/src/n64/core/cpu/instructions.cpp +++ b/src/n64/core/cpu/instructions.cpp @@ -169,7 +169,7 @@ void Cpu::bllink(u32 instr, bool cond) { void Cpu::lui(u32 instr) { s64 val = (s16)instr; - val *= 65536; + val <<= 16; regs.gpr[RT(instr)] = val; } diff --git a/src/n64/core/cpu/registers/Cop0.cpp b/src/n64/core/cpu/registers/Cop0.cpp index dd9290ae..52d0df2f 100644 --- a/src/n64/core/cpu/registers/Cop0.cpp +++ b/src/n64/core/cpu/registers/Cop0.cpp @@ -5,12 +5,16 @@ namespace n64 { Cop0::Cop0() { + Reset(); +} + +void Cop0::Reset() { cause.raw = 0xB000007C; random = 0x0000001F; status.raw = 0x241000E0; wired = 64; index = 64; - PRId = 0x00000B00; + PRId = 0x00000B22; Config = 0x7006E463; EPC = 0xFFFFFFFFFFFFFFFF; ErrorEPC = 0xFFFFFFFFFFFFFFFF; diff --git a/src/n64/core/cpu/registers/Cop0.hpp b/src/n64/core/cpu/registers/Cop0.hpp index 1652f716..f2044802 100644 --- a/src/n64/core/cpu/registers/Cop0.hpp +++ b/src/n64/core/cpu/registers/Cop0.hpp @@ -159,6 +159,8 @@ struct Cop0 { template void SetReg(u8, T); + void Reset(); + PageMask pageMask{}; EntryHi entryHi{}; EntryLo entryLo0{}, entryLo1{}; diff --git a/src/n64/core/cpu/registers/Cop1.cpp b/src/n64/core/cpu/registers/Cop1.cpp index 603e8bc2..05c8b77d 100644 --- a/src/n64/core/cpu/registers/Cop1.cpp +++ b/src/n64/core/cpu/registers/Cop1.cpp @@ -4,6 +4,16 @@ #include namespace n64 { +Cop1::Cop1() { + Reset(); +} + +void Cop1::Reset() { + fcr0 = 0xa00; + fcr31.raw = 0; + memset(fgr, 0, 32 * sizeof(FGR)); +} + void Cop1::decode(Cpu& cpu, u32 instr) { Registers& regs = cpu.regs; if(!regs.cop0.status.cu1) { diff --git a/src/n64/core/cpu/registers/Cop1.hpp b/src/n64/core/cpu/registers/Cop1.hpp index 31785c54..74c085ef 100644 --- a/src/n64/core/cpu/registers/Cop1.hpp +++ b/src/n64/core/cpu/registers/Cop1.hpp @@ -50,9 +50,11 @@ struct Cpu; struct Registers; struct Cop1 { - u32 fcr0; - FCR31 fcr31; - FGR fgr[32]; + Cop1(); + u32 fcr0{}; + FCR31 fcr31{}; + FGR fgr[32]{}; + void Reset(); void decode(Cpu&, u32); friend struct Cpu; private: diff --git a/src/n64/core/mmio/AI.cpp b/src/n64/core/mmio/AI.cpp index 7059bfe5..695d1b00 100644 --- a/src/n64/core/mmio/AI.cpp +++ b/src/n64/core/mmio/AI.cpp @@ -5,6 +5,18 @@ #include namespace n64 { +void AI::Reset() { + dmaEnable = 0; + dacRate = 0; + bitrate = 0; + dmaCount = 0; + memset(dmaLen, 0, 2); + memset(dmaAddr, 0, 2); + dmaAddrCarry = false; + cycles = 0; + dac = {44100, N64_CPU_FREQ / dac.freq, 16}; +} + auto AI::Read(u32 addr) const -> u32 { switch(addr) { case 0x04500004: return dmaLen[0]; diff --git a/src/n64/core/mmio/AI.hpp b/src/n64/core/mmio/AI.hpp index e6c05e6a..88389cba 100644 --- a/src/n64/core/mmio/AI.hpp +++ b/src/n64/core/mmio/AI.hpp @@ -8,6 +8,7 @@ struct Registers; struct AI { AI() = default; + void Reset(); auto Read(u32) const -> u32; void Write(Mem&, Registers&, u32, u32); void Step(Mem&, Registers&, int); diff --git a/src/n64/core/mmio/MI.cpp b/src/n64/core/mmio/MI.cpp index 79162b3c..8eb85ac1 100644 --- a/src/n64/core/mmio/MI.cpp +++ b/src/n64/core/mmio/MI.cpp @@ -7,6 +7,10 @@ namespace n64 { MI::MI() { + Reset(); +} + +void MI::Reset() { miIntrMask.raw = 0; miIntr.raw = 0; miMode = 0; diff --git a/src/n64/core/mmio/MI.hpp b/src/n64/core/mmio/MI.hpp index d2d5c70d..c8b5b04a 100644 --- a/src/n64/core/mmio/MI.hpp +++ b/src/n64/core/mmio/MI.hpp @@ -20,6 +20,7 @@ struct Registers; struct MI { MI(); + void Reset(); [[nodiscard]] auto Read(u32) const -> u32; void Write(Registers& regs, u32, u32); diff --git a/src/n64/core/mmio/PI.cpp b/src/n64/core/mmio/PI.cpp index 65aa9341..6d437b02 100644 --- a/src/n64/core/mmio/PI.cpp +++ b/src/n64/core/mmio/PI.cpp @@ -4,6 +4,19 @@ #include namespace n64 { +PI::PI() { + Reset(); +} + +void PI::Reset() { + dramAddr = 0; + cartAddr = 0; + rdLen = 0; + wrLen = 0; + status = 0; + memset(stub, 0, 8); +} + auto PI::Read(MI& mi, u32 addr) const -> u32 { switch(addr) { case 0x04600000: return dramAddr; diff --git a/src/n64/core/mmio/PI.hpp b/src/n64/core/mmio/PI.hpp index a6114d0f..49ac8617 100644 --- a/src/n64/core/mmio/PI.hpp +++ b/src/n64/core/mmio/PI.hpp @@ -8,7 +8,8 @@ struct Mem; struct Registers; struct PI { - PI() = default; + PI(); + void Reset(); auto Read(MI&, u32) const -> u32; void Write(Mem&, Registers&, u32, u32); u32 dramAddr{}, cartAddr{}; diff --git a/src/n64/core/mmio/RI.cpp b/src/n64/core/mmio/RI.cpp index 214b7f5a..0c693cd3 100644 --- a/src/n64/core/mmio/RI.cpp +++ b/src/n64/core/mmio/RI.cpp @@ -2,6 +2,17 @@ #include namespace n64 { +RI::RI() { + Reset(); +} + +void RI::Reset() { + mode = 0xE; + config = 0x40; + select = 0x14; + refresh = 0x63634; +} + auto RI::Read(u32 addr) const -> u32 { switch(addr) { case 0x04700000: return mode; diff --git a/src/n64/core/mmio/RI.hpp b/src/n64/core/mmio/RI.hpp index 19f20791..31c0ee64 100644 --- a/src/n64/core/mmio/RI.hpp +++ b/src/n64/core/mmio/RI.hpp @@ -4,7 +4,8 @@ namespace n64 { struct RI { - RI() = default; + RI(); + void Reset(); u32 mode{0xE}, config{0x40}, select{0x14}, refresh{0x63634}; auto Read(u32) const -> u32; void Write(u32, u32); diff --git a/src/n64/core/mmio/SI.cpp b/src/n64/core/mmio/SI.cpp index 3c22521c..a33dec8a 100644 --- a/src/n64/core/mmio/SI.cpp +++ b/src/n64/core/mmio/SI.cpp @@ -3,6 +3,15 @@ #include namespace n64 { +SI::SI() { + Reset(); +} + +void SI::Reset() { + status.raw = 0; + dramAddr = 0; + controller.raw = 0; +} auto SI::Read(MI& mi, u32 addr) const -> u32 { switch(addr) { diff --git a/src/n64/core/mmio/SI.hpp b/src/n64/core/mmio/SI.hpp index 3fb8c8d3..1f05236e 100644 --- a/src/n64/core/mmio/SI.hpp +++ b/src/n64/core/mmio/SI.hpp @@ -21,7 +21,8 @@ union SIStatus { struct Mem; struct SI { - SI() = default; + SI(); + void Reset(); SIStatus status{}; u32 dramAddr{}; Controller controller{}; diff --git a/src/n64/core/mmio/VI.cpp b/src/n64/core/mmio/VI.cpp index 5202629f..724a1a7f 100644 --- a/src/n64/core/mmio/VI.cpp +++ b/src/n64/core/mmio/VI.cpp @@ -6,13 +6,11 @@ namespace n64 { VI::VI () { - status.raw = 0xF; + Reset(); +} + +void VI::Reset() { intr = 256; - origin = 0; - width = 320; - current = 0; - vsync = 0; - hsync = 0; numHalflines = 262; numFields = 1; cyclesPerHalfline = 1000; @@ -29,8 +27,8 @@ u32 VI::Read(u32 paddr) const { case 0x04400018: return vsync; case 0x0440001C: return hsync; case 0x04400020: return hsyncLeap.raw; - case 0x04400024: return hvideo.raw; - case 0x04400028: return vvideo.raw; + case 0x04400024: return hstart.raw; + case 0x04400028: return vstart.raw; case 0x0440002C: return vburst; case 0x04400030: return xscale.raw; case 0x04400034: return yscale.raw; @@ -72,8 +70,8 @@ void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) { hsync = val & 0x3FF; } break; case 0x04400020: hsyncLeap.raw = val; break; - case 0x04400024: hvideo.raw = val; break; - case 0x04400028: vvideo.raw = val; break; + case 0x04400024: hstart.raw = val; break; + case 0x04400028: vstart.raw = val; break; case 0x0440002C: vburst = val; break; case 0x04400030: xscale.raw = val; break; case 0x04400034: yscale.raw = val; break; diff --git a/src/n64/core/mmio/VI.hpp b/src/n64/core/mmio/VI.hpp index 820637d3..caf7fef3 100644 --- a/src/n64/core/mmio/VI.hpp +++ b/src/n64/core/mmio/VI.hpp @@ -87,10 +87,10 @@ struct Registers; struct VI { VI(); + void Reset(); [[nodiscard]] u32 Read(u32) const; void Write(MI&, Registers&, u32, u32); AxisScale xscale{}, yscale{}; - VIVideo hvideo{}, vvideo{}; VIHsyncLeap hsyncLeap{}; VIStatus status{}; VIBurst burst{}; diff --git a/src/util.hpp b/src/util.hpp index 18062484..b44ff268 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -8,7 +8,7 @@ namespace util { enum MessageType : u8 { - Info, Warn, Error, Debug + Info, Warn, Error }; 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 || messageType == Debug) { + } else if constexpr(messageType == Info) { fmt::print(fmt, args...); } }