MMIO: Port the EXI MMIOs to the new interface.
This commit is contained in:
parent
353c145e64
commit
bdedaa24a9
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "ProcessorInterface.h"
|
#include "ProcessorInterface.h"
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
|
#include "MMIO.h"
|
||||||
|
|
||||||
#include "EXI.h"
|
#include "EXI.h"
|
||||||
#include "Sram.h"
|
#include "Sram.h"
|
||||||
|
@ -62,6 +63,19 @@ void PauseAndLock(bool doLock, bool unpauseOnUnlock)
|
||||||
channel->PauseAndLock(doLock, unpauseOnUnlock);
|
channel->PauseAndLock(doLock, unpauseOnUnlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_EXI_CHANNELS; ++i)
|
||||||
|
{
|
||||||
|
_dbg_assert_(EXPANSIONINTERFACE, g_Channels[i] != nullptr);
|
||||||
|
// Each channel has 5 32 bit registers assigned to it. We offset the
|
||||||
|
// base that we give to each channel for registration.
|
||||||
|
//
|
||||||
|
// Be careful: this means the base is no longer aligned on a page
|
||||||
|
// boundary and using "base | FOO" is not valid!
|
||||||
|
g_Channels[i]->RegisterMMIO(mmio, base + 5 * 4 * i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChangeDeviceCallback(u64 userdata, int cyclesLate)
|
void ChangeDeviceCallback(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
|
@ -101,34 +115,14 @@ void Update()
|
||||||
|
|
||||||
void Read32(u32& _uReturnValue, const u32 _iAddress)
|
void Read32(u32& _uReturnValue, const u32 _iAddress)
|
||||||
{
|
{
|
||||||
// TODO 0xfff00000 is mapped to EXI -> mapped to first MB of maskrom
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
u32 iAddr = _iAddress & 0x3FF;
|
Memory::mmio_mapping->Read(_iAddress, _uReturnValue);
|
||||||
u32 iRegister = (iAddr >> 2) % 5;
|
|
||||||
u32 iChannel = (iAddr >> 2) / 5;
|
|
||||||
|
|
||||||
_dbg_assert_(EXPANSIONINTERFACE, iChannel < MAX_EXI_CHANNELS);
|
|
||||||
|
|
||||||
if (iChannel < MAX_EXI_CHANNELS)
|
|
||||||
{
|
|
||||||
g_Channels[iChannel]->Read32(_uReturnValue, iRegister);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_uReturnValue = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write32(const u32 _iValue, const u32 _iAddress)
|
void Write32(const u32 _iValue, const u32 _iAddress)
|
||||||
{
|
{
|
||||||
// TODO 0xfff00000 is mapped to EXI -> mapped to first MB of maskrom
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
u32 iAddr = _iAddress & 0x3FF;
|
Memory::mmio_mapping->Write(_iAddress, _iValue);
|
||||||
u32 iRegister = (iAddr >> 2) % 5;
|
|
||||||
u32 iChannel = (iAddr >> 2) / 5;
|
|
||||||
|
|
||||||
_dbg_assert_(EXPANSIONINTERFACE, iChannel < MAX_EXI_CHANNELS);
|
|
||||||
|
|
||||||
if (iChannel < MAX_EXI_CHANNELS)
|
|
||||||
g_Channels[iChannel]->Write32(_iValue, iRegister);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateInterrupts()
|
void UpdateInterrupts()
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "EXI_Channel.h"
|
#include "EXI_Channel.h"
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
namespace MMIO { class Mapping; }
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,8 @@ void Shutdown();
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
void PauseAndLock(bool doLock, bool unpauseOnUnlock);
|
void PauseAndLock(bool doLock, bool unpauseOnUnlock);
|
||||||
|
|
||||||
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "EXI.h"
|
#include "EXI.h"
|
||||||
#include "../ConfigManager.h"
|
#include "../ConfigManager.h"
|
||||||
#include "../Movie.h"
|
#include "../Movie.h"
|
||||||
|
#include "MMIO.h"
|
||||||
|
|
||||||
#define EXI_READ 0
|
#define EXI_READ 0
|
||||||
#define EXI_WRITE 1
|
#define EXI_WRITE 1
|
||||||
|
@ -41,6 +42,117 @@ CEXIChannel::~CEXIChannel()
|
||||||
RemoveDevices();
|
RemoveDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEXIChannel::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
|
{
|
||||||
|
// Warning: the base is not aligned on a page boundary here. We can't use |
|
||||||
|
// to select a register address, instead we need to use +.
|
||||||
|
|
||||||
|
mmio->Register(base + EXI_STATUS,
|
||||||
|
MMIO::ComplexRead<u32>([this](u32) {
|
||||||
|
// check if external device is present
|
||||||
|
// pretty sure it is memcard only, not entirely sure
|
||||||
|
if (m_ChannelId == 2)
|
||||||
|
{
|
||||||
|
m_Status.EXT = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Status.EXT = GetDevice(1)->IsPresent() ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_Status.Hex;
|
||||||
|
}),
|
||||||
|
MMIO::ComplexWrite<u32>([this](u32, u32 val) {
|
||||||
|
UEXI_STATUS newStatus(val);
|
||||||
|
|
||||||
|
m_Status.EXIINTMASK = newStatus.EXIINTMASK;
|
||||||
|
if (newStatus.EXIINT)
|
||||||
|
m_Status.EXIINT = 0;
|
||||||
|
|
||||||
|
m_Status.TCINTMASK = newStatus.TCINTMASK;
|
||||||
|
if (newStatus.TCINT)
|
||||||
|
m_Status.TCINT = 0;
|
||||||
|
|
||||||
|
m_Status.CLK = newStatus.CLK;
|
||||||
|
|
||||||
|
if (m_ChannelId == 0 || m_ChannelId == 1)
|
||||||
|
{
|
||||||
|
m_Status.EXTINTMASK = newStatus.EXTINTMASK;
|
||||||
|
|
||||||
|
if (newStatus.EXTINT)
|
||||||
|
m_Status.EXTINT = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_ChannelId == 0)
|
||||||
|
m_Status.ROMDIS = newStatus.ROMDIS;
|
||||||
|
|
||||||
|
IEXIDevice* pDevice = GetDevice(m_Status.CHIP_SELECT ^ newStatus.CHIP_SELECT);
|
||||||
|
m_Status.CHIP_SELECT = newStatus.CHIP_SELECT;
|
||||||
|
if (pDevice != NULL)
|
||||||
|
pDevice->SetCS(m_Status.CHIP_SELECT);
|
||||||
|
|
||||||
|
CoreTiming::ScheduleEvent_Threadsafe_Immediate(updateInterrupts, 0);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
mmio->Register(base + EXI_DMAADDR,
|
||||||
|
MMIO::DirectRead<u32>(&m_DMAMemoryAddress),
|
||||||
|
MMIO::DirectWrite<u32>(&m_DMAMemoryAddress)
|
||||||
|
);
|
||||||
|
mmio->Register(base + EXI_DMALENGTH,
|
||||||
|
MMIO::DirectRead<u32>(&m_DMALength),
|
||||||
|
MMIO::DirectWrite<u32>(&m_DMALength)
|
||||||
|
);
|
||||||
|
mmio->Register(base + EXI_DMACONTROL,
|
||||||
|
MMIO::DirectRead<u32>(&m_Control.Hex),
|
||||||
|
MMIO::ComplexWrite<u32>([this](u32, u32 val) {
|
||||||
|
m_Control.Hex = val;
|
||||||
|
|
||||||
|
if (m_Control.TSTART)
|
||||||
|
{
|
||||||
|
IEXIDevice* pDevice = GetDevice(m_Status.CHIP_SELECT);
|
||||||
|
if (pDevice == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_Control.DMA == 0)
|
||||||
|
{
|
||||||
|
// immediate data
|
||||||
|
switch (m_Control.RW)
|
||||||
|
{
|
||||||
|
case EXI_READ: m_ImmData = pDevice->ImmRead(m_Control.TLEN + 1); break;
|
||||||
|
case EXI_WRITE: pDevice->ImmWrite(m_ImmData, m_Control.TLEN + 1); break;
|
||||||
|
case EXI_READWRITE: pDevice->ImmReadWrite(m_ImmData, m_Control.TLEN + 1); break;
|
||||||
|
default: _dbg_assert_msg_(EXPANSIONINTERFACE,0,"EXI Imm: Unknown transfer type %i", m_Control.RW);
|
||||||
|
}
|
||||||
|
m_Control.TSTART = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// DMA
|
||||||
|
switch (m_Control.RW)
|
||||||
|
{
|
||||||
|
case EXI_READ: pDevice->DMARead (m_DMAMemoryAddress, m_DMALength); break;
|
||||||
|
case EXI_WRITE: pDevice->DMAWrite(m_DMAMemoryAddress, m_DMALength); break;
|
||||||
|
default: _dbg_assert_msg_(EXPANSIONINTERFACE,0,"EXI DMA: Unknown transfer type %i", m_Control.RW);
|
||||||
|
}
|
||||||
|
m_Control.TSTART = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_Control.TSTART) // completed !
|
||||||
|
{
|
||||||
|
m_Status.TCINT = 1;
|
||||||
|
CoreTiming::ScheduleEvent_Threadsafe_Immediate(updateInterrupts, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
mmio->Register(base + EXI_IMMDATA,
|
||||||
|
MMIO::DirectRead<u32>(&m_ImmData),
|
||||||
|
MMIO::DirectWrite<u32>(&m_ImmData)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void CEXIChannel::RemoveDevices()
|
void CEXIChannel::RemoveDevices()
|
||||||
{
|
{
|
||||||
for (auto& device : m_pDevices)
|
for (auto& device : m_pDevices)
|
||||||
|
@ -115,152 +227,6 @@ void CEXIChannel::Update()
|
||||||
device->Update();
|
device->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEXIChannel::Read32(u32& _uReturnValue, const u32 _iRegister)
|
|
||||||
{
|
|
||||||
switch (_iRegister)
|
|
||||||
{
|
|
||||||
case EXI_STATUS:
|
|
||||||
{
|
|
||||||
// check if external device is present
|
|
||||||
// pretty sure it is memcard only, not entirely sure
|
|
||||||
if (m_ChannelId == 2)
|
|
||||||
{
|
|
||||||
m_Status.EXT = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Status.EXT = GetDevice(1)->IsPresent() ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_uReturnValue = m_Status.Hex;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EXI_DMAADDR:
|
|
||||||
_uReturnValue = m_DMAMemoryAddress;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXI_DMALENGTH:
|
|
||||||
_uReturnValue = m_DMALength;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXI_DMACONTROL:
|
|
||||||
_uReturnValue = m_Control.Hex;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXI_IMMDATA:
|
|
||||||
_uReturnValue = m_ImmData;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
_dbg_assert_(EXPANSIONINTERFACE, 0);
|
|
||||||
_uReturnValue = 0xDEADBEEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG(EXPANSIONINTERFACE, "(r32) 0x%08x channel: %i register: %s",
|
|
||||||
_uReturnValue, m_ChannelId, Debug_GetRegisterName(_iRegister));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
|
|
||||||
{
|
|
||||||
DEBUG_LOG(EXPANSIONINTERFACE, "(w32) 0x%08x channel: %i register: %s",
|
|
||||||
_iValue, m_ChannelId, Debug_GetRegisterName(_iRegister));
|
|
||||||
|
|
||||||
switch (_iRegister)
|
|
||||||
{
|
|
||||||
case EXI_STATUS:
|
|
||||||
{
|
|
||||||
UEXI_STATUS newStatus(_iValue);
|
|
||||||
|
|
||||||
m_Status.EXIINTMASK = newStatus.EXIINTMASK;
|
|
||||||
if (newStatus.EXIINT)
|
|
||||||
m_Status.EXIINT = 0;
|
|
||||||
|
|
||||||
m_Status.TCINTMASK = newStatus.TCINTMASK;
|
|
||||||
if (newStatus.TCINT)
|
|
||||||
m_Status.TCINT = 0;
|
|
||||||
|
|
||||||
m_Status.CLK = newStatus.CLK;
|
|
||||||
|
|
||||||
if (m_ChannelId == 0 || m_ChannelId == 1)
|
|
||||||
{
|
|
||||||
m_Status.EXTINTMASK = newStatus.EXTINTMASK;
|
|
||||||
|
|
||||||
if (newStatus.EXTINT)
|
|
||||||
m_Status.EXTINT = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_ChannelId == 0)
|
|
||||||
m_Status.ROMDIS = newStatus.ROMDIS;
|
|
||||||
|
|
||||||
IEXIDevice* pDevice = GetDevice(m_Status.CHIP_SELECT ^ newStatus.CHIP_SELECT);
|
|
||||||
m_Status.CHIP_SELECT = newStatus.CHIP_SELECT;
|
|
||||||
if (pDevice != NULL)
|
|
||||||
pDevice->SetCS(m_Status.CHIP_SELECT);
|
|
||||||
|
|
||||||
CoreTiming::ScheduleEvent_Threadsafe_Immediate(updateInterrupts, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXI_DMAADDR:
|
|
||||||
INFO_LOG(EXPANSIONINTERFACE, "Wrote DMAAddr, channel %i", m_ChannelId);
|
|
||||||
m_DMAMemoryAddress = _iValue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXI_DMALENGTH:
|
|
||||||
INFO_LOG(EXPANSIONINTERFACE, "Wrote DMALength, channel %i", m_ChannelId);
|
|
||||||
m_DMALength = _iValue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXI_DMACONTROL:
|
|
||||||
INFO_LOG(EXPANSIONINTERFACE, "Wrote DMAControl, channel %i", m_ChannelId);
|
|
||||||
m_Control.Hex = _iValue;
|
|
||||||
|
|
||||||
if (m_Control.TSTART)
|
|
||||||
{
|
|
||||||
IEXIDevice* pDevice = GetDevice(m_Status.CHIP_SELECT);
|
|
||||||
if (pDevice == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_Control.DMA == 0)
|
|
||||||
{
|
|
||||||
// immediate data
|
|
||||||
switch (m_Control.RW)
|
|
||||||
{
|
|
||||||
case EXI_READ: m_ImmData = pDevice->ImmRead(m_Control.TLEN + 1); break;
|
|
||||||
case EXI_WRITE: pDevice->ImmWrite(m_ImmData, m_Control.TLEN + 1); break;
|
|
||||||
case EXI_READWRITE: pDevice->ImmReadWrite(m_ImmData, m_Control.TLEN + 1); break;
|
|
||||||
default: _dbg_assert_msg_(EXPANSIONINTERFACE,0,"EXI Imm: Unknown transfer type %i", m_Control.RW);
|
|
||||||
}
|
|
||||||
m_Control.TSTART = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// DMA
|
|
||||||
switch (m_Control.RW)
|
|
||||||
{
|
|
||||||
case EXI_READ: pDevice->DMARead (m_DMAMemoryAddress, m_DMALength); break;
|
|
||||||
case EXI_WRITE: pDevice->DMAWrite(m_DMAMemoryAddress, m_DMALength); break;
|
|
||||||
default: _dbg_assert_msg_(EXPANSIONINTERFACE,0,"EXI DMA: Unknown transfer type %i", m_Control.RW);
|
|
||||||
}
|
|
||||||
m_Control.TSTART = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!m_Control.TSTART) // completed !
|
|
||||||
{
|
|
||||||
m_Status.TCINT = 1;
|
|
||||||
CoreTiming::ScheduleEvent_Threadsafe_Immediate(updateInterrupts, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXI_IMMDATA:
|
|
||||||
INFO_LOG(EXPANSIONINTERFACE, "Wrote IMMData, channel %i", m_ChannelId);
|
|
||||||
m_ImmData = _iValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CEXIChannel::DoState(PointerWrap &p)
|
void CEXIChannel::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.DoPOD(m_Status);
|
p.DoPOD(m_Status);
|
||||||
|
|
|
@ -9,30 +9,20 @@
|
||||||
#include "EXI_Device.h"
|
#include "EXI_Device.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
namespace MMIO { class Mapping; }
|
||||||
|
|
||||||
class CEXIChannel
|
class CEXIChannel
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
EXI_STATUS = 0,
|
EXI_STATUS = 0x00,
|
||||||
EXI_DMAADDR = 1,
|
EXI_DMAADDR = 0x04,
|
||||||
EXI_DMALENGTH = 2,
|
EXI_DMALENGTH = 0x08,
|
||||||
EXI_DMACONTROL = 3,
|
EXI_DMACONTROL = 0x0C,
|
||||||
EXI_IMMDATA = 4
|
EXI_IMMDATA = 0x10
|
||||||
};
|
};
|
||||||
const char* Debug_GetRegisterName(u32 _register)
|
|
||||||
{
|
|
||||||
switch (_register)
|
|
||||||
{
|
|
||||||
case EXI_STATUS: return "STATUS";
|
|
||||||
case EXI_DMAADDR: return "DMAADDR";
|
|
||||||
case EXI_DMALENGTH: return "DMALENGTH";
|
|
||||||
case EXI_DMACONTROL: return "DMACONTROL";
|
|
||||||
case EXI_IMMDATA: return "IMMDATA";
|
|
||||||
default: return "!!! Unknown EXI Register !!!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EXI Status Register - "Channel Parameter Register"
|
// EXI Status Register - "Channel Parameter Register"
|
||||||
union UEXI_STATUS
|
union UEXI_STATUS
|
||||||
|
@ -104,15 +94,14 @@ public:
|
||||||
CEXIChannel(u32 ChannelId);
|
CEXIChannel(u32 ChannelId);
|
||||||
~CEXIChannel();
|
~CEXIChannel();
|
||||||
|
|
||||||
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
|
|
||||||
void AddDevice(const TEXIDevices device_type, const int device_num);
|
void AddDevice(const TEXIDevices device_type, const int device_num);
|
||||||
void AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged=true);
|
void AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged=true);
|
||||||
|
|
||||||
// Remove all devices
|
// Remove all devices
|
||||||
void RemoveDevices();
|
void RemoveDevices();
|
||||||
|
|
||||||
void Read32(u32& _uReturnValue, const u32 _iRegister);
|
|
||||||
void Write32(const u32 _iValue, const u32 _iRegister);
|
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
bool IsCausingInterrupt();
|
bool IsCausingInterrupt();
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
|
|
|
@ -38,11 +38,11 @@ namespace HW
|
||||||
VideoInterface::Init();
|
VideoInterface::Init();
|
||||||
SerialInterface::Init();
|
SerialInterface::Init();
|
||||||
ProcessorInterface::Init();
|
ProcessorInterface::Init();
|
||||||
|
ExpansionInterface::Init(); // Needs to be initialized before Memory
|
||||||
Memory::Init();
|
Memory::Init();
|
||||||
DSP::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPHLE);
|
DSP::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPHLE);
|
||||||
DVDInterface::Init();
|
DVDInterface::Init();
|
||||||
GPFifo::Init();
|
GPFifo::Init();
|
||||||
ExpansionInterface::Init();
|
|
||||||
CCPU::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore);
|
CCPU::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore);
|
||||||
SystemTimers::Init();
|
SystemTimers::Init();
|
||||||
|
|
||||||
|
|
|
@ -316,6 +316,7 @@ void InitMMIO(MMIO::Mapping* mmio)
|
||||||
DSP::RegisterMMIO(mmio, 0xCC005000);
|
DSP::RegisterMMIO(mmio, 0xCC005000);
|
||||||
DVDInterface::RegisterMMIO(mmio, 0xCC006000);
|
DVDInterface::RegisterMMIO(mmio, 0xCC006000);
|
||||||
SerialInterface::RegisterMMIO(mmio, 0xCC006400);
|
SerialInterface::RegisterMMIO(mmio, 0xCC006400);
|
||||||
|
ExpansionInterface::RegisterMMIO(mmio, 0xCC006800);
|
||||||
AudioInterface::RegisterMMIO(mmio, 0xCC006C00);
|
AudioInterface::RegisterMMIO(mmio, 0xCC006C00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +327,7 @@ void InitMMIOWii(MMIO::Mapping* mmio)
|
||||||
WII_IPCInterface::RegisterMMIO(mmio, 0xCD000000);
|
WII_IPCInterface::RegisterMMIO(mmio, 0xCD000000);
|
||||||
DVDInterface::RegisterMMIO(mmio, 0xCD006000);
|
DVDInterface::RegisterMMIO(mmio, 0xCD006000);
|
||||||
SerialInterface::RegisterMMIO(mmio, 0xCD006400);
|
SerialInterface::RegisterMMIO(mmio, 0xCD006400);
|
||||||
|
ExpansionInterface::RegisterMMIO(mmio, 0xCD006800);
|
||||||
AudioInterface::RegisterMMIO(mmio, 0xCD006C00);
|
AudioInterface::RegisterMMIO(mmio, 0xCD006C00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue