Lay down BaseCPU structure

This commit is contained in:
SimoneN64
2023-07-24 16:06:33 +02:00
parent e587c31150
commit 698032f0a1
8 changed files with 64 additions and 36 deletions

View File

@@ -9,15 +9,15 @@ Core::Core() {
} }
void Core::Stop() { void Core::Stop() {
cpu.Reset(); cpu->Reset();
cpu.mem.Reset(); cpu->mem.Reset();
pause = true; pause = true;
romLoaded = false; romLoaded = false;
} }
void Core::LoadROM(const std::string& rom_) { void Core::LoadROM(const std::string& rom_) {
rom = rom_; rom = rom_;
cpu.Reset(); cpu->Reset();
pause = false; pause = false;
romLoaded = true; romLoaded = true;
@@ -30,21 +30,21 @@ void Core::LoadROM(const std::string& rom_) {
} }
} }
cpu.mem.LoadROM(isArchive, rom); cpu->mem.LoadROM(isArchive, rom);
GameDB::match(cpu.mem); GameDB::match(cpu->mem);
cpu.mem.mmio.vi.isPal = cpu.mem.IsROMPAL(); cpu->mem.mmio.vi.isPal = cpu->mem.IsROMPAL();
cpu.mem.mmio.si.pif.InitDevices(cpu.mem.saveType); cpu->mem.mmio.si.pif.InitDevices(cpu->mem.saveType);
cpu.mem.mmio.si.pif.LoadMempak(rom); cpu->mem.mmio.si.pif.LoadMempak(rom);
cpu.mem.mmio.si.pif.LoadEeprom(cpu.mem.saveType, rom); cpu->mem.mmio.si.pif.LoadEeprom(cpu->mem.saveType, rom);
cpu.mem.flash.Load(cpu.mem.saveType, rom); cpu->mem.flash.Load(cpu->mem.saveType, rom);
cpu.mem.LoadSRAM(cpu.mem.saveType, rom); cpu->mem.LoadSRAM(cpu->mem.saveType, rom);
PIF::ExecutePIF(cpu.mem, cpu.regs); PIF::ExecutePIF(cpu->mem, cpu->regs);
} }
void Core::Run(float volumeL, float volumeR) { void Core::Run(float volumeL, float volumeR) {
Mem& mem = cpu.mem; Mem& mem = cpu->mem;
MMIO& mmio = mem.mmio; MMIO& mmio = mem.mmio;
Registers& regs = cpu.regs; Registers& regs = cpu->regs;
for (int field = 0; field < mmio.vi.numFields; field++) { for (int field = 0; field < mmio.vi.numFields; field++) {
int frameCycles = 0; int frameCycles = 0;
@@ -56,7 +56,7 @@ void Core::Run(float volumeL, float volumeR) {
} }
for(; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) { for(; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
int taken = cpu.Step(); int taken = cpu->Step();
static int cpuSteps = 0; static int cpuSteps = 0;
cpuSteps += taken; cpuSteps += taken;
if(mmio.rsp.spStatus.halt) { if(mmio.rsp.spStatus.halt) {
@@ -86,7 +86,7 @@ void Core::Run(float volumeL, float volumeR) {
InterruptRaise(mmio.mi, regs, Interrupt::VI); 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); scheduler.tick(frameCycles, mem, regs);
} }
} }

View File

@@ -14,7 +14,7 @@ struct Core {
void LoadROM(const std::string&); void LoadROM(const std::string&);
void Run(float volumeL, float volumeR); void Run(float volumeL, float volumeR);
void TogglePause() { pause = !pause; } void TogglePause() { pause = !pause; }
[[nodiscard]] VI& GetVI() { return cpu.mem.mmio.vi; } [[nodiscard]] VI& GetVI() { return cpu->mem.mmio.vi; }
u32 breakpoint = 0; u32 breakpoint = 0;
@@ -23,6 +23,6 @@ struct Core {
int cycles = 0; int cycles = 0;
bool romLoaded = false; bool romLoaded = false;
std::string rom; std::string rom;
Interpreter cpu; std::unique_ptr<BaseCPU> cpu;
}; };
} }

View File

@@ -0,0 +1,13 @@
#pragma once
#include <Registers.hpp>
#include <Mem.hpp>
namespace n64 {
struct BaseCPU {
virtual ~BaseCPU() = default;
virtual int Step() {return 0;}
virtual void Reset() {}
Registers regs;
Mem mem;
};
}

View File

@@ -1,13 +1,14 @@
#pragma once #pragma once
#include <Mem.hpp> #include <Mem.hpp>
#include <vector> #include <vector>
#include "BaseCPU.hpp"
namespace n64 { namespace n64 {
struct Core; struct Core;
struct Interpreter { struct Interpreter : BaseCPU {
Interpreter() = default; Interpreter() = default;
~Interpreter() = default; ~Interpreter() override = default;
FORCE_INLINE int Step() { FORCE_INLINE int Step() override {
CheckCompareInterrupt(); CheckCompareInterrupt();
regs.prevDelaySlot = regs.delaySlot; regs.prevDelaySlot = regs.delaySlot;
@@ -35,7 +36,7 @@ struct Interpreter {
return 1; return 1;
} }
void Reset(); void Reset() override;
Registers regs; Registers regs;
Mem mem; Mem mem;
private: private:

View File

@@ -9,7 +9,7 @@ App::App() : window(core) {
void App::Run() { void App::Run() {
SDL_EventState(SDL_DROPFILE, SDL_ENABLE); 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) { while (!window.done) {
SDL_Event event; SDL_Event event;

View File

@@ -21,7 +21,7 @@ namespace fs = std::filesystem;
} while(0) } while(0)
Settings::Settings() { Settings::Settings(n64::Core& core) {
auto fileExists = fs::exists("resources/settings.json"); auto fileExists = fs::exists("resources/settings.json");
std::fstream settingsFile; std::fstream settingsFile;
if(fileExists) { if(fileExists) {
@@ -34,20 +34,29 @@ Settings::Settings() {
volumeR = oldVolumeR; volumeR = oldVolumeR;
checkjsonentry(mute, bool, "audio", "mute", false); checkjsonentry(mute, bool, "audio", "mute", false);
checkjsonentry(lockChannels, bool, "audio", "lockChannels", true); checkjsonentry(lockChannels, bool, "audio", "lockChannels", true);
checkjsonentry(jit, bool, "cpu", "enableJIT", false);
} else { } else {
settingsFile = std::fstream("resources/settings.json", std::fstream::trunc | std::fstream::in | std::fstream::out); settingsFile = std::fstream("resources/settings.json", std::fstream::trunc | std::fstream::in | std::fstream::out);
settings["audio"]["volumeR"] = 0.5; settings["audio"]["volumeR"] = 0.5;
settings["audio"]["volumeL"] = 0.5; settings["audio"]["volumeL"] = 0.5;
settings["audio"]["lockChannels"] = true; settings["audio"]["lockChannels"] = true;
settings["audio"]["mute"] = false; settings["audio"]["mute"] = false;
settings["cpu"]["enableJIT"] = false;
oldVolumeR = volumeR = 0.5; oldVolumeR = volumeR = 0.5;
oldVolumeL = volumeL = 0.5; oldVolumeL = volumeL = 0.5;
lockChannels = true; lockChannels = true;
mute = false; mute = false;
jit = false;
settingsFile << settings; settingsFile << settings;
} }
if(jit) {
Util::panic("JIT is unimplemented!");
} else {
core.cpu = std::make_unique<n64::Interpreter>();
}
settingsFile.close(); settingsFile.close();
} }
@@ -64,6 +73,7 @@ Settings::~Settings() {
settings["audio"]["volumeL"] = oldVolumeL; settings["audio"]["volumeL"] = oldVolumeL;
settings["audio"]["lockChannels"] = lockChannels; settings["audio"]["lockChannels"] = lockChannels;
settings["audio"]["mute"] = mute; settings["audio"]["mute"] = mute;
settings["cpu"]["enableJIT"] = jit;
settingsFile << settings; settingsFile << settings;
settingsFile.close(); settingsFile.close();
@@ -73,9 +83,9 @@ void Settings::RenderWidget(bool& show) {
if(show) { if(show) {
ImGui::OpenPopup("Settings"); ImGui::OpenPopup("Settings");
if(ImGui::BeginPopupModal("Settings", &show)) { if(ImGui::BeginPopupModal("Settings", &show)) {
enum class SelectedSetting { Audio, COUNT }; enum class SelectedSetting { CPU, Audio, COUNT };
static SelectedSetting selectedSetting = SelectedSetting::Audio; static SelectedSetting selectedSetting = SelectedSetting::CPU;
const char *categories[(int)SelectedSetting::COUNT] = { "Audio" }; const char *categories[(int)SelectedSetting::COUNT] = { "CPU", "Audio" };
CreateComboList("##", (int*)&selectedSetting, categories, (int)SelectedSetting::COUNT); CreateComboList("##", (int*)&selectedSetting, categories, (int)SelectedSetting::COUNT);
ImGui::Separator(); ImGui::Separator();
switch (selectedSetting) { switch (selectedSetting) {
@@ -112,6 +122,9 @@ void Settings::RenderWidget(bool& show) {
} }
break; break;
case SelectedSetting::CPU:
ImGui::Checkbox("Enable JIT", &jit);
break;
case SelectedSetting::COUNT: case SelectedSetting::COUNT:
Util::panic("BRUH"); Util::panic("BRUH");
} }

View File

@@ -6,7 +6,7 @@ namespace n64 { struct Core; }
using namespace nlohmann; using namespace nlohmann;
struct Settings { struct Settings {
Settings(); Settings(n64::Core& core);
~Settings(); ~Settings();
[[nodiscard]] FORCE_INLINE float GetVolumeL() const { return volumeL; }; [[nodiscard]] FORCE_INLINE float GetVolumeL() const { return volumeL; };
@@ -14,6 +14,7 @@ struct Settings {
void RenderWidget(bool& show); void RenderWidget(bool& show);
private: private:
bool jit = false;
float volumeL, volumeR; float volumeL, volumeR;
float oldVolumeL, oldVolumeR; float oldVolumeL, oldVolumeR;
bool lockChannels = true; bool lockChannels = true;

View File

@@ -8,9 +8,9 @@
VkInstance instance{}; VkInstance instance{};
namespace fs = std::filesystem; namespace fs = std::filesystem;
Window::Window(n64::Core& core) : settings() { Window::Window(n64::Core& core) : settings(core) {
InitSDL(); InitSDL();
InitParallelRDP(core.cpu.mem.GetRDRAM(), window); InitParallelRDP(core.cpu->mem.GetRDRAM(), window);
InitImgui(); InitImgui();
NFD::Init(); NFD::Init();
} }
@@ -155,7 +155,7 @@ ImDrawData* Window::Present(n64::Core& core) {
void Window::LoadROM(n64::Core& core, const std::string &path) { void Window::LoadROM(n64::Core& core, const std::string &path) {
if(!path.empty()) { if(!path.empty()) {
core.LoadROM(path); core.LoadROM(path);
gameName = core.cpu.mem.rom.gameNameDB; gameName = core.cpu->mem.rom.gameNameDB;
if(gameName.empty()) { if(gameName.empty()) {
gameName = fs::path(path).stem().string(); gameName = fs::path(path).stem().string();
@@ -177,13 +177,13 @@ void Window::RenderMainMenuBar(n64::Core &core) {
OpenROMDialog(*this, core); OpenROMDialog(*this, core);
} }
if (ImGui::MenuItem("Dump RDRAM")) { if (ImGui::MenuItem("Dump RDRAM")) {
core.cpu.mem.DumpRDRAM(); core.cpu->mem.DumpRDRAM();
} }
if (ImGui::MenuItem("Dump IMEM")) { if (ImGui::MenuItem("Dump IMEM")) {
core.cpu.mem.DumpIMEM(); core.cpu->mem.DumpIMEM();
} }
if (ImGui::MenuItem("Dump DMEM")) { if (ImGui::MenuItem("Dump DMEM")) {
core.cpu.mem.DumpDMEM(); core.cpu->mem.DumpDMEM();
} }
if (ImGui::MenuItem("Exit")) { if (ImGui::MenuItem("Exit")) {
done = true; done = true;
@@ -228,8 +228,8 @@ void Window::Render(n64::Core& core) {
static u32 lastFrame = 0; static u32 lastFrame = 0;
if(!core.pause && core.romLoaded && lastFrame < ticks - 1000) { if(!core.pause && core.romLoaded && lastFrame < ticks - 1000) {
lastFrame = ticks; lastFrame = ticks;
windowTitle += fmt::format(" | {:02d} VI/s", core.cpu.mem.mmio.vi.swaps); windowTitle += fmt::format(" | {:02d} VI/s", core.cpu->mem.mmio.vi.swaps);
core.cpu.mem.mmio.vi.swaps = 0; core.cpu->mem.mmio.vi.swaps = 0;
SDL_SetWindowTitle(window, windowTitle.c_str()); SDL_SetWindowTitle(window, windowTitle.c_str());
windowTitle = shadowWindowTitle; windowTitle = shadowWindowTitle;
} }