Files
kaizen/src/backend/Core.cpp
2025-07-29 11:08:05 +02:00

106 lines
2.9 KiB
C++

#include <Core.hpp>
#include <ParallelRDPWrapper.hpp>
#include <Scheduler.hpp>
#include <Options.hpp>
namespace n64 {
Core::Core() {
auto cpuType = Options::GetInstance().GetValue<std::string>("cpu", "type");
if (cpuType == "interpreter") {
cpu = std::make_unique<Interpreter>(parallel);
} else if(cpuType == "jit") {
#ifndef __aarch64__
cpu = std::make_unique<JIT>(parallel);
#else
panic("JIT currently unsupported on aarch64");
#endif
} else {
panic("Unimplemented CPU type");
}
}
void Core::Stop() {
pause = true;
romLoaded = false;
cpu->Reset();
}
bool Core::LoadTAS(const fs::path &path) const { return cpu->GetMem().mmio.si.pif.movie.Load(path); }
void Core::LoadROM(const std::string &rom_) {
Stop();
rom = rom_;
std::string archive_types[] = {".zip", ".7z", ".rar", ".tar"};
auto extension = fs::path(rom).extension().string();
const bool isArchive = std::ranges::any_of(archive_types, [&extension](const auto &e) { return e == extension; });
cpu->GetMem().LoadROM(isArchive, rom);
GameDB::match();
if (cpu->GetMem().rom.gameNameDB.empty()) {
cpu->GetMem().rom.gameNameDB = fs::path(rom).stem().string();
}
cpu->GetMem().mmio.vi.isPal = cpu->GetMem().IsROMPAL();
cpu->GetMem().mmio.si.pif.InitDevices(cpu->GetMem().saveType);
cpu->GetMem().mmio.si.pif.mempakPath = rom;
cpu->GetMem().mmio.si.pif.LoadEeprom(cpu->GetMem().saveType, rom);
cpu->GetMem().flash.Load(cpu->GetMem().saveType, rom);
cpu->GetMem().LoadSRAM(cpu->GetMem().saveType, rom);
cpu->GetMem().mmio.si.pif.Execute();
pause = false;
romLoaded = true;
}
void Core::Run(float volumeL, float volumeR) {
Mem &mem = cpu->GetMem();
MMIO &mmio = mem.mmio;
Registers &regs = cpu->GetRegs();
for (int field = 0; field < mmio.vi.numFields; field++) {
u32 frameCycles = 0;
for (int i = 0; i < mmio.vi.numHalflines; i++) {
mmio.vi.current = (i << 1) + field;
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
mmio.mi.InterruptRaise(MI::Interrupt::VI);
}
for (; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
u32 taken = cpu->Step();
taken += regs.PopStalledCycles();
regs.steps += taken;
if (mmio.rsp.spStatus.halt) {
regs.steps = 0;
mmio.rsp.steps = 0;
} else {
while (regs.steps > 2) {
mmio.rsp.steps += 2;
regs.steps -= 3;
}
while (mmio.rsp.steps > 0) {
mmio.rsp.steps--;
mmio.rsp.Step();
}
}
cycles += taken;
frameCycles += taken;
Scheduler::GetInstance().Tick(taken);
}
cycles -= mmio.vi.cyclesPerHalfline;
}
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
mmio.mi.InterruptRaise(MI::Interrupt::VI);
}
mmio.ai.Step(frameCycles, volumeL, volumeR);
Scheduler::GetInstance().Tick(frameCycles);
}
}
} // namespace n64