diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index 9e84ca5645..7c37adeb67 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -321,15 +321,11 @@ void InitMMIO(MMIO::Mapping* mmio) void InitMMIOWii(MMIO::Mapping* mmio) { - VideoInterface::RegisterMMIO(mmio, 0xCC002000); - ProcessorInterface::RegisterMMIO(mmio, 0xCC003000); - MemoryInterface::RegisterMMIO(mmio, 0xCC004000); - DSP::RegisterMMIO(mmio, 0xCC005000); - DVDInterface::RegisterMMIO(mmio, 0xCC006000); + InitMMIO(mmio); + + WII_IPCInterface::RegisterMMIO(mmio, 0xCD000000); DVDInterface::RegisterMMIO(mmio, 0xCD006000); - SerialInterface::RegisterMMIO(mmio, 0xCC006400); SerialInterface::RegisterMMIO(mmio, 0xCD006400); - AudioInterface::RegisterMMIO(mmio, 0xCC006C00); AudioInterface::RegisterMMIO(mmio, 0xCD006C00); } diff --git a/Source/Core/Core/HW/WII_IPC.cpp b/Source/Core/Core/HW/WII_IPC.cpp index 912bb8a61d..3ffdd39226 100644 --- a/Source/Core/Core/HW/WII_IPC.cpp +++ b/Source/Core/Core/HW/WII_IPC.cpp @@ -12,6 +12,7 @@ #include "CPU.h" #include "Memmap.h" #include "ProcessorInterface.h" +#include "MMIO.h" #include "../IPC_HLE/WII_IPC_HLE.h" #include "WII_IPC.h" @@ -37,12 +38,21 @@ enum IPC_ARMMSG = 0x08, IPC_ARMCTRL = 0x0c, + PPCSPEED = 0x18, + VISOLID = 0x24, + PPC_IRQFLAG = 0x30, PPC_IRQMASK = 0x34, ARM_IRQFLAG = 0x38, ARM_IRQMASK = 0x3c, - GPIOB_OUT = 0xc0 // sensor bar power flag?? + GPIOB_OUT = 0xc0, + GPIOB_DIR = 0xc4, + GPIOB_IN = 0xc8, + + UNK_180 = 0x180, + UNK_1CC = 0x1cc, + UNK_1D0 = 0x1d0, }; struct CtrlRegister @@ -135,86 +145,76 @@ void Shutdown() { } +void RegisterMMIO(MMIO::Mapping* mmio, u32 base) +{ + mmio->Register(base | IPC_PPCMSG, + MMIO::InvalidRead(), + MMIO::DirectWrite(&ppc_msg) + ); + + mmio->Register(base | IPC_PPCCTRL, + MMIO::ComplexRead([](u32) { + return ctrl.ppc(); + }), + MMIO::ComplexWrite([](u32, u32 val) { + ctrl.ppc(val); + if (ctrl.X1) + WII_IPC_HLE_Interface::EnqRequest(ppc_msg); + WII_IPC_HLE_Interface::Update(); + CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + }) + ); + + mmio->Register(base | IPC_ARMMSG, + MMIO::DirectRead(&arm_msg), + MMIO::InvalidWrite() + ); + + mmio->Register(base | PPC_IRQFLAG, + MMIO::InvalidRead(), + MMIO::ComplexWrite([](u32, u32 val) { + ppc_irq_flags &= ~val; + WII_IPC_HLE_Interface::Update(); + CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + }) + ); + + mmio->Register(base | PPC_IRQMASK, + MMIO::InvalidRead(), + MMIO::ComplexWrite([](u32, u32 val) { + ppc_irq_masks = val; + if (ppc_irq_masks & INT_CAUSE_IPC_BROADWAY) // wtf? + Reset(); + WII_IPC_HLE_Interface::Update(); + CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + }) + ); + + mmio->Register(base | GPIOB_OUT, + MMIO::Constant(0), + MMIO::DirectWrite(&sensorbar_power) + ); + + // Register some stubbed/unknown MMIOs required to make Wii games work. + mmio->Register(base | PPCSPEED, MMIO::InvalidRead(), MMIO::Nop()); + mmio->Register(base | VISOLID, MMIO::InvalidRead(), MMIO::Nop()); + mmio->Register(base | GPIOB_DIR, MMIO::Constant(0), MMIO::Nop()); + mmio->Register(base | GPIOB_IN, MMIO::Constant(0), MMIO::Nop()); + mmio->Register(base | UNK_180, MMIO::Constant(0), MMIO::Nop()); + mmio->Register(base | UNK_1CC, MMIO::Constant(0), MMIO::Nop()); + mmio->Register(base | UNK_1D0, MMIO::Constant(0), MMIO::Nop()); +} + void Read32(u32& _rReturnValue, const u32 _Address) { - switch(_Address & 0xFFFF) - { - case IPC_PPCCTRL: - _rReturnValue = ctrl.ppc(); - DEBUG_LOG(WII_IPC, "r32 IPC_PPCCTRL %03x [R:%i A:%i E:%i]", - ctrl.ppc(), ctrl.Y1, ctrl.Y2, ctrl.X1); - - // if ((REASON_REG & 0x14) == 0x14) CALL IPCReplayHandler - // if ((REASON_REG & 0x22) != 0x22) Jumps to the end - break; - - case IPC_ARMMSG: // looks a little bit like a callback function - _rReturnValue = arm_msg; - DEBUG_LOG(WII_IPC, "r32 IPC_ARMMSG %08x ", _rReturnValue); - break; - - case GPIOB_OUT: - _rReturnValue = sensorbar_power; - break; - - default: - _dbg_assert_msg_(WII_IPC, 0, "r32 from %08x", _Address); - break; - } + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Read(_Address, _rReturnValue); } void Write32(const u32 _Value, const u32 _Address) { - switch(_Address & 0xFFFF) - { - case IPC_PPCMSG: // __ios_Ipc2 ... a value from __responses is loaded - { - ppc_msg = _Value; - DEBUG_LOG(WII_IPC, "IPC_PPCMSG = %08x", ppc_msg); - } - break; - - case IPC_PPCCTRL: - { - ctrl.ppc(_Value); - DEBUG_LOG(WII_IPC, "w32 %08x IPC_PPCCTRL = %03x [R:%i A:%i E:%i]", - _Value, ctrl.ppc(), ctrl.Y1, ctrl.Y2, ctrl.X1); - if (ctrl.X1) - { - INFO_LOG(WII_IPC, "New pointer available: %08x", ppc_msg); - // Let the HLE handle the request on it's own time - WII_IPC_HLE_Interface::EnqRequest(ppc_msg); - } - } - break; - - case PPC_IRQFLAG: // ACR REGISTER IT IS CALLED IN DEBUG - { - ppc_irq_flags &= ~_Value; - DEBUG_LOG(WII_IPC, "w32 PPC_IRQFLAG %08x (%08x)", _Value, ppc_irq_flags); - } - break; - - case PPC_IRQMASK: // __OSInterruptInit (0x40000000) - { - ppc_irq_masks = _Value; - if (ppc_irq_masks & INT_CAUSE_IPC_BROADWAY) // wtf? - Reset(); - DEBUG_LOG(WII_IPC, "w32 PPC_IRQMASK %08x", ppc_irq_masks); - } - break; - - case GPIOB_OUT: - sensorbar_power = _Value; - break; - - default: - _dbg_assert_msg_(WII_IPC, 0, "w32 %08x @ %08x", _Value, _Address); - break; - } - - WII_IPC_HLE_Interface::Update(); - CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Write(_Address, _Value); } void UpdateInterrupts(u64 userdata, int cyclesLate) diff --git a/Source/Core/Core/HW/WII_IPC.h b/Source/Core/Core/HW/WII_IPC.h index 1f598418b7..e407ff4918 100644 --- a/Source/Core/Core/HW/WII_IPC.h +++ b/Source/Core/Core/HW/WII_IPC.h @@ -6,6 +6,7 @@ #include "Common.h" class PointerWrap; +namespace MMIO { class Mapping; } namespace WII_IPCInterface { @@ -36,6 +37,8 @@ void Reset(); void Shutdown(); void DoState(PointerWrap &p); +void RegisterMMIO(MMIO::Mapping* mmio, u32 base); + void Read32(u32& _rReturnValue, const u32 _Address); void Write32(const u32 _Value, const u32 _Address);