From c3bafa2a40f551c81046144fc0bceedeae655426 Mon Sep 17 00:00:00 2001 From: RedPanda4552 Date: Tue, 19 Dec 2023 20:52:34 -0500 Subject: [PATCH] Memcard: Fix terminator not properly flagging ejections --- pcsx2/SIO/Memcard/MemoryCardProtocol.cpp | 16 +++++++++++----- pcsx2/SIO/Sio.cpp | 2 +- pcsx2/SIO/Sio2.cpp | 4 ++-- pcsx2/SIO/SioTypes.h | 3 ++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/pcsx2/SIO/Memcard/MemoryCardProtocol.cpp b/pcsx2/SIO/Memcard/MemoryCardProtocol.cpp index 4c998ad3ad..4f7269ff7e 100644 --- a/pcsx2/SIO/Memcard/MemoryCardProtocol.cpp +++ b/pcsx2/SIO/Memcard/MemoryCardProtocol.cpp @@ -191,22 +191,27 @@ void MemoryCardProtocol::SetTerminator() { MC_LOG.WriteLn("%s", __FUNCTION__); PS1_FAIL(); - const u8 newTerminator = g_Sio2FifoIn.front(); + mcd->term = g_Sio2FifoIn.front(); g_Sio2FifoIn.pop_front(); - const u8 oldTerminator = mcd->term; - mcd->term = newTerminator; g_Sio2FifoOut.push_back(0x00); g_Sio2FifoOut.push_back(0x2b); - g_Sio2FifoOut.push_back(oldTerminator); + g_Sio2FifoOut.push_back(mcd->term); } +// This one is a bit unusual. Old and new versions of MCMAN seem to handle this differently. +// Some commands may check [4] for the terminator. Others may check [3]. Typically, older +// MCMAN revisions will exclusively check [4], and newer revisions will check both [3] and [4] +// for different values. In all cases, they expect to see a valid terminator value. +// +// Also worth noting old revisions of MCMAN will not set anything other than 0x55 for the terminator, +// while newer revisions will set the terminator to another value (most commonly 0x5a). void MemoryCardProtocol::GetTerminator() { MC_LOG.WriteLn("%s", __FUNCTION__); PS1_FAIL(); g_Sio2FifoOut.push_back(0x2b); g_Sio2FifoOut.push_back(mcd->term); - g_Sio2FifoOut.push_back(static_cast(Terminator::DEFAULT)); + g_Sio2FifoOut.push_back(mcd->term); } void MemoryCardProtocol::WriteData() @@ -521,6 +526,7 @@ void MemoryCardProtocol::AuthF3() } else { + mcd->term = Terminator::READY; The2bTerminator(5); } } diff --git a/pcsx2/SIO/Sio.cpp b/pcsx2/SIO/Sio.cpp index f0bd8ac2fe..5b28cc6e37 100644 --- a/pcsx2/SIO/Sio.cpp +++ b/pcsx2/SIO/Sio.cpp @@ -101,7 +101,7 @@ void AutoEject::Set(size_t port, size_t slot) if (mcds[port][slot].autoEjectTicks == 0) { mcds[port][slot].autoEjectTicks = 60; // 60 frames is enough. - mcds[port][slot].term = 0x55; // Reset terminator to default (0x55), forces the PS2 to recheck the memcard. + mcds[port][slot].term = Terminator::NOT_READY; // Reset terminator to NOT_READY (0x66), forces the PS2 to recheck the memcard. } } diff --git a/pcsx2/SIO/Sio2.cpp b/pcsx2/SIO/Sio2.cpp index f99c8e56cb..c9dcadc8cd 100644 --- a/pcsx2/SIO/Sio2.cpp +++ b/pcsx2/SIO/Sio2.cpp @@ -265,12 +265,12 @@ void Sio2::Memcard() if (mcd->autoEjectTicks) { SetRecv1(Recv1::DISCONNECTED); - g_Sio2FifoOut.push_back(0x00); // Because Sio2::Write pops the first g_Sio2FifoIn member + g_Sio2FifoOut.push_back(0xff); // Because Sio2::Write pops the first g_Sio2FifoIn member while (!g_Sio2FifoIn.empty()) { g_Sio2FifoIn.pop_front(); - g_Sio2FifoOut.push_back(0x00); + g_Sio2FifoOut.push_back(0xff); } return; diff --git a/pcsx2/SIO/SioTypes.h b/pcsx2/SIO/SioTypes.h index 2668a9fb54..42794de705 100644 --- a/pcsx2/SIO/SioTypes.h +++ b/pcsx2/SIO/SioTypes.h @@ -170,5 +170,6 @@ namespace Recv3 namespace Terminator { - static constexpr u32 DEFAULT = 0x55; + static constexpr u32 NOT_READY = 0x66; + static constexpr u32 READY = 0x55; } // namespace Terminator