small MI refactor in preparation of (eventually) implementing the RDRAM interface properly

This commit is contained in:
2026-04-03 11:28:51 +02:00
parent 694b45341a
commit d5024ebbf6
5 changed files with 61 additions and 71 deletions
+17 -17
View File
@@ -1,50 +1,50 @@
#include <Core.hpp> #include <Core.hpp>
namespace n64 { namespace n64 {
void MI::InterruptRaise(const Interrupt intr) { void MI::InterruptRaise(const Interrupt intType) {
switch (intr) { switch (intType) {
case Interrupt::VI: case Interrupt::VI:
miIntr.vi = true; intr.vi = true;
break; break;
case Interrupt::SI: case Interrupt::SI:
miIntr.si = true; intr.si = true;
break; break;
case Interrupt::PI: case Interrupt::PI:
miIntr.pi = true; intr.pi = true;
break; break;
case Interrupt::AI: case Interrupt::AI:
miIntr.ai = true; intr.ai = true;
break; break;
case Interrupt::DP: case Interrupt::DP:
miIntr.dp = true; intr.dp = true;
break; break;
case Interrupt::SP: case Interrupt::SP:
miIntr.sp = true; intr.sp = true;
break; break;
} }
UpdateInterrupt(); UpdateInterrupt();
} }
void MI::InterruptLower(const Interrupt intr) { void MI::InterruptLower(const Interrupt intType) {
switch (intr) { switch (intType) {
case Interrupt::VI: case Interrupt::VI:
miIntr.vi = false; intr.vi = false;
break; break;
case Interrupt::SI: case Interrupt::SI:
miIntr.si = false; intr.si = false;
break; break;
case Interrupt::PI: case Interrupt::PI:
miIntr.pi = false; intr.pi = false;
break; break;
case Interrupt::AI: case Interrupt::AI:
miIntr.ai = false; intr.ai = false;
break; break;
case Interrupt::DP: case Interrupt::DP:
miIntr.dp = false; intr.dp = false;
break; break;
case Interrupt::SP: case Interrupt::SP:
miIntr.sp = false; intr.sp = false;
break; break;
} }
@@ -53,7 +53,7 @@ void MI::InterruptLower(const Interrupt intr) {
void MI::UpdateInterrupt() const { void MI::UpdateInterrupt() const {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
const bool interrupt = miIntr.raw & miIntrMask.raw; const bool interrupt = intr.raw & intrMask.raw;
regs.cop0.cause.ip2 = interrupt; regs.cop0.cause.ip2 = interrupt;
} }
} // namespace n64 } // namespace n64
+15 -37
View File
@@ -8,58 +8,36 @@ namespace n64 {
MI::MI() { Reset(); } MI::MI() { Reset(); }
void MI::Reset() { void MI::Reset() {
miIntrMask.raw = 0; intrMask.raw = 0;
miIntr.raw = 0; intr.raw = 0;
miMode = 0; mode.raw = 0;
} }
auto MI::Read(u32 paddr) const -> u32 { auto MI::Read(u32 paddr) const -> u32 {
switch (paddr & 0xF) { switch (paddr & 0xF) {
case 0x0: case 0x0:
return miMode & 0x3FF; return mode.raw & 0x3FF;
case 0x4: case 0x4:
return MI_VERSION_REG; return MI_VERSION_REG;
case 0x8: case 0x8:
return miIntr.raw & 0x3F; return intr.raw & 0x3F;
case 0xC: case 0xC:
return miIntrMask.raw & 0x3F; return intrMask.raw & 0x3F;
default: default:
panic("Unhandled MI[{:08X}] read", paddr); panic("Unhandled MI[{:08X}] read", paddr);
} }
} }
void MI::Write(u32 paddr, u32 val) { void MI::Write(u32 paddr, u32 val) {
switch (paddr & 0xF) { switch (paddr & 0xF) { //-----------sc-cscs-cvvv-vvvv
case 0x0: case 0x0: // ----|----|----|----|--uu|deer|rccc|cccc
miMode &= 0xFFFFFF80; mode.repeatCount = val & 0x7F;
miMode |= val & 0x7F; mode.repeat = val & 0x100 ? 1 : val & 0x80 ? 0 : mode.repeat;
if (val & (1 << 7)) { mode.ebus = val & 0x400 ? 1 : val & 0x200 ? 0 : mode.ebus;
miMode &= ~(1 << 7); mode.upper = val & 0x2000 ? 1 : val & 0x1000 ? 0 : mode.upper;
} if(val & 0x800) {
if (val & (1 << 8)) {
miMode |= 1 << 7;
}
if (val & (1 << 9)) {
miMode &= ~(1 << 8);
}
if (val & (1 << 10)) {
miMode |= 1 << 8;
}
if (val & (1 << 11)) {
InterruptLower(Interrupt::DP); InterruptLower(Interrupt::DP);
} }
if (val & (1 << 12)) {
miMode &= ~(1 << 9);
}
if (val & (1 << 13)) {
miMode |= 1 << 9;
}
break; break;
case 0x4: case 0x4:
case 0x8: case 0x8:
@@ -70,11 +48,11 @@ void MI::Write(u32 paddr, u32 val) {
const int setbit = (bit << 1) + 1; const int setbit = (bit << 1) + 1;
if (val & (1 << clearbit)) { if (val & (1 << clearbit)) {
miIntrMask.raw &= ~(1 << bit); intrMask.raw &= ~(1 << bit);
} }
if (val & (1 << setbit)) { if (val & (1 << setbit)) {
miIntrMask.raw |= 1 << bit; intrMask.raw |= 1 << bit;
} }
} }
+17 -5
View File
@@ -3,7 +3,8 @@
namespace n64 { namespace n64 {
union MIIntr { struct MI {
union Intr {
struct { struct {
unsigned sp : 1; unsigned sp : 1;
unsigned si : 1; unsigned si : 1;
@@ -14,9 +15,20 @@ union MIIntr {
unsigned : 26; unsigned : 26;
}; };
u32 raw; u32 raw;
}; };
union Mode {
struct {
unsigned repeatCount:7;
unsigned repeat:1;
unsigned ebus:1;
unsigned upper:1;
unsigned : 22;
};
u32 raw;
};
struct MI {
enum class Interrupt : u8 { VI, SI, PI, AI, DP, SP }; enum class Interrupt : u8 { VI, SI, PI, AI, DP, SP };
explicit MI(); explicit MI();
@@ -27,7 +39,7 @@ struct MI {
void InterruptLower(Interrupt intr); void InterruptLower(Interrupt intr);
void UpdateInterrupt() const; void UpdateInterrupt() const;
u32 miMode{}; Mode mode{};
MIIntr miIntr{}, miIntrMask{}; Intr intr{}, intrMask{};
}; };
} // namespace n64 } // namespace n64
+1 -1
View File
@@ -426,7 +426,7 @@ auto PI::Read(u32 addr) const -> u32 {
value |= (dmaBusy << 0); // Is PI DMA active? No, because it's instant value |= (dmaBusy << 0); // Is PI DMA active? No, because it's instant
value |= (ioBusy << 1); // Is PI IO busy? No, because it's instant value |= (ioBusy << 1); // Is PI IO busy? No, because it's instant
value |= (0 << 2); // PI IO error? value |= (0 << 2); // PI IO error?
value |= (mem.mmio.mi.miIntr.pi << 3); // PI interrupt? value |= (mem.mmio.mi.intr.pi << 3); // PI interrupt?
return value; return value;
} }
case 0x04600014: case 0x04600014:
+1 -1
View File
@@ -28,7 +28,7 @@ auto SI::Read(u32 addr) const -> u32 {
val |= status.dmaBusy; val |= status.dmaBusy;
val |= (0 << 1); val |= (0 << 1);
val |= (0 << 3); val |= (0 << 3);
val |= (mem.mmio.mi.miIntr.si << 12); val |= (mem.mmio.mi.intr.si << 12);
return val; return val;
} }
default: default: