HW/EXI: Refactor ExpansionInterface to class.

This commit is contained in:
Admiral H. Curtiss
2023-03-10 20:16:37 +01:00
parent e4df388128
commit bf95d4012f
13 changed files with 137 additions and 146 deletions

View File

@ -783,7 +783,7 @@ static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unl
was_unpaused = system.GetCPU().PauseAndLock(true); was_unpaused = system.GetCPU().PauseAndLock(true);
} }
ExpansionInterface::PauseAndLock(do_lock, false); system.GetExpansionInterface().PauseAndLock(do_lock, false);
// audio has to come after CPU, because CPU thread can wait for audio thread (m_throttle). // audio has to come after CPU, because CPU thread can wait for audio thread (m_throttle).
system.GetDSP().GetDSPEmulator()->PauseAndLock(do_lock, false); system.GetDSP().GetDSPEmulator()->PauseAndLock(do_lock, false);

View File

@ -27,28 +27,13 @@
namespace ExpansionInterface namespace ExpansionInterface
{ {
struct ExpansionInterfaceState::Data ExpansionInterfaceManager::ExpansionInterfaceManager(Core::System& system) : m_system(system)
{
CoreTiming::EventType* event_type_change_device = nullptr;
CoreTiming::EventType* event_type_update_interrupts = nullptr;
std::array<std::unique_ptr<CEXIChannel>, MAX_EXI_CHANNELS> channels{};
bool using_overridden_sram = false;
};
ExpansionInterfaceState::ExpansionInterfaceState() : m_data(std::make_unique<Data>())
{ {
} }
ExpansionInterfaceState::~ExpansionInterfaceState() = default; ExpansionInterfaceManager::~ExpansionInterfaceManager() = default;
static void ChangeDeviceCallback(Core::System& system, u64 userdata, s64 cyclesLate); void ExpansionInterfaceManager::AddMemoryCard(Slot slot)
static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late);
namespace
{
void AddMemoryCard(Slot slot)
{ {
EXIDeviceType memorycard_device; EXIDeviceType memorycard_device;
if (Movie::IsPlayingInput() && Movie::IsConfigSaved()) if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
@ -76,10 +61,8 @@ void AddMemoryCard(Slot slot)
memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot)); memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot));
} }
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData(); m_channels[SlotToEXIChannel(slot)]->AddDevice(memorycard_device, SlotToEXIDevice(slot));
state.channels[SlotToEXIChannel(slot)]->AddDevice(memorycard_device, SlotToEXIDevice(slot));
} }
} // namespace
u8 SlotToEXIChannel(Slot slot) u8 SlotToEXIChannel(Slot slot)
{ {
@ -113,20 +96,18 @@ u8 SlotToEXIDevice(Slot slot)
} }
} }
void Init(const Sram* override_sram) void ExpansionInterfaceManager::Init(const Sram* override_sram)
{ {
auto& system = Core::System::GetInstance(); auto& sram = m_system.GetSRAM();
auto& state = system.GetExpansionInterfaceState().GetData();
auto& sram = system.GetSRAM();
if (override_sram) if (override_sram)
{ {
sram = *override_sram; sram = *override_sram;
state.using_overridden_sram = true; m_using_overridden_sram = true;
} }
else else
{ {
InitSRAM(&sram, SConfig::GetInstance().m_strSRAM); InitSRAM(&sram, SConfig::GetInstance().m_strSRAM);
state.using_overridden_sram = false; m_using_overridden_sram = false;
} }
CEXIMemoryCard::Init(); CEXIMemoryCard::Init();
@ -149,141 +130,130 @@ void Init(const Sram* override_sram)
Memcard::HeaderData header_data; Memcard::HeaderData header_data;
Memcard::InitializeHeaderData(&header_data, flash_id, size_mbits, shift_jis, rtc_bias, Memcard::InitializeHeaderData(&header_data, flash_id, size_mbits, shift_jis, rtc_bias,
sram_language, format_time + i); sram_language, format_time + i);
state.channels[i] = std::make_unique<CEXIChannel>(system, i, header_data); m_channels[i] = std::make_unique<CEXIChannel>(m_system, i, header_data);
} }
} }
for (Slot slot : MEMCARD_SLOTS) for (Slot slot : MEMCARD_SLOTS)
AddMemoryCard(slot); AddMemoryCard(slot);
state.channels[0]->AddDevice(EXIDeviceType::MaskROM, 1); m_channels[0]->AddDevice(EXIDeviceType::MaskROM, 1);
state.channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1), m_channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1),
SlotToEXIDevice(Slot::SP1)); SlotToEXIDevice(Slot::SP1));
state.channels[2]->AddDevice(EXIDeviceType::AD16, 0); m_channels[2]->AddDevice(EXIDeviceType::AD16, 0);
auto& core_timing = system.GetCoreTiming(); auto& core_timing = m_system.GetCoreTiming();
state.event_type_change_device = m_event_type_change_device = core_timing.RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback);
core_timing.RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback); m_event_type_update_interrupts =
state.event_type_update_interrupts =
core_timing.RegisterEvent("EXIUpdateInterrupts", UpdateInterruptsCallback); core_timing.RegisterEvent("EXIUpdateInterrupts", UpdateInterruptsCallback);
} }
void Shutdown() void ExpansionInterfaceManager::Shutdown()
{ {
auto& system = Core::System::GetInstance(); for (auto& channel : m_channels)
auto& state = system.GetExpansionInterfaceState().GetData();
for (auto& channel : state.channels)
channel.reset(); channel.reset();
CEXIMemoryCard::Shutdown(); CEXIMemoryCard::Shutdown();
if (!state.using_overridden_sram) if (!m_using_overridden_sram)
{ {
File::IOFile file(SConfig::GetInstance().m_strSRAM, "wb"); File::IOFile file(SConfig::GetInstance().m_strSRAM, "wb");
auto& sram = system.GetSRAM(); auto& sram = m_system.GetSRAM();
file.WriteArray(&sram, 1); file.WriteArray(&sram, 1);
} }
} }
void DoState(PointerWrap& p) void ExpansionInterfaceManager::DoState(PointerWrap& p)
{ {
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData(); for (auto& channel : m_channels)
for (auto& channel : state.channels)
channel->DoState(p); channel->DoState(p);
} }
void PauseAndLock(bool doLock, bool unpauseOnUnlock) void ExpansionInterfaceManager::PauseAndLock(bool doLock, bool unpauseOnUnlock)
{ {
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData(); for (auto& channel : m_channels)
for (auto& channel : state.channels)
channel->PauseAndLock(doLock, unpauseOnUnlock); channel->PauseAndLock(doLock, unpauseOnUnlock);
} }
void RegisterMMIO(MMIO::Mapping* mmio, u32 base) void ExpansionInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{ {
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
for (int i = 0; i < MAX_EXI_CHANNELS; ++i) for (int i = 0; i < MAX_EXI_CHANNELS; ++i)
{ {
DEBUG_ASSERT(state.channels[i] != nullptr); DEBUG_ASSERT(m_channels[i] != nullptr);
// Each channel has 5 32 bit registers assigned to it. We offset the // Each channel has 5 32 bit registers assigned to it. We offset the
// base that we give to each channel for registration. // base that we give to each channel for registration.
// //
// Be careful: this means the base is no longer aligned on a page // Be careful: this means the base is no longer aligned on a page
// boundary and using "base | FOO" is not valid! // boundary and using "base | FOO" is not valid!
state.channels[i]->RegisterMMIO(mmio, base + 5 * 4 * i); m_channels[i]->RegisterMMIO(mmio, base + 5 * 4 * i);
} }
} }
static void ChangeDeviceCallback(Core::System& system, u64 userdata, s64 cyclesLate) void ExpansionInterfaceManager::ChangeDeviceCallback(Core::System& system, u64 userdata,
s64 cycles_late)
{ {
u8 channel = (u8)(userdata >> 32); u8 channel = (u8)(userdata >> 32);
u8 type = (u8)(userdata >> 16); u8 type = (u8)(userdata >> 16);
u8 num = (u8)userdata; u8 num = (u8)userdata;
auto& state = system.GetExpansionInterfaceState().GetData(); system.GetExpansionInterface().m_channels.at(channel)->AddDevice(static_cast<EXIDeviceType>(type),
state.channels.at(channel)->AddDevice(static_cast<EXIDeviceType>(type), num); num);
} }
void ChangeDevice(Slot slot, EXIDeviceType device_type, CoreTiming::FromThread from_thread) void ExpansionInterfaceManager::ChangeDevice(Slot slot, EXIDeviceType device_type,
CoreTiming::FromThread from_thread)
{ {
ChangeDevice(SlotToEXIChannel(slot), SlotToEXIDevice(slot), device_type, from_thread); ChangeDevice(SlotToEXIChannel(slot), SlotToEXIDevice(slot), device_type, from_thread);
} }
void ChangeDevice(u8 channel, u8 device_num, EXIDeviceType device_type, void ExpansionInterfaceManager::ChangeDevice(u8 channel, u8 device_num, EXIDeviceType device_type,
CoreTiming::FromThread from_thread) CoreTiming::FromThread from_thread)
{ {
// Let the hardware see no device for 1 second // Let the hardware see no device for 1 second
auto& system = Core::System::GetInstance(); auto& core_timing = m_system.GetCoreTiming();
auto& core_timing = system.GetCoreTiming(); core_timing.ScheduleEvent(0, m_event_type_change_device,
auto& state = system.GetExpansionInterfaceState().GetData();
core_timing.ScheduleEvent(0, state.event_type_change_device,
((u64)channel << 32) | ((u64)EXIDeviceType::None << 16) | device_num, ((u64)channel << 32) | ((u64)EXIDeviceType::None << 16) | device_num,
from_thread); from_thread);
core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond(), state.event_type_change_device, core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond(), m_event_type_change_device,
((u64)channel << 32) | ((u64)device_type << 16) | device_num, ((u64)channel << 32) | ((u64)device_type << 16) | device_num,
from_thread); from_thread);
} }
CEXIChannel* GetChannel(u32 index) CEXIChannel* ExpansionInterfaceManager::GetChannel(u32 index)
{ {
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData(); return m_channels.at(index).get();
return state.channels.at(index).get();
} }
IEXIDevice* GetDevice(Slot slot) IEXIDevice* ExpansionInterfaceManager::GetDevice(Slot slot)
{ {
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData(); return m_channels.at(SlotToEXIChannel(slot))->GetDevice(1 << SlotToEXIDevice(slot));
return state.channels.at(SlotToEXIChannel(slot))->GetDevice(1 << SlotToEXIDevice(slot));
} }
void UpdateInterrupts() void ExpansionInterfaceManager::UpdateInterrupts()
{ {
// Interrupts are mapped a bit strangely: // Interrupts are mapped a bit strangely:
// Channel 0 Device 0 generates interrupt on channel 0 // Channel 0 Device 0 generates interrupt on channel 0
// Channel 0 Device 2 generates interrupt on channel 2 // Channel 0 Device 2 generates interrupt on channel 2
// Channel 1 Device 0 generates interrupt on channel 1 // Channel 1 Device 0 generates interrupt on channel 1
auto& system = Core::System::GetInstance(); m_channels[2]->SetEXIINT(m_channels[0]->GetDevice(4)->IsInterruptSet());
auto& state = system.GetExpansionInterfaceState().GetData();
state.channels[2]->SetEXIINT(state.channels[0]->GetDevice(4)->IsInterruptSet());
bool causeInt = false; bool causeInt = false;
for (auto& channel : state.channels) for (auto& channel : m_channels)
causeInt |= channel->IsCausingInterrupt(); causeInt |= channel->IsCausingInterrupt();
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, causeInt); m_system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, causeInt);
} }
static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late) void ExpansionInterfaceManager::UpdateInterruptsCallback(Core::System& system, u64 userdata,
s64 cycles_late)
{ {
UpdateInterrupts(); system.GetExpansionInterface().UpdateInterrupts();
} }
void ScheduleUpdateInterrupts(CoreTiming::FromThread from, int cycles_late) void ExpansionInterfaceManager::ScheduleUpdateInterrupts(CoreTiming::FromThread from,
int cycles_late)
{ {
auto& system = Core::System::GetInstance(); m_system.GetCoreTiming().ScheduleEvent(cycles_late, m_event_type_update_interrupts, 0, from);
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
system.GetCoreTiming().ScheduleEvent(cycles_late, state.event_type_update_interrupts, 0, from);
} }
} // namespace ExpansionInterface } // namespace ExpansionInterface

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <array>
#include <initializer_list> #include <initializer_list>
#include <memory> #include <memory>
@ -13,10 +14,15 @@
class PointerWrap; class PointerWrap;
struct Sram; struct Sram;
namespace Core
{
class System;
}
namespace CoreTiming namespace CoreTiming
{ {
struct EventType;
enum class FromThread; enum class FromThread;
} } // namespace CoreTiming
namespace MMIO namespace MMIO
{ {
class Mapping; class Mapping;
@ -24,23 +30,6 @@ class Mapping;
namespace ExpansionInterface namespace ExpansionInterface
{ {
class ExpansionInterfaceState
{
public:
ExpansionInterfaceState();
ExpansionInterfaceState(const ExpansionInterfaceState&) = delete;
ExpansionInterfaceState(ExpansionInterfaceState&&) = delete;
ExpansionInterfaceState& operator=(const ExpansionInterfaceState&) = delete;
ExpansionInterfaceState& operator=(ExpansionInterfaceState&&) = delete;
~ExpansionInterfaceState();
struct Data;
Data& GetData() { return *m_data; }
private:
std::unique_ptr<Data> m_data;
};
class CEXIChannel; class CEXIChannel;
class IEXIDevice; class IEXIDevice;
enum class EXIDeviceType : int; enum class EXIDeviceType : int;
@ -70,24 +59,49 @@ constexpr bool IsMemcardSlot(Slot slot)
u8 SlotToEXIChannel(Slot slot); u8 SlotToEXIChannel(Slot slot);
u8 SlotToEXIDevice(Slot slot); u8 SlotToEXIDevice(Slot slot);
void Init(const Sram* override_sram); class ExpansionInterfaceManager
void Shutdown(); {
void DoState(PointerWrap& p); public:
void PauseAndLock(bool doLock, bool unpauseOnUnlock); explicit ExpansionInterfaceManager(Core::System& system);
ExpansionInterfaceManager(const ExpansionInterfaceManager&) = delete;
ExpansionInterfaceManager(ExpansionInterfaceManager&&) = delete;
ExpansionInterfaceManager& operator=(const ExpansionInterfaceManager&) = delete;
ExpansionInterfaceManager& operator=(ExpansionInterfaceManager&&) = delete;
~ExpansionInterfaceManager();
void RegisterMMIO(MMIO::Mapping* mmio, u32 base); void Init(const Sram* override_sram);
void Shutdown();
void DoState(PointerWrap& p);
void PauseAndLock(bool doLock, bool unpauseOnUnlock);
void UpdateInterrupts(); void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void ScheduleUpdateInterrupts(CoreTiming::FromThread from, int cycles_late);
void ChangeDevice(Slot slot, EXIDeviceType device_type, void UpdateInterrupts();
CoreTiming::FromThread from_thread = CoreTiming::FromThread::NON_CPU); void ScheduleUpdateInterrupts(CoreTiming::FromThread from, int cycles_late);
void ChangeDevice(u8 channel, u8 device_num, EXIDeviceType device_type,
CoreTiming::FromThread from_thread = CoreTiming::FromThread::NON_CPU);
CEXIChannel* GetChannel(u32 index); void ChangeDevice(Slot slot, EXIDeviceType device_type,
IEXIDevice* GetDevice(Slot slot); CoreTiming::FromThread from_thread = CoreTiming::FromThread::NON_CPU);
void ChangeDevice(u8 channel, u8 device_num, EXIDeviceType device_type,
CoreTiming::FromThread from_thread = CoreTiming::FromThread::NON_CPU);
CEXIChannel* GetChannel(u32 index);
IEXIDevice* GetDevice(Slot slot);
private:
void AddMemoryCard(Slot slot);
static void ChangeDeviceCallback(Core::System& system, u64 userdata, s64 cycles_late);
static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late);
CoreTiming::EventType* m_event_type_change_device = nullptr;
CoreTiming::EventType* m_event_type_update_interrupts = nullptr;
std::array<std::unique_ptr<CEXIChannel>, MAX_EXI_CHANNELS> m_channels;
bool m_using_overridden_sram = false;
Core::System& m_system;
};
} // namespace ExpansionInterface } // namespace ExpansionInterface
template <> template <>

View File

@ -62,7 +62,7 @@ void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
return m_status.Hex; return m_status.Hex;
}), }),
MMIO::ComplexWrite<u32>([this](Core::System&, u32, u32 val) { MMIO::ComplexWrite<u32>([this](Core::System& system, u32, u32 val) {
UEXI_STATUS new_status(val); UEXI_STATUS new_status(val);
m_status.EXIINTMASK = new_status.EXIINTMASK; m_status.EXIINTMASK = new_status.EXIINTMASK;
@ -91,7 +91,7 @@ void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
if (device != nullptr) if (device != nullptr)
device->SetCS(m_status.CHIP_SELECT); device->SetCS(m_status.CHIP_SELECT);
ExpansionInterface::UpdateInterrupts(); system.GetExpansionInterface().UpdateInterrupts();
})); }));
mmio->Register(base + EXI_DMA_ADDRESS, MMIO::DirectRead<u32>(&m_dma_memory_address), mmio->Register(base + EXI_DMA_ADDRESS, MMIO::DirectRead<u32>(&m_dma_memory_address),
@ -160,7 +160,7 @@ void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
void CEXIChannel::SendTransferComplete() void CEXIChannel::SendTransferComplete()
{ {
m_status.TCINT = 1; m_status.TCINT = 1;
ExpansionInterface::UpdateInterrupts(); m_system.GetExpansionInterface().UpdateInterrupts();
} }
void CEXIChannel::RemoveDevices() void CEXIChannel::RemoveDevices()
@ -195,7 +195,7 @@ void CEXIChannel::AddDevice(std::unique_ptr<IEXIDevice> device, const int device
if (m_channel_id != 2) if (m_channel_id != 2)
{ {
m_status.EXTINT = 1; m_status.EXTINT = 1;
ExpansionInterface::UpdateInterrupts(); m_system.GetExpansionInterface().UpdateInterrupts();
} }
} }
} }
@ -280,8 +280,8 @@ void CEXIChannel::DoState(PointerWrap& p)
// the new device type are identical in this case. I assume there is a reason we have this // the new device type are identical in this case. I assume there is a reason we have this
// grace period when switching in the GUI. // grace period when switching in the GUI.
AddDevice(EXIDeviceType::None, device_index); AddDevice(EXIDeviceType::None, device_index);
ExpansionInterface::ChangeDevice(m_channel_id, device_index, EXIDeviceType::MemoryCardFolder, m_system.GetExpansionInterface().ChangeDevice(
CoreTiming::FromThread::CPU); m_channel_id, device_index, EXIDeviceType::MemoryCardFolder, CoreTiming::FromThread::CPU);
} }
} }
} }

View File

@ -178,7 +178,7 @@ void CEXIETHERNET::ImmWrite(u32 data, u32 size)
exi_status.interrupt_mask = data; exi_status.interrupt_mask = data;
break; break;
} }
ExpansionInterface::UpdateInterrupts(); m_system.GetExpansionInterface().UpdateInterrupts();
} }
else else
{ {
@ -466,7 +466,7 @@ void CEXIETHERNET::SendComplete()
mBbaMem[BBA_IR] |= INT_T; mBbaMem[BBA_IR] |= INT_T;
exi_status.interrupt |= exi_status.TRANSFER; exi_status.interrupt |= exi_status.TRANSFER;
ExpansionInterface::ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, 0); m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, 0);
} }
mBbaMem[BBA_LTPS] = 0; mBbaMem[BBA_LTPS] = 0;
@ -637,7 +637,7 @@ bool CEXIETHERNET::RecvHandlePacket()
mBbaMem[BBA_IR] |= INT_R; mBbaMem[BBA_IR] |= INT_R;
exi_status.interrupt |= exi_status.TRANSFER; exi_status.interrupt |= exi_status.TRANSFER;
ExpansionInterface::ScheduleUpdateInterrupts(CoreTiming::FromThread::NON_CPU, 0); m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::NON_CPU, 0);
} }
else else
{ {

View File

@ -56,11 +56,11 @@ static Common::EnumMap<char, MAX_MEMCARD_SLOT> s_card_short_names{'A', 'B'};
// Takes care of the nasty recovery of the 'this' pointer from card_slot, // Takes care of the nasty recovery of the 'this' pointer from card_slot,
// stored in the userdata parameter of the CoreTiming event. // stored in the userdata parameter of the CoreTiming event.
void CEXIMemoryCard::EventCompleteFindInstance(u64 userdata, void CEXIMemoryCard::EventCompleteFindInstance(Core::System& system, u64 userdata,
std::function<void(CEXIMemoryCard*)> callback) std::function<void(CEXIMemoryCard*)> callback)
{ {
Slot card_slot = static_cast<Slot>(userdata); Slot card_slot = static_cast<Slot>(userdata);
IEXIDevice* self = ExpansionInterface::GetDevice(card_slot); IEXIDevice* self = system.GetExpansionInterface().GetDevice(card_slot);
if (self != nullptr) if (self != nullptr)
{ {
if (self->m_device_type == EXIDeviceType::MemoryCard || if (self->m_device_type == EXIDeviceType::MemoryCard ||
@ -73,12 +73,13 @@ void CEXIMemoryCard::EventCompleteFindInstance(u64 userdata,
void CEXIMemoryCard::CmdDoneCallback(Core::System& system, u64 userdata, s64) void CEXIMemoryCard::CmdDoneCallback(Core::System& system, u64 userdata, s64)
{ {
EventCompleteFindInstance(userdata, [](CEXIMemoryCard* instance) { instance->CmdDone(); }); EventCompleteFindInstance(system, userdata,
[](CEXIMemoryCard* instance) { instance->CmdDone(); });
} }
void CEXIMemoryCard::TransferCompleteCallback(Core::System& system, u64 userdata, s64) void CEXIMemoryCard::TransferCompleteCallback(Core::System& system, u64 userdata, s64)
{ {
EventCompleteFindInstance(userdata, EventCompleteFindInstance(system, userdata,
[](CEXIMemoryCard* instance) { instance->TransferComplete(); }); [](CEXIMemoryCard* instance) { instance->TransferComplete(); });
} }
@ -256,13 +257,14 @@ void CEXIMemoryCard::CmdDone()
m_status &= ~MC_STATUS_BUSY; m_status &= ~MC_STATUS_BUSY;
m_interrupt_set = true; m_interrupt_set = true;
ExpansionInterface::UpdateInterrupts(); m_system.GetExpansionInterface().UpdateInterrupts();
} }
void CEXIMemoryCard::TransferComplete() void CEXIMemoryCard::TransferComplete()
{ {
// Transfer complete, send interrupt // Transfer complete, send interrupt
ExpansionInterface::GetChannel(ExpansionInterface::SlotToEXIChannel(m_card_slot)) m_system.GetExpansionInterface()
.GetChannel(ExpansionInterface::SlotToEXIChannel(m_card_slot))
->SendTransferComplete(); ->SendTransferComplete();
} }

View File

@ -59,7 +59,7 @@ public:
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);
static void EventCompleteFindInstance(u64 userdata, static void EventCompleteFindInstance(Core::System& system, u64 userdata,
std::function<void(CEXIMemoryCard*)> callback); std::function<void(CEXIMemoryCard*)> callback);
// Scheduled when a command that required delayed end signaling is done. // Scheduled when a command that required delayed end signaling is done.

View File

@ -266,7 +266,7 @@ void CEXIMic::UpdateNextInterruptTicks()
{ {
int diff = (SystemTimers::GetTicksPerSecond() / sample_rate) * buff_size_samples; int diff = (SystemTimers::GetTicksPerSecond() / sample_rate) * buff_size_samples;
next_int_ticks = m_system.GetCoreTiming().GetTicks() + diff; next_int_ticks = m_system.GetCoreTiming().GetTicks() + diff;
ExpansionInterface::ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, diff); m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, diff);
} }
bool CEXIMic::IsInterruptSet() bool CEXIMic::IsInterruptSet()

View File

@ -44,7 +44,7 @@ void Init(const Sram* override_sram)
VideoInterface::Init(); VideoInterface::Init();
SerialInterface::Init(); SerialInterface::Init();
system.GetProcessorInterface().Init(); system.GetProcessorInterface().Init();
ExpansionInterface::Init(override_sram); // Needs to be initialized before Memory system.GetExpansionInterface().Init(override_sram); // Needs to be initialized before Memory
system.GetHSP().Init(); system.GetHSP().Init();
system.GetMemory().Init(); // Needs to be initialized before AddressSpace system.GetMemory().Init(); // Needs to be initialized before AddressSpace
AddressSpace::Init(); AddressSpace::Init();
@ -78,7 +78,7 @@ void Shutdown()
AddressSpace::Shutdown(); AddressSpace::Shutdown();
system.GetMemory().Shutdown(); system.GetMemory().Shutdown();
system.GetHSP().Shutdown(); system.GetHSP().Shutdown();
ExpansionInterface::Shutdown(); system.GetExpansionInterface().Shutdown();
SerialInterface::Shutdown(); SerialInterface::Shutdown();
system.GetAudioInterface().Shutdown(); system.GetAudioInterface().Shutdown();
@ -105,7 +105,7 @@ void DoState(PointerWrap& p)
p.DoMarker("DVDInterface"); p.DoMarker("DVDInterface");
system.GetGPFifo().DoState(p); system.GetGPFifo().DoState(p);
p.DoMarker("GPFifo"); p.DoMarker("GPFifo");
ExpansionInterface::DoState(p); system.GetExpansionInterface().DoState(p);
p.DoMarker("ExpansionInterface"); p.DoMarker("ExpansionInterface");
system.GetAudioInterface().DoState(p); system.GetAudioInterface().DoState(p);
p.DoMarker("AudioInterface"); p.DoMarker("AudioInterface");

View File

@ -57,14 +57,14 @@ void MemoryManager::InitMMIO(bool is_wii)
system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000); system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false); system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006400); SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006400);
ExpansionInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006800); system.GetExpansionInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006800);
system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006C00); system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C006C00);
if (is_wii) if (is_wii)
{ {
IOS::RegisterMMIO(m_mmio_mapping.get(), 0x0D000000); IOS::RegisterMMIO(m_mmio_mapping.get(), 0x0D000000);
system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006000, true); system.GetDVDInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006000, true);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006400); SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006400);
ExpansionInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0D006800); system.GetExpansionInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006800);
system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006C00); system.GetAudioInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0D006C00);
} }
} }

View File

@ -37,7 +37,8 @@ struct System::Impl
{ {
explicit Impl(System& system) explicit Impl(System& system)
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system), : m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
m_dvd_thread(system), m_gp_fifo(system), m_ppc_state(PowerPC::ppcState) m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system),
m_ppc_state(PowerPC::ppcState)
{ {
} }
@ -52,7 +53,7 @@ struct System::Impl
DSP::DSPManager m_dsp; DSP::DSPManager m_dsp;
DVD::DVDInterface m_dvd_interface; DVD::DVDInterface m_dvd_interface;
DVD::DVDThread m_dvd_thread; DVD::DVDThread m_dvd_thread;
ExpansionInterface::ExpansionInterfaceState m_expansion_interface_state; ExpansionInterface::ExpansionInterfaceManager m_expansion_interface;
Fifo::FifoManager m_fifo; Fifo::FifoManager m_fifo;
GeometryShaderManager m_geometry_shader_manager; GeometryShaderManager m_geometry_shader_manager;
GPFifo::GPFifoManager m_gp_fifo; GPFifo::GPFifoManager m_gp_fifo;
@ -148,9 +149,9 @@ DVD::DVDThread& System::GetDVDThread() const
return m_impl->m_dvd_thread; return m_impl->m_dvd_thread;
} }
ExpansionInterface::ExpansionInterfaceState& System::GetExpansionInterfaceState() const ExpansionInterface::ExpansionInterfaceManager& System::GetExpansionInterface() const
{ {
return m_impl->m_expansion_interface_state; return m_impl->m_expansion_interface;
} }
Fifo::FifoManager& System::GetFifo() const Fifo::FifoManager& System::GetFifo() const

View File

@ -38,7 +38,7 @@ class DVDThread;
} // namespace DVD } // namespace DVD
namespace ExpansionInterface namespace ExpansionInterface
{ {
class ExpansionInterfaceState; class ExpansionInterfaceManager;
}; };
namespace Fifo namespace Fifo
{ {
@ -126,7 +126,7 @@ public:
DSP::DSPManager& GetDSP() const; DSP::DSPManager& GetDSP() const;
DVD::DVDInterface& GetDVDInterface() const; DVD::DVDInterface& GetDVDInterface() const;
DVD::DVDThread& GetDVDThread() const; DVD::DVDThread& GetDVDThread() const;
ExpansionInterface::ExpansionInterfaceState& GetExpansionInterfaceState() const; ExpansionInterface::ExpansionInterfaceManager& GetExpansionInterface() const;
Fifo::FifoManager& GetFifo() const; Fifo::FifoManager& GetFifo() const;
GeometryShaderManager& GetGeometryShaderManager() const; GeometryShaderManager& GetGeometryShaderManager() const;
GPFifo::GPFifoManager& GetGPFifo() const; GPFifo::GPFifoManager& GetGPFifo() const;

View File

@ -32,6 +32,7 @@
#include "Core/HW/EXI/EXI.h" #include "Core/HW/EXI/EXI.h"
#include "Core/HW/GCMemcard/GCMemcard.h" #include "Core/HW/GCMemcard/GCMemcard.h"
#include "Core/NetPlayServer.h" #include "Core/NetPlayServer.h"
#include "Core/System.h"
#include "DolphinQt/Config/Mapping/MappingWindow.h" #include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/GCMemcardManager.h" #include "DolphinQt/GCMemcardManager.h"
@ -496,7 +497,8 @@ bool GameCubePane::SetMemcard(ExpansionInterface::Slot slot, const QString& file
{ {
// ChangeDevice unplugs the device for 1 second, which means that games should notice that // ChangeDevice unplugs the device for 1 second, which means that games should notice that
// the path has changed and thus the memory card contents have changed // the path has changed and thus the memory card contents have changed
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::MemoryCard); Core::System::GetInstance().GetExpansionInterface().ChangeDevice(
slot, ExpansionInterface::EXIDeviceType::MemoryCard);
} }
} }
@ -601,7 +603,8 @@ bool GameCubePane::SetGCIFolder(ExpansionInterface::Slot slot, const QString& pa
{ {
// ChangeDevice unplugs the device for 1 second, which means that games should notice that // ChangeDevice unplugs the device for 1 second, which means that games should notice that
// the path has changed and thus the memory card contents have changed // the path has changed and thus the memory card contents have changed
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::MemoryCardFolder); Core::System::GetInstance().GetExpansionInterface().ChangeDevice(
slot, ExpansionInterface::EXIDeviceType::MemoryCardFolder);
} }
} }
@ -637,7 +640,8 @@ void GameCubePane::SetAGPRom(ExpansionInterface::Slot slot, const QString& filen
// cartridge without unplugging it, and it's not clear if the AGP software actually notices // cartridge without unplugging it, and it's not clear if the AGP software actually notices
// that it's been unplugged or the cartridge has changed, but this was done for memcards so // that it's been unplugged or the cartridge has changed, but this was done for memcards so
// we might as well do it for the AGP too. // we might as well do it for the AGP too.
ExpansionInterface::ChangeDevice(slot, ExpansionInterface::EXIDeviceType::AGP); Core::System::GetInstance().GetExpansionInterface().ChangeDevice(
slot, ExpansionInterface::EXIDeviceType::AGP);
} }
LoadSettings(); LoadSettings();
@ -761,7 +765,7 @@ void GameCubePane::SaveSettings()
if (Core::IsRunning() && current_exi_device != dev) if (Core::IsRunning() && current_exi_device != dev)
{ {
ExpansionInterface::ChangeDevice(slot, dev); Core::System::GetInstance().GetExpansionInterface().ChangeDevice(slot, dev);
} }
Config::SetBaseOrCurrent(Config::GetInfoForEXIDevice(slot), dev); Config::SetBaseOrCurrent(Config::GetInfoForEXIDevice(slot), dev);