Refactor MIPS Interface
This commit is contained in:
@@ -66,7 +66,7 @@ void Core::Run(float volumeL, float volumeR) {
|
||||
mmio.vi.current = (i << 1) + field;
|
||||
|
||||
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
|
||||
InterruptRaise(mmio.mi, regs, Interrupt::VI);
|
||||
mmio.mi.InterruptRaise(MI::Interrupt::VI);
|
||||
}
|
||||
|
||||
for(; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
|
||||
@@ -98,7 +98,7 @@ void Core::Run(float volumeL, float volumeR) {
|
||||
}
|
||||
|
||||
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
|
||||
InterruptRaise(mmio.mi, regs, Interrupt::VI);
|
||||
mmio.mi.InterruptRaise(MI::Interrupt::VI);
|
||||
}
|
||||
|
||||
mmio.ai.Step(cpu->mem, regs, frameCycles, volumeL, volumeR);
|
||||
|
||||
@@ -37,7 +37,7 @@ void Scheduler::tick(u64 t, n64::Mem& mem, n64::Registers& regs) {
|
||||
si.DMA(mem, regs);
|
||||
break;
|
||||
case PI_DMA_COMPLETE:
|
||||
InterruptRaise(mi, regs, n64::Interrupt::PI);
|
||||
mi.InterruptRaise(n64::MI::Interrupt::PI);
|
||||
pi.dmaBusy = false;
|
||||
break;
|
||||
case PI_BUS_WRITE_COMPLETE:
|
||||
|
||||
@@ -15,6 +15,6 @@ struct BaseCPU {
|
||||
virtual std::vector<u8> Serialize() = 0;
|
||||
virtual void Deserialize(const std::vector<u8>&) = 0;
|
||||
Registers regs;
|
||||
Mem mem;
|
||||
Mem mem{regs};
|
||||
};
|
||||
}
|
||||
@@ -17,7 +17,7 @@ void Interpreter::CheckCompareInterrupt() {
|
||||
regs.cop0.count &= 0x1FFFFFFFF;
|
||||
if(regs.cop0.count == (u64)regs.cop0.compare << 1) {
|
||||
regs.cop0.cause.ip7 = 1;
|
||||
UpdateInterrupt(mem.mmio.mi, regs);
|
||||
mem.mmio.mi.UpdateInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ struct Mem;
|
||||
struct Registers;
|
||||
|
||||
struct MMIO {
|
||||
MMIO() = default;
|
||||
MMIO(Registers& regs) : mi(regs) {}
|
||||
void Reset();
|
||||
|
||||
VI vi;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <cassert>
|
||||
|
||||
namespace n64 {
|
||||
Mem::Mem() : flash(saveData) {
|
||||
Mem::Mem(Registers& regs) : flash(saveData), mmio(regs) {
|
||||
memset(readPages, 0, PAGE_COUNT);
|
||||
memset(writePages, 0, PAGE_COUNT);
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ struct Flash {
|
||||
|
||||
struct Mem {
|
||||
~Mem() = default;
|
||||
Mem();
|
||||
Mem(Registers&);
|
||||
void Reset();
|
||||
void LoadSRAM(SaveType, fs::path);
|
||||
static std::vector<u8> OpenROM(const std::string&, size_t&);
|
||||
|
||||
@@ -204,6 +204,6 @@ void RDP::OnFullSync(MI& mi, Registers& regs) {
|
||||
dpc.status.pipeBusy = false;
|
||||
dpc.status.startGclk = false;
|
||||
dpc.status.cbufReady = false;
|
||||
InterruptRaise(mi, regs, Interrupt::DP);
|
||||
mi.InterruptRaise(MI::Interrupt::DP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,9 +94,9 @@ void RSP::WriteStatus(MI& mi, Registers& regs, u32 value) {
|
||||
}
|
||||
if(write.clearBroke) spStatus.broke = false;
|
||||
if(write.clearIntr && !write.setIntr)
|
||||
InterruptLower(mi, regs, Interrupt::SP);
|
||||
mi.InterruptLower(MI::Interrupt::SP);
|
||||
if(write.setIntr && !write.clearIntr)
|
||||
InterruptRaise(mi, regs, Interrupt::SP);
|
||||
mi.InterruptRaise(MI::Interrupt::SP);
|
||||
CLEAR_SET(spStatus.singleStep, write.clearSstep, write.setSstep);
|
||||
CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak);
|
||||
CLEAR_SET(spStatus.signal0, write.clearSignal0, write.setSignal0);
|
||||
|
||||
@@ -43,7 +43,7 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
case 0x04500004: {
|
||||
u32 len = (val & 0x3FFFF) & ~7;
|
||||
if(dmaCount < 2) {
|
||||
if(dmaCount == 0) InterruptRaise(mem.mmio.mi, regs, Interrupt::AI);
|
||||
if(dmaCount == 0) mem.mmio.mi.InterruptRaise(MI::Interrupt::AI);
|
||||
dmaLen[dmaCount] = len;
|
||||
dmaCount++;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
dmaEnable = val & 1;
|
||||
break;
|
||||
case 0x0450000C:
|
||||
InterruptLower(mem.mmio.mi, regs, Interrupt::AI);
|
||||
mem.mmio.mi.InterruptLower(MI::Interrupt::AI);
|
||||
break;
|
||||
case 0x04500010: {
|
||||
u32 oldDacFreq = dac.freq;
|
||||
@@ -97,7 +97,7 @@ void AI::Step(Mem& mem, Registers& regs, u32 cpuCycles, float volumeL, float vol
|
||||
|
||||
if(!dmaLen[0]) {
|
||||
if(--dmaCount > 0) {
|
||||
InterruptRaise(mem.mmio.mi, regs, Interrupt::AI);
|
||||
mem.mmio.mi.InterruptRaise(MI::Interrupt::AI);
|
||||
dmaAddr[0] = dmaAddr[1];
|
||||
dmaLen[0] = dmaLen[1];
|
||||
}
|
||||
|
||||
@@ -3,57 +3,58 @@
|
||||
#include <core/registers/Registers.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void InterruptRaise(MI &mi, Registers ®s, Interrupt intr) {
|
||||
void MI::InterruptRaise(Interrupt intr) {
|
||||
switch(intr) {
|
||||
case Interrupt::VI:
|
||||
mi.miIntr.vi = true;
|
||||
miIntr.vi = true;
|
||||
break;
|
||||
case Interrupt::SI:
|
||||
mi.miIntr.si = true;
|
||||
miIntr.si = true;
|
||||
break;
|
||||
case Interrupt::PI:
|
||||
mi.miIntr.pi = true;
|
||||
miIntr.pi = true;
|
||||
break;
|
||||
case Interrupt::AI:
|
||||
mi.miIntr.ai = true;
|
||||
miIntr.ai = true;
|
||||
break;
|
||||
case Interrupt::DP:
|
||||
mi.miIntr.dp = true;
|
||||
miIntr.dp = true;
|
||||
break;
|
||||
case Interrupt::SP:
|
||||
mi.miIntr.sp = true;
|
||||
miIntr.sp = true;
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateInterrupt(mi, regs);
|
||||
UpdateInterrupt();
|
||||
}
|
||||
|
||||
void InterruptLower(MI &mi, Registers ®s, Interrupt intr) {
|
||||
void MI::InterruptLower(Interrupt intr) {
|
||||
switch(intr) {
|
||||
case Interrupt::VI:
|
||||
mi.miIntr.vi = false;
|
||||
miIntr.vi = false;
|
||||
break;
|
||||
case Interrupt::SI:
|
||||
mi.miIntr.si = false;
|
||||
miIntr.si = false;
|
||||
break;
|
||||
case Interrupt::PI:
|
||||
mi.miIntr.pi = false;
|
||||
miIntr.pi = false;
|
||||
break;
|
||||
case Interrupt::AI:
|
||||
mi.miIntr.ai = false;
|
||||
miIntr.ai = false;
|
||||
break;
|
||||
case Interrupt::DP:
|
||||
mi.miIntr.dp = false;
|
||||
miIntr.dp = false;
|
||||
break;
|
||||
case Interrupt::SP:
|
||||
mi.miIntr.sp = false;
|
||||
miIntr.sp = false;
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateInterrupt(mi, regs);
|
||||
UpdateInterrupt();
|
||||
}
|
||||
void UpdateInterrupt(MI &mi, Registers ®s) {
|
||||
bool interrupt = mi.miIntr.raw & mi.miIntrMask.raw;
|
||||
|
||||
void MI::UpdateInterrupt() {
|
||||
bool interrupt = miIntr.raw & miIntrMask.raw;
|
||||
regs.cop0.cause.ip2 = interrupt;
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,4 @@ namespace n64 {
|
||||
|
||||
struct Registers;
|
||||
|
||||
enum class Interrupt : u8 {
|
||||
VI, SI, PI, AI, DP, SP
|
||||
};
|
||||
|
||||
void InterruptRaise(MI &mi, Registers ®s, Interrupt intr);
|
||||
void InterruptLower(MI &mi, Registers ®s, Interrupt intr);
|
||||
void UpdateInterrupt(MI &mi, Registers ®s);
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
#define MI_VERSION_REG 0x02020102
|
||||
|
||||
namespace n64 {
|
||||
MI::MI() {
|
||||
MI::MI(Registers& regs) : regs(regs) {
|
||||
Reset();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ void MI::Write(Registers& regs, u32 paddr, u32 val) {
|
||||
}
|
||||
|
||||
if (val & (1 << 11)) {
|
||||
InterruptLower(*this, regs, Interrupt::DP);
|
||||
InterruptLower(Interrupt::DP);
|
||||
}
|
||||
|
||||
if (val & (1 << 12)) {
|
||||
@@ -75,7 +75,7 @@ void MI::Write(Registers& regs, u32 paddr, u32 val) {
|
||||
}
|
||||
}
|
||||
|
||||
UpdateInterrupt(*this, regs);
|
||||
UpdateInterrupt();
|
||||
break;
|
||||
default:
|
||||
Util::panic("Unhandled MI[{:08X}] write ({:08X})", val, paddr);
|
||||
|
||||
@@ -19,12 +19,20 @@ union MIIntr {
|
||||
struct Registers;
|
||||
|
||||
struct MI {
|
||||
MI();
|
||||
enum class Interrupt : u8 {
|
||||
VI, SI, PI, AI, DP, SP
|
||||
};
|
||||
|
||||
MI(Registers&);
|
||||
void Reset();
|
||||
[[nodiscard]] auto Read(u32) const -> u32;
|
||||
void Write(Registers& regs, u32, u32);
|
||||
void InterruptRaise(Interrupt intr);
|
||||
void InterruptLower(Interrupt intr);
|
||||
void UpdateInterrupt();
|
||||
|
||||
u32 miMode{};
|
||||
MIIntr miIntr{}, miIntrMask{};
|
||||
Registers& regs;
|
||||
};
|
||||
}
|
||||
@@ -474,7 +474,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
} break;
|
||||
case 0x04600010:
|
||||
if(val & 2) {
|
||||
InterruptLower(mi, regs, Interrupt::PI);
|
||||
mi.InterruptLower(MI::Interrupt::PI);
|
||||
} break;
|
||||
case 0x04600014: pi_bsd_dom1_lat = val & 0xff; break;
|
||||
case 0x04600018: pi_bsd_dom1_pwd = val & 0xff; break;
|
||||
|
||||
@@ -48,7 +48,7 @@ void SI::DMA(Mem& mem, Registers& regs) const {
|
||||
Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", si.dramAddr, si.pifAddr);
|
||||
si.pif.ProcessCommands(mem);
|
||||
}
|
||||
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
|
||||
mem.mmio.mi.InterruptRaise(MI::Interrupt::SI);
|
||||
}
|
||||
|
||||
void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
@@ -69,7 +69,7 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
scheduler.enqueueRelative(SI_DMA_DELAY, SI_DMA);
|
||||
} break;
|
||||
case 0x04800018:
|
||||
InterruptLower(mem.mmio.mi, regs, Interrupt::SI);
|
||||
mem.mmio.mi.InterruptLower(MI::Interrupt::SI);
|
||||
break;
|
||||
default:
|
||||
Util::panic("Unhandled SI[{:08X}] write ({:08X})", addr, val);
|
||||
|
||||
@@ -63,7 +63,7 @@ void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) {
|
||||
intr = val & 0x3FF;
|
||||
} break;
|
||||
case 0x04400010:
|
||||
InterruptLower(mi, regs, Interrupt::VI);
|
||||
mi.InterruptLower(MI::Interrupt::VI);
|
||||
break;
|
||||
case 0x04400014: burst.raw = val; break;
|
||||
case 0x04400018: {
|
||||
|
||||
@@ -26,7 +26,7 @@ FORCE_INLINE void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) {
|
||||
rsp.steps = 0;
|
||||
rsp.spStatus.broke = true;
|
||||
if(rsp.spStatus.interruptOnBreak) {
|
||||
InterruptRaise(mi, regs, Interrupt::SP);
|
||||
mi.InterruptRaise(MI::Interrupt::SP);
|
||||
}
|
||||
break;
|
||||
case 0x20: case 0x21:
|
||||
|
||||
Reference in New Issue
Block a user