Begin USBGecko. Kinda works already, need to make a checkpoint before making the socket stuff better.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6865 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
4f5211cc39
commit
bc3565341d
|
@ -583,6 +583,14 @@
|
||||||
RelativePath=".\Src\HW\EXI_DeviceEthernet.h"
|
RelativePath=".\Src\HW\EXI_DeviceEthernet.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\HW\EXI_DeviceGecko.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\HW\EXI_DeviceGecko.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\Hw\EXI_DeviceIPL.cpp"
|
RelativePath=".\Src\Hw\EXI_DeviceIPL.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -233,13 +233,7 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
|
||||||
{
|
{
|
||||||
case EXI_READ: m_ImmData = pDevice->ImmRead(m_Control.TLEN + 1); break;
|
case EXI_READ: m_ImmData = pDevice->ImmRead(m_Control.TLEN + 1); break;
|
||||||
case EXI_WRITE: pDevice->ImmWrite(m_ImmData, m_Control.TLEN + 1); break;
|
case EXI_WRITE: pDevice->ImmWrite(m_ImmData, m_Control.TLEN + 1); break;
|
||||||
case EXI_READWRITE:
|
case EXI_READWRITE: pDevice->ImmReadWrite(m_ImmData, m_Control.TLEN + 1); break;
|
||||||
ERROR_LOG(SP1, "RW UNSUPPORTED");
|
|
||||||
/* Only used by USBGecko?
|
|
||||||
pDevice->ImmWrite(m_ImmData, m_Control.TLEN + 1);
|
|
||||||
m_ImmData = pDevice->ImmRead(m_Control.TLEN + 1); */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: _dbg_assert_msg_(EXPANSIONINTERFACE,0,"EXI Imm: Unknown transfer type %i", m_Control.RW);
|
default: _dbg_assert_msg_(EXPANSIONINTERFACE,0,"EXI Imm: Unknown transfer type %i", m_Control.RW);
|
||||||
}
|
}
|
||||||
m_Control.TSTART = 0;
|
m_Control.TSTART = 0;
|
||||||
|
|
|
@ -24,13 +24,14 @@
|
||||||
#include "EXI_DeviceMic.h"
|
#include "EXI_DeviceMic.h"
|
||||||
#include "EXI_DeviceEthernet.h"
|
#include "EXI_DeviceEthernet.h"
|
||||||
#include "EXI_DeviceAMBaseboard.h"
|
#include "EXI_DeviceAMBaseboard.h"
|
||||||
|
#include "EXI_DeviceGecko.h"
|
||||||
|
|
||||||
#include "../Core.h"
|
#include "../Core.h"
|
||||||
#include "../ConfigManager.h"
|
#include "../ConfigManager.h"
|
||||||
|
|
||||||
|
|
||||||
// --- interface IEXIDevice ---
|
// --- interface IEXIDevice ---
|
||||||
void IEXIDevice::ImmWrite(u32 _uData, u32 _uSize)
|
void IEXIDevice::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
{
|
{
|
||||||
while (_uSize--)
|
while (_uSize--)
|
||||||
{
|
{
|
||||||
|
@ -137,6 +138,10 @@ IEXIDevice* EXIDevice_Create(TEXIDevices _EXIDevice)
|
||||||
return new CEXIAMBaseboard();
|
return new CEXIAMBaseboard();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EXIDEVICE_GECKO:
|
||||||
|
return new CEXIGecko();
|
||||||
|
break;
|
||||||
|
|
||||||
case EXIDEVICE_NONE:
|
case EXIDEVICE_NONE:
|
||||||
default:
|
default:
|
||||||
return new IEXIDevice();
|
return new IEXIDevice();
|
||||||
|
|
|
@ -30,7 +30,8 @@ private:
|
||||||
public:
|
public:
|
||||||
// Immediate copy functions
|
// Immediate copy functions
|
||||||
virtual void ImmWrite(u32 _uData, u32 _uSize);
|
virtual void ImmWrite(u32 _uData, u32 _uSize);
|
||||||
virtual u32 ImmRead(u32 _uSize);
|
virtual u32 ImmRead(u32 _uSize);
|
||||||
|
virtual void ImmReadWrite(u32 &/*_uData*/, u32 /*_uSize*/) {}
|
||||||
|
|
||||||
// DMA copy functions
|
// DMA copy functions
|
||||||
virtual void DMAWrite(u32 _uAddr, u32 _uSize);
|
virtual void DMAWrite(u32 _uAddr, u32 _uSize);
|
||||||
|
@ -59,6 +60,7 @@ enum TEXIDevices
|
||||||
EXIDEVICE_MIC,
|
EXIDEVICE_MIC,
|
||||||
EXIDEVICE_ETH,
|
EXIDEVICE_ETH,
|
||||||
EXIDEVICE_AM_BASEBOARD,
|
EXIDEVICE_AM_BASEBOARD,
|
||||||
|
EXIDEVICE_GECKO,
|
||||||
EXIDEVICE_NONE = (u8)-1
|
EXIDEVICE_NONE = (u8)-1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "EXI_Device.h"
|
||||||
|
#include "EXI_DeviceGecko.h"
|
||||||
|
|
||||||
|
#include "SFML/Network.hpp"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
static Common::Thread *connectionThread = NULL;
|
||||||
|
static std::queue<sf::SocketTCP> waiting_socks;
|
||||||
|
static Common::CriticalSection cs_gecko;
|
||||||
|
namespace { volatile bool server_running; }
|
||||||
|
|
||||||
|
static THREAD_RETURN GeckoConnectionWaiter(void*)
|
||||||
|
{
|
||||||
|
server_running = true;
|
||||||
|
|
||||||
|
Common::SetCurrentThreadName("Gecko Connection Waiter");
|
||||||
|
|
||||||
|
sf::SocketTCP server;
|
||||||
|
// "dolphin gecko"
|
||||||
|
if (!server.Listen(0xd6ec))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
server.SetBlocking(false);
|
||||||
|
|
||||||
|
sf::SocketTCP new_client;
|
||||||
|
while (server_running)
|
||||||
|
{
|
||||||
|
if (server.Accept(new_client) == sf::Socket::Done)
|
||||||
|
{
|
||||||
|
cs_gecko.Enter();
|
||||||
|
waiting_socks.push(new_client);
|
||||||
|
cs_gecko.Leave();
|
||||||
|
}
|
||||||
|
SLEEP(1);
|
||||||
|
}
|
||||||
|
server.Close();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeckoConnectionWaiter_Shutdown()
|
||||||
|
{
|
||||||
|
server_running = false;
|
||||||
|
if (connectionThread)
|
||||||
|
{
|
||||||
|
connectionThread->WaitForDeath();
|
||||||
|
delete connectionThread;
|
||||||
|
connectionThread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
|
||||||
|
{
|
||||||
|
bool sock_filled = false;
|
||||||
|
|
||||||
|
cs_gecko.Enter();
|
||||||
|
if (waiting_socks.size())
|
||||||
|
{
|
||||||
|
sock_to_fill = waiting_socks.front();
|
||||||
|
waiting_socks.pop();
|
||||||
|
sock_filled = true;
|
||||||
|
}
|
||||||
|
cs_gecko.Leave();
|
||||||
|
|
||||||
|
return sock_filled;
|
||||||
|
}
|
||||||
|
|
||||||
|
GeckoSockServer::GeckoSockServer()
|
||||||
|
{
|
||||||
|
if (!connectionThread)
|
||||||
|
connectionThread = new Common::Thread(GeckoConnectionWaiter, (void*)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GeckoSockServer::~GeckoSockServer()
|
||||||
|
{
|
||||||
|
client.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
CEXIGecko::CEXIGecko()
|
||||||
|
: m_uPosition(0)
|
||||||
|
, recv_fifo(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIGecko::SetCS(int cs)
|
||||||
|
{
|
||||||
|
if (cs)
|
||||||
|
m_uPosition = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CEXIGecko::IsPresent()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIGecko::ImmReadWrite(u32 &_uData, u32 _uSize)
|
||||||
|
{
|
||||||
|
if (!client.IsValid())
|
||||||
|
if (!GetAvailableSock(client))
|
||||||
|
;// TODO nothing for now
|
||||||
|
|
||||||
|
// for debug
|
||||||
|
u32 oldval = _uData;
|
||||||
|
// TODO do we really care about _uSize?
|
||||||
|
|
||||||
|
u8 data = 0;
|
||||||
|
std::size_t got;
|
||||||
|
|
||||||
|
switch (_uData >> 28)
|
||||||
|
{
|
||||||
|
// maybe do something fun later
|
||||||
|
case CMD_LED_OFF:
|
||||||
|
break;
|
||||||
|
case CMD_LED_ON:
|
||||||
|
break;
|
||||||
|
// maybe should only | 2bytes?
|
||||||
|
case CMD_INIT:
|
||||||
|
_uData = ident;
|
||||||
|
break;
|
||||||
|
// PC -> Gecko
|
||||||
|
case CMD_RECV:
|
||||||
|
// TODO recv
|
||||||
|
client.Receive((char*)&data, sizeof(data), got);
|
||||||
|
recv_fifo = !!got;
|
||||||
|
if (recv_fifo)
|
||||||
|
_uData = 0x08000000 | (data << 16);
|
||||||
|
break;
|
||||||
|
// Gecko -> PC
|
||||||
|
case CMD_SEND:
|
||||||
|
data = (_uData >> 20) & 0xff;
|
||||||
|
// TODO send
|
||||||
|
client.Send((char*)&data, sizeof(data));
|
||||||
|
// If successful
|
||||||
|
_uData |= 0x04000000;
|
||||||
|
break;
|
||||||
|
// Check if ok for Gecko -> PC, or FIFO full
|
||||||
|
// |= 0x04000000 if FIFO is not full
|
||||||
|
case CMD_CHK_TX:
|
||||||
|
_uData = 0x04000000;
|
||||||
|
break;
|
||||||
|
// Check if data in FIFO for PC -> Gecko, or FIFO empty
|
||||||
|
// |= 0x04000000 if data in recv FIFO
|
||||||
|
case CMD_CHK_RX:
|
||||||
|
//_uData = recv_fifo ? 0x04000000 : 0;
|
||||||
|
_uData = 0x04000000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR_LOG(EXPANSIONINTERFACE, "Uknown USBGecko command %x", _uData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_uData) { ERROR_LOG(EXPANSIONINTERFACE, "rw %x %08x %08x", oldval, _uData, _uSize); }
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#ifndef _EXIDEVICE_GECKO_H
|
||||||
|
#define _EXIDEVICE_GECKO_H
|
||||||
|
|
||||||
|
#include "SFML/Network.hpp"
|
||||||
|
|
||||||
|
class GeckoSockServer
|
||||||
|
: public sf::SocketTCP
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeckoSockServer();
|
||||||
|
~GeckoSockServer();
|
||||||
|
|
||||||
|
//private:
|
||||||
|
sf::SocketTCP client;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CEXIGecko
|
||||||
|
: public IEXIDevice
|
||||||
|
, private GeckoSockServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CEXIGecko();
|
||||||
|
void SetCS(int _iCS);
|
||||||
|
bool IsPresent();
|
||||||
|
void ImmReadWrite(u32 &_uData, u32 _uSize);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CMD_LED_OFF = 0x7,
|
||||||
|
CMD_LED_ON = 0x8,
|
||||||
|
CMD_INIT = 0x9,
|
||||||
|
CMD_RECV = 0xa,
|
||||||
|
CMD_SEND = 0xb,
|
||||||
|
CMD_CHK_TX = 0xc,
|
||||||
|
CMD_CHK_RX = 0xd,
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 m_uPosition;
|
||||||
|
bool recv_fifo;
|
||||||
|
|
||||||
|
static const u32 ident = 0x04700000;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
static Common::Thread *connectionThread = NULL;
|
static Common::Thread *connectionThread = NULL;
|
||||||
static std::queue<sf::SocketTCP> waiting_socks;
|
static std::queue<sf::SocketTCP> waiting_socks;
|
||||||
static Common::CriticalSection cs_gba;
|
static Common::CriticalSection cs_gba;
|
||||||
volatile bool server_running;
|
namespace { volatile bool server_running; }
|
||||||
|
|
||||||
// --- GameBoy Advance "Link Cable" ---
|
// --- GameBoy Advance "Link Cable" ---
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ THREAD_RETURN GBAConnectionWaiter(void*)
|
||||||
Common::SetCurrentThreadName("GBA Connection Waiter");
|
Common::SetCurrentThreadName("GBA Connection Waiter");
|
||||||
|
|
||||||
sf::SocketTCP server;
|
sf::SocketTCP server;
|
||||||
|
// "dolphin gba"
|
||||||
if (!server.Listen(0xd6ba))
|
if (!server.Listen(0xd6ba))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -101,11 +102,8 @@ void GBASockServer::Transfer(char* si_buffer)
|
||||||
if (!GetAvailableSock(client))
|
if (!GetAvailableSock(client))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
current_data[0] = si_buffer[3];
|
for (int i = 0; i < 5; i++)
|
||||||
current_data[1] = si_buffer[2];
|
current_data[i] = si_buffer[i ^ 3];
|
||||||
current_data[2] = si_buffer[1];
|
|
||||||
current_data[3] = si_buffer[0];
|
|
||||||
current_data[4] = si_buffer[7];
|
|
||||||
|
|
||||||
u8 cmd = *current_data;
|
u8 cmd = *current_data;
|
||||||
|
|
||||||
|
@ -138,11 +136,8 @@ void GBASockServer::Transfer(char* si_buffer)
|
||||||
(unsigned int)num_received, (unsigned int)num_expecting);
|
(unsigned int)num_received, (unsigned int)num_expecting);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
si_buffer[0] = current_data[3];
|
for (int i = 0; i < 5; i++)
|
||||||
si_buffer[1] = current_data[2];
|
si_buffer[i ^ 3] = current_data[i];
|
||||||
si_buffer[2] = current_data[1];
|
|
||||||
si_buffer[3] = current_data[0];
|
|
||||||
si_buffer[7] = current_data[4];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSIDevice_GBA::CSIDevice_GBA(int _iDeviceNumber)
|
CSIDevice_GBA::CSIDevice_GBA(int _iDeviceNumber)
|
||||||
|
|
|
@ -75,6 +75,7 @@ static const wxLanguage langIds[] =
|
||||||
#define EXIDEV_MIC_STR _trans("Mic")
|
#define EXIDEV_MIC_STR _trans("Mic")
|
||||||
#define EXIDEV_BBA_STR "BBA"
|
#define EXIDEV_BBA_STR "BBA"
|
||||||
#define EXIDEV_AM_BB_STR _trans("AM-Baseboard")
|
#define EXIDEV_AM_BB_STR _trans("AM-Baseboard")
|
||||||
|
#define EXIDEV_GECKO_STR "USBGecko"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
//only used with xgettext to be picked up as translatable string.
|
//only used with xgettext to be picked up as translatable string.
|
||||||
|
@ -564,7 +565,7 @@ void CConfigMain::CreateGUIControls()
|
||||||
GCEXIDeviceText[0] = new wxStaticText(GamecubePage, ID_GC_EXIDEVICE_SLOTA_TEXT, wxT("Slot A"), wxDefaultPosition, wxDefaultSize);
|
GCEXIDeviceText[0] = new wxStaticText(GamecubePage, ID_GC_EXIDEVICE_SLOTA_TEXT, wxT("Slot A"), wxDefaultPosition, wxDefaultSize);
|
||||||
GCEXIDeviceText[1] = new wxStaticText(GamecubePage, ID_GC_EXIDEVICE_SLOTB_TEXT, wxT("Slot B"), wxDefaultPosition, wxDefaultSize);
|
GCEXIDeviceText[1] = new wxStaticText(GamecubePage, ID_GC_EXIDEVICE_SLOTB_TEXT, wxT("Slot B"), wxDefaultPosition, wxDefaultSize);
|
||||||
GCEXIDeviceText[2] = new wxStaticText(GamecubePage, ID_GC_EXIDEVICE_SP1_TEXT, wxT("SP1 "), wxDefaultPosition, wxDefaultSize);
|
GCEXIDeviceText[2] = new wxStaticText(GamecubePage, ID_GC_EXIDEVICE_SP1_TEXT, wxT("SP1 "), wxDefaultPosition, wxDefaultSize);
|
||||||
const wxString SlotDevices[] = {_(DEV_NONE_STR), _(DEV_DUMMY_STR), _(EXIDEV_MEMCARD_STR)
|
const wxString SlotDevices[] = {_(DEV_NONE_STR), _(DEV_DUMMY_STR), _(EXIDEV_MEMCARD_STR), _(EXIDEV_GECKO_STR)
|
||||||
#if HAVE_PORTAUDIO
|
#if HAVE_PORTAUDIO
|
||||||
, _(EXIDEV_MIC_STR)
|
, _(EXIDEV_MIC_STR)
|
||||||
#endif
|
#endif
|
||||||
|
@ -591,7 +592,7 @@ void CConfigMain::CreateGUIControls()
|
||||||
isMemcard = GCEXIDevice[i]->SetStringSelection(SlotDevices[2]);
|
isMemcard = GCEXIDevice[i]->SetStringSelection(SlotDevices[2]);
|
||||||
break;
|
break;
|
||||||
case EXIDEVICE_MIC:
|
case EXIDEVICE_MIC:
|
||||||
GCEXIDevice[i]->SetStringSelection(SlotDevices[3]);
|
GCEXIDevice[i]->SetStringSelection(SlotDevices[4]);
|
||||||
break;
|
break;
|
||||||
case EXIDEVICE_ETH:
|
case EXIDEVICE_ETH:
|
||||||
GCEXIDevice[i]->SetStringSelection(SP1Devices[2]);
|
GCEXIDevice[i]->SetStringSelection(SP1Devices[2]);
|
||||||
|
@ -599,6 +600,9 @@ void CConfigMain::CreateGUIControls()
|
||||||
case EXIDEVICE_AM_BASEBOARD:
|
case EXIDEVICE_AM_BASEBOARD:
|
||||||
GCEXIDevice[i]->SetStringSelection(SP1Devices[3]);
|
GCEXIDevice[i]->SetStringSelection(SP1Devices[3]);
|
||||||
break;
|
break;
|
||||||
|
case EXIDEVICE_GECKO:
|
||||||
|
GCEXIDevice[i]->SetStringSelection(SlotDevices[3]);
|
||||||
|
break;
|
||||||
case EXIDEVICE_DUMMY:
|
case EXIDEVICE_DUMMY:
|
||||||
default:
|
default:
|
||||||
GCEXIDevice[i]->SetStringSelection(SlotDevices[1]);
|
GCEXIDevice[i]->SetStringSelection(SlotDevices[1]);
|
||||||
|
@ -1039,6 +1043,8 @@ void CConfigMain::ChooseEXIDevice(std::string deviceName, int deviceNum)
|
||||||
tempType = EXIDEVICE_ETH;
|
tempType = EXIDEVICE_ETH;
|
||||||
else if (!deviceName.compare(EXIDEV_AM_BB_STR))
|
else if (!deviceName.compare(EXIDEV_AM_BB_STR))
|
||||||
tempType = EXIDEVICE_AM_BASEBOARD;
|
tempType = EXIDEVICE_AM_BASEBOARD;
|
||||||
|
else if (!deviceName.compare(EXIDEV_GECKO_STR))
|
||||||
|
tempType = EXIDEVICE_GECKO;
|
||||||
else if (!deviceName.compare(DEV_NONE_STR))
|
else if (!deviceName.compare(DEV_NONE_STR))
|
||||||
tempType = EXIDEVICE_NONE;
|
tempType = EXIDEVICE_NONE;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue