summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2014-01-25 20:08:58 +0100
committerPierre Bourdon <delroth@gmail.com>2014-02-16 19:22:40 +0100
commit191b447092467393d0125ed4ff6ecf4923be6bed (patch)
treefe0d7fb4d001643732ebe7fc9030b14e9f395225 /Source/Core
parentf34651f48daafdd7f4524442a95da810dc595f7f (diff)
MMIO: Port the SI MMIOs to the new interface.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/HW/Memmap.cpp3
-rw-r--r--Source/Core/Core/HW/SI.cpp231
-rw-r--r--Source/Core/Core/HW/SI.h3
3 files changed, 74 insertions, 163 deletions
diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp
index c534cfe095..f510ecb9ca 100644
--- a/Source/Core/Core/HW/Memmap.cpp
+++ b/Source/Core/Core/HW/Memmap.cpp
@@ -315,6 +315,7 @@ void InitMMIO(MMIO::Mapping* mmio)
MemoryInterface::RegisterMMIO(mmio, 0xCC004000);
DSP::RegisterMMIO(mmio, 0xCC005000);
DVDInterface::RegisterMMIO(mmio, 0xCC006000);
+ SerialInterface::RegisterMMIO(mmio, 0xCC006400);
}
void InitMMIOWii(MMIO::Mapping* mmio)
@@ -325,6 +326,8 @@ void InitMMIOWii(MMIO::Mapping* mmio)
DSP::RegisterMMIO(mmio, 0xCC005000);
DVDInterface::RegisterMMIO(mmio, 0xCC006000);
DVDInterface::RegisterMMIO(mmio, 0xCD006000);
+ SerialInterface::RegisterMMIO(mmio, 0xCC006400);
+ SerialInterface::RegisterMMIO(mmio, 0xCD006400);
}
writeFn32 GetHWWriteFun32(const u32 _Address)
diff --git a/Source/Core/Core/HW/SI.cpp b/Source/Core/Core/HW/SI.cpp
index 8e087df6a6..3182a829bc 100644
--- a/Source/Core/Core/HW/SI.cpp
+++ b/Source/Core/Core/HW/SI.cpp
@@ -8,6 +8,7 @@
#include "../CoreTiming.h"
#include "../Movie.h"
#include "../NetPlayProto.h"
+#include "MMIO.h"
#include "SystemTimers.h"
#include "ProcessorInterface.h"
@@ -281,157 +282,56 @@ void Shutdown()
GBAConnectionWaiter_Shutdown();
}
-void Read32(u32& _uReturnValue, const u32 _iAddress)
+void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{
- // SIBuffer
- if ((_iAddress >= 0xCC006480 && _iAddress < 0xCC006500) ||
- (_iAddress >= 0xCD006480 && _iAddress < 0xCD006500))
- {
- _uReturnValue = *(u32*)&g_SIBuffer[_iAddress & 0x7F];
- return;
- }
-
- // error if not changed in the switch
- _uReturnValue = 0xdeadbeef;
-
- // registers
- switch (_iAddress & 0x3FF)
+ // Register SI buffer direct accesses.
+ for (int i = 0; i < 0x80; i += 4)
+ mmio->Register(base | (0x80 + i),
+ MMIO::DirectRead<u32>((u32*)&g_SIBuffer[i]),
+ MMIO::DirectWrite<u32>((u32*)&g_SIBuffer[i])
+ );
+
+ // In and out for the 4 SI channels.
+ for (int i = 0; i < MAX_SI_CHANNELS; ++i)
{
- //////////////////////////////////////////////////////////////////////////
- // Channel 0
- //////////////////////////////////////////////////////////////////////////
- case SI_CHANNEL_0_OUT:
- _uReturnValue = g_Channel[0].m_Out.Hex;
- break;
-
- case SI_CHANNEL_0_IN_HI:
- g_StatusReg.RDST0 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[0].m_InHi.Hex;
- break;
-
- case SI_CHANNEL_0_IN_LO:
- g_StatusReg.RDST0 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[0].m_InLo.Hex;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- // Channel 1
- //////////////////////////////////////////////////////////////////////////
- case SI_CHANNEL_1_OUT:
- _uReturnValue = g_Channel[1].m_Out.Hex;
- break;
-
- case SI_CHANNEL_1_IN_HI:
- g_StatusReg.RDST1 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[1].m_InHi.Hex;
- break;
-
- case SI_CHANNEL_1_IN_LO:
- g_StatusReg.RDST1 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[1].m_InLo.Hex;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- // Channel 2
- //////////////////////////////////////////////////////////////////////////
- case SI_CHANNEL_2_OUT:
- _uReturnValue = g_Channel[2].m_Out.Hex;
- break;
-
- case SI_CHANNEL_2_IN_HI:
- g_StatusReg.RDST2 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[2].m_InHi.Hex;
- break;
-
- case SI_CHANNEL_2_IN_LO:
- g_StatusReg.RDST2 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[2].m_InLo.Hex;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- // Channel 3
- //////////////////////////////////////////////////////////////////////////
- case SI_CHANNEL_3_OUT:
- _uReturnValue = g_Channel[3].m_Out.Hex;
- break;
-
- case SI_CHANNEL_3_IN_HI:
- g_StatusReg.RDST3 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[3].m_InHi.Hex;
- break;
-
- case SI_CHANNEL_3_IN_LO:
- g_StatusReg.RDST3 = 0;
- UpdateInterrupts();
- _uReturnValue = g_Channel[3].m_InLo.Hex;
- break;
-
- //////////////////////////////////////////////////////////////////////////
- // Other
- //////////////////////////////////////////////////////////////////////////
- case SI_POLL: _uReturnValue = g_Poll.Hex; break;
- case SI_COM_CSR: _uReturnValue = g_ComCSR.Hex; break;
- case SI_STATUS_REG: _uReturnValue = g_StatusReg.Hex; break;
-
- case SI_EXI_CLOCK_COUNT: _uReturnValue = g_EXIClockCount.Hex; break;
-
- default:
- INFO_LOG(SERIALINTERFACE, "(r32-unk): 0x%08x", _iAddress);
- _dbg_assert_(SERIALINTERFACE,0);
- break;
+ // We need to clear the RDST bit for the SI channel when reading.
+ // CH0 -> Bit 24 + 5
+ // CH1 -> Bit 16 + 5
+ // CH2 -> Bit 8 + 5
+ // CH3 -> Bit 0 + 5
+ int rdst_bit = 8 * (3 - i) + 5;
+
+ mmio->Register(base | (SI_CHANNEL_0_OUT + 0xC * i),
+ MMIO::DirectRead<u32>(&g_Channel[i].m_Out.Hex),
+ MMIO::DirectWrite<u32>(&g_Channel[i].m_Out.Hex)
+ );
+ mmio->Register(base | (SI_CHANNEL_0_IN_HI + 0xC * i),
+ MMIO::ComplexRead<u32>([i, rdst_bit](u32) {
+ g_StatusReg.Hex &= ~(1 << rdst_bit);
+ UpdateInterrupts();
+ return g_Channel[i].m_InHi.Hex;
+ }),
+ MMIO::DirectWrite<u32>(&g_Channel[i].m_InHi.Hex)
+ );
+ mmio->Register(base | (SI_CHANNEL_0_IN_LO + 0xC * i),
+ MMIO::ComplexRead<u32>([i, rdst_bit](u32) {
+ g_StatusReg.Hex &= ~(1 << rdst_bit);
+ UpdateInterrupts();
+ return g_Channel[i].m_InLo.Hex;
+ }),
+ MMIO::DirectWrite<u32>(&g_Channel[i].m_InLo.Hex)
+ );
}
- DEBUG_LOG(SERIALINTERFACE, "(r32) 0x%08x - 0x%08x", _iAddress, _uReturnValue);
-}
-
-void Write32(const u32 _iValue, const u32 _iAddress)
-{
- DEBUG_LOG(SERIALINTERFACE, "(w32) 0x%08x @ 0x%08x", _iValue, _iAddress);
-
- // SIBuffer
- if ((_iAddress >= 0xCC006480 && _iAddress < 0xCC006500) ||
- (_iAddress >= 0xCD006480 && _iAddress < 0xCD006500))
- {
- *(u32*)&g_SIBuffer[_iAddress & 0x7F] = _iValue;
- return;
- }
+ mmio->Register(base | SI_POLL,
+ MMIO::DirectRead<u32>(&g_Poll.Hex),
+ MMIO::DirectWrite<u32>(&g_Poll.Hex)
+ );
- // registers
- switch (_iAddress & 0x3FF)
- {
- case SI_CHANNEL_0_OUT: g_Channel[0].m_Out.Hex = _iValue; break;
- case SI_CHANNEL_0_IN_HI: g_Channel[0].m_InHi.Hex = _iValue; break;
- case SI_CHANNEL_0_IN_LO: g_Channel[0].m_InLo.Hex = _iValue; break;
- case SI_CHANNEL_1_OUT: g_Channel[1].m_Out.Hex = _iValue; break;
- case SI_CHANNEL_1_IN_HI: g_Channel[1].m_InHi.Hex = _iValue; break;
- case SI_CHANNEL_1_IN_LO: g_Channel[1].m_InLo.Hex = _iValue; break;
- case SI_CHANNEL_2_OUT: g_Channel[2].m_Out.Hex = _iValue; break;
- case SI_CHANNEL_2_IN_HI: g_Channel[2].m_InHi.Hex = _iValue; break;
- case SI_CHANNEL_2_IN_LO: g_Channel[2].m_InLo.Hex = _iValue; break;
- case SI_CHANNEL_3_OUT: g_Channel[3].m_Out.Hex = _iValue; break;
- case SI_CHANNEL_3_IN_HI: g_Channel[3].m_InHi.Hex = _iValue; break;
- case SI_CHANNEL_3_IN_LO: g_Channel[3].m_InLo.Hex = _iValue; break;
-
- case SI_POLL:
- INFO_LOG(SERIALINTERFACE, "Wrote Poll: X=%03d Y=%03d %s%s%s%s%s%s%s%s",
- g_Poll.X, g_Poll.Y,
- g_Poll.EN0 ? "EN0 ":" ", g_Poll.EN1 ? "EN1 ":" ",
- g_Poll.EN2 ? "EN2 ":" ", g_Poll.EN3 ? "EN3 ":" ",
- g_Poll.VBCPY0 ? "VBCPY0 ":" ", g_Poll.VBCPY1 ? "VBCPY1 ":" ",
- g_Poll.VBCPY2 ? "VBCPY2 ":" ", g_Poll.VBCPY3 ? "VBCPY3 ":" ");
- g_Poll.Hex = _iValue;
- break;
-
- case SI_COM_CSR:
- {
- USIComCSR tmpComCSR(_iValue);
+ mmio->Register(base | SI_COM_CSR,
+ MMIO::DirectRead<u32>(&g_ComCSR.Hex),
+ MMIO::ComplexWrite<u32>([](u32, u32 val) {
+ USIComCSR tmpComCSR(val);
g_ComCSR.CHANNEL = tmpComCSR.CHANNEL;
g_ComCSR.INLNGTH = tmpComCSR.INLNGTH;
@@ -447,12 +347,13 @@ void Write32(const u32 _iValue, const u32 _iAddress)
// be careful: run si-buffer after updating the INT flags
if (tmpComCSR.TSTART) RunSIBuffer();
UpdateInterrupts();
- }
- break;
+ })
+ );
- case SI_STATUS_REG:
- {
- USIStatusReg tmpStatus(_iValue);
+ mmio->Register(base | SI_STATUS_REG,
+ MMIO::DirectRead<u32>(&g_StatusReg.Hex),
+ MMIO::ComplexWrite<u32>([](u32, u32 val) {
+ USIStatusReg tmpStatus(val);
// clear bits ( if(tmp.bit) SISR.bit=0 )
if (tmpStatus.NOREP0) g_StatusReg.NOREP0 = 0;
@@ -489,21 +390,25 @@ void Write32(const u32 _iValue, const u32 _iAddress)
g_StatusReg.WRST2 = 0;
g_StatusReg.WRST3 = 0;
}
- }
- break;
+ })
+ );
- case SI_EXI_CLOCK_COUNT:
- g_EXIClockCount.Hex = _iValue;
- break;
+ mmio->Register(base | SI_EXI_CLOCK_COUNT,
+ MMIO::DirectRead<u32>(&g_EXIClockCount.Hex),
+ MMIO::DirectWrite<u32>(&g_EXIClockCount.Hex)
+ );
+}
- case 0x80: // Bogus? never seen it with ma own eyes
- INFO_LOG(SERIALINTERFACE, "WII something at 0xCD006480");
- break;
+void Read32(u32& _uReturnValue, const u32 _iAddress)
+{
+ // HACK: Remove this function when the new MMIO interface is used.
+ Memory::mmio_mapping->Read(_iAddress, _uReturnValue);
+}
- default:
- _dbg_assert_(SERIALINTERFACE, 0);
- break;
- }
+void Write32(const u32 _iValue, const u32 _iAddress)
+{
+ // HACK: Remove this function when the new MMIO interface is used.
+ Memory::mmio_mapping->Write(_iAddress, _iValue);
}
void UpdateInterrupts()
diff --git a/Source/Core/Core/HW/SI.h b/Source/Core/Core/HW/SI.h
index c2225a231e..d0d3ee98cf 100644
--- a/Source/Core/Core/HW/SI.h
+++ b/Source/Core/Core/HW/SI.h
@@ -8,6 +8,7 @@
#include "SI_Device.h"
class PointerWrap;
class ISIDevice;
+namespace MMIO { class Mapping; }
// SI number of channels
enum
@@ -22,6 +23,8 @@ void Init();
void Shutdown();
void DoState(PointerWrap &p);
+void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
+
void UpdateDevices();
void RemoveDevice(int _iDeviceNumber);