mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
Implement Broadway GPIOs
SLOT_LED and the AVE ones are not implemented yet, but the other Broadway ones are.
This commit is contained in:
parent
a695b05b21
commit
77189e74cd
@ -8,6 +8,7 @@
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common
|
||||
@ -299,4 +300,44 @@ void SetBit(T& value, size_t bit_number, bool bit_value)
|
||||
value &= ~(T{1} << bit_number);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class FlagBit
|
||||
{
|
||||
public:
|
||||
FlagBit(std::underlying_type_t<T>& bits, T bit) : m_bits(bits), m_bit(bit) {}
|
||||
explicit operator bool() const
|
||||
{
|
||||
return (m_bits & static_cast<std::underlying_type_t<T>>(m_bit)) != 0;
|
||||
}
|
||||
FlagBit& operator=(const bool rhs)
|
||||
{
|
||||
if (rhs)
|
||||
m_bits |= static_cast<std::underlying_type_t<T>>(m_bit);
|
||||
else
|
||||
m_bits &= ~static_cast<std::underlying_type_t<T>>(m_bit);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::underlying_type_t<T>& m_bits;
|
||||
T m_bit;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Flags
|
||||
{
|
||||
public:
|
||||
constexpr Flags() = default;
|
||||
constexpr Flags(std::initializer_list<T> bits)
|
||||
{
|
||||
for (auto bit : bits)
|
||||
{
|
||||
m_hex |= static_cast<std::underlying_type_t<T>>(bit);
|
||||
}
|
||||
}
|
||||
FlagBit<T> operator[](T bit) { return FlagBit(m_hex, bit); }
|
||||
|
||||
std::underlying_type_t<T> m_hex = 0;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/HW/DVD/DVDInterface.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
#include "Core/HW/ProcessorInterface.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
@ -97,7 +98,11 @@ static u32 ppc_irq_masks;
|
||||
static u32 arm_irq_flags;
|
||||
static u32 arm_irq_masks;
|
||||
|
||||
static u32 sensorbar_power; // do we need to care about this?
|
||||
// Indicates which pins are accessible by broadway. Writable by starlet only.
|
||||
static constexpr Common::Flags<GPIO> gpio_owner = {GPIO::SLOT_LED, GPIO::SLOT_IN, GPIO::SENSOR_BAR,
|
||||
GPIO::DO_EJECT, GPIO::AVE_SCL, GPIO::AVE_SDA};
|
||||
static Common::Flags<GPIO> gpio_dir;
|
||||
Common::Flags<GPIO> g_gpio_out;
|
||||
|
||||
static CoreTiming::EventType* updateInterrupts;
|
||||
static void UpdateInterrupts(u64 = 0, s64 cyclesLate = 0);
|
||||
@ -111,7 +116,7 @@ void DoState(PointerWrap& p)
|
||||
p.Do(ppc_irq_masks);
|
||||
p.Do(arm_irq_flags);
|
||||
p.Do(arm_irq_masks);
|
||||
p.Do(sensorbar_power);
|
||||
p.Do(g_gpio_out);
|
||||
}
|
||||
|
||||
static void InitState()
|
||||
@ -125,7 +130,9 @@ static void InitState()
|
||||
arm_irq_flags = 0;
|
||||
arm_irq_masks = 0;
|
||||
|
||||
sensorbar_power = 0;
|
||||
// The only input broadway has is SLOT_IN; all the others it has access to are outputs
|
||||
gpio_dir = {GPIO::SLOT_LED, GPIO::SENSOR_BAR, GPIO::DO_EJECT, GPIO::AVE_SCL, GPIO::AVE_SDA};
|
||||
g_gpio_out = {};
|
||||
|
||||
ppc_irq_masks |= INT_CAUSE_IPC_BROADWAY;
|
||||
}
|
||||
@ -181,14 +188,29 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||
CoreTiming::ScheduleEvent(0, updateInterrupts, 0);
|
||||
}));
|
||||
|
||||
mmio->Register(base | GPIOB_OUT, MMIO::Constant<u32>(0),
|
||||
MMIO::DirectWrite<u32>(&sensorbar_power));
|
||||
mmio->Register(base | GPIOB_OUT, MMIO::DirectRead<u32>(&g_gpio_out.m_hex),
|
||||
MMIO::ComplexWrite<u32>([](u32, u32 val) {
|
||||
g_gpio_out.m_hex = val & gpio_owner.m_hex;
|
||||
if (g_gpio_out[GPIO::DO_EJECT])
|
||||
{
|
||||
INFO_LOG(WII_IPC, "Ejecting disc due to GPIO write");
|
||||
DVDInterface::EjectDisc();
|
||||
}
|
||||
// SENSOR_BAR is checked by WiimoteEmu::CameraLogic
|
||||
// TODO: AVE, SLOT_LED
|
||||
}));
|
||||
mmio->Register(base | GPIOB_DIR, MMIO::DirectRead<u32>(&gpio_dir.m_hex),
|
||||
MMIO::DirectWrite<u32>(&gpio_dir.m_hex));
|
||||
mmio->Register(base | GPIOB_IN, MMIO::ComplexRead<u32>([](u32) {
|
||||
Common::Flags<GPIO> gpio_in;
|
||||
gpio_in[GPIO::SLOT_IN] = DVDInterface::IsDiscInside();
|
||||
return gpio_in.m_hex;
|
||||
}),
|
||||
MMIO::Nop<u32>());
|
||||
|
||||
// Register some stubbed/unknown MMIOs required to make Wii games work.
|
||||
mmio->Register(base | PPCSPEED, MMIO::InvalidRead<u32>(), MMIO::Nop<u32>());
|
||||
mmio->Register(base | VISOLID, MMIO::InvalidRead<u32>(), MMIO::Nop<u32>());
|
||||
mmio->Register(base | GPIOB_DIR, MMIO::Constant<u32>(0), MMIO::Nop<u32>());
|
||||
mmio->Register(base | GPIOB_IN, MMIO::Constant<u32>(0), MMIO::Nop<u32>());
|
||||
mmio->Register(base | UNK_180, MMIO::Constant<u32>(0), MMIO::Nop<u32>());
|
||||
mmio->Register(base | UNK_1CC, MMIO::Constant<u32>(0), MMIO::Nop<u32>());
|
||||
mmio->Register(base | UNK_1D0, MMIO::Constant<u32>(0), MMIO::Nop<u32>());
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/BitUtils.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
class PointerWrap;
|
||||
@ -35,6 +36,36 @@ enum StarletInterruptCause
|
||||
INT_CAUSE_IPC_STARLET = 0x80000000
|
||||
};
|
||||
|
||||
enum class GPIO : u32
|
||||
{
|
||||
POWER = 0x1,
|
||||
SHUTDOWN = 0x2,
|
||||
FAN = 0x4,
|
||||
DC_DC = 0x8,
|
||||
DI_SPIN = 0x10,
|
||||
SLOT_LED = 0x20,
|
||||
EJECT_BTN = 0x40,
|
||||
SLOT_IN = 0x80,
|
||||
SENSOR_BAR = 0x100,
|
||||
DO_EJECT = 0x200,
|
||||
EEP_CS = 0x400,
|
||||
EEP_CLK = 0x800,
|
||||
EEP_MOSI = 0x1000,
|
||||
EEP_MISO = 0x2000,
|
||||
AVE_SCL = 0x4000,
|
||||
AVE_SDA = 0x8000,
|
||||
DEBUG0 = 0x10000,
|
||||
DEBUG1 = 0x20000,
|
||||
DEBUG2 = 0x40000,
|
||||
DEBUG3 = 0x80000,
|
||||
DEBUG4 = 0x100000,
|
||||
DEBUG5 = 0x200000,
|
||||
DEBUG6 = 0x400000,
|
||||
DEBUG7 = 0x800000,
|
||||
};
|
||||
|
||||
extern Common::Flags<GPIO> g_gpio_out;
|
||||
|
||||
void Init();
|
||||
void Reset();
|
||||
void Shutdown();
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/Matrix.h"
|
||||
|
||||
#include "Core/HW/WII_IPC.h"
|
||||
#include "Core/HW/WiimoteCommon/WiimoteReport.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
@ -103,6 +104,8 @@ void CameraLogic::Update(const Common::Matrix44& transform)
|
||||
|
||||
std::array<CameraPoint, leds.size()> camera_points;
|
||||
|
||||
if (IOS::g_gpio_out[IOS::GPIO::SENSOR_BAR])
|
||||
{
|
||||
std::transform(leds.begin(), leds.end(), camera_points.begin(), [&](const Vec3& v) {
|
||||
const auto point = camera_view * Vec4(v, 1.0);
|
||||
|
||||
@ -120,6 +123,12 @@ void CameraLogic::Update(const Common::Matrix44& transform)
|
||||
|
||||
return INVISIBLE_POINT;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sensor bar is off
|
||||
camera_points.fill(INVISIBLE_POINT);
|
||||
}
|
||||
|
||||
// IR data is read from offset 0x37 on real hardware
|
||||
auto& data = reg_data.camera_data;
|
||||
|
Loading…
x
Reference in New Issue
Block a user