EXI: Add method to disable writes in CEXIMemoryCard.
This commit is contained in:
parent
5b8c07a190
commit
89bf3d2dd4
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue