Core: Change COP0 registers to use an enum

This commit is contained in:
zilmar 2022-11-07 09:24:58 +10:30
parent 0503f32034
commit b3c6858b69
5 changed files with 83 additions and 46 deletions

View File

@ -1798,22 +1798,22 @@ void R4300iOp::REGIMM_TNEI()
void R4300iOp::COP0_MF() void R4300iOp::COP0_MF()
{ {
_GPR[m_Opcode.rt].DW = (int32_t)g_Reg->Cop0_MF(m_Opcode.rd); _GPR[m_Opcode.rt].DW = (int32_t)g_Reg->Cop0_MF((CRegisters::COP0Reg)m_Opcode.rd);
} }
void R4300iOp::COP0_DMF() void R4300iOp::COP0_DMF()
{ {
_GPR[m_Opcode.rt].DW = g_Reg->Cop0_MF(m_Opcode.rd); _GPR[m_Opcode.rt].DW = g_Reg->Cop0_MF((CRegisters::COP0Reg)m_Opcode.rd);
} }
void R4300iOp::COP0_MT() void R4300iOp::COP0_MT()
{ {
g_Reg->Cop0_MT(m_Opcode.rd, (int64_t)_GPR[m_Opcode.rt].W[0]); g_Reg->Cop0_MT((CRegisters::COP0Reg)m_Opcode.rd, (int64_t)_GPR[m_Opcode.rt].W[0]);
} }
void R4300iOp::COP0_DMT() void R4300iOp::COP0_DMT()
{ {
g_Reg->Cop0_MT(m_Opcode.rd, _GPR[m_Opcode.rt].UDW); g_Reg->Cop0_MT((CRegisters::COP0Reg)m_Opcode.rd, _GPR[m_Opcode.rt].UDW);
} }
// COP0 CO functions // COP0 CO functions

View File

@ -1103,7 +1103,7 @@ void R4300iOp32::REGIMM_BGEZAL()
void R4300iOp32::COP0_MF() void R4300iOp32::COP0_MF()
{ {
_GPR[m_Opcode.rt].W[0] = (int32_t)g_Reg->Cop0_MF(m_Opcode.rd); _GPR[m_Opcode.rt].W[0] = (int32_t)g_Reg->Cop0_MF((CRegisters::COP0Reg)m_Opcode.rd);
} }
// COP1 functions // COP1 functions

View File

@ -331,28 +331,28 @@ void CRegisters::SetAsCurrentSystem()
_RoundingModel = &m_RoundingModel; _RoundingModel = &m_RoundingModel;
} }
uint64_t CRegisters::Cop0_MF(uint32_t Reg) uint64_t CRegisters::Cop0_MF(COP0Reg Reg)
{ {
if (LogCP0reads() && Reg <= 0x1F) if (LogCP0reads() && Reg <= COP0Reg_31)
{ {
LogMessage("%08X: R4300i read from %s (0x%08X)", (*_PROGRAM_COUNTER), CRegName::Cop0[Reg], m_CP0[Reg]); LogMessage("%08X: R4300i read from %s (0x%08X)", (*_PROGRAM_COUNTER), CRegName::Cop0[Reg], m_CP0[Reg]);
} }
if (Reg == 9) if (Reg == COP0Reg_Count || Reg == COP0Reg_Wired || Reg == COP0Reg_Random)
{ {
g_SystemTimer->UpdateTimers(); g_SystemTimer->UpdateTimers();
} }
else if (Reg == 7 || Reg == 21 || Reg == 22 || Reg == 23 || Reg == 24 || Reg == 25 || Reg == 31) else if (Reg == COP0Reg_7 || Reg == COP0Reg_21 || Reg == COP0Reg_22 || Reg == COP0Reg_23 || Reg == COP0Reg_24 || Reg == COP0Reg_25 || Reg == COP0Reg_31)
{ {
// Unused registers // Unused registers
return m_CP0Latch; return m_CP0Latch;
} }
return Reg <= 0x1F ? m_CP0[Reg] : 0; return Reg <= COP0Reg_31 ? m_CP0[Reg] : 0;
} }
void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value) void CRegisters::Cop0_MT(COP0Reg Reg, uint64_t Value)
{ {
if (LogCP0changes() && Reg <= 0x1F) if (LogCP0changes() && Reg <= COP0Reg_31)
{ {
LogMessage("%08X: Writing 0x%I64U to %s register (originally: 0x%I64U)", (*_PROGRAM_COUNTER), Value, CRegName::Cop0[Reg], m_CP0[Reg]); LogMessage("%08X: Writing 0x%I64U to %s register (originally: 0x%I64U)", (*_PROGRAM_COUNTER), Value, CRegName::Cop0[Reg], m_CP0[Reg]);
if (Reg == 11) // Compare if (Reg == 11) // Compare
@ -364,42 +364,43 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
switch (Reg) switch (Reg)
{ {
case 0: // Index case COP0Reg_Index:
case 2: // EntryLo0 case COP0Reg_EntryLo0:
case 3: // EntryLo1 case COP0Reg_EntryLo1:
case 5: // PageMask case COP0Reg_PageMask:
case 10: // Entry Hi case COP0Reg_EntryHi:
case 14: // EPC case COP0Reg_EPC:
case 18: // WatchLo case COP0Reg_WatchLo:
case 19: // WatchHi case COP0Reg_WatchHi:
case 28: // Tag lo case COP0Reg_TagLo:
case 29: // Tag Hi case COP0Reg_TagHi:
case 30: // ErrEPC case COP0Reg_ErrEPC:
case 31: // Reg31 case COP0Reg_31:
m_CP0[Reg] = Value; m_CP0[Reg] = Value;
break; break;
case 4: // Context case COP0Reg_Context:
m_CP0[Reg] = (Value & 0xFFFFFFFFFF800000) | (m_CP0[Reg] & 0x7FFFF0); m_CP0[Reg] = (Value & 0xFFFFFFFFFF800000) | (m_CP0[Reg] & 0x7FFFF0);
break; break;
case 6: // Wired case COP0Reg_Wired:
g_SystemTimer->UpdateTimers(); g_SystemTimer->UpdateTimers();
m_CP0[Reg] = Value & 0x3F; m_CP0[Reg] = Value & 0x3F;
break; break;
case 7: // Reg7 - Unused case COP0Reg_7:
case 8: // BadVaddr - read only case COP0Reg_BadVAddr:
// Read only
break; break;
case 9: // Count case COP0Reg_Count:
g_SystemTimer->UpdateTimers(); g_SystemTimer->UpdateTimers();
m_CP0[Reg] = Value; m_CP0[Reg] = Value;
g_SystemTimer->UpdateCompareTimer(); g_SystemTimer->UpdateCompareTimer();
break; break;
case 11: // Compare case COP0Reg_Compare:
g_SystemTimer->UpdateTimers(); g_SystemTimer->UpdateTimers();
m_CP0[Reg] = Value; m_CP0[Reg] = Value;
FAKE_CAUSE_REGISTER &= ~CAUSE_IP7; FAKE_CAUSE_REGISTER &= ~CAUSE_IP7;
g_SystemTimer->UpdateCompareTimer(); g_SystemTimer->UpdateCompareTimer();
break; break;
case 12: // Status case COP0Reg_Status:
{ {
bool FRBitChanged = (m_CP0[Reg] & STATUS_FR) != (Value & STATUS_FR); bool FRBitChanged = (m_CP0[Reg] & STATUS_FR) != (Value & STATUS_FR);
m_CP0[Reg] = Value & 0xFFF7FFFF; m_CP0[Reg] = Value & 0xFFF7FFFF;
@ -410,34 +411,36 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
CheckInterrupts(); CheckInterrupts();
break; break;
} }
case 13: // Cause case COP0Reg_Cause:
m_CP0[Reg] &= 0xFFFFCFF; m_CP0[Reg] &= 0xFFFFCFF;
if ((Value & 0x300) != 0 && HaveDebugger()) if ((Value & 0x300) != 0 && HaveDebugger())
{ {
g_Notify->DisplayError("Set IP0 or IP1"); g_Notify->DisplayError("Set IP0 or IP1");
} }
break; break;
case 15: // PRId - read only case COP0Reg_PRId:
// Read only
break; break;
case 16: // Config case COP0Reg_Config:
m_CP0[Reg] = (Value & 0x3F00800F) | (m_CP0[Reg] & 0xC0FF7FF0); m_CP0[Reg] = (Value & 0x3F00800F) | (m_CP0[Reg] & 0xC0FF7FF0);
break; break;
case 17: // LLAdrr case COP0Reg_LLAddr:
m_CP0[Reg] = (Value & 0xFFFFFFFF) | (m_CP0[Reg] & 0xFFFFFFFF00000000); m_CP0[Reg] = (Value & 0xFFFFFFFF) | (m_CP0[Reg] & 0xFFFFFFFF00000000);
break; break;
case 20: // XContext case COP0Reg_XContext:
m_CP0[Reg] = (Value & 0xFFFFFFFE00000000) | (m_CP0[Reg] & 0x00000001FFFFFFFF); m_CP0[Reg] = (Value & 0xFFFFFFFE00000000) | (m_CP0[Reg] & 0x00000001FFFFFFFF);
break; break;
case 21: // Reg21 - unused case COP0Reg_21:
case 22: // Reg22 - unused case COP0Reg_22:
case 23: // Reg23 - unused case COP0Reg_23:
case 24: // Reg24 - unused case COP0Reg_24:
case 25: // Reg25 - unused case COP0Reg_25:
// Unused
break; break;
case 26: // ParityError case COP0Reg_ParityError:
m_CP0[Reg] = Value & 0xFF; m_CP0[Reg] = Value & 0xFF;
break; break;
case 27: // CacheErr - read only case COP0Reg_CacheErr:
break; break;
default: default:
if (HaveDebugger()) if (HaveDebugger())

View File

@ -302,6 +302,41 @@ class CRegisters :
public DiskInterfaceReg public DiskInterfaceReg
{ {
public: public:
enum COP0Reg : uint32_t
{
COP0Reg_Index = 0,
COP0Reg_Random = 1,
COP0Reg_EntryLo0 = 2,
COP0Reg_EntryLo1 = 3,
COP0Reg_Context = 4,
COP0Reg_PageMask = 5,
COP0Reg_Wired = 6,
COP0Reg_7 = 7,
COP0Reg_BadVAddr = 8,
COP0Reg_Count = 9,
COP0Reg_EntryHi = 10,
COP0Reg_Compare = 11,
COP0Reg_Status = 12,
COP0Reg_Cause = 13,
COP0Reg_EPC = 14,
COP0Reg_PRId = 15,
COP0Reg_Config = 16,
COP0Reg_LLAddr = 17,
COP0Reg_WatchLo = 18,
COP0Reg_WatchHi = 19,
COP0Reg_XContext = 20,
COP0Reg_21 = 21,
COP0Reg_22 = 22,
COP0Reg_23 = 23,
COP0Reg_24 = 24,
COP0Reg_25 = 25,
COP0Reg_ParityError = 26,
COP0Reg_CacheErr = 27,
COP0Reg_TagLo = 28,
COP0Reg_TagHi = 29,
COP0Reg_ErrEPC = 30,
COP0Reg_31 = 31,
};
CRegisters(CN64System * System, CSystemEvents * SystemEvents); CRegisters(CN64System * System, CSystemEvents * SystemEvents);
void CheckInterrupts(); void CheckInterrupts();
@ -319,8 +354,8 @@ public:
void Reset(); void Reset();
void SetAsCurrentSystem(); void SetAsCurrentSystem();
uint64_t Cop0_MF(uint32_t Reg); uint64_t Cop0_MF(COP0Reg Reg);
void Cop0_MT(uint32_t Reg, uint64_t Value); void Cop0_MT(COP0Reg Reg, uint64_t Value);
// General registers // General registers
uint32_t m_PROGRAM_COUNTER; uint32_t m_PROGRAM_COUNTER;

View File

@ -64,7 +64,6 @@ public:
void WriteX86Comment(const char * Comment); void WriteX86Comment(const char * Comment);
void WriteX86Label(const char * Label); void WriteX86Label(const char * Label);
void AdcX86regToVariable(x86Reg reg, void * Variable, const char * VariableName);
void AdcConstToVariable(void * Variable, const char * VariableName, uint8_t Constant); void AdcConstToVariable(void * Variable, const char * VariableName, uint8_t Constant);
void AdcConstToX86Reg(x86Reg Reg, uint32_t Const); void AdcConstToX86Reg(x86Reg Reg, uint32_t Const);
void AdcVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName); void AdcVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName);