Mem and Regs not part of cpu anymore.
This commit is contained in:
2
external/parallel-rdp/ParallelRDPWrapper.cpp
vendored
2
external/parallel-rdp/ParallelRDPWrapper.cpp
vendored
@@ -193,7 +193,7 @@ void ParallelRDP::UpdateScreen(Util::IntrusivePtr<Image> image) const {
|
||||
void ParallelRDP::UpdateScreen(bool playing) const {
|
||||
if(playing) {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
n64::VI& vi = core.GetVI();
|
||||
n64::VI& vi = core.GetMem().mmio.vi;
|
||||
command_processor->set_vi_register(VIRegister::Control, vi.status.raw);
|
||||
command_processor->set_vi_register(VIRegister::Origin, vi.origin);
|
||||
command_processor->set_vi_register(VIRegister::Width, vi.width);
|
||||
|
||||
@@ -7,10 +7,10 @@ namespace n64 {
|
||||
Core::Core() {
|
||||
auto cpuType = Options::GetInstance().GetValue<std::string>("cpu", "type");
|
||||
if (cpuType == "interpreter") {
|
||||
cpu = std::make_unique<Interpreter>(parallel);
|
||||
cpu = std::make_unique<Interpreter>(parallel, *mem, regs);
|
||||
} else if(cpuType == "jit") {
|
||||
#ifndef __aarch64__
|
||||
cpu = std::make_unique<JIT>(parallel);
|
||||
cpu = std::make_unique<JIT>(parallel, *mem, regs);
|
||||
#else
|
||||
panic("JIT currently unsupported on aarch64");
|
||||
#endif
|
||||
@@ -26,11 +26,13 @@ void Core::Stop() {
|
||||
}
|
||||
|
||||
void Core::Reset() {
|
||||
regs.Reset();
|
||||
mem->Reset();
|
||||
cpu->Reset();
|
||||
cpu->GetMem().mmio.si.pif.Execute();
|
||||
mem->mmio.si.pif.Execute();
|
||||
}
|
||||
|
||||
bool Core::LoadTAS(const fs::path &path) const { return cpu->GetMem().mmio.si.pif.movie.Load(path); }
|
||||
bool Core::LoadTAS(const fs::path &path) const { return mem->mmio.si.pif.movie.Load(path); }
|
||||
|
||||
void Core::LoadROM(const std::string &rom_) {
|
||||
Stop();
|
||||
@@ -41,26 +43,24 @@ void Core::LoadROM(const std::string &rom_) {
|
||||
auto extension = fs::path(rom).extension().string();
|
||||
const bool isArchive = std::ranges::any_of(archive_types, [&extension](const auto &e) { return e == extension; });
|
||||
|
||||
cpu->GetMem().LoadROM(isArchive, rom);
|
||||
mem->LoadROM(isArchive, rom);
|
||||
GameDB::match();
|
||||
if (cpu->GetMem().rom.gameNameDB.empty()) {
|
||||
cpu->GetMem().rom.gameNameDB = fs::path(rom).stem().string();
|
||||
if (mem->rom.gameNameDB.empty()) {
|
||||
mem->rom.gameNameDB = fs::path(rom).stem().string();
|
||||
}
|
||||
cpu->GetMem().mmio.vi.isPal = cpu->GetMem().IsROMPAL();
|
||||
cpu->GetMem().mmio.si.pif.InitDevices(cpu->GetMem().saveType);
|
||||
cpu->GetMem().mmio.si.pif.mempakPath = rom;
|
||||
cpu->GetMem().mmio.si.pif.LoadEeprom(cpu->GetMem().saveType, rom);
|
||||
cpu->GetMem().flash.Load(cpu->GetMem().saveType, rom);
|
||||
cpu->GetMem().LoadSRAM(cpu->GetMem().saveType, rom);
|
||||
cpu->GetMem().mmio.si.pif.Execute();
|
||||
mem->mmio.vi.isPal = mem->IsROMPAL();
|
||||
mem->mmio.si.pif.InitDevices(mem->saveType);
|
||||
mem->mmio.si.pif.mempakPath = rom;
|
||||
mem->mmio.si.pif.LoadEeprom(mem->saveType, rom);
|
||||
mem->flash.Load(mem->saveType, rom);
|
||||
mem->LoadSRAM(mem->saveType, rom);
|
||||
mem->mmio.si.pif.Execute();
|
||||
pause = false;
|
||||
romLoaded = true;
|
||||
}
|
||||
|
||||
void Core::Run(float volumeL, float volumeR) {
|
||||
Mem &mem = cpu->GetMem();
|
||||
MMIO &mmio = mem.mmio;
|
||||
Registers ®s = cpu->GetRegs();
|
||||
MMIO &mmio = mem->mmio;
|
||||
|
||||
for (int field = 0; field < mmio.vi.numFields; field++) {
|
||||
u32 frameCycles = 0;
|
||||
@@ -71,7 +71,7 @@ void Core::Run(float volumeL, float volumeR) {
|
||||
mmio.mi.InterruptRaise(MI::Interrupt::VI);
|
||||
}
|
||||
|
||||
for (; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
|
||||
for (; cycles < mem->mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
|
||||
u32 taken = cpu->Step();
|
||||
taken += regs.PopStalledCycles();
|
||||
|
||||
|
||||
@@ -20,13 +20,20 @@ struct Core {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static Registers& GetRegs() {
|
||||
return GetInstance().regs;
|
||||
}
|
||||
|
||||
static Mem& GetMem() {
|
||||
return *GetInstance().mem;
|
||||
}
|
||||
|
||||
void Stop();
|
||||
void Reset();
|
||||
void LoadROM(const std::string &);
|
||||
[[nodiscard]] bool LoadTAS(const fs::path &) const;
|
||||
void Run(float volumeL, float volumeR);
|
||||
void TogglePause() { pause = !pause; }
|
||||
[[nodiscard]] VI &GetVI() const { return cpu->GetMem().mmio.vi; }
|
||||
inline void ToggleBreakpoint(s64 addr) {
|
||||
if(breakpoints.contains(addr)){
|
||||
breakpoints.erase(addr);
|
||||
@@ -42,6 +49,8 @@ struct Core {
|
||||
u32 cycles = 0;
|
||||
bool romLoaded = false;
|
||||
std::string rom;
|
||||
Registers regs;
|
||||
std::unique_ptr<Mem> mem = std::make_unique<Mem>();
|
||||
std::unique_ptr<BaseCPU> cpu;
|
||||
size_t memSize{}, cpuSize{}, verSize{};
|
||||
int slot = 0;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace n64 {
|
||||
void GameDB::match() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
const ROM &rom = mem.rom;
|
||||
for (const auto &[code, regions, saveType, name] : gamedb) {
|
||||
const bool matches_code = code == rom.code;
|
||||
|
||||
@@ -19,8 +19,7 @@ u64 Scheduler::Remove(const EventType eventType) const {
|
||||
}
|
||||
|
||||
void Scheduler::Tick(const u64 t) {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
n64::Mem& mem = core.cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
ticks += t;
|
||||
n64::MI &mi = mem.mmio.mi;
|
||||
n64::SI &si = mem.mmio.si;
|
||||
|
||||
@@ -8,7 +8,5 @@ struct BaseCPU {
|
||||
virtual ~BaseCPU() = default;
|
||||
virtual int Step() = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual Mem &GetMem() = 0;
|
||||
virtual Registers &GetRegs() = 0;
|
||||
};
|
||||
} // namespace n64
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
template <>
|
||||
std::optional<u64> Disassembler::CapstoneToRegValue(mips_reg reg) const {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
u64 val = 0;
|
||||
switch(reg) {
|
||||
case MIPS_REG_ZERO: case MIPS_REG_ZERO_64: case MIPS_REG_ZERO_NM:
|
||||
@@ -109,7 +109,7 @@ std::optional<u64> Disassembler::CapstoneToRegValue(mips_reg reg) const {
|
||||
|
||||
template <>
|
||||
std::string Disassembler::CapstoneToRegValue(mips_reg reg) const {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
auto val = CapstoneToRegValue<std::optional<u64>>(reg);
|
||||
|
||||
return std::format("{}", val.has_value() ? std::format("{} (= 0x{:016X})", cs_reg_name(handle, reg), val.value()) : "! Unknown !");
|
||||
@@ -131,13 +131,11 @@ Disassembler::DisassemblyResult Disassembler::DisassembleSimple(const u32 addres
|
||||
}
|
||||
|
||||
[[nodiscard]] Disassembler::DisassemblyResult Disassembler::Disassemble(const u32 address) const {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
n64::Mem& mem = core.cpu->GetMem();
|
||||
u32 paddr;
|
||||
if(!core.cpu->GetRegs().cop0.MapVAddr(n64::Cop0::TLBAccessType::LOAD, address, paddr))
|
||||
if(!n64::Core::GetRegs().cop0.MapVAddr(n64::Cop0::TLBAccessType::LOAD, address, paddr))
|
||||
return DisassemblyResult{false, ""};
|
||||
|
||||
u32 instruction = mem.Read<u32>(paddr);
|
||||
u32 instruction = n64::Core::GetMem().Read<u32>(paddr);
|
||||
|
||||
return details ? DisassembleDetailed(address, instruction) : DisassembleSimple(address, instruction);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <Core.hpp>
|
||||
|
||||
namespace n64 {
|
||||
Interpreter::Interpreter(ParallelRDP ¶llel) {}
|
||||
Interpreter::Interpreter(ParallelRDP& parallel, Mem& mem, Registers& regs) : mem(mem), regs(regs) {}
|
||||
|
||||
bool Interpreter::ShouldServiceInterrupt() const {
|
||||
const bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0;
|
||||
|
||||
@@ -7,22 +7,17 @@ namespace n64 {
|
||||
struct Core;
|
||||
|
||||
struct Interpreter : BaseCPU {
|
||||
explicit Interpreter(ParallelRDP &);
|
||||
explicit Interpreter(ParallelRDP&, Mem&, Registers&);
|
||||
~Interpreter() override = default;
|
||||
int Step() override;
|
||||
|
||||
void Reset() override {
|
||||
regs.Reset();
|
||||
mem.Reset();
|
||||
cop2Latch = {};
|
||||
}
|
||||
|
||||
Mem &GetMem() override { return mem; }
|
||||
|
||||
Registers &GetRegs() override { return regs; }
|
||||
private:
|
||||
Registers regs;
|
||||
Mem mem;
|
||||
Registers& regs;
|
||||
Mem& mem;
|
||||
u64 cop2Latch{};
|
||||
friend struct Cop1;
|
||||
#define check_address_error(mask, vaddr) \
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
namespace n64 {
|
||||
#ifndef __aarch64__
|
||||
JIT::JIT(ParallelRDP ¶llel) : regs(this), mem(this) {
|
||||
JIT::JIT(ParallelRDP& parallel, Mem& mem, Registers& regs) : mem(mem), regs(regs) {
|
||||
regs.SetJIT(this);
|
||||
blockCache.resize(kUpperSize);
|
||||
if (cs_open(CS_ARCH_MIPS, static_cast<cs_mode>(CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN), &disassemblerMips) !=
|
||||
CS_ERR_OK) {
|
||||
@@ -29,7 +30,7 @@ void JIT::CheckCompareInterrupt() {
|
||||
regs.cop0.count &= 0x1FFFFFFFF;
|
||||
if (regs.cop0.count == static_cast<u64>(regs.cop0.compare) << 1) {
|
||||
regs.cop0.cause.ip7 = 1;
|
||||
mem.mmio.mi.UpdateInterrupt();
|
||||
Core::GetMem().mmio.mi.UpdateInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +59,42 @@ u32 JIT::FetchInstruction() {
|
||||
static_cast<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast<u64>(blockPC));
|
||||
}
|
||||
|
||||
return mem.Read<u32>(paddr);
|
||||
return Core::GetMem().Read<u32>(paddr);
|
||||
}
|
||||
|
||||
void JIT::SetPC32(s32 val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.mov(code.SCR1, s64(val));
|
||||
code.mov(REG(qword, pc), code.SCR1);
|
||||
code.mov(code.SCR1, s64(val) + 4);
|
||||
code.mov(REG(qword, nextPC), code.SCR1);
|
||||
}
|
||||
|
||||
void JIT::SetPC64(s64 val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.mov(code.SCR1, val);
|
||||
code.mov(REG(qword, pc), code.SCR1);
|
||||
code.mov(code.SCR1, val + 4);
|
||||
code.mov(REG(qword, nextPC), code.SCR1);
|
||||
}
|
||||
|
||||
void JIT::SetPC32(const Xbyak::Reg32& val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.movsxd(val.cvt64(), val);
|
||||
code.mov(REG(qword, pc), val);
|
||||
code.add(val, 4);
|
||||
code.mov(REG(qword, nextPC), val);
|
||||
}
|
||||
|
||||
void JIT::SetPC64(const Xbyak::Reg64& val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.mov(REG(qword, pc), val);
|
||||
code.add(val, 4);
|
||||
code.mov(REG(qword, nextPC), val);
|
||||
}
|
||||
|
||||
int JIT::Step() {
|
||||
@@ -126,7 +162,7 @@ int JIT::Step() {
|
||||
static_cast<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast<u64>(blockPC));
|
||||
}
|
||||
|
||||
instruction = mem.Read<u32>(paddr);
|
||||
instruction = Core::GetMem().Read<u32>(paddr);
|
||||
instructionsInBlock++;
|
||||
|
||||
blockOldPC = blockPC;
|
||||
|
||||
@@ -22,27 +22,21 @@ static constexpr u32 kCodeCacheAllocSize = kCodeCacheSize + 4_kb;
|
||||
struct JIT : BaseCPU {};
|
||||
#else
|
||||
struct JIT : BaseCPU {
|
||||
explicit JIT(ParallelRDP &);
|
||||
explicit JIT(ParallelRDP&, Mem&, Registers&);
|
||||
~JIT() override = default;
|
||||
int Step() override;
|
||||
|
||||
void Reset() override {
|
||||
regs.Reset();
|
||||
mem.Reset();
|
||||
code.reset();
|
||||
blockCache = {};
|
||||
blockCache.resize(kUpperSize);
|
||||
}
|
||||
|
||||
void InvalidateBlock(u32);
|
||||
|
||||
Mem &GetMem() override { return mem; }
|
||||
|
||||
Registers &GetRegs() override { return regs; }
|
||||
private:
|
||||
Registers& regs;
|
||||
Mem& mem;
|
||||
Xbyak::CodeGenerator code{kCodeCacheAllocSize};
|
||||
Registers regs;
|
||||
Mem mem;
|
||||
u64 cop2Latch{};
|
||||
u64 blockOldPC = 0, blockPC = 0, blockNextPC = 0;
|
||||
friend struct Cop1;
|
||||
@@ -69,6 +63,7 @@ private:
|
||||
return Xbyak::Address{0};
|
||||
}
|
||||
|
||||
|
||||
// Thanks to https://github.com/grumpycoders/pcsx-redux
|
||||
// Load a pointer to the JIT object in "reg"
|
||||
template <typename T>
|
||||
@@ -96,41 +91,10 @@ private:
|
||||
code.add(code.rsp, 8);
|
||||
}
|
||||
|
||||
void SetPC32(s32 val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.mov(code.SCR1, s64(val));
|
||||
code.mov(REG(qword, pc), code.SCR1);
|
||||
code.mov(code.SCR1, s64(val) + 4);
|
||||
code.mov(REG(qword, nextPC), code.SCR1);
|
||||
}
|
||||
|
||||
void SetPC64(s64 val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.mov(code.SCR1, val);
|
||||
code.mov(REG(qword, pc), code.SCR1);
|
||||
code.mov(code.SCR1, val + 4);
|
||||
code.mov(REG(qword, nextPC), code.SCR1);
|
||||
}
|
||||
|
||||
void SetPC32(const Xbyak::Reg32& val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.movsxd(val.cvt64(), val);
|
||||
code.mov(REG(qword, pc), val);
|
||||
code.add(val, 4);
|
||||
code.mov(REG(qword, nextPC), val);
|
||||
}
|
||||
|
||||
void SetPC64(const Xbyak::Reg64& val) {
|
||||
code.mov(code.SCR1, REG(qword, pc));
|
||||
code.mov(REG(qword, oldPC), code.SCR1);
|
||||
code.mov(REG(qword, pc), val);
|
||||
code.add(val, 4);
|
||||
code.mov(REG(qword, nextPC), val);
|
||||
}
|
||||
|
||||
void SetPC32(s32 val);
|
||||
void SetPC64(s64 val);
|
||||
void SetPC32(const Xbyak::Reg32& val);
|
||||
void SetPC64(const Xbyak::Reg64& val);
|
||||
void BranchNotTaken();
|
||||
void BranchTaken(s64 offs);
|
||||
void BranchTaken(const Xbyak::Reg64 &offs);
|
||||
|
||||
@@ -133,7 +133,7 @@ void Mem::LoadROM(const bool isArchive, const std::string &filename) {
|
||||
|
||||
template <>
|
||||
u8 Mem::Read(const u32 paddr) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u8>(paddr);
|
||||
@@ -165,7 +165,7 @@ u8 Mem::Read(const u32 paddr) {
|
||||
|
||||
template <>
|
||||
u16 Mem::Read(const u32 paddr) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u16>(paddr);
|
||||
@@ -190,7 +190,7 @@ u16 Mem::Read(const u32 paddr) {
|
||||
|
||||
template <>
|
||||
u32 Mem::Read(const u32 paddr) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u32>(paddr);
|
||||
@@ -216,7 +216,7 @@ u32 Mem::Read(const u32 paddr) {
|
||||
|
||||
template <>
|
||||
u64 Mem::Read(const u32 paddr) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u64>(paddr);
|
||||
@@ -242,7 +242,7 @@ u64 Mem::Read(const u32 paddr) {
|
||||
|
||||
template <>
|
||||
void Mem::WriteInterpreter<u8>(u32 paddr, u32 val) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u8>(paddr, val); return; }
|
||||
@@ -296,7 +296,7 @@ void Mem::Write<u8>(const u32 paddr, const u32 val) {
|
||||
|
||||
template <>
|
||||
void Mem::WriteInterpreter<u16>(u32 paddr, u32 val) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u16>(paddr, val); return; }
|
||||
@@ -350,7 +350,7 @@ void Mem::Write<u16>(const u32 paddr, const u32 val) {
|
||||
|
||||
template <>
|
||||
void Mem::WriteInterpreter<u32>(const u32 paddr, const u32 val) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u32>(paddr, val); return; }
|
||||
@@ -409,7 +409,7 @@ void Mem::WriteJIT(const u32 paddr, const u64 val) {
|
||||
void Mem::Write(const u32 paddr, const u64 val) { WriteInterpreter(paddr, val); }
|
||||
|
||||
void Mem::WriteInterpreter(const u32 paddr, u64 val) {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u64>(paddr, val); return; }
|
||||
|
||||
@@ -23,7 +23,6 @@ struct ROMHeader {
|
||||
u32 manufacturerId;
|
||||
u16 cartridgeId;
|
||||
char countryCode[2];
|
||||
u8 bootCode[4032];
|
||||
};
|
||||
|
||||
struct ROM {
|
||||
|
||||
@@ -197,7 +197,7 @@ FORCE_INLINE void logCommand(u8 cmd) {
|
||||
*/
|
||||
|
||||
void RDP::RunCommand() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
ParallelRDP& parallel = n64::Core::GetInstance().parallel;
|
||||
if (dpc.status.freeze) {
|
||||
return;
|
||||
@@ -285,7 +285,7 @@ void RDP::RunCommand() {
|
||||
}
|
||||
|
||||
void RDP::OnFullSync() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
ParallelRDP& parallel = n64::Core::GetInstance().parallel;
|
||||
|
||||
parallel.OnFullSync();
|
||||
|
||||
@@ -88,8 +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();
|
||||
Mem& mem = Core::GetMem();
|
||||
Registers& regs = Core::GetRegs();
|
||||
MI &mi = mem.mmio.mi;
|
||||
const auto write = SPStatusWrite{.raw = value};
|
||||
if (write.clearHalt && !write.setHalt) {
|
||||
@@ -130,7 +130,7 @@ void RSP::WriteStatus(const u32 value) {
|
||||
|
||||
template <>
|
||||
void RSP::DMA<true>() {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Mem& mem = Core::GetMem();
|
||||
u32 length = spDMALen.len + 1;
|
||||
|
||||
length = (length + 0x7) & ~0x7;
|
||||
@@ -163,7 +163,7 @@ void RSP::DMA<true>() {
|
||||
|
||||
template <>
|
||||
void RSP::DMA<false>() {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Mem& mem = Core::GetMem();
|
||||
u32 length = spDMALen.len + 1;
|
||||
|
||||
length = (length + 0x7) & ~0x7;
|
||||
|
||||
@@ -4,27 +4,27 @@
|
||||
|
||||
namespace n64 {
|
||||
void Cop0::mtc0(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
SetReg32(RD(instr), regs.Read<u32>(RT(instr)));
|
||||
}
|
||||
|
||||
void Cop0::dmtc0(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
SetReg64(RD(instr), regs.Read<u64>(RT(instr)));
|
||||
}
|
||||
|
||||
void Cop0::mfc0(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
regs.Write(RT(instr), s32(GetReg32(RD(instr))));
|
||||
}
|
||||
|
||||
void Cop0::dmfc0(const u32 instr) const {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
regs.Write(RT(instr), s64(GetReg64(RD(instr))));
|
||||
}
|
||||
|
||||
void Cop0::eret() {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (status.erl) {
|
||||
regs.SetPC64(ErrorEPC);
|
||||
status.erl = false;
|
||||
|
||||
@@ -132,7 +132,7 @@ bool Cop1::isqnan<double>(const double f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s32>(const float f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -153,7 +153,7 @@ bool Cop1::CheckCVTArg<s32>(const float f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s32>(const double f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -174,7 +174,7 @@ bool Cop1::CheckCVTArg<s32>(const double f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s64>(const float f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -195,7 +195,7 @@ bool Cop1::CheckCVTArg<s64>(const float f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s64>(const double f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -216,7 +216,7 @@ bool Cop1::CheckCVTArg<s64>(const double f) {
|
||||
|
||||
template <typename T>
|
||||
bool Cop1::CheckArg(const T f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
SetCauseUnimplemented();
|
||||
@@ -234,7 +234,7 @@ bool Cop1::CheckArg(const T f) {
|
||||
|
||||
template <typename T>
|
||||
bool Cop1::CheckArgs(const T f1, const T f2) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
auto class1 = std::fpclassify(f1), class2 = std::fpclassify(f2);
|
||||
if ((class1 == FP_NAN && !isqnan(f1)) || (class2 == FP_NAN && !isqnan(f2))) {
|
||||
SetCauseUnimplemented();
|
||||
@@ -260,7 +260,7 @@ bool Cop1::CheckArgs(const T f1, const T f2) {
|
||||
|
||||
template <bool preserveCause>
|
||||
bool Cop1::CheckFPUUsable() {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if constexpr (preserveCause) {
|
||||
if (!regs.cop0.status.cu1) {
|
||||
regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 1, regs.oldPC);
|
||||
@@ -295,7 +295,7 @@ FORCE_INLINE T FlushResult(T f, const u32 round) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckResult<float>(float &f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
if (!fcr31.fs || fcr31.enable.underflow || fcr31.enable.inexact_operation) {
|
||||
@@ -318,7 +318,7 @@ bool Cop1::CheckResult<float>(float &f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckResult<double>(double &f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
if (!fcr31.fs || fcr31.enable.underflow || fcr31.enable.inexact_operation) {
|
||||
@@ -341,7 +341,7 @@ bool Cop1::CheckResult<double>(double &f) {
|
||||
|
||||
template <bool cvt>
|
||||
bool Cop1::TestExceptions() {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
const u32 exc = std::fetestexcept(FE_ALL_EXCEPT);
|
||||
|
||||
if (!exc)
|
||||
@@ -445,7 +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();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -458,7 +458,7 @@ void Cop1::absd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::abss(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -471,7 +471,7 @@ void Cop1::abss(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::adds(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -485,7 +485,7 @@ void Cop1::adds(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::addd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -499,7 +499,7 @@ void Cop1::addd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceills(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -510,7 +510,7 @@ void Cop1::ceills(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceilld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -521,7 +521,7 @@ void Cop1::ceilld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceilws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -532,7 +532,7 @@ void Cop1::ceilws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceilwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -543,7 +543,7 @@ void Cop1::ceilwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cfc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
const u8 fd = RD(instr);
|
||||
@@ -562,7 +562,7 @@ void Cop1::cfc1(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ctc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
const u8 fs = RD(instr);
|
||||
@@ -610,7 +610,7 @@ void Cop1::ctc1(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtds(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -623,7 +623,7 @@ void Cop1::cvtds(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtsd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -636,7 +636,7 @@ void Cop1::cvtsd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtsw(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<s32>(regs.cop0.status, FS(instr));
|
||||
@@ -647,7 +647,7 @@ void Cop1::cvtsw(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtsl(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<s64>(regs.cop0.status, FS(instr));
|
||||
@@ -663,7 +663,7 @@ void Cop1::cvtsl(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -674,7 +674,7 @@ void Cop1::cvtwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -685,7 +685,7 @@ void Cop1::cvtws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -696,7 +696,7 @@ void Cop1::cvtls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtdw(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<s32>(regs.cop0.status, FS(instr));
|
||||
@@ -707,7 +707,7 @@ void Cop1::cvtdw(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtdl(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
|
||||
@@ -725,7 +725,7 @@ void Cop1::cvtdl(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -737,7 +737,7 @@ void Cop1::cvtld(const u32 instr) {
|
||||
|
||||
template <typename T, bool quiet, bool cf>
|
||||
bool Cop1::XORDERED(const T fs, const T ft) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (std::isnan(fs) || std::isnan(ft)) {
|
||||
if (std::isnan(fs) && (!quiet || isqnan(fs)) && SetCauseInvalid()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
@@ -759,7 +759,7 @@ bool Cop1::XORDERED(const T fs, const T ft) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cf(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
|
||||
@@ -771,7 +771,7 @@ void Cop1::cf(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cun(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -782,7 +782,7 @@ void Cop1::cun(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::ceq(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -794,7 +794,7 @@ void Cop1::ceq(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cueq(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -806,7 +806,7 @@ void Cop1::cueq(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::colt(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -818,7 +818,7 @@ void Cop1::colt(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cult(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -830,7 +830,7 @@ void Cop1::cult(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cole(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -842,7 +842,7 @@ void Cop1::cole(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cule(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -854,7 +854,7 @@ void Cop1::cule(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::csf(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -865,7 +865,7 @@ void Cop1::csf(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cngle(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -876,7 +876,7 @@ void Cop1::cngle(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cseq(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -888,7 +888,7 @@ void Cop1::cseq(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cngl(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -900,7 +900,7 @@ void Cop1::cngl(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::clt(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -912,7 +912,7 @@ void Cop1::clt(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cnge(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -924,7 +924,7 @@ void Cop1::cnge(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cle(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -936,7 +936,7 @@ void Cop1::cle(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cngt(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -980,7 +980,7 @@ template void Cop1::cle<double>(u32 instr);
|
||||
template void Cop1::cngt<double>(u32 instr);
|
||||
|
||||
void Cop1::divs(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -994,7 +994,7 @@ void Cop1::divs(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::divd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1008,7 +1008,7 @@ void Cop1::divd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::muls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1022,7 +1022,7 @@ void Cop1::muls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::muld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1036,7 +1036,7 @@ void Cop1::muld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::subs(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1050,7 +1050,7 @@ void Cop1::subs(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::subd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1066,14 +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();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
FGR_D<double>(regs.cop0.status, FD(instr)) = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
}
|
||||
|
||||
void Cop1::negs(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1086,7 +1086,7 @@ void Cop1::negs(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::negd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1099,7 +1099,7 @@ void Cop1::negd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::sqrts(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1112,7 +1112,7 @@ void Cop1::sqrts(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::sqrtd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1125,7 +1125,7 @@ void Cop1::sqrtd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1140,7 +1140,7 @@ void Cop1::roundls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1155,7 +1155,7 @@ void Cop1::roundld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1170,7 +1170,7 @@ void Cop1::roundws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1185,7 +1185,7 @@ void Cop1::roundwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1196,7 +1196,7 @@ void Cop1::floorls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1207,7 +1207,7 @@ void Cop1::floorld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1218,7 +1218,7 @@ void Cop1::floorws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1229,7 +1229,7 @@ void Cop1::floorwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1244,7 +1244,7 @@ void Cop1::truncws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1259,7 +1259,7 @@ void Cop1::truncwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1274,7 +1274,7 @@ void Cop1::truncls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1289,8 +1289,8 @@ void Cop1::truncld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::lwc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Mem& mem = Core::GetMem();
|
||||
Registers& regs = Core::GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
|
||||
@@ -1303,8 +1303,8 @@ void Cop1::lwc1(u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::swc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Mem& mem = Core::GetMem();
|
||||
Registers& regs = Core::GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) {
|
||||
@@ -1316,8 +1316,8 @@ void Cop1::swc1(u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ldc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Mem& mem = Core::GetMem();
|
||||
Registers& regs = Core::GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
|
||||
@@ -1330,8 +1330,8 @@ void Cop1::ldc1(u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::sdc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Mem& mem = Core::GetMem();
|
||||
Registers& regs = Core::GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) {
|
||||
@@ -1343,7 +1343,7 @@ void Cop1::sdc1(u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::unimplemented() {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
SetCauseUnimplemented();
|
||||
@@ -1351,28 +1351,28 @@ void Cop1::unimplemented() {
|
||||
}
|
||||
|
||||
void Cop1::mfc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
regs.Write(RT(instr), FGR_T<s32>(regs.cop0.status, FS(instr)));
|
||||
}
|
||||
|
||||
void Cop1::dmfc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
regs.Write(RT(instr), FGR_S<s64>(regs.cop0.status, FS(instr)));
|
||||
}
|
||||
|
||||
void Cop1::mtc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
FGR_T<s32>(regs.cop0.status, FS(instr)) = regs.Read<s64>(RT(instr));
|
||||
}
|
||||
|
||||
void Cop1::dmtc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
FGR_S<u64>(regs.cop0.status, FS(instr)) = regs.Read<s64>(RT(instr));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <Core.hpp>
|
||||
#include <CpuDefinitions.hpp>
|
||||
#include <core/Interpreter.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
|
||||
@@ -824,7 +824,7 @@ void Interpreter::mtlo(const u32 instr) { regs.lo = regs.Read<s64>(RS(instr)); }
|
||||
void Interpreter::mthi(const u32 instr) { regs.hi = regs.Read<s64>(RS(instr)); }
|
||||
|
||||
void Interpreter::trap(const bool cond) const {
|
||||
Cop0& cop0 = Core::GetInstance().cpu->GetRegs().cop0;
|
||||
Cop0& cop0 = Core::GetRegs().cop0;
|
||||
if (cond) {
|
||||
cop0.FireException(ExceptionCode::Trap, 0, regs.oldPC);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <JIT.hpp>
|
||||
#include <jit/helpers.hpp>
|
||||
#include <Core.hpp>
|
||||
|
||||
#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)
|
||||
|
||||
@@ -35,7 +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();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04500000:
|
||||
if (dmaCount < 2) {
|
||||
@@ -80,7 +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();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
cycles += cpuCycles;
|
||||
while (cycles > dac.period) {
|
||||
if (dmaCount == 0) {
|
||||
|
||||
@@ -52,7 +52,7 @@ void MI::InterruptLower(const Interrupt intr) {
|
||||
}
|
||||
|
||||
void MI::UpdateInterrupt() const {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
const bool interrupt = miIntr.raw & miIntrMask.raw;
|
||||
regs.cop0.cause.ip2 = interrupt;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ bool PI::WriteLatch(u32 value) {
|
||||
}
|
||||
|
||||
bool PI::ReadLatch() {
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
if (ioBusy) [[unlikely]] {
|
||||
ioBusy = false;
|
||||
regs.CpuStall(Scheduler::GetInstance().Remove(PI_BUS_WRITE_COMPLETE));
|
||||
@@ -48,7 +48,7 @@ bool PI::ReadLatch() {
|
||||
|
||||
template <>
|
||||
auto PI::BusRead<u8, true>(u32 addr) -> u8 {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case REGION_PI_UNKNOWN:
|
||||
panic("Reading byte from address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN - This is the N64DD, "
|
||||
@@ -83,7 +83,7 @@ auto PI::BusRead<u8, true>(u32 addr) -> u8 {
|
||||
|
||||
template <>
|
||||
auto PI::BusRead<u8, false>(u32 addr) -> u8 {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
if (!ReadLatch()) [[unlikely]] {
|
||||
return latch >> 24;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ auto PI::BusRead<u8, false>(u32 addr) -> u8 {
|
||||
|
||||
template <>
|
||||
void PI::BusWrite<u8, true>(u32 addr, u32 val) {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case REGION_PI_UNKNOWN:
|
||||
panic("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", val, addr);
|
||||
@@ -161,7 +161,7 @@ void PI::BusWrite<u8, false>(u32 addr, u32 val) {
|
||||
|
||||
template <>
|
||||
auto PI::BusRead<u16, false>(u32 addr) -> u16 {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
if (!ReadLatch()) [[unlikely]] {
|
||||
return latch >> 16;
|
||||
}
|
||||
@@ -231,7 +231,7 @@ void PI::BusWrite<u16, true>(u32 addr, u32 val) {
|
||||
|
||||
template <>
|
||||
auto PI::BusRead<u32, false>(u32 addr) -> u32 {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
if (!ReadLatch()) [[unlikely]] {
|
||||
return latch;
|
||||
}
|
||||
@@ -284,7 +284,7 @@ auto PI::BusRead<u32, true>(u32 addr) -> u32 {
|
||||
|
||||
template <>
|
||||
void PI::BusWrite<u32, false>(u32 addr, u32 val) {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case REGION_PI_UNKNOWN:
|
||||
if (!WriteLatch(val)) [[unlikely]] {
|
||||
@@ -348,7 +348,7 @@ void PI::BusWrite<u32, true>(u32 addr, u32 val) {
|
||||
|
||||
template <>
|
||||
auto PI::BusRead<u64, false>(u32 addr) -> u64 {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
if (!ReadLatch()) [[unlikely]] {
|
||||
return static_cast<u64>(latch) << 32;
|
||||
}
|
||||
@@ -409,7 +409,7 @@ void PI::BusWrite<true>(u32 addr, u64 val) {
|
||||
}
|
||||
|
||||
auto PI::Read(u32 addr) const -> u32 {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04600000:
|
||||
return dramAddr & 0x00FFFFFE;
|
||||
@@ -498,7 +498,7 @@ u32 PI::AccessTiming(const u8 domain, const u32 length) const {
|
||||
// rdram -> cart
|
||||
template <>
|
||||
void PI::DMA<false>() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
const s32 len = rdLen + 1;
|
||||
trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
|
||||
|
||||
@@ -522,7 +522,7 @@ void PI::DMA<false>() {
|
||||
// cart -> rdram
|
||||
template <>
|
||||
void PI::DMA<true>() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
const s32 len = wrLen + 1;
|
||||
trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
|
||||
|
||||
@@ -544,7 +544,7 @@ void PI::DMA<true>() {
|
||||
}
|
||||
|
||||
void PI::Write(u32 addr, u32 val) {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
MI &mi = mem.mmio.mi;
|
||||
switch (addr) {
|
||||
case 0x04600000:
|
||||
|
||||
@@ -166,7 +166,7 @@ FORCE_INLINE u8 DataCRC(const u8 *data) {
|
||||
#define BCD_DECODE(x) (((x) >> 4) * 10 + ((x) & 15))
|
||||
|
||||
void PIF::ConfigureJoyBusFrame() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
channel = 0;
|
||||
int i = 0;
|
||||
while (i < 63) {
|
||||
@@ -332,7 +332,7 @@ void PIF::MempakWrite(u8 *cmd, u8 *res) {
|
||||
}
|
||||
|
||||
void PIF::EepromRead(const u8 *cmd, u8 *res) const {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k);
|
||||
if (channel == 4) {
|
||||
const u8 offset = cmd[3];
|
||||
@@ -347,7 +347,7 @@ void PIF::EepromRead(const u8 *cmd, u8 *res) const {
|
||||
}
|
||||
|
||||
void PIF::EepromWrite(const u8 *cmd, u8 *res) {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k);
|
||||
if (channel == 4) {
|
||||
const u8 offset = cmd[3];
|
||||
@@ -364,8 +364,8 @@ void PIF::EepromWrite(const u8 *cmd, u8 *res) {
|
||||
}
|
||||
|
||||
void PIF::HLE(const bool pal, const CICType cicType) const {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Registers& regs = n64::Core::GetInstance().cpu->GetRegs();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
mem.Write<u32>(PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);
|
||||
|
||||
switch (cicType) {
|
||||
@@ -631,7 +631,7 @@ void PIF::HLE(const bool pal, const CICType cicType) const {
|
||||
}
|
||||
|
||||
void PIF::Execute() const {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
const CICType cicType = mem.rom.cicType;
|
||||
const bool pal = mem.rom.pal;
|
||||
mem.Write<u32>(PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);
|
||||
|
||||
@@ -13,7 +13,7 @@ void SI::Reset() {
|
||||
}
|
||||
|
||||
auto SI::Read(u32 addr) const -> u32 {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04800000:
|
||||
return dramAddr;
|
||||
@@ -39,7 +39,7 @@ auto SI::Read(u32 addr) const -> u32 {
|
||||
// pif -> rdram
|
||||
template <>
|
||||
void SI::DMA<true>() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
pif.ProcessCommands();
|
||||
for (int i = 0; i < 64; i++) {
|
||||
mem.mmio.rdp.WriteRDRAM<u8>(dramAddr + i, pif.Read(pifAddr + i));
|
||||
@@ -50,7 +50,7 @@ void SI::DMA<true>() {
|
||||
// rdram -> pif
|
||||
template <>
|
||||
void SI::DMA<false>() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
for (int i = 0; i < 64; i++) {
|
||||
pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM<u8>(dramAddr + i));
|
||||
}
|
||||
@@ -58,7 +58,7 @@ void SI::DMA<false>() {
|
||||
}
|
||||
|
||||
void SI::DMA() {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
status.dmaBusy = false;
|
||||
if (toDram)
|
||||
DMA<true>();
|
||||
@@ -68,7 +68,7 @@ void SI::DMA() {
|
||||
}
|
||||
|
||||
void SI::Write(u32 addr, u32 val) {
|
||||
n64::Mem& mem = n64::Core::GetInstance().cpu->GetMem();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04800000:
|
||||
dramAddr = val & RDRAM_DSIZE;
|
||||
|
||||
@@ -62,7 +62,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();
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (paddr) {
|
||||
case 0x04400000:
|
||||
status.raw = val;
|
||||
|
||||
@@ -370,7 +370,7 @@ FORCE_INLINE bool Is64BitAddressing(const Cop0 &cp0, const u64 addr) {
|
||||
}
|
||||
|
||||
void Cop0::FireException(const ExceptionCode code, const int cop, s64 pc) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
const bool old_exl = status.exl;
|
||||
|
||||
if (!status.exl) {
|
||||
@@ -452,7 +452,7 @@ ExceptionCode Cop0::GetTLBExceptionCode(const TLBError error, const TLBAccessTyp
|
||||
}
|
||||
|
||||
void Cop0::decode(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
Registers& regs = Core::GetRegs();
|
||||
const u8 mask_cop = instr >> 21 & 0x1F;
|
||||
const u8 mask_cop2 = instr & 0x3F;
|
||||
switch (mask_cop) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <core/JIT.hpp>
|
||||
|
||||
namespace n64 {
|
||||
Registers::Registers(JIT *jit) : jit(jit) { Reset(); }
|
||||
Registers::Registers() { Reset(); }
|
||||
|
||||
void Registers::Reset() {
|
||||
hi = 0;
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include <backend/core/registers/Cop1.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct JIT;
|
||||
struct Registers {
|
||||
Registers(JIT *jit = nullptr);
|
||||
Registers();
|
||||
void Reset();
|
||||
void SetPC64(s64);
|
||||
void SetPC32(s32);
|
||||
void SetJIT(JIT* jit) { this->jit = jit; }
|
||||
|
||||
[[nodiscard]] bool IsRegConstant(const u32 index) const {
|
||||
if (index == 0)
|
||||
|
||||
@@ -365,7 +365,7 @@ FORCE_INLINE void cop0(Mem &mem, const u32 instr) {
|
||||
}
|
||||
|
||||
void RSP::Exec(const u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Mem& mem = Core::GetMem();
|
||||
MMIO &mmio = mem.mmio;
|
||||
MI &mi = mmio.mi;
|
||||
switch (const u8 mask = instr >> 26 & 0x3F) {
|
||||
|
||||
@@ -1802,7 +1802,7 @@ 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 {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Mem& mem = Core::GetMem();
|
||||
SetCop0Reg(mem, RD(instr), gpr[RT(instr)]);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,8 +58,6 @@ void InstructionFunc(s64, s64, Disassembler::DisassemblyResult& disasm) {
|
||||
|
||||
void CommentFunc(s64, s64, Disassembler::DisassemblyResult& disasm) {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
n64::Mem& mem = core.cpu->GetMem();
|
||||
n64::Registers& regs = core.cpu->GetRegs();
|
||||
|
||||
if(!disasm.success) {
|
||||
ImGui::TextColored(ImColor(0xff71efe5), "");
|
||||
@@ -92,10 +90,10 @@ void CommentFunc(s64, s64, Disassembler::DisassemblyResult& disasm) {
|
||||
ImGui::TableNextRow();
|
||||
for(u32 col = 0; col < 16; col+=4) {
|
||||
u32 paddr;
|
||||
if(!regs.cop0.MapVAddr(n64::Cop0::LOAD, vaddr+row*0x10+col, paddr))
|
||||
if(!n64::Core::GetRegs().cop0.MapVAddr(n64::Cop0::LOAD, vaddr+row*0x10+col, paddr))
|
||||
continue;
|
||||
|
||||
u32 val = mem.Read<u32>(paddr);
|
||||
u32 val = n64::Core::GetMem().Read<u32>(paddr);
|
||||
|
||||
ImGui::TableSetColumnIndex(col+0);
|
||||
ImGui::Text("%02X", (val >> 24) & 0xff);
|
||||
@@ -114,7 +112,7 @@ void CommentFunc(s64, s64, Disassembler::DisassemblyResult& disasm) {
|
||||
|
||||
bool Debugger::render() {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
n64::Registers& regs = core.cpu->GetRegs();
|
||||
n64::Registers& regs = core.GetRegs();
|
||||
|
||||
if(!enabled)
|
||||
return false;
|
||||
|
||||
@@ -35,7 +35,7 @@ void KaizenGui::QueryDevices(SDL_Event event) {
|
||||
|
||||
void KaizenGui::HandleInput(SDL_Event event) {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
n64::PIF &pif = core.cpu->GetMem().mmio.si.pif;
|
||||
n64::PIF &pif = core.GetMem().mmio.si.pif;
|
||||
switch(event.type) {
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
if(!gamepad)
|
||||
@@ -261,7 +261,8 @@ void KaizenGui::RenderUI() {
|
||||
void KaizenGui::LoadROM(const std::string &path) noexcept {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
core.LoadROM(path);
|
||||
const auto gameNameDB = core.cpu->GetMem().rom.gameNameDB;
|
||||
const auto gameNameDB = core.GetMem().rom.gameNameDB;
|
||||
SDL_SetWindowTitle(window.getHandle(), ("Kaizen - " + gameNameDB).c_str());
|
||||
}
|
||||
|
||||
void KaizenGui::run() {
|
||||
@@ -291,12 +292,7 @@ void KaizenGui::run() {
|
||||
}
|
||||
|
||||
void KaizenGui::LoadTAS(const std::string &path) const noexcept {
|
||||
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;
|
||||
if (!n64::Core::GetInstance().LoadTAS(fs::path(path))) {
|
||||
panic("Could not load TAS movie {}!", path);
|
||||
}
|
||||
|
||||
panic("Could not load TAS movie {}!", path);
|
||||
}
|
||||
@@ -8,5 +8,5 @@ RenderWidget::RenderWidget(SDL_Window* window) {
|
||||
wsiPlatform = std::make_shared<SDLWSIPlatform>(window);
|
||||
windowInfo = std::make_shared<SDLParallelRdpWindowInfo>(window);
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
core.parallel.Init(wsiPlatform, windowInfo, core.cpu->GetMem().GetRDRAMPtr());
|
||||
core.parallel.Init(wsiPlatform, windowInfo, core.GetMem().GetRDRAMPtr());
|
||||
}
|
||||
@@ -54,11 +54,11 @@ struct Error {
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
std::string Format(Severity severity,
|
||||
std::optional<u64> lastPC,
|
||||
std::optional<MemoryAccess> memoryAccess,
|
||||
std::optional<Type> type,
|
||||
const std::format_string<Args...> fmt, Args... args) {
|
||||
void Throw (Severity severity,
|
||||
Type type,
|
||||
std::optional<u64> lastPC,
|
||||
std::optional<MemoryAccess> memoryAccess,
|
||||
const std::format_string<Args...> fmt, Args... args) {
|
||||
this->severity = severity;
|
||||
this->lastPC = lastPC;
|
||||
this->memoryAccess = memoryAccess;
|
||||
@@ -74,11 +74,16 @@ struct Error {
|
||||
return severity == NONE;
|
||||
}
|
||||
|
||||
static Error& Get() {
|
||||
static Error& GetInstance() {
|
||||
static Error instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
static std::string Get() {
|
||||
return GetInstance().err;
|
||||
}
|
||||
private:
|
||||
std::string err;
|
||||
Severity severity = NONE;
|
||||
Type type = {};
|
||||
std::optional<u64> lastPC = {};
|
||||
|
||||
Reference in New Issue
Block a user