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