From 6b28b3929a60a63b68216fbe2c60712b1da30ea0 Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 24 Feb 2013 21:32:14 +1100 Subject: [PATCH] Delayed the interrupts in the EXI Channel. Fixes issue 5580. --- Source/Core/Core/Src/HW/EXI_Channel.cpp | 14 +++++++++----- Source/Core/Core/Src/HW/EXI_Channel.h | 4 +++- Source/Core/Core/Src/HW/ProcessorInterface.cpp | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/HW/EXI_Channel.cpp b/Source/Core/Core/Src/HW/EXI_Channel.cpp index b38009f0b1..f31fc59b3f 100644 --- a/Source/Core/Core/Src/HW/EXI_Channel.cpp +++ b/Source/Core/Core/Src/HW/EXI_Channel.cpp @@ -25,9 +25,9 @@ #define EXI_WRITE 1 #define EXI_READWRITE 2 - #include "ProcessorInterface.h" #include "../PowerPC/PowerPC.h" +#include "CoreTiming.h" CEXIChannel::CEXIChannel(u32 ChannelId) : m_DMAMemoryAddress(0), @@ -45,6 +45,8 @@ CEXIChannel::CEXIChannel(u32 ChannelId) : for (int i = 0; i < NUM_DEVICES; i++) m_pDevices[i] = EXIDevice_Create(EXIDEVICE_NONE, m_ChannelId); + + updateInterrupts = CoreTiming::RegisterEvent("EXIInterrupt", UpdateInterrupts); } CEXIChannel::~CEXIChannel() @@ -88,12 +90,12 @@ void CEXIChannel::AddDevice(IEXIDevice* pDevice, const int device_num, bool noti if (m_ChannelId != 2) { m_Status.EXTINT = 1; - UpdateInterrupts(); + CoreTiming::ScheduleEvent_Threadsafe_Immediate(updateInterrupts, 0); } } } -void CEXIChannel::UpdateInterrupts() +void CEXIChannel::UpdateInterrupts(u64 userdata, int cyclesLate) { ExpansionInterface::UpdateInterrupts(); } @@ -149,7 +151,9 @@ void CEXIChannel::Read32(u32& _uReturnValue, const u32 _iRegister) if (m_ChannelId == 2) m_Status.EXT = 0; else + { m_Status.EXT = GetDevice(1)->IsPresent() ? 1 : 0; + } _uReturnValue = m_Status.Hex; break; @@ -213,7 +217,7 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister) if (pDevice != NULL) pDevice->SetCS(m_Status.CHIP_SELECT); - UpdateInterrupts(); + CoreTiming::ScheduleEvent_Threadsafe_Immediate(updateInterrupts, 0); } break; @@ -264,7 +268,7 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister) if(!m_Control.TSTART) // completed ! { m_Status.TCINT = 1; - UpdateInterrupts(); + CoreTiming::ScheduleEvent_Threadsafe_Immediate(updateInterrupts, 0); } } break; diff --git a/Source/Core/Core/Src/HW/EXI_Channel.h b/Source/Core/Core/Src/HW/EXI_Channel.h index ef6c0a4e0f..dfbd8558f9 100644 --- a/Source/Core/Core/Src/HW/EXI_Channel.h +++ b/Source/Core/Core/Src/HW/EXI_Channel.h @@ -110,6 +110,9 @@ private: // Since channels operate a bit differently from each other u32 m_ChannelId; + int updateInterrupts; + + static void UpdateInterrupts(u64 userdata, int cyclesLate); public: // get device IEXIDevice* GetDevice(const u8 _CHIP_SELECT); @@ -129,7 +132,6 @@ public: void Update(); bool IsCausingInterrupt(); - void UpdateInterrupts(); void DoState(PointerWrap &p); void PauseAndLock(bool doLock, bool unpauseOnUnlock); diff --git a/Source/Core/Core/Src/HW/ProcessorInterface.cpp b/Source/Core/Core/Src/HW/ProcessorInterface.cpp index 9e72cc2169..d4142efaae 100644 --- a/Source/Core/Core/Src/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/Src/HW/ProcessorInterface.cpp @@ -99,7 +99,7 @@ void Init() m_ResetCode = 0x80000000; // Cold reset m_InterruptCause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI; - toggleResetButton = CoreTiming::RegisterEvent("ToggleResetButton", &ToggleResetButtonCallback); + toggleResetButton = CoreTiming::RegisterEvent("ToggleResetButton", ToggleResetButtonCallback); } void Read16(u16& _uReturnValue, const u32 _iAddress)