code style cleanup for bba which has been sitting around my hdd for a long time

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3944 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2009-08-06 23:08:18 +00:00
parent fa731c0b29
commit 5013ab957c
4 changed files with 318 additions and 251 deletions

View File

@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include <assert.h> #include <assert.h>
#include "StringUtil.h"
#include "../Memmap.h" #include "../Memmap.h"
// GROSS CODE ALERT: headers need to be included in the following order // GROSS CODE ALERT: headers need to be included in the following order
#include "TAP_Win32.h" #include "TAP_Win32.h"
@ -162,16 +163,17 @@ bool GetGUID(char *name, int name_size)
bool CEXIETHERNET::deactivate() bool CEXIETHERNET::deactivate()
{ {
DEBUGPRINT("Deactivating BBA...\n"); DEBUGPRINT("Deactivating BBA...");
if(!isActivated()) if (!isActivated())
return true; return true;
CloseHandle(mHRecvEvent); CloseHandle(mHRecvEvent);
mHRecvEvent = INVALID_HANDLE_VALUE; mHRecvEvent = INVALID_HANDLE_VALUE;
CloseHandle(mHAdapter); CloseHandle(mHAdapter);
mHAdapter = INVALID_HANDLE_VALUE; mHAdapter = INVALID_HANDLE_VALUE;
DEBUGPRINT("Success!\n"); DEBUGPRINT("Success!");
return true; return true;
} }
bool CEXIETHERNET::isActivated() bool CEXIETHERNET::isActivated()
{ {
return mHAdapter != INVALID_HANDLE_VALUE; return mHAdapter != INVALID_HANDLE_VALUE;
@ -179,11 +181,10 @@ bool CEXIETHERNET::isActivated()
bool CEXIETHERNET::activate() bool CEXIETHERNET::activate()
{ {
if (isActivated()) if (isActivated())
return true; return true;
DEBUGPRINT("\nActivating BBA...\n"); DEBUGPRINT("Activating BBA...");
DWORD len; DWORD len;
char device_path[256]; char device_path[256];
@ -209,7 +210,7 @@ bool CEXIETHERNET::activate()
if (mHAdapter == INVALID_HANDLE_VALUE) if (mHAdapter == INVALID_HANDLE_VALUE)
{ {
DEBUGPRINT("Failed to open TAP at %s\n", device_path); DEBUGPRINT("Failed to open TAP at %s", device_path);
return false; return false;
} }
@ -219,14 +220,14 @@ bool CEXIETHERNET::activate()
if (DeviceIoControl (mHAdapter, TAP_IOCTL_GET_VERSION, if (DeviceIoControl (mHAdapter, TAP_IOCTL_GET_VERSION,
&info, sizeof (info), &info, sizeof (info), &len, NULL)) &info, sizeof (info), &info, sizeof (info), &len, NULL))
{ {
DEBUGPRINT("TAP-Win32 Driver Version %d.%d %s\n", DEBUGPRINT("TAP-Win32 Driver Version %d.%d %s",
info[0], info[1], (info[2] ? "(DEBUG)" : "")); info[0], info[1], (info[2] ? "(DEBUG)" : ""));
} }
if ( !(info[0] > TAP_WIN32_MIN_MAJOR if ( !(info[0] > TAP_WIN32_MIN_MAJOR
|| (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)) ) || (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)) )
{ {
#define PACKAGE_NAME "Dolphin" #define PACKAGE_NAME "Dolphin"
DEBUGPRINT("ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.\n", DEBUGPRINT("ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
TAP_WIN32_MIN_MAJOR, TAP_WIN32_MIN_MAJOR,
TAP_WIN32_MIN_MINOR); TAP_WIN32_MIN_MINOR);
return false; return false;
@ -235,13 +236,13 @@ bool CEXIETHERNET::activate()
/* get driver MTU */ /* get driver MTU */
{ {
if(!DeviceIoControl(mHAdapter, TAP_IOCTL_GET_MTU, if (!DeviceIoControl(mHAdapter, TAP_IOCTL_GET_MTU,
&mMtu, sizeof (mMtu), &mMtu, sizeof (mMtu), &len, NULL)) &mMtu, sizeof (mMtu), &mMtu, sizeof (mMtu), &len, NULL))
{ {
DEBUGPRINT("Couldn't get device MTU"); DEBUGPRINT("Couldn't get device MTU");
return false; return false;
} }
DEBUGPRINT("TAP-Win32 MTU=%d (ignored)\n", mMtu); DEBUGPRINT("TAP-Win32 MTU=%d (ignored)", mMtu);
} }
/* set driver media status to 'connected' */ /* set driver media status to 'connected' */
@ -250,12 +251,12 @@ bool CEXIETHERNET::activate()
if (!DeviceIoControl (mHAdapter, TAP_IOCTL_SET_MEDIA_STATUS, if (!DeviceIoControl (mHAdapter, TAP_IOCTL_SET_MEDIA_STATUS,
&status, sizeof (status), &status, sizeof (status), &len, NULL)) &status, sizeof (status), &status, sizeof (status), &len, NULL))
{ {
DEBUGPRINT("WARNING: The TAP-Win32 driver rejected a TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.\n"); DEBUGPRINT("WARNING: The TAP-Win32 driver rejected a TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
return false; return false;
} }
else else
{ {
DEBUGPRINT("TAP-WIN32 status as Connected\n"); DEBUGPRINT("TAP-WIN32 status as Connected");
} }
} }
@ -264,54 +265,55 @@ bool CEXIETHERNET::activate()
memset((void*)&mReadOverlapped, 0 , sizeof(mReadOverlapped)); memset((void*)&mReadOverlapped, 0 , sizeof(mReadOverlapped));
resume(); resume();
DEBUGPRINT("Success!\n\n"); DEBUGPRINT("Success!");
return true; return true;
//TODO: Activate Device! //TODO: Activate Device!
} }
bool CEXIETHERNET::CheckRecieved() bool CEXIETHERNET::CheckRecieved()
{ {
if(!isActivated()) if (!isActivated())
return false; return false;
// I have no idea o_O // I have no idea o_O
return false; return false;
} }
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size) bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
{ {
if(!isActivated()) if (!isActivated())
activate(); activate();
DEBUGPRINT( "Packet: 0x");
for(int a = 0; a < size; ++a) DEBUGPRINT("Packet (%i): %s", size, ArrayToString(etherpckt, size).c_str());
{
DEBUGPRINT( "%02X", etherpckt[a]);
}
DEBUGPRINT( " : Size: %d\n", size);
DWORD numBytesWrit; DWORD numBytesWrit;
OVERLAPPED overlap; OVERLAPPED overlap;
memset((void*)&overlap, 0, sizeof(overlap)); memset((void*)&overlap, 0, sizeof(overlap));
//ZERO_OBJECT(overlap); //ZERO_OBJECT(overlap);
//overlap.hEvent = mHRecvEvent; //overlap.hEvent = mHRecvEvent;
if(!WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap)) if (!WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap))
{ // Fail Boat
DWORD res = GetLastError();
DEBUGPRINT("Failed to send packet with error 0x%X\n", res);
}
if(numBytesWrit != size)
{ {
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit); // Fail Boat
DWORD res = GetLastError();
DEBUGPRINT("Failed to send packet with error 0x%X", res);
}
if (numBytesWrit != size)
{
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!", size, numBytesWrit);
return false; return false;
} }
recordSendComplete(); recordSendComplete();
//exit(0); //exit(0);
return true; return true;
} }
bool CEXIETHERNET::handleRecvdPacket() bool CEXIETHERNET::handleRecvdPacket()
{ {
int rbwpp = mCbw.p_write() + CB_OFFSET; //read buffer write page pointer int rbwpp = mCbw.p_write() + CB_OFFSET; //read buffer write page pointer
u32 available_bytes_in_cb; u32 available_bytes_in_cb;
if(rbwpp < mRBRPP) if (rbwpp < mRBRPP)
available_bytes_in_cb = mRBRPP - rbwpp; available_bytes_in_cb = mRBRPP - rbwpp;
else if(rbwpp == mRBRPP) else if (rbwpp == mRBRPP)
available_bytes_in_cb = mRBEmpty ? CB_SIZE : 0; available_bytes_in_cb = mRBEmpty ? CB_SIZE : 0;
else //rbwpp > mRBRPP else //rbwpp > mRBRPP
available_bytes_in_cb = CB_SIZE - rbwpp + (mRBRPP - CB_OFFSET); available_bytes_in_cb = CB_SIZE - rbwpp + (mRBRPP - CB_OFFSET);
@ -321,7 +323,7 @@ bool CEXIETHERNET::handleRecvdPacket()
//DUMPWORD(available_bytes_in_cb); //DUMPWORD(available_bytes_in_cb);
assert(available_bytes_in_cb <= CB_SIZE); assert(available_bytes_in_cb <= CB_SIZE);
if(available_bytes_in_cb != CB_SIZE)//< mRecvBufferLength + SIZEOF_RECV_DESCRIPTOR) if (available_bytes_in_cb != CB_SIZE)//< mRecvBufferLength + SIZEOF_RECV_DESCRIPTOR)
return true; return true;
cbwriteDescriptor(mRecvBufferLength); cbwriteDescriptor(mRecvBufferLength);
mCbw.write(mRecvBuffer, mRecvBufferLength); mCbw.write(mRecvBuffer, mRecvBufferLength);
@ -332,69 +334,94 @@ bool CEXIETHERNET::handleRecvdPacket()
//mPacketsRcvd++; //mPacketsRcvd++;
mRecvBufferLength = 0; mRecvBufferLength = 0;
if(mBbaMem[0x08] & BBA_INTERRUPT_RECV) if (mBbaMem[0x08] & BBA_INTERRUPT_RECV)
{ {
if(!(mBbaMem[0x09] & BBA_INTERRUPT_RECV)) if (!(mBbaMem[0x09] & BBA_INTERRUPT_RECV))
{ {
mBbaMem[0x09] |= BBA_INTERRUPT_RECV; mBbaMem[0x09] |= BBA_INTERRUPT_RECV;
DEBUGPRINT("BBA Recv interrupt raised\n"); DEBUGPRINT("BBA Recv interrupt raised");
//interrupt.raiseEXI("BBA Recv"); //interrupt.raiseEXI("BBA Recv");
m_bInterruptSet = true; m_bInterruptSet = true;
} }
} }
if(mBbaMem[BBA_NCRA] & BBA_NCRA_SR) if (mBbaMem[BBA_NCRA] & BBA_NCRA_SR)
{
startRecv(); startRecv();
return true;
}
bool CEXIETHERNET::resume()
{
if(!isActivated())
return true;
DEBUGPRINT("BBA resume");
//mStop = false;
RegisterWaitForSingleObject(&mHReadWait, mHRecvEvent, ReadWaitCallback,
this, INFINITE, WT_EXECUTEDEFAULT);//WT_EXECUTEINWAITTHREAD
mReadOverlapped.hEvent = mHRecvEvent;
if (mBbaMem[BBA_NCRA] & BBA_NCRA_SR)
startRecv();
DEBUGPRINT("BBA resume complete");
return true;
}
bool CEXIETHERNET::startRecv()
{
if (!isActivated())
return false;// Should actually be an assert
DEBUGPRINT("startRecv... ");
if (mWaiting)
{
DEBUGPRINT("already waiting");
return true;
}
DWORD res = ReadFile(mHAdapter, mRecvBuffer, mRecvBuffer.size(),
&mRecvBufferLength, &mReadOverlapped);
if (res)
{
// Operation completed immediately
DEBUGPRINT("completed, res %i", res);
mWaiting = true;
}
else
{
res = GetLastError();
if (res == ERROR_IO_PENDING)
{
//'s ok :)
DEBUGPRINT("pending");
// WaitCallback will be called
mWaiting = true;
}
else
{
// error occurred
return false;
}
} }
return true; return true;
} }
bool CEXIETHERNET::resume() {
if(!isActivated()) VOID CALLBACK CEXIETHERNET::ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired)
return true; {
DEBUGPRINT("BBA resume\n");
//mStop = false;
RegisterWaitForSingleObject(&mHReadWait, mHRecvEvent, ReadWaitCallback,
this, INFINITE, WT_EXECUTEDEFAULT);//WT_EXECUTEINWAITTHREAD
mReadOverlapped.hEvent = mHRecvEvent;
if(mBbaMem[BBA_NCRA] & BBA_NCRA_SR) {
startRecv();
}
DEBUGPRINT("BBA resume complete\n");
return true;
}
bool CEXIETHERNET::startRecv() {
if(!isActivated())
return false;// Should actually be an assert
DEBUGPRINT("startRecv... ");
if(mWaiting) {
DEBUGPRINT("already waiting\n");
return true;
}
DWORD res = ReadFile(mHAdapter, mRecvBuffer, mRecvBuffer.size(),
&mRecvBufferLength, &mReadOverlapped);
if(res) { //Operation completed immediately
DEBUGPRINT("completed, res %i\n", res);
mWaiting = true;
} else {
res = GetLastError();
if (res == ERROR_IO_PENDING) { //'s ok :)
DEBUGPRINT("pending\n");
//WaitCallback will be called
mWaiting = true;
} else { //error occurred
return false;
}
}
return true;
}
VOID CALLBACK CEXIETHERNET::ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired) {
static int sNumber = 0; static int sNumber = 0;
int cNumber = sNumber++; int cNumber = sNumber++;
DEBUGPRINT("WaitCallback %i\n", cNumber); DEBUGPRINT("WaitCallback %i", cNumber);
if(TimerFired)
if (TimerFired)
return; return;
CEXIETHERNET* self = (CEXIETHERNET*)lpParameter; CEXIETHERNET* self = (CEXIETHERNET*)lpParameter;
if(self->mHAdapter == INVALID_HANDLE_VALUE) if(self->mHAdapter == INVALID_HANDLE_VALUE)
return; return;
@ -402,33 +429,38 @@ VOID CALLBACK CEXIETHERNET::ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFir
&self->mRecvBufferLength, false); &self->mRecvBufferLength, false);
self->mWaiting = false; self->mWaiting = false;
self->handleRecvdPacket(); self->handleRecvdPacket();
DEBUGPRINT("WaitCallback %i done\n", cNumber); DEBUGPRINT("WaitCallback %i done", cNumber);
} }
union bba_descr {
union bba_descr
{
struct { u32 next_packet_ptr:12, packet_len:12, status:8; }; struct { u32 next_packet_ptr:12, packet_len:12, status:8; };
u32 word; u32 word;
}; };
bool CEXIETHERNET::cbwriteDescriptor(u32 size) {
bool CEXIETHERNET::cbwriteDescriptor(u32 size)
{
//if(size < 0x3C) {//60 //if(size < 0x3C) {//60
#define ETHERNET_HEADER_SIZE 0xE #define ETHERNET_HEADER_SIZE 0xE
if(size < ETHERNET_HEADER_SIZE) if (size < ETHERNET_HEADER_SIZE)
{ {
DEBUGPRINT("Packet too small: %i bytes\n", size); DEBUGPRINT("Packet too small: %i bytes", size);
return false; return false;
} }
size += SIZEOF_RECV_DESCRIPTOR; //The descriptor supposed to include the size of itself // The descriptor supposed to include the size of itself
size += SIZEOF_RECV_DESCRIPTOR;
//We should probably not implement wraparound here, //We should probably not implement wraparound here,
//since neither tmbinc, riptool.dol, or libogc does... //since neither tmbinc, riptool.dol, or libogc does...
if(mCbw.p_write() + SIZEOF_RECV_DESCRIPTOR >= CB_SIZE) if (mCbw.p_write() + SIZEOF_RECV_DESCRIPTOR >= CB_SIZE)
{ {
DEBUGPRINT("The descriptor won't fit\n"); DEBUGPRINT("The descriptor won't fit");
return false; return false;
} }
if(size >= CB_SIZE) if (size >= CB_SIZE)
{ {
DEBUGPRINT("Packet too big: %i bytes\n", size); DEBUGPRINT("Packet too big: %i bytes", size);
return false; return false;
} }
@ -437,7 +469,7 @@ bool CEXIETHERNET::cbwriteDescriptor(u32 size) {
descr.packet_len = size; descr.packet_len = size;
descr.status = 0; descr.status = 0;
u32 npp; u32 npp;
if(mCbw.p_write() + size < CB_SIZE) if (mCbw.p_write() + size < CB_SIZE)
{ {
npp = mCbw.p_write() + size + CB_OFFSET; npp = mCbw.p_write() + size + CB_OFFSET;
} }
@ -445,15 +477,19 @@ bool CEXIETHERNET::cbwriteDescriptor(u32 size) {
{ {
npp = mCbw.p_write() + size + CB_OFFSET - CB_SIZE; npp = mCbw.p_write() + size + CB_OFFSET - CB_SIZE;
} }
npp = (npp + 0xff) & ~0xff; npp = (npp + 0xff) & ~0xff;
if(npp >= CB_SIZE + CB_OFFSET)
if (npp >= CB_SIZE + CB_OFFSET)
npp -= CB_SIZE; npp -= CB_SIZE;
descr.next_packet_ptr = npp >> 8; descr.next_packet_ptr = npp >> 8;
//DWORD swapped = swapw(descr.word); //DWORD swapped = swapw(descr.word);
//next_packet_ptr:12, packet_len:12, status:8; //next_packet_ptr:12, packet_len:12, status:8;
DEBUGPRINT("Writing descriptor 0x%08X @ 0x%04X: next 0x%03X len 0x%03X status 0x%02X\n", DEBUGPRINT("Writing descriptor 0x%08X @ 0x%04X: next 0x%03X len 0x%03X status 0x%02X",
descr.word, mCbw.p_write() + CB_OFFSET, descr.next_packet_ptr, descr.word, mCbw.p_write() + CB_OFFSET, descr.next_packet_ptr,
descr.packet_len, descr.status); descr.packet_len, descr.status);
mCbw.write(&descr.word, SIZEOF_RECV_DESCRIPTOR); mCbw.write(&descr.word, SIZEOF_RECV_DESCRIPTOR);
return true; return true;

View File

@ -23,22 +23,22 @@
#include "EXI_Device.h" #include "EXI_Device.h"
#include "EXI_DeviceEthernet.h" #include "EXI_DeviceEthernet.h"
#define SONICDEBUG //#define SONICDEBUG
#define FILEDEBUG #define FILEDEBUG
#ifdef FILEDEBUG #ifdef FILEDEBUG
FILE *ME = 0; FILE *ME = 0;
#endif #endif
void DEBUGPRINT (const char * format, ...) void DEBUGPRINT (const char * format, ...)
{ {
char buffer[256]; char buffer[0x1000];
va_list args; va_list args;
va_start (args, format); va_start (args, format);
vsprintf (buffer,format, args); vsprintf (buffer,format, args);
#ifdef SONICDEBUG #ifdef SONICDEBUG
#ifdef FILEDEBUG #ifdef FILEDEBUG
fprintf(ME, "%s", buffer); fprintf(ME, "%s\n", buffer);
#endif #endif
printf("%s", buffer); printf("%s\n", buffer);
#else #else
INFO_LOG(SP1, buffer); INFO_LOG(SP1, buffer);
#endif #endif
@ -53,12 +53,7 @@ void DEBUGPRINT (const char * format, ...)
int mPacketsSent = 0; int mPacketsSent = 0;
u8 mac_address[6] = {0x00, 0x1A, 0x4D, 0x5E, 0x64, 0x2B}; // Looks Appropriate u8 mac_address[6] = {0x00, 0x1A, 0x4D, 0x5E, 0x64, 0x2B}; // Looks Appropriate
unsigned int Expecting; unsigned int Expecting;
CEXIETHERNET::~CEXIETHERNET()
{
#ifdef FILEDEBUG
fclose(ME);
#endif
}
CEXIETHERNET::CEXIETHERNET() : CEXIETHERNET::CEXIETHERNET() :
m_uPosition(0), m_uPosition(0),
m_uCommand(0), m_uCommand(0),
@ -90,12 +85,21 @@ CEXIETHERNET::CEXIETHERNET() :
ME = fopen("Debug.txt", "wb"); ME = fopen("Debug.txt", "wb");
#endif #endif
} }
CEXIETHERNET::~CEXIETHERNET()
{
#ifdef FILEDEBUG
fclose(ME);
#endif
}
void CyclicBufferWriter::write(void *src, size_t size) void CyclicBufferWriter::write(void *src, size_t size)
{ {
assert(size < _cap); assert(size < _cap);
u8* bsrc = (u8*) src; u8* bsrc = (u8*) src;
if(_write + size >= _cap) if(_write + size >= _cap)
{ //wraparound {
// wraparound
memcpy(_buffer + _write, src, _cap - _write); memcpy(_buffer + _write, src, _cap - _write);
memcpy(_buffer, bsrc + (_cap - _write), size - (_cap - _write)); memcpy(_buffer, bsrc + (_cap - _write), size - (_cap - _write));
_write = size - (_cap - _write); _write = size - (_cap - _write);
@ -105,17 +109,19 @@ void CyclicBufferWriter::write(void *src, size_t size)
memcpy(_buffer + _write, src, size); memcpy(_buffer + _write, src, size);
_write += size; _write += size;
} }
//DEGUB("CBWrote %i bytes\n", size); //DEGUB("CBWrote %i bytes", size);
} }
void CyclicBufferWriter::align() void CyclicBufferWriter::align()
{ {
_write = (_write + 0xff) & ~0xff; _write = (_write + 0xff) & ~0xff;
if(_write >= _cap) if(_write >= _cap)
_write -= _cap; _write -= _cap;
} }
void CEXIETHERNET::SetCS(int cs) void CEXIETHERNET::SetCS(int cs)
{ {
DEBUGPRINT("Set CS: %s Expect Variable write?: %s\n", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false"); DEBUGPRINT("Set CS: %s Expect Variable write?: %s", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false");
if (!cs) if (!cs)
{ {
if (mExpectVariableLengthImmWrite) if (mExpectVariableLengthImmWrite)
@ -140,6 +146,7 @@ void CEXIETHERNET::Update()
{ {
return; return;
} }
bool CEXIETHERNET::IsInterruptSet() bool CEXIETHERNET::IsInterruptSet()
{ {
//bool Temp = m_bInterruptSet; //bool Temp = m_bInterruptSet;
@ -154,7 +161,7 @@ void CEXIETHERNET::recordSendComplete()
if(mBbaMem[BBA_IMR] & BBA_INTERRUPT_SENT) if(mBbaMem[BBA_IMR] & BBA_INTERRUPT_SENT)
{ {
mBbaMem[BBA_IR] |= BBA_INTERRUPT_SENT; mBbaMem[BBA_IR] |= BBA_INTERRUPT_SENT;
DEBUGPRINT( "\t\tBBA Send interrupt raised\n"); DEBUGPRINT("\t\tBBA Send interrupt raised");
//exit(0); //exit(0);
m_bInterruptSet = true; m_bInterruptSet = true;
//interrupt.raiseEXI("BBA Send"); //interrupt.raiseEXI("BBA Send");
@ -171,13 +178,13 @@ bool CEXIETHERNET::checkRecvBuffer()
} }
return true; return true;
} }
void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
{ {
DEBUGPRINT("IMM Write, size 0x%x, data32: 0x%08x data16: 0x%04x data8: 0x%02x mWriteP 0x%x", _uSize, _uData, (u16)Common::swap32(_uData >> 8), (u8)Common::swap32(_uData), mWriteP);
DEBUGPRINT( "IMM Write, size 0x%x, data32: 0x%08x data16: 0x%04x data8: 0x%02x mWriteP 0x%x\n", _uSize, _uData, (u16)Common::swap32(_uData >> 8), (u8)Common::swap32(_uData), mWriteP);
if (mExpectVariableLengthImmWrite) if (mExpectVariableLengthImmWrite)
{ {
DEBUGPRINT("\t[INFO]Variable length IMM write\n"); DEBUGPRINT("\t[INFO]Variable length IMM write");
if(_uSize == 4) if(_uSize == 4)
{ {
// Correct // Correct
@ -195,10 +202,10 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
{ {
if (mWriteP + _uSize > BBAMEM_SIZE) if (mWriteP + _uSize > BBAMEM_SIZE)
{ {
DEBUGPRINT( "[EEE]Write error: mWriteP + size = 0x%04X + %i\n", mWriteP, _uSize); DEBUGPRINT("[EEE]Write error: mWriteP + size = 0x%04X + %i", mWriteP, _uSize);
exit(0); exit(0);
} }
DEBUGPRINT("\t[INFO]Write to BBA address 0x%0*X, %i byte%s: 0x%0*X\n",mWriteP >= CB_OFFSET ? 4 : 2, mWriteP, _uSize, (_uSize==1?"":"s"), _uSize*2, _uData); DEBUGPRINT("\t[INFO]Write to BBA address 0x%0*X, %i byte%s: 0x%0*X",mWriteP >= CB_OFFSET ? 4 : 2, mWriteP, _uSize, (_uSize==1?"":"s"), _uSize*2, _uData);
switch (mWriteP) switch (mWriteP)
{ {
@ -207,33 +214,33 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
// Correct, we use swapped // Correct, we use swapped
assert(_uSize == 1); assert(_uSize == 1);
u32 SwappedData = Common::swap32(_uData); u32 SwappedData = Common::swap32(_uData);
DEBUGPRINT("\t\t[INFO]BBA Interrupt reset 0x%02X & ~(0x%02X) => 0x%02X\n", mBbaMem[0x09], MAKE(u8, SwappedData), mBbaMem[0x09] & ~MAKE(u8, SwappedData)); DEBUGPRINT("\t\t[INFO]BBA Interrupt reset 0x%02X & ~(0x%02X) => 0x%02X", mBbaMem[0x09], MAKE(u8, SwappedData), mBbaMem[0x09] & ~MAKE(u8, SwappedData));
mBbaMem[BBA_IR] &= ~MAKE(u8, SwappedData); mBbaMem[BBA_IR] &= ~MAKE(u8, SwappedData);
break; break;
} }
case BBA_NCRA: case BBA_NCRA:
{ {
DEBUGPRINT("\t\t[INFO]BBA_NCRA\n"); DEBUGPRINT("\t\t[INFO]BBA_NCRA");
// Correct, we use the swap here // Correct, we use the swap here
u32 SwappedData = (u8)Common::swap32(_uData); u32 SwappedData = (u8)Common::swap32(_uData);
if (RISE(BBA_NCRA_RESET)) if (RISE(BBA_NCRA_RESET))
{ {
// Normal // Normal
// Whinecube did nothing else as well // Whinecube did nothing else as well
DEBUGPRINT( "\t\t[INFO]BBA Reset\n"); DEBUGPRINT("\t\t[INFO]BBA Reset");
} }
if (RISE(BBA_NCRA_SR) && isActivated()) if (RISE(BBA_NCRA_SR) && isActivated())
{ {
DEBUGPRINT( "\t\t[INFO]BBA Start Recieve\n"); DEBUGPRINT("\t\t[INFO]BBA Start Recieve");
//exit(0); //exit(0);
startRecv(); startRecv();
} }
if (RISE(BBA_NCRA_ST1)) if (RISE(BBA_NCRA_ST1))
{ {
DEBUGPRINT( "\t\t[INFO]BBA Start Transmit\n"); DEBUGPRINT("\t\t[INFO]BBA Start Transmit");
if (!mReadyToSend) if (!mReadyToSend)
{ {
DEBUGPRINT( "\t\t\t[EEE]Not ready to send!\n"); DEBUGPRINT("\t\t\t[EEE]Not ready to send!");
exit(0); exit(0);
//throw hardware_fatal_exception("BBA Transmit without a packet!"); //throw hardware_fatal_exception("BBA Transmit without a packet!");
} }
@ -244,7 +251,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
} }
break; break;
case BBA_NWAYC: case BBA_NWAYC:
DEBUGPRINT( "\t\t[INFO]BBA_NWAYC\n"); DEBUGPRINT("\t\t[INFO]BBA_NWAYC");
if(Common::swap32(_uData) & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA)) if(Common::swap32(_uData) & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA))
{ {
//say we've successfully negotiated for 10 Mbit full duplex //say we've successfully negotiated for 10 Mbit full duplex
@ -256,33 +263,33 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
{ {
if(_uData != 0x0) if(_uData != 0x0)
{ {
DEBUGPRINT("Not activate!\n"); DEBUGPRINT("Not activate!");
exit(0); exit(0);
} }
} }
break; break;
case BBA_RRP: //RRP - Receive Buffer Read Page Pointer case BBA_RRP: //RRP - Receive Buffer Read Page Pointer
DEBUGPRINT( "\t\t[INFO]RRP\n"); DEBUGPRINT("\t\t[INFO]RRP");
assert(_uSize == 2 || _uSize == 1); assert(_uSize == 2 || _uSize == 1);
mRBRPP = (u8)Common::swap32(_uData) << 8; //Whinecube: I hope this works with both write sizes. mRBRPP = (u8)Common::swap32(_uData) << 8; //Whinecube: I hope this works with both write sizes.
mRBEmpty = (mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET)); mRBEmpty = (mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET));
checkRecvBuffer(); checkRecvBuffer();
break; break;
case BBA_RWP: //RWP - Receive Buffer Write Page Pointer case BBA_RWP: //RWP - Receive Buffer Write Page Pointer
DEBUGPRINT( "\t\t[INFO]RWP\n"); DEBUGPRINT("\t\t[INFO]RWP");
assert(_uSize == 2 || _uSize == 1); assert(_uSize == 2 || _uSize == 1);
DEBUGPRINT("\t\t\tThing is 0x%0X\n", (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8); DEBUGPRINT("\t\t\tThing is 0x%0X", (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
// TODO: This assert FAILS! // TODO: This assert FAILS!
//assert(Common::swap32(_uData) == (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8); //assert(Common::swap32(_uData) == (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
break; break;
case BBA_NWAYS: case BBA_NWAYS:
DEBUGPRINT("[ERR]Call to BBA_NWAYS directly!\n"); DEBUGPRINT("[ERR]Call to BBA_NWAYS directly!");
exit(0); exit(0);
break; break;
case BBA_SI_ACTRL2: case BBA_SI_ACTRL2:
default: default:
DEBUGPRINT( "\t\t[INFO]Default one!Size 0x%x _uData: 0x%08x Swapped 0x%08x to 0x%x\n", _uSize, _uData, Common::swap32(_uData),mWriteP); DEBUGPRINT("\t\t[INFO]Default one!Size 0x%x _uData: 0x%08x Swapped 0x%08x to 0x%x", _uSize, _uData, Common::swap32(_uData),mWriteP);
u32 SwappedData = 0; u32 SwappedData = 0;
if(_uSize == 4 || _uSize == 1) if(_uSize == 4 || _uSize == 1)
{ {
@ -291,7 +298,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
SwappedData = Common::swap32(_uData); SwappedData = Common::swap32(_uData);
if(_uSize == 4) if(_uSize == 4)
{ {
printf("\t\t\tData is 0x%08x\n", SwappedData); DEBUGPRINT("\t\t\tData is 0x%08x", SwappedData);
//exit(0); //exit(0);
} }
} }
@ -299,7 +306,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
{ {
//Correct //Correct
SwappedData = (u16)(_uData >> 16); SwappedData = (u16)(_uData >> 16);
//printf("\t\t\tData is 0x%04x\n", SwappedData); //DEBUGPRINT("\t\t\tData is 0x%04x", SwappedData);
} }
//u32 SwappedData = _uData; //u32 SwappedData = _uData;
memcpy(mBbaMem + mWriteP, &SwappedData, _uSize); memcpy(mBbaMem + mWriteP, &SwappedData, _uSize);
@ -311,7 +318,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
{ {
// Device ID Request // Device ID Request
// 100% this returns correctly // 100% this returns correctly
DEBUGPRINT( "\t[INFO]Request Dev ID\n"); DEBUGPRINT("\t[INFO]Request Dev ID");
mSpecialImmData = EXI_DEVTYPE_ETHER; mSpecialImmData = EXI_DEVTYPE_ETHER;
mExpectSpecialImmRead = true; mExpectSpecialImmRead = true;
return; return;
@ -319,7 +326,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
else if ((_uSize == 4 && (_uData & 0xC0000000) == 0xC0000000) || (_uSize == 2 && ((u16)Common::swap32(_uData >> 8) & 0x4000) == 0x4000)) else if ((_uSize == 4 && (_uData & 0xC0000000) == 0xC0000000) || (_uSize == 2 && ((u16)Common::swap32(_uData >> 8) & 0x4000) == 0x4000))
{ {
// Write to BBA Register // Write to BBA Register
DEBUGPRINT( "\t[INFO]Write to BBA register!\n"); DEBUGPRINT("\t[INFO]Write to BBA register!");
if (_uSize == 4) if (_uSize == 4)
{ {
// Dunno if this is correct TODO // Dunno if this is correct TODO
@ -338,11 +345,11 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
{ {
mWriteBuffer.clear(); mWriteBuffer.clear();
mExpectVariableLengthImmWrite = true; mExpectVariableLengthImmWrite = true;
DEBUGPRINT( "\t\t[INFO]Prepared for variable length write to address 0x48\n"); DEBUGPRINT("\t\t[INFO]Prepared for variable length write to address 0x48");
} }
else else
{ {
DEBUGPRINT( "\t\t[INFO]BBA Write pointer set to 0x%0*X\n", _uSize, mWriteP); DEBUGPRINT("\t\t[INFO]BBA Write pointer set to 0x%0*X", _uSize, mWriteP);
//exit(0); //exit(0);
} }
return; return;
@ -358,7 +365,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
mReadP = (u16)getbitsw(SwappedData, 8, 23); mReadP = (u16)getbitsw(SwappedData, 8, 23);
if (mReadP >= BBAMEM_SIZE) if (mReadP >= BBAMEM_SIZE)
{ {
DEBUGPRINT( "\t\t[EEE]Illegal BBA address: 0x%04X\n", mReadP); DEBUGPRINT("\t\t[EEE]Illegal BBA address: 0x%04X", mReadP);
//if(g::bouehr) //if(g::bouehr)
exit(0); exit(0);
//return EXI_UNHANDLED; //return EXI_UNHANDLED;
@ -370,29 +377,29 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
//size == 2 //size == 2
mReadP = (u8)Common::swap32(_uData); mReadP = (u8)Common::swap32(_uData);
} }
DEBUGPRINT( "\t[INFO]Read from BBA register! 0x%X\n", mReadP); DEBUGPRINT("\t[INFO]Read from BBA register! 0x%X", mReadP);
switch (mReadP) switch (mReadP)
{ {
case 0x20: //MAC address case 0x20: //MAC address
DEBUGPRINT( "\t\t[INFO]Mac Address!\n"); DEBUGPRINT("\t\t[INFO]Mac Address!");
memcpy(mBbaMem + mReadP, mac_address, 6); memcpy(mBbaMem + mReadP, mac_address, 6);
break; break;
case 0x01: //Revision ID case 0x01: //Revision ID
break; break;
case 0x16: //RWP - Receive Buffer Write Page Pointer case 0x16: //RWP - Receive Buffer Write Page Pointer
DEBUGPRINT( "\t\t[INFO]RWP! 0x%04x Swapped 0x%04x\n", (((u16)mCbw.p_write() + CB_OFFSET) >> 8), Common::swap16(((u16)mCbw.p_write() + CB_OFFSET) >> 8)); DEBUGPRINT("\t\t[INFO]RWP! 0x%04x Swapped 0x%04x", (((u16)mCbw.p_write() + CB_OFFSET) >> 8), Common::swap16(((u16)mCbw.p_write() + CB_OFFSET) >> 8));
//exit(0); //exit(0);
// TODO: Dunno if correct // TODO: Dunno if correct
MAKE(u16, mBbaMem[mReadP]) = (((u16)mCbw.p_write() + CB_OFFSET) >> 8); MAKE(u16, mBbaMem[mReadP]) = (((u16)mCbw.p_write() + CB_OFFSET) >> 8);
break; break;
case 0x18: //RRP - Receive Buffer Read Page Pointer case 0x18: //RRP - Receive Buffer Read Page Pointer
DEBUGPRINT( "\t\t[INFO]RRP!\n"); DEBUGPRINT("\t\t[INFO]RRP!");
//exit(0); //exit(0);
// TODO: Dunno if correct // TODO: Dunno if correct
MAKE(u16, mBbaMem[mReadP]) = (mRBRPP) >> 8; MAKE(u16, mBbaMem[mReadP]) = (mRBRPP) >> 8;
break; break;
case 0x3A: //bit 1 set if no data available case 0x3A: //bit 1 set if no data available
DEBUGPRINT( "\t\t[INFO]Bit 1 set!\n"); DEBUGPRINT("\t\t[INFO]Bit 1 set!");
exit(0); exit(0);
//mBbaMem[mReadP] = !mRBEmpty; //mBbaMem[mReadP] = !mRBEmpty;
break; break;
@ -401,12 +408,12 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
//mBbaMem[mReadP] = 0x00; //mBbaMem[mReadP] = 0x00;
//if(!sendInProgress()) //if(!sendInProgress())
mBbaMem[mReadP] &= ~(0x06); mBbaMem[mReadP] &= ~(0x06);
//DEBUGPRINT( "\t\t[INFO]mBbaMem[0x%x] &= ~(0x06);! Now 0x%x\n", mReadP, mBbaMem[mReadP]); //DEBUGPRINT("\t\t[INFO]mBbaMem[0x%x] &= ~(0x06);! Now 0x%x", mReadP, mBbaMem[mReadP]);
//exit(0); //exit(0);
break; break;
case 0x03: case 0x03:
mBbaMem[mReadP] = 0x80; mBbaMem[mReadP] = 0x80;
//DEBUGPRINT( "\t\t[INFO]mBbaMem[0x%x] = 0x80;! Now %x\n", mReadP, mBbaMem[mReadP]); //DEBUGPRINT("\t\t[INFO]mBbaMem[0x%x] = 0x80;! Now %x", mReadP, mBbaMem[mReadP]);
//exit(0); //exit(0);
break; break;
case 0x0e: case 0x0e:
@ -427,25 +434,25 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
case 0x30: // NWAYC - NWAY Configuration Register case 0x30: // NWAYC - NWAY Configuration Register
break; break;
default: default:
printf("Read from 0x%02x\n", mReadP); DEBUGPRINT("Read from 0x%02x", mReadP);
//exit(0); //exit(0);
break; break;
} }
//DEBUGPRINT("BBA Read pointer set to 0x%0*X, Data: 0x%08X\n", _uSize, mReadP, _uData); //DEBUGPRINT("BBA Read pointer set to 0x%0*X, Data: 0x%08X", _uSize, mReadP, _uData);
return; return;
} }
DEBUGPRINT( "\t[EEE]Not expecting ImmWrite of size %d\n", _uSize); DEBUGPRINT("\t[EEE]Not expecting ImmWrite of size %d", _uSize);
DEBUGPRINT( "\t\t[INFO] SKIPPING!\n"); DEBUGPRINT("\t\t[INFO] SKIPPING!");
//exit(0); //exit(0);
} }
u32 CEXIETHERNET::ImmRead(u32 _uSize) u32 CEXIETHERNET::ImmRead(u32 _uSize)
{ {
DEBUGPRINT( "IMM Read, size 0x%x\n", _uSize); DEBUGPRINT("IMM Read, size 0x%x", _uSize);
if (mExpectSpecialImmRead) if (mExpectSpecialImmRead)
{ {
// 100% that this returns correctly // 100% that this returns correctly
DEBUGPRINT( "\t[INFO]special IMMRead\n"); DEBUGPRINT("\t[INFO]special IMMRead");
mExpectSpecialImmRead = false; mExpectSpecialImmRead = false;
return mSpecialImmData; return mSpecialImmData;
} }
@ -453,7 +460,7 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
{ {
if (mReadP + _uSize > BBAMEM_SIZE) if (mReadP + _uSize > BBAMEM_SIZE)
{ {
DEBUGPRINT( "\t[EEE]Read error: mReadP + size = 0x%04X + %i\n", mReadP, _uSize); DEBUGPRINT("\t[EEE]Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
exit(0); exit(0);
} }
u32 uResult = 0; u32 uResult = 0;
@ -461,21 +468,21 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
// TODO: We do as well? // TODO: We do as well?
uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem... uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem...
//DEBUGPRINT("Mem spot is 0x%02x uResult is 0x%x\n", mBbaMem[mReadP], uResult); //DEBUGPRINT("Mem spot is 0x%02x uResult is 0x%x", mBbaMem[mReadP], uResult);
/*#ifndef _WIN32 /*#ifndef _WIN32
if(CheckRecieved()) if(CheckRecieved())
startRecv(); startRecv();
#endif*/ #endif*/
DEBUGPRINT( "\t[INFO]Read from BBA address 0x%0*X, %i byte%s: 0x%0*X\n",mReadP >= CB_OFFSET ? 4 : 2, mReadP, _uSize, (_uSize==1?"":"s"),_uSize*2, getbitsw(uResult, 0, _uSize * 8 - 1)); DEBUGPRINT("\t[INFO]Read from BBA address 0x%0*X, %i byte%s: 0x%0*X",mReadP >= CB_OFFSET ? 4 : 2, mReadP, _uSize, (_uSize==1?"":"s"),_uSize*2, getbitsw(uResult, 0, _uSize * 8 - 1));
mReadP = mReadP + _uSize; mReadP = mReadP + _uSize;
return uResult; return uResult;
} }
else else
{ {
DEBUGPRINT( "\t[EEE]Unhandled IMM read of %d bytes\n", _uSize); DEBUGPRINT("\t[EEE]Unhandled IMM read of %d bytes", _uSize);
exit(0); exit(0);
} }
DEBUGPRINT( "[EEE]Not Expecting IMMRead of size %d!\n", _uSize); DEBUGPRINT("[EEE]Not Expecting IMMRead of size %d!", _uSize);
exit(0); exit(0);
} }
@ -483,13 +490,13 @@ void CEXIETHERNET::DMAWrite(u32 _uAddr, u32 _uSize)
{ {
if(mExpectVariableLengthImmWrite) if(mExpectVariableLengthImmWrite)
{ {
DEBUGPRINT("DMA Write: Address is 0x%x and size is 0x%x\n", _uAddr, _uSize); DEBUGPRINT("DMA Write: Address is 0x%x and size is 0x%x", _uAddr, _uSize);
mWriteBuffer.write(_uSize, Memory::GetPointer(_uAddr)); mWriteBuffer.write(_uSize, Memory::GetPointer(_uAddr));
return; return;
} }
else else
{ {
DEBUGPRINT("Unhandled BBA DMA write: %i, 0x%08X\n", _uSize, _uAddr); DEBUGPRINT("Unhandled BBA DMA write: %i, 0x%08X", _uSize, _uAddr);
//if(g::bouehr) //if(g::bouehr)
exit(0); exit(0);
//return EXI_UNHANDLED; //return EXI_UNHANDLED;
@ -502,12 +509,12 @@ void CEXIETHERNET::DMARead(u32 _uAddr, u32 _uSize)
{ {
if(mReadP + _uSize > BBAMEM_SIZE) if(mReadP + _uSize > BBAMEM_SIZE)
{ {
DEBUGPRINT("Read error: mReadP + size = 0x%04X + %i\n", mReadP, _uSize); DEBUGPRINT("Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
return; return;
} }
//mem.write_physical(address, size, mBbaMem + mReadP); //mem.write_physical(address, size, mBbaMem + mReadP);
memcpy(Memory::GetPointer(_uAddr), mBbaMem + mReadP, _uSize); memcpy(Memory::GetPointer(_uAddr), mBbaMem + mReadP, _uSize);
DEBUGPRINT("DMA Read from BBA address 0x%0*X, %i bytes\n", DEBUGPRINT("DMA Read from BBA address 0x%0*X, %i bytes",
mReadP >= CB_OFFSET ? 4 : 2, mReadP, _uSize); mReadP >= CB_OFFSET ? 4 : 2, mReadP, _uSize);
//exit(0); //exit(0);
mReadP = mReadP + _uSize; mReadP = mReadP + _uSize;
@ -515,10 +522,10 @@ void CEXIETHERNET::DMARead(u32 _uAddr, u32 _uSize)
} }
else else
{ {
DEBUGPRINT("Unhandled BBA DMA read: %i, 0x%08X\n", _uSize, _uAddr); DEBUGPRINT("Unhandled BBA DMA read: %i, 0x%08X", _uSize, _uAddr);
//if(g::bouehr) //if(g::bouehr)
exit(0); exit(0);
//throw bouehr_exception("Unhandled BBA DMA read"); //throw bouehr_exception("Unhandled BBA DMA read");
//return EXI_UNHANDLED; //return EXI_UNHANDLED;
} }
}; }

View File

@ -17,6 +17,7 @@
#ifndef _EXIDEVICE_ETHERNET_H #ifndef _EXIDEVICE_ETHERNET_H
#define _EXIDEVICE_ETHERNET_H #define _EXIDEVICE_ETHERNET_H
#include "Thread.h" #include "Thread.h"
inline u8 makemaskb(int start, int end) { inline u8 makemaskb(int start, int end) {
@ -41,7 +42,8 @@ inline u32 getbitsw(u32 dword, int start, int end) {
// Container Class Stolen from Whinecube // Container Class Stolen from Whinecube
template<class T> class SubContainer; template<class T> class SubContainer;
template<class T> class Container { template<class T> class Container
{
public: public:
Container(size_t _size) { Container(size_t _size) {
b = 0; b = 0;
@ -53,10 +55,10 @@ public:
memcpy(a, data, _size); memcpy(a, data, _size);
} }
~Container() { ~Container() {
if(a) /*if(_msize(a))*/ free(a); if (a) /*if(_msize(a))*/ free(a);
} }
void resize(size_t _size) { void resize(size_t _size) {
if(b == _size) if (b == _size)
return; return;
free(a); free(a);
allocate(_size); allocate(_size);
@ -103,17 +105,20 @@ public:
a = other.a; b = other.b; a = other.a; b = other.b;
other.a = ta; other.b = tb; other.a = ta; other.b = tb;
} }
protected: protected:
void *a; void *a;
size_t b; size_t b;
private: private:
Container(const Container&); Container(const Container&);
Container &operator=(const Container&); Container &operator=(const Container&);
Container(void* ptr, size_t _size) : a(ptr), b(_size) {} Container(void* ptr, size_t _size) : a(ptr), b(_size) {}
friend class SubContainer; friend class SubContainer;
void allocate(size_t _size) { void allocate(size_t _size)
if(_size > (100*1024*1024)) // 100 MB cap {
if (_size > (100*1024*1024)) // 100 MB cap
exit(0); exit(0);
//DEGUB("Resize: %i -> %i = %i\n", b, size, g_con_total); //DEGUB("Resize: %i -> %i = %i\n", b, size, g_con_total);
@ -122,9 +127,10 @@ private:
//} //}
b = _size; b = _size;
if(_size == 0) if (_size == 0)
a = NULL; a = NULL;
else { else
{
a = malloc(_size); a = malloc(_size);
//if(!_CrtIsValidHeapPointer(a)) //if(!_CrtIsValidHeapPointer(a))
//throw generic_fatal_exception("malloc failed in Container"); //throw generic_fatal_exception("malloc failed in Container");
@ -133,14 +139,21 @@ private:
}; };
void DEBUGPRINT (const char * format, ...); void DEBUGPRINT (const char * format, ...);
class WriteBuffer {
class WriteBuffer
{
public: public:
WriteBuffer(u32 s) :_size(0) { _buffer = (u8*)malloc(s*sizeof(u8)); ucapacity = s;} WriteBuffer(u32 s) :_size(0)
{
_buffer = (u8*)malloc(s*sizeof(u8));
ucapacity = s;
}
~WriteBuffer() { free(_buffer);} ~WriteBuffer() { free(_buffer);}
u32 size() const { return _size; } u32 size() const { return _size; }
u32 capacity() const { return ucapacity; } u32 capacity() const { return ucapacity; }
void write(u32 s, const void *src) { void write(u32 s, const void *src)
if(_size + s >= ucapacity) {
if (_size + s >= ucapacity)
{ {
printf("Write too large!"); printf("Write too large!");
exit(0); exit(0);
@ -149,10 +162,9 @@ public:
memcpy(_buffer + _size, src, s); memcpy(_buffer + _size, src, s);
_size = _size + s; _size = _size + s;
} }
void clear() { void clear() { _size = 0; }
_size = 0;
}
u8* const p() { return _buffer; } u8* const p() { return _buffer; }
private: private:
u8* _buffer; u8* _buffer;
u32 ucapacity; u32 ucapacity;
@ -162,21 +174,22 @@ private:
//Doesn't contain error checks for wraparound writes //Doesn't contain error checks for wraparound writes
class CyclicBufferWriter class CyclicBufferWriter
{ {
public: public:
CyclicBufferWriter(u8 *buffer, size_t cap) CyclicBufferWriter(u8 *buffer, size_t cap)
{ {
_buffer = buffer; _cap = cap; _write = 0; _buffer = buffer; _cap = cap; _write = 0;
} }
size_t p_write() const { return _write; } size_t p_write() const { return _write; }
void reset() { _write = 0; } void reset() { _write = 0; }
void write(void *src, size_t size); void write(void *src, size_t size);
void align(); //aligns the write pointer to steps of 0x100, like the real BBA void align(); //aligns the write pointer to steps of 0x100, like the real BBA
private:
size_t _write; private:
size_t _cap; //capacity size_t _write;
u8 *_buffer; size_t _cap; //capacity
u8 *_buffer;
}; };
class CEXIETHERNET : public IEXIDevice class CEXIETHERNET : public IEXIDevice
@ -197,29 +210,30 @@ public:
// STATE_TO_SAVE // STATE_TO_SAVE
u32 m_uPosition; u32 m_uPosition;
u32 m_uCommand; u32 m_uCommand;
bool m_bInterruptSet; bool m_bInterruptSet;
u32 mWriteP, mReadP; u32 mWriteP, mReadP;
#define INVALID_P 0xFFFF #define INVALID_P 0xFFFF
bool mExpectSpecialImmRead; //reset to false on deselect bool mExpectSpecialImmRead; //reset to false on deselect
u32 mSpecialImmData; u32 mSpecialImmData;
bool Activated; bool Activated;
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
bool mRBEmpty; bool mRBEmpty;
#define BBAMEM_SIZE 0x1000 #define BBAMEM_SIZE 0x1000
u8 mBbaMem[BBAMEM_SIZE]; u8 mBbaMem[BBAMEM_SIZE];
WriteBuffer mWriteBuffer; WriteBuffer mWriteBuffer;
CyclicBufferWriter mCbw; CyclicBufferWriter mCbw;
bool mExpectVariableLengthImmWrite; bool mExpectVariableLengthImmWrite;
bool mReadyToSend; bool mReadyToSend;
unsigned int ID; unsigned int ID;
u8 RegisterBlock[0x1000]; u8 RegisterBlock[0x1000];
enum { enum
{
CMD_ID = 0x00, CMD_ID = 0x00,
CMD_READ_REG = 0x01, CMD_READ_REG = 0x01,
}; };
@ -228,7 +242,7 @@ public:
bool sendPacket(u8 *etherpckt, int size); bool sendPacket(u8 *etherpckt, int size);
bool checkRecvBuffer(); bool checkRecvBuffer();
bool handleRecvdPacket(); bool handleRecvdPacket();
//TAP interface //TAP interface
bool activate(); bool activate();
bool CheckRecieved(); bool CheckRecieved();
@ -238,7 +252,7 @@ public:
bool startRecv(); bool startRecv();
bool cbwriteDescriptor(u32 size); bool cbwriteDescriptor(u32 size);
volatile bool mWaiting; volatile bool mWaiting;
Container<u8> mRecvBuffer; Container<u8> mRecvBuffer;
#ifdef _WIN32 #ifdef _WIN32
@ -250,73 +264,81 @@ public:
#else #else
u32 mRecvBufferLength; u32 mRecvBufferLength;
#endif #endif
};
}; enum
enum { {
EXPECT_NONE = 0, EXPECT_NONE = 0,
EXPECT_ID, EXPECT_ID
}; };
enum{
CB_OFFSET = 0x100, // TODO: convert into unions
CB_SIZE = (BBAMEM_SIZE - CB_OFFSET), enum
{
CB_OFFSET = 0x100,
CB_SIZE = (BBAMEM_SIZE - CB_OFFSET),
SIZEOF_RECV_DESCRIPTOR = 4, SIZEOF_RECV_DESCRIPTOR = 4,
EXI_DEVTYPE_ETHER = 0x04020200, EXI_DEVTYPE_ETHER = 0x04020200,
BBA_NCRA = 0x00, /* Network Control Register A, RW */
BBA_NCRA_RESET = (1<<0), /* RESET */ BBA_NCRA = 0x00, // Network Control Register A, RW
BBA_NCRA_ST0 = (1<<1), /* ST0, Start transmit command/status */ BBA_NCRA_RESET = 0x01, // RESET
BBA_NCRA_ST1 = (1<<2), /* ST1, " */ BBA_NCRA_ST0 = 0x02, // ST0, Start transmit command/status
BBA_NCRA_SR = (1<<3), /* SR, Start Receive */ BBA_NCRA_ST1 = 0x04, // ST1, "
BBA_NCRA_SR = 0x08, // SR, Start Receive
BBA_NCRB = 0x01, /* Network Control Register B, RW */ BBA_NCRB = 0x01, // Network Control Register B, RW
BBA_NCRB_PR = (1<<0), /* PR, Promiscuous Mode */ BBA_NCRB_PR = 0x01, // PR, Promiscuous Mode
BBA_NCRB_CA = (1<<1), /* CA, Capture Effect Mode */ BBA_NCRB_CA = 0x02, // CA, Capture Effect Mode
BBA_NCRB_PM = (1<<2), /* PM, Pass Multicast */ BBA_NCRB_PM = 0x04, // PM, Pass Multicast
BBA_NCRB_PB = (1<<3), /* PB, Pass Bad Frame */ BBA_NCRB_PB = 0x08, // PB, Pass Bad Frame
BBA_NCRB_AB = (1<<4), /* AB, Accept Broadcast */ BBA_NCRB_AB = 0x10, // AB, Accept Broadcast
BBA_NCRB_HBD = (1<<5), /* HBD, reserved */ BBA_NCRB_HBD = 0x20, // HBD, reserved
BBA_NCRB_RXINTC0 = (1<<6), /* RXINTC, Receive Interrupt Counter */ BBA_NCRB_RXINTC0 = 0x40, // RXINTC, Receive Interrupt Counter
BBA_NCRB_RXINTC1 = (1<<7), /* " */ BBA_NCRB_RXINTC1 = 0x80, // "
BBA_NCRB_1_PACKET_PER_INT = (0<<6), /* 0 0 */ BBA_NCRB_1_PACKET_PER_INT = 0x00, // 0 0
BBA_NCRB_2_PACKETS_PER_INT = (1<<6), /* 0 1 */ BBA_NCRB_2_PACKETS_PER_INT = 0x40, // 0 1
BBA_NCRB_4_PACKETS_PER_INT = (2<<6), /* 1 0 */ BBA_NCRB_4_PACKETS_PER_INT = 0x80, // 1 0
BBA_NCRB_8_PACKETS_PER_INT = (3<<6), /* 1 1 */ BBA_NCRB_8_PACKETS_PER_INT = 0xC0, // 1 1
BBA_IMR = 0x08, /* Interrupt Mask Register, RW, 00h */ BBA_IMR = 0x08, // Interrupt Mask Register, RW, 00h
BBA_IR = 0x09, /* Interrupt Register, RW, 00h */ BBA_IR = 0x09, // Interrupt Register, RW, 00h
BBA_IR_FRAGI = (1<<0), /* FRAGI, Fragment Counter Interrupt */ BBA_IR_FRAGI = 0x01, // FRAGI, Fragment Counter Interrupt
BBA_IR_RI = (1<<1), /* RI, Receive Interrupt */ BBA_IR_RI = 0x02, // RI, Receive Interrupt
BBA_IR_TI = (1<<2), /* TI, Transmit Interrupt */ BBA_IR_TI = 0x04, // TI, Transmit Interrupt
BBA_IR_REI = (1<<3), /* REI, Receive Error Interrupt */ BBA_IR_REI = 0x08, // REI, Receive Error Interrupt
BBA_IR_TEI = (1<<4), /* TEI, Transmit Error Interrupt */ BBA_IR_TEI = 0x10, // TEI, Transmit Error Interrupt
BBA_IR_FIFOEI = (1<<5), /* FIFOEI, FIFO Error Interrupt */ BBA_IR_FIFOEI = 0x20, // FIFOEI, FIFO Error Interrupt
BBA_IR_BUSEI = (1<<6), /* BUSEI, BUS Error Interrupt */ BBA_IR_BUSEI = 0x40, // BUSEI, BUS Error Interrupt
BBA_IR_RBFI = (1<<7), /* RBFI, RX Buffer Full Interrupt */ BBA_IR_RBFI = 0x80, // RBFI, RX Buffer Full Interrupt
BBA_NWAYC = 0x30, /* NWAY Configuration Register, RW, 84h */ BBA_NWAYC = 0x30, // NWAY Configuration Register, RW, 84h
BBA_NWAYC_FD = (1<<0), /* FD, Full Duplex Mode */ BBA_NWAYC_FD = 0x01, // FD, Full Duplex Mode
BBA_NWAYC_PS100 = (1<<1), /* PS100/10, Port Select 100/10 */ BBA_NWAYC_PS100 = 0x02, // PS100/10, Port Select 100/10
BBA_NWAYC_ANE = (1<<2), /* ANE, Autonegotiation Enable */ BBA_NWAYC_ANE = 0x04, // ANE, Autonegotiation Enable
BBA_NWAYC_ANS_RA = (1<<3), /* ANS, Restart Autonegotiation */ BBA_NWAYC_ANS_RA = 0x08, // ANS, Restart Autonegotiation
BBA_NWAYC_LTE = (1<<7), /* LTE, Link Test Enable */ BBA_NWAYC_LTE = 0x80, // LTE, Link Test Enable
BBA_NWAYS = 0x31, BBA_NWAYS = 0x31,
BBA_NWAYS_LS10 = (1<<0), BBA_NWAYS_LS10 = 0x01,
BBA_NWAYS_LS100 = (1<<1), BBA_NWAYS_LS100 = 0x02,
BBA_NWAYS_LPNWAY = (1<<2), BBA_NWAYS_LPNWAY = 0x04,
BBA_NWAYS_ANCLPT = (1<<3), BBA_NWAYS_ANCLPT = 0x08,
BBA_NWAYS_100TXF = (1<<4), BBA_NWAYS_100TXF = 0x10,
BBA_NWAYS_100TXH = (1<<5), BBA_NWAYS_100TXH = 0x20,
BBA_NWAYS_10TXF = (1<<6), BBA_NWAYS_10TXF = 0x40,
BBA_NWAYS_10TXH = (1<<7), BBA_NWAYS_10TXH = 0x80,
BBA_INTERRUPT_RECV = 0x02,
BBA_INTERRUPT_SENT = 0x04, BBA_INTERRUPT_RECV = 0x02,
BBA_INTERRUPT_RECV_ERROR = 0x08, BBA_INTERRUPT_SENT = 0x04,
BBA_INTERRUPT_SEND_ERROR = 0x10, BBA_INTERRUPT_RECV_ERROR = 0x08,
BBA_RWP = 0x16, /* Receive Buffer Write Page Pointer Register */ BBA_INTERRUPT_SEND_ERROR = 0x10,
BBA_RRP = 0x18, /* Receive Buffer Read Page Pointer Register */
BBA_SI_ACTRL2 = 0x60, BBA_RWP = 0x16, // Receive Buffer Write Page Pointer Register
BBA_RRP = 0x18, // Receive Buffer Read Page Pointer Register
BBA_SI_ACTRL2 = 0x60
}; };
#endif #endif

View File

@ -626,14 +626,16 @@ Global
{823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|x64.Build.0 = Release|x64 {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|x64.Build.0 = Release|x64
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|Win32.ActiveCfg = Debug|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|Win32.ActiveCfg = Debug|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|Win32.Build.0 = Debug|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|Win32.Build.0 = Debug|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|x64.ActiveCfg = Debug|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|x64.ActiveCfg = Debug|x64
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Debug|x64.Build.0 = Debug|x64
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|Win32.ActiveCfg = Debug|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|Win32.ActiveCfg = Debug|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|Win32.Build.0 = Debug|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|Win32.Build.0 = Debug|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|x64.ActiveCfg = DebugFast|x64 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|x64.ActiveCfg = Debug|x64
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|x64.Build.0 = DebugFast|x64 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.DebugFast|x64.Build.0 = Debug|x64
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release_JITIL|Win32.ActiveCfg = Release|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release_JITIL|Win32.ActiveCfg = Release|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release_JITIL|Win32.Build.0 = Release|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release_JITIL|Win32.Build.0 = Release|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release_JITIL|x64.ActiveCfg = Release|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release_JITIL|x64.ActiveCfg = Release|x64
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release_JITIL|x64.Build.0 = Release|x64
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|Win32.ActiveCfg = Release|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|Win32.ActiveCfg = Release|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|Win32.Build.0 = Release|Win32 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|Win32.Build.0 = Release|Win32
{40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|x64.ActiveCfg = Release|x64 {40C636FA-B5BF-4D67-ABC8-376B524A7551}.Release|x64.ActiveCfg = Release|x64