From 96a52410e3d7b273b1c47ba73dafbe364e844260 Mon Sep 17 00:00:00 2001 From: Link Mauve Date: Wed, 6 May 2026 22:24:49 +0200 Subject: [PATCH] HW/ProcessorInterface: Implement more of the registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I’ve found those masks by writing 0xFFFF_FFFF to the registers on Linux on my Wii, whereas the masks are smaller on the GameCube. --- Source/Core/Core/HW/ProcessorInterface.cpp | 42 +++++++++++++++++++--- Source/Core/Core/HW/ProcessorInterface.h | 25 ++++++++++++- Source/Core/Core/State.cpp | 2 +- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/HW/ProcessorInterface.cpp b/Source/Core/Core/HW/ProcessorInterface.cpp index 7b999ac0de..10cca6c1c5 100644 --- a/Source/Core/Core/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/HW/ProcessorInterface.cpp @@ -41,20 +41,27 @@ void ProcessorInterfaceManager::DoState(PointerWrap& p) p.Do(m_fifo_cpu_base); p.Do(m_fifo_cpu_end); p.Do(m_fifo_cpu_write_pointer); + p.Do(m_error_cause); + p.Do(m_error_address); p.Do(m_reset_code); + p.Do(m_unknown); + p.Do(m_flipper_bus_strength); } void ProcessorInterfaceManager::Init() { m_interrupt_mask = 0; - m_interrupt_cause = 0; + m_interrupt_cause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI; m_fifo_cpu_base = 0; m_fifo_cpu_end = 0; m_fifo_cpu_write_pointer = 0; + m_error_cause = 0; + m_error_address = 0; m_reset_code = 0; // Cold reset - m_interrupt_cause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI; + m_unknown = 0x000001FF; + m_flipper_bus_strength = 0x02492492; auto& core_timing = m_system.GetCoreTiming(); m_event_type_toggle_reset_button = @@ -82,13 +89,25 @@ void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base) })); mmio->Register(base | PI_FIFO_BASE, MMIO::DirectRead(&m_fifo_cpu_base), - MMIO::DirectWrite(&m_fifo_cpu_base, 0xFFFFFFE0)); + MMIO::ComplexWrite([](Core::System& system, u32, u32 val) { + u32 mask = CommandProcessor::GetPhysicalAddressMask(system.IsWii()) & 0xFFFFFFE0; + auto& processor_interface = system.GetProcessorInterface(); + processor_interface.m_fifo_cpu_base = val & mask; + })); mmio->Register(base | PI_FIFO_END, MMIO::DirectRead(&m_fifo_cpu_end), - MMIO::DirectWrite(&m_fifo_cpu_end, 0xFFFFFFE0)); + MMIO::ComplexWrite([](Core::System& system, u32, u32 val) { + u32 mask = CommandProcessor::GetPhysicalAddressMask(system.IsWii()) & 0xFFFFFFE0; + auto& processor_interface = system.GetProcessorInterface(); + processor_interface.m_fifo_cpu_end = val & mask; + })); mmio->Register(base | PI_FIFO_WPTR, MMIO::DirectRead(&m_fifo_cpu_write_pointer), - MMIO::DirectWrite(&m_fifo_cpu_write_pointer, 0xFFFFFFE0)); + MMIO::ComplexWrite([](Core::System& system, u32, u32 val) { + u32 mask = CommandProcessor::GetPhysicalAddressMask(system.IsWii()) & 0xFFFFFFE0; + auto& processor_interface = system.GetProcessorInterface(); + processor_interface.m_fifo_cpu_write_pointer = val & mask; + })); mmio->Register(base | PI_FIFO_RESET, MMIO::InvalidRead(), MMIO::ComplexWrite([](Core::System& system, u32, u32 val) { @@ -116,6 +135,13 @@ void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base) } })); + // TODO: Use the ErrorCause enum instead. + mmio->Register(base | PI_ERROR_CAUSE, MMIO::DirectRead(&m_error_cause), + MMIO::DirectWrite(&m_error_cause, 0x00000007)); + + mmio->Register(base | PI_ERROR_ADDRESS, MMIO::DirectRead(&m_error_address), + MMIO::InvalidWrite()); + mmio->Register(base | PI_RESET_CODE, MMIO::ComplexRead([](Core::System& system, u32) { auto& processor_interface = system.GetProcessorInterface(); DEBUG_LOG_FMT(PROCESSORINTERFACE, "Read PI_RESET_CODE: {:08x}", @@ -133,9 +159,15 @@ void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base) } })); + mmio->Register(base | PI_UNKNOWN, MMIO::DirectRead(&m_unknown), + MMIO::DirectWrite(&m_unknown, 0x000003FF)); + mmio->Register(base | PI_FLIPPER_REV, MMIO::Constant(FLIPPER_REV_C), MMIO::InvalidWrite()); + mmio->Register(base | PI_FLIPPER_BUS_STRENGTH, MMIO::DirectRead(&m_flipper_bus_strength), + MMIO::DirectWrite(&m_flipper_bus_strength, 0x07FFFFFF)); + // 16 bit reads are based on 32 bit reads. for (u32 i = 0; i < 0x1000; i += 4) { diff --git a/Source/Core/Core/HW/ProcessorInterface.h b/Source/Core/Core/HW/ProcessorInterface.h index 6387634843..4934147609 100644 --- a/Source/Core/Core/HW/ProcessorInterface.h +++ b/Source/Core/Core/HW/ProcessorInterface.h @@ -55,9 +55,27 @@ enum PI_FIFO_END = 0x10, PI_FIFO_WPTR = 0x14, PI_FIFO_RESET = 0x18, // Used by GXAbortFrame + PI_ERROR_CAUSE = 0x1C, + PI_ERROR_ADDRESS = 0x20, PI_RESET_CODE = 0x24, + PI_UNKNOWN = 0x28, PI_FLIPPER_REV = 0x2C, - PI_FLIPPER_UNK = 0x30 // BS1 writes 0x0245248A to it - prolly some bootstrap thing + PI_FLIPPER_BUS_STRENGTH = 0x30 // BS1 writes 0x0245248A to it - controls the strength of the + // signal on the bus. 0 means the bus is dead and Flipper will + // not respond any longer, increasing it from the default value + // can reduce the noise in the Game Boy Player. +}; + +enum ErrorCause : u32 +{ + NoError = 0, + MisalignedAddress = 1, + IncorrectTransferType = 2, + UnsupportedTransferSize = 3, + AddressOutOfRange = 4, + WriteToROM = 5, + ReadFromGXFIFO = 6, + Reserved = 7, }; class ProcessorInterfaceManager @@ -92,6 +110,11 @@ public: u32 m_fifo_cpu_end = 0; u32 m_fifo_cpu_write_pointer = 0; + u32 m_error_cause = 0; + u32 m_error_address = 0; + u32 m_unknown = 0x000001FF; + u32 m_flipper_bus_strength = 0x02492492; + private: // Let the PPC know that an external exception is set/cleared void UpdateException(); diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 1d7ff9eb6a..9dffc65eb8 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -95,7 +95,7 @@ struct CompressAndDumpStateArgs static Common::WorkQueueThreadSP s_compress_and_dump_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 189; // Last changed in PR 14560 +constexpr u32 STATE_VERSION = 190; // Last changed in PR 14646 // Increase this if the StateExtendedHeader definition changes constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217