mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-04 15:19:09 +00:00
EXI: Add method to disable writes in CEXIMemoryCard.
This commit is contained in:
parent
5b8c07a190
commit
89bf3d2dd4
2 changed files with 26 additions and 6 deletions
|
@ -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);
|
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)
|
void CEXIMemoryCard::SetupGciFolder(const Memcard::HeaderData& header_data)
|
||||||
{
|
{
|
||||||
const std::string& game_id = SConfig::GetInstance().GetGameID();
|
const std::string& game_id = SConfig::GetInstance().GetGameID();
|
||||||
|
@ -297,6 +302,7 @@ void CEXIMemoryCard::SetCS(int cs)
|
||||||
case Command::SectorErase:
|
case Command::SectorErase:
|
||||||
if (m_position > 2)
|
if (m_position > 2)
|
||||||
{
|
{
|
||||||
|
if (m_allow_writes)
|
||||||
m_memory_card->ClearBlock(m_address & (m_memory_card_size - 1));
|
m_memory_card->ClearBlock(m_address & (m_memory_card_size - 1));
|
||||||
m_status |= MC_STATUS_BUSY;
|
m_status |= MC_STATUS_BUSY;
|
||||||
m_status &= ~MC_STATUS_READY;
|
m_status &= ~MC_STATUS_READY;
|
||||||
|
@ -310,6 +316,7 @@ void CEXIMemoryCard::SetCS(int cs)
|
||||||
case Command::ChipErase:
|
case Command::ChipErase:
|
||||||
if (m_position > 2)
|
if (m_position > 2)
|
||||||
{
|
{
|
||||||
|
if (m_allow_writes)
|
||||||
m_memory_card->ClearAll();
|
m_memory_card->ClearAll();
|
||||||
m_status &= ~MC_STATUS_BUSY;
|
m_status &= ~MC_STATUS_BUSY;
|
||||||
}
|
}
|
||||||
|
@ -324,6 +331,7 @@ void CEXIMemoryCard::SetCS(int cs)
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
|
if (m_allow_writes)
|
||||||
m_memory_card->Write(m_address, 1, &(m_programming_buffer[i++]));
|
m_memory_card->Write(m_address, 1, &(m_programming_buffer[i++]));
|
||||||
i &= 127;
|
i &= 127;
|
||||||
m_address = (m_address & ~0x1FF) | ((m_address + 1) & 0x1FF);
|
m_address = (m_address & ~0x1FF) | ((m_address + 1) & 0x1FF);
|
||||||
|
@ -549,13 +557,17 @@ void CEXIMemoryCard::DMARead(u32 addr, u32 size)
|
||||||
// DMA write are preceded by all of the necessary setup via IMMWrite
|
// DMA write are preceded by all of the necessary setup via IMMWrite
|
||||||
// write all at once instead of single byte at a time as done by IEXIDevice::DMAWrite
|
// write all at once instead of single byte at a time as done by IEXIDevice::DMAWrite
|
||||||
void CEXIMemoryCard::DMAWrite(u32 addr, u32 size)
|
void CEXIMemoryCard::DMAWrite(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
if (m_allow_writes)
|
||||||
{
|
{
|
||||||
auto& memory = m_system.GetMemory();
|
auto& memory = m_system.GetMemory();
|
||||||
m_memory_card->Write(m_address, size, memory.GetPointerForRange(addr, size));
|
m_memory_card->Write(m_address, size, memory.GetPointerForRange(addr, size));
|
||||||
|
}
|
||||||
|
|
||||||
if (((m_address + size) % Memcard::BLOCK_SIZE) == 0)
|
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
|
// Schedule transfer complete later based on write speed
|
||||||
|
|
|
@ -66,6 +66,13 @@ public:
|
||||||
|
|
||||||
s32 ReadFromMemcard(u32 memcard_offset, s32 length, u8* dest_address) const;
|
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:
|
private:
|
||||||
void SetupGciFolder(const Memcard::HeaderData& header_data);
|
void SetupGciFolder(const Memcard::HeaderData& header_data);
|
||||||
void SetupRawMemcard(u16 size_mb);
|
void SetupRawMemcard(u16 size_mb);
|
||||||
|
@ -121,6 +128,7 @@ private:
|
||||||
unsigned int m_address;
|
unsigned int m_address;
|
||||||
u32 m_memory_card_size;
|
u32 m_memory_card_size;
|
||||||
std::unique_ptr<MemoryCardBase> m_memory_card;
|
std::unique_ptr<MemoryCardBase> m_memory_card;
|
||||||
|
bool m_allow_writes = true;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void TransferByte(u8& byte) override;
|
void TransferByte(u8& byte) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue