Skip to content

Commit

Permalink
Refactoring finished; AVE working again
Browse files Browse the repository at this point in the history
  • Loading branch information
Pokechu22 committed Jan 14, 2024
1 parent 5f20644 commit d4c181a
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 56 deletions.
4 changes: 2 additions & 2 deletions Source/Core/Common/I2C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -508,6 +506,8 @@ void I2CSlaveAutoIncrementing::DoState(PointerWrap& p)
}
p.Do(m_active);
p.Do(m_device_address);

DoDeviceState(p);
}

}; // namespace Common
Expand Down
25 changes: 23 additions & 2 deletions Source/Core/Common/I2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,28 @@ class I2CSlave
// transmitting device to NACK a read; only the receiver can NACK.
virtual std::optional<u8> ReadByte() = 0;
virtual bool WriteByte(u8 value) = 0;

protected:
template <typename T>
static u8 RawRead(T* reg_data, u8 addr)
{
static_assert(std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>);
static_assert(0x100 == sizeof(T));

return reinterpret_cast<u8*>(reg_data)[addr];
}

template <typename T>
static void RawWrite(T* reg_data, u8 addr, u8 value)
{
static_assert(std::is_standard_layout_v<T> && std::is_trivially_copyable_v<T>);
static_assert(0x100 == sizeof(T));

reinterpret_cast<u8*>(reg_data)[addr] = value;
}
};

class I2CSlaveAutoIncrementing : I2CSlave
class I2CSlaveAutoIncrementing : public I2CSlave
{
public:
I2CSlaveAutoIncrementing(u8 slave_addr) : m_slave_addr(slave_addr) {}
Expand All @@ -40,12 +59,14 @@ class I2CSlaveAutoIncrementing : I2CSlave
std::optional<u8> 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;
Expand Down
143 changes: 91 additions & 52 deletions Source/Core/Core/HW/WII_IPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,97 @@ struct AVEState
};
#pragma pack()
static_assert(sizeof(AVEState) == 0x100);
Common::I2CSlaveSimple<0x70, AVEState> ave_state;
std::bitset<sizeof(AVEState)> 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<sizeof(AVEState)> ave_ever_logged{}; // logging only, not saved
};
AVEDevice ave_state;

Common::I2CBus i2c_state;

WiiIPC::WiiIPC(Core::System& system) : m_system(system)
{
Expand All @@ -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);
}

Expand Down Expand Up @@ -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()
Expand All @@ -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> gpio_in;
Expand Down

0 comments on commit d4c181a

Please sign in to comment.