Merge pull request #11121 from AdmiralCurtiss/globals-exi

HW: Move ExpansionInterface variables to Core::System.
This commit is contained in:
Mai 2022-10-06 10:33:22 -04:00 committed by GitHub
commit 7498eb1e6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 31 deletions

View File

@ -25,14 +25,23 @@
#include "DiscIO/Enums.h" #include "DiscIO/Enums.h"
bool s_using_overridden_sram = false;
namespace ExpansionInterface namespace ExpansionInterface
{ {
static CoreTiming::EventType* changeDevice; struct ExpansionInterfaceState::Data
static CoreTiming::EventType* updateInterrupts; {
CoreTiming::EventType* event_type_change_device;
CoreTiming::EventType* event_type_update_interrupts;
static std::array<std::unique_ptr<CEXIChannel>, MAX_EXI_CHANNELS> g_Channels; 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;
static void ChangeDeviceCallback(u64 userdata, s64 cyclesLate); static void ChangeDeviceCallback(u64 userdata, s64 cyclesLate);
static void UpdateInterruptsCallback(u64 userdata, s64 cycles_late); static void UpdateInterruptsCallback(u64 userdata, s64 cycles_late);
@ -67,7 +76,8 @@ void AddMemoryCard(Slot slot)
memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot)); memorycard_device = Config::Get(Config::GetInfoForEXIDevice(slot));
} }
g_Channels[SlotToEXIChannel(slot)]->AddDevice(memorycard_device, SlotToEXIDevice(slot)); auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
state.channels[SlotToEXIChannel(slot)]->AddDevice(memorycard_device, SlotToEXIDevice(slot));
} }
} // namespace } // namespace
@ -105,16 +115,18 @@ u8 SlotToEXIDevice(Slot slot)
void Init(const Sram* override_sram) void Init(const Sram* override_sram)
{ {
auto& sram = Core::System::GetInstance().GetSRAM(); auto& system = Core::System::GetInstance();
auto& state = system.GetExpansionInterfaceState().GetData();
auto& sram = system.GetSRAM();
if (override_sram) if (override_sram)
{ {
sram = *override_sram; sram = *override_sram;
s_using_overridden_sram = true; state.using_overridden_sram = true;
} }
else else
{ {
InitSRAM(&sram, SConfig::GetInstance().m_strSRAM); InitSRAM(&sram, SConfig::GetInstance().m_strSRAM);
s_using_overridden_sram = false; state.using_overridden_sram = false;
} }
CEXIMemoryCard::Init(); CEXIMemoryCard::Init();
@ -137,60 +149,68 @@ 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);
g_Channels[i] = std::make_unique<CEXIChannel>(i, header_data); state.channels[i] = std::make_unique<CEXIChannel>(i, header_data);
} }
} }
for (Slot slot : MEMCARD_SLOTS) for (Slot slot : MEMCARD_SLOTS)
AddMemoryCard(slot); AddMemoryCard(slot);
g_Channels[0]->AddDevice(EXIDeviceType::MaskROM, 1); state.channels[0]->AddDevice(EXIDeviceType::MaskROM, 1);
g_Channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1), state.channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1),
SlotToEXIDevice(Slot::SP1)); SlotToEXIDevice(Slot::SP1));
g_Channels[2]->AddDevice(EXIDeviceType::AD16, 0); state.channels[2]->AddDevice(EXIDeviceType::AD16, 0);
changeDevice = CoreTiming::RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback); state.event_type_change_device =
updateInterrupts = CoreTiming::RegisterEvent("EXIUpdateInterrupts", UpdateInterruptsCallback); CoreTiming::RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback);
state.event_type_update_interrupts =
CoreTiming::RegisterEvent("EXIUpdateInterrupts", UpdateInterruptsCallback);
} }
void Shutdown() void Shutdown()
{ {
for (auto& channel : g_Channels) auto& system = Core::System::GetInstance();
auto& state = system.GetExpansionInterfaceState().GetData();
for (auto& channel : state.channels)
channel.reset(); channel.reset();
CEXIMemoryCard::Shutdown(); CEXIMemoryCard::Shutdown();
if (!s_using_overridden_sram) if (!state.using_overridden_sram)
{ {
File::IOFile file(SConfig::GetInstance().m_strSRAM, "wb"); File::IOFile file(SConfig::GetInstance().m_strSRAM, "wb");
auto& sram = Core::System::GetInstance().GetSRAM(); auto& sram = system.GetSRAM();
file.WriteArray(&sram, 1); file.WriteArray(&sram, 1);
} }
} }
void DoState(PointerWrap& p) void DoState(PointerWrap& p)
{ {
for (auto& channel : g_Channels) auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
for (auto& channel : state.channels)
channel->DoState(p); channel->DoState(p);
} }
void PauseAndLock(bool doLock, bool unpauseOnUnlock) void PauseAndLock(bool doLock, bool unpauseOnUnlock)
{ {
for (auto& channel : g_Channels) auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
for (auto& channel : state.channels)
channel->PauseAndLock(doLock, unpauseOnUnlock); channel->PauseAndLock(doLock, unpauseOnUnlock);
} }
void RegisterMMIO(MMIO::Mapping* mmio, u32 base) void 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(g_Channels[i] != nullptr); DEBUG_ASSERT(state.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!
g_Channels[i]->RegisterMMIO(mmio, base + 5 * 4 * i); state.channels[i]->RegisterMMIO(mmio, base + 5 * 4 * i);
} }
} }
@ -200,7 +220,8 @@ static void ChangeDeviceCallback(u64 userdata, s64 cyclesLate)
u8 type = (u8)(userdata >> 16); u8 type = (u8)(userdata >> 16);
u8 num = (u8)userdata; u8 num = (u8)userdata;
g_Channels.at(channel)->AddDevice(static_cast<EXIDeviceType>(type), num); auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
state.channels.at(channel)->AddDevice(static_cast<EXIDeviceType>(type), num);
} }
void ChangeDevice(Slot slot, EXIDeviceType device_type, CoreTiming::FromThread from_thread) void ChangeDevice(Slot slot, EXIDeviceType device_type, CoreTiming::FromThread from_thread)
@ -212,22 +233,25 @@ void 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
CoreTiming::ScheduleEvent(0, changeDevice, auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
CoreTiming::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);
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), changeDevice, CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), state.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* GetChannel(u32 index)
{ {
return g_Channels.at(index).get(); auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
return state.channels.at(index).get();
} }
IEXIDevice* GetDevice(Slot slot) IEXIDevice* GetDevice(Slot slot)
{ {
return g_Channels.at(SlotToEXIChannel(slot))->GetDevice(1 << SlotToEXIDevice(slot)); auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
return state.channels.at(SlotToEXIChannel(slot))->GetDevice(1 << SlotToEXIDevice(slot));
} }
void UpdateInterrupts() void UpdateInterrupts()
@ -236,10 +260,11 @@ void UpdateInterrupts()
// 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
g_Channels[2]->SetEXIINT(g_Channels[0]->GetDevice(4)->IsInterruptSet()); auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
state.channels[2]->SetEXIINT(state.channels[0]->GetDevice(4)->IsInterruptSet());
bool causeInt = false; bool causeInt = false;
for (auto& channel : g_Channels) for (auto& channel : state.channels)
causeInt |= channel->IsCausingInterrupt(); causeInt |= channel->IsCausingInterrupt();
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, causeInt); ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, causeInt);
@ -252,7 +277,8 @@ static void UpdateInterruptsCallback(u64 userdata, s64 cycles_late)
void ScheduleUpdateInterrupts(CoreTiming::FromThread from, int cycles_late) void ScheduleUpdateInterrupts(CoreTiming::FromThread from, int cycles_late)
{ {
CoreTiming::ScheduleEvent(cycles_late, updateInterrupts, 0, from); auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
CoreTiming::ScheduleEvent(cycles_late, state.event_type_update_interrupts, 0, from);
} }
} // namespace ExpansionInterface } // namespace ExpansionInterface

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <initializer_list> #include <initializer_list>
#include <memory>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/EnumFormatter.h" #include "Common/EnumFormatter.h"
@ -23,6 +24,23 @@ 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;

View File

@ -11,6 +11,7 @@
#include "Core/HW/DSP.h" #include "Core/HW/DSP.h"
#include "Core/HW/DVD/DVDInterface.h" #include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/DVD/DVDThread.h" #include "Core/HW/DVD/DVDThread.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/Sram.h" #include "Core/HW/Sram.h"
#include "Core/HW/VideoInterface.h" #include "Core/HW/VideoInterface.h"
@ -26,6 +27,7 @@ struct System::Impl
DSP::DSPState m_dsp_state; DSP::DSPState m_dsp_state;
DVDInterface::DVDInterfaceState m_dvd_interface_state; DVDInterface::DVDInterfaceState m_dvd_interface_state;
DVDThread::DVDThreadState m_dvd_thread_state; DVDThread::DVDThreadState m_dvd_thread_state;
ExpansionInterface::ExpansionInterfaceState m_expansion_interface_state;
Sram m_sram; Sram m_sram;
VideoInterface::VideoInterfaceState m_video_interface_state; VideoInterface::VideoInterfaceState m_video_interface_state;
}; };
@ -93,6 +95,11 @@ DVDThread::DVDThreadState& System::GetDVDThreadState() const
return m_impl->m_dvd_thread_state; return m_impl->m_dvd_thread_state;
} }
ExpansionInterface::ExpansionInterfaceState& System::GetExpansionInterfaceState() const
{
return m_impl->m_expansion_interface_state;
}
Sram& System::GetSRAM() const Sram& System::GetSRAM() const
{ {
return m_impl->m_sram; return m_impl->m_sram;

View File

@ -24,6 +24,10 @@ namespace DVDThread
{ {
class DVDThreadState; class DVDThreadState;
} }
namespace ExpansionInterface
{
class ExpansionInterfaceState;
};
namespace VideoInterface namespace VideoInterface
{ {
class VideoInterfaceState; class VideoInterfaceState;
@ -67,6 +71,7 @@ public:
DSP::DSPState& GetDSPState() const; DSP::DSPState& GetDSPState() const;
DVDInterface::DVDInterfaceState& GetDVDInterfaceState() const; DVDInterface::DVDInterfaceState& GetDVDInterfaceState() const;
DVDThread::DVDThreadState& GetDVDThreadState() const; DVDThread::DVDThreadState& GetDVDThreadState() const;
ExpansionInterface::ExpansionInterfaceState& GetExpansionInterfaceState() const;
Sram& GetSRAM() const; Sram& GetSRAM() const;
VideoInterface::VideoInterfaceState& GetVideoInterfaceState() const; VideoInterface::VideoInterfaceState& GetVideoInterfaceState() const;