mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-04 15:19:09 +00:00
Handle dir behavior better
This commit is contained in:
parent
76767fcfb4
commit
143e4a8319
2 changed files with 28 additions and 11 deletions
|
@ -245,19 +245,25 @@ static u32 ReadGPIOIn(Core::System& system)
|
||||||
return gpio_in.m_hex;
|
return gpio_in.m_hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiiIPC::WriteGPIOOut(Core::System& system, bool broadway, u32 value)
|
u32 WiiIPC::GetGPIOOut()
|
||||||
{
|
{
|
||||||
Common::Flags<GPIO> old_value = m_gpio_out;
|
// In the direction field, a '1' bit for a pin indicates that it will behave as an output (drive),
|
||||||
|
// while a '0' bit tristates the pin and it becomes a high-impedance input.
|
||||||
|
// In practice this means that (at least for the AVE I²C pins) a 1 is output when the pin is an
|
||||||
|
// input. (RVLoader depends on this.)
|
||||||
|
// https://github.com/Aurelio92/RVLoader/blob/75732f248019f589deb1109bba7b5323a8afaadf/source/i2c.c#L101-L109
|
||||||
|
return m_gpio_out.m_hex | ~m_gpio_dir.m_hex;
|
||||||
|
}
|
||||||
|
|
||||||
if (broadway)
|
void WiiIPC::GPIOOutChanged(u32 old_value_hex)
|
||||||
m_gpio_out.m_hex = (value & gpio_owner.m_hex) | (m_gpio_out.m_hex & ~gpio_owner.m_hex);
|
{
|
||||||
else
|
Common::Flags<GPIO> old_value;
|
||||||
m_gpio_out.m_hex = (value & ~gpio_owner.m_hex) | (m_gpio_out.m_hex & gpio_owner.m_hex);
|
old_value.m_hex = old_value_hex;
|
||||||
|
|
||||||
if (m_gpio_out[GPIO::DO_EJECT])
|
if (m_gpio_out[GPIO::DO_EJECT])
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(WII_IPC, "Ejecting disc due to GPIO write");
|
INFO_LOG_FMT(WII_IPC, "Ejecting disc due to GPIO write");
|
||||||
system.GetDVDInterface().EjectDisc(Core::CPUThreadGuard{system}, DVD::EjectCause::Software);
|
m_system.GetDVDInterface().EjectDisc(Core::CPUThreadGuard{m_system}, DVD::EjectCause::Software);
|
||||||
}
|
}
|
||||||
|
|
||||||
// I²C logic for the audio/video encoder (AVE)
|
// I²C logic for the audio/video encoder (AVE)
|
||||||
|
@ -425,13 +431,18 @@ void WiiIPC::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
mmio->Register(base | GPIOB_OUT, MMIO::DirectRead<u32>(&m_gpio_out.m_hex),
|
mmio->Register(base | GPIOB_OUT, MMIO::DirectRead<u32>(&m_gpio_out.m_hex),
|
||||||
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
||||||
auto& wii_ipc = system.GetWiiIPC();
|
auto& wii_ipc = system.GetWiiIPC();
|
||||||
wii_ipc.WriteGPIOOut(system, true, val);
|
const u32 old_out = wii_ipc.GetGPIOOut();
|
||||||
|
wii_ipc.m_gpio_out.m_hex =
|
||||||
|
(val & gpio_owner.m_hex) | (wii_ipc.m_gpio_out.m_hex & ~gpio_owner.m_hex);
|
||||||
|
wii_ipc.GPIOOutChanged(old_out);
|
||||||
}));
|
}));
|
||||||
mmio->Register(base | GPIOB_DIR, MMIO::DirectRead<u32>(&m_gpio_dir.m_hex),
|
mmio->Register(base | GPIOB_DIR, MMIO::DirectRead<u32>(&m_gpio_dir.m_hex),
|
||||||
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
||||||
auto& wii_ipc = system.GetWiiIPC();
|
auto& wii_ipc = system.GetWiiIPC();
|
||||||
|
const u32 old_out = wii_ipc.GetGPIOOut();
|
||||||
wii_ipc.m_gpio_dir.m_hex =
|
wii_ipc.m_gpio_dir.m_hex =
|
||||||
(val & gpio_owner.m_hex) | (wii_ipc.m_gpio_dir.m_hex & ~gpio_owner.m_hex);
|
(val & gpio_owner.m_hex) | (wii_ipc.m_gpio_dir.m_hex & ~gpio_owner.m_hex);
|
||||||
|
wii_ipc.GPIOOutChanged(old_out);
|
||||||
}));
|
}));
|
||||||
mmio->Register(base | GPIOB_IN, MMIO::ComplexRead<u32>([](Core::System& system, u32) {
|
mmio->Register(base | GPIOB_IN, MMIO::ComplexRead<u32>([](Core::System& system, u32) {
|
||||||
return ReadGPIOIn(system);
|
return ReadGPIOIn(system);
|
||||||
|
@ -451,13 +462,18 @@ void WiiIPC::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
mmio->Register(base | GPIO_OUT, MMIO::DirectRead<u32>(&m_gpio_out.m_hex),
|
mmio->Register(base | GPIO_OUT, MMIO::DirectRead<u32>(&m_gpio_out.m_hex),
|
||||||
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
||||||
auto& wii_ipc = system.GetWiiIPC();
|
auto& wii_ipc = system.GetWiiIPC();
|
||||||
wii_ipc.WriteGPIOOut(system, false, val);
|
const u32 old_out = wii_ipc.GetGPIOOut();
|
||||||
|
wii_ipc.m_gpio_out.m_hex =
|
||||||
|
(val & ~gpio_owner.m_hex) | (wii_ipc.m_gpio_out.m_hex & gpio_owner.m_hex);
|
||||||
|
wii_ipc.GPIOOutChanged(old_out);
|
||||||
}));
|
}));
|
||||||
mmio->Register(base | GPIO_DIR, MMIO::DirectRead<u32>(&m_gpio_dir.m_hex),
|
mmio->Register(base | GPIO_DIR, MMIO::DirectRead<u32>(&m_gpio_dir.m_hex),
|
||||||
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
||||||
auto& wii_ipc = system.GetWiiIPC();
|
auto& wii_ipc = system.GetWiiIPC();
|
||||||
|
const u32 old_out = wii_ipc.GetGPIOOut();
|
||||||
wii_ipc.m_gpio_dir.m_hex =
|
wii_ipc.m_gpio_dir.m_hex =
|
||||||
(wii_ipc.m_gpio_dir.m_hex & gpio_owner.m_hex) | (val & ~gpio_owner.m_hex);
|
(val & gpio_owner.m_hex) | (wii_ipc.m_gpio_dir.m_hex & ~gpio_owner.m_hex);
|
||||||
|
wii_ipc.GPIOOutChanged(old_out);
|
||||||
}));
|
}));
|
||||||
mmio->Register(base | GPIO_IN, MMIO::ComplexRead<u32>([](Core::System& system, u32) {
|
mmio->Register(base | GPIO_IN, MMIO::ComplexRead<u32>([](Core::System& system, u32) {
|
||||||
return ReadGPIOIn(system);
|
return ReadGPIOIn(system);
|
||||||
|
|
|
@ -140,7 +140,8 @@ private:
|
||||||
|
|
||||||
static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
void WriteGPIOOut(Core::System& system, bool broadway, u32 value);
|
u32 GetGPIOOut();
|
||||||
|
void GPIOOutChanged(u32 old_value_hex);
|
||||||
|
|
||||||
u32 m_ppc_msg = 0;
|
u32 m_ppc_msg = 0;
|
||||||
u32 m_arm_msg = 0;
|
u32 m_arm_msg = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue