small MI refactor in preparation of (eventually) implementing the RDRAM interface properly
This commit is contained in:
@@ -1,50 +1,50 @@
|
||||
#include <Core.hpp>
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user