diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp index 11b7d8e70..641770fb3 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp @@ -27,10 +27,10 @@ void CInterpreterCPU::BuildCPU() void CInterpreterCPU::InPermLoop() { if (EndOnPermLoop() && - ((g_Reg->STATUS_REGISTER & STATUS_IE) == 0 || - (g_Reg->STATUS_REGISTER & STATUS_EXL) != 0 || - (g_Reg->STATUS_REGISTER & STATUS_ERL) != 0 || - (g_Reg->STATUS_REGISTER & 0xFF00) == 0)) + ((g_Reg->STATUS_REGISTER.InterruptEnable) == 0 || + (g_Reg->STATUS_REGISTER.ExceptionLevel) != 0 || + (g_Reg->STATUS_REGISTER.ErrorLevel) != 0 || + (g_Reg->STATUS_REGISTER.InterruptMask) == 0)) { if (g_Plugins->Gfx()->UpdateScreen != nullptr) { diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 756b8f95e..3e4ebf554 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -1869,15 +1869,15 @@ void R4300iOp::COP0_CO_TLBP() void R4300iOp::COP0_CO_ERET() { g_System->m_PipelineStage = PIPELINE_STAGE_JUMP; - if ((g_Reg->STATUS_REGISTER & STATUS_ERL) != 0) + if ((g_Reg->STATUS_REGISTER.ErrorLevel) != 0) { g_System->m_JumpToLocation = (uint32_t)g_Reg->ERROREPC_REGISTER; - g_Reg->STATUS_REGISTER &= ~STATUS_ERL; + g_Reg->STATUS_REGISTER.ErrorLevel = 0; } else { g_System->m_JumpToLocation = (uint32_t)g_Reg->EPC_REGISTER; - g_Reg->STATUS_REGISTER &= ~STATUS_EXL; + g_Reg->STATUS_REGISTER.ExceptionLevel = 0; } (*_LLBit) = 0; g_Reg->CheckInterrupts(); @@ -2928,12 +2928,12 @@ void R4300iOp::COP1_L_CVT_D() // COP2 functions void R4300iOp::CPO2_INVALID_OP(void) { - g_Reg->TriggerException((g_Reg->STATUS_REGISTER & STATUS_CU2) == 0 ? EXC_CPU : EXC_II, 2); + g_Reg->TriggerException(g_Reg->STATUS_REGISTER.CU2 == 0 ? EXC_CPU : EXC_II, 2); } void R4300iOp::COP2_MF() { - if ((g_Reg->STATUS_REGISTER & STATUS_CU2) == 0) + if (g_Reg->STATUS_REGISTER.CU2 == 0) { g_Reg->TriggerException(EXC_CPU, 2); } @@ -2945,7 +2945,7 @@ void R4300iOp::COP2_MF() void R4300iOp::COP2_DMF() { - if ((g_Reg->STATUS_REGISTER & STATUS_CU2) == 0) + if (g_Reg->STATUS_REGISTER.CU2 == 0) { g_Reg->TriggerException(EXC_CPU, 2); } @@ -2957,7 +2957,7 @@ void R4300iOp::COP2_DMF() void R4300iOp::COP2_CF() { - if ((g_Reg->STATUS_REGISTER & STATUS_CU2) == 0) + if (g_Reg->STATUS_REGISTER.CU2 == 0) { g_Reg->TriggerException(EXC_CPU, 2); } @@ -2969,7 +2969,7 @@ void R4300iOp::COP2_CF() void R4300iOp::COP2_MT() { - if ((g_Reg->STATUS_REGISTER & STATUS_CU2) == 0) + if (g_Reg->STATUS_REGISTER.CU2 == 0) { g_Reg->TriggerException(EXC_CPU, 2); } @@ -2981,7 +2981,7 @@ void R4300iOp::COP2_MT() void R4300iOp::COP2_DMT() { - if ((g_Reg->STATUS_REGISTER & STATUS_CU2) == 0) + if (g_Reg->STATUS_REGISTER.CU2 == 0) { g_Reg->TriggerException(EXC_CPU, 2); } @@ -2993,7 +2993,7 @@ void R4300iOp::COP2_DMT() void R4300iOp::COP2_CT() { - if ((g_Reg->STATUS_REGISTER & STATUS_CU2) == 0) + if (g_Reg->STATUS_REGISTER.CU2 == 0) { g_Reg->TriggerException(EXC_CPU, 2); } @@ -3074,7 +3074,7 @@ void R4300iOp::GenerateTLBWriteException(uint64_t VAddr, const char * function) bool R4300iOp::TestCop1UsableException(void) { - if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) + if (g_Reg->STATUS_REGISTER.CU1 == 0) { g_Reg->TriggerException(EXC_CPU, 1); return true; diff --git a/Source/Project64-core/N64System/Mips/Register.cpp b/Source/Project64-core/N64System/Mips/Register.cpp index c4ffe47e4..3eae6a136 100644 --- a/Source/Project64-core/N64System/Mips/Register.cpp +++ b/Source/Project64-core/N64System/Mips/Register.cpp @@ -239,7 +239,7 @@ CP0registers::CP0registers(uint64_t * _CP0) : COUNT_REGISTER(_CP0[9]), ENTRYHI_REGISTER(_CP0[10]), COMPARE_REGISTER(_CP0[11]), - STATUS_REGISTER(_CP0[12]), + STATUS_REGISTER((COP0Status &)_CP0[12]), CAUSE_REGISTER((COP0Cause &)_CP0[13]), EPC_REGISTER(_CP0[14]), PREVID_REGISTER(_CP0[15]), @@ -411,8 +411,8 @@ void CRegisters::Cop0_MT(COP0Reg Reg, uint64_t Value) break; case COP0Reg_Status: { - bool FRBitChanged = (m_CP0[Reg] & STATUS_FR) != (Value & STATUS_FR); - m_CP0[Reg] = Value & 0xFFF7FFFF; + bool FRBitChanged = STATUS_REGISTER.FR != ((COP0Status &)Value).FR; + STATUS_REGISTER.Value = Value & 0xFFF7FFFF; if (FRBitChanged) { FixFpuLocations(); @@ -490,7 +490,7 @@ void CRegisters::Cop2_MT(uint32_t /*Reg*/, uint64_t Value) void CRegisters::CheckInterrupts() { - uint32_t mi_intr_reg = MI_INTR_REG, status_register; + uint32_t mi_intr_reg = MI_INTR_REG; if (!m_System->bFixedAudio() && CpuType() != CPU_SyncCores) { mi_intr_reg &= ~MI_INTR_AI; @@ -507,22 +507,14 @@ void CRegisters::CheckInterrupts() CAUSE_REGISTER.PendingInterrupts &= ~CAUSE_IP2; } MI_INTR_REG = mi_intr_reg; - status_register = (uint32_t)STATUS_REGISTER; + COP0Status STATUS_REGISTER_Value = STATUS_REGISTER; - if ((status_register & STATUS_IE) == 0) - { - return; - } - if ((status_register & STATUS_EXL) != 0) - { - return; - } - if ((status_register & STATUS_ERL) != 0) + if (STATUS_REGISTER_Value.InterruptEnable == 0 || STATUS_REGISTER_Value.ExceptionLevel != 0 || STATUS_REGISTER_Value.ErrorLevel != 0) { return; } - if ((status_register & CAUSE_REGISTER.Value & 0xFF00) != 0) + if ((STATUS_REGISTER_Value.Value & CAUSE_REGISTER.Value & 0xFF00) != 0) { if (m_FirstInterupt) { @@ -567,13 +559,13 @@ void CRegisters::DoAddressError(bool DelaySlot, uint64_t BadVaddr, bool FromRead CAUSE_REGISTER.BranchDelay = 0; EPC_REGISTER = (int32_t)m_PROGRAM_COUNTER; } - STATUS_REGISTER |= STATUS_EXL; + STATUS_REGISTER.ExceptionLevel = 1; m_PROGRAM_COUNTER = 0x80000180; } void CRegisters::FixFpuLocations() { - if ((STATUS_REGISTER & STATUS_FR) == 0) + if (STATUS_REGISTER.FR == 0) { for (int count = 0; count < 32; count++) { @@ -593,7 +585,7 @@ void CRegisters::FixFpuLocations() bool CRegisters::DoIntrException() { - if ((STATUS_REGISTER & STATUS_IE) == 0 || (STATUS_REGISTER & STATUS_EXL) != 0 || (STATUS_REGISTER & STATUS_ERL) != 0) + if (STATUS_REGISTER.InterruptEnable == 0 || STATUS_REGISTER.ExceptionLevel != 0 || STATUS_REGISTER.ErrorLevel != 0) { return false; } @@ -608,7 +600,7 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr) BAD_VADDR_REGISTER = BadVaddr; CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000); - if ((STATUS_REGISTER & STATUS_EXL) == 0) + if ((STATUS_REGISTER.ExceptionLevel) == 0) { if (DelaySlot) { @@ -628,7 +620,7 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr) { m_PROGRAM_COUNTER = 0x80000000; } - STATUS_REGISTER |= STATUS_EXL; + STATUS_REGISTER.ExceptionLevel = 1; } else { @@ -647,7 +639,7 @@ void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr) BAD_VADDR_REGISTER = BadVaddr; CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000); - if ((STATUS_REGISTER & STATUS_EXL) == 0) + if ((STATUS_REGISTER.ExceptionLevel) == 0) { if (DelaySlot) { @@ -667,7 +659,7 @@ void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr) { m_PROGRAM_COUNTER = 0x80000000; } - STATUS_REGISTER |= STATUS_EXL; + STATUS_REGISTER.ExceptionLevel = 1; } else { @@ -697,7 +689,7 @@ void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor) CAUSE_REGISTER.CoprocessorUnitNumber = Coprocessor; CAUSE_REGISTER.BranchDelay = m_System->m_PipelineStage == PIPELINE_STAGE_JUMP; EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - (CAUSE_REGISTER.BranchDelay ? 4 : 0)); - STATUS_REGISTER |= STATUS_EXL; + STATUS_REGISTER.ExceptionLevel = 1; m_System->m_PipelineStage = PIPELINE_STAGE_JUMP; m_System->m_JumpToLocation = 0x80000180; } diff --git a/Source/Project64-core/N64System/Mips/Register.h b/Source/Project64-core/N64System/Mips/Register.h index 521551224..2fc6230e2 100644 --- a/Source/Project64-core/N64System/Mips/Register.h +++ b/Source/Project64-core/N64System/Mips/Register.h @@ -19,6 +19,46 @@ #pragma warning(push) #pragma warning(disable : 4201) // Non-standard extension used: nameless struct/union +enum PRIVILEGE_MODE : unsigned +{ + PrivilegeMode_Kernel, + PrivilegeMode_Supervisor, + PrivilegeMode_User +}; + +union COP0Status +{ + uint64_t Value; + + struct + { + unsigned InterruptEnable : 1; + unsigned ExceptionLevel : 1; + unsigned ErrorLevel : 1; + PRIVILEGE_MODE PrivilegeMode : 2; + unsigned UserExtendedAddressing : 1; + unsigned SupervisorExtendedAddressing : 1; + unsigned KernelExtendedAddressing : 1; + unsigned InterruptMask : 8; + unsigned DE : 1; + unsigned CE : 1; + unsigned CH : 1; + unsigned NMI : 1; + unsigned SR : 1; + unsigned TS : 1; + unsigned BEV : 1; + unsigned : 1; + unsigned : 1; + unsigned RE : 1; + unsigned FR : 1; + unsigned RP : 1; + unsigned CU0 : 1; + unsigned CU1 : 1; + unsigned CU2 : 1; + unsigned CU3 : 1; + }; +}; + union COP0Cause { uint64_t Value; @@ -137,7 +177,7 @@ public: uint64_t & COUNT_REGISTER; uint64_t & ENTRYHI_REGISTER; uint64_t & COMPARE_REGISTER; - uint64_t & STATUS_REGISTER; + COP0Status & STATUS_REGISTER; COP0Cause & CAUSE_REGISTER; uint64_t & EPC_REGISTER; uint64_t & PREVID_REGISTER; diff --git a/Source/Project64-core/N64System/N64System.cpp b/Source/Project64-core/N64System/N64System.cpp index aa3deafa4..eb9372bf1 100644 --- a/Source/Project64-core/N64System/N64System.cpp +++ b/Source/Project64-core/N64System/N64System.cpp @@ -897,7 +897,7 @@ void CN64System::PluginReset() void CN64System::ApplyGSButton(void) { - if ((m_Reg.STATUS_REGISTER & STATUS_IE) != 0) + if (m_Reg.STATUS_REGISTER.InterruptEnable != 0) { g_Enhancements->ApplyGSButton(m_MMU_VM, !m_SyncSystem); } @@ -1037,7 +1037,7 @@ void CN64System::InitRegisters(bool bPostPif, CMipsMemoryVM & MMU) m_Reg.ERROREPC_REGISTER = 0xFFFFFFFFFFFFFFFF; m_Reg.PREVID_REGISTER = 0x00000B22; m_Reg.CONFIG_REGISTER = 0x7006E463; - m_Reg.STATUS_REGISTER = 0x34000000; + m_Reg.STATUS_REGISTER.Value = 0x34000000; // N64DD registers @@ -1822,9 +1822,9 @@ bool CN64System::SaveState() WriteTrace(TraceN64System, TraceDebug, "Start"); // if (!m_SystemTimer.SaveAllowed()) { return false; } - if ((m_Reg.STATUS_REGISTER & STATUS_EXL) != 0) + if (m_Reg.STATUS_REGISTER.ExceptionLevel != 0) { - WriteTrace(TraceN64System, TraceDebug, "Done - STATUS_EXL set, can't save"); + WriteTrace(TraceN64System, TraceDebug, "Done - ExceptionLevel set, can't save"); return false; } @@ -2639,7 +2639,7 @@ void CN64System::RefreshScreen() m_CPU_Usage.ShowCPU_Usage(); m_CPU_Usage.StartTimer(CPU_UsageAddr != Timer_None ? CPU_UsageAddr : Timer_R4300); } - if ((m_Reg.STATUS_REGISTER & STATUS_IE) != 0) + if (m_Reg.STATUS_REGISTER.InterruptEnable != 0) { g_Enhancements->ApplyActive(m_MMU_VM, g_BaseSystem->m_Plugins, !m_SyncSystem); } diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 88196f468..3052749d6 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -7409,15 +7409,15 @@ void CX86RecompilerOps::COP0_CO_TLBP(void) void x86_compiler_COP0_CO_ERET() { - if ((g_Reg->STATUS_REGISTER & STATUS_ERL) != 0) + if (g_Reg->STATUS_REGISTER.ErrorLevel != 0) { g_Reg->m_PROGRAM_COUNTER = (uint32_t)g_Reg->ERROREPC_REGISTER; - g_Reg->STATUS_REGISTER &= ~STATUS_ERL; + g_Reg->STATUS_REGISTER.ErrorLevel = 0; } else { g_Reg->m_PROGRAM_COUNTER = (uint32_t)g_Reg->EPC_REGISTER; - g_Reg->STATUS_REGISTER &= ~STATUS_EXL; + g_Reg->STATUS_REGISTER.ExceptionLevel = 0; } g_Reg->m_LLBit = 0; g_Reg->CheckInterrupts(); diff --git a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp index 16a182941..6d76e8f5f 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp @@ -143,7 +143,7 @@ void CRegisterTabs::RefreshEdits() m_COP0Edits[8].SetValue((uint32_t)g_Reg->COUNT_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[9].SetValue((uint32_t)g_Reg->ENTRYHI_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[10].SetValue((uint32_t)g_Reg->COMPARE_REGISTER, DisplayMode::ZeroExtend); - m_COP0Edits[11].SetValue((uint32_t)g_Reg->STATUS_REGISTER, DisplayMode::ZeroExtend); + m_COP0Edits[11].SetValue((uint32_t)g_Reg->STATUS_REGISTER.Value, DisplayMode::ZeroExtend); m_COP0Edits[12].SetValue((uint32_t)g_Reg->CAUSE_REGISTER.Value, DisplayMode::ZeroExtend); m_COP0Edits[13].SetValue((uint32_t)g_Reg->EPC_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[14].SetValue((uint32_t)g_Reg->CONFIG_REGISTER, DisplayMode::ZeroExtend); @@ -322,7 +322,7 @@ void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam) case IDC_COP0_8_EDIT: g_Reg->COUNT_REGISTER = value; break; case IDC_COP0_9_EDIT: g_Reg->ENTRYHI_REGISTER = value; break; case IDC_COP0_10_EDIT: g_Reg->COMPARE_REGISTER = value; break; - case IDC_COP0_11_EDIT: g_Reg->STATUS_REGISTER = value; break; + case IDC_COP0_11_EDIT: g_Reg->STATUS_REGISTER.Value = value; break; case IDC_COP0_12_EDIT: g_Reg->CAUSE_REGISTER.Value = value; break; case IDC_COP0_13_EDIT: g_Reg->EPC_REGISTER = value; break; case IDC_COP0_14_EDIT: g_Reg->CONFIG_REGISTER = value; break; diff --git a/Source/Project64/UserInterface/Debugger/Debugger.cpp b/Source/Project64/UserInterface/Debugger/Debugger.cpp index a2de06ec0..7999efca9 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger.cpp @@ -630,7 +630,7 @@ void CDebuggerUI::CPUStepStarted() if (pc == 0x80000000 || pc == 0x80000080 || pc == 0xA0000100 || pc == 0x80000180) { - if ((g_Reg->STATUS_REGISTER >> 1) & 3) // If EXL/ERL bits are set + if (g_Reg->STATUS_REGISTER.ExceptionLevel != 0 || g_Reg->STATUS_REGISTER.ErrorLevel != 0) // If EXL/ERL bits are set { HandleCPUException(); }