From d5024ebbf6265358f5a7e871729e0fdf46b3b3bd Mon Sep 17 00:00:00 2001 From: iris Date: Fri, 3 Apr 2026 11:28:51 +0200 Subject: [PATCH] small MI refactor in preparation of (eventually) implementing the RDRAM interface properly --- src/backend/core/mmio/Interrupt.cpp | 34 +++++++++---------- src/backend/core/mmio/MI.cpp | 52 +++++++++-------------------- src/backend/core/mmio/MI.hpp | 42 ++++++++++++++--------- src/backend/core/mmio/PI.cpp | 2 +- src/backend/core/mmio/SI.cpp | 2 +- 5 files changed, 61 insertions(+), 71 deletions(-) diff --git a/src/backend/core/mmio/Interrupt.cpp b/src/backend/core/mmio/Interrupt.cpp index 3156cfb..7d17488 100644 --- a/src/backend/core/mmio/Interrupt.cpp +++ b/src/backend/core/mmio/Interrupt.cpp @@ -1,50 +1,50 @@ #include namespace n64 { -void MI::InterruptRaise(const Interrupt intr) { - switch (intr) { +void MI::InterruptRaise(const Interrupt intType) { + switch (intType) { case Interrupt::VI: - miIntr.vi = true; + intr.vi = true; break; case Interrupt::SI: - miIntr.si = true; + intr.si = true; break; case Interrupt::PI: - miIntr.pi = true; + intr.pi = true; break; case Interrupt::AI: - miIntr.ai = true; + intr.ai = true; break; case Interrupt::DP: - miIntr.dp = true; + intr.dp = true; break; case Interrupt::SP: - miIntr.sp = true; + intr.sp = true; break; } UpdateInterrupt(); } -void MI::InterruptLower(const Interrupt intr) { - switch (intr) { +void MI::InterruptLower(const Interrupt intType) { + switch (intType) { case Interrupt::VI: - miIntr.vi = false; + intr.vi = false; break; case Interrupt::SI: - miIntr.si = false; + intr.si = false; break; case Interrupt::PI: - miIntr.pi = false; + intr.pi = false; break; case Interrupt::AI: - miIntr.ai = false; + intr.ai = false; break; case Interrupt::DP: - miIntr.dp = false; + intr.dp = false; break; case Interrupt::SP: - miIntr.sp = false; + intr.sp = false; break; } @@ -53,7 +53,7 @@ void MI::InterruptLower(const Interrupt intr) { void MI::UpdateInterrupt() const { 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; } } // namespace n64 diff --git a/src/backend/core/mmio/MI.cpp b/src/backend/core/mmio/MI.cpp index 2d2df50..c55b6fd 100644 --- a/src/backend/core/mmio/MI.cpp +++ b/src/backend/core/mmio/MI.cpp @@ -8,58 +8,36 @@ namespace n64 { MI::MI() { Reset(); } void MI::Reset() { - miIntrMask.raw = 0; - miIntr.raw = 0; - miMode = 0; + intrMask.raw = 0; + intr.raw = 0; + mode.raw = 0; } auto MI::Read(u32 paddr) const -> u32 { switch (paddr & 0xF) { case 0x0: - return miMode & 0x3FF; + return mode.raw & 0x3FF; case 0x4: return MI_VERSION_REG; case 0x8: - return miIntr.raw & 0x3F; + return intr.raw & 0x3F; case 0xC: - return miIntrMask.raw & 0x3F; + return intrMask.raw & 0x3F; default: panic("Unhandled MI[{:08X}] read", paddr); } } void MI::Write(u32 paddr, u32 val) { - switch (paddr & 0xF) { - case 0x0: - miMode &= 0xFFFFFF80; - miMode |= val & 0x7F; - if (val & (1 << 7)) { - miMode &= ~(1 << 7); - } - - 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)) { + switch (paddr & 0xF) { //-----------sc-cscs-cvvv-vvvv + case 0x0: // ----|----|----|----|--uu|deer|rccc|cccc + mode.repeatCount = val & 0x7F; + mode.repeat = val & 0x100 ? 1 : val & 0x80 ? 0 : mode.repeat; + mode.ebus = val & 0x400 ? 1 : val & 0x200 ? 0 : mode.ebus; + mode.upper = val & 0x2000 ? 1 : val & 0x1000 ? 0 : mode.upper; + if(val & 0x800) { InterruptLower(Interrupt::DP); } - - if (val & (1 << 12)) { - miMode &= ~(1 << 9); - } - - if (val & (1 << 13)) { - miMode |= 1 << 9; - } break; case 0x4: case 0x8: @@ -70,11 +48,11 @@ void MI::Write(u32 paddr, u32 val) { const int setbit = (bit << 1) + 1; if (val & (1 << clearbit)) { - miIntrMask.raw &= ~(1 << bit); + intrMask.raw &= ~(1 << bit); } if (val & (1 << setbit)) { - miIntrMask.raw |= 1 << bit; + intrMask.raw |= 1 << bit; } } diff --git a/src/backend/core/mmio/MI.hpp b/src/backend/core/mmio/MI.hpp index 01f7388..75e3cec 100644 --- a/src/backend/core/mmio/MI.hpp +++ b/src/backend/core/mmio/MI.hpp @@ -3,20 +3,32 @@ namespace n64 { -union MIIntr { - struct { - unsigned sp : 1; - unsigned si : 1; - unsigned ai : 1; - unsigned vi : 1; - unsigned pi : 1; - unsigned dp : 1; - unsigned : 26; - }; - u32 raw; -}; - struct MI { + union Intr { + struct { + unsigned sp : 1; + unsigned si : 1; + unsigned ai : 1; + unsigned vi : 1; + unsigned pi : 1; + unsigned dp : 1; + unsigned : 26; + }; + u32 raw; + }; + + union Mode { + struct { + unsigned repeatCount:7; + unsigned repeat:1; + unsigned ebus:1; + unsigned upper:1; + unsigned : 22; + }; + + u32 raw; + }; + enum class Interrupt : u8 { VI, SI, PI, AI, DP, SP }; explicit MI(); @@ -27,7 +39,7 @@ struct MI { void InterruptLower(Interrupt intr); void UpdateInterrupt() const; - u32 miMode{}; - MIIntr miIntr{}, miIntrMask{}; + Mode mode{}; + Intr intr{}, intrMask{}; }; } // namespace n64 diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index 9ece210..22aa45f 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -426,7 +426,7 @@ auto PI::Read(u32 addr) const -> u32 { 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 |= (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; } case 0x04600014: diff --git a/src/backend/core/mmio/SI.cpp b/src/backend/core/mmio/SI.cpp index 47e986d..9bedbd8 100644 --- a/src/backend/core/mmio/SI.cpp +++ b/src/backend/core/mmio/SI.cpp @@ -28,7 +28,7 @@ auto SI::Read(u32 addr) const -> u32 { val |= status.dmaBusy; val |= (0 << 1); val |= (0 << 3); - val |= (mem.mmio.mi.miIntr.si << 12); + val |= (mem.mmio.mi.intr.si << 12); return val; } default: