summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-02-22 07:49:32 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2025-02-22 09:25:57 -0600
commit8431c23cbc347e8c1b669e69c85d157dc6d7a8eb (patch)
tree6e377ee832c8cc627da357b7ee886780c63201af
parentddb0e1e309d176ea1ba9e8dc33cb76e47ff6681e (diff)
SI: Set NOREP, ERRSTAT, and ERRLATCH when GetData returns false.
-rw-r--r--Source/Core/Core/HW/SI/SI.cpp45
-rw-r--r--Source/Core/Core/HW/SI/SI_DeviceGCController.cpp5
-rw-r--r--Source/Core/Core/HW/SI/SI_DeviceNull.cpp3
3 files changed, 30 insertions, 23 deletions
diff --git a/Source/Core/Core/HW/SI/SI.cpp b/Source/Core/Core/HW/SI/SI.cpp
index 423f373337..89b200bad4 100644
--- a/Source/Core/Core/HW/SI/SI.cpp
+++ b/Source/Core/Core/HW/SI/SI.cpp
@@ -59,6 +59,12 @@ SerialInterfaceManager::SerialInterfaceManager(Core::System& system) : m_system(
SerialInterfaceManager::~SerialInterfaceManager() = default;
+static constexpr u32 GetRDSTBit(u32 channel)
+{
+ // Returns bit for RDST0,1,2,3
+ return 0x20000000 >> (channel * 8);
+}
+
void SerialInterfaceManager::SetNoResponse(u32 channel)
{
// raise the NO RESPONSE error
@@ -357,27 +363,23 @@ void SerialInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
for (u32 i = 0; i < u32(MAX_SI_CHANNELS); ++i)
{
// 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
- const u32 rdst_bit = 8 * (3 - i) + 5;
+ const u32 clear_rdst = ~GetRDSTBit(i);
mmio->Register(base | (SI_CHANNEL_0_OUT + 0xC * i),
MMIO::DirectRead<u32>(&m_channel[i].out.hex),
MMIO::DirectWrite<u32>(&m_channel[i].out.hex));
mmio->Register(base | (SI_CHANNEL_0_IN_HI + 0xC * i),
- MMIO::ComplexRead<u32>([i, rdst_bit](Core::System& system, u32) {
+ MMIO::ComplexRead<u32>([i, clear_rdst](Core::System& system, u32) {
auto& si = system.GetSerialInterface();
- si.m_status_reg.hex &= ~(1U << rdst_bit);
+ si.m_status_reg.hex &= clear_rdst;
si.UpdateInterrupts();
return si.m_channel[i].in_hi.hex;
}),
MMIO::DirectWrite<u32>(&m_channel[i].in_hi.hex));
mmio->Register(base | (SI_CHANNEL_0_IN_LO + 0xC * i),
- MMIO::ComplexRead<u32>([i, rdst_bit](Core::System& system, u32) {
+ MMIO::ComplexRead<u32>([i, clear_rdst](Core::System& system, u32) {
auto& si = system.GetSerialInterface();
- si.m_status_reg.hex &= ~(1U << rdst_bit);
+ si.m_status_reg.hex &= clear_rdst;
si.UpdateInterrupts();
return si.m_channel[i].in_lo.hex;
}),
@@ -554,14 +556,23 @@ void SerialInterfaceManager::UpdateDevices()
g_controller_interface.UpdateInput();
// Update channels and set the status bit if there's new data
- m_status_reg.RDST0 =
- !!m_channel[0].device->GetData(m_channel[0].in_hi.hex, m_channel[0].in_lo.hex);
- m_status_reg.RDST1 =
- !!m_channel[1].device->GetData(m_channel[1].in_hi.hex, m_channel[1].in_lo.hex);
- m_status_reg.RDST2 =
- !!m_channel[2].device->GetData(m_channel[2].in_hi.hex, m_channel[2].in_lo.hex);
- m_status_reg.RDST3 =
- !!m_channel[3].device->GetData(m_channel[3].in_hi.hex, m_channel[3].in_lo.hex);
+ for (u32 i = 0; i != MAX_SI_CHANNELS; ++i)
+ {
+ // ERRLATCH bit is maintained.
+ u32 errlatch = m_channel[i].in_hi.ERRLATCH.Value();
+ if (m_channel[i].device->GetData(m_channel[i].in_hi.hex, m_channel[i].in_lo.hex))
+ {
+ m_status_reg.hex |= GetRDSTBit(i);
+ }
+ else
+ {
+ errlatch = 1;
+ m_channel[i].in_hi.ERRSTAT = 1;
+ SetNoResponse(i);
+ }
+
+ m_channel[i].in_hi.ERRLATCH = errlatch;
+ }
UpdateInterrupts();
diff --git a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp
index f8150a6339..f3867cf1fc 100644
--- a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp
+++ b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp
@@ -175,10 +175,7 @@ bool CSIDevice_GCController::GetData(u32& hi, u32& low)
GCPadStatus pad_status = GetPadStatus();
if (!pad_status.isConnected)
- {
- hi = 0x80000000;
- return true;
- }
+ return false;
if (HandleButtonCombos(pad_status) == COMBO_ORIGIN)
pad_status.button |= PAD_GET_ORIGIN;
diff --git a/Source/Core/Core/HW/SI/SI_DeviceNull.cpp b/Source/Core/Core/HW/SI/SI_DeviceNull.cpp
index e7d7afd836..076765fd3c 100644
--- a/Source/Core/Core/HW/SI/SI_DeviceNull.cpp
+++ b/Source/Core/Core/HW/SI/SI_DeviceNull.cpp
@@ -17,8 +17,7 @@ int CSIDevice_Null::RunBuffer(u8* buffer, int request_length)
bool CSIDevice_Null::GetData(u32& hi, u32& low)
{
- hi = 0x80000000;
- return true;
+ return false;
}
void CSIDevice_Null::SendCommand(u32 command, u8 poll)