HW: Move ExpansionInterface variables to Core::System.
This commit is contained in:
parent
4b6086b20a
commit
26318e2c51
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue