summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2012-08-24 12:45:45 +0200
committerPierre Bourdon <delroth@gmail.com>2012-08-24 12:45:45 +0200
commit60aed4e5b0971ded7b761ed26da186d47d9f84d4 (patch)
treeccde66f50b472a0744915ec2c3c4c9ad25101e5c /Source/Core
parentbe200074e9ed151df484d9aba5d7abcb1036c8a8 (diff)
parent0b00c95b79dd40ee23d8c960aa6c07a7cbe2c078 (diff)
Merge branch 'memcard-delay'
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp38
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h11
2 files changed, 37 insertions, 12 deletions
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
index 6f4bc502b6..4705e849be 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
+++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
@@ -47,13 +47,22 @@ void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate)
pThis->Flush();
}
+void CEXIMemoryCard::CmdDoneCallback(u64 userdata, int cyclesLate)
+{
+ int card_index = (int)userdata;
+ CEXIMemoryCard* pThis = (CEXIMemoryCard*)ExpansionInterface::FindDevice(EXIDEVICE_MEMORYCARD, card_index);
+ if (pThis)
+ pThis->CmdDone();
+}
+
CEXIMemoryCard::CEXIMemoryCard(const int index)
: card_index(index)
, m_bDirty(false)
{
m_strFilename = (card_index == 0) ? SConfig::GetInstance().m_strMemoryCardA : SConfig::GetInstance().m_strMemoryCardB;
// we're potentially leaking events here, since there's no UnregisterEvent until emu shutdown, but I guess it's inconsequential
- et_this_card = CoreTiming::RegisterEvent((card_index == 0) ? "memcardA" : "memcardB", FlushCallback);
+ et_this_card = CoreTiming::RegisterEvent((card_index == 0) ? "memcardFlushA" : "memcardFlushB", FlushCallback);
+ et_cmd_done = CoreTiming::RegisterEvent((card_index == 0) ? "memcardDoneA" : "memcardDoneB", CmdDoneCallback);
interruptSwitch = 0;
m_bInterruptSet = 0;
@@ -175,6 +184,21 @@ bool CEXIMemoryCard::IsPresent()
return true;
}
+void CEXIMemoryCard::CmdDone()
+{
+ status |= MC_STATUS_READY;
+ status &= ~MC_STATUS_BUSY;
+
+ m_bInterruptSet = 1;
+ m_bDirty = true;
+}
+
+void CEXIMemoryCard::CmdDoneLater(u64 cycles)
+{
+ CoreTiming::RemoveEvent(et_cmd_done);
+ CoreTiming::ScheduleEvent(cycles, et_cmd_done, (u64)card_index);
+}
+
void CEXIMemoryCard::SetCS(int cs)
{
// So that memory card won't be invalidated during flushing
@@ -198,11 +222,7 @@ void CEXIMemoryCard::SetCS(int cs)
//???
- status |= MC_STATUS_READY;
- status &= ~MC_STATUS_BUSY;
-
- m_bInterruptSet = 1;
- m_bDirty = true;
+ CmdDoneLater(5000);
}
break;
@@ -229,11 +249,7 @@ void CEXIMemoryCard::SetCS(int cs)
address = (address & ~0x1FF) | ((address+1) & 0x1FF);
}
- status |= MC_STATUS_READY;
- status &= ~MC_STATUS_BUSY;
-
- m_bInterruptSet = 1;
- m_bDirty = true;
+ CmdDoneLater(5000);
}
// Page written to memory card, not just to buffer - let's schedule a flush 0.5b cycles into the future (1 sec)
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h
index dfdc6349aa..33b94ca530 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h
+++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h
@@ -47,9 +47,18 @@ private:
// through the userdata parameter, so that it can then call Flush on the right card.
static void FlushCallback(u64 userdata, int cyclesLate);
+ // Scheduled when a command that required delayed end signaling is done.
+ static void CmdDoneCallback(u64 userdata, int cyclesLate);
+
// Flushes the memory card contents to disk.
void Flush(bool exiting = false);
+ // Signals that the command that was previously executed is now done.
+ void CmdDone();
+
+ // Variant of CmdDone which schedules an event later in the future to complete the command.
+ void CmdDoneLater(u64 cycles);
+
enum
{
cmdNintendoID = 0x00,
@@ -71,7 +80,7 @@ private:
std::string m_strFilename;
int card_index;
- int et_this_card;
+ int et_this_card, et_cmd_done;
//! memory card state
// STATE_TO_SAVE