diff --git a/external/parallel-rdp/ParallelRDPWrapper.cpp b/external/parallel-rdp/ParallelRDPWrapper.cpp index 6864835d..40fb8f38 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.cpp +++ b/external/parallel-rdp/ParallelRDPWrapper.cpp @@ -190,8 +190,9 @@ void ParallelRDP::UpdateScreen(Util::IntrusivePtr image) const { wsi->end_frame(); } -void ParallelRDP::UpdateScreen(n64::Core &core, bool playing) const { +void ParallelRDP::UpdateScreen(bool playing) const { if(playing) { + n64::Core& core = n64::Core::GetInstance(); n64::VI& vi = core.GetVI(); command_processor->set_vi_register(VIRegister::Control, vi.status.raw); command_processor->set_vi_register(VIRegister::Origin, vi.origin); diff --git a/external/parallel-rdp/ParallelRDPWrapper.hpp b/external/parallel-rdp/ParallelRDPWrapper.hpp index a7c18e73..d1f56c2d 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.hpp +++ b/external/parallel-rdp/ParallelRDPWrapper.hpp @@ -3,10 +3,6 @@ #include #include -namespace n64 { -struct Core; -} - class ParallelRDP { public: class WindowInfo { @@ -22,7 +18,7 @@ public: void Init(const std::shared_ptr &, const std::shared_ptr &, const u8 *); - void UpdateScreen(n64::Core &, bool = true) const; + void UpdateScreen(bool = true) const; void EnqueueCommand(int, const u32 *) const; void OnFullSync() const; bool IsFramerateUnlocked() const; diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 4f97b16b..346027bb 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -1,15 +1,21 @@ #include #include #include +#include namespace n64 { -Core::Core(CPUType cpuType) { - switch (cpuType) { - case Interpreted: cpu = std::make_unique(parallel); break; +Core::Core() { + auto cpuType = Options::GetInstance().GetValue("cpu", "type"); + if (cpuType == "interpreter") { + cpu = std::make_unique(parallel); + } else if(cpuType == "jit") { #ifndef __aarch64__ - case DynamicRecompiler: cpu = std::make_unique(parallel); break; + cpu = std::make_unique(parallel); + #else + panic("JIT currently unsupported on aarch64"); #endif - default: panic("Unimplemented CPU type\n"); + } else { + panic("Unimplemented CPU type"); } } @@ -31,7 +37,7 @@ void Core::LoadROM(const std::string &rom_) { const bool isArchive = std::ranges::any_of(archive_types, [&extension](const auto &e) { return e == extension; }); cpu->GetMem().LoadROM(isArchive, rom); - GameDB::match(cpu->GetMem()); + GameDB::match(); if (cpu->GetMem().rom.gameNameDB.empty()) { cpu->GetMem().rom.gameNameDB = fs::path(rom).stem().string(); } @@ -82,7 +88,7 @@ void Core::Run(float volumeL, float volumeR) { cycles += taken; frameCycles += taken; - Scheduler::GetInstance().Tick(taken, mem); + Scheduler::GetInstance().Tick(taken); } cycles -= mmio.vi.cyclesPerHalfline; @@ -93,32 +99,7 @@ void Core::Run(float volumeL, float volumeR) { } mmio.ai.Step(frameCycles, volumeL, volumeR); - Scheduler::GetInstance().Tick(frameCycles, mem); + Scheduler::GetInstance().Tick(frameCycles); } } - -void Core::Serialize() { - auto sMEM = cpu->GetMem().Serialize(); - auto sCPU = cpu->Serialize(); - auto sVER = std::vector{KAIZEN_VERSION >> 8, KAIZEN_VERSION >> 4, KAIZEN_VERSION & 0xFF}; - memSize = sMEM.size(); - cpuSize = sCPU.size(); - verSize = sVER.size(); - serialized[slot].insert(serialized[slot].begin(), sVER.begin(), sVER.end()); - serialized[slot].insert(serialized[slot].end(), sMEM.begin(), sMEM.end()); - serialized[slot].insert(serialized[slot].end(), sCPU.begin(), sCPU.end()); -} - -void Core::Deserialize() { - std::vector dVER(serialized[slot].begin(), serialized[slot].begin() + verSize); - if (dVER[0] != (KAIZEN_VERSION >> 8) || dVER[1] != (KAIZEN_VERSION >> 4) || dVER[2] != (KAIZEN_VERSION & 0xFF)) { - panic("PROBLEMI!"); - } - - cpu->GetMem().Deserialize( - std::vector(serialized[slot].begin() + verSize, serialized[slot].begin() + verSize + memSize)); - cpu->Deserialize( - std::vector(serialized[slot].begin() + verSize + memSize, serialized[slot].begin() + verSize + memSize + cpuSize)); - serialized[slot].erase(serialized[slot].begin(), serialized[slot].end()); -} } // namespace n64 diff --git a/src/backend/Core.hpp b/src/backend/Core.hpp index f8906e68..ab88f865 100644 --- a/src/backend/Core.hpp +++ b/src/backend/Core.hpp @@ -11,13 +11,18 @@ struct Core { DynamicRecompiler, CachedInterpreter }; - explicit Core(CPUType); + + explicit Core(); + + static Core& GetInstance() { + static Core instance; + return instance; + } + void Stop(); void LoadROM(const std::string &); [[nodiscard]] bool LoadTAS(const fs::path &) const; void Run(float volumeL, float volumeR); - void Serialize(); - void Deserialize(); void TogglePause() { pause = !pause; } [[nodiscard]] VI &GetVI() const { return cpu->GetMem().mmio.vi; } @@ -28,7 +33,6 @@ struct Core { bool romLoaded = false; std::string rom; std::unique_ptr cpu; - std::vector serialized[10]{}; size_t memSize{}, cpuSize{}, verSize{}; int slot = 0; ParallelRDP parallel; diff --git a/src/backend/GameDB.cpp b/src/backend/GameDB.cpp index 293b85ed..ee28e01e 100644 --- a/src/backend/GameDB.cpp +++ b/src/backend/GameDB.cpp @@ -1,8 +1,9 @@ #include -#include +#include namespace n64 { -void GameDB::match(Mem &mem) { +void GameDB::match() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); const ROM &rom = mem.rom; for (const auto &[code, regions, saveType, name] : gamedb) { const bool matches_code = code == rom.code; diff --git a/src/backend/GameDB.hpp b/src/backend/GameDB.hpp index 76a4b3b4..36ecc3b4 100644 --- a/src/backend/GameDB.hpp +++ b/src/backend/GameDB.hpp @@ -4,7 +4,6 @@ namespace n64 { enum SaveType { SAVE_NONE, SAVE_EEPROM_4k, SAVE_EEPROM_16k, SAVE_FLASH_1m, SAVE_SRAM_256k }; -struct Mem; struct GameDBEntry { std::string code; std::string regions; @@ -13,7 +12,7 @@ struct GameDBEntry { }; namespace GameDB { - void match(Mem &mem); + void match(); } static const GameDBEntry gamedb[] = { diff --git a/src/backend/Scheduler.cpp b/src/backend/Scheduler.cpp index cb63107f..861d38b2 100644 --- a/src/backend/Scheduler.cpp +++ b/src/backend/Scheduler.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include void Scheduler::EnqueueRelative(const u64 t, const EventType type) { EnqueueAbsolute(t + ticks, type); } @@ -19,7 +18,9 @@ u64 Scheduler::Remove(const EventType eventType) const { return 0; } -void Scheduler::Tick(const u64 t, n64::Mem &mem) { +void Scheduler::Tick(const u64 t) { + n64::Core& core = n64::Core::GetInstance(); + n64::Mem& mem = core.cpu->GetMem(); ticks += t; n64::MI &mi = mem.mmio.mi; n64::SI &si = mem.mmio.si; diff --git a/src/backend/Scheduler.hpp b/src/backend/Scheduler.hpp index c309eb1d..a9221a2f 100644 --- a/src/backend/Scheduler.hpp +++ b/src/backend/Scheduler.hpp @@ -3,11 +3,6 @@ #include #include -namespace n64 { -struct Mem; -struct Registers; -} // namespace n64 - enum EventType { NONE, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE }; struct Event { @@ -43,7 +38,7 @@ struct Scheduler { void EnqueueRelative(u64, EventType); void EnqueueAbsolute(u64, EventType); [[nodiscard]] u64 Remove(EventType) const; - void Tick(u64 t, n64::Mem &); + void Tick(u64 t); IterableEvents events{}; u64 ticks = 0; diff --git a/src/backend/core/BaseCPU.hpp b/src/backend/core/BaseCPU.hpp index bbc10d72..62181a4d 100644 --- a/src/backend/core/BaseCPU.hpp +++ b/src/backend/core/BaseCPU.hpp @@ -8,8 +8,6 @@ struct BaseCPU { virtual ~BaseCPU() = default; virtual int Step() = 0; virtual void Reset() = 0; - virtual std::vector Serialize() = 0; - virtual void Deserialize(const std::vector &) = 0; virtual Mem &GetMem() = 0; virtual Registers &GetRegs() = 0; [[nodiscard]] virtual Disassembler::DisassemblyResult Disassemble(u32) = 0; diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 7440560c..92cc8586 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -1,7 +1,7 @@ #include namespace n64 { -Interpreter::Interpreter(ParallelRDP ¶llel) : mem(regs, parallel) {} +Interpreter::Interpreter(ParallelRDP ¶llel) {} bool Interpreter::ShouldServiceInterrupt() const { const bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; @@ -26,7 +26,7 @@ Disassembler::DisassemblyResult Interpreter::Disassemble(const u32 address) { if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { return {}; } - return Disassembler::GetInstance().Disassemble(address, mem.Read(regs, paddr)); + return Disassembler::GetInstance().Disassemble(address, mem.Read(paddr)); } int Interpreter::Step() { @@ -48,7 +48,7 @@ int Interpreter::Step() { return 1; } - const u32 instruction = mem.Read(regs, paddr); + const u32 instruction = mem.Read(paddr); if (ShouldServiceInterrupt()) { regs.cop0.FireException(ExceptionCode::Interrupt, 0, regs.pc); @@ -63,16 +63,4 @@ int Interpreter::Step() { return 1; } - -std::vector Interpreter::Serialize() { - std::vector res{}; - - res.resize(sizeof(Registers)); - - memcpy(res.data(), ®s, sizeof(Registers)); - - return res; -} - -void Interpreter::Deserialize(const std::vector &data) { memcpy(®s, data.data(), sizeof(Registers)); } } // namespace n64 diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 48a434df..243a2d7e 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -31,8 +31,6 @@ private: (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) bool ShouldServiceInterrupt() const; void CheckCompareInterrupt(); - std::vector Serialize() override; - void Deserialize(const std::vector &) override; void cop2Decode(u32); void special(u32); diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index 1fc5c547..c969a5e1 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -3,7 +3,7 @@ namespace n64 { #ifndef __aarch64__ -JIT::JIT(ParallelRDP ¶llel) : regs(this), mem(regs, parallel, this) { +JIT::JIT(ParallelRDP ¶llel) : regs(this), mem(this) { blockCache.resize(kUpperSize); if (cs_open(CS_ARCH_MIPS, static_cast(CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN), &disassemblerMips) != CS_ERR_OK) { @@ -58,7 +58,7 @@ u32 JIT::FetchInstruction() { static_cast(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast(blockPC)); } - return mem.Read(regs, paddr); + return mem.Read(paddr); } int JIT::Step() { @@ -181,17 +181,5 @@ int JIT::Step() { // panic(""); return block(); } - -std::vector JIT::Serialize() { - std::vector res{}; - - res.resize(sizeof(Registers)); - - memcpy(res.data(), ®s, sizeof(Registers)); - - return res; -} - -void JIT::Deserialize(const std::vector &data) { memcpy(®s, data.data(), sizeof(Registers)); } #endif } // namespace n64 diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index e9e31ec6..e317cc6b 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -145,8 +145,6 @@ private: [[nodiscard]] bool ShouldServiceInterrupt() const; void CheckCompareInterrupt(); - std::vector Serialize() override; - void Deserialize(const std::vector &) override; u32 FetchInstruction(); void Emit(u32); diff --git a/src/backend/core/MMIO.cpp b/src/backend/core/MMIO.cpp index 0174bd0f..73717163 100644 --- a/src/backend/core/MMIO.cpp +++ b/src/backend/core/MMIO.cpp @@ -66,101 +66,4 @@ void MMIO::Write(const u32 addr, const u32 val) { panic("Unhandled mmio write at addr {:08X} with val {:08X}", addr, val); } } - -std::vector MMIO::Serialize() { - std::vector res{}; - - auto sPIF = si.pif.Serialize(); - constexpr u32 rdpSize = sizeof(DPC) + 0xFFFFF + RDRAM_SIZE; - res.resize(rdpSize + sizeof(RSP) + sizeof(MI) + sizeof(VI) + sizeof(SI) + sizeof(PI) + sizeof(RI) + sizeof(AI) + - sizeof(u32) * 2 + sizeof(SIStatus)); - - u32 index = 0; - memcpy(res.data(), &rsp, sizeof(RSP)); - index += sizeof(RSP); - memcpy(res.data() + index, &rdp.dpc, sizeof(DPC)); - index += sizeof(DPC); - memcpy(res.data() + index, rdp.cmd_buf.data(), RDP::COMMAND_BUFFER_SIZE); - index += 0xFFFFF; - std::ranges::copy(rdp.rdram, res.begin() + index); - index += RDRAM_SIZE; - memcpy(res.data() + index, &mi, sizeof(MI)); - index += sizeof(MI); - memcpy(res.data() + index, &vi, sizeof(VI)); - index += sizeof(VI); - memcpy(res.data() + index, &ai.dmaEnable, sizeof(ai.dmaEnable)); - index += sizeof(ai.dmaEnable); - memcpy(res.data() + index, &ai.dacRate, sizeof(ai.dacRate)); - index += sizeof(ai.dacRate); - memcpy(res.data() + index, &ai.bitrate, sizeof(ai.bitrate)); - index += sizeof(ai.bitrate); - memcpy(res.data() + index, &ai.dmaCount, sizeof(ai.dmaCount)); - index += sizeof(ai.dmaCount); - memcpy(res.data() + index, &ai.dmaLen, sizeof(ai.dmaLen)); - index += sizeof(ai.dmaLen); - memcpy(res.data() + index, &ai.dmaAddr, sizeof(ai.dmaAddr)); - index += sizeof(ai.dmaAddr); - memcpy(res.data() + index, &ai.dmaAddrCarry, sizeof(ai.dmaAddrCarry)); - index += sizeof(ai.dmaAddrCarry); - memcpy(res.data() + index, &ai.cycles, sizeof(ai.cycles)); - index += sizeof(ai.cycles); - memcpy(res.data() + index, &ai.dac, sizeof(ai.dac)); - index += sizeof(ai.dac); - memcpy(res.data() + index, &pi, sizeof(PI)); - index += sizeof(PI); - memcpy(res.data() + index, &ri, sizeof(RI)); - index += sizeof(RI); - memcpy(res.data() + index, &si.dramAddr, sizeof(u32)); - index += sizeof(u32); - memcpy(res.data() + index, &si.pifAddr, sizeof(u32)); - index += sizeof(u32); - memcpy(res.data() + index, &si.status, sizeof(SIStatus)); - - res.insert(res.end(), sPIF.begin(), sPIF.end()); - - return res; -} - -void MMIO::Deserialize(const std::vector &data) { - u32 index = 0; - memcpy(&rsp, data.data(), sizeof(RSP)); - index += sizeof(RSP); - memcpy(&rdp.dpc, data.data() + index, sizeof(DPC)); - index += sizeof(DPC); - memcpy(rdp.cmd_buf.data(), data.data() + index, RDP::COMMAND_BUFFER_SIZE); - index += 0xFFFFF; - std::copy_n(data.begin() + index, RDRAM_SIZE, rdp.rdram.begin()); - index += RDRAM_SIZE; - memcpy(&mi, data.data() + index, sizeof(MI)); - index += sizeof(MI); - memcpy(&vi, data.data() + index, sizeof(VI)); - index += sizeof(VI); - memcpy(&ai.dmaEnable, data.data() + index, sizeof(ai.dmaEnable)); - index += sizeof(ai.dmaEnable); - memcpy(&ai.dacRate, data.data() + index, sizeof(ai.dacRate)); - index += sizeof(ai.dacRate); - memcpy(&ai.bitrate, data.data() + index, sizeof(ai.bitrate)); - index += sizeof(ai.bitrate); - memcpy(&ai.dmaCount, data.data() + index, sizeof(ai.dmaCount)); - index += sizeof(ai.dmaCount); - memcpy(&ai.dmaLen, data.data() + index, sizeof(ai.dmaLen)); - index += sizeof(ai.dmaLen); - memcpy(&ai.dmaAddr, data.data() + index, sizeof(ai.dmaAddr)); - index += sizeof(ai.dmaAddr); - memcpy(&ai.dmaAddrCarry, data.data() + index, sizeof(ai.dmaAddrCarry)); - index += sizeof(ai.dmaAddrCarry); - memcpy(&ai.cycles, data.data() + index, sizeof(ai.cycles)); - index += sizeof(ai.cycles); - memcpy(&ai.dac, data.data() + index, sizeof(ai.dac)); - index += sizeof(ai.dac); - memcpy(&pi, data.data() + index, sizeof(PI)); - index += sizeof(PI); - memcpy(&ri, data.data() + index, sizeof(RI)); - index += sizeof(RI); - memcpy(&si.dramAddr, data.data() + index, sizeof(u32)); - index += sizeof(u32); - memcpy(&si.pifAddr, data.data() + index, sizeof(u32)); - index += sizeof(u32); - memcpy(&si.status, data.data() + index, sizeof(SIStatus)); -} } // namespace n64 diff --git a/src/backend/core/MMIO.hpp b/src/backend/core/MMIO.hpp index b61629fc..3d49e58c 100644 --- a/src/backend/core/MMIO.hpp +++ b/src/backend/core/MMIO.hpp @@ -15,10 +15,7 @@ struct Mem; struct Registers; struct MMIO { - MMIO(Mem &mem, Registers ®s, ParallelRDP ¶llel) : - vi(mem, regs), mi(regs), ai(mem, regs), pi(mem, regs), si(mem, regs), rsp(mem, regs), rdp(mem, parallel) { - Reset(); - } + MMIO() { Reset(); } void Reset(); VI vi; @@ -32,7 +29,5 @@ struct MMIO { u32 Read(u32); void Write(u32, u32); - std::vector Serialize(); - void Deserialize(const std::vector &); }; } // namespace n64 diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index 882503ca..05692b8a 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -2,12 +2,12 @@ #include #include #include -#include +#include #include #include namespace n64 { -Mem::Mem(Registers ®s, ParallelRDP ¶llel, JIT *jit) : mmio(*this, regs, parallel), flash(saveData), jit(jit) { +Mem::Mem(JIT *jit) : flash(saveData), jit(jit) { rom.cart.resize(CART_SIZE); std::ranges::fill(rom.cart, 0); } @@ -187,7 +187,8 @@ void Mem::LoadROM(const bool isArchive, const std::string &filename) { } template <> -u8 Mem::Read(Registers ®s, const u32 paddr) { +u8 Mem::Read(const u32 paddr) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); const SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM(paddr); @@ -218,7 +219,8 @@ u8 Mem::Read(Registers ®s, const u32 paddr) { } template <> -u16 Mem::Read(Registers ®s, const u32 paddr) { +u16 Mem::Read(const u32 paddr) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); const SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM(paddr); @@ -242,7 +244,8 @@ u16 Mem::Read(Registers ®s, const u32 paddr) { } template <> -u32 Mem::Read(Registers ®s, const u32 paddr) { +u32 Mem::Read(const u32 paddr) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); const SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM(paddr); @@ -267,7 +270,8 @@ u32 Mem::Read(Registers ®s, const u32 paddr) { } template <> -u64 Mem::Read(Registers ®s, const u32 paddr) { +u64 Mem::Read(const u32 paddr) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); const SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM(paddr); @@ -292,7 +296,8 @@ u64 Mem::Read(Registers ®s, const u32 paddr) { } template <> -void Mem::WriteInterpreter(Registers ®s, u32 paddr, u32 val) { +void Mem::WriteInterpreter(u32 paddr, u32 val) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(paddr, val); return; } @@ -317,7 +322,7 @@ void Mem::WriteInterpreter(Registers ®s, u32 paddr, u32 val) { val = val << (8 * (3 - (paddr & 3))); paddr = (paddr - PIF_RAM_REGION_START) & ~3; Util::WriteAccess(si.pif.ram, paddr, std::byteswap(val)); - si.pif.ProcessCommands(*this); + si.pif.ProcessCommands(); return; } @@ -332,20 +337,21 @@ void Mem::WriteInterpreter(Registers ®s, u32 paddr, u32 val) { #ifndef __aarch64__ template <> -void Mem::WriteJIT(Registers ®s, const u32 paddr, const u32 val) { - WriteInterpreter(regs, paddr, val); +void Mem::WriteJIT(const u32 paddr, const u32 val) { + WriteInterpreter(paddr, val); if (jit) jit->InvalidateBlock(paddr); } #endif template <> -void Mem::Write(Registers ®s, const u32 paddr, const u32 val) { - WriteInterpreter(regs, paddr, val); +void Mem::Write(const u32 paddr, const u32 val) { + WriteInterpreter(paddr, val); } template <> -void Mem::WriteInterpreter(Registers ®s, u32 paddr, u32 val) { +void Mem::WriteInterpreter(u32 paddr, u32 val) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(paddr, val); return; } @@ -370,7 +376,7 @@ void Mem::WriteInterpreter(Registers ®s, u32 paddr, u32 val) { val = val << (16 * !(paddr & 2)); paddr &= ~3; Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val)); - si.pif.ProcessCommands(*this); + si.pif.ProcessCommands(); return; } @@ -385,20 +391,21 @@ void Mem::WriteInterpreter(Registers ®s, u32 paddr, u32 val) { #ifndef __aarch64__ template <> -void Mem::WriteJIT(Registers ®s, const u32 paddr, const u32 val) { - WriteInterpreter(regs, paddr, val); +void Mem::WriteJIT(const u32 paddr, const u32 val) { + WriteInterpreter(paddr, val); if (jit) jit->InvalidateBlock(paddr); } #endif template <> -void Mem::Write(Registers ®s, const u32 paddr, const u32 val) { - WriteInterpreter(regs, paddr, val); +void Mem::Write(const u32 paddr, const u32 val) { + WriteInterpreter(paddr, val); } template <> -void Mem::WriteInterpreter(Registers ®s, const u32 paddr, const u32 val) { +void Mem::WriteInterpreter(const u32 paddr, const u32 val) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(paddr, val); return; } @@ -419,7 +426,7 @@ void Mem::WriteInterpreter(Registers ®s, const u32 paddr, const u32 val) if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val)); - si.pif.ProcessCommands(*this); + si.pif.ProcessCommands(); return; } @@ -434,29 +441,30 @@ void Mem::WriteInterpreter(Registers ®s, const u32 paddr, const u32 val) #ifndef __aarch64__ template <> -void Mem::WriteJIT(Registers ®s, const u32 paddr, const u32 val) { - WriteInterpreter(regs, paddr, val); +void Mem::WriteJIT(const u32 paddr, const u32 val) { + WriteInterpreter(paddr, val); if (jit) jit->InvalidateBlock(paddr); } #endif template <> -void Mem::Write(Registers ®s, const u32 paddr, const u32 val) { - WriteInterpreter(regs, paddr, val); +void Mem::Write(const u32 paddr, const u32 val) { + WriteInterpreter(paddr, val); } #ifndef __aarch64__ -void Mem::WriteJIT(const Registers ®s, const u32 paddr, const u64 val) { - WriteInterpreter(regs, paddr, val); +void Mem::WriteJIT(const const u32 paddr, const u64 val) { + WriteInterpreter(paddr, val); if (jit) jit->InvalidateBlock(paddr); } #endif -void Mem::Write(const Registers ®s, const u32 paddr, const u64 val) { WriteInterpreter(regs, paddr, val); } +void Mem::Write(const u32 paddr, const u64 val) { WriteInterpreter(paddr, val); } -void Mem::WriteInterpreter(const Registers ®s, const u32 paddr, u64 val) { +void Mem::WriteInterpreter(const u32 paddr, u64 val) { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); SI &si = mmio.si; if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM(paddr, val); return; } @@ -478,7 +486,7 @@ void Mem::WriteInterpreter(const Registers ®s, const u32 paddr, u64 val) { if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val)); - si.pif.ProcessCommands(*this); + si.pif.ProcessCommands(); return; } @@ -575,25 +583,4 @@ void Mem::BackupWrite(const u32 addr, const u8 val) { panic("Backup read word with unknown save type"); } } - -std::vector Mem::Serialize() { - std::vector res{}; - - auto sMMIO = mmio.Serialize(); - auto sFLASH = flash.Serialize(); - mmioSize = sMMIO.size(); - flashSize = sFLASH.size(); - - res.insert(res.begin(), sMMIO.begin(), sMMIO.end()); - res.insert(res.end(), sFLASH.begin(), sFLASH.end()); - res.insert(res.end(), saveData.begin(), saveData.end()); - - return res; -} - -void Mem::Deserialize(const std::vector &data) { - mmio.Deserialize(std::vector(data.begin(), data.begin() + mmioSize)); - flash.Deserialize(std::vector(data.begin() + mmioSize, data.begin() + mmioSize + flashSize)); - memcpy(saveData.data(), data.data() + mmioSize + flashSize, saveData.size()); -} } // namespace n64 diff --git a/src/backend/core/Mem.hpp b/src/backend/core/Mem.hpp index f7c565a7..f254a43a 100644 --- a/src/backend/core/Mem.hpp +++ b/src/backend/core/Mem.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include #include #include #include @@ -70,17 +69,17 @@ struct Flash { void CommandSetWriteOffs(u32); void CommandWrite(); void CommandRead(); - std::vector Serialize(); - void Deserialize(const std::vector &data); template void Write(u32 index, T val); template T Read(u32 index) const; }; +struct JIT; + struct Mem { ~Mem() = default; - Mem(Registers &, ParallelRDP &, JIT * = nullptr); + Mem(JIT * = nullptr); void Reset(); void LoadSRAM(SaveType, fs::path); static std::vector OpenROM(const std::string &, size_t &); @@ -90,14 +89,11 @@ struct Mem { [[nodiscard]] auto GetRDRAM() -> std::vector & { return mmio.rdp.rdram; } - std::vector Serialize(); - void Deserialize(const std::vector &); - template - T Read(Registers &, u32); + T Read(u32); template - void Write(Registers &, u32, u32); - void Write(const Registers &, u32, u64); + void Write(u32, u32); + void Write(u32, u64); template T BackupRead(u32); @@ -133,11 +129,11 @@ struct Mem { private: template - void WriteInterpreter(Registers &, u32, u32); - void WriteInterpreter(const Registers &, u32, u64); + void WriteInterpreter(u32, u32); + void WriteInterpreter(u32, u64); template - void WriteJIT(Registers &, u32, u32); - void WriteJIT(const Registers &, u32, u64); + void WriteJIT(u32, u32); + void WriteJIT(u32, u64); JIT *jit = nullptr; friend struct SI; diff --git a/src/backend/core/RDP.cpp b/src/backend/core/RDP.cpp index a2bc6773..8ccf15f1 100644 --- a/src/backend/core/RDP.cpp +++ b/src/backend/core/RDP.cpp @@ -1,15 +1,11 @@ -#include -#include #include #include -#include +#include namespace n64 { -RDP::RDP(Mem &mem, ParallelRDP ¶llel) : mem(mem), parallel(parallel) { +RDP::RDP() { rdram.resize(RDRAM_SIZE); - std::ranges::fill(rdram, 0); - std::ranges::fill(cmd_buf, 0); - dpc.status.raw = 0x80; + Reset(); } void RDP::Reset() { @@ -201,6 +197,8 @@ FORCE_INLINE void logCommand(u8 cmd) { */ void RDP::RunCommand() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); + ParallelRDP& parallel = n64::Core::GetInstance().parallel; if (dpc.status.freeze) { return; } @@ -287,6 +285,9 @@ void RDP::RunCommand() { } void RDP::OnFullSync() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); + ParallelRDP& parallel = n64::Core::GetInstance().parallel; + parallel.OnFullSync(); dpc.status.pipeBusy = false; diff --git a/src/backend/core/RDP.hpp b/src/backend/core/RDP.hpp index 95837b46..c0c13d53 100644 --- a/src/backend/core/RDP.hpp +++ b/src/backend/core/RDP.hpp @@ -3,14 +3,8 @@ #include #include -class ParallelRDP; - namespace n64 { -struct RSP; -struct Mem; -struct Registers; - union DPCStatusWrite { u32 raw; struct { @@ -59,7 +53,7 @@ struct RDP { DPC dpc{}; std::array cmd_buf{}; - RDP(Mem &, ParallelRDP &); + RDP(); void Reset(); [[nodiscard]] auto Read(u32 addr) const -> u32; @@ -93,8 +87,5 @@ private: friend struct Mem; friend struct MMIO; std::vector rdram{}; - - Mem &mem; - ParallelRDP ∥ }; } // namespace n64 diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index 3de0eadf..f4345092 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -1,10 +1,8 @@ -#include -#include -#include +#include #include namespace n64 { -RSP::RSP(Mem &mem, Registers ®s) : regs(regs), mem(mem) { Reset(); } +RSP::RSP() { Reset(); } void RSP::Reset() { lastSuccessfulSPAddr.raw = 0; @@ -90,6 +88,8 @@ auto RSP::Read(const u32 addr) -> u32 { } void RSP::WriteStatus(const u32 value) { + Mem& mem = Core::GetInstance().cpu->GetMem(); + Registers& regs = Core::GetInstance().cpu->GetRegs(); MI &mi = mem.mmio.mi; const auto write = SPStatusWrite{.raw = value}; if (write.clearHalt && !write.setHalt) { @@ -130,6 +130,7 @@ void RSP::WriteStatus(const u32 value) { template <> void RSP::DMA() { + Mem& mem = Core::GetInstance().cpu->GetMem(); u32 length = spDMALen.len + 1; length = (length + 0x7) & ~0x7; @@ -162,6 +163,7 @@ void RSP::DMA() { template <> void RSP::DMA() { + Mem& mem = Core::GetInstance().cpu->GetMem(); u32 length = spDMALen.len + 1; length = (length + 0x7) & ~0x7; diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index af6cc012..d220042e 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -118,7 +118,7 @@ struct Registers; #define DE(x) (((x) >> 11) & 0x1F) struct RSP { - RSP(Mem &, Registers &); + RSP(); void Reset(); FORCE_INLINE void Step() { @@ -369,8 +369,6 @@ struct RSP { void WriteStatus(u32 value); private: - Registers ®s; - Mem &mem; FORCE_INLINE void branch(const u16 address, const bool cond) { if (cond) { nextPC = address & 0xFFC; diff --git a/src/backend/core/interpreter/cop0instructions.cpp b/src/backend/core/interpreter/cop0instructions.cpp index 170f75ed..482b8e3b 100644 --- a/src/backend/core/interpreter/cop0instructions.cpp +++ b/src/backend/core/interpreter/cop0instructions.cpp @@ -1,18 +1,30 @@ -#include -#include +#include #include #include namespace n64 { -void Cop0::mtc0(const u32 instr) { SetReg32(RD(instr), regs.Read(RT(instr))); } +void Cop0::mtc0(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); + SetReg32(RD(instr), regs.Read(RT(instr))); +} -void Cop0::dmtc0(const u32 instr) { SetReg64(RD(instr), regs.Read(RT(instr))); } +void Cop0::dmtc0(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); + SetReg64(RD(instr), regs.Read(RT(instr))); +} -void Cop0::mfc0(const u32 instr) { regs.Write(RT(instr), s32(GetReg32(RD(instr)))); } +void Cop0::mfc0(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); + regs.Write(RT(instr), s32(GetReg32(RD(instr)))); +} -void Cop0::dmfc0(const u32 instr) const { regs.Write(RT(instr), s64(GetReg64(RD(instr)))); } +void Cop0::dmfc0(const u32 instr) const { + Registers& regs = Core::GetInstance().cpu->GetRegs(); + regs.Write(RT(instr), s64(GetReg64(RD(instr)))); +} void Cop0::eret() { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (status.erl) { regs.SetPC64(ErrorEPC); status.erl = false; diff --git a/src/backend/core/interpreter/cop1instructions.cpp b/src/backend/core/interpreter/cop1instructions.cpp index c4f980e7..153ea933 100644 --- a/src/backend/core/interpreter/cop1instructions.cpp +++ b/src/backend/core/interpreter/cop1instructions.cpp @@ -1,8 +1,6 @@ #include #include -#include -#include -#include +#include #include namespace n64 { @@ -134,6 +132,7 @@ bool Cop1::isqnan(const double f) { template <> bool Cop1::CheckCVTArg(const float f) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -154,6 +153,7 @@ bool Cop1::CheckCVTArg(const float f) { template <> bool Cop1::CheckCVTArg(const double f) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -174,6 +174,7 @@ bool Cop1::CheckCVTArg(const double f) { template <> bool Cop1::CheckCVTArg(const float f) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -194,6 +195,7 @@ bool Cop1::CheckCVTArg(const float f) { template <> bool Cop1::CheckCVTArg(const double f) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -214,6 +216,7 @@ bool Cop1::CheckCVTArg(const double f) { template bool Cop1::CheckArg(const T f) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); switch (std::fpclassify(f)) { case FP_SUBNORMAL: SetCauseUnimplemented(); @@ -231,6 +234,7 @@ bool Cop1::CheckArg(const T f) { template bool Cop1::CheckArgs(const T f1, const T f2) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); auto class1 = std::fpclassify(f1), class2 = std::fpclassify(f2); if ((class1 == FP_NAN && !isqnan(f1)) || (class2 == FP_NAN && !isqnan(f2))) { SetCauseUnimplemented(); @@ -256,6 +260,7 @@ bool Cop1::CheckArgs(const T f1, const T f2) { template bool Cop1::CheckFPUUsable() { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if constexpr (preserveCause) { if (!regs.cop0.status.cu1) { regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 1, regs.oldPC); @@ -290,6 +295,7 @@ FORCE_INLINE T FlushResult(T f, const u32 round) { template <> bool Cop1::CheckResult(float &f) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); switch (std::fpclassify(f)) { case FP_SUBNORMAL: if (!fcr31.fs || fcr31.enable.underflow || fcr31.enable.inexact_operation) { @@ -312,6 +318,7 @@ bool Cop1::CheckResult(float &f) { template <> bool Cop1::CheckResult(double &f) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); switch (std::fpclassify(f)) { case FP_SUBNORMAL: if (!fcr31.fs || fcr31.enable.underflow || fcr31.enable.inexact_operation) { @@ -334,6 +341,7 @@ bool Cop1::CheckResult(double &f) { template bool Cop1::TestExceptions() { + Registers& regs = Core::GetInstance().cpu->GetRegs(); const u32 exc = std::fetestexcept(FE_ALL_EXCEPT); if (!exc) @@ -437,6 +445,7 @@ bool Cop1::SetCauseInvalid() { #define CHECK_FPE_CONV_CONST(type, res, operation) CHECK_FPE_IMPL_CONST(type, res, operation, true) void Cop1::absd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -449,6 +458,7 @@ void Cop1::absd(const u32 instr) { } void Cop1::abss(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -461,6 +471,7 @@ void Cop1::abss(const u32 instr) { } void Cop1::adds(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -474,6 +485,7 @@ void Cop1::adds(const u32 instr) { } void Cop1::addd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -487,6 +499,7 @@ void Cop1::addd(const u32 instr) { } void Cop1::ceills(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -497,6 +510,7 @@ void Cop1::ceills(const u32 instr) { } void Cop1::ceilld(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -507,6 +521,7 @@ void Cop1::ceilld(const u32 instr) { } void Cop1::ceilws(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -517,6 +532,7 @@ void Cop1::ceilws(const u32 instr) { } void Cop1::ceilwd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -527,6 +543,7 @@ void Cop1::ceilwd(const u32 instr) { } void Cop1::cfc1(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const u8 fd = RD(instr); @@ -545,6 +562,7 @@ void Cop1::cfc1(const u32 instr) { } void Cop1::ctc1(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const u8 fs = RD(instr); @@ -592,6 +610,7 @@ void Cop1::ctc1(const u32 instr) { } void Cop1::cvtds(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -604,6 +623,7 @@ void Cop1::cvtds(const u32 instr) { } void Cop1::cvtsd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -616,6 +636,7 @@ void Cop1::cvtsd(const u32 instr) { } void Cop1::cvtsw(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -626,6 +647,7 @@ void Cop1::cvtsw(const u32 instr) { } void Cop1::cvtsl(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -641,6 +663,7 @@ void Cop1::cvtsl(const u32 instr) { } void Cop1::cvtwd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -651,6 +674,7 @@ void Cop1::cvtwd(const u32 instr) { } void Cop1::cvtws(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -661,6 +685,7 @@ void Cop1::cvtws(const u32 instr) { } void Cop1::cvtls(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -671,6 +696,7 @@ void Cop1::cvtls(const u32 instr) { } void Cop1::cvtdw(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -681,6 +707,7 @@ void Cop1::cvtdw(const u32 instr) { } void Cop1::cvtdl(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; @@ -698,6 +725,7 @@ void Cop1::cvtdl(const u32 instr) { } void Cop1::cvtld(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -709,6 +737,7 @@ void Cop1::cvtld(const u32 instr) { template bool Cop1::XORDERED(const T fs, const T ft) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (std::isnan(fs) || std::isnan(ft)) { if (std::isnan(fs) && (!quiet || isqnan(fs)) && SetCauseInvalid()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); @@ -730,6 +759,7 @@ bool Cop1::XORDERED(const T fs, const T ft) { template void Cop1::cf(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; @@ -741,6 +771,7 @@ void Cop1::cf(const u32 instr) { template void Cop1::cun(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -751,6 +782,7 @@ void Cop1::cun(const u32 instr) { template void Cop1::ceq(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -762,6 +794,7 @@ void Cop1::ceq(const u32 instr) { template void Cop1::cueq(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -773,6 +806,7 @@ void Cop1::cueq(const u32 instr) { template void Cop1::colt(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -784,6 +818,7 @@ void Cop1::colt(const u32 instr) { template void Cop1::cult(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -795,6 +830,7 @@ void Cop1::cult(const u32 instr) { template void Cop1::cole(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -806,6 +842,7 @@ void Cop1::cole(const u32 instr) { template void Cop1::cule(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -817,6 +854,7 @@ void Cop1::cule(const u32 instr) { template void Cop1::csf(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -827,6 +865,7 @@ void Cop1::csf(const u32 instr) { template void Cop1::cngle(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -837,6 +876,7 @@ void Cop1::cngle(const u32 instr) { template void Cop1::cseq(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -848,6 +888,7 @@ void Cop1::cseq(const u32 instr) { template void Cop1::cngl(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -859,6 +900,7 @@ void Cop1::cngl(const u32 instr) { template void Cop1::clt(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -870,6 +912,7 @@ void Cop1::clt(const u32 instr) { template void Cop1::cnge(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -881,6 +924,7 @@ void Cop1::cnge(const u32 instr) { template void Cop1::cle(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -892,6 +936,7 @@ void Cop1::cle(const u32 instr) { template void Cop1::cngt(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const T fs = FGR_S(regs.cop0.status, FS(instr)); @@ -935,6 +980,7 @@ template void Cop1::cle(u32 instr); template void Cop1::cngt(u32 instr); void Cop1::divs(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -948,6 +994,7 @@ void Cop1::divs(const u32 instr) { } void Cop1::divd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -961,6 +1008,7 @@ void Cop1::divd(const u32 instr) { } void Cop1::muls(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -974,6 +1022,7 @@ void Cop1::muls(const u32 instr) { } void Cop1::muld(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -987,6 +1036,7 @@ void Cop1::muld(const u32 instr) { } void Cop1::subs(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1000,6 +1050,7 @@ void Cop1::subs(const u32 instr) { } void Cop1::subd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1015,12 +1066,14 @@ void Cop1::subd(const u32 instr) { void Cop1::movs(const u32 instr) { movd(instr); } void Cop1::movd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; FGR_D(regs.cop0.status, FD(instr)) = FGR_S(regs.cop0.status, FS(instr)); } void Cop1::negs(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1033,6 +1086,7 @@ void Cop1::negs(const u32 instr) { } void Cop1::negd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1045,6 +1099,7 @@ void Cop1::negd(const u32 instr) { } void Cop1::sqrts(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1057,6 +1112,7 @@ void Cop1::sqrts(const u32 instr) { } void Cop1::sqrtd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1069,6 +1125,7 @@ void Cop1::sqrtd(const u32 instr) { } void Cop1::roundls(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1083,6 +1140,7 @@ void Cop1::roundls(const u32 instr) { } void Cop1::roundld(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1097,6 +1155,7 @@ void Cop1::roundld(const u32 instr) { } void Cop1::roundws(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1111,6 +1170,7 @@ void Cop1::roundws(const u32 instr) { } void Cop1::roundwd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1125,6 +1185,7 @@ void Cop1::roundwd(const u32 instr) { } void Cop1::floorls(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1135,6 +1196,7 @@ void Cop1::floorls(const u32 instr) { } void Cop1::floorld(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1145,6 +1207,7 @@ void Cop1::floorld(const u32 instr) { } void Cop1::floorws(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1155,6 +1218,7 @@ void Cop1::floorws(const u32 instr) { } void Cop1::floorwd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1165,6 +1229,7 @@ void Cop1::floorwd(const u32 instr) { } void Cop1::truncws(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1179,6 +1244,7 @@ void Cop1::truncws(const u32 instr) { } void Cop1::truncwd(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1193,6 +1259,7 @@ void Cop1::truncwd(const u32 instr) { } void Cop1::truncls(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1207,6 +1274,7 @@ void Cop1::truncls(const u32 instr) { } void Cop1::truncld(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; const auto fs = FGR_S(regs.cop0.status, FS(instr)); @@ -1220,53 +1288,62 @@ void Cop1::truncld(const u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::lwc1(Mem &mem, u32 instr) { +void Cop1::lwc1(u32 instr) { + Mem& mem = Core::GetInstance().cpu->GetMem(); + Registers& regs = Core::GetInstance().cpu->GetRegs(); const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { regs.cop0.HandleTLBException(addr); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - const u32 data = mem.Read(regs, physical); + const u32 data = mem.Read(physical); FGR_T(regs.cop0.status, FT(instr)) = data; } } -void Cop1::swc1(Mem &mem, u32 instr) { +void Cop1::swc1(u32 instr) { + Mem& mem = Core::GetInstance().cpu->GetMem(); + Registers& regs = Core::GetInstance().cpu->GetRegs(); const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { regs.cop0.HandleTLBException(addr); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, physical, FGR_T(regs.cop0.status, FT(instr))); + mem.Write(physical, FGR_T(regs.cop0.status, FT(instr))); } } -void Cop1::ldc1(Mem &mem, u32 instr) { +void Cop1::ldc1(u32 instr) { + Mem& mem = Core::GetInstance().cpu->GetMem(); + Registers& regs = Core::GetInstance().cpu->GetRegs(); const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { regs.cop0.HandleTLBException(addr); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - const u64 data = mem.Read(regs, physical); + const u64 data = mem.Read(physical); FGR_T(regs.cop0.status, FT(instr)) = data; } } -void Cop1::sdc1(Mem &mem, u32 instr) { +void Cop1::sdc1(u32 instr) { + Mem& mem = Core::GetInstance().cpu->GetMem(); + Registers& regs = Core::GetInstance().cpu->GetRegs(); const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { regs.cop0.HandleTLBException(addr); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, physical, FGR_T(regs.cop0.status, FT(instr))); + mem.Write(physical, FGR_T(regs.cop0.status, FT(instr))); } } void Cop1::unimplemented() { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; SetCauseUnimplemented(); @@ -1274,24 +1351,28 @@ void Cop1::unimplemented() { } void Cop1::mfc1(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; regs.Write(RT(instr), FGR_T(regs.cop0.status, FS(instr))); } void Cop1::dmfc1(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; regs.Write(RT(instr), FGR_S(regs.cop0.status, FS(instr))); } void Cop1::mtc1(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; FGR_T(regs.cop0.status, FS(instr)) = regs.Read(RT(instr)); } void Cop1::dmtc1(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); if (!CheckFPUUsable()) return; FGR_S(regs.cop0.status, FS(instr)) = regs.Read(RT(instr)); diff --git a/src/backend/core/interpreter/decode.cpp b/src/backend/core/interpreter/decode.cpp index b6be45ee..4a904a9a 100644 --- a/src/backend/core/interpreter/decode.cpp +++ b/src/backend/core/interpreter/decode.cpp @@ -418,13 +418,13 @@ void Interpreter::Exec(const u32 instr) { ll(instr); break; case LWC1: - regs.cop1.lwc1(mem, instr); + regs.cop1.lwc1(instr); break; case LLD: lld(instr); break; case LDC1: - regs.cop1.ldc1(mem, instr); + regs.cop1.ldc1(instr); break; case LD: ld(instr); @@ -433,13 +433,13 @@ void Interpreter::Exec(const u32 instr) { sc(instr); break; case SWC1: - regs.cop1.swc1(mem, instr); + regs.cop1.swc1(instr); break; case SCD: scd(instr); break; case SDC1: - regs.cop1.sdc1(mem, instr); + regs.cop1.sdc1(instr); break; case SD: sd(instr); diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index 035b9ada..9f3e879b 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -1,4 +1,4 @@ -#include +#include #define check_signed_overflow(op1, op2, res) (((~((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1) #define check_signed_underflow(op1, op2, res) (((((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1) @@ -194,7 +194,7 @@ void Interpreter::lb(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - regs.Write(RT(instr), (s8)mem.Read(regs, paddr)); + regs.Write(RT(instr), (s8)mem.Read(paddr)); } } @@ -211,7 +211,7 @@ void Interpreter::lh(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - regs.Write(RT(instr), (s16)mem.Read(regs, paddr)); + regs.Write(RT(instr), (s16)mem.Read(paddr)); } } @@ -229,7 +229,7 @@ void Interpreter::lw(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - regs.Write(RT(instr), (s32)mem.Read(regs, physical)); + regs.Write(RT(instr), (s32)mem.Read(physical)); } } @@ -240,7 +240,7 @@ void Interpreter::ll(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - const s32 result = mem.Read(regs, physical); + const s32 result = mem.Read(physical); if (check_address_error(0b11, address)) { regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; @@ -262,7 +262,7 @@ void Interpreter::lwl(const u32 instr) { } else { const u32 shift = 8 * ((address ^ 0) & 3); const u32 mask = 0xFFFFFFFF << shift; - const u32 data = mem.Read(regs, paddr & ~3); + const u32 data = mem.Read(paddr & ~3); const s32 result = s32((regs.Read(RT(instr)) & ~mask) | (data << shift)); regs.Write(RT(instr), result); } @@ -277,7 +277,7 @@ void Interpreter::lwr(const u32 instr) { } else { const u32 shift = 8 * ((address ^ 3) & 3); const u32 mask = 0xFFFFFFFF >> shift; - const u32 data = mem.Read(regs, paddr & ~3); + const u32 data = mem.Read(paddr & ~3); const s32 result = s32((regs.Read(RT(instr)) & ~mask) | (data >> shift)); regs.Write(RT(instr), result); } @@ -296,7 +296,7 @@ void Interpreter::ld(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - const s64 value = mem.Read(regs, paddr); + const s64 value = mem.Read(paddr); regs.Write(RT(instr), value); } } @@ -316,7 +316,7 @@ void Interpreter::lld(const u32 instr) { if (check_address_error(0b111, address)) { regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); } else { - regs.Write(RT(instr), mem.Read(regs, paddr)); + regs.Write(RT(instr), mem.Read(paddr)); regs.cop0.llbit = true; regs.cop0.LLAddr = paddr >> 4; } @@ -332,7 +332,7 @@ void Interpreter::ldl(const u32 instr) { } else { const s32 shift = 8 * ((address ^ 0) & 7); const u64 mask = 0xFFFFFFFFFFFFFFFF << shift; - const u64 data = mem.Read(regs, paddr & ~7); + const u64 data = mem.Read(paddr & ~7); const s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data << shift)); regs.Write(RT(instr), result); } @@ -347,7 +347,7 @@ void Interpreter::ldr(const u32 instr) { } else { const s32 shift = 8 * ((address ^ 7) & 7); const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; - const u64 data = mem.Read(regs, paddr & ~7); + const u64 data = mem.Read(paddr & ~7); const s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data >> shift)); regs.Write(RT(instr), result); } @@ -360,7 +360,7 @@ void Interpreter::lbu(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - const u8 value = mem.Read(regs, paddr); + const u8 value = mem.Read(paddr); regs.Write(RT(instr), value); } } @@ -377,7 +377,7 @@ void Interpreter::lhu(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - const u16 value = mem.Read(regs, paddr); + const u16 value = mem.Read(paddr); regs.Write(RT(instr), value); } } @@ -395,7 +395,7 @@ void Interpreter::lwu(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - const u32 value = mem.Read(regs, paddr); + const u32 value = mem.Read(paddr); regs.Write(RT(instr), value); } } @@ -407,7 +407,7 @@ void Interpreter::sb(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, paddr, regs.Read(RT(instr))); + mem.Write(paddr, regs.Read(RT(instr))); } } @@ -430,7 +430,7 @@ void Interpreter::sc(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, paddr, regs.Read(RT(instr))); + mem.Write(paddr, regs.Read(RT(instr))); regs.Write(RT(instr), 1); } } else { @@ -462,7 +462,7 @@ void Interpreter::scd(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, paddr, regs.Read(RT(instr))); + mem.Write(paddr, regs.Read(RT(instr))); regs.Write(RT(instr), 1); } } else { @@ -478,7 +478,7 @@ void Interpreter::sh(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, physical, regs.Read(RT(instr))); + mem.Write(physical, regs.Read(RT(instr))); } } @@ -496,7 +496,7 @@ void Interpreter::sw(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, physical, regs.Read(RT(instr))); + mem.Write(physical, regs.Read(RT(instr))); } } @@ -513,7 +513,7 @@ void Interpreter::sd(const u32 instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - mem.Write(regs, physical, regs.Read(RT(instr))); + mem.Write(physical, regs.Read(RT(instr))); } } @@ -526,9 +526,9 @@ void Interpreter::sdl(const u32 instr) { } else { const s32 shift = 8 * ((address ^ 0) & 7); const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; - const u64 data = mem.Read(regs, paddr & ~7); + const u64 data = mem.Read(paddr & ~7); const u64 rt = regs.Read(RT(instr)); - mem.Write(regs, paddr & ~7, (data & ~mask) | (rt >> shift)); + mem.Write(paddr & ~7, (data & ~mask) | (rt >> shift)); } } @@ -541,9 +541,9 @@ void Interpreter::sdr(const u32 instr) { } else { const s32 shift = 8 * ((address ^ 7) & 7); const u64 mask = 0xFFFFFFFFFFFFFFFF << shift; - const u64 data = mem.Read(regs, paddr & ~7); + const u64 data = mem.Read(paddr & ~7); const u64 rt = regs.Read(RT(instr)); - mem.Write(regs, paddr & ~7, (data & ~mask) | (rt << shift)); + mem.Write(paddr & ~7, (data & ~mask) | (rt << shift)); } } @@ -556,9 +556,9 @@ void Interpreter::swl(const u32 instr) { } else { const u32 shift = 8 * ((address ^ 0) & 3); const u32 mask = 0xFFFFFFFF >> shift; - const u32 data = mem.Read(regs, paddr & ~3); + const u32 data = mem.Read(paddr & ~3); const u32 rt = regs.Read(RT(instr)); - mem.Write(regs, paddr & ~3, (data & ~mask) | (rt >> shift)); + mem.Write(paddr & ~3, (data & ~mask) | (rt >> shift)); } } @@ -571,9 +571,9 @@ void Interpreter::swr(const u32 instr) { } else { const u32 shift = 8 * ((address ^ 3) & 3); const u32 mask = 0xFFFFFFFF << shift; - const u32 data = mem.Read(regs, paddr & ~3); + const u32 data = mem.Read(paddr & ~3); const u32 rt = regs.Read(RT(instr)); - mem.Write(regs, paddr & ~3, (data & ~mask) | (rt << shift)); + mem.Write(paddr & ~3, (data & ~mask) | (rt << shift)); } } @@ -824,8 +824,9 @@ void Interpreter::mtlo(const u32 instr) { regs.lo = regs.Read(RS(instr)); } void Interpreter::mthi(const u32 instr) { regs.hi = regs.Read(RS(instr)); } void Interpreter::trap(const bool cond) const { + Cop0& cop0 = Core::GetInstance().cpu->GetRegs().cop0; if (cond) { - regs.cop0.FireException(ExceptionCode::Trap, 0, regs.oldPC); + cop0.FireException(ExceptionCode::Trap, 0, regs.oldPC); } } diff --git a/src/backend/core/jit/instructions.cpp b/src/backend/core/jit/instructions.cpp index be63f900..092e386a 100644 --- a/src/backend/core/jit/instructions.cpp +++ b/src/backend/core/jit/instructions.cpp @@ -958,7 +958,7 @@ void JIT::ldc1(u32 instr) { // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); panic("[JIT]: Unhandled TLBL exception in LD1!"); } else { - const u64 data = mem.Read(regs, physical); + const u64 data = mem.Read(physical); regs.cop1.FGR_T(regs.cop0.status, FT(instr)) = data; regs.cop1.fgrIsConstant[FT(instr)] = true; } @@ -979,7 +979,7 @@ void JIT::ldl(u32 instr) { panic("[JIT]: Implement constant LDL!"); const s32 shift = 8 * ((address ^ 0) & 7); const u64 mask = 0xFFFFFFFFFFFFFFFF << shift; - const u64 data = mem.Read(regs, paddr & ~7); + const u64 data = mem.Read(paddr & ~7); const s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data << shift)); regs.Write(RT(instr), result); } @@ -999,7 +999,7 @@ void JIT::ldr(u32 instr) { } else { const s32 shift = 8 * ((address ^ 7) & 7); const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; - const u64 data = mem.Read(regs, paddr & ~7); + const u64 data = mem.Read(paddr & ~7); const s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data >> shift)); regs.Write(RT(instr), result); } diff --git a/src/backend/core/mem/Flash.cpp b/src/backend/core/mem/Flash.cpp index c0394780..ea9cffe3 100644 --- a/src/backend/core/mem/Flash.cpp +++ b/src/backend/core/mem/Flash.cpp @@ -107,38 +107,6 @@ void Flash::CommandRead() { status = 0x11118004F0000000; } -std::vector Flash::Serialize() { - std::vector res{}; - - res.resize(sizeof(state) + sizeof(status) + sizeof(eraseOffs) + sizeof(writeOffs) + 128); - - u32 index = 0; - memcpy(res.data() + index, &state, sizeof(state)); - index += sizeof(state); - memcpy(res.data() + index, &status, sizeof(status)); - index += sizeof(status); - memcpy(res.data() + index, &eraseOffs, sizeof(eraseOffs)); - index += sizeof(eraseOffs); - memcpy(res.data() + index, &writeOffs, sizeof(writeOffs)); - index += sizeof(writeOffs); - std::ranges::copy(writeBuf, res.begin() + index); - - return res; -} - -void Flash::Deserialize(const std::vector &data) { - u32 index = 0; - memcpy(&state, data.data() + index, sizeof(state)); - index += sizeof(state); - memcpy(&status, data.data() + index, sizeof(status)); - index += sizeof(status); - memcpy(&eraseOffs, data.data() + index, sizeof(eraseOffs)); - index += sizeof(eraseOffs); - memcpy(&writeOffs, data.data() + index, sizeof(writeOffs)); - index += sizeof(writeOffs); - std::copy(data.begin() + index, data.begin() + index + 128, writeBuf.begin()); -} - template <> void Flash::Write(u32 index, u32 val) { if (index > 0) { diff --git a/src/backend/core/mmio/AI.cpp b/src/backend/core/mmio/AI.cpp index 647d8424..42b9624a 100644 --- a/src/backend/core/mmio/AI.cpp +++ b/src/backend/core/mmio/AI.cpp @@ -1,10 +1,8 @@ -#include -#include -#include +#include #include namespace n64 { -AI::AI(Mem &mem, Registers ®s) : mem(mem), regs(regs) {} +AI::AI() { Reset(); } void AI::Reset() { dmaEnable = false; @@ -37,6 +35,7 @@ auto AI::Read(const u32 addr) const -> u32 { } void AI::Write(const u32 addr, const u32 val) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (addr) { case 0x04500000: if (dmaCount < 2) { @@ -81,6 +80,7 @@ void AI::Write(const u32 addr, const u32 val) { } void AI::Step(const u32 cpuCycles, const float volumeL, const float volumeR) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); cycles += cpuCycles; while (cycles > dac.period) { if (dmaCount == 0) { diff --git a/src/backend/core/mmio/AI.hpp b/src/backend/core/mmio/AI.hpp index 2ac3abec..8c46d378 100644 --- a/src/backend/core/mmio/AI.hpp +++ b/src/backend/core/mmio/AI.hpp @@ -3,11 +3,8 @@ #include namespace n64 { -struct Mem; -struct Registers; - struct AI { - AI(Mem &, Registers ®s); + AI(); void Reset(); auto Read(u32) const -> u32; void Write(u32, u32); @@ -27,9 +24,5 @@ struct AI { u32 period{N64_CPU_FREQ / freq}; u32 precision{16}; } dac; - -private: - Mem &mem; - Registers ®s; }; } // namespace n64 diff --git a/src/backend/core/mmio/Interrupt.cpp b/src/backend/core/mmio/Interrupt.cpp index 634081d0..3a025248 100644 --- a/src/backend/core/mmio/Interrupt.cpp +++ b/src/backend/core/mmio/Interrupt.cpp @@ -1,5 +1,4 @@ -#include -#include +#include namespace n64 { void MI::InterruptRaise(const Interrupt intr) { @@ -53,6 +52,7 @@ void MI::InterruptLower(const Interrupt intr) { } void MI::UpdateInterrupt() const { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); const bool interrupt = miIntr.raw & miIntrMask.raw; regs.cop0.cause.ip2 = interrupt; } diff --git a/src/backend/core/mmio/MI.cpp b/src/backend/core/mmio/MI.cpp index 0ff5a814..2d2df50e 100644 --- a/src/backend/core/mmio/MI.cpp +++ b/src/backend/core/mmio/MI.cpp @@ -5,7 +5,7 @@ #define MI_VERSION_REG 0x02020102 namespace n64 { -MI::MI(Registers ®s) : regs(regs) { Reset(); } +MI::MI() { Reset(); } void MI::Reset() { miIntrMask.raw = 0; diff --git a/src/backend/core/mmio/MI.hpp b/src/backend/core/mmio/MI.hpp index c1912971..01f7388a 100644 --- a/src/backend/core/mmio/MI.hpp +++ b/src/backend/core/mmio/MI.hpp @@ -16,12 +16,10 @@ union MIIntr { u32 raw; }; -struct Registers; - struct MI { enum class Interrupt : u8 { VI, SI, PI, AI, DP, SP }; - explicit MI(Registers &); + explicit MI(); void Reset(); [[nodiscard]] auto Read(u32) const -> u32; void Write(u32, u32); @@ -31,6 +29,5 @@ struct MI { u32 miMode{}; MIIntr miIntr{}, miIntrMask{}; - Registers ®s; }; } // namespace n64 diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index 61830a07..e7c70a11 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -5,7 +5,7 @@ #include namespace n64 { -PI::PI(Mem &mem, Registers ®s) : mem(mem), regs(regs) { Reset(); } +PI::PI() { Reset(); } void PI::Reset() { dmaBusy = false; @@ -37,6 +37,7 @@ bool PI::WriteLatch(u32 value) { } bool PI::ReadLatch() { + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); if (ioBusy) [[unlikely]] { ioBusy = false; regs.CpuStall(Scheduler::GetInstance().Remove(PI_BUS_WRITE_COMPLETE)); @@ -47,6 +48,7 @@ bool PI::ReadLatch() { template <> auto PI::BusRead(u32 addr) -> u8 { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (addr) { case REGION_PI_UNKNOWN: panic("Reading byte from address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN - This is the N64DD, " @@ -81,6 +83,7 @@ auto PI::BusRead(u32 addr) -> u8 { template <> auto PI::BusRead(u32 addr) -> u8 { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); if (!ReadLatch()) [[unlikely]] { return latch >> 24; } @@ -120,6 +123,7 @@ auto PI::BusRead(u32 addr) -> u8 { template <> void PI::BusWrite(u32 addr, u32 val) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (addr) { case REGION_PI_UNKNOWN: panic("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", val, addr); @@ -157,6 +161,7 @@ void PI::BusWrite(u32 addr, u32 val) { template <> auto PI::BusRead(u32 addr) -> u16 { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); if (!ReadLatch()) [[unlikely]] { return latch >> 16; } @@ -226,6 +231,7 @@ void PI::BusWrite(u32 addr, u32 val) { template <> auto PI::BusRead(u32 addr) -> u32 { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); if (!ReadLatch()) [[unlikely]] { return latch; } @@ -278,6 +284,7 @@ auto PI::BusRead(u32 addr) -> u32 { template <> void PI::BusWrite(u32 addr, u32 val) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (addr) { case REGION_PI_UNKNOWN: if (!WriteLatch(val)) [[unlikely]] { @@ -341,6 +348,7 @@ void PI::BusWrite(u32 addr, u32 val) { template <> auto PI::BusRead(u32 addr) -> u64 { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); if (!ReadLatch()) [[unlikely]] { return static_cast(latch) << 32; } @@ -401,6 +409,7 @@ void PI::BusWrite(u32 addr, u64 val) { } auto PI::Read(u32 addr) const -> u32 { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (addr) { case 0x04600000: return dramAddr & 0x00FFFFFE; @@ -489,6 +498,7 @@ u32 PI::AccessTiming(const u8 domain, const u32 length) const { // rdram -> cart template <> void PI::DMA() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); const s32 len = rdLen + 1; trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); @@ -512,6 +522,7 @@ void PI::DMA() { // cart -> rdram template <> void PI::DMA() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); const s32 len = wrLen + 1; trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); @@ -533,6 +544,7 @@ void PI::DMA() { } void PI::Write(u32 addr, u32 val) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); MI &mi = mem.mmio.mi; switch (addr) { case 0x04600000: diff --git a/src/backend/core/mmio/PI.hpp b/src/backend/core/mmio/PI.hpp index 664065b8..66642db0 100644 --- a/src/backend/core/mmio/PI.hpp +++ b/src/backend/core/mmio/PI.hpp @@ -2,12 +2,8 @@ #include namespace n64 { - -struct Mem; -struct Registers; - struct PI { - PI(Mem &, Registers &); + PI(); void Reset(); [[nodiscard]] auto Read(u32) const -> u32; void Write(u32, u32); @@ -37,8 +33,5 @@ struct PI { private: template void DMA(); - - Mem &mem; - Registers ®s; }; } // namespace n64 diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 430eb347..1bca2783 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -1,9 +1,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -167,7 +165,8 @@ FORCE_INLINE u8 DataCRC(const u8 *data) { #define BCD_ENCODE(x) (((x) / 10) << 4 | ((x) % 10)) #define BCD_DECODE(x) (((x) >> 4) * 10 + ((x) & 15)) -void PIF::ConfigureJoyBusFrame(const Mem& mem) { +void PIF::ConfigureJoyBusFrame() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); channel = 0; int i = 0; while (i < 63) { @@ -211,10 +210,10 @@ void PIF::ConfigureJoyBusFrame(const Mem& mem) { MempakWrite(packet, res); break; case 4: - EepromRead(packet, res, mem); + EepromRead(packet, res); break; case 5: - EepromWrite(packet, res, mem); + EepromWrite(packet, res); break; case 6: res[0] = 0x00; @@ -259,10 +258,10 @@ void PIF::ConfigureJoyBusFrame(const Mem& mem) { } } -void PIF::ProcessCommands(const Mem &mem) { +void PIF::ProcessCommands() { const u8 control = ram[63]; if (control & 1) { - ConfigureJoyBusFrame(mem); + ConfigureJoyBusFrame(); } if (control & 0x02) { @@ -332,7 +331,8 @@ void PIF::MempakWrite(u8 *cmd, u8 *res) { res[0] = DataCRC(&cmd[5]); } -void PIF::EepromRead(const u8 *cmd, u8 *res, const Mem &mem) const { +void PIF::EepromRead(const u8 *cmd, u8 *res) const { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k); if (channel == 4) { const u8 offset = cmd[3]; @@ -346,7 +346,8 @@ void PIF::EepromRead(const u8 *cmd, u8 *res, const Mem &mem) const { } } -void PIF::EepromWrite(const u8 *cmd, u8 *res, const Mem &mem) { +void PIF::EepromWrite(const u8 *cmd, u8 *res) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k); if (channel == 4) { const u8 offset = cmd[3]; @@ -363,7 +364,9 @@ void PIF::EepromWrite(const u8 *cmd, u8 *res, const Mem &mem) { } void PIF::HLE(const bool pal, const CICType cicType) const { - mem.Write(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); + n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs(); + mem.Write(PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); switch (cicType) { case UNKNOWN_CIC_TYPE: @@ -568,14 +571,14 @@ void PIF::HLE(const bool pal, const CICType cicType) const { regs.Write(31, 0xFFFFFFFFA4001554); } - mem.Write(regs, IMEM_REGION_START + 0x00, 0x3C0DBFC0); - mem.Write(regs, IMEM_REGION_START + 0x04, 0x8DA807FC); - mem.Write(regs, IMEM_REGION_START + 0x08, 0x25AD07C0); - mem.Write(regs, IMEM_REGION_START + 0x0C, 0x31080080); - mem.Write(regs, IMEM_REGION_START + 0x10, 0x5500FFFC); - mem.Write(regs, IMEM_REGION_START + 0x14, 0x3C0DBFC0); - mem.Write(regs, IMEM_REGION_START + 0x18, 0x8DA80024); - mem.Write(regs, IMEM_REGION_START + 0x1C, 0x3C0BB000); + mem.Write(IMEM_REGION_START + 0x00, 0x3C0DBFC0); + mem.Write(IMEM_REGION_START + 0x04, 0x8DA807FC); + mem.Write(IMEM_REGION_START + 0x08, 0x25AD07C0); + mem.Write(IMEM_REGION_START + 0x0C, 0x31080080); + mem.Write(IMEM_REGION_START + 0x10, 0x5500FFFC); + mem.Write(IMEM_REGION_START + 0x14, 0x3C0DBFC0); + mem.Write(IMEM_REGION_START + 0x18, 0x8DA80024); + mem.Write(IMEM_REGION_START + 0x1C, 0x3C0BB000); break; case CIC_NUS_6106_7106: regs.Write(0, 0x0000000000000000); @@ -622,24 +625,25 @@ void PIF::HLE(const bool pal, const CICType cicType) const { regs.Write(22, (cicSeeds[cicType] >> 8) & 0xFF); regs.cop0.Reset(); - mem.Write(regs, 0x04300004, 0x01010101); + mem.Write(0x04300004, 0x01010101); std::copy_n(mem.rom.cart.begin(), 0x1000, mem.mmio.rsp.dmem.begin()); regs.SetPC32(static_cast(0xA4000040)); } void PIF::Execute() const { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); const CICType cicType = mem.rom.cicType; const bool pal = mem.rom.pal; - mem.Write(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); + mem.Write(PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); switch (cicType) { case UNKNOWN_CIC_TYPE: warn("Unknown CIC type!"); break; case CIC_NUS_6101 ... CIC_NUS_6103_7103: - mem.Write(regs, 0x318, RDRAM_SIZE); + mem.Write(0x318, RDRAM_SIZE); break; case CIC_NUS_6105_7105: - mem.Write(regs, 0x3F0, RDRAM_SIZE); + mem.Write(0x3F0, RDRAM_SIZE); break; case CIC_NUS_6106_7106: break; @@ -647,24 +651,4 @@ void PIF::Execute() const { HLE(pal, cicType); } - -std::vector PIF::Serialize() { - std::vector res{}; - res.resize(6 * sizeof(JoybusDevice) + PIF_BOOTROM_SIZE + PIF_RAM_SIZE + mempak.size() + eeprom.size() + sizeof(int)); - - u32 index = 0; - memcpy(res.data() + index, joybusDevices.data(), 6 * sizeof(JoybusDevice)); - index += 6 * sizeof(JoybusDevice); - memcpy(res.data() + index, bootrom.data(), PIF_BOOTROM_SIZE); - index += PIF_BOOTROM_SIZE; - memcpy(res.data() + index, ram.data(), PIF_RAM_SIZE); - index += PIF_RAM_SIZE; - memcpy(res.data() + index, mempak.data(), mempak.size()); - index += mempak.size(); - memcpy(res.data() + index, eeprom.data(), eeprom.size()); - index += eeprom.size(); - memcpy(res.data() + index, &channel, sizeof(int)); - - return res; -} } // namespace n64 diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index 61a55d49..ece02c10 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -5,7 +5,7 @@ #include #include #include -#include "MupenMovie.hpp" +#include namespace fs = std::filesystem; @@ -153,9 +153,6 @@ struct JoybusDevice { JoybusDevice() = default; }; -struct Mem; -struct Registers; - // https://github.com/ares-emulator/ares/blob/master/ares/n64/cic/cic.cpp // https://github.com/ares-emulator/ares/blob/master/LICENSE constexpr u32 cicSeeds[] = { @@ -179,12 +176,10 @@ enum CICType { }; struct PIF { - PIF(Mem &mem, Registers ®s) : mem(mem), regs(regs) {} - ~PIF() = default; void Reset(); void MaybeLoadMempak(); void LoadEeprom(SaveType, const std::string &); - void ProcessCommands(const Mem &); + void ProcessCommands(); void InitDevices(SaveType); void CICChallenge(); void Execute() const; @@ -193,9 +188,8 @@ struct PIF { void ControllerID(u8 *) const; void MempakRead(const u8 *, u8 *); void MempakWrite(u8 *, u8 *); - void EepromRead(const u8 *, u8 *, const Mem &) const; - void EepromWrite(const u8 *, u8 *, const Mem &); - std::vector Serialize(); + void EepromRead(const u8 *, u8 *) const; + void EepromWrite(const u8 *, u8 *); void UpdateButton(int index, Controller::Key k, bool state) { joybusDevices[index].controller.UpdateButton(k, state); } @@ -211,8 +205,6 @@ struct PIF { std::string mempakPath{}, eepromPath{}; size_t eepromSize{}; MupenMovie movie; - Mem &mem; - Registers ®s; [[nodiscard]] FORCE_INLINE u8 Read(u32 addr) const { addr &= 0x7FF; @@ -236,6 +228,6 @@ struct PIF { return joybusDevices[channel].accessoryType; } private: - void ConfigureJoyBusFrame(const Mem &); + void ConfigureJoyBusFrame(); }; } // namespace n64 diff --git a/src/backend/core/mmio/SI.cpp b/src/backend/core/mmio/SI.cpp index 92636ccf..a8a3c19c 100644 --- a/src/backend/core/mmio/SI.cpp +++ b/src/backend/core/mmio/SI.cpp @@ -1,9 +1,8 @@ #include -#include -#include +#include namespace n64 { -SI::SI(Mem &mem, Registers ®s) : pif(mem, regs), mem(mem), regs(regs) { Reset(); } +SI::SI() { Reset(); } void SI::Reset() { status.raw = 0; @@ -14,6 +13,7 @@ void SI::Reset() { } auto SI::Read(u32 addr) const -> u32 { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (addr) { case 0x04800000: return dramAddr; @@ -39,7 +39,8 @@ auto SI::Read(u32 addr) const -> u32 { // pif -> rdram template <> void SI::DMA() { - pif.ProcessCommands(mem); + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); + pif.ProcessCommands(); for (int i = 0; i < 64; i++) { mem.mmio.rdp.WriteRDRAM(dramAddr + i, pif.Read(pifAddr + i)); } @@ -49,6 +50,7 @@ void SI::DMA() { // rdram -> pif template <> void SI::DMA() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); for (int i = 0; i < 64; i++) { pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM(dramAddr + i)); } @@ -56,6 +58,7 @@ void SI::DMA() { } void SI::DMA() { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); status.dmaBusy = false; if (toDram) DMA(); @@ -65,6 +68,7 @@ void SI::DMA() { } void SI::Write(u32 addr, u32 val) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (addr) { case 0x04800000: dramAddr = val & RDRAM_DSIZE; diff --git a/src/backend/core/mmio/SI.hpp b/src/backend/core/mmio/SI.hpp index 386b23d9..68c551f5 100644 --- a/src/backend/core/mmio/SI.hpp +++ b/src/backend/core/mmio/SI.hpp @@ -17,10 +17,8 @@ union SIStatus { }; }; -struct Mem; - struct SI { - SI(Mem &, Registers &); + SI(); void Reset(); SIStatus status{}; u32 dramAddr{}; @@ -33,10 +31,6 @@ struct SI { void DMA(); void DMA(); PIF pif; - -private: - Mem &mem; - Registers ®s; }; #define SI_DMA_DELAY (65536 * 2) diff --git a/src/backend/core/mmio/VI.cpp b/src/backend/core/mmio/VI.cpp index 03328766..924995a0 100644 --- a/src/backend/core/mmio/VI.cpp +++ b/src/backend/core/mmio/VI.cpp @@ -1,10 +1,8 @@ -#include -#include -#include +#include #include namespace n64 { -VI::VI(Mem &mem, Registers ®s) : mem(mem), regs(regs) { Reset(); } +VI::VI() { Reset(); } void VI::Reset() { status.raw = 0xF; @@ -60,6 +58,7 @@ u32 VI::Read(const u32 paddr) const { } void VI::Write(const u32 paddr, const u32 val) { + n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem(); switch (paddr) { case 0x04400000: status.raw = val; diff --git a/src/backend/core/mmio/VI.hpp b/src/backend/core/mmio/VI.hpp index 02faa470..883ee44a 100644 --- a/src/backend/core/mmio/VI.hpp +++ b/src/backend/core/mmio/VI.hpp @@ -67,11 +67,8 @@ union AxisStart { }; }; -struct Mem; -struct Registers; - struct VI { - VI(Mem &, Registers &); + VI(); void Reset(); [[nodiscard]] u32 Read(u32) const; void Write(u32, u32); @@ -88,9 +85,5 @@ struct VI { int numHalflines{}; int numFields{}; int cyclesPerHalfline{}; - -private: - Mem &mem; - Registers ®s; }; } // namespace n64 diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 17c37b62..7ab331e2 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -1,9 +1,8 @@ -#include -#include +#include #include namespace n64 { -Cop0::Cop0(Registers ®s) : regs(regs) { Reset(); } +Cop0::Cop0() { Reset(); } void Cop0::Reset() { cause.raw = 0xB000007C; @@ -293,15 +292,15 @@ static FORCE_INLINE u64 getVPN(const u64 addr, const u64 pageMask) { return vpn & ~mask; } -TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int &index) const { +TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int &index) { for (int i = 0; i < 32; i++) { - if (TLBEntry *entry = ®s.cop0.tlb[i]; entry->initialized) { + if (TLBEntry *entry = &tlb[i]; entry->initialized) { const u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw); const u64 vaddr_vpn = getVPN(vaddr, entry->pageMask.raw); const bool vpn_match = entry_vpn == vaddr_vpn; - if (const bool asid_match = entry->global || regs.cop0.entryHi.asid == entry->entryHi.asid; + if (const bool asid_match = entry->global || entryHi.asid == entry->entryHi.asid; vpn_match && asid_match) { index = i; return entry; @@ -312,15 +311,15 @@ TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int &index) const { return nullptr; } -TLBEntry *Cop0::TLBTryMatch(const u64 vaddr) const { - for (auto &i : regs.cop0.tlb) { +TLBEntry *Cop0::TLBTryMatch(const u64 vaddr) { + for (auto &i : tlb) { if (TLBEntry *entry = &i; entry->initialized) { const u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw); const u64 vaddr_vpn = getVPN(vaddr, entry->pageMask.raw); const bool vpn_match = entry_vpn == vaddr_vpn; - if (const bool asid_match = entry->global || regs.cop0.entryHi.asid == entry->entryHi.asid; + if (const bool asid_match = entry->global || entryHi.asid == entry->entryHi.asid; vpn_match && asid_match) { return entry; } @@ -330,10 +329,10 @@ TLBEntry *Cop0::TLBTryMatch(const u64 vaddr) const { return nullptr; } -bool Cop0::ProbeTLB(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) const { +bool Cop0::ProbeTLB(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { const TLBEntry *entry = TLBTryMatch(vaddr); if (!entry) { - regs.cop0.tlbError = MISS; + tlbError = MISS; return false; } @@ -343,12 +342,12 @@ bool Cop0::ProbeTLB(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) const EntryLo entryLo = odd ? entry->entryLo1 : entry->entryLo0; if (!entryLo.v) { - regs.cop0.tlbError = INVALID; + tlbError = INVALID; return false; } if (accessType == STORE && !entryLo.d) { - regs.cop0.tlbError = MODIFICATION; + tlbError = MODIFICATION; return false; } @@ -370,22 +369,23 @@ FORCE_INLINE bool Is64BitAddressing(const Cop0 &cp0, const u64 addr) { } } -void Cop0::FireException(const ExceptionCode code, const int cop, s64 pc) const { - const bool old_exl = regs.cop0.status.exl; +void Cop0::FireException(const ExceptionCode code, const int cop, s64 pc) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); + const bool old_exl = status.exl; - if (!regs.cop0.status.exl) { - if ((regs.cop0.cause.branchDelay = regs.prevDelaySlot)) { + if (!status.exl) { + if ((cause.branchDelay = regs.prevDelaySlot)) { pc -= 4; } - regs.cop0.status.exl = true; - regs.cop0.EPC = pc; + status.exl = true; + EPC = pc; } - regs.cop0.cause.copError = cop; - regs.cop0.cause.exceptionCode = static_cast(code); + cause.copError = cop; + cause.exceptionCode = static_cast(code); - if (regs.cop0.status.bev) { + if (status.bev) { panic("BEV bit set!"); } else { switch (code) { @@ -423,15 +423,15 @@ void Cop0::FireException(const ExceptionCode code, const int cop, s64 pc) const regs.cop0.Update(); } -void Cop0::HandleTLBException(const u64 vaddr) const { +void Cop0::HandleTLBException(const u64 vaddr) { const u64 vpn2 = vaddr >> 13 & 0x7FFFF; const u64 xvpn2 = vaddr >> 13 & 0x7FFFFFF; - regs.cop0.badVaddr = vaddr; - regs.cop0.context.badvpn2 = vpn2; - regs.cop0.xcontext.badvpn2 = xvpn2; - regs.cop0.xcontext.r = vaddr >> 62 & 3; - regs.cop0.entryHi.vpn2 = xvpn2; - regs.cop0.entryHi.r = vaddr >> 62 & 3; + badVaddr = vaddr; + context.badvpn2 = vpn2; + xcontext.badvpn2 = xvpn2; + xcontext.r = vaddr >> 62 & 3; + entryHi.vpn2 = xvpn2; + entryHi.r = vaddr >> 62 & 3; } ExceptionCode Cop0::GetTLBExceptionCode(const TLBError error, const TLBAccessType accessType) { @@ -452,6 +452,7 @@ ExceptionCode Cop0::GetTLBExceptionCode(const TLBError error, const TLBAccessTyp } void Cop0::decode(const u32 instr) { + Registers& regs = Core::GetInstance().cpu->GetRegs(); const u8 mask_cop = instr >> 21 & 0x1F; const u8 mask_cop2 = instr & 0x3F; switch (mask_cop) { @@ -495,30 +496,30 @@ void Cop0::decode(const u32 instr) { } bool Cop0::MapVAddr(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { - if (regs.cop0.is64BitAddressing) [[unlikely]] { - if (regs.cop0.kernelMode) [[likely]] { + if (is64BitAddressing) [[unlikely]] { + if (kernelMode) [[likely]] { return MapVAddr64(accessType, vaddr, paddr); } - if (regs.cop0.userMode) { + if (userMode) { return UserMapVAddr64(accessType, vaddr, paddr); } - if (regs.cop0.supervisorMode) { + if (supervisorMode) { panic("Supervisor mode memory access, 64 bit mode"); } else { panic("Unknown mode! This should never happen!"); } } else { - if (regs.cop0.kernelMode) [[likely]] { + if (kernelMode) [[likely]] { return MapVAddr32(accessType, vaddr, paddr); } - if (regs.cop0.userMode) { + if (userMode) { return UserMapVAddr32(accessType, vaddr, paddr); } - if (regs.cop0.supervisorMode) { + if (supervisorMode) { panic("Supervisor mode memory access, 32 bit mode"); } else { panic("Unknown mode! This should never happen!"); @@ -531,7 +532,7 @@ bool Cop0::UserMapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 & case VREGION_KUSEG: return ProbeTLB(accessType, s64(s32(vaddr)), paddr); default: - regs.cop0.tlbError = DISALLOWED_ADDRESS; + tlbError = DISALLOWED_ADDRESS; return false; } } @@ -558,7 +559,7 @@ bool Cop0::UserMapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 & case VREGION_XKUSEG: return ProbeTLB(accessType, vaddr, paddr); default: - regs.cop0.tlbError = DISALLOWED_ADDRESS; + tlbError = DISALLOWED_ADDRESS; return false; } } @@ -570,7 +571,7 @@ bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &padd return ProbeTLB(accessType, vaddr, paddr); case VREGION_XKPHYS: { - if (!regs.cop0.kernelMode) { + if (!kernelMode) { panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr); } if (const u8 high_two_bits = (vaddr >> 62) & 0b11; high_two_bits != 0b10) { @@ -580,7 +581,7 @@ bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &padd bool cached = subsegment != 2; // do something with this eventually // If any bits in the range of 58:32 are set, the address is invalid. if (const bool valid = (vaddr & 0x07FFFFFF00000000) == 0; !valid) { - regs.cop0.tlbError = DISALLOWED_ADDRESS; + tlbError = DISALLOWED_ADDRESS; return false; } paddr = vaddr & 0xFFFFFFFF; @@ -607,7 +608,7 @@ bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &padd case VREGION_XBAD1: case VREGION_XBAD2: case VREGION_XBAD3: - regs.cop0.tlbError = DISALLOWED_ADDRESS; + tlbError = DISALLOWED_ADDRESS; return false; default: panic("Resolving virtual address 0x{:016X} in 64 bit mode", vaddr); diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index 24d8625b..bf1b5bc1 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -37,11 +37,6 @@ namespace n64 { #define ENTRY_HI_MASK 0xC00000FFFFFFE0FF #define PAGEMASK_MASK 0x1FFE000 -struct JIT; -struct Interpreter; -struct Registers; -struct Mem; - union Cop0Cause { u32 raw; struct { @@ -194,7 +189,7 @@ union Cop0XContext { }; struct Cop0 { - Cop0(Registers &); + Cop0(); u32 GetReg32(u8); [[nodiscard]] u64 GetReg64(u8) const; @@ -257,22 +252,21 @@ struct Cop0 { enum TLBAccessType { LOAD, STORE }; - bool ProbeTLB(TLBAccessType accessType, u64 vaddr, u32 &paddr) const; - void FireException(ExceptionCode code, int cop, s64 pc) const; + bool ProbeTLB(TLBAccessType accessType, u64 vaddr, u32 &paddr); + void FireException(ExceptionCode code, int cop, s64 pc); bool MapVAddr(TLBAccessType accessType, u64 vaddr, u32 &paddr); bool UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr); bool MapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr); bool UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr); bool MapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr); - TLBEntry *TLBTryMatch(u64 vaddr, int &index) const; - TLBEntry *TLBTryMatch(u64 vaddr) const; - void HandleTLBException(u64 vaddr) const; + TLBEntry *TLBTryMatch(u64 vaddr, int &index); + TLBEntry *TLBTryMatch(u64 vaddr); + void HandleTLBException(u64 vaddr); static ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType accessType); void decode(u32); private: - Registers ®s; [[nodiscard]] FORCE_INLINE u32 GetWired() const { return wired & 0x3F; } [[nodiscard]] FORCE_INLINE u32 GetCount() const { return u32(u64(count >> 1)); } diff --git a/src/backend/core/registers/Cop1.cpp b/src/backend/core/registers/Cop1.cpp index c15a2f7c..8f9a3144 100644 --- a/src/backend/core/registers/Cop1.cpp +++ b/src/backend/core/registers/Cop1.cpp @@ -1,10 +1,8 @@ -#include -#include -#include +#include #include namespace n64 { -Cop1::Cop1(Registers ®s) : regs(regs) { Reset(); } +Cop1::Cop1() { Reset(); } void Cop1::Reset() { fcr0 = 0xa00; diff --git a/src/backend/core/registers/Cop1.hpp b/src/backend/core/registers/Cop1.hpp index d758d3a3..7cce78c5 100644 --- a/src/backend/core/registers/Cop1.hpp +++ b/src/backend/core/registers/Cop1.hpp @@ -109,12 +109,8 @@ union FloatingPointReg { }; }; -struct Interpreter; -struct JIT; -struct Registers; - struct Cop1 { - explicit Cop1(Registers &); + explicit Cop1(); u32 fcr0{}; FCR31 fcr31{}; FloatingPointReg fgr[32]{}; @@ -233,10 +229,10 @@ private: void negd(u32 instr); void sqrts(u32 instr); void sqrtd(u32 instr); - void lwc1(Mem &, u32); - void swc1(Mem &, u32); - void ldc1(Mem &, u32); - void sdc1(Mem &, u32); + void lwc1(u32); + void swc1(u32); + void ldc1(u32); + void sdc1(u32); void mfc1(u32 instr); void dmfc1(u32 instr); @@ -246,7 +242,5 @@ private: void truncwd(u32 instr); void truncls(u32 instr); void truncld(u32 instr); - - Registers ®s; }; } // namespace n64 diff --git a/src/backend/core/registers/Registers.cpp b/src/backend/core/registers/Registers.cpp index da902783..3c90a4a2 100644 --- a/src/backend/core/registers/Registers.cpp +++ b/src/backend/core/registers/Registers.cpp @@ -1,11 +1,9 @@ -#include "jit/helpers.hpp" - - +#include #include #include namespace n64 { -Registers::Registers(JIT *jit) : jit(jit), cop0(*this), cop1(*this) { Reset(); } +Registers::Registers(JIT *jit) : jit(jit) { Reset(); } void Registers::Reset() { hi = 0; diff --git a/src/backend/core/rsp/decode.cpp b/src/backend/core/rsp/decode.cpp index 4958bcfb..875035c6 100644 --- a/src/backend/core/rsp/decode.cpp +++ b/src/backend/core/rsp/decode.cpp @@ -1,6 +1,4 @@ -#include -#include -#include +#include #include namespace n64 { @@ -367,6 +365,7 @@ FORCE_INLINE void cop0(Mem &mem, const u32 instr) { } void RSP::Exec(const u32 instr) { + Mem& mem = Core::GetInstance().cpu->GetMem(); MMIO &mmio = mem.mmio; MI &mi = mmio.mi; switch (const u8 mask = instr >> 26 & 0x3F) { diff --git a/src/backend/core/rsp/instructions.cpp b/src/backend/core/rsp/instructions.cpp index 6df8b4fa..c1c2cc99 100644 --- a/src/backend/core/rsp/instructions.cpp +++ b/src/backend/core/rsp/instructions.cpp @@ -1,8 +1,6 @@ -#include +#include #include -#include #include -#include #include namespace n64 { @@ -1803,7 +1801,10 @@ void RSP::vzero(const u32 instr) { void RSP::mfc0(const RDP &rdp, const u32 instr) { gpr[RT(instr)] = GetCop0Reg(*this, rdp, RD(instr)); } -void RSP::mtc0(const u32 instr) const { SetCop0Reg(mem, RD(instr), gpr[RT(instr)]); } +void RSP::mtc0(const u32 instr) const { + Mem& mem = Core::GetInstance().cpu->GetMem(); + SetCop0Reg(mem, RD(instr), gpr[RT(instr)]); +} void RSP::mfc2(const u32 instr) { const u8 hi = vpr[RD(instr)].byte[BYTE_INDEX(E1(instr))]; diff --git a/src/frontend/CPUSettings.hpp b/src/frontend/CPUSettings.hpp index 9b132520..63f4859c 100644 --- a/src/frontend/CPUSettings.hpp +++ b/src/frontend/CPUSettings.hpp @@ -5,7 +5,6 @@ class CPUSettings final { int selectedCpuTypeIndex = 0; bool modified = false; public: - int GetCPUType() { return selectedCpuTypeIndex; } bool render(); explicit CPUSettings(); void setModified(bool v) { modified = v; } diff --git a/src/frontend/Debugger.cpp b/src/frontend/Debugger.cpp index 8c115a89..58e793e7 100644 --- a/src/frontend/Debugger.cpp +++ b/src/frontend/Debugger.cpp @@ -3,6 +3,7 @@ #include bool Debugger::render() { + n64::Core& core = n64::Core::GetInstance(); if(enabled && ImGui::Begin("Debugger", &enabled)) { static u64 startAddr = 0xFFFF'FFFF'8000'0000; static constexpr int addrStep = 4; @@ -13,7 +14,7 @@ bool Debugger::render() { ImGui::SameLine(); ImGui::Checkbox("Follow program counter:", &followPC); if(followPC) - startAddr = core->cpu->GetRegs().oldPC - 64; // TODO: arbitrary??? + startAddr = core.cpu->GetRegs().oldPC - 64; // TODO: arbitrary??? if(ImGui::BeginTable("Disassembly", 3, ImGuiTableFlags_RowBg)) { ImGui::TableSetupColumn("Address"); @@ -22,7 +23,7 @@ bool Debugger::render() { ImGui::TableHeadersRow(); for(u64 addr = startAddr; addr < startAddr + MAX_LINES_OF_DISASM * sizeof(u32); addr += sizeof(u32)) { - auto disasm = core->cpu->Disassemble(addr); + auto disasm = core.cpu->Disassemble(addr); std::string op_str; for(int i = 0; i < 3; i++) { if(i < 2) { @@ -34,7 +35,7 @@ bool Debugger::render() { if(!disasm.ops[i].empty()) op_str += disasm.ops[i]; } } - auto isPc = addr == core->cpu->GetRegs().oldPC; + auto isPc = addr == core.cpu->GetRegs().oldPC; if(isPc) { ImGui::PushStyleColor(ImGuiCol_TableRowBg, 0x809a9ade); ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, 0x807777bf); diff --git a/src/frontend/Debugger.hpp b/src/frontend/Debugger.hpp index a7bcc544..0f486a98 100644 --- a/src/frontend/Debugger.hpp +++ b/src/frontend/Debugger.hpp @@ -2,11 +2,9 @@ #include class Debugger final { - std::shared_ptr core; bool enabled = false; static constexpr auto MAX_LINES_OF_DISASM = 150; public: - Debugger(const std::shared_ptr& core) : core(core) { } void Open() { enabled = true; } void Close() { enabled = false; } bool render(); diff --git a/src/frontend/EmuThread.cpp b/src/frontend/EmuThread.cpp index 3c861871..6a73c51e 100644 --- a/src/frontend/EmuThread.cpp +++ b/src/frontend/EmuThread.cpp @@ -2,12 +2,13 @@ #include #include -EmuThread::EmuThread(const std::shared_ptr &core, double &fps, RenderWidget &renderWidget, +EmuThread::EmuThread(double &fps, RenderWidget &renderWidget, SettingsWindow &settings) noexcept : - renderWidget(renderWidget), core(core), settings(settings), fps(fps) {} + renderWidget(renderWidget), settings(settings), fps(fps) {} void EmuThread::run() const noexcept { - if(!core->romLoaded) return; + n64::Core& core = n64::Core::GetInstance(); + if(!core.romLoaded) return; auto lastSample = std::chrono::high_resolution_clock::now(); auto avgFps = 16.667; @@ -17,8 +18,8 @@ void EmuThread::run() const noexcept { fps = 1000.0 / avgFps; const auto startFrameTime = std::chrono::high_resolution_clock::now(); - if (!core->pause) { - core->Run(settings.getVolumeL(), settings.getVolumeR()); + if (!core.pause) { + core.Run(settings.getVolumeL(), settings.getVolumeR()); } const auto endFrameTime = std::chrono::high_resolution_clock::now(); @@ -40,15 +41,17 @@ void EmuThread::run() const noexcept { } void EmuThread::TogglePause() const noexcept { - core->TogglePause(); + n64::Core::GetInstance().TogglePause(); } void EmuThread::Reset() const noexcept { - core->Stop(); - core->LoadROM(core->rom); + n64::Core& core = n64::Core::GetInstance(); + core.Stop(); + core.LoadROM(core.rom); } void EmuThread::Stop() const noexcept { - core->Stop(); - core->rom = {}; + n64::Core& core = n64::Core::GetInstance(); + core.Stop(); + core.rom = {}; } diff --git a/src/frontend/EmuThread.hpp b/src/frontend/EmuThread.hpp index 6526312a..0829e380 100644 --- a/src/frontend/EmuThread.hpp +++ b/src/frontend/EmuThread.hpp @@ -11,7 +11,7 @@ class EmuThread final { RenderWidget &renderWidget; bool started = false; public: - explicit EmuThread(const std::shared_ptr &, double &, RenderWidget &, SettingsWindow &) noexcept; + explicit EmuThread(double &, RenderWidget &, SettingsWindow &) noexcept; ~EmuThread() = default; void run() const noexcept; void TogglePause() const noexcept; @@ -19,7 +19,6 @@ public: void Stop() const noexcept; bool interruptionRequested = false, parallelRDPInitialized = false; - std::shared_ptr core; SettingsWindow &settings; double& fps; }; diff --git a/src/frontend/KaizenGui.cpp b/src/frontend/KaizenGui.cpp index ccf2c3f2..a59c0877 100644 --- a/src/frontend/KaizenGui.cpp +++ b/src/frontend/KaizenGui.cpp @@ -4,8 +4,8 @@ #include #include -KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), settingsWindow(window), core(std::make_shared(static_cast(settingsWindow.cpuSettings.GetCPUType()))), vulkanWidget(core, window.getHandle()), emuThread(core, fpsCounter, vulkanWidget, settingsWindow), debugger(core) { - gui::Initialize(core->parallel.wsi, window.getHandle()); +KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), settingsWindow(window), vulkanWidget(window.getHandle()), emuThread(fpsCounter, vulkanWidget, settingsWindow) { + gui::Initialize(n64::Core::GetInstance().parallel.wsi, window.getHandle()); SDL_InitSubSystem(SDL_INIT_GAMEPAD); SDL_AddGamepadMapping(gamecontrollerdb_str); @@ -34,7 +34,8 @@ void KaizenGui::QueryDevices(SDL_Event event) { } void KaizenGui::HandleInput(SDL_Event event) { - n64::PIF &pif = core->cpu->GetMem().mmio.si.pif; + n64::Core& core = n64::Core::GetInstance(); + n64::PIF &pif = core.cpu->GetMem().mmio.si.pif; switch(event.type) { case SDL_EVENT_GAMEPAD_AXIS_MOTION: if(!gamepad) @@ -95,9 +96,9 @@ void KaizenGui::HandleInput(SDL_Event event) { fastForward = keys[SDL_SCANCODE_SPACE]; if(!unlockFramerate) - core->parallel.SetFramerateUnlocked(fastForward); + core.parallel.SetFramerateUnlocked(fastForward); - if(core->romLoaded) { + if(core.romLoaded) { if(keys[SDL_SCANCODE_P]) { emuThread.TogglePause(); } @@ -134,6 +135,7 @@ void KaizenGui::HandleInput(SDL_Event event) { } void KaizenGui::RenderUI() { + n64::Core& core = n64::Core::GetInstance(); gui::StartFrame(); if(ImGui::BeginMainMenuBar()) { @@ -148,9 +150,9 @@ void KaizenGui::RenderUI() { ImGui::EndMenu(); } if(ImGui::BeginMenu("Emulation")) { - ImGui::BeginDisabled(!core->romLoaded); + ImGui::BeginDisabled(!core.romLoaded); - if(ImGui::MenuItem(core->pause ? "Resume" : "Pause", "P")) { + if(ImGui::MenuItem(core.pause ? "Resume" : "Pause", "P")) { emuThread.TogglePause(); } @@ -160,11 +162,11 @@ void KaizenGui::RenderUI() { if(ImGui::MenuItem("Stop", "Q")) { emuThread.Stop(); - core->romLoaded = false; + core.romLoaded = false; } if(ImGui::Checkbox("Unlock framerate", &unlockFramerate)) { - core->parallel.SetFramerateUnlocked(unlockFramerate); + core.parallel.SetFramerateUnlocked(unlockFramerate); } if(ImGui::MenuItem("Open Debugger")) { @@ -245,17 +247,18 @@ void KaizenGui::RenderUI() { }, this, window.getHandle(), filters, 3, nullptr, false); } - if(core->romLoaded) { - core->parallel.UpdateScreen(*core.get()); + if(core.romLoaded) { + core.parallel.UpdateScreen(); return; } - core->parallel.UpdateScreen(*core.get(), false); + core.parallel.UpdateScreen(false); } void KaizenGui::LoadROM(const std::string &path) noexcept { - emuThread.core->LoadROM(path); - const auto gameNameDB = emuThread.core->cpu->GetMem().rom.gameNameDB; + n64::Core& core = n64::Core::GetInstance(); + core.LoadROM(path); + const auto gameNameDB = core.cpu->GetMem().rom.gameNameDB; } void KaizenGui::run() { @@ -279,8 +282,9 @@ void KaizenGui::run() { } void KaizenGui::LoadTAS(const std::string &path) const noexcept { - if (emuThread.core->LoadTAS(fs::path(path))) { - const auto gameNameDB = emuThread.core->cpu->GetMem().rom.gameNameDB; + n64::Core& core = n64::Core::GetInstance(); + if (core.LoadTAS(fs::path(path))) { + const auto gameNameDB = core.cpu->GetMem().rom.gameNameDB; const auto movieName = fs::path(path).stem().string(); return; } diff --git a/src/frontend/KaizenGui.hpp b/src/frontend/KaizenGui.hpp index f987955b..2ed396ed 100644 --- a/src/frontend/KaizenGui.hpp +++ b/src/frontend/KaizenGui.hpp @@ -16,7 +16,6 @@ public: bool unlockFramerate = false; SettingsWindow settingsWindow; - std::shared_ptr core; RenderWidget vulkanWidget; EmuThread emuThread; Debugger debugger; diff --git a/src/frontend/RenderWidget.cpp b/src/frontend/RenderWidget.cpp index e53f543f..6b5b2c7a 100644 --- a/src/frontend/RenderWidget.cpp +++ b/src/frontend/RenderWidget.cpp @@ -4,8 +4,9 @@ #include #include -RenderWidget::RenderWidget(const std::shared_ptr &core, SDL_Window* window) { - wsiPlatform = std::make_shared(core, window); +RenderWidget::RenderWidget(SDL_Window* window) { + wsiPlatform = std::make_shared(window); windowInfo = std::make_shared(window); - core->parallel.Init(wsiPlatform, windowInfo, core->cpu->GetMem().GetRDRAMPtr()); + n64::Core& core = n64::Core::GetInstance(); + core.parallel.Init(wsiPlatform, windowInfo, core.cpu->GetMem().GetRDRAMPtr()); } \ No newline at end of file diff --git a/src/frontend/RenderWidget.hpp b/src/frontend/RenderWidget.hpp index 647d6d08..af3ff6aa 100644 --- a/src/frontend/RenderWidget.hpp +++ b/src/frontend/RenderWidget.hpp @@ -24,7 +24,7 @@ private: class SDLWSIPlatform final : public Vulkan::WSIPlatform { public: - explicit SDLWSIPlatform(const std::shared_ptr &core, SDL_Window* window) : window(window), core(core) {} + explicit SDLWSIPlatform(SDL_Window* window) : window(window) {} ~SDLWSIPlatform() = default; std::vector get_instance_extensions() override { @@ -67,13 +67,12 @@ public: SDL_Window* window{}; VkSurfaceKHR surface; private: - std::shared_ptr core; bool gamepadConnected = false; }; class RenderWidget final { public: - explicit RenderWidget(const std::shared_ptr &, SDL_Window*); + explicit RenderWidget(SDL_Window*); std::shared_ptr windowInfo; std::shared_ptr wsiPlatform;