mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-20 19:44:57 +00:00
Refactoring finished; AVE working again
This commit is contained in:
parent
5893ea9660
commit
c553cd5dbf
3 changed files with 142 additions and 82 deletions
|
@ -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
|
||||
|
|
|
@ -26,9 +26,28 @@ public:
|
|||
// 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) {}
|
||||
|
@ -40,12 +59,14 @@ public:
|
|||
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;
|
||||
|
|
|
@ -120,84 +120,6 @@ 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;
|
||||
|
||||
static CoreTiming::EventType* updateInterrupts;
|
||||
|
||||
WiiIPC::WiiIPC(Core::System& system) : m_system(system)
|
||||
{
|
||||
}
|
||||
|
||||
WiiIPC::~WiiIPC() = default;
|
||||
|
||||
void WiiIPC::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_ppc_msg);
|
||||
p.Do(m_arm_msg);
|
||||
p.Do(m_ctrl);
|
||||
p.Do(m_ppc_irq_flags);
|
||||
p.Do(m_ppc_irq_masks);
|
||||
p.Do(m_arm_irq_flags);
|
||||
p.Do(m_arm_irq_masks);
|
||||
p.Do(m_gpio_dir);
|
||||
p.Do(m_gpio_out);
|
||||
i2c_state.DoState(p);
|
||||
p.Do(ave_state.data);
|
||||
p.Do(m_resets);
|
||||
}
|
||||
|
||||
void WiiIPC::InitState()
|
||||
{
|
||||
m_ctrl = CtrlRegister();
|
||||
m_ppc_msg = 0;
|
||||
m_arm_msg = 0;
|
||||
|
||||
m_ppc_irq_flags = 0;
|
||||
m_ppc_irq_masks = 0;
|
||||
m_arm_irq_flags = 0;
|
||||
m_arm_irq_masks = 0;
|
||||
|
||||
// The only inputs are POWER, EJECT_BTN, SLOT_IN, EEP_MISO, and sometimes AVE_SCL and AVE_SDA;
|
||||
// Broadway only has access to SLOT_IN, AVE_SCL, and AVE_SDA.
|
||||
m_gpio_dir = {
|
||||
GPIO::POWER, GPIO::SHUTDOWN, GPIO::FAN, GPIO::DC_DC, GPIO::DI_SPIN, GPIO::SLOT_LED,
|
||||
GPIO::SENSOR_BAR, GPIO::DO_EJECT, GPIO::EEP_CS, GPIO::EEP_CLK, GPIO::EEP_MOSI, GPIO::AVE_SCL,
|
||||
GPIO::AVE_SDA, GPIO::DEBUG0, GPIO::DEBUG1, GPIO::DEBUG2, GPIO::DEBUG3, GPIO::DEBUG4,
|
||||
GPIO::DEBUG5, GPIO::DEBUG6, GPIO::DEBUG7,
|
||||
};
|
||||
m_gpio_out = {};
|
||||
|
||||
// A cleared bit indicates the device is reset/off, so set everything to 1 (this may not exactly
|
||||
// match hardware)
|
||||
m_resets = 0xffffffff;
|
||||
|
||||
m_ppc_irq_masks |= INT_CAUSE_IPC_BROADWAY;
|
||||
|
||||
i2c_state = {};
|
||||
ave_state = {};
|
||||
ave_state.data.video_output_config = 0x23;
|
||||
ave_ever_logged.reset();
|
||||
}
|
||||
|
||||
void WiiIPC::Init()
|
||||
{
|
||||
InitState();
|
||||
m_event_type_update_interrupts =
|
||||
m_system.GetCoreTiming().RegisterEvent("IPCInterrupt", UpdateInterruptsCallback);
|
||||
}
|
||||
|
||||
void WiiIPC::Reset()
|
||||
{
|
||||
INFO_LOG_FMT(WII_IPC, "Resetting ...");
|
||||
InitState();
|
||||
}
|
||||
|
||||
void WiiIPC::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
std::string_view GetAVERegisterName(u8 address)
|
||||
{
|
||||
|
@ -243,6 +165,123 @@ std::string_view GetAVERegisterName(u8 address)
|
|||
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); }
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
WiiIPC::~WiiIPC() = default;
|
||||
|
||||
void WiiIPC::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_ppc_msg);
|
||||
p.Do(m_arm_msg);
|
||||
p.Do(m_ctrl);
|
||||
p.Do(m_ppc_irq_flags);
|
||||
p.Do(m_ppc_irq_masks);
|
||||
p.Do(m_arm_irq_flags);
|
||||
p.Do(m_arm_irq_masks);
|
||||
p.Do(m_gpio_dir);
|
||||
p.Do(m_gpio_out);
|
||||
i2c_state.DoState(p);
|
||||
ave_state.DoState(p);
|
||||
p.Do(m_resets);
|
||||
}
|
||||
|
||||
void WiiIPC::InitState()
|
||||
{
|
||||
m_ctrl = CtrlRegister();
|
||||
m_ppc_msg = 0;
|
||||
m_arm_msg = 0;
|
||||
|
||||
m_ppc_irq_flags = 0;
|
||||
m_ppc_irq_masks = 0;
|
||||
m_arm_irq_flags = 0;
|
||||
m_arm_irq_masks = 0;
|
||||
|
||||
// The only inputs are POWER, EJECT_BTN, SLOT_IN, EEP_MISO, and sometimes AVE_SCL and AVE_SDA;
|
||||
// Broadway only has access to SLOT_IN, AVE_SCL, and AVE_SDA.
|
||||
m_gpio_dir = {
|
||||
GPIO::POWER, GPIO::SHUTDOWN, GPIO::FAN, GPIO::DC_DC, GPIO::DI_SPIN, GPIO::SLOT_LED,
|
||||
GPIO::SENSOR_BAR, GPIO::DO_EJECT, GPIO::EEP_CS, GPIO::EEP_CLK, GPIO::EEP_MOSI, GPIO::AVE_SCL,
|
||||
GPIO::AVE_SDA, GPIO::DEBUG0, GPIO::DEBUG1, GPIO::DEBUG2, GPIO::DEBUG3, GPIO::DEBUG4,
|
||||
GPIO::DEBUG5, GPIO::DEBUG6, GPIO::DEBUG7,
|
||||
};
|
||||
m_gpio_out = {};
|
||||
|
||||
// A cleared bit indicates the device is reset/off, so set everything to 1 (this may not exactly
|
||||
// match hardware)
|
||||
m_resets = 0xffffffff;
|
||||
|
||||
m_ppc_irq_masks |= INT_CAUSE_IPC_BROADWAY;
|
||||
|
||||
i2c_state = {};
|
||||
ave_state.Reset();
|
||||
}
|
||||
|
||||
void WiiIPC::Init()
|
||||
{
|
||||
InitState();
|
||||
m_event_type_update_interrupts =
|
||||
m_system.GetCoreTiming().RegisterEvent("IPCInterrupt", UpdateInterruptsCallback);
|
||||
}
|
||||
|
||||
void WiiIPC::Reset()
|
||||
{
|
||||
INFO_LOG_FMT(WII_IPC, "Resetting ...");
|
||||
InitState();
|
||||
}
|
||||
|
||||
void WiiIPC::Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
static u32 ReadGPIOIn(Core::System& system)
|
||||
{
|
||||
Common::Flags<GPIO> gpio_in;
|
||||
|
|
Loading…
Add table
Reference in a new issue