From 698032f0a12e437c0e4c5bb57fddff7507c54c5c Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Mon, 24 Jul 2023 16:06:33 +0200 Subject: [PATCH] Lay down BaseCPU structure --- src/backend/Core.cpp | 32 ++++++++++++++++---------------- src/backend/Core.hpp | 4 ++-- src/backend/core/BaseCPU.hpp | 13 +++++++++++++ src/backend/core/Interpreter.hpp | 9 +++++---- src/frontend/App.cpp | 2 +- src/frontend/imgui/Settings.cpp | 21 +++++++++++++++++---- src/frontend/imgui/Settings.hpp | 3 ++- src/frontend/imgui/Window.cpp | 16 ++++++++-------- 8 files changed, 64 insertions(+), 36 deletions(-) create mode 100644 src/backend/core/BaseCPU.hpp diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 2a44ebb5..2f0ccab1 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -9,15 +9,15 @@ Core::Core() { } void Core::Stop() { - cpu.Reset(); - cpu.mem.Reset(); + cpu->Reset(); + cpu->mem.Reset(); pause = true; romLoaded = false; } void Core::LoadROM(const std::string& rom_) { rom = rom_; - cpu.Reset(); + cpu->Reset(); pause = false; romLoaded = true; @@ -30,21 +30,21 @@ void Core::LoadROM(const std::string& rom_) { } } - cpu.mem.LoadROM(isArchive, rom); - GameDB::match(cpu.mem); - cpu.mem.mmio.vi.isPal = cpu.mem.IsROMPAL(); - cpu.mem.mmio.si.pif.InitDevices(cpu.mem.saveType); - cpu.mem.mmio.si.pif.LoadMempak(rom); - cpu.mem.mmio.si.pif.LoadEeprom(cpu.mem.saveType, rom); - cpu.mem.flash.Load(cpu.mem.saveType, rom); - cpu.mem.LoadSRAM(cpu.mem.saveType, rom); - PIF::ExecutePIF(cpu.mem, cpu.regs); + cpu->mem.LoadROM(isArchive, rom); + GameDB::match(cpu->mem); + cpu->mem.mmio.vi.isPal = cpu->mem.IsROMPAL(); + cpu->mem.mmio.si.pif.InitDevices(cpu->mem.saveType); + cpu->mem.mmio.si.pif.LoadMempak(rom); + cpu->mem.mmio.si.pif.LoadEeprom(cpu->mem.saveType, rom); + cpu->mem.flash.Load(cpu->mem.saveType, rom); + cpu->mem.LoadSRAM(cpu->mem.saveType, rom); + PIF::ExecutePIF(cpu->mem, cpu->regs); } void Core::Run(float volumeL, float volumeR) { - Mem& mem = cpu.mem; + Mem& mem = cpu->mem; MMIO& mmio = mem.mmio; - Registers& regs = cpu.regs; + Registers& regs = cpu->regs; for (int field = 0; field < mmio.vi.numFields; field++) { int frameCycles = 0; @@ -56,7 +56,7 @@ void Core::Run(float volumeL, float volumeR) { } for(; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) { - int taken = cpu.Step(); + int taken = cpu->Step(); static int cpuSteps = 0; cpuSteps += taken; if(mmio.rsp.spStatus.halt) { @@ -86,7 +86,7 @@ void Core::Run(float volumeL, float volumeR) { InterruptRaise(mmio.mi, regs, Interrupt::VI); } - mmio.ai.Step(cpu.mem, regs, frameCycles, volumeL, volumeR); + mmio.ai.Step(cpu->mem, regs, frameCycles, volumeL, volumeR); scheduler.tick(frameCycles, mem, regs); } } diff --git a/src/backend/Core.hpp b/src/backend/Core.hpp index a6cd8a75..8057aaf2 100644 --- a/src/backend/Core.hpp +++ b/src/backend/Core.hpp @@ -14,7 +14,7 @@ struct Core { void LoadROM(const std::string&); void Run(float volumeL, float volumeR); void TogglePause() { pause = !pause; } - [[nodiscard]] VI& GetVI() { return cpu.mem.mmio.vi; } + [[nodiscard]] VI& GetVI() { return cpu->mem.mmio.vi; } u32 breakpoint = 0; @@ -23,6 +23,6 @@ struct Core { int cycles = 0; bool romLoaded = false; std::string rom; - Interpreter cpu; + std::unique_ptr cpu; }; } diff --git a/src/backend/core/BaseCPU.hpp b/src/backend/core/BaseCPU.hpp new file mode 100644 index 00000000..e836160f --- /dev/null +++ b/src/backend/core/BaseCPU.hpp @@ -0,0 +1,13 @@ +#pragma once +#include +#include + +namespace n64 { +struct BaseCPU { + virtual ~BaseCPU() = default; + virtual int Step() {return 0;} + virtual void Reset() {} + Registers regs; + Mem mem; +}; +} \ No newline at end of file diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index c6a1c480..4313e561 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -1,13 +1,14 @@ #pragma once #include #include +#include "BaseCPU.hpp" namespace n64 { struct Core; -struct Interpreter { +struct Interpreter : BaseCPU { Interpreter() = default; - ~Interpreter() = default; - FORCE_INLINE int Step() { + ~Interpreter() override = default; + FORCE_INLINE int Step() override { CheckCompareInterrupt(); regs.prevDelaySlot = regs.delaySlot; @@ -35,7 +36,7 @@ struct Interpreter { return 1; } - void Reset(); + void Reset() override; Registers regs; Mem mem; private: diff --git a/src/frontend/App.cpp b/src/frontend/App.cpp index 0129cf38..214a2bce 100644 --- a/src/frontend/App.cpp +++ b/src/frontend/App.cpp @@ -9,7 +9,7 @@ App::App() : window(core) { void App::Run() { SDL_EventState(SDL_DROPFILE, SDL_ENABLE); - n64::SI& si = core.cpu.mem.mmio.si; + n64::SI& si = core.cpu->mem.mmio.si; while (!window.done) { SDL_Event event; diff --git a/src/frontend/imgui/Settings.cpp b/src/frontend/imgui/Settings.cpp index b43e4b92..b8ec46fd 100644 --- a/src/frontend/imgui/Settings.cpp +++ b/src/frontend/imgui/Settings.cpp @@ -21,7 +21,7 @@ namespace fs = std::filesystem; } while(0) -Settings::Settings() { +Settings::Settings(n64::Core& core) { auto fileExists = fs::exists("resources/settings.json"); std::fstream settingsFile; if(fileExists) { @@ -34,20 +34,29 @@ Settings::Settings() { volumeR = oldVolumeR; checkjsonentry(mute, bool, "audio", "mute", false); checkjsonentry(lockChannels, bool, "audio", "lockChannels", true); + checkjsonentry(jit, bool, "cpu", "enableJIT", false); } else { settingsFile = std::fstream("resources/settings.json", std::fstream::trunc | std::fstream::in | std::fstream::out); settings["audio"]["volumeR"] = 0.5; settings["audio"]["volumeL"] = 0.5; settings["audio"]["lockChannels"] = true; settings["audio"]["mute"] = false; + settings["cpu"]["enableJIT"] = false; oldVolumeR = volumeR = 0.5; oldVolumeL = volumeL = 0.5; lockChannels = true; mute = false; + jit = false; settingsFile << settings; } + + if(jit) { + Util::panic("JIT is unimplemented!"); + } else { + core.cpu = std::make_unique(); + } settingsFile.close(); } @@ -64,6 +73,7 @@ Settings::~Settings() { settings["audio"]["volumeL"] = oldVolumeL; settings["audio"]["lockChannels"] = lockChannels; settings["audio"]["mute"] = mute; + settings["cpu"]["enableJIT"] = jit; settingsFile << settings; settingsFile.close(); @@ -73,9 +83,9 @@ void Settings::RenderWidget(bool& show) { if(show) { ImGui::OpenPopup("Settings"); if(ImGui::BeginPopupModal("Settings", &show)) { - enum class SelectedSetting { Audio, COUNT }; - static SelectedSetting selectedSetting = SelectedSetting::Audio; - const char *categories[(int)SelectedSetting::COUNT] = { "Audio" }; + enum class SelectedSetting { CPU, Audio, COUNT }; + static SelectedSetting selectedSetting = SelectedSetting::CPU; + const char *categories[(int)SelectedSetting::COUNT] = { "CPU", "Audio" }; CreateComboList("##", (int*)&selectedSetting, categories, (int)SelectedSetting::COUNT); ImGui::Separator(); switch (selectedSetting) { @@ -112,6 +122,9 @@ void Settings::RenderWidget(bool& show) { } break; + case SelectedSetting::CPU: + ImGui::Checkbox("Enable JIT", &jit); + break; case SelectedSetting::COUNT: Util::panic("BRUH"); } diff --git a/src/frontend/imgui/Settings.hpp b/src/frontend/imgui/Settings.hpp index d356be58..bbe24bb6 100644 --- a/src/frontend/imgui/Settings.hpp +++ b/src/frontend/imgui/Settings.hpp @@ -6,7 +6,7 @@ namespace n64 { struct Core; } using namespace nlohmann; struct Settings { - Settings(); + Settings(n64::Core& core); ~Settings(); [[nodiscard]] FORCE_INLINE float GetVolumeL() const { return volumeL; }; @@ -14,6 +14,7 @@ struct Settings { void RenderWidget(bool& show); private: + bool jit = false; float volumeL, volumeR; float oldVolumeL, oldVolumeR; bool lockChannels = true; diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index 44faabbc..fb16e449 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -8,9 +8,9 @@ VkInstance instance{}; namespace fs = std::filesystem; -Window::Window(n64::Core& core) : settings() { +Window::Window(n64::Core& core) : settings(core) { InitSDL(); - InitParallelRDP(core.cpu.mem.GetRDRAM(), window); + InitParallelRDP(core.cpu->mem.GetRDRAM(), window); InitImgui(); NFD::Init(); } @@ -155,7 +155,7 @@ ImDrawData* Window::Present(n64::Core& core) { void Window::LoadROM(n64::Core& core, const std::string &path) { if(!path.empty()) { core.LoadROM(path); - gameName = core.cpu.mem.rom.gameNameDB; + gameName = core.cpu->mem.rom.gameNameDB; if(gameName.empty()) { gameName = fs::path(path).stem().string(); @@ -177,13 +177,13 @@ void Window::RenderMainMenuBar(n64::Core &core) { OpenROMDialog(*this, core); } if (ImGui::MenuItem("Dump RDRAM")) { - core.cpu.mem.DumpRDRAM(); + core.cpu->mem.DumpRDRAM(); } if (ImGui::MenuItem("Dump IMEM")) { - core.cpu.mem.DumpIMEM(); + core.cpu->mem.DumpIMEM(); } if (ImGui::MenuItem("Dump DMEM")) { - core.cpu.mem.DumpDMEM(); + core.cpu->mem.DumpDMEM(); } if (ImGui::MenuItem("Exit")) { done = true; @@ -228,8 +228,8 @@ void Window::Render(n64::Core& core) { static u32 lastFrame = 0; if(!core.pause && core.romLoaded && lastFrame < ticks - 1000) { lastFrame = ticks; - windowTitle += fmt::format(" | {:02d} VI/s", core.cpu.mem.mmio.vi.swaps); - core.cpu.mem.mmio.vi.swaps = 0; + windowTitle += fmt::format(" | {:02d} VI/s", core.cpu->mem.mmio.vi.swaps); + core.cpu->mem.mmio.vi.swaps = 0; SDL_SetWindowTitle(window, windowTitle.c_str()); windowTitle = shadowWindowTitle; }