diff options
| author | Link Mauve <linkmauve@linkmauve.fr> | 2026-05-06 22:24:49 +0200 |
|---|---|---|
| committer | Link Mauve <linkmauve@linkmauve.fr> | 2026-06-26 01:32:15 +0200 |
| commit | 82a317124ade2392ad04dd47582c14e839a4c998 (patch) | |
| tree | f62feac0380890486515721ac10dbca35fa548f7 /Source/Core | |
| parent | baf91d4436449ef9b7e5afe2988cbba0fcc60eb8 (diff) | |
HW/ProcessorInterface: Add support for all known registers
These changes originate from testing the behaviour of the PI registers
in Linux on my Wii.
I started by testing the masks, writing 0xFFFF_FFFF to the registers on
the Wii, and then got told about their value on a GameCube, and then
figured out most of the registers through a discussion with Extrems.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/HW/ProcessorInterface.cpp | 42 | ||||
| -rw-r--r-- | Source/Core/Core/HW/ProcessorInterface.h | 25 | ||||
| -rw-r--r-- | 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<u32>(&m_fifo_cpu_base), - MMIO::DirectWrite<u32>(&m_fifo_cpu_base, 0xFFFFFFE0)); + MMIO::ComplexWrite<u32>([](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<u32>(&m_fifo_cpu_end), - MMIO::DirectWrite<u32>(&m_fifo_cpu_end, 0xFFFFFFE0)); + MMIO::ComplexWrite<u32>([](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<u32>(&m_fifo_cpu_write_pointer), - MMIO::DirectWrite<u32>(&m_fifo_cpu_write_pointer, 0xFFFFFFE0)); + MMIO::ComplexWrite<u32>([](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<u32>(), MMIO::ComplexWrite<u32>([](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<u32>(&m_error_cause), + MMIO::DirectWrite<u32>(&m_error_cause, 0x00000007)); + + mmio->Register(base | PI_ERROR_ADDRESS, MMIO::DirectRead<u32>(&m_error_address), + MMIO::InvalidWrite<u32>()); + mmio->Register(base | PI_RESET_CODE, MMIO::ComplexRead<u32>([](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<u32>(&m_unknown), + MMIO::DirectWrite<u32>(&m_unknown, 0x000003FF)); + mmio->Register(base | PI_FLIPPER_REV, MMIO::Constant<u32>(FLIPPER_REV_C), MMIO::InvalidWrite<u32>()); + mmio->Register(base | PI_FLIPPER_BUS_STRENGTH, MMIO::DirectRead<u32>(&m_flipper_bus_strength), + MMIO::DirectWrite<u32>(&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 040c60f6ab..345e1537e5 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -96,7 +96,7 @@ struct CompressAndDumpStateArgs static Common::WorkQueueThreadSP<CompressAndDumpStateArgs> s_compress_and_dump_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 191; // Last changed in PR 14668 +constexpr u32 STATE_VERSION = 192; // Last changed in PR 14646 // Increase this if the StateExtendedHeader definition changes constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217 |
