From 2d74062abb29c63eeccec700e7ff638d465ed3a4 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 3 Jul 2020 00:57:22 +1000 Subject: [PATCH] CPU: Delay interrupts by one instruction/block Fixes Gameshark Sampler Disc. --- src/core/cpu_core.cpp | 10 ++++++++-- src/core/cpu_core.h | 1 + src/core/save_state_version.h | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/core/cpu_core.cpp b/src/core/cpu_core.cpp index 88b4afdac..6faf24ee8 100644 --- a/src/core/cpu_core.cpp +++ b/src/core/cpu_core.cpp @@ -1,7 +1,7 @@ #include "cpu_core.h" +#include "common/align.h" #include "common/log.h" #include "common/state_wrapper.h" -#include "common/align.h" #include "cpu_disasm.h" #include Log_SetChannel(CPU::Core); @@ -93,6 +93,8 @@ bool Core::DoState(StateWrapper& sw) sw.Do(&m_current_instruction_was_branch_taken); sw.Do(&m_next_instruction_is_branch_delay_slot); sw.Do(&m_branch_was_taken); + sw.Do(&m_exception_raised); + sw.Do(&m_interrupt_delay); sw.Do(&m_load_delay_reg); sw.Do(&m_load_delay_value); sw.Do(&m_next_load_delay_reg); @@ -328,6 +330,7 @@ void Core::RaiseException(Exception excode, u32 EPC, bool BD, bool BT, u8 CE) void Core::SetExternalInterrupt(u8 bit) { m_cop0_regs.cause.Ip |= static_cast(1u << bit); + m_interrupt_delay = 1; } void Core::ClearExternalInterrupt(u8 bit) @@ -341,7 +344,10 @@ bool Core::HasPendingInterrupt() const bool do_interrupt = m_cop0_regs.sr.IEc && (((m_cop0_regs.cause.bits & m_cop0_regs.sr.bits) & (UINT32_C(0xFF) << 8)) != 0); - return do_interrupt; + const bool interrupt_delay = m_interrupt_delay; + m_interrupt_delay = false; + + return do_interrupt && !interrupt_delay; } void Core::DispatchInterrupt() diff --git a/src/core/cpu_core.h b/src/core/cpu_core.h index d91cf0dfd..ce07632be 100644 --- a/src/core/cpu_core.h +++ b/src/core/cpu_core.h @@ -155,6 +155,7 @@ private: bool m_next_instruction_is_branch_delay_slot = false; bool m_branch_was_taken = false; bool m_exception_raised = false; + bool m_interrupt_delay = false; // load delays Reg m_load_delay_reg = Reg::count; diff --git a/src/core/save_state_version.h b/src/core/save_state_version.h index b7cfb1c5b..ea9999566 100644 --- a/src/core/save_state_version.h +++ b/src/core/save_state_version.h @@ -2,7 +2,7 @@ #include "types.h" static constexpr u32 SAVE_STATE_MAGIC = 0x43435544; -static constexpr u32 SAVE_STATE_VERSION = 37; +static constexpr u32 SAVE_STATE_VERSION = 38; #pragma pack(push, 4) struct SAVE_STATE_HEADER