From d4c181a6f1dda4c398f32d62736a18218e24c98e Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 6 Sep 2022 14:00:21 -0700 Subject: [PATCH] Refactoring finished; AVE working again --- Source/Core/Common/I2C.cpp | 4 +- Source/Core/Common/I2C.h | 25 +++++- Source/Core/Core/HW/WII_IPC.cpp | 143 ++++++++++++++++++++------------ 3 files changed, 116 insertions(+), 56 deletions(-) diff --git a/Source/Core/Common/I2C.cpp b/Source/Core/Common/I2C.cpp index 43883d171a1f..82c2a57e9f1a 100644 --- a/Source/Core/Common/I2C.cpp +++ b/Source/Core/Common/I2C.cpp @@ -295,8 +295,6 @@ void I2CBus::SCLRisingEdge(const bool sda) { current_byte = byte.value(); } - // INFO_LOG_FMT(WII_IPC, "AVE: Read from {:02x} ({}) -> {:02x}", device_address.value(), - // IOS::GetAVERegisterName(device_address.value()), current_byte); } // Dolphin_Debugger::PrintCallstack(Common::Log::LogType::WII_IPC, Common::Log::LogLevel::LINFO); } @@ -508,6 +506,8 @@ void I2CSlaveAutoIncrementing::DoState(PointerWrap& p) } p.Do(m_active); p.Do(m_device_address); + + DoDeviceState(p); } }; // namespace Common diff --git a/Source/Core/Common/I2C.h b/Source/Core/Common/I2C.h index df13e03585d5..61b3c518bda1 100644 --- a/Source/Core/Common/I2C.h +++ b/Source/Core/Common/I2C.h @@ -26,9 +26,28 @@ class I2CSlave // transmitting device to NACK a read; only the receiver can NACK. virtual std::optional ReadByte() = 0; virtual bool WriteByte(u8 value) = 0; + +protected: + template + static u8 RawRead(T* reg_data, u8 addr) + { + static_assert(std::is_standard_layout_v && std::is_trivially_copyable_v); + static_assert(0x100 == sizeof(T)); + + return reinterpret_cast(reg_data)[addr]; + } + + template + static void RawWrite(T* reg_data, u8 addr, u8 value) + { + static_assert(std::is_standard_layout_v && std::is_trivially_copyable_v); + static_assert(0x100 == sizeof(T)); + + reinterpret_cast(reg_data)[addr] = value; + } }; -class I2CSlaveAutoIncrementing : I2CSlave +class I2CSlaveAutoIncrementing : public I2CSlave { public: I2CSlaveAutoIncrementing(u8 slave_addr) : m_slave_addr(slave_addr) {} @@ -40,12 +59,14 @@ class I2CSlaveAutoIncrementing : I2CSlave std::optional ReadByte() override; bool WriteByte(u8 value) override; - virtual void DoState(PointerWrap& p); + void DoState(PointerWrap& p); protected: virtual u8 ReadByte(u8 addr) = 0; virtual void WriteByte(u8 addr, u8 value) = 0; + virtual void DoDeviceState(PointerWrap& p) = 0; + private: const u8 m_slave_addr; bool m_active = false; diff --git a/Source/Core/Core/HW/WII_IPC.cpp b/Source/Core/Core/HW/WII_IPC.cpp index e854adafd64e..4a8fc2676acd 100644 --- a/Source/Core/Core/HW/WII_IPC.cpp +++ b/Source/Core/Core/HW/WII_IPC.cpp @@ -120,12 +120,97 @@ struct AVEState }; #pragma pack() static_assert(sizeof(AVEState) == 0x100); -Common::I2CSlaveSimple<0x70, AVEState> ave_state; -std::bitset ave_ever_logged; -Common::I2CBus i2c_state; +std::string_view GetAVERegisterName(u8 address) +{ + if (address == 0x00) + return "A/V Timings"; + else if (address == 0x01) + return "Video Output configuration"; + else if (address == 0x02) + return "Vertical blanking interval (VBI) control"; + else if (address == 0x03) + return "Composite Video Trap Filter control"; + else if (address == 0x04) + return "A/V output control"; + else if (address == 0x05 || address == 0x06) + return "CGMS protection"; + else if (address == 0x08 || address == 0x09) + return "WSS (Widescreen signaling)"; + else if (address == 0x0A) + return "RGB color output control"; + else if (address >= 0x10 && address <= 0x30) + return "Gamma coefficients"; + else if (address >= 0x40 && address <= 0x59) + return "Macrovision code"; + else if (address == 0x62) + return "RGB switch control"; + else if (address == 0x65) + return "Color DAC control"; + else if (address == 0x67) + return "Color Test"; + else if (address == 0x6A) + return "CCSEL"; + else if (address == 0x6D) + return "Audio mute control"; + else if (address == 0x6E) + return "RGB output filter"; + else if (address == 0x71) + return "Audio stereo output control - right volume"; + else if (address == 0x72) + return "Audio stereo output control - right volume"; + else if (address >= 0x7a && address <= 0x7d) + return "Closed Captioning control"; + else + return fmt::format("Unknown ({:02x})", address); +} + +class AVEDevice : public Common::I2CSlaveAutoIncrementing +{ +public: + AVEDevice() : I2CSlaveAutoIncrementing(0x70) {} + + void Reset() + { + m_registers = {}; + ave_ever_logged = {}; + } + + AVEState m_registers{}; + +protected: + u8 ReadByte(u8 addr) override + { + const u8 result = RawRead(&m_registers, addr); + INFO_LOG_FMT(WII_IPC, "AVE: Read from {:02x} ({}) -> {:02x}", addr, GetAVERegisterName(addr), + result); + return result; + } + void WriteByte(u8 addr, u8 value) override + { + const u8 old_value = RawRead(&m_registers, addr); + RawWrite(&m_registers, addr, value); + + if (old_value != value || !ave_ever_logged[addr]) + { + INFO_LOG_FMT(WII_IPC, "AVE: Write to {:02x} ({}): {:02x} -> {:02x}", addr, + GetAVERegisterName(addr), old_value, value); + ave_ever_logged[addr] = true; + } + else + { + DEBUG_LOG_FMT(WII_IPC, "AVE: Write to {:02x} ({}): {:02x}", addr, GetAVERegisterName(addr), + value); + } + } + void DoDeviceState(PointerWrap& p) override { p.Do(m_registers); } -static CoreTiming::EventType* updateInterrupts; +private: + std::bitset ave_ever_logged{}; // logging only, not saved +}; +AVEDevice ave_state; + +Common::I2CBus i2c_state; WiiIPC::WiiIPC(Core::System& system) : m_system(system) { @@ -145,7 +230,7 @@ void WiiIPC::DoState(PointerWrap& p) p.Do(m_gpio_dir); p.Do(m_gpio_out); i2c_state.DoState(p); - p.Do(ave_state.data); + ave_state.DoState(p); p.Do(m_resets); } @@ -177,9 +262,7 @@ void WiiIPC::InitState() m_ppc_irq_masks |= INT_CAUSE_IPC_BROADWAY; i2c_state = {}; - ave_state = {}; - ave_state.data.video_output_config = 0x23; - ave_ever_logged.reset(); + ave_state.Reset(); } void WiiIPC::Init() @@ -199,50 +282,6 @@ void WiiIPC::Shutdown() { } -std::string_view GetAVERegisterName(u8 address) -{ - if (address == 0x00) - return "A/V Timings"; - else if (address == 0x01) - return "Video Output configuration"; - else if (address == 0x02) - return "Vertical blanking interval (VBI) control"; - else if (address == 0x03) - return "Composite Video Trap Filter control"; - else if (address == 0x04) - return "A/V output control"; - else if (address == 0x05 || address == 0x06) - return "CGMS protection"; - else if (address == 0x08 || address == 0x09) - return "WSS (Widescreen signaling)"; - else if (address == 0x0A) - return "RGB color output control"; - else if (address >= 0x10 && address <= 0x30) - return "Gamma coefficients"; - else if (address >= 0x40 && address <= 0x59) - return "Macrovision code"; - else if (address == 0x62) - return "RGB switch control"; - else if (address == 0x65) - return "Color DAC control"; - else if (address == 0x67) - return "Color Test"; - else if (address == 0x6A) - return "CCSEL"; - else if (address == 0x6D) - return "Audio mute control"; - else if (address == 0x6E) - return "RGB output filter"; - else if (address == 0x71) - return "Audio stereo output control - right volume"; - else if (address == 0x72) - return "Audio stereo output control - right volume"; - else if (address >= 0x7a && address <= 0x7d) - return "Closed Captioning control"; - else - return fmt::format("Unknown ({:02x})", address); -} - static u32 ReadGPIOIn(Core::System& system) { Common::Flags gpio_in;