Don't use virtual class for different type of cpu core
This commit is contained in:
2
external/parallel-rdp/CMakeLists.txt
vendored
2
external/parallel-rdp/CMakeLists.txt
vendored
@@ -63,7 +63,7 @@ target_include_directories(parallel-rdp PUBLIC
|
|||||||
../../src/n64/core/
|
../../src/n64/core/
|
||||||
../../src/n64/core/mmio
|
../../src/n64/core/mmio
|
||||||
../../src/n64/core/interpreter/
|
../../src/n64/core/interpreter/
|
||||||
../../src/n64/core/interpreter/registers
|
../../src/n64/core/registers
|
||||||
parallel-rdp-standalone
|
parallel-rdp-standalone
|
||||||
..
|
..
|
||||||
../capstone/include
|
../capstone/include
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ target_include_directories(gadolinium PRIVATE
|
|||||||
n64
|
n64
|
||||||
n64/core
|
n64/core
|
||||||
n64/core/interpreter/
|
n64/core/interpreter/
|
||||||
n64/core/interpreter/registers
|
n64/core/registers
|
||||||
n64/core/mmio
|
n64/core/mmio
|
||||||
n64/core/rsp
|
n64/core/rsp
|
||||||
frontend
|
frontend
|
||||||
|
|||||||
@@ -2,17 +2,16 @@
|
|||||||
#include <nfd.hpp>
|
#include <nfd.hpp>
|
||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
#include <Audio.hpp>
|
#include <Audio.hpp>
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
VkInstance instance{};
|
VkInstance instance{};
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
Window::Window(n64::Core& core) {
|
Window::Window(n64::Core& core) {
|
||||||
InitSDL();
|
InitSDL();
|
||||||
|
LoadSettings(core);
|
||||||
InitParallelRDP(core.mem.GetRDRAM(), window);
|
InitParallelRDP(core.mem.GetRDRAM(), window);
|
||||||
InitImgui(core);
|
InitImgui();
|
||||||
NFD::Init();
|
NFD::Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,6 +20,34 @@ Window::Window(n64::Core& core) {
|
|||||||
&& event.window.windowID == SDL_GetWindowID(window);
|
&& 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() {
|
void Window::InitSDL() {
|
||||||
SDL_Init(SDL_INIT_EVERYTHING);
|
SDL_Init(SDL_INIT_EVERYTHING);
|
||||||
n64::InitAudio();
|
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;
|
VkResult err;
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
explicit Window(n64::Core& core);
|
explicit Window(n64::Core& core);
|
||||||
@@ -18,13 +21,16 @@ struct Window {
|
|||||||
float volumeL = 0.1, volumeR = 0.1;
|
float volumeL = 0.1, volumeR = 0.1;
|
||||||
void LoadROM(n64::Core& core, const std::string& path);
|
void LoadROM(n64::Core& core, const std::string& path);
|
||||||
private:
|
private:
|
||||||
|
json settings;
|
||||||
|
std::fstream settingsFile;
|
||||||
bool lockVolume = true;
|
bool lockVolume = true;
|
||||||
SDL_Window* window{};
|
SDL_Window* window{};
|
||||||
std::string windowTitle;
|
std::string windowTitle;
|
||||||
std::string shadowWindowTitle;
|
std::string shadowWindowTitle;
|
||||||
void InitSDL();
|
void InitSDL();
|
||||||
void InitImgui(const n64::Core& core);
|
void InitImgui();
|
||||||
void Render(n64::Core& core);
|
void Render(n64::Core& core);
|
||||||
|
void LoadSettings(n64::Core&);
|
||||||
|
|
||||||
VkPhysicalDevice physicalDevice{};
|
VkPhysicalDevice physicalDevice{};
|
||||||
VkDevice device{};
|
VkDevice device{};
|
||||||
|
|||||||
@@ -7,12 +7,11 @@
|
|||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
Core::Core() {
|
Core::Core() {
|
||||||
cpu = std::make_unique<Interpreter>();
|
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Stop() {
|
void Core::Stop() {
|
||||||
cpu->Reset();
|
CpuReset();
|
||||||
mem.Reset();
|
mem.Reset();
|
||||||
pause = true;
|
pause = true;
|
||||||
romLoaded = false;
|
romLoaded = false;
|
||||||
@@ -20,13 +19,13 @@ void Core::Stop() {
|
|||||||
|
|
||||||
CartInfo Core::LoadROM(const std::string& rom_) {
|
CartInfo Core::LoadROM(const std::string& rom_) {
|
||||||
rom = rom_;
|
rom = rom_;
|
||||||
cpu->Reset();
|
CpuReset();
|
||||||
mem.Reset();
|
mem.Reset();
|
||||||
pause = false;
|
pause = false;
|
||||||
romLoaded = true;
|
romLoaded = true;
|
||||||
|
|
||||||
CartInfo cartInfo = mem.LoadROM(rom);
|
CartInfo cartInfo = mem.LoadROM(rom);
|
||||||
DoPIFHLE(mem, cpu->regs, cartInfo);
|
DoPIFHLE(mem, CpuGetRegs(), cartInfo);
|
||||||
|
|
||||||
return cartInfo;
|
return cartInfo;
|
||||||
}
|
}
|
||||||
@@ -42,11 +41,11 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
|
|||||||
mmio.vi.current = (i << 1) + field;
|
mmio.vi.current = (i << 1) + field;
|
||||||
|
|
||||||
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
|
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++) {
|
for(;cycles <= mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
|
||||||
cpu->Step(mem);
|
CpuStep(mem);
|
||||||
cpuSteps++;
|
cpuSteps++;
|
||||||
if(mmio.rsp.spStatus.halt) {
|
if(mmio.rsp.spStatus.halt) {
|
||||||
mmio.rsp.steps = 0;
|
mmio.rsp.steps = 0;
|
||||||
@@ -59,25 +58,25 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
|
|||||||
|
|
||||||
while(mmio.rsp.steps > 0) {
|
while(mmio.rsp.steps > 0) {
|
||||||
mmio.rsp.steps--;
|
mmio.rsp.steps--;
|
||||||
mmio.rsp.Step(cpu->regs, mem);
|
mmio.rsp.Step(CpuGetRegs(), mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mmio.ai.Step(mem, cpu->regs, 1, volumeL, volumeR);
|
mmio.ai.Step(mem, CpuGetRegs(), 1, volumeL, volumeR);
|
||||||
scheduler.tick(1, mem, cpu->regs);
|
scheduler.tick(1, mem, CpuGetRegs());
|
||||||
}
|
}
|
||||||
|
|
||||||
cycles -= mmio.vi.cyclesPerHalfline;
|
cycles -= mmio.vi.cyclesPerHalfline;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
|
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());
|
UpdateScreenParallelRdp(*this, window, GetVI());
|
||||||
|
|
||||||
int missedCycles = N64_CYCLES_PER_FRAME - frameCycles;
|
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) {
|
} else if(pause && romLoaded) {
|
||||||
UpdateScreenParallelRdp(*this, window, GetVI());
|
UpdateScreenParallelRdp(*this, window, GetVI());
|
||||||
} else if(pause && !romLoaded) {
|
} else if(pause && !romLoaded) {
|
||||||
|
|||||||
@@ -3,10 +3,15 @@
|
|||||||
#include <Interpreter.hpp>
|
#include <Interpreter.hpp>
|
||||||
#include <Mem.hpp>
|
#include <Mem.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <Dynarec.hpp>
|
||||||
|
|
||||||
struct Window;
|
struct Window;
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
|
enum class CpuType {
|
||||||
|
Dynarec, Interpreter
|
||||||
|
};
|
||||||
|
|
||||||
struct Core {
|
struct Core {
|
||||||
~Core() { Stop(); }
|
~Core() { Stop(); }
|
||||||
Core();
|
Core();
|
||||||
@@ -17,6 +22,27 @@ struct Core {
|
|||||||
void TogglePause() { pause = !pause; }
|
void TogglePause() { pause = !pause; }
|
||||||
VI& GetVI() { return mem.mmio.vi; }
|
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;
|
u32 breakpoint = 0;
|
||||||
int cycles = 0;
|
int cycles = 0;
|
||||||
|
|
||||||
@@ -27,6 +53,8 @@ struct Core {
|
|||||||
bool done = false;
|
bool done = false;
|
||||||
std::string rom;
|
std::string rom;
|
||||||
Mem mem;
|
Mem mem;
|
||||||
std::unique_ptr<BaseCpu> cpu;
|
CpuType cpuType = CpuType::Dynarec;
|
||||||
|
Interpreter cpuInterp;
|
||||||
|
Dynarec cpuDynarec;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <BaseCpu.hpp>
|
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
#include <Mem.hpp>
|
||||||
|
#include <Registers.hpp>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
struct Dynarec : BaseCpu {
|
struct Dynarec {
|
||||||
void Step(Mem& mem) override;
|
void Step(Mem& mem);
|
||||||
void Reset() override;
|
void Reset();
|
||||||
|
Registers regs;
|
||||||
private:
|
private:
|
||||||
Xbyak::CodeGenerator code;
|
Xbyak::CodeGenerator code;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <BaseCpu.hpp>
|
|
||||||
#include <core/registers/Registers.hpp>
|
#include <core/registers/Registers.hpp>
|
||||||
#include <Mem.hpp>
|
#include <Mem.hpp>
|
||||||
#include <capstone/capstone.h>
|
#include <capstone/capstone.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
struct Interpreter : BaseCpu {
|
struct Interpreter {
|
||||||
Interpreter() {
|
Interpreter() {
|
||||||
if(cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle) != CS_ERR_OK) {
|
if(cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle) != CS_ERR_OK) {
|
||||||
util::panic("Could not initialize capstone!\n");
|
util::panic("Could not initialize capstone!\n");
|
||||||
@@ -17,8 +16,9 @@ struct Interpreter : BaseCpu {
|
|||||||
~Interpreter() {
|
~Interpreter() {
|
||||||
cs_close(&handle);
|
cs_close(&handle);
|
||||||
}
|
}
|
||||||
void Reset() override;
|
void Reset();
|
||||||
void Step(Mem&) override;
|
void Step(Mem&);
|
||||||
|
Registers regs;
|
||||||
private:
|
private:
|
||||||
csh handle;
|
csh handle;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user