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:
Shawn Hoffman 2009-12-21 07:39:57 +00:00
parent c3b196541d
commit 5e7607b700
10 changed files with 217 additions and 159 deletions

View File

@ -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);

View File

@ -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();
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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
}