mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-31 18:11:31 +02:00
replace SI_DUMMY with SI_NONE, an actual null device.
tweak SI a little so that it doesn't block things which block on the status reg. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4713 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
c3b196541d
commit
5e7607b700
@ -228,7 +228,7 @@ void SConfig::LoadSettings()
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
sprintf(sidevicenum, "SIDevice%i", i);
|
||||
ini.Get("Core", sidevicenum, (u32*)&m_SIDevice[i], i==0 ? SI_GC_CONTROLLER:SI_DUMMY);
|
||||
ini.Get("Core", sidevicenum, (u32*)&m_SIDevice[i], i==0 ? SI_GC_CONTROLLER:SI_NONE);
|
||||
}
|
||||
|
||||
ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false);
|
||||
|
@ -75,10 +75,10 @@ union USIChannelOut
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
unsigned OUTPUT1 : 8;
|
||||
unsigned OUTPUT0 : 8;
|
||||
unsigned CMD : 8;
|
||||
unsigned : 8;
|
||||
u32 OUTPUT1 : 8;
|
||||
u32 OUTPUT0 : 8;
|
||||
u32 CMD : 8;
|
||||
u32 : 8;
|
||||
};
|
||||
};
|
||||
|
||||
@ -88,12 +88,12 @@ union USIChannelIn_Hi
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
unsigned INPUT3 : 8;
|
||||
unsigned INPUT2 : 8;
|
||||
unsigned INPUT1 : 8;
|
||||
unsigned INPUT0 : 6;
|
||||
unsigned ERRLATCH : 1; // 0: no error 1: Error latched. Check SISR.
|
||||
unsigned ERRSTAT : 1; // 0: no error 1: error on last transfer
|
||||
u32 INPUT3 : 8;
|
||||
u32 INPUT2 : 8;
|
||||
u32 INPUT1 : 8;
|
||||
u32 INPUT0 : 6;
|
||||
u32 ERRLATCH : 1; // 0: no error 1: Error latched. Check SISR.
|
||||
u32 ERRSTAT : 1; // 0: no error 1: error on last transfer
|
||||
};
|
||||
};
|
||||
|
||||
@ -103,10 +103,10 @@ union USIChannelIn_Lo
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
unsigned INPUT7 : 8;
|
||||
unsigned INPUT6 : 8;
|
||||
unsigned INPUT5 : 8;
|
||||
unsigned INPUT4 : 8;
|
||||
u32 INPUT7 : 8;
|
||||
u32 INPUT6 : 8;
|
||||
u32 INPUT5 : 8;
|
||||
u32 INPUT4 : 8;
|
||||
};
|
||||
};
|
||||
|
||||
@ -125,17 +125,17 @@ union USIPoll
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
unsigned VBCPY3 : 1; // 1: write to output buffer only on vblank
|
||||
unsigned VBCPY2 : 1;
|
||||
unsigned VBCPY1 : 1;
|
||||
unsigned VBCPY0 : 1;
|
||||
unsigned EN3 : 1; // Enable polling of channel
|
||||
unsigned EN2 : 1; // does not affect communication RAM transfers
|
||||
unsigned EN1 : 1;
|
||||
unsigned EN0 : 1;
|
||||
unsigned Y : 8; // Polls per frame
|
||||
unsigned X : 10; // Polls per X lines. begins at vsync, min 7, max depends on video mode
|
||||
unsigned : 6;
|
||||
u32 VBCPY3 : 1; // 1: write to output buffer only on vblank
|
||||
u32 VBCPY2 : 1;
|
||||
u32 VBCPY1 : 1;
|
||||
u32 VBCPY0 : 1;
|
||||
u32 EN3 : 1; // Enable polling of channel
|
||||
u32 EN2 : 1; // does not affect communication RAM transfers
|
||||
u32 EN1 : 1;
|
||||
u32 EN0 : 1;
|
||||
u32 Y : 8; // Polls per frame
|
||||
u32 X : 10; // Polls per X lines. begins at vsync, min 7, max depends on video mode
|
||||
u32 : 6;
|
||||
};
|
||||
};
|
||||
|
||||
@ -145,22 +145,22 @@ union USIComCSR
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
unsigned TSTART : 1; // write: start transfer read: transfer status
|
||||
unsigned CHANNEL : 2; // determines which SI channel will be used on the communication interface.
|
||||
unsigned : 3;
|
||||
unsigned CALLBEN : 1; // Callback enable
|
||||
unsigned CMDEN : 1; // Command enable?
|
||||
unsigned INLNGTH : 7;
|
||||
unsigned : 1;
|
||||
unsigned OUTLNGTH : 7; // Communication Channel Output Length in bytes
|
||||
unsigned : 1;
|
||||
unsigned CHANEN : 1; // Channel enable?
|
||||
unsigned CHANNUM : 2; // Channel number?
|
||||
unsigned RDSTINTMSK : 1; // Read Status Interrupt Status Mask
|
||||
unsigned RDSTINT : 1; // Read Status Interrupt Status
|
||||
unsigned COMERR : 1; // Communication Error (set 0)
|
||||
unsigned TCINTMSK : 1; // Transfer Complete Interrupt Mask
|
||||
unsigned TCINT : 1; // Transfer Complete Interrupt
|
||||
u32 TSTART : 1; // write: start transfer read: transfer status
|
||||
u32 CHANNEL : 2; // determines which SI channel will be used on the communication interface.
|
||||
u32 : 3;
|
||||
u32 CALLBEN : 1; // Callback enable
|
||||
u32 CMDEN : 1; // Command enable?
|
||||
u32 INLNGTH : 7;
|
||||
u32 : 1;
|
||||
u32 OUTLNGTH : 7; // Communication Channel Output Length in bytes
|
||||
u32 : 1;
|
||||
u32 CHANEN : 1; // Channel enable?
|
||||
u32 CHANNUM : 2; // Channel number?
|
||||
u32 RDSTINTMSK : 1; // Read Status Interrupt Status Mask
|
||||
u32 RDSTINT : 1; // Read Status Interrupt Status
|
||||
u32 COMERR : 1; // Communication Error (set 0)
|
||||
u32 TCINTMSK : 1; // Transfer Complete Interrupt Mask
|
||||
u32 TCINT : 1; // Transfer Complete Interrupt
|
||||
};
|
||||
USIComCSR() {Hex = 0;}
|
||||
USIComCSR(u32 _hex) {Hex = _hex;}
|
||||
@ -172,35 +172,35 @@ union USIStatusReg
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
unsigned UNRUN3 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
unsigned OVRUN3 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
unsigned COLL3 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
unsigned NOREP3 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
unsigned WRST3 : 1; // (R) 1: buffer channel0 not copied
|
||||
unsigned RDST3 : 1; // (R) 1: new Data available
|
||||
unsigned : 2; // 7:6
|
||||
unsigned UNRUN2 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
unsigned OVRUN2 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
unsigned COLL2 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
unsigned NOREP2 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
unsigned WRST2 : 1; // (R) 1: buffer channel0 not copied
|
||||
unsigned RDST2 : 1; // (R) 1: new Data available
|
||||
unsigned : 2; // 15:14
|
||||
unsigned UNRUN1 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
unsigned OVRUN1 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
unsigned COLL1 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
unsigned NOREP1 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
unsigned WRST1 : 1; // (R) 1: buffer channel0 not copied
|
||||
unsigned RDST1 : 1; // (R) 1: new Data available
|
||||
unsigned : 2; // 23:22
|
||||
unsigned UNRUN0 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
unsigned OVRUN0 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
unsigned COLL0 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
unsigned NOREP0 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
unsigned WRST0 : 1; // (R) 1: buffer channel0 not copied
|
||||
unsigned RDST0 : 1; // (R) 1: new Data available
|
||||
unsigned : 1;
|
||||
unsigned WR : 1; // (RW) write 1 start copy, read 0 copy done
|
||||
u32 UNRUN3 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
u32 OVRUN3 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
u32 COLL3 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
u32 NOREP3 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
u32 WRST3 : 1; // (R) 1: buffer channel0 not copied
|
||||
u32 RDST3 : 1; // (R) 1: new Data available
|
||||
u32 : 2; // 7:6
|
||||
u32 UNRUN2 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
u32 OVRUN2 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
u32 COLL2 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
u32 NOREP2 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
u32 WRST2 : 1; // (R) 1: buffer channel0 not copied
|
||||
u32 RDST2 : 1; // (R) 1: new Data available
|
||||
u32 : 2; // 15:14
|
||||
u32 UNRUN1 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
u32 OVRUN1 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
u32 COLL1 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
u32 NOREP1 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
u32 WRST1 : 1; // (R) 1: buffer channel0 not copied
|
||||
u32 RDST1 : 1; // (R) 1: new Data available
|
||||
u32 : 2; // 23:22
|
||||
u32 UNRUN0 : 1; // (RWC) write 1: bit cleared read 1: main proc underrun error
|
||||
u32 OVRUN0 : 1; // (RWC) write 1: bit cleared read 1: overrun error
|
||||
u32 COLL0 : 1; // (RWC) write 1: bit cleared read 1: collision error
|
||||
u32 NOREP0 : 1; // (RWC) write 1: bit cleared read 1: response error
|
||||
u32 WRST0 : 1; // (R) 1: buffer channel0 not copied
|
||||
u32 RDST0 : 1; // (R) 1: new Data available
|
||||
u32 : 1;
|
||||
u32 WR : 1; // (RW) write 1 start copy, read 0 copy done
|
||||
};
|
||||
USIStatusReg() {Hex = 0;}
|
||||
USIStatusReg(u32 _hex) {Hex = _hex;}
|
||||
@ -212,8 +212,8 @@ union USIEXIClockCount
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
unsigned LOCK : 1; // 1: prevents CPU from setting EXI clock to 32MHz
|
||||
unsigned : 30;
|
||||
u32 LOCK : 1; // 1: prevents CPU from setting EXI clock to 32MHz
|
||||
u32 : 0;
|
||||
};
|
||||
};
|
||||
|
||||
@ -249,9 +249,13 @@ void Init()
|
||||
|
||||
g_Poll.Hex = 0;
|
||||
g_Poll.X = 7;
|
||||
|
||||
g_ComCSR.Hex = 0;
|
||||
|
||||
g_StatusReg.Hex = 0;
|
||||
|
||||
g_EXIClockCount.Hex = 0;
|
||||
g_EXIClockCount.LOCK = 1;
|
||||
memset(g_SIBuffer, 0, 128);
|
||||
|
||||
changeDevice = CoreTiming::RegisterEvent("ChangeSIDevice", ChangeDeviceCallback);
|
||||
@ -286,13 +290,11 @@ void Read32(u32& _uReturnValue, const u32 _iAddress)
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_0_IN_HI:
|
||||
g_StatusReg.RDST0 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[0].m_InHi.Hex;
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_0_IN_LO:
|
||||
g_StatusReg.RDST0 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[0].m_InLo.Hex;
|
||||
return;
|
||||
@ -305,13 +307,11 @@ void Read32(u32& _uReturnValue, const u32 _iAddress)
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_1_IN_HI:
|
||||
g_StatusReg.RDST1 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[1].m_InHi.Hex;
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_1_IN_LO:
|
||||
g_StatusReg.RDST1 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[1].m_InLo.Hex;
|
||||
return;
|
||||
@ -324,13 +324,11 @@ void Read32(u32& _uReturnValue, const u32 _iAddress)
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_2_IN_HI:
|
||||
g_StatusReg.RDST2 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[2].m_InHi.Hex;
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_2_IN_LO:
|
||||
g_StatusReg.RDST2 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[2].m_InLo.Hex;
|
||||
return;
|
||||
@ -343,13 +341,11 @@ void Read32(u32& _uReturnValue, const u32 _iAddress)
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_3_IN_HI:
|
||||
g_StatusReg.RDST3 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[3].m_InHi.Hex;
|
||||
return;
|
||||
|
||||
case SI_CHANNEL_3_IN_LO:
|
||||
g_StatusReg.RDST3 = 0;
|
||||
UpdateInterrupts();
|
||||
_uReturnValue = g_Channel[3].m_InLo.Hex;
|
||||
return;
|
||||
@ -402,7 +398,7 @@ void Write32(const u32 _iValue, const u32 _iAddress)
|
||||
case SI_CHANNEL_3_IN_LO: g_Channel[3].m_InLo.Hex = _iValue; break;
|
||||
|
||||
case SI_POLL:
|
||||
INFO_LOG(SERIALINTERFACE, "Poll: X=%03d Y=%03d %s%s%s%s%s%s%s%s",
|
||||
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 ":" ",
|
||||
@ -478,12 +474,12 @@ void Write32(const u32 _iValue, const u32 _iAddress)
|
||||
g_EXIClockCount.Hex = _iValue;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
case 0x80: // Bogus? never seen it with ma own eyes
|
||||
INFO_LOG(SERIALINTERFACE, "WII something at 0xCD006480");
|
||||
break;
|
||||
|
||||
default:
|
||||
_dbg_assert_(SERIALINTERFACE,0);
|
||||
_dbg_assert_(SERIALINTERFACE, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -522,11 +518,8 @@ void GenerateSIInterrupt(SIInterruptType _SIInterrupt)
|
||||
|
||||
void RemoveDevice(int _iDeviceNumber)
|
||||
{
|
||||
if (g_Channel[_iDeviceNumber].m_pDevice != NULL)
|
||||
{
|
||||
delete g_Channel[_iDeviceNumber].m_pDevice;
|
||||
g_Channel[_iDeviceNumber].m_pDevice = NULL;
|
||||
}
|
||||
delete g_Channel[_iDeviceNumber].m_pDevice;
|
||||
g_Channel[_iDeviceNumber].m_pDevice = NULL;
|
||||
}
|
||||
|
||||
void AddDevice(const TSIDevices _device, int _iDeviceNumber)
|
||||
@ -538,54 +531,50 @@ void AddDevice(const TSIDevices _device, int _iDeviceNumber)
|
||||
|
||||
// create the new one
|
||||
g_Channel[_iDeviceNumber].m_pDevice = SIDevice_Create(_device, _iDeviceNumber);
|
||||
_dbg_assert_(SERIALINTERFACE, g_Channel[_iDeviceNumber].m_pDevice != NULL);
|
||||
}
|
||||
|
||||
void SetNoResponse(u32 channel)
|
||||
{
|
||||
// raise the NO RESPONSE error
|
||||
switch (channel)
|
||||
{
|
||||
case 0: g_StatusReg.NOREP0 = 1; break;
|
||||
case 1: g_StatusReg.NOREP1 = 1; break;
|
||||
case 2: g_StatusReg.NOREP2 = 1; break;
|
||||
case 3: g_StatusReg.NOREP3 = 1; break;
|
||||
}
|
||||
g_ComCSR.COMERR = 1;
|
||||
}
|
||||
|
||||
void ChangeDeviceCallback(u64 userdata, int cyclesLate)
|
||||
{
|
||||
u8 channel = (u8)(userdata >> 32);
|
||||
// doubt this matters...
|
||||
|
||||
g_Channel[channel].m_Out.Hex = 0;
|
||||
g_Channel[channel].m_InHi.Hex = 0;
|
||||
g_Channel[channel].m_InLo.Hex = 0;
|
||||
|
||||
// raise the NO RESPONSE error
|
||||
switch (channel)
|
||||
{
|
||||
case 0:
|
||||
g_StatusReg.NOREP0 = 1;
|
||||
break;
|
||||
case 1:
|
||||
g_StatusReg.NOREP1 = 1;
|
||||
break;
|
||||
case 2:
|
||||
g_StatusReg.NOREP2 = 1;
|
||||
break;
|
||||
case 3:
|
||||
g_StatusReg.NOREP3 = 1;
|
||||
break;
|
||||
}
|
||||
SetNoResponse(channel);
|
||||
|
||||
AddDevice((TSIDevices)(u32)userdata, channel);
|
||||
}
|
||||
|
||||
void ChangeDevice(TSIDevices device, int deviceNumber)
|
||||
void ChangeDevice(TSIDevices device, int channel)
|
||||
{
|
||||
// Called from GUI, so we need to make it thread safe.
|
||||
// Let the hardware see no device for .5b cycles
|
||||
CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, (SI_DUMMY | (u64)deviceNumber << 32));
|
||||
CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDevice, (device | (u64)deviceNumber << 32));
|
||||
CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, ((u64)channel << 32) | SI_NONE);
|
||||
CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDevice, ((u64)channel << 32) | device);
|
||||
}
|
||||
|
||||
void UpdateDevices()
|
||||
{
|
||||
// Update channels
|
||||
g_StatusReg.RDST0 = g_Channel[0].m_pDevice->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex) ? 1 : 0;
|
||||
g_StatusReg.RDST1 = g_Channel[1].m_pDevice->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex) ? 1 : 0;
|
||||
g_StatusReg.RDST2 = g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex) ? 1 : 0;
|
||||
g_StatusReg.RDST3 = g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex) ? 1 : 0;
|
||||
// Update channels and set the status bit if there's new data
|
||||
g_StatusReg.RDST0 = !!g_Channel[0].m_pDevice->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex);
|
||||
g_StatusReg.RDST1 = !!g_Channel[1].m_pDevice->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex);
|
||||
g_StatusReg.RDST2 = !!g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex);
|
||||
g_StatusReg.RDST3 = !!g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex);
|
||||
|
||||
// Update interrupts
|
||||
UpdateInterrupts();
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ void RemoveDevice(int _iDeviceNumber);
|
||||
void AddDevice(const TSIDevices _device, int _iDeviceNumber);
|
||||
|
||||
void ChangeDeviceCallback(u64 userdata, int cyclesLate);
|
||||
void ChangeDevice(TSIDevices device, int deviceNumber);
|
||||
void ChangeDevice(TSIDevices device, int channel);
|
||||
|
||||
void Read32(u32& _uReturnValue, const u32 _iAddress);
|
||||
void Write32(const u32 _iValue, const u32 _iAddress);
|
||||
|
@ -48,30 +48,22 @@ int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength)
|
||||
};
|
||||
|
||||
|
||||
// --- class CSIDummy ---
|
||||
// Just a dummy that logs reads and writes
|
||||
// to be used for SI devices we haven't emulated
|
||||
// DOES NOT FUNCTION AS "NO DEVICE INSERTED" -> Appears as unknown device
|
||||
class CSIDevice_Dummy : public ISIDevice
|
||||
// Stub class for saying nothing is attached, and not having to deal with null pointers :)
|
||||
class CSIDevice_Null : public ISIDevice
|
||||
{
|
||||
public:
|
||||
CSIDevice_Dummy(int _iDeviceNumber) :
|
||||
ISIDevice(_iDeviceNumber)
|
||||
{}
|
||||
CSIDevice_Null(int _iDeviceNumber) : ISIDevice(_iDeviceNumber) {}
|
||||
virtual ~CSIDevice_Null() {}
|
||||
|
||||
virtual ~CSIDevice_Dummy(){}
|
||||
|
||||
int RunBuffer(u8* _pBuffer, int _iLength)
|
||||
{
|
||||
// Debug logging
|
||||
ISIDevice::RunBuffer(_pBuffer, _iLength);
|
||||
|
||||
reinterpret_cast<u32*>(_pBuffer)[0] = 0x00000000;
|
||||
int RunBuffer(u8* _pBuffer, int _iLength) {
|
||||
reinterpret_cast<u32*>(_pBuffer)[0] = SI_ERROR_NO_RESPONSE;
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool GetData(u32& _Hi, u32& _Low) {DEBUG_LOG(SERIALINTERFACE, "SI DUMMY %i GetData", this->m_iDeviceNumber); return false;}
|
||||
void SendCommand(u32 _Cmd, u8 _Poll){DEBUG_LOG(SERIALINTERFACE, "SI DUMMY %i SendCommand: %08x", this->m_iDeviceNumber, _Cmd);}
|
||||
bool GetData(u32& _Hi, u32& _Low) {
|
||||
_Hi = 0x80000000;
|
||||
return true;
|
||||
}
|
||||
void SendCommand(u32 _Cmd, u8 _Poll) {}
|
||||
};
|
||||
|
||||
|
||||
@ -80,10 +72,6 @@ ISIDevice* SIDevice_Create(TSIDevices _SIDevice, int _iDeviceNumber)
|
||||
{
|
||||
switch(_SIDevice)
|
||||
{
|
||||
case SI_DUMMY:
|
||||
return new CSIDevice_Dummy(_iDeviceNumber);
|
||||
break;
|
||||
|
||||
case SI_GC_CONTROLLER:
|
||||
return new CSIDevice_GCController(_iDeviceNumber);
|
||||
break;
|
||||
@ -96,10 +84,9 @@ ISIDevice* SIDevice_Create(TSIDevices _SIDevice, int _iDeviceNumber)
|
||||
return new CSIDevice_AMBaseboard(_iDeviceNumber);
|
||||
break;
|
||||
|
||||
case SI_NONE:
|
||||
default:
|
||||
return new CSIDevice_Dummy(_iDeviceNumber);
|
||||
return new CSIDevice_Null(_iDeviceNumber);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
// Devices can reply with these, but idk if we'll ever use them...
|
||||
// Devices can reply with these
|
||||
#define SI_ERROR_NO_RESPONSE 0x0008 // Nothing is attached
|
||||
#define SI_ERROR_UNKNOWN 0x0040 // Unknown device is attached
|
||||
#define SI_ERROR_BUSY 0x0080 // Still detecting
|
||||
@ -60,7 +60,7 @@ public:
|
||||
// SI Device IDs
|
||||
enum TSIDevices
|
||||
{
|
||||
SI_DUMMY = 0,
|
||||
SI_NONE = SI_ERROR_NO_RESPONSE,
|
||||
SI_N64_MIC = 0x00010000,
|
||||
SI_N64_KEYBOARD = 0x00020000,
|
||||
SI_N64_MOUSE = 0x02000000,
|
||||
|
@ -214,6 +214,7 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||
}
|
||||
|
||||
// Keep track of the special button combos (embedded in controller hardware... :( )
|
||||
// Should technically be in "gc time", but we just use host system time :)
|
||||
EButtonCombo tempCombo;
|
||||
if ((PadStatus.button & 0xff00) == (PAD_BUTTON_Y|PAD_BUTTON_X|PAD_BUTTON_START))
|
||||
tempCombo = COMBO_ORIGIN;
|
||||
|
@ -411,7 +411,7 @@ void CConfigMain::CreateGUIControls()
|
||||
GCSIDeviceText[1] = new wxStaticText(GamecubePage, ID_GC_SIDEVICE_TEXT, wxT("Port 2"), wxDefaultPosition, wxDefaultSize);
|
||||
GCSIDeviceText[2] = new wxStaticText(GamecubePage, ID_GC_SIDEVICE_TEXT, wxT("Port 3"), wxDefaultPosition, wxDefaultSize);
|
||||
GCSIDeviceText[3] = new wxStaticText(GamecubePage, ID_GC_SIDEVICE_TEXT, wxT("Port 4"), wxDefaultPosition, wxDefaultSize);
|
||||
const wxString SIDevices[] = {wxT(DEV_DUMMY_STR),wxT(SIDEV_STDCONT_STR),wxT(SIDEV_GBA_STR),wxT(SIDEV_AM_BB_STR)};
|
||||
const wxString SIDevices[] = {wxT(DEV_NONE_STR),wxT(SIDEV_STDCONT_STR),wxT(SIDEV_GBA_STR),wxT(SIDEV_AM_BB_STR)};
|
||||
static const int numSIDevices = sizeof(SIDevices)/sizeof(wxString);
|
||||
GCSIDevice[0] = new wxChoice(GamecubePage, ID_GC_SIDEVICE0, wxDefaultPosition, wxDefaultSize, numSIDevices, SIDevices, 0, wxDefaultValidator);
|
||||
GCSIDevice[1] = new wxChoice(GamecubePage, ID_GC_SIDEVICE1, wxDefaultPosition, wxDefaultSize, numSIDevices, SIDevices, 0, wxDefaultValidator);
|
||||
@ -793,7 +793,7 @@ void CConfigMain::ChooseSIDevice(std::string deviceName, int deviceNum)
|
||||
else if (!deviceName.compare(SIDEV_AM_BB_STR))
|
||||
tempType = SI_AM_BASEBOARD;
|
||||
else
|
||||
tempType = SI_DUMMY;
|
||||
tempType = SI_NONE;
|
||||
|
||||
SConfig::GetInstance().m_SIDevice[deviceNum] = tempType;
|
||||
|
||||
|
@ -230,7 +230,7 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
|
||||
|
||||
// Better disable unused ports
|
||||
for (int i = m_numClients+1; i < 4; i++)
|
||||
SerialInterface::ChangeDevice(SI_DUMMY, i);
|
||||
SerialInterface::ChangeDevice(SI_NONE, i);
|
||||
}
|
||||
|
||||
if (m_timer.GetTimeDifference() > 1000)
|
||||
|
@ -7,7 +7,7 @@ ifeq ($(strip $(DEVKITPPC)),)
|
||||
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
|
||||
endif
|
||||
|
||||
include $(DEVKITPPC)/gamecube_rules
|
||||
include $(DEVKITPPC)/wii_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
@ -33,7 +33,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -logc -lm
|
||||
LIBS := -lfat -logc -lm
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
@ -7,28 +7,106 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <unistd.h>
|
||||
#include <fat.h>
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#endif
|
||||
|
||||
static void *xfb;
|
||||
static GXRModeObj *rmode;
|
||||
|
||||
void Initialise();
|
||||
void (*reboot)() = (void(*)())0x80001800;
|
||||
static u32* const SI_REG = (u32*)0xCD006400;
|
||||
static bool haveInit = false;
|
||||
static int counter = 0;
|
||||
static bool logWritten = false;
|
||||
|
||||
void AppendSDLog()
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
FILE *f = fopen("sd:/si_log.txt", "a");
|
||||
if (f)
|
||||
{
|
||||
fprintf(f, "\n-------------------------------------\n");
|
||||
for (int i = 0; i < 4; i++)
|
||||
fprintf(f, "%i\tstatus: %x\t type:%x\n", i, SI_GetStatus(i), SI_GetType(i));
|
||||
u32 x = 0;
|
||||
fprintf(f, "-------------------------------------\n");
|
||||
fprintf(f, "SI_CHANNEL_0_OUT\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_0_IN_HI\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_0_IN_LO\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_1_OUT\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_1_IN_HI\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_1_IN_LO\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_2_OUT\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_2_IN_HI\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_2_IN_LO\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_3_OUT\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_3_IN_HI\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_CHANNEL_3_IN_LO\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_POLL\t\t\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_COM_CSR\t\t\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_STATUS_REG\t\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "SI_EXI_CLOCK_COUNT\t%08x\n", SI_REG[x++]);
|
||||
fprintf(f, "-------------------------------------\n");
|
||||
fclose(f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Initialise();
|
||||
|
||||
while(1) {
|
||||
PAD_ScanPads();
|
||||
VIDEO_ClearFrameBuffer(rmode, xfb, 0);
|
||||
std::cout<<"\x1b[0;0H"; // Position the cursor (at 0, 0)
|
||||
if (haveInit) PAD_ScanPads();
|
||||
|
||||
VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK);
|
||||
|
||||
printf("\x1b[4;0H");
|
||||
|
||||
for(int Chan = 0; Chan < 4; Chan++)
|
||||
printf("%i\tstatus: %x\t type:%x\n", Chan, SI_GetStatus(Chan), SI_GetType(Chan));
|
||||
|
||||
printf("SI Regs: (cc006000)\n");
|
||||
for (u32 i = 0; i < 16/*num SI regs*/; ++i)
|
||||
{
|
||||
std::cout << "Chan " << Chan << std::endl;
|
||||
std::cout << "Status is " << SI_GetStatus(Chan) << std::endl;
|
||||
std::cout << "Type is 0x" << std::setbase(16) << SI_GetType(Chan) << std::setbase(10) << std::endl << std::endl;
|
||||
printf("%08x ", SI_REG[i]);
|
||||
if ((i+1)%8==0) printf("\n");
|
||||
}
|
||||
|
||||
if (haveInit)
|
||||
printf("\nPAD_Init\n");
|
||||
|
||||
VIDEO_WaitVSync();
|
||||
|
||||
if (haveInit)
|
||||
{
|
||||
if (PAD_ButtonsDown(0) & PAD_BUTTON_START)
|
||||
{
|
||||
AppendSDLog();
|
||||
#ifdef HW_RVL
|
||||
fatUnmount("sd");
|
||||
__io_wiisd.shutdown();
|
||||
#endif
|
||||
reboot();
|
||||
}
|
||||
}
|
||||
|
||||
counter++;
|
||||
AppendSDLog();
|
||||
if (counter > 5 && !haveInit)
|
||||
{
|
||||
PAD_Init();
|
||||
haveInit = true;
|
||||
}
|
||||
else if (haveInit && !logWritten)
|
||||
{
|
||||
logWritten = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -39,9 +117,6 @@ void Initialise()
|
||||
// Initialise the video system
|
||||
VIDEO_Init();
|
||||
|
||||
// This function initialises the attached controllers
|
||||
PAD_Init();
|
||||
|
||||
// Obtain the preferred video mode from the system
|
||||
// This will correspond to the settings in the Wii menu
|
||||
rmode = VIDEO_GetPreferredMode(NULL);
|
||||
@ -67,4 +142,10 @@ void Initialise()
|
||||
// Wait for Video setup to complete
|
||||
VIDEO_WaitVSync();
|
||||
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||
|
||||
#ifdef HW_RVL
|
||||
// Initialize FAT so we can write to SD.
|
||||
__io_wiisd.startup();
|
||||
fatMountSimple("sd", &__io_wiisd);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user