Merge pull request #5090 from lioncash/si

SI: Minor cleanup
This commit is contained in:
Markus Wick 2017-03-16 09:57:04 +01:00 committed by GitHub
commit bb708397db
2 changed files with 180 additions and 178 deletions

View File

@ -24,10 +24,10 @@
namespace SerialInterface namespace SerialInterface
{ {
static CoreTiming::EventType* changeDevice; static CoreTiming::EventType* s_change_device_event;
static CoreTiming::EventType* et_transfer_pending; static CoreTiming::EventType* s_tranfer_pending_event;
static void RunSIBuffer(u64 userdata, s64 cyclesLate); static void RunSIBuffer(u64 user_data, s64 cycles_late);
static void UpdateInterrupts(); static void UpdateInterrupts();
// SI Interrupt Types // SI Interrupt Types
@ -36,7 +36,7 @@ enum SIInterruptType
INT_RDSTINT = 0, INT_RDSTINT = 0,
INT_TCINT = 1, INT_TCINT = 1,
}; };
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt); static void GenerateSIInterrupt(SIInterruptType type);
// SI Internal Hardware Addresses // SI Internal Hardware Addresses
enum enum
@ -62,7 +62,7 @@ enum
// SI Channel Output // SI Channel Output
union USIChannelOut union USIChannelOut
{ {
u32 Hex; u32 hex;
struct struct
{ {
u32 OUTPUT1 : 8; u32 OUTPUT1 : 8;
@ -75,7 +75,7 @@ union USIChannelOut
// SI Channel Input High u32 // SI Channel Input High u32
union USIChannelIn_Hi union USIChannelIn_Hi
{ {
u32 Hex; u32 hex;
struct struct
{ {
u32 INPUT3 : 8; u32 INPUT3 : 8;
@ -90,7 +90,7 @@ union USIChannelIn_Hi
// SI Channel Input Low u32 // SI Channel Input Low u32
union USIChannelIn_Lo union USIChannelIn_Lo
{ {
u32 Hex; u32 hex;
struct struct
{ {
u32 INPUT7 : 8; u32 INPUT7 : 8;
@ -103,16 +103,16 @@ union USIChannelIn_Lo
// SI Channel // SI Channel
struct SSIChannel struct SSIChannel
{ {
USIChannelOut m_Out; USIChannelOut out;
USIChannelIn_Hi m_InHi; USIChannelIn_Hi in_hi;
USIChannelIn_Lo m_InLo; USIChannelIn_Lo in_lo;
std::unique_ptr<ISIDevice> m_device; std::unique_ptr<ISIDevice> device;
}; };
// SI Poll: Controls how often a device is polled // SI Poll: Controls how often a device is polled
union USIPoll union USIPoll
{ {
u32 Hex; u32 hex;
struct struct
{ {
u32 VBCPY3 : 1; // 1: write to output buffer only on vblank u32 VBCPY3 : 1; // 1: write to output buffer only on vblank
@ -132,7 +132,7 @@ union USIPoll
// SI Communication Control Status Register // SI Communication Control Status Register
union USIComCSR union USIComCSR
{ {
u32 Hex; u32 hex = 0;
struct struct
{ {
u32 TSTART : 1; // write: start transfer read: transfer status u32 TSTART : 1; // write: start transfer read: transfer status
@ -152,14 +152,14 @@ union USIComCSR
u32 TCINTMSK : 1; // Transfer Complete Interrupt Mask u32 TCINTMSK : 1; // Transfer Complete Interrupt Mask
u32 TCINT : 1; // Transfer Complete Interrupt u32 TCINT : 1; // Transfer Complete Interrupt
}; };
USIComCSR() { Hex = 0; } USIComCSR() = default;
USIComCSR(u32 _hex) { Hex = _hex; } USIComCSR(u32 value) : hex{value} {}
}; };
// SI Status Register // SI Status Register
union USIStatusReg union USIStatusReg
{ {
u32 Hex; u32 hex = 0;
struct struct
{ {
u32 UNRUN3 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error u32 UNRUN3 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
@ -192,14 +192,14 @@ union USIStatusReg
u32 : 1; u32 : 1;
u32 WR : 1; // (RW) write 1 start copy, read 0 copy done u32 WR : 1; // (RW) write 1 start copy, read 0 copy done
}; };
USIStatusReg() { Hex = 0; } USIStatusReg() = default;
USIStatusReg(u32 _hex) { Hex = _hex; } USIStatusReg(u32 value) : hex{value} {}
}; };
// SI EXI Clock Count // SI EXI Clock Count
union USIEXIClockCount union USIEXIClockCount
{ {
u32 Hex; u32 hex;
struct struct
{ {
u32 LOCK : 1; // 1: prevents CPU from setting EXI clock to 32MHz u32 LOCK : 1; // 1: prevents CPU from setting EXI clock to 32MHz
@ -208,22 +208,22 @@ union USIEXIClockCount
}; };
// STATE_TO_SAVE // STATE_TO_SAVE
static std::array<SSIChannel, MAX_SI_CHANNELS> g_Channel; static std::array<SSIChannel, MAX_SI_CHANNELS> s_channel;
static USIPoll g_Poll; static USIPoll s_poll;
static USIComCSR g_ComCSR; static USIComCSR s_com_csr;
static USIStatusReg g_StatusReg; static USIStatusReg s_status_reg;
static USIEXIClockCount g_EXIClockCount; static USIEXIClockCount s_exi_clock_count;
static u8 g_SIBuffer[128]; static u8 s_si_buffer[128];
void DoState(PointerWrap& p) void DoState(PointerWrap& p)
{ {
for (int i = 0; i < MAX_SI_CHANNELS; i++) for (int i = 0; i < MAX_SI_CHANNELS; i++)
{ {
p.Do(g_Channel[i].m_InHi.Hex); p.Do(s_channel[i].in_hi.hex);
p.Do(g_Channel[i].m_InLo.Hex); p.Do(s_channel[i].in_lo.hex);
p.Do(g_Channel[i].m_Out.Hex); p.Do(s_channel[i].out.hex);
std::unique_ptr<ISIDevice>& device = g_Channel[i].m_device; std::unique_ptr<ISIDevice>& device = s_channel[i].device;
SIDevices type = device->GetDeviceType(); SIDevices type = device->GetDeviceType();
p.Do(type); p.Do(type);
@ -244,23 +244,23 @@ void DoState(PointerWrap& p)
} }
} }
p.Do(g_Poll); p.Do(s_poll);
p.DoPOD(g_ComCSR); p.DoPOD(s_com_csr);
p.DoPOD(g_StatusReg); p.DoPOD(s_status_reg);
p.Do(g_EXIClockCount); p.Do(s_exi_clock_count);
p.Do(g_SIBuffer); p.Do(s_si_buffer);
} }
static void ChangeDeviceCallback(u64 userdata, s64 cyclesLate); static void ChangeDeviceCallback(u64 user_data, s64 cycles_late);
static void RunSIBuffer(u64 userdata, s64 cyclesLate); static void RunSIBuffer(u64 user_data, s64 cycles_late);
void Init() void Init()
{ {
for (int i = 0; i < MAX_SI_CHANNELS; i++) for (int i = 0; i < MAX_SI_CHANNELS; i++)
{ {
g_Channel[i].m_Out.Hex = 0; s_channel[i].out.hex = 0;
g_Channel[i].m_InHi.Hex = 0; s_channel[i].in_hi.hex = 0;
g_Channel[i].m_InLo.Hex = 0; s_channel[i].in_lo.hex = 0;
if (Movie::IsMovieActive()) if (Movie::IsMovieActive())
{ {
@ -284,20 +284,22 @@ void Init()
} }
} }
g_Poll.Hex = 0; s_poll.hex = 0;
g_Poll.X = 492; s_poll.X = 492;
g_ComCSR.Hex = 0; s_com_csr.hex = 0;
g_StatusReg.Hex = 0; s_status_reg.hex = 0;
g_EXIClockCount.Hex = 0; s_exi_clock_count.hex = 0;
// g_EXIClockCount.LOCK = 1; // Supposedly set on reset, but logs from real Wii don't look like it
// is...
memset(g_SIBuffer, 0, 128);
changeDevice = CoreTiming::RegisterEvent("ChangeSIDevice", ChangeDeviceCallback); // Supposedly set on reset, but logs from real Wii don't look like it is...
et_transfer_pending = CoreTiming::RegisterEvent("SITransferPending", RunSIBuffer); // s_exi_clock_count.LOCK = 1;
memset(s_si_buffer, 0, 128);
s_change_device_event = CoreTiming::RegisterEvent("ChangeSIDevice", ChangeDeviceCallback);
s_tranfer_pending_event = CoreTiming::RegisterEvent("SITransferPending", RunSIBuffer);
} }
void Shutdown() void Shutdown()
@ -311,8 +313,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{ {
// Register SI buffer direct accesses. // Register SI buffer direct accesses.
for (int i = 0; i < 0x80; i += 4) for (int i = 0; i < 0x80; i += 4)
mmio->Register(base | (0x80 + i), MMIO::DirectRead<u32>((u32*)&g_SIBuffer[i]), mmio->Register(base | (0x80 + i), MMIO::DirectRead<u32>((u32*)&s_si_buffer[i]),
MMIO::DirectWrite<u32>((u32*)&g_SIBuffer[i])); MMIO::DirectWrite<u32>((u32*)&s_si_buffer[i]));
// In and out for the 4 SI channels. // In and out for the 4 SI channels.
for (int i = 0; i < MAX_SI_CHANNELS; ++i) for (int i = 0; i < MAX_SI_CHANNELS; ++i)
@ -325,130 +327,130 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
int rdst_bit = 8 * (3 - i) + 5; int 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>(&g_Channel[i].m_Out.Hex), MMIO::DirectRead<u32>(&s_channel[i].out.hex),
MMIO::DirectWrite<u32>(&g_Channel[i].m_Out.Hex)); MMIO::DirectWrite<u32>(&s_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](u32) { MMIO::ComplexRead<u32>([i, rdst_bit](u32) {
g_StatusReg.Hex &= ~(1 << rdst_bit); s_status_reg.hex &= ~(1 << rdst_bit);
UpdateInterrupts(); UpdateInterrupts();
return g_Channel[i].m_InHi.Hex; return s_channel[i].in_hi.hex;
}), }),
MMIO::DirectWrite<u32>(&g_Channel[i].m_InHi.Hex)); MMIO::DirectWrite<u32>(&s_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](u32) { MMIO::ComplexRead<u32>([i, rdst_bit](u32) {
g_StatusReg.Hex &= ~(1 << rdst_bit); s_status_reg.hex &= ~(1 << rdst_bit);
UpdateInterrupts(); UpdateInterrupts();
return g_Channel[i].m_InLo.Hex; return s_channel[i].in_lo.hex;
}), }),
MMIO::DirectWrite<u32>(&g_Channel[i].m_InLo.Hex)); MMIO::DirectWrite<u32>(&s_channel[i].in_lo.hex));
} }
mmio->Register(base | SI_POLL, MMIO::DirectRead<u32>(&g_Poll.Hex), mmio->Register(base | SI_POLL, MMIO::DirectRead<u32>(&s_poll.hex),
MMIO::DirectWrite<u32>(&g_Poll.Hex)); MMIO::DirectWrite<u32>(&s_poll.hex));
mmio->Register(base | SI_COM_CSR, MMIO::DirectRead<u32>(&g_ComCSR.Hex), mmio->Register(base | SI_COM_CSR, MMIO::DirectRead<u32>(&s_com_csr.hex),
MMIO::ComplexWrite<u32>([](u32, u32 val) { MMIO::ComplexWrite<u32>([](u32, u32 val) {
USIComCSR tmpComCSR(val); USIComCSR tmp_com_csr(val);
g_ComCSR.CHANNEL = tmpComCSR.CHANNEL; s_com_csr.CHANNEL = tmp_com_csr.CHANNEL;
g_ComCSR.INLNGTH = tmpComCSR.INLNGTH; s_com_csr.INLNGTH = tmp_com_csr.INLNGTH;
g_ComCSR.OUTLNGTH = tmpComCSR.OUTLNGTH; s_com_csr.OUTLNGTH = tmp_com_csr.OUTLNGTH;
g_ComCSR.RDSTINTMSK = tmpComCSR.RDSTINTMSK; s_com_csr.RDSTINTMSK = tmp_com_csr.RDSTINTMSK;
g_ComCSR.TCINTMSK = tmpComCSR.TCINTMSK; s_com_csr.TCINTMSK = tmp_com_csr.TCINTMSK;
g_ComCSR.COMERR = 0; s_com_csr.COMERR = 0;
if (tmpComCSR.RDSTINT) if (tmp_com_csr.RDSTINT)
g_ComCSR.RDSTINT = 0; s_com_csr.RDSTINT = 0;
if (tmpComCSR.TCINT) if (tmp_com_csr.TCINT)
g_ComCSR.TCINT = 0; s_com_csr.TCINT = 0;
// be careful: run si-buffer after updating the INT flags // be careful: run si-buffer after updating the INT flags
if (tmpComCSR.TSTART) if (tmp_com_csr.TSTART)
{ {
g_ComCSR.TSTART = 1; s_com_csr.TSTART = 1;
RunSIBuffer(0, 0); RunSIBuffer(0, 0);
} }
else if (g_ComCSR.TSTART) else if (s_com_csr.TSTART)
{ {
CoreTiming::RemoveEvent(et_transfer_pending); CoreTiming::RemoveEvent(s_tranfer_pending_event);
} }
if (!g_ComCSR.TSTART) if (!s_com_csr.TSTART)
UpdateInterrupts(); UpdateInterrupts();
})); }));
mmio->Register(base | SI_STATUS_REG, MMIO::DirectRead<u32>(&g_StatusReg.Hex), mmio->Register(base | SI_STATUS_REG, MMIO::DirectRead<u32>(&s_status_reg.hex),
MMIO::ComplexWrite<u32>([](u32, u32 val) { MMIO::ComplexWrite<u32>([](u32, u32 val) {
USIStatusReg tmpStatus(val); USIStatusReg tmp_status(val);
// clear bits ( if (tmp.bit) SISR.bit=0 ) // clear bits ( if (tmp.bit) SISR.bit=0 )
if (tmpStatus.NOREP0) if (tmp_status.NOREP0)
g_StatusReg.NOREP0 = 0; s_status_reg.NOREP0 = 0;
if (tmpStatus.COLL0) if (tmp_status.COLL0)
g_StatusReg.COLL0 = 0; s_status_reg.COLL0 = 0;
if (tmpStatus.OVRUN0) if (tmp_status.OVRUN0)
g_StatusReg.OVRUN0 = 0; s_status_reg.OVRUN0 = 0;
if (tmpStatus.UNRUN0) if (tmp_status.UNRUN0)
g_StatusReg.UNRUN0 = 0; s_status_reg.UNRUN0 = 0;
if (tmpStatus.NOREP1) if (tmp_status.NOREP1)
g_StatusReg.NOREP1 = 0; s_status_reg.NOREP1 = 0;
if (tmpStatus.COLL1) if (tmp_status.COLL1)
g_StatusReg.COLL1 = 0; s_status_reg.COLL1 = 0;
if (tmpStatus.OVRUN1) if (tmp_status.OVRUN1)
g_StatusReg.OVRUN1 = 0; s_status_reg.OVRUN1 = 0;
if (tmpStatus.UNRUN1) if (tmp_status.UNRUN1)
g_StatusReg.UNRUN1 = 0; s_status_reg.UNRUN1 = 0;
if (tmpStatus.NOREP2) if (tmp_status.NOREP2)
g_StatusReg.NOREP2 = 0; s_status_reg.NOREP2 = 0;
if (tmpStatus.COLL2) if (tmp_status.COLL2)
g_StatusReg.COLL2 = 0; s_status_reg.COLL2 = 0;
if (tmpStatus.OVRUN2) if (tmp_status.OVRUN2)
g_StatusReg.OVRUN2 = 0; s_status_reg.OVRUN2 = 0;
if (tmpStatus.UNRUN2) if (tmp_status.UNRUN2)
g_StatusReg.UNRUN2 = 0; s_status_reg.UNRUN2 = 0;
if (tmpStatus.NOREP3) if (tmp_status.NOREP3)
g_StatusReg.NOREP3 = 0; s_status_reg.NOREP3 = 0;
if (tmpStatus.COLL3) if (tmp_status.COLL3)
g_StatusReg.COLL3 = 0; s_status_reg.COLL3 = 0;
if (tmpStatus.OVRUN3) if (tmp_status.OVRUN3)
g_StatusReg.OVRUN3 = 0; s_status_reg.OVRUN3 = 0;
if (tmpStatus.UNRUN3) if (tmp_status.UNRUN3)
g_StatusReg.UNRUN3 = 0; s_status_reg.UNRUN3 = 0;
// send command to devices // send command to devices
if (tmpStatus.WR) if (tmp_status.WR)
{ {
g_Channel[0].m_device->SendCommand(g_Channel[0].m_Out.Hex, g_Poll.EN0); s_channel[0].device->SendCommand(s_channel[0].out.hex, s_poll.EN0);
g_Channel[1].m_device->SendCommand(g_Channel[1].m_Out.Hex, g_Poll.EN1); s_channel[1].device->SendCommand(s_channel[1].out.hex, s_poll.EN1);
g_Channel[2].m_device->SendCommand(g_Channel[2].m_Out.Hex, g_Poll.EN2); s_channel[2].device->SendCommand(s_channel[2].out.hex, s_poll.EN2);
g_Channel[3].m_device->SendCommand(g_Channel[3].m_Out.Hex, g_Poll.EN3); s_channel[3].device->SendCommand(s_channel[3].out.hex, s_poll.EN3);
g_StatusReg.WR = 0; s_status_reg.WR = 0;
g_StatusReg.WRST0 = 0; s_status_reg.WRST0 = 0;
g_StatusReg.WRST1 = 0; s_status_reg.WRST1 = 0;
g_StatusReg.WRST2 = 0; s_status_reg.WRST2 = 0;
g_StatusReg.WRST3 = 0; s_status_reg.WRST3 = 0;
} }
})); }));
mmio->Register(base | SI_EXI_CLOCK_COUNT, MMIO::DirectRead<u32>(&g_EXIClockCount.Hex), mmio->Register(base | SI_EXI_CLOCK_COUNT, MMIO::DirectRead<u32>(&s_exi_clock_count.hex),
MMIO::DirectWrite<u32>(&g_EXIClockCount.Hex)); MMIO::DirectWrite<u32>(&s_exi_clock_count.hex));
} }
static void UpdateInterrupts() static void UpdateInterrupts()
{ {
// check if we have to update the RDSTINT flag // check if we have to update the RDSTINT flag
if (g_StatusReg.RDST0 || g_StatusReg.RDST1 || g_StatusReg.RDST2 || g_StatusReg.RDST3) if (s_status_reg.RDST0 || s_status_reg.RDST1 || s_status_reg.RDST2 || s_status_reg.RDST3)
g_ComCSR.RDSTINT = 1; s_com_csr.RDSTINT = 1;
else else
g_ComCSR.RDSTINT = 0; s_com_csr.RDSTINT = 0;
// check if we have to generate an interrupt // check if we have to generate an interrupt
if ((g_ComCSR.RDSTINT & g_ComCSR.RDSTINTMSK) || (g_ComCSR.TCINT & g_ComCSR.TCINTMSK)) if ((s_com_csr.RDSTINT & s_com_csr.RDSTINTMSK) || (s_com_csr.TCINT & s_com_csr.TCINTMSK))
{ {
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_SI, true); ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_SI, true);
} }
@ -458,15 +460,15 @@ static void UpdateInterrupts()
} }
} }
void GenerateSIInterrupt(SIInterruptType _SIInterrupt) void GenerateSIInterrupt(SIInterruptType type)
{ {
switch (_SIInterrupt) switch (type)
{ {
case INT_RDSTINT: case INT_RDSTINT:
g_ComCSR.RDSTINT = 1; s_com_csr.RDSTINT = 1;
break; break;
case INT_TCINT: case INT_TCINT:
g_ComCSR.TCINT = 1; s_com_csr.TCINT = 1;
break; break;
} }
@ -475,7 +477,7 @@ void GenerateSIInterrupt(SIInterruptType _SIInterrupt)
void RemoveDevice(int device_number) void RemoveDevice(int device_number)
{ {
g_Channel.at(device_number).m_device.reset(); s_channel.at(device_number).device.reset();
} }
void AddDevice(std::unique_ptr<ISIDevice> device) void AddDevice(std::unique_ptr<ISIDevice> device)
@ -486,7 +488,7 @@ void AddDevice(std::unique_ptr<ISIDevice> device)
RemoveDevice(device_number); RemoveDevice(device_number);
// Set the new one // Set the new one
g_Channel.at(device_number).m_device = std::move(device); s_channel.at(device_number).device = std::move(device);
} }
void AddDevice(const SIDevices device, int device_number) void AddDevice(const SIDevices device, int device_number)
@ -500,32 +502,32 @@ static void SetNoResponse(u32 channel)
switch (channel) switch (channel)
{ {
case 0: case 0:
g_StatusReg.NOREP0 = 1; s_status_reg.NOREP0 = 1;
break; break;
case 1: case 1:
g_StatusReg.NOREP1 = 1; s_status_reg.NOREP1 = 1;
break; break;
case 2: case 2:
g_StatusReg.NOREP2 = 1; s_status_reg.NOREP2 = 1;
break; break;
case 3: case 3:
g_StatusReg.NOREP3 = 1; s_status_reg.NOREP3 = 1;
break; break;
} }
g_ComCSR.COMERR = 1; s_com_csr.COMERR = 1;
} }
static void ChangeDeviceCallback(u64 userdata, s64 cyclesLate) static void ChangeDeviceCallback(u64 user_data, s64 cycles_late)
{ {
u8 channel = (u8)(userdata >> 32); u8 channel = (u8)(user_data >> 32);
SIDevices device = (SIDevices)(u32)userdata; SIDevices device = (SIDevices)(u32)user_data;
// Skip redundant (spammed) device changes // Skip redundant (spammed) device changes
if (GetDeviceType(channel) != device) if (GetDeviceType(channel) != device)
{ {
g_Channel[channel].m_Out.Hex = 0; s_channel[channel].out.hex = 0;
g_Channel[channel].m_InHi.Hex = 0; s_channel[channel].in_hi.hex = 0;
g_Channel[channel].m_InLo.Hex = 0; s_channel[channel].in_lo.hex = 0;
SetNoResponse(channel); SetNoResponse(channel);
@ -540,9 +542,9 @@ void ChangeDevice(SIDevices device, int channel)
// TODO: Calling GetDeviceType here isn't threadsafe. // TODO: Calling GetDeviceType here isn't threadsafe.
if (GetDeviceType(channel) != device) if (GetDeviceType(channel) != device)
{ {
CoreTiming::ScheduleEvent(0, changeDevice, ((u64)channel << 32) | SIDEVICE_NONE, CoreTiming::ScheduleEvent(0, s_change_device_event, ((u64)channel << 32) | SIDEVICE_NONE,
CoreTiming::FromThread::NON_CPU); CoreTiming::FromThread::NON_CPU);
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), changeDevice, CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_change_device_event,
((u64)channel << 32) | device, CoreTiming::FromThread::NON_CPU); ((u64)channel << 32) | device, CoreTiming::FromThread::NON_CPU);
} }
} }
@ -552,8 +554,8 @@ void ChangeDeviceDeterministic(SIDevices device, int channel)
// Called from savestates, so we don't use FromThread::NON_CPU. // Called from savestates, so we don't use FromThread::NON_CPU.
if (GetDeviceType(channel) != device) if (GetDeviceType(channel) != device)
{ {
CoreTiming::ScheduleEvent(0, changeDevice, ((u64)channel << 32) | SIDEVICE_NONE); CoreTiming::ScheduleEvent(0, s_change_device_event, ((u64)channel << 32) | SIDEVICE_NONE);
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), changeDevice, CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_change_device_event,
((u64)channel << 32) | device); ((u64)channel << 32) | device);
} }
} }
@ -565,14 +567,14 @@ void 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
g_StatusReg.RDST0 = s_status_reg.RDST0 =
!!g_Channel[0].m_device->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex); !!s_channel[0].device->GetData(s_channel[0].in_hi.hex, s_channel[0].in_lo.hex);
g_StatusReg.RDST1 = s_status_reg.RDST1 =
!!g_Channel[1].m_device->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex); !!s_channel[1].device->GetData(s_channel[1].in_hi.hex, s_channel[1].in_lo.hex);
g_StatusReg.RDST2 = s_status_reg.RDST2 =
!!g_Channel[2].m_device->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex); !!s_channel[2].device->GetData(s_channel[2].in_hi.hex, s_channel[2].in_lo.hex);
g_StatusReg.RDST3 = s_status_reg.RDST3 =
!!g_Channel[3].m_device->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex); !!s_channel[3].device->GetData(s_channel[3].in_hi.hex, s_channel[3].in_lo.hex);
UpdateInterrupts(); UpdateInterrupts();
} }
@ -582,48 +584,48 @@ SIDevices GetDeviceType(int channel)
if (channel < 0 || channel > 3) if (channel < 0 || channel > 3)
return SIDEVICE_NONE; return SIDEVICE_NONE;
return g_Channel[channel].m_device->GetDeviceType(); return s_channel[channel].device->GetDeviceType();
} }
static void RunSIBuffer(u64 userdata, s64 cyclesLate) static void RunSIBuffer(u64 user_data, s64 cycles_late)
{ {
if (g_ComCSR.TSTART) if (s_com_csr.TSTART)
{ {
// Math inLength // Math in_length
int inLength = g_ComCSR.INLNGTH; int in_length = s_com_csr.INLNGTH;
if (inLength == 0) if (in_length == 0)
inLength = 128; in_length = 128;
else else
inLength++; in_length++;
// Math outLength // Math out_length
int outLength = g_ComCSR.OUTLNGTH; int out_length = s_com_csr.OUTLNGTH;
if (outLength == 0) if (out_length == 0)
outLength = 128; out_length = 128;
else else
outLength++; out_length++;
std::unique_ptr<ISIDevice>& device = g_Channel[g_ComCSR.CHANNEL].m_device; std::unique_ptr<ISIDevice>& device = s_channel[s_com_csr.CHANNEL].device;
int numOutput = device->RunBuffer(g_SIBuffer, inLength); int numOutput = device->RunBuffer(s_si_buffer, in_length);
DEBUG_LOG(SERIALINTERFACE, "RunSIBuffer chan: %d inLen: %i outLen: %i processed: %i", DEBUG_LOG(SERIALINTERFACE, "RunSIBuffer chan: %d inLen: %i outLen: %i processed: %i",
g_ComCSR.CHANNEL, inLength, outLength, numOutput); s_com_csr.CHANNEL, in_length, out_length, numOutput);
if (numOutput != 0) if (numOutput != 0)
{ {
g_ComCSR.TSTART = 0; s_com_csr.TSTART = 0;
GenerateSIInterrupt(INT_TCINT); GenerateSIInterrupt(INT_TCINT);
} }
else else
{ {
CoreTiming::ScheduleEvent(device->TransferInterval() - cyclesLate, et_transfer_pending); CoreTiming::ScheduleEvent(device->TransferInterval() - cycles_late, s_tranfer_pending_event);
} }
} }
} }
u32 GetPollXLines() u32 GetPollXLines()
{ {
return g_Poll.X; return s_poll.X;
} }
} // end of namespace SerialInterface } // end of namespace SerialInterface

View File

@ -31,8 +31,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void UpdateDevices(); void UpdateDevices();
void RemoveDevice(int _iDeviceNumber); void RemoveDevice(int device_number);
void AddDevice(const SIDevices _device, int _iDeviceNumber); void AddDevice(SIDevices device, int device_number);
void AddDevice(std::unique_ptr<ISIDevice> device); void AddDevice(std::unique_ptr<ISIDevice> device);
void ChangeDevice(SIDevices device, int channel); void ChangeDevice(SIDevices device, int channel);