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