From 691135dbc30551cff01ffa9073dc336094f748f3 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 6 Oct 2022 22:08:20 +0200 Subject: [PATCH] HW: Move SerialInterface variables to Core::System. --- Source/Core/Core/HW/SI/SI.cpp | 339 +++++++++++++++++++--------------- Source/Core/Core/HW/SI/SI.h | 17 ++ Source/Core/Core/System.cpp | 7 + Source/Core/Core/System.h | 5 + 4 files changed, 222 insertions(+), 146 deletions(-) diff --git a/Source/Core/Core/HW/SI/SI.cpp b/Source/Core/Core/HW/SI/SI.cpp index 64d91a3246..1a199e1fa6 100644 --- a/Source/Core/Core/HW/SI/SI.cpp +++ b/Source/Core/Core/HW/SI/SI.cpp @@ -25,6 +25,7 @@ #include "Core/HW/SystemTimers.h" #include "Core/Movie.h" #include "Core/NetPlayProto.h" +#include "Core/System.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" @@ -198,37 +199,46 @@ union USIEXIClockCount BitField<1, 30, u32> reserved; }; -static CoreTiming::EventType* s_change_device_event; -static CoreTiming::EventType* s_tranfer_pending_event; -static std::array s_device_events; +struct SerialInterfaceState::Data +{ + CoreTiming::EventType* event_type_change_device; + CoreTiming::EventType* event_type_tranfer_pending; + std::array event_types_device; -// User-configured device type. possibly overridden by TAS/Netplay -static std::array, MAX_SI_CHANNELS> s_desired_device_types; + // User-configured device type. possibly overridden by TAS/Netplay + std::array, MAX_SI_CHANNELS> desired_device_types; -// STATE_TO_SAVE -static std::array s_channel; -static USIPoll s_poll; -static USIComCSR s_com_csr; -static USIStatusReg s_status_reg; -static USIEXIClockCount s_exi_clock_count; -static std::array s_si_buffer; + std::array channel; + USIPoll poll; + USIComCSR com_csr; + USIStatusReg status_reg; + USIEXIClockCount exi_clock_count; + std::array si_buffer; +}; + +SerialInterfaceState::SerialInterfaceState() : m_data(std::make_unique()) +{ +} + +SerialInterfaceState::~SerialInterfaceState() = default; static void SetNoResponse(u32 channel) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); // raise the NO RESPONSE error switch (channel) { case 0: - s_status_reg.NOREP0 = 1; + state.status_reg.NOREP0 = 1; break; case 1: - s_status_reg.NOREP1 = 1; + state.status_reg.NOREP1 = 1; break; case 2: - s_status_reg.NOREP2 = 1; + state.status_reg.NOREP2 = 1; break; case 3: - s_status_reg.NOREP3 = 1; + state.status_reg.NOREP3 = 1; break; } } @@ -236,33 +246,41 @@ static void SetNoResponse(u32 channel) static void ChangeDeviceCallback(u64 user_data, s64 cycles_late) { // The purpose of this callback is to simply re-enable device changes. - s_channel[user_data].has_recent_device_change = false; + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.channel[user_data].has_recent_device_change = false; } static void UpdateInterrupts() { // check if we have to update the RDSTINT flag - if (s_status_reg.RDST0 || s_status_reg.RDST1 || s_status_reg.RDST2 || s_status_reg.RDST3) - s_com_csr.RDSTINT = 1; + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + if (state.status_reg.RDST0 || state.status_reg.RDST1 || state.status_reg.RDST2 || + state.status_reg.RDST3) + { + state.com_csr.RDSTINT = 1; + } else - s_com_csr.RDSTINT = 0; + { + state.com_csr.RDSTINT = 0; + } // check if we have to generate an interrupt - const bool generate_interrupt = (s_com_csr.RDSTINT & s_com_csr.RDSTINTMSK) != 0 || - (s_com_csr.TCINT & s_com_csr.TCINTMSK) != 0; + const bool generate_interrupt = (state.com_csr.RDSTINT & state.com_csr.RDSTINTMSK) != 0 || + (state.com_csr.TCINT & state.com_csr.TCINTMSK) != 0; ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_SI, generate_interrupt); } static void GenerateSIInterrupt(SIInterruptType type) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); switch (type) { case INT_RDSTINT: - s_com_csr.RDSTINT = 1; + state.com_csr.RDSTINT = 1; break; case INT_TCINT: - s_com_csr.TCINT = 1; + state.com_csr.TCINT = 1; break; } @@ -279,19 +297,21 @@ constexpr s32 ConvertSILengthField(u32 field) static void RunSIBuffer(u64 user_data, s64 cycles_late) { - if (s_com_csr.TSTART) + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + if (state.com_csr.TSTART) { - const s32 request_length = ConvertSILengthField(s_com_csr.OUTLNGTH); - const s32 expected_response_length = ConvertSILengthField(s_com_csr.INLNGTH); - const std::vector request_copy(s_si_buffer.data(), s_si_buffer.data() + request_length); + const s32 request_length = ConvertSILengthField(state.com_csr.OUTLNGTH); + const s32 expected_response_length = ConvertSILengthField(state.com_csr.INLNGTH); + const std::vector request_copy(state.si_buffer.data(), + state.si_buffer.data() + request_length); - const std::unique_ptr& device = s_channel[s_com_csr.CHANNEL].device; - const s32 actual_response_length = device->RunBuffer(s_si_buffer.data(), request_length); + const std::unique_ptr& device = state.channel[state.com_csr.CHANNEL].device; + const s32 actual_response_length = device->RunBuffer(state.si_buffer.data(), request_length); DEBUG_LOG_FMT(SERIALINTERFACE, "RunSIBuffer chan: {} request_length: {} expected_response_length: {} " "actual_response_length: {}", - s_com_csr.CHANNEL, request_length, expected_response_length, + state.com_csr.CHANNEL, request_length, expected_response_length, actual_response_length); if (actual_response_length > 0 && expected_response_length != actual_response_length) { @@ -316,29 +336,31 @@ static void RunSIBuffer(u64 user_data, s64 cycles_late) // 2) Investigate the timeout period for NOREP0 if (actual_response_length != 0) { - s_com_csr.TSTART = 0; - s_com_csr.COMERR = actual_response_length < 0; + state.com_csr.TSTART = 0; + state.com_csr.COMERR = actual_response_length < 0; if (actual_response_length < 0) - SetNoResponse(s_com_csr.CHANNEL); + SetNoResponse(state.com_csr.CHANNEL); GenerateSIInterrupt(INT_TCINT); } else { - CoreTiming::ScheduleEvent(device->TransferInterval() - cycles_late, s_tranfer_pending_event); + CoreTiming::ScheduleEvent(device->TransferInterval() - cycles_late, + state.event_type_tranfer_pending); } } } void DoState(PointerWrap& p) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); for (int i = 0; i < MAX_SI_CHANNELS; i++) { - p.Do(s_channel[i].in_hi.hex); - p.Do(s_channel[i].in_lo.hex); - p.Do(s_channel[i].out.hex); - p.Do(s_channel[i].has_recent_device_change); + p.Do(state.channel[i].in_hi.hex); + p.Do(state.channel[i].in_lo.hex); + p.Do(state.channel[i].out.hex); + p.Do(state.channel[i].has_recent_device_change); - std::unique_ptr& device = s_channel[i].device; + std::unique_ptr& device = state.channel[i].device; SIDevices type = device->GetDeviceType(); p.Do(type); @@ -350,23 +372,26 @@ void DoState(PointerWrap& p) device->DoState(p); } - p.Do(s_poll); - p.Do(s_com_csr); - p.Do(s_status_reg); - p.Do(s_exi_clock_count); - p.Do(s_si_buffer); + p.Do(state.poll); + p.Do(state.com_csr); + p.Do(state.status_reg); + p.Do(state.exi_clock_count); + p.Do(state.si_buffer); } template static void DeviceEventCallback(u64 userdata, s64 cyclesLate) { - s_channel[device_number].device->OnEvent(userdata, cyclesLate); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.channel[device_number].device->OnEvent(userdata, cyclesLate); } static void RegisterEvents() { - s_change_device_event = CoreTiming::RegisterEvent("ChangeSIDevice", ChangeDeviceCallback); - s_tranfer_pending_event = CoreTiming::RegisterEvent("SITransferPending", RunSIBuffer); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.event_type_change_device = + CoreTiming::RegisterEvent("ChangeSIDevice", ChangeDeviceCallback); + state.event_type_tranfer_pending = CoreTiming::RegisterEvent("SITransferPending", RunSIBuffer); constexpr std::array event_callbacks = { DeviceEventCallback<0>, @@ -376,73 +401,76 @@ static void RegisterEvents() }; for (int i = 0; i < MAX_SI_CHANNELS; ++i) { - s_device_events[i] = + state.event_types_device[i] = CoreTiming::RegisterEvent(fmt::format("SIEventChannel{}", i), event_callbacks[i]); } } void ScheduleEvent(int device_number, s64 cycles_into_future, u64 userdata) { - CoreTiming::ScheduleEvent(cycles_into_future, s_device_events[device_number], userdata); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + CoreTiming::ScheduleEvent(cycles_into_future, state.event_types_device[device_number], userdata); } void RemoveEvent(int device_number) { - CoreTiming::RemoveEvent(s_device_events[device_number]); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + CoreTiming::RemoveEvent(state.event_types_device[device_number]); } void Init() { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); RegisterEvents(); for (int i = 0; i < MAX_SI_CHANNELS; i++) { - s_channel[i].out.hex = 0; - s_channel[i].in_hi.hex = 0; - s_channel[i].in_lo.hex = 0; - s_channel[i].has_recent_device_change = false; + state.channel[i].out.hex = 0; + state.channel[i].in_hi.hex = 0; + state.channel[i].in_lo.hex = 0; + state.channel[i].has_recent_device_change = false; if (Movie::IsMovieActive()) { - s_desired_device_types[i] = SIDEVICE_NONE; + state.desired_device_types[i] = SIDEVICE_NONE; if (Movie::IsUsingGBA(i)) { - s_desired_device_types[i] = SIDEVICE_GC_GBA_EMULATED; + state.desired_device_types[i] = SIDEVICE_GC_GBA_EMULATED; } else if (Movie::IsUsingPad(i)) { SIDevices current = Config::Get(Config::GetInfoForSIDevice(i)); // GC pad-compatible devices can be used for both playing and recording if (Movie::IsUsingBongo(i)) - s_desired_device_types[i] = SIDEVICE_GC_TARUKONGA; + state.desired_device_types[i] = SIDEVICE_GC_TARUKONGA; else if (SIDevice_IsGCController(current)) - s_desired_device_types[i] = current; + state.desired_device_types[i] = current; else - s_desired_device_types[i] = SIDEVICE_GC_CONTROLLER; + state.desired_device_types[i] = SIDEVICE_GC_CONTROLLER; } } else if (!NetPlay::IsNetPlayRunning()) { - s_desired_device_types[i] = Config::Get(Config::GetInfoForSIDevice(i)); + state.desired_device_types[i] = Config::Get(Config::GetInfoForSIDevice(i)); } - AddDevice(s_desired_device_types[i], i); + AddDevice(state.desired_device_types[i], i); } - s_poll.hex = 0; - s_poll.X = 492; + state.poll.hex = 0; + state.poll.X = 492; - s_com_csr.hex = 0; + state.com_csr.hex = 0; - s_status_reg.hex = 0; + state.status_reg.hex = 0; - s_exi_clock_count.hex = 0; + state.exi_clock_count.hex = 0; // Supposedly set on reset, but logs from real Wii don't look like it is... - // s_exi_clock_count.LOCK = 1; + // state.exi_clock_count.LOCK = 1; - s_si_buffer = {}; + state.si_buffer = {}; } void Shutdown() @@ -454,34 +482,40 @@ void Shutdown() void RegisterMMIO(MMIO::Mapping* mmio, u32 base) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + // Register SI buffer direct accesses. const u32 io_buffer_base = base | SI_IO_BUFFER; - for (size_t i = 0; i < s_si_buffer.size(); i += sizeof(u32)) + for (size_t i = 0; i < state.si_buffer.size(); i += sizeof(u32)) { const u32 address = base | static_cast(io_buffer_base + i); mmio->Register(address, MMIO::ComplexRead([i](u32) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); u32 val; - std::memcpy(&val, &s_si_buffer[i], sizeof(val)); + std::memcpy(&val, &state.si_buffer[i], sizeof(val)); return Common::swap32(val); }), MMIO::ComplexWrite([i](u32, u32 val) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); val = Common::swap32(val); - std::memcpy(&s_si_buffer[i], &val, sizeof(val)); + std::memcpy(&state.si_buffer[i], &val, sizeof(val)); })); } - for (size_t i = 0; i < s_si_buffer.size(); i += sizeof(u16)) + for (size_t i = 0; i < state.si_buffer.size(); i += sizeof(u16)) { const u32 address = base | static_cast(io_buffer_base + i); mmio->Register(address, MMIO::ComplexRead([i](u32) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); u16 val; - std::memcpy(&val, &s_si_buffer[i], sizeof(val)); + std::memcpy(&val, &state.si_buffer[i], sizeof(val)); return Common::swap16(val); }), MMIO::ComplexWrite([i](u32, u16 val) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); val = Common::swap16(val); - std::memcpy(&s_si_buffer[i], &val, sizeof(val)); + std::memcpy(&state.si_buffer[i], &val, sizeof(val)); })); } @@ -496,119 +530,124 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) const u32 rdst_bit = 8 * (3 - i) + 5; mmio->Register(base | (SI_CHANNEL_0_OUT + 0xC * i), - MMIO::DirectRead(&s_channel[i].out.hex), - MMIO::DirectWrite(&s_channel[i].out.hex)); + MMIO::DirectRead(&state.channel[i].out.hex), + MMIO::DirectWrite(&state.channel[i].out.hex)); mmio->Register(base | (SI_CHANNEL_0_IN_HI + 0xC * i), MMIO::ComplexRead([i, rdst_bit](u32) { - s_status_reg.hex &= ~(1U << rdst_bit); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.status_reg.hex &= ~(1U << rdst_bit); UpdateInterrupts(); - return s_channel[i].in_hi.hex; + return state.channel[i].in_hi.hex; }), - MMIO::DirectWrite(&s_channel[i].in_hi.hex)); + MMIO::DirectWrite(&state.channel[i].in_hi.hex)); mmio->Register(base | (SI_CHANNEL_0_IN_LO + 0xC * i), MMIO::ComplexRead([i, rdst_bit](u32) { - s_status_reg.hex &= ~(1U << rdst_bit); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.status_reg.hex &= ~(1U << rdst_bit); UpdateInterrupts(); - return s_channel[i].in_lo.hex; + return state.channel[i].in_lo.hex; }), - MMIO::DirectWrite(&s_channel[i].in_lo.hex)); + MMIO::DirectWrite(&state.channel[i].in_lo.hex)); } - mmio->Register(base | SI_POLL, MMIO::DirectRead(&s_poll.hex), - MMIO::DirectWrite(&s_poll.hex)); + mmio->Register(base | SI_POLL, MMIO::DirectRead(&state.poll.hex), + MMIO::DirectWrite(&state.poll.hex)); - mmio->Register(base | SI_COM_CSR, MMIO::DirectRead(&s_com_csr.hex), + mmio->Register(base | SI_COM_CSR, MMIO::DirectRead(&state.com_csr.hex), MMIO::ComplexWrite([](u32, u32 val) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); const USIComCSR tmp_com_csr(val); - s_com_csr.CHANNEL = tmp_com_csr.CHANNEL.Value(); - s_com_csr.INLNGTH = tmp_com_csr.INLNGTH.Value(); - s_com_csr.OUTLNGTH = tmp_com_csr.OUTLNGTH.Value(); - s_com_csr.RDSTINTMSK = tmp_com_csr.RDSTINTMSK.Value(); - s_com_csr.TCINTMSK = tmp_com_csr.TCINTMSK.Value(); + state.com_csr.CHANNEL = tmp_com_csr.CHANNEL.Value(); + state.com_csr.INLNGTH = tmp_com_csr.INLNGTH.Value(); + state.com_csr.OUTLNGTH = tmp_com_csr.OUTLNGTH.Value(); + state.com_csr.RDSTINTMSK = tmp_com_csr.RDSTINTMSK.Value(); + state.com_csr.TCINTMSK = tmp_com_csr.TCINTMSK.Value(); if (tmp_com_csr.RDSTINT) - s_com_csr.RDSTINT = 0; + state.com_csr.RDSTINT = 0; if (tmp_com_csr.TCINT) - s_com_csr.TCINT = 0; + state.com_csr.TCINT = 0; // be careful: run si-buffer after updating the INT flags if (tmp_com_csr.TSTART) { - if (s_com_csr.TSTART) - CoreTiming::RemoveEvent(s_tranfer_pending_event); - s_com_csr.TSTART = 1; + if (state.com_csr.TSTART) + CoreTiming::RemoveEvent(state.event_type_tranfer_pending); + state.com_csr.TSTART = 1; RunSIBuffer(0, 0); } - if (!s_com_csr.TSTART) + if (!state.com_csr.TSTART) UpdateInterrupts(); })); - mmio->Register(base | SI_STATUS_REG, MMIO::DirectRead(&s_status_reg.hex), + mmio->Register(base | SI_STATUS_REG, MMIO::DirectRead(&state.status_reg.hex), MMIO::ComplexWrite([](u32, u32 val) { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); const USIStatusReg tmp_status(val); // clear bits ( if (tmp.bit) SISR.bit=0 ) if (tmp_status.NOREP0) - s_status_reg.NOREP0 = 0; + state.status_reg.NOREP0 = 0; if (tmp_status.COLL0) - s_status_reg.COLL0 = 0; + state.status_reg.COLL0 = 0; if (tmp_status.OVRUN0) - s_status_reg.OVRUN0 = 0; + state.status_reg.OVRUN0 = 0; if (tmp_status.UNRUN0) - s_status_reg.UNRUN0 = 0; + state.status_reg.UNRUN0 = 0; if (tmp_status.NOREP1) - s_status_reg.NOREP1 = 0; + state.status_reg.NOREP1 = 0; if (tmp_status.COLL1) - s_status_reg.COLL1 = 0; + state.status_reg.COLL1 = 0; if (tmp_status.OVRUN1) - s_status_reg.OVRUN1 = 0; + state.status_reg.OVRUN1 = 0; if (tmp_status.UNRUN1) - s_status_reg.UNRUN1 = 0; + state.status_reg.UNRUN1 = 0; if (tmp_status.NOREP2) - s_status_reg.NOREP2 = 0; + state.status_reg.NOREP2 = 0; if (tmp_status.COLL2) - s_status_reg.COLL2 = 0; + state.status_reg.COLL2 = 0; if (tmp_status.OVRUN2) - s_status_reg.OVRUN2 = 0; + state.status_reg.OVRUN2 = 0; if (tmp_status.UNRUN2) - s_status_reg.UNRUN2 = 0; + state.status_reg.UNRUN2 = 0; if (tmp_status.NOREP3) - s_status_reg.NOREP3 = 0; + state.status_reg.NOREP3 = 0; if (tmp_status.COLL3) - s_status_reg.COLL3 = 0; + state.status_reg.COLL3 = 0; if (tmp_status.OVRUN3) - s_status_reg.OVRUN3 = 0; + state.status_reg.OVRUN3 = 0; if (tmp_status.UNRUN3) - s_status_reg.UNRUN3 = 0; + state.status_reg.UNRUN3 = 0; // send command to devices if (tmp_status.WR) { - s_channel[0].device->SendCommand(s_channel[0].out.hex, s_poll.EN0); - s_channel[1].device->SendCommand(s_channel[1].out.hex, s_poll.EN1); - s_channel[2].device->SendCommand(s_channel[2].out.hex, s_poll.EN2); - s_channel[3].device->SendCommand(s_channel[3].out.hex, s_poll.EN3); + state.channel[0].device->SendCommand(state.channel[0].out.hex, state.poll.EN0); + state.channel[1].device->SendCommand(state.channel[1].out.hex, state.poll.EN1); + state.channel[2].device->SendCommand(state.channel[2].out.hex, state.poll.EN2); + state.channel[3].device->SendCommand(state.channel[3].out.hex, state.poll.EN3); - s_status_reg.WR = 0; - s_status_reg.WRST0 = 0; - s_status_reg.WRST1 = 0; - s_status_reg.WRST2 = 0; - s_status_reg.WRST3 = 0; + state.status_reg.WR = 0; + state.status_reg.WRST0 = 0; + state.status_reg.WRST1 = 0; + state.status_reg.WRST2 = 0; + state.status_reg.WRST3 = 0; } })); - mmio->Register(base | SI_EXI_CLOCK_COUNT, MMIO::DirectRead(&s_exi_clock_count.hex), - MMIO::DirectWrite(&s_exi_clock_count.hex)); + mmio->Register(base | SI_EXI_CLOCK_COUNT, MMIO::DirectRead(&state.exi_clock_count.hex), + MMIO::DirectWrite(&state.exi_clock_count.hex)); } void RemoveDevice(int device_number) { - s_channel.at(device_number).device.reset(); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.channel.at(device_number).device.reset(); } void AddDevice(std::unique_ptr device) @@ -619,7 +658,8 @@ void AddDevice(std::unique_ptr device) RemoveDevice(device_number); // Set the new one - s_channel.at(device_number).device = std::move(device); + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.channel.at(device_number).device = std::move(device); } void AddDevice(const SIDevices device, int device_number) @@ -630,12 +670,14 @@ void AddDevice(const SIDevices device, int device_number) void ChangeDevice(SIDevices device, int channel) { // Actual device change will happen in UpdateDevices. - s_desired_device_types[channel] = device; + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + state.desired_device_types[channel] = device; } static void ChangeDeviceDeterministic(SIDevices device, int channel) { - if (s_channel[channel].has_recent_device_change) + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + if (state.channel[channel].has_recent_device_change) return; if (GetDeviceType(channel) != SIDEVICE_NONE) @@ -644,26 +686,29 @@ static void ChangeDeviceDeterministic(SIDevices device, int channel) device = SIDEVICE_NONE; } - s_channel[channel].out.hex = 0; - s_channel[channel].in_hi.hex = 0; - s_channel[channel].in_lo.hex = 0; + state.channel[channel].out.hex = 0; + state.channel[channel].in_hi.hex = 0; + state.channel[channel].in_lo.hex = 0; SetNoResponse(channel); AddDevice(device, channel); // Prevent additional device changes on this channel for one second. - s_channel[channel].has_recent_device_change = true; - CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_change_device_event, channel); + state.channel[channel].has_recent_device_change = true; + CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), state.event_type_change_device, + channel); } void UpdateDevices() { + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + // Check for device change requests: for (int i = 0; i != MAX_SI_CHANNELS; ++i) { const SIDevices current_type = GetDeviceType(i); - const SIDevices desired_type = s_desired_device_types[i]; + const SIDevices desired_type = state.desired_device_types[i]; if (current_type != desired_type) { @@ -681,14 +726,14 @@ void UpdateDevices() g_controller_interface.UpdateInput(); // Update channels and set the status bit if there's new data - s_status_reg.RDST0 = - !!s_channel[0].device->GetData(s_channel[0].in_hi.hex, s_channel[0].in_lo.hex); - s_status_reg.RDST1 = - !!s_channel[1].device->GetData(s_channel[1].in_hi.hex, s_channel[1].in_lo.hex); - s_status_reg.RDST2 = - !!s_channel[2].device->GetData(s_channel[2].in_hi.hex, s_channel[2].in_lo.hex); - s_status_reg.RDST3 = - !!s_channel[3].device->GetData(s_channel[3].in_hi.hex, s_channel[3].in_lo.hex); + state.status_reg.RDST0 = + !!state.channel[0].device->GetData(state.channel[0].in_hi.hex, state.channel[0].in_lo.hex); + state.status_reg.RDST1 = + !!state.channel[1].device->GetData(state.channel[1].in_hi.hex, state.channel[1].in_lo.hex); + state.status_reg.RDST2 = + !!state.channel[2].device->GetData(state.channel[2].in_hi.hex, state.channel[2].in_lo.hex); + state.status_reg.RDST3 = + !!state.channel[3].device->GetData(state.channel[3].in_hi.hex, state.channel[3].in_lo.hex); UpdateInterrupts(); @@ -698,15 +743,17 @@ void UpdateDevices() SIDevices GetDeviceType(int channel) { - if (channel < 0 || channel >= MAX_SI_CHANNELS || !s_channel[channel].device) + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + if (channel < 0 || channel >= MAX_SI_CHANNELS || !state.channel[channel].device) return SIDEVICE_NONE; - return s_channel[channel].device->GetDeviceType(); + return state.channel[channel].device->GetDeviceType(); } u32 GetPollXLines() { - return s_poll.X; + auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData(); + return state.poll.X; } } // namespace SerialInterface diff --git a/Source/Core/Core/HW/SI/SI.h b/Source/Core/Core/HW/SI/SI.h index 07ece208ce..2c877c7ba6 100644 --- a/Source/Core/Core/HW/SI/SI.h +++ b/Source/Core/Core/HW/SI/SI.h @@ -15,6 +15,23 @@ class Mapping; namespace SerialInterface { +class SerialInterfaceState +{ +public: + SerialInterfaceState(); + SerialInterfaceState(const SerialInterfaceState&) = delete; + SerialInterfaceState(SerialInterfaceState&&) = delete; + SerialInterfaceState& operator=(const SerialInterfaceState&) = delete; + SerialInterfaceState& operator=(SerialInterfaceState&&) = delete; + ~SerialInterfaceState(); + + struct Data; + Data& GetData() { return *m_data; } + +private: + std::unique_ptr m_data; +}; + class ISIDevice; enum SIDevices : int; diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp index e88386b025..700a1dd15c 100644 --- a/Source/Core/Core/System.cpp +++ b/Source/Core/Core/System.cpp @@ -12,6 +12,7 @@ #include "Core/HW/DVD/DVDInterface.h" #include "Core/HW/DVD/DVDThread.h" #include "Core/HW/EXI/EXI.h" +#include "Core/HW/SI/SI.h" #include "Core/HW/Sram.h" #include "Core/HW/VideoInterface.h" @@ -28,6 +29,7 @@ struct System::Impl DVDInterface::DVDInterfaceState m_dvd_interface_state; DVDThread::DVDThreadState m_dvd_thread_state; ExpansionInterface::ExpansionInterfaceState m_expansion_interface_state; + SerialInterface::SerialInterfaceState m_serial_interface_state; Sram m_sram; VideoInterface::VideoInterfaceState m_video_interface_state; }; @@ -100,6 +102,11 @@ ExpansionInterface::ExpansionInterfaceState& System::GetExpansionInterfaceState( return m_impl->m_expansion_interface_state; } +SerialInterface::SerialInterfaceState& System::GetSerialInterfaceState() const +{ + return m_impl->m_serial_interface_state; +} + Sram& System::GetSRAM() const { return m_impl->m_sram; diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h index f8b2f1ef5e..75a28ead97 100644 --- a/Source/Core/Core/System.h +++ b/Source/Core/Core/System.h @@ -28,6 +28,10 @@ namespace ExpansionInterface { class ExpansionInterfaceState; }; +namespace SerialInterface +{ +class SerialInterfaceState; +}; namespace VideoInterface { class VideoInterfaceState; @@ -72,6 +76,7 @@ public: DVDInterface::DVDInterfaceState& GetDVDInterfaceState() const; DVDThread::DVDThreadState& GetDVDThreadState() const; ExpansionInterface::ExpansionInterfaceState& GetExpansionInterfaceState() const; + SerialInterface::SerialInterfaceState& GetSerialInterfaceState() const; Sram& GetSRAM() const; VideoInterface::VideoInterfaceState& GetVideoInterfaceState() const;