Don't use virtual class for different type of cpu core

This commit is contained in:
CocoSimone
2022-12-06 20:51:37 +01:00
parent f6824eaa4f
commit 1aeddbfc9f
9 changed files with 89 additions and 39 deletions

View File

@@ -32,7 +32,7 @@ target_include_directories(gadolinium PRIVATE
n64
n64/core
n64/core/interpreter/
n64/core/interpreter/registers
n64/core/registers
n64/core/mmio
n64/core/rsp
frontend

View File

@@ -2,17 +2,16 @@
#include <nfd.hpp>
#include <Core.hpp>
#include <Audio.hpp>
#include <nlohmann/json.hpp>
#include <filesystem>
#include <SDL.h>
VkInstance instance{};
using json = nlohmann::json;
Window::Window(n64::Core& core) {
InitSDL();
LoadSettings(core);
InitParallelRDP(core.mem.GetRDRAM(), window);
InitImgui(core);
InitImgui();
NFD::Init();
}
@@ -21,6 +20,34 @@ Window::Window(n64::Core& core) {
&& event.window.windowID == SDL_GetWindowID(window);
}
void Window::LoadSettings(n64::Core &core) {
settingsFile.open("settings.json", std::fstream::in | std::fstream::out);
if(settingsFile.is_open()) {
settings = json::parse(settingsFile);
auto entryCpuType = settings["cpu_type"];
if(!entryCpuType.empty()) {
auto cpuType = entryCpuType.get<std::string>();
if(cpuType == "dynarec") {
core.cpuType = n64::CpuType::Dynarec;
} else if(cpuType == "interpreter") {
core.cpuType = n64::CpuType::Interpreter;
} else {
util::panic("Unrecognized cpu type: {}\n", cpuType);
}
} else {
settings["cpu_type"] = "dynarec";
settingsFile << settings;
core.cpuType = n64::CpuType::Dynarec;
}
} else {
settings["cpu_type"] = "dynarec";
settingsFile << settings;
core.cpuType = n64::CpuType::Dynarec;
}
settingsFile.close();
}
void Window::InitSDL() {
SDL_Init(SDL_INIT_EVERYTHING);
n64::InitAudio();
@@ -47,7 +74,7 @@ static void check_vk_result(VkResult err) {
}
}
void Window::InitImgui(const n64::Core& core) {
void Window::InitImgui() {
VkResult err;
IMGUI_CHECKVERSION();

View File

@@ -6,6 +6,9 @@
#include <SDL.h>
#include <Core.hpp>
#include <vector>
#include <nlohmann/json.hpp>
using namespace nlohmann;
struct Window {
explicit Window(n64::Core& core);
@@ -18,13 +21,16 @@ struct Window {
float volumeL = 0.1, volumeR = 0.1;
void LoadROM(n64::Core& core, const std::string& path);
private:
json settings;
std::fstream settingsFile;
bool lockVolume = true;
SDL_Window* window{};
std::string windowTitle;
std::string shadowWindowTitle;
void InitSDL();
void InitImgui(const n64::Core& core);
void InitImgui();
void Render(n64::Core& core);
void LoadSettings(n64::Core&);
VkPhysicalDevice physicalDevice{};
VkDevice device{};

View File

@@ -7,12 +7,11 @@
namespace n64 {
Core::Core() {
cpu = std::make_unique<Interpreter>();
Stop();
}
void Core::Stop() {
cpu->Reset();
CpuReset();
mem.Reset();
pause = true;
romLoaded = false;
@@ -20,13 +19,13 @@ void Core::Stop() {
CartInfo Core::LoadROM(const std::string& rom_) {
rom = rom_;
cpu->Reset();
CpuReset();
mem.Reset();
pause = false;
romLoaded = true;
CartInfo cartInfo = mem.LoadROM(rom);
DoPIFHLE(mem, cpu->regs, cartInfo);
DoPIFHLE(mem, CpuGetRegs(), cartInfo);
return cartInfo;
}
@@ -42,11 +41,11 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
mmio.vi.current = (i << 1) + field;
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI);
InterruptRaise(mmio.mi, CpuGetRegs(), Interrupt::VI);
}
for(;cycles <= mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
cpu->Step(mem);
CpuStep(mem);
cpuSteps++;
if(mmio.rsp.spStatus.halt) {
mmio.rsp.steps = 0;
@@ -59,25 +58,25 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
while(mmio.rsp.steps > 0) {
mmio.rsp.steps--;
mmio.rsp.Step(cpu->regs, mem);
mmio.rsp.Step(CpuGetRegs(), mem);
}
}
mmio.ai.Step(mem, cpu->regs, 1, volumeL, volumeR);
scheduler.tick(1, mem, cpu->regs);
mmio.ai.Step(mem, CpuGetRegs(), 1, volumeL, volumeR);
scheduler.tick(1, mem, CpuGetRegs());
}
cycles -= mmio.vi.cyclesPerHalfline;
}
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI);
InterruptRaise(mmio.mi, CpuGetRegs(), Interrupt::VI);
}
UpdateScreenParallelRdp(*this, window, GetVI());
int missedCycles = N64_CYCLES_PER_FRAME - frameCycles;
mmio.ai.Step(mem, cpu->regs, missedCycles, volumeL, volumeR);
mmio.ai.Step(mem, CpuGetRegs(), missedCycles, volumeL, volumeR);
} else if(pause && romLoaded) {
UpdateScreenParallelRdp(*this, window, GetVI());
} else if(pause && !romLoaded) {

View File

@@ -3,10 +3,15 @@
#include <Interpreter.hpp>
#include <Mem.hpp>
#include <string>
#include <Dynarec.hpp>
struct Window;
namespace n64 {
enum class CpuType {
Dynarec, Interpreter
};
struct Core {
~Core() { Stop(); }
Core();
@@ -17,6 +22,27 @@ struct Core {
void TogglePause() { pause = !pause; }
VI& GetVI() { return mem.mmio.vi; }
void CpuReset() {
switch(cpuType) {
case CpuType::Dynarec: cpuDynarec.Reset(); break;
case CpuType::Interpreter: cpuInterp.Reset(); break;
}
}
void CpuStep(Mem& mem) {
switch(cpuType) {
case CpuType::Dynarec: cpuDynarec.Step(mem); break;
case CpuType::Interpreter: cpuInterp.Step(mem); break;
}
}
Registers& CpuGetRegs() {
switch(cpuType) {
case CpuType::Dynarec: return cpuDynarec.regs;
case CpuType::Interpreter: return cpuInterp.regs;
}
}
u32 breakpoint = 0;
int cycles = 0;
@@ -27,6 +53,8 @@ struct Core {
bool done = false;
std::string rom;
Mem mem;
std::unique_ptr<BaseCpu> cpu;
CpuType cpuType = CpuType::Dynarec;
Interpreter cpuInterp;
Dynarec cpuDynarec;
};
}

View File

@@ -1,12 +0,0 @@
#pragma
#include <core/registers/Registers.hpp>
namespace n64 {
struct BaseCpu {
virtual ~BaseCpu() {}
Registers regs;
virtual void Step(Mem& mem) {}
virtual void Reset() {}
};
}

View File

@@ -1,11 +1,13 @@
#pragma once
#include <BaseCpu.hpp>
#include <xbyak/xbyak.h>
#include <Mem.hpp>
#include <Registers.hpp>
namespace n64 {
struct Dynarec : BaseCpu {
void Step(Mem& mem) override;
void Reset() override;
struct Dynarec {
void Step(Mem& mem);
void Reset();
Registers regs;
private:
Xbyak::CodeGenerator code;
};

View File

@@ -1,12 +1,11 @@
#pragma once
#include <BaseCpu.hpp>
#include <core/registers/Registers.hpp>
#include <Mem.hpp>
#include <capstone/capstone.h>
#include <vector>
namespace n64 {
struct Interpreter : BaseCpu {
struct Interpreter {
Interpreter() {
if(cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle) != CS_ERR_OK) {
util::panic("Could not initialize capstone!\n");
@@ -17,8 +16,9 @@ struct Interpreter : BaseCpu {
~Interpreter() {
cs_close(&handle);
}
void Reset() override;
void Step(Mem&) override;
void Reset();
void Step(Mem&);
Registers regs;
private:
csh handle;