Core: Clean up masking of COP0 registers
This commit is contained in:
parent
9186dcab39
commit
53e00b8023
|
@ -290,6 +290,7 @@ void CRegisters::Reset()
|
||||||
memset(m_CP0, 0, sizeof(m_CP0));
|
memset(m_CP0, 0, sizeof(m_CP0));
|
||||||
memset(m_FPR, 0, sizeof(m_FPR));
|
memset(m_FPR, 0, sizeof(m_FPR));
|
||||||
memset(m_FPCR, 0, sizeof(m_FPCR));
|
memset(m_FPCR, 0, sizeof(m_FPCR));
|
||||||
|
m_CP0Latch = 0;
|
||||||
m_HI.DW = 0;
|
m_HI.DW = 0;
|
||||||
m_LO.DW = 0;
|
m_LO.DW = 0;
|
||||||
m_RoundingModel = FE_TONEAREST;
|
m_RoundingModel = FE_TONEAREST;
|
||||||
|
@ -341,6 +342,11 @@ uint64_t CRegisters::Cop0_MF(uint32_t Reg)
|
||||||
{
|
{
|
||||||
g_SystemTimer->UpdateTimers();
|
g_SystemTimer->UpdateTimers();
|
||||||
}
|
}
|
||||||
|
else if (Reg == 7 || Reg == 21 || Reg == 22 || Reg == 23 || Reg == 24 || Reg == 25 || Reg == 31)
|
||||||
|
{
|
||||||
|
// Unused registers
|
||||||
|
return m_CP0Latch;
|
||||||
|
}
|
||||||
return Reg <= 0x1F ? m_CP0[Reg] : 0;
|
return Reg <= 0x1F ? m_CP0[Reg] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,6 +360,7 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
|
||||||
LogMessage("%08X: Cause register changed from %08X to %08X", (*_PROGRAM_COUNTER), CAUSE_REGISTER, (g_Reg->CAUSE_REGISTER & ~CAUSE_IP7));
|
LogMessage("%08X: Cause register changed from %08X to %08X", (*_PROGRAM_COUNTER), CAUSE_REGISTER, (g_Reg->CAUSE_REGISTER & ~CAUSE_IP7));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_CP0Latch = Value;
|
||||||
|
|
||||||
switch (Reg)
|
switch (Reg)
|
||||||
{
|
{
|
||||||
|
@ -361,36 +368,26 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
|
||||||
case 2: // EntryLo0
|
case 2: // EntryLo0
|
||||||
case 3: // EntryLo1
|
case 3: // EntryLo1
|
||||||
case 5: // PageMask
|
case 5: // PageMask
|
||||||
case 7: // Reg7
|
|
||||||
case 8: // BadVaddr
|
|
||||||
case 10: // Entry Hi
|
case 10: // Entry Hi
|
||||||
case 14: // EPC
|
case 14: // EPC
|
||||||
case 15: // PRId
|
|
||||||
case 16: // Config
|
|
||||||
case 17: // LLAdrr
|
|
||||||
case 18: // WatchLo
|
case 18: // WatchLo
|
||||||
case 19: // WatchHi
|
case 19: // WatchHi
|
||||||
case 20: // XContext
|
|
||||||
case 21: // Reg21
|
|
||||||
case 22: // Reg22
|
|
||||||
case 23: // Reg23
|
|
||||||
case 24: // Reg24
|
|
||||||
case 25: // Reg25
|
|
||||||
case 26: // ECC
|
|
||||||
case 27: // CacheErr
|
|
||||||
case 28: // Tag lo
|
case 28: // Tag lo
|
||||||
case 29: // Tag Hi
|
case 29: // Tag Hi
|
||||||
case 30: // ErrEPC
|
case 30: // ErrEPC
|
||||||
case 31: // Reg31
|
case 31: // Reg31
|
||||||
m_CP0[Reg] = Value;
|
m_CP0[Reg] = Value;
|
||||||
break;
|
break;
|
||||||
case 6: // Wired
|
|
||||||
g_SystemTimer->UpdateTimers();
|
|
||||||
m_CP0[Reg] = Value;
|
|
||||||
break;
|
|
||||||
case 4: // Context
|
case 4: // Context
|
||||||
m_CP0[Reg] = (Value & 0xFFFFFFFFFF800000) | (m_CP0[Reg] & 0x7FFFF0);
|
m_CP0[Reg] = (Value & 0xFFFFFFFFFF800000) | (m_CP0[Reg] & 0x7FFFF0);
|
||||||
break;
|
break;
|
||||||
|
case 6: // Wired
|
||||||
|
g_SystemTimer->UpdateTimers();
|
||||||
|
m_CP0[Reg] = Value & 0x3F;
|
||||||
|
break;
|
||||||
|
case 7: // Reg7 - Unused
|
||||||
|
case 8: // BadVaddr - read only
|
||||||
|
break;
|
||||||
case 9: // Count
|
case 9: // Count
|
||||||
g_SystemTimer->UpdateTimers();
|
g_SystemTimer->UpdateTimers();
|
||||||
m_CP0[Reg] = Value;
|
m_CP0[Reg] = Value;
|
||||||
|
@ -403,21 +400,16 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
|
||||||
g_SystemTimer->UpdateCompareTimer();
|
g_SystemTimer->UpdateCompareTimer();
|
||||||
break;
|
break;
|
||||||
case 12: // Status
|
case 12: // Status
|
||||||
if ((m_CP0[Reg] & STATUS_FR) != (Value & STATUS_FR))
|
|
||||||
{
|
{
|
||||||
m_CP0[Reg] = Value;
|
bool FRBitChanged = (m_CP0[Reg] & STATUS_FR) != (Value & STATUS_FR);
|
||||||
|
m_CP0[Reg] = Value & 0xFFF7FFFF;
|
||||||
|
if (FRBitChanged)
|
||||||
|
{
|
||||||
FixFpuLocations();
|
FixFpuLocations();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_CP0[Reg] = Value;
|
|
||||||
}
|
|
||||||
if ((m_CP0[Reg] & 0x18) != 0 && HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->DisplayError("Left kernel mode ??");
|
|
||||||
}
|
|
||||||
CheckInterrupts();
|
CheckInterrupts();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 13: // Cause
|
case 13: // Cause
|
||||||
m_CP0[Reg] &= 0xFFFFCFF;
|
m_CP0[Reg] &= 0xFFFFCFF;
|
||||||
if ((Value & 0x300) != 0 && HaveDebugger())
|
if ((Value & 0x300) != 0 && HaveDebugger())
|
||||||
|
@ -425,6 +417,28 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
|
||||||
g_Notify->DisplayError("Set IP0 or IP1");
|
g_Notify->DisplayError("Set IP0 or IP1");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 15: // PRId - read only
|
||||||
|
break;
|
||||||
|
case 16: // Config
|
||||||
|
m_CP0[Reg] = (Value & 0x3F00800F) | (m_CP0[Reg] & 0xC0FF7FF0);
|
||||||
|
break;
|
||||||
|
case 17: // LLAdrr
|
||||||
|
m_CP0[Reg] = (Value & 0xFFFFFFFF) | (m_CP0[Reg] & 0xFFFFFFFF00000000);
|
||||||
|
break;
|
||||||
|
case 20: // XContext
|
||||||
|
m_CP0[Reg] = (Value & 0xFFFFFFFE00000000) | (m_CP0[Reg] & 0x00000001FFFFFFFF);
|
||||||
|
break;
|
||||||
|
case 21: // Reg21 - unused
|
||||||
|
case 22: // Reg22 - unused
|
||||||
|
case 23: // Reg23 - unused
|
||||||
|
case 24: // Reg24 - unused
|
||||||
|
case 25: // Reg25 - unused
|
||||||
|
break;
|
||||||
|
case 26: // ParityError
|
||||||
|
m_CP0[Reg] = Value & 0xFF;
|
||||||
|
break;
|
||||||
|
case 27: // CacheErr - read only
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (HaveDebugger())
|
if (HaveDebugger())
|
||||||
{
|
{
|
||||||
|
|
|
@ -326,6 +326,7 @@ public:
|
||||||
uint32_t m_PROGRAM_COUNTER;
|
uint32_t m_PROGRAM_COUNTER;
|
||||||
MIPS_DWORD m_GPR[32];
|
MIPS_DWORD m_GPR[32];
|
||||||
uint64_t m_CP0[33];
|
uint64_t m_CP0[33];
|
||||||
|
uint64_t m_CP0Latch;
|
||||||
MIPS_DWORD m_HI;
|
MIPS_DWORD m_HI;
|
||||||
MIPS_DWORD m_LO;
|
MIPS_DWORD m_LO;
|
||||||
uint32_t m_LLBit;
|
uint32_t m_LLBit;
|
||||||
|
|
Loading…
Reference in New Issue