From 951a84833a87acb79bd39c141a98cb96d88604be Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Thu, 27 Feb 2025 21:38:59 +0000 Subject: [PATCH 1/2] EXI: fix AD16 The GameCube IPL is now able to detect this device. However, this triggers some memory clearing code that trips up Dolphin's I$. --- Source/Core/Core/HW/EXI/EXI_DeviceAD16.cpp | 4 +++- Source/Core/Core/HW/EXI/EXI_DeviceAD16.h | 2 +- Source/Core/Core/State.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceAD16.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceAD16.cpp index 9172df5041..397679bcb7 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceAD16.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceAD16.cpp @@ -6,6 +6,7 @@ #include "Common/Assert.h" #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" +#include "Common/Swap.h" namespace ExpansionInterface { @@ -36,7 +37,7 @@ void CEXIAD16::TransferByte(u8& byte) { case init: { - m_ad16_register.U32 = 0x04120000; + m_ad16_register.U32 = Common::swap32(0x04120000); switch (m_position) { case 1: @@ -73,6 +74,7 @@ void CEXIAD16::TransferByte(u8& byte) break; case 4: m_ad16_register.U8[3] = byte; + INFO_LOG_FMT(EXPANSIONINTERFACE, "AD16 received: 0x{:08X}", m_ad16_register.U32); break; } } diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceAD16.h b/Source/Core/Core/HW/EXI/EXI_DeviceAD16.h index 4e64c9519d..a1e088e6ab 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceAD16.h +++ b/Source/Core/Core/HW/EXI/EXI_DeviceAD16.h @@ -28,7 +28,7 @@ private: union AD16Reg { u32 U32 = 0; - u32 U8[4]; + u8 U8[4]; }; // STATE_TO_SAVE diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index a244fda1b6..bbbe71c71c 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -99,7 +99,7 @@ static size_t s_state_writes_in_queue; static std::condition_variable s_state_write_queue_is_empty; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 171; // Last changed in PR 13416 +constexpr u32 STATE_VERSION = 172; // Last changed in PR 13385 // Increase this if the StateExtendedHeader definition changes constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217 From 90b6f0d16d6036b1bc326b8a7fbb0b986892262f Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Sat, 1 Mar 2025 16:34:43 +0000 Subject: [PATCH 2/2] Config: make SP2 configurable --- Source/Core/Core/Config/MainSettings.cpp | 3 +++ Source/Core/Core/Config/MainSettings.h | 1 + Source/Core/Core/HW/EXI/EXI.cpp | 7 ++++++- Source/Core/Core/HW/EXI/EXI.h | 7 ++++--- .../Core/DolphinQt/Settings/GameCubePane.cpp | 20 +++++++++---------- Source/Core/DolphinQt/Settings/GameCubePane.h | 4 ++-- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 2a3c11afd0..751ab05656 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -116,6 +116,8 @@ const Info MAIN_SLOT_B{{System::Main, "Core", ExpansionInterface::EXIDeviceType::None}; const Info MAIN_SERIAL_PORT_1{ {System::Main, "Core", "SerialPort1"}, ExpansionInterface::EXIDeviceType::None}; +const Info MAIN_SERIAL_PORT_2{ + {System::Main, "Core", "SerialPort2"}, ExpansionInterface::EXIDeviceType::None}; const Info& GetInfoForEXIDevice(ExpansionInterface::Slot slot) { @@ -125,6 +127,7 @@ const Info& GetInfoForEXIDevice(ExpansionInte &MAIN_SLOT_A, &MAIN_SLOT_B, &MAIN_SERIAL_PORT_1, + &MAIN_SERIAL_PORT_2, }; return *infos[slot]; } diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 44f33b0111..8d8fbebb57 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -89,6 +89,7 @@ extern const Info MAIN_MEMORY_CARD_SIZE; extern const Info MAIN_SLOT_A; extern const Info MAIN_SLOT_B; extern const Info MAIN_SERIAL_PORT_1; +extern const Info MAIN_SERIAL_PORT_2; const Info& GetInfoForEXIDevice(ExpansionInterface::Slot slot); extern const Info MAIN_BBA_MAC; extern const Info MAIN_BBA_XLINK_IP; diff --git a/Source/Core/Core/HW/EXI/EXI.cpp b/Source/Core/Core/HW/EXI/EXI.cpp index fd371fa076..303191c574 100644 --- a/Source/Core/Core/HW/EXI/EXI.cpp +++ b/Source/Core/Core/HW/EXI/EXI.cpp @@ -76,6 +76,8 @@ u8 SlotToEXIChannel(Slot slot) return 1; case Slot::SP1: return 0; + case Slot::SP2: + return 2; default: PanicAlertFmt("Unhandled slot {}", slot); return 0; @@ -92,6 +94,8 @@ u8 SlotToEXIDevice(Slot slot) return 0; case Slot::SP1: return 2; + case Slot::SP2: + return 0; default: PanicAlertFmt("Unhandled slot {}", slot); return 0; @@ -143,7 +147,8 @@ void ExpansionInterfaceManager::Init(const Sram* override_sram) m_channels[0]->AddDevice(EXIDeviceType::MaskROM, 1); m_channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1), SlotToEXIDevice(Slot::SP1)); - m_channels[2]->AddDevice(EXIDeviceType::AD16, 0); + m_channels[SlotToEXIChannel(Slot::SP2)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_2), + SlotToEXIDevice(Slot::SP2)); m_event_type_change_device = core_timing.RegisterEvent("ChangeEXIDevice", ChangeDeviceCallback); m_event_type_update_interrupts = diff --git a/Source/Core/Core/HW/EXI/EXI.h b/Source/Core/Core/HW/EXI/EXI.h index a4f2b899d0..7ded905b98 100644 --- a/Source/Core/Core/HW/EXI/EXI.h +++ b/Source/Core/Core/HW/EXI/EXI.h @@ -44,11 +44,12 @@ enum class Slot : int A, B, SP1, + SP2, }; // Note: using auto here results in a false warning on GCC // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80351 -constexpr std::initializer_list SLOTS = {Slot::A, Slot::B, Slot::SP1}; -constexpr auto MAX_SLOT = Slot::SP1; +constexpr std::initializer_list SLOTS = {Slot::A, Slot::B, Slot::SP1, Slot::SP2}; +constexpr auto MAX_SLOT = Slot::SP2; constexpr std::initializer_list MEMCARD_SLOTS = {Slot::A, Slot::B}; constexpr auto MAX_MEMCARD_SLOT = Slot::B; constexpr bool IsMemcardSlot(Slot slot) @@ -106,5 +107,5 @@ private: template <> struct fmt::formatter : EnumFormatter { - constexpr formatter() : EnumFormatter({"Slot A", "Slot B", "Serial Port 1"}) {} + constexpr formatter() : EnumFormatter({"Slot A", "Slot B", "Serial Port 1", "Serial Port 2"}) {} }; diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index 806e0c7840..8043ea51a0 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -44,13 +44,8 @@ #include "DolphinQt/Settings.h" #include "DolphinQt/Settings/BroadbandAdapterSettingsDialog.h" -enum -{ - SLOT_A_INDEX, - SLOT_B_INDEX, - SLOT_SP1_INDEX, - SLOT_COUNT -}; +constexpr std::initializer_list GUI_SLOTS = { + ExpansionInterface::Slot::A, ExpansionInterface::Slot::B, ExpansionInterface::Slot::SP1}; GameCubePane::GameCubePane() { @@ -95,7 +90,7 @@ void GameCubePane::CreateWidgets() QGridLayout* device_layout = new QGridLayout(device_box); device_box->setLayout(device_layout); - for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS) + for (ExpansionInterface::Slot slot : GUI_SLOTS) { m_slot_combos[slot] = new QComboBox(device_box); m_slot_combos[slot]->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); @@ -251,7 +246,7 @@ void GameCubePane::ConnectWidgets() connect(m_language_combo, &QComboBox::currentIndexChanged, this, &GameCubePane::SaveSettings); // Device Settings - for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS) + for (ExpansionInterface::Slot slot : GUI_SLOTS) { connect(m_slot_combos[slot], &QComboBox::currentIndexChanged, this, [this, slot] { UpdateButton(slot); }); @@ -358,6 +353,9 @@ void GameCubePane::UpdateButton(ExpansionInterface::Slot slot) device == ExpansionInterface::EXIDeviceType::EthernetBuiltIn || device == ExpansionInterface::EXIDeviceType::ModemTapServer); break; + case ExpansionInterface::Slot::SP2: + has_config = false; + break; } m_slot_buttons[slot]->setEnabled(has_config); @@ -739,7 +737,7 @@ void GameCubePane::LoadSettings() m_skip_main_menu->setToolTip(have_menu ? QString{} : tr("Put IPL ROMs in User/GC/.")); // Device Settings - for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS) + for (ExpansionInterface::Slot slot : GUI_SLOTS) { const ExpansionInterface::EXIDeviceType exi_device = Config::Get(Config::GetInfoForEXIDevice(slot)); @@ -784,7 +782,7 @@ void GameCubePane::SaveSettings() auto& system = Core::System::GetInstance(); // Device Settings - for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS) + for (ExpansionInterface::Slot slot : GUI_SLOTS) { const auto dev = static_cast(m_slot_combos[slot]->currentData().toInt()); diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.h b/Source/Core/DolphinQt/Settings/GameCubePane.h index 35862e2f57..05186f81aa 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.h +++ b/Source/Core/DolphinQt/Settings/GameCubePane.h @@ -55,8 +55,8 @@ private: QCheckBox* m_skip_main_menu; QComboBox* m_language_combo; - Common::EnumMap m_slot_buttons; - Common::EnumMap m_slot_combos; + Common::EnumMap m_slot_buttons; + Common::EnumMap m_slot_combos; Common::EnumMap m_memcard_path_layouts; Common::EnumMap m_memcard_path_labels;