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()
{
_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()
{
_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()
{
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()
{
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

View File

@ -1103,7 +1103,7 @@ void R4300iOp32::REGIMM_BGEZAL()
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

View File

@ -331,28 +331,28 @@ void CRegisters::SetAsCurrentSystem()
_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]);
}
if (Reg == 9)
if (Reg == COP0Reg_Count || Reg == COP0Reg_Wired || Reg == COP0Reg_Random)
{
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
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]);
if (Reg == 11) // Compare
@ -364,42 +364,43 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
switch (Reg)
{
case 0: // Index
case 2: // EntryLo0
case 3: // EntryLo1
case 5: // PageMask
case 10: // Entry Hi
case 14: // EPC
case 18: // WatchLo
case 19: // WatchHi
case 28: // Tag lo
case 29: // Tag Hi
case 30: // ErrEPC
case 31: // Reg31
case COP0Reg_Index:
case COP0Reg_EntryLo0:
case COP0Reg_EntryLo1:
case COP0Reg_PageMask:
case COP0Reg_EntryHi:
case COP0Reg_EPC:
case COP0Reg_WatchLo:
case COP0Reg_WatchHi:
case COP0Reg_TagLo:
case COP0Reg_TagHi:
case COP0Reg_ErrEPC:
case COP0Reg_31:
m_CP0[Reg] = Value;
break;
case 4: // Context
case COP0Reg_Context:
m_CP0[Reg] = (Value & 0xFFFFFFFFFF800000) | (m_CP0[Reg] & 0x7FFFF0);
break;
case 6: // Wired
case COP0Reg_Wired:
g_SystemTimer->UpdateTimers();
m_CP0[Reg] = Value & 0x3F;
break;
case 7: // Reg7 - Unused
case 8: // BadVaddr - read only
case COP0Reg_7:
case COP0Reg_BadVAddr:
// Read only
break;
case 9: // Count
case COP0Reg_Count:
g_SystemTimer->UpdateTimers();
m_CP0[Reg] = Value;
g_SystemTimer->UpdateCompareTimer();
break;
case 11: // Compare
case COP0Reg_Compare:
g_SystemTimer->UpdateTimers();
m_CP0[Reg] = Value;
FAKE_CAUSE_REGISTER &= ~CAUSE_IP7;
g_SystemTimer->UpdateCompareTimer();
break;
case 12: // Status
case COP0Reg_Status:
{
bool FRBitChanged = (m_CP0[Reg] & STATUS_FR) != (Value & STATUS_FR);
m_CP0[Reg] = Value & 0xFFF7FFFF;
@ -410,34 +411,36 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value)
CheckInterrupts();
break;
}
case 13: // Cause
case COP0Reg_Cause:
m_CP0[Reg] &= 0xFFFFCFF;
if ((Value & 0x300) != 0 && HaveDebugger())
{
g_Notify->DisplayError("Set IP0 or IP1");
}
break;
case 15: // PRId - read only
case COP0Reg_PRId:
// Read only
break;
case 16: // Config
case COP0Reg_Config:
m_CP0[Reg] = (Value & 0x3F00800F) | (m_CP0[Reg] & 0xC0FF7FF0);
break;
case 17: // LLAdrr
case COP0Reg_LLAddr:
m_CP0[Reg] = (Value & 0xFFFFFFFF) | (m_CP0[Reg] & 0xFFFFFFFF00000000);
break;
case 20: // XContext
case COP0Reg_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
case COP0Reg_21:
case COP0Reg_22:
case COP0Reg_23:
case COP0Reg_24:
case COP0Reg_25:
// Unused
break;
case 26: // ParityError
case COP0Reg_ParityError:
m_CP0[Reg] = Value & 0xFF;
break;
case 27: // CacheErr - read only
case COP0Reg_CacheErr:
break;
default:
if (HaveDebugger())

View File

@ -302,6 +302,41 @@ class CRegisters :
public DiskInterfaceReg
{
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);
void CheckInterrupts();
@ -319,8 +354,8 @@ public:
void Reset();
void SetAsCurrentSystem();
uint64_t Cop0_MF(uint32_t Reg);
void Cop0_MT(uint32_t Reg, uint64_t Value);
uint64_t Cop0_MF(COP0Reg Reg);
void Cop0_MT(COP0Reg Reg, uint64_t Value);
// General registers
uint32_t m_PROGRAM_COUNTER;

View File

@ -64,7 +64,6 @@ public:
void WriteX86Comment(const char * Comment);
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 AdcConstToX86Reg(x86Reg Reg, uint32_t Const);
void AdcVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName);