EXI: Add method to disable writes in CEXIMemoryCard.

This commit is contained in:
Admiral H. Curtiss 2020-08-11 23:58:26 +02:00
parent 5b8c07a190
commit 89bf3d2dd4
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
2 changed files with 26 additions and 6 deletions

View File

@ -180,6 +180,11 @@ s32 CEXIMemoryCard::ReadFromMemcard(u32 memcard_offset, s32 length, u8* dest_add
return m_memory_card->Read(memcard_offset, length, dest_address);
}
void CEXIMemoryCard::DisableWrites()
{
m_allow_writes = false;
}
void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data)
{
const std::string& game_id = SConfig::GetInstance().GetGameID();
@ -297,7 +302,8 @@ void CEXIMemoryCard::SetCS(int cs)
case Command::SectorErase:
if (m_position > 2)
{
m_memory_card->ClearBlock(m_address & (m_memory_card_size - 1));
if (m_allow_writes)
m_memory_card->ClearBlock(m_address & (m_memory_card_size - 1));
m_status |= MC_STATUS_BUSY;
m_status &= ~MC_STATUS_READY;
@ -310,7 +316,8 @@ void CEXIMemoryCard::SetCS(int cs)
case Command::ChipErase:
if (m_position > 2)
{
m_memory_card->ClearAll();
if (m_allow_writes)
m_memory_card->ClearAll();
m_status &= ~MC_STATUS_BUSY;
}
break;
@ -324,7 +331,8 @@ void CEXIMemoryCard::SetCS(int cs)
while (count--)
{
m_memory_card->Write(m_address, 1, &(m_programming_buffer[i++]));
if (m_allow_writes)
m_memory_card->Write(m_address, 1, &(m_programming_buffer[i++]));
i &= 127;
m_address = (m_address & ~0x1FF) | ((m_address + 1) & 0x1FF);
}
@ -550,12 +558,16 @@ void CEXIMemoryCard::DMARead(u32 addr, u32 size)
// write all at once instead of single byte at a time as done by IEXIDevice::DMAWrite
void CEXIMemoryCard::DMAWrite(u32 addr, u32 size)
{
auto& memory = m_system.GetMemory();
m_memory_card->Write(m_address, size, memory.GetPointerForRange(addr, size));
if (m_allow_writes)
{
auto& memory = m_system.GetMemory();
m_memory_card->Write(m_address, size, memory.GetPointerForRange(addr, size));
}
if (((m_address + size) % Memcard::BLOCK_SIZE) == 0)
{
INFO_LOG_FMT(EXPANSIONINTERFACE, "writing to block: {:x}", m_address / Memcard::BLOCK_SIZE);
INFO_LOG_FMT(EXPANSIONINTERFACE, "{}writing to block: {:x}", m_allow_writes ? "" : "fake ",
m_address / Memcard::BLOCK_SIZE);
}
// Schedule transfer complete later based on write speed

View File

@ -66,6 +66,13 @@ public:
s32 ReadFromMemcard(u32 memcard_offset, s32 length, u8* dest_address) const;
// After this call all writes to the card are disabled.
// This is used to have a 'grace period' after loading a savestate where the emulated software
// still sees the memory card but can't write to it anymore.
// It is expected that this device is destroyed and possibly recreated soon (within a few emulated
// frames) after this method has been called.
void DisableWrites();
private:
void SetupGciFolder(const Memcard::HeaderData& header_data);
void SetupRawMemcard(u16 size_mb);
@ -121,6 +128,7 @@ private:
unsigned int m_address;
u32 m_memory_card_size;
std::unique_ptr<MemoryCardBase> m_memory_card;
bool m_allow_writes = true;
protected:
void TransferByte(u8& byte) override;