Call SetCS for all devices

The xor technique doesn't work well when 0 is a legal device, since CS not changing will return device 0, and then reset CS for that device.  This broke memcards; they now work.
This commit is contained in:
Pokechu22 2020-09-12 17:57:03 -07:00
parent 74d72198cc
commit d53407252e
17 changed files with 33 additions and 25 deletions

View File

@ -87,10 +87,16 @@ void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
if (m_channel_id == 0)
m_status.ROMDIS = new_status.ROMDIS;
IEXIDevice* device = GetDevice(m_status.CHIP_SELECT ^ new_status.CHIP_SELECT);
for (int device = 0; device < NUM_DEVICES; device++)
{
if (m_devices[device])
{
bool was_selected = m_status.CHIP_SELECT & (1 << device);
bool is_selected = new_status.CHIP_SELECT & (1 << device);
m_devices[device]->SetCS(new_status.CHIP_SELECT, was_selected, is_selected);
}
}
m_status.CHIP_SELECT = new_status.CHIP_SELECT;
if (device != nullptr)
device->SetCS(m_status.CHIP_SELECT);
system.GetExpansionInterface().UpdateInterrupts();
}));

View File

@ -83,7 +83,7 @@ bool IEXIDevice::IsPresent() const
return false;
}
void IEXIDevice::SetCS(int cs)
void IEXIDevice::SetCS(u32 cs, bool was_selected, bool is_selected)
{
}

View File

@ -63,7 +63,7 @@ public:
virtual bool UseDelayedTransferCompletion() const;
virtual bool IsPresent() const;
virtual void SetCS(int cs);
virtual void SetCS(u32 cs, bool was_selected, bool is_selected);
virtual void DoState(PointerWrap& p);
// Is generating interrupt ?

View File

@ -13,9 +13,9 @@ CEXIAD16::CEXIAD16(Core::System& system) : IEXIDevice(system)
{
}
void CEXIAD16::SetCS(int cs)
void CEXIAD16::SetCS(u32 cs, bool was_selected, bool is_selected)
{
if (cs)
if (!was_selected && is_selected)
m_position = 0;
}

View File

@ -13,7 +13,8 @@ class CEXIAD16 : public IEXIDevice
{
public:
explicit CEXIAD16(Core::System& system);
void SetCS(int cs) override;
void SetCS(u32 cs, bool was_selected, bool is_selected) override;
bool IsPresent() const override;
void DoState(PointerWrap& p) override;

View File

@ -103,9 +103,9 @@ CEXIETHERNET::~CEXIETHERNET()
m_network_interface->Deactivate();
}
void CEXIETHERNET::SetCS(int cs)
void CEXIETHERNET::SetCS(u32 cs, bool was_selected, bool is_selected)
{
if (cs)
if (!was_selected && is_selected)
{
// Invalidate the previous transfer
transfer.valid = false;

View File

@ -216,7 +216,7 @@ class CEXIETHERNET : public IEXIDevice
public:
CEXIETHERNET(Core::System& system, BBADeviceType type);
virtual ~CEXIETHERNET();
void SetCS(int cs) override;
void SetCS(u32 cs, bool was_selected, bool is_selected) override;
bool IsPresent() const override;
bool IsInterruptSet() override;
void ImmWrite(u32 data, u32 size) override;

View File

@ -246,9 +246,9 @@ void CEXIIPL::LoadFontFile(const std::string& filename, u32 offset)
m_fonts_loaded = true;
}
void CEXIIPL::SetCS(int cs)
void CEXIIPL::SetCS(u32 cs, bool was_selected, bool is_selected)
{
if (cs)
if (!was_selected && is_selected)
{
m_command_bytes_received = 0;
m_cursor = 0;

View File

@ -19,7 +19,7 @@ public:
explicit CEXIIPL(Core::System& system);
~CEXIIPL() override;
void SetCS(int cs) override;
void SetCS(u32 cs, bool was_selected, bool is_selected) override;
bool IsPresent() const override;
void DoState(PointerWrap& p) override;

View File

@ -276,9 +276,9 @@ void CEXIMemoryCard::CmdDoneLater(u64 cycles)
core_timing.ScheduleEvent(cycles, s_et_cmd_done[m_card_slot], static_cast<u64>(m_card_slot));
}
void CEXIMemoryCard::SetCS(int cs)
void CEXIMemoryCard::SetCS(u32 cs, bool was_selected, bool is_selected)
{
if (cs) // not-selected to selected
if (!was_selected && is_selected)
{
m_position = 0;
}

View File

@ -47,7 +47,7 @@ public:
CEXIMemoryCard(Core::System& system, Slot slot, bool gci_folder,
const Memcard::HeaderData& header_data);
~CEXIMemoryCard() override;
void SetCS(int cs) override;
void SetCS(u32 cs, bool was_selected, bool is_selected) override;
bool IsInterruptSet() override;
bool UseDelayedTransferCompletion() const override;
bool IsPresent() const override;

View File

@ -254,9 +254,9 @@ bool CEXIMic::IsPresent() const
return true;
}
void CEXIMic::SetCS(int cs)
void CEXIMic::SetCS(u32 cs, bool was_selected, bool is_selected)
{
if (cs) // not-selected to selected
if (!was_selected && is_selected)
m_position = 0;
// Doesn't appear to do anything we care about
// else if (command == cmdReset)

View File

@ -19,7 +19,7 @@ class CEXIMic : public IEXIDevice
public:
CEXIMic(Core::System& system, const int index);
virtual ~CEXIMic();
void SetCS(int cs) override;
void SetCS(u32 cs, bool was_selected, bool is_selected) override;
bool IsInterruptSet() override;
bool IsPresent() const override;

View File

@ -53,9 +53,10 @@ bool CEXIModem::IsPresent() const
return true;
}
void CEXIModem::SetCS(int cs)
void CEXIModem::SetCS(u32 cs, bool was_selected, bool is_selected)
{
m_transfer_descriptor = INVALID_TRANSFER_DESCRIPTOR;
if (!was_selected && is_selected)
m_transfer_descriptor = INVALID_TRANSFER_DESCRIPTOR;
}
bool CEXIModem::IsInterruptSet()

View File

@ -34,7 +34,7 @@ class CEXIModem : public IEXIDevice
public:
CEXIModem(Core::System& system, ModemDeviceType type);
virtual ~CEXIModem();
void SetCS(int cs) override;
void SetCS(u32 cs, bool was_selected, bool is_selected) override;
bool IsPresent() const override;
bool IsInterruptSet() override;
void ImmWrite(u32 data, u32 size) override;

View File

@ -110,7 +110,7 @@ void CEXISD::ImmReadWrite(u32& data, u32 size)
data = ImmRead(size);
}
void CEXISD::SetCS(int cs)
void CEXISD::SetCS(u32 cs, bool was_selected, bool is_selected)
{
INFO_LOG_FMT(EXPANSIONINTERFACE, "EXI SD SetCS: {}", cs);
}

View File

@ -31,7 +31,7 @@ public:
u32 ImmRead(u32 size) override;
void ImmReadWrite(u32& data, u32 size) override;
// TODO: DMA
void SetCS(int cs) override;
void SetCS(u32 cs, bool was_selected, bool is_selected) override;
bool IsPresent() const override;
void DoState(PointerWrap& p) override;