mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-10 03:27:42 +01:00
SI: Set NOREP, ERRSTAT, and ERRLATCH when GetData returns false.
This commit is contained in:
parent
ddb0e1e309
commit
8431c23cbc
@ -59,6 +59,12 @@ SerialInterfaceManager::SerialInterfaceManager(Core::System& system) : m_system(
|
|||||||
|
|
||||||
SerialInterfaceManager::~SerialInterfaceManager() = default;
|
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)
|
void SerialInterfaceManager::SetNoResponse(u32 channel)
|
||||||
{
|
{
|
||||||
// raise the NO RESPONSE error
|
// 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)
|
for (u32 i = 0; i < u32(MAX_SI_CHANNELS); ++i)
|
||||||
{
|
{
|
||||||
// We need to clear the RDST bit for the SI channel when reading.
|
// We need to clear the RDST bit for the SI channel when reading.
|
||||||
// CH0 -> Bit 24 + 5
|
const u32 clear_rdst = ~GetRDSTBit(i);
|
||||||
// CH1 -> Bit 16 + 5
|
|
||||||
// CH2 -> Bit 8 + 5
|
|
||||||
// CH3 -> Bit 0 + 5
|
|
||||||
const u32 rdst_bit = 8 * (3 - i) + 5;
|
|
||||||
|
|
||||||
mmio->Register(base | (SI_CHANNEL_0_OUT + 0xC * i),
|
mmio->Register(base | (SI_CHANNEL_0_OUT + 0xC * i),
|
||||||
MMIO::DirectRead<u32>(&m_channel[i].out.hex),
|
MMIO::DirectRead<u32>(&m_channel[i].out.hex),
|
||||||
MMIO::DirectWrite<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->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();
|
auto& si = system.GetSerialInterface();
|
||||||
si.m_status_reg.hex &= ~(1U << rdst_bit);
|
si.m_status_reg.hex &= clear_rdst;
|
||||||
si.UpdateInterrupts();
|
si.UpdateInterrupts();
|
||||||
return si.m_channel[i].in_hi.hex;
|
return si.m_channel[i].in_hi.hex;
|
||||||
}),
|
}),
|
||||||
MMIO::DirectWrite<u32>(&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->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();
|
auto& si = system.GetSerialInterface();
|
||||||
si.m_status_reg.hex &= ~(1U << rdst_bit);
|
si.m_status_reg.hex &= clear_rdst;
|
||||||
si.UpdateInterrupts();
|
si.UpdateInterrupts();
|
||||||
return si.m_channel[i].in_lo.hex;
|
return si.m_channel[i].in_lo.hex;
|
||||||
}),
|
}),
|
||||||
@ -554,14 +556,23 @@ void SerialInterfaceManager::UpdateDevices()
|
|||||||
g_controller_interface.UpdateInput();
|
g_controller_interface.UpdateInput();
|
||||||
|
|
||||||
// Update channels and set the status bit if there's new data
|
// Update channels and set the status bit if there's new data
|
||||||
m_status_reg.RDST0 =
|
for (u32 i = 0; i != MAX_SI_CHANNELS; ++i)
|
||||||
!!m_channel[0].device->GetData(m_channel[0].in_hi.hex, m_channel[0].in_lo.hex);
|
{
|
||||||
m_status_reg.RDST1 =
|
// ERRLATCH bit is maintained.
|
||||||
!!m_channel[1].device->GetData(m_channel[1].in_hi.hex, m_channel[1].in_lo.hex);
|
u32 errlatch = m_channel[i].in_hi.ERRLATCH.Value();
|
||||||
m_status_reg.RDST2 =
|
if (m_channel[i].device->GetData(m_channel[i].in_hi.hex, m_channel[i].in_lo.hex))
|
||||||
!!m_channel[2].device->GetData(m_channel[2].in_hi.hex, m_channel[2].in_lo.hex);
|
{
|
||||||
m_status_reg.RDST3 =
|
m_status_reg.hex |= GetRDSTBit(i);
|
||||||
!!m_channel[3].device->GetData(m_channel[3].in_hi.hex, m_channel[3].in_lo.hex);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errlatch = 1;
|
||||||
|
m_channel[i].in_hi.ERRSTAT = 1;
|
||||||
|
SetNoResponse(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_channel[i].in_hi.ERRLATCH = errlatch;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateInterrupts();
|
UpdateInterrupts();
|
||||||
|
|
||||||
|
@ -175,10 +175,7 @@ bool CSIDevice_GCController::GetData(u32& hi, u32& low)
|
|||||||
GCPadStatus pad_status = GetPadStatus();
|
GCPadStatus pad_status = GetPadStatus();
|
||||||
|
|
||||||
if (!pad_status.isConnected)
|
if (!pad_status.isConnected)
|
||||||
{
|
return false;
|
||||||
hi = 0x80000000;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HandleButtonCombos(pad_status) == COMBO_ORIGIN)
|
if (HandleButtonCombos(pad_status) == COMBO_ORIGIN)
|
||||||
pad_status.button |= PAD_GET_ORIGIN;
|
pad_status.button |= PAD_GET_ORIGIN;
|
||||||
|
@ -17,8 +17,7 @@ int CSIDevice_Null::RunBuffer(u8* buffer, int request_length)
|
|||||||
|
|
||||||
bool CSIDevice_Null::GetData(u32& hi, u32& low)
|
bool CSIDevice_Null::GetData(u32& hi, u32& low)
|
||||||
{
|
{
|
||||||
hi = 0x80000000;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSIDevice_Null::SendCommand(u32 command, u8 poll)
|
void CSIDevice_Null::SendCommand(u32 command, u8 poll)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user