Some cleanup of BBA code. No behavioral changes.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4500 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
7a0055e113
commit
281636b79b
|
@ -384,7 +384,7 @@ bool CEXIETHERNET::startRecv()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD res = ReadFile(mHAdapter, mRecvBuffer, (DWORD)mRecvBuffer.size(),
|
DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE,
|
||||||
&mRecvBufferLength, &mReadOverlapped);
|
&mRecvBufferLength, &mReadOverlapped);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
|
|
|
@ -17,32 +17,31 @@
|
||||||
|
|
||||||
#include "Memmap.h"
|
#include "Memmap.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include "../Core.h"
|
|
||||||
|
|
||||||
#include "EXI_Device.h"
|
#include "EXI_Device.h"
|
||||||
#include "EXI_DeviceEthernet.h"
|
#include "EXI_DeviceEthernet.h"
|
||||||
|
|
||||||
//#define SONICDEBUG
|
//#define SONICDEBUG
|
||||||
|
#ifdef SONICDEBUG
|
||||||
#define FILEDEBUG
|
#define FILEDEBUG
|
||||||
#ifdef FILEDEBUG
|
#ifdef FILEDEBUG
|
||||||
FILE *ME = 0;
|
FILE *ME = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
void DEBUGPRINT (const char * format, ...)
|
void DEBUGPRINT (const char * format, ...)
|
||||||
{
|
{
|
||||||
char buffer[0x1000];
|
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\n", buffer);
|
fprintf(ME, "%s\n", buffer);
|
||||||
#endif
|
#endif
|
||||||
printf("%s\n", buffer);
|
printf("%s\n", buffer);
|
||||||
#else
|
#else
|
||||||
INFO_LOG(SP1, buffer);
|
INFO_LOG(SP1, buffer);
|
||||||
#endif
|
#endif
|
||||||
va_end (args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,19 +49,17 @@ void DEBUGPRINT (const char * format, ...)
|
||||||
|
|
||||||
#define RISE(flags) ((SwappedData & (flags)) && !(mBbaMem[0x00] & (flags)))
|
#define RISE(flags) ((SwappedData & (flags)) && !(mBbaMem[0x00] & (flags)))
|
||||||
|
|
||||||
int mPacketsSent = 0;
|
static u32 mPacketsSent = 0;
|
||||||
u8 mac_address[6] = {0x00, 0x1A, 0x4D, 0x5E, 0x64, 0x2B}; // Looks Appropriate
|
static u8 mac_address[6] = {0x00, 0x09, 0xbf, 0x01, 0x00, 0xc1}; // (shuffle2) from my bba
|
||||||
unsigned int Expecting;
|
static u32 Expecting;
|
||||||
|
|
||||||
CEXIETHERNET::CEXIETHERNET() :
|
CEXIETHERNET::CEXIETHERNET() :
|
||||||
m_uPosition(0),
|
m_uPosition(0),
|
||||||
m_uCommand(0),
|
m_uCommand(0),
|
||||||
mWriteBuffer(2048),
|
mWriteBuffer(2048),
|
||||||
mCbw(mBbaMem + CB_OFFSET, CB_SIZE),
|
mCbw(mBbaMem + CB_OFFSET, CB_SIZE)
|
||||||
mRecvBuffer(2048)
|
|
||||||
{
|
{
|
||||||
memset(mBbaMem, 0, BBAMEM_SIZE);
|
memset(mBbaMem, 0, BBA_MEM_SIZE);
|
||||||
ID = 0x04020200;
|
|
||||||
mWriteP = INVALID_P;
|
mWriteP = INVALID_P;
|
||||||
mReadP = INVALID_P;
|
mReadP = INVALID_P;
|
||||||
mWaiting = false;
|
mWaiting = false;
|
||||||
|
@ -81,9 +78,9 @@ CEXIETHERNET::CEXIETHERNET() :
|
||||||
|
|
||||||
Expecting = EXPECT_NONE;
|
Expecting = EXPECT_NONE;
|
||||||
mExpectVariableLengthImmWrite = false;
|
mExpectVariableLengthImmWrite = false;
|
||||||
#ifdef FILEDEBUG
|
#ifdef FILEDEBUG
|
||||||
ME = fopen("Debug.txt", "wb");
|
ME = fopen("Debug.txt", "wb");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CEXIETHERNET::~CEXIETHERNET()
|
CEXIETHERNET::~CEXIETHERNET()
|
||||||
|
@ -93,32 +90,6 @@ CEXIETHERNET::~CEXIETHERNET()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CyclicBufferWriter::write(void *src, size_t size)
|
|
||||||
{
|
|
||||||
assert(size < _cap);
|
|
||||||
u8* bsrc = (u8*) src;
|
|
||||||
if(_write + size >= _cap)
|
|
||||||
{
|
|
||||||
// wraparound
|
|
||||||
memcpy(_buffer + _write, src, _cap - _write);
|
|
||||||
memcpy(_buffer, bsrc + (_cap - _write), size - (_cap - _write));
|
|
||||||
_write = size - (_cap - _write);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(_buffer + _write, src, size);
|
|
||||||
_write += size;
|
|
||||||
}
|
|
||||||
//DEGUB("CBWrote %i bytes", size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CyclicBufferWriter::align()
|
|
||||||
{
|
|
||||||
_write = (_write + 0xff) & ~0xff;
|
|
||||||
if(_write >= _cap)
|
|
||||||
_write -= _cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CEXIETHERNET::SetCS(int cs)
|
void CEXIETHERNET::SetCS(int cs)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("Set CS: %s Expect Variable write?: %s", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false");
|
DEBUGPRINT("Set CS: %s Expect Variable write?: %s", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false");
|
||||||
|
@ -158,7 +129,7 @@ bool CEXIETHERNET::IsInterruptSet()
|
||||||
void CEXIETHERNET::recordSendComplete()
|
void CEXIETHERNET::recordSendComplete()
|
||||||
{
|
{
|
||||||
mBbaMem[BBA_NCRA] &= ~0x06;
|
mBbaMem[BBA_NCRA] &= ~0x06;
|
||||||
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");
|
DEBUGPRINT("\t\tBBA Send interrupt raised");
|
||||||
|
@ -172,7 +143,7 @@ void CEXIETHERNET::recordSendComplete()
|
||||||
|
|
||||||
bool CEXIETHERNET::checkRecvBuffer()
|
bool CEXIETHERNET::checkRecvBuffer()
|
||||||
{
|
{
|
||||||
if(mRecvBufferLength != 0)
|
if (mRecvBufferLength != 0)
|
||||||
{
|
{
|
||||||
handleRecvdPacket();
|
handleRecvdPacket();
|
||||||
}
|
}
|
||||||
|
@ -185,12 +156,12 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
if (mExpectVariableLengthImmWrite)
|
if (mExpectVariableLengthImmWrite)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("\t[INFO]Variable length IMM write");
|
DEBUGPRINT("\t[INFO]Variable length IMM write");
|
||||||
if(_uSize == 4)
|
if (_uSize == 4)
|
||||||
{
|
{
|
||||||
// Correct
|
// Correct
|
||||||
_uData = Common::swap32(_uData);
|
_uData = Common::swap32(_uData);
|
||||||
}
|
}
|
||||||
else if(_uSize == 2)
|
else if (_uSize == 2)
|
||||||
{
|
{
|
||||||
// Correct
|
// Correct
|
||||||
_uData = (u16)Common::swap32(_uData);
|
_uData = (u16)Common::swap32(_uData);
|
||||||
|
@ -200,7 +171,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
}
|
}
|
||||||
else if (mWriteP != INVALID_P)
|
else if (mWriteP != INVALID_P)
|
||||||
{
|
{
|
||||||
if (mWriteP + _uSize > BBAMEM_SIZE)
|
if (mWriteP + _uSize > BBA_MEM_SIZE)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("[EEE]Write error: mWriteP + size = 0x%04X + %i", mWriteP, _uSize);
|
DEBUGPRINT("[EEE]Write error: mWriteP + size = 0x%04X + %i", mWriteP, _uSize);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -209,16 +180,16 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
|
|
||||||
switch (mWriteP)
|
switch (mWriteP)
|
||||||
{
|
{
|
||||||
case BBA_IR:
|
case BBA_IR:
|
||||||
{
|
{
|
||||||
// Correct, we use swapped
|
// Correct, we use swapped
|
||||||
assert(_uSize == 1);
|
_dbg_assert_(SP1, _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", 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");
|
DEBUGPRINT("\t\t[INFO]BBA_NCRA");
|
||||||
// Correct, we use the swap here
|
// Correct, we use the swap here
|
||||||
|
@ -231,7 +202,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
}
|
}
|
||||||
if (RISE(BBA_NCRA_SR) && isActivated())
|
if (RISE(BBA_NCRA_SR) && isActivated())
|
||||||
{
|
{
|
||||||
DEBUGPRINT("\t\t[INFO]BBA Start Recieve");
|
DEBUGPRINT("\t\t[INFO]BBA Start Receive");
|
||||||
//exit(0);
|
//exit(0);
|
||||||
startRecv();
|
startRecv();
|
||||||
}
|
}
|
||||||
|
@ -249,68 +220,68 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
}
|
}
|
||||||
mBbaMem[BBA_NCRA] = MAKE(u8, SwappedData);
|
mBbaMem[BBA_NCRA] = MAKE(u8, SwappedData);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BBA_NWAYC:
|
case BBA_NWAYC:
|
||||||
DEBUGPRINT("\t\t[INFO]BBA_NWAYC");
|
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
|
||||||
|
//should placate libogc
|
||||||
|
activate();
|
||||||
|
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_uData != 0x0)
|
||||||
{
|
{
|
||||||
//say we've successfully negotiated for 10 Mbit full duplex
|
DEBUGPRINT("Not activate!");
|
||||||
//should placate libogc
|
exit(0);
|
||||||
activate();
|
|
||||||
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(_uData != 0x0)
|
|
||||||
{
|
|
||||||
DEBUGPRINT("Not activate!");
|
|
||||||
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");
|
DEBUGPRINT("\t\t[INFO]RRP");
|
||||||
assert(_uSize == 2 || _uSize == 1);
|
_dbg_assert_(SP1, _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");
|
DEBUGPRINT("\t\t[INFO]RWP");
|
||||||
assert(_uSize == 2 || _uSize == 1);
|
_dbg_assert_(SP1, _uSize == 2 || _uSize == 1);
|
||||||
DEBUGPRINT("\t\t\tThing is 0x%0X", (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!");
|
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", _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)
|
||||||
|
{
|
||||||
|
// Correct, use Swapped here
|
||||||
|
// Size of 4 untested Though
|
||||||
|
SwappedData = Common::swap32(_uData);
|
||||||
|
if(_uSize == 4)
|
||||||
{
|
{
|
||||||
// Correct, use Swapped here
|
DEBUGPRINT("\t\t\tData is 0x%08x", SwappedData);
|
||||||
// Size of 4 untested Though
|
//exit(0);
|
||||||
SwappedData = Common::swap32(_uData);
|
|
||||||
if(_uSize == 4)
|
|
||||||
{
|
|
||||||
DEBUGPRINT("\t\t\tData is 0x%08x", SwappedData);
|
|
||||||
//exit(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if( _uSize == 2)
|
}
|
||||||
{
|
else if ( _uSize == 2)
|
||||||
//Correct
|
{
|
||||||
SwappedData = (u16)(_uData >> 16);
|
//Correct
|
||||||
//DEBUGPRINT("\t\t\tData is 0x%04x", SwappedData);
|
SwappedData = (u16)(_uData >> 16);
|
||||||
}
|
//DEBUGPRINT("\t\t\tData is 0x%04x", SwappedData);
|
||||||
//u32 SwappedData = _uData;
|
}
|
||||||
memcpy(mBbaMem + mWriteP, &SwappedData, _uSize);
|
//u32 SwappedData = _uData;
|
||||||
mWriteP = mWriteP + _uSize;
|
memcpy(mBbaMem + mWriteP, &SwappedData, _uSize);
|
||||||
|
mWriteP = mWriteP + _uSize;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -333,7 +304,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
u32 SwappedData = _uData;
|
u32 SwappedData = _uData;
|
||||||
mWriteP = (u8)getbitsw(SwappedData, 16, 23);
|
mWriteP = (u8)getbitsw(SwappedData, 16, 23);
|
||||||
}
|
}
|
||||||
else //size == 2
|
else //size == 2
|
||||||
{
|
{
|
||||||
// Correct, Size of 1 untested, should be correct.
|
// Correct, Size of 1 untested, should be correct.
|
||||||
u16 SwappedData = (u16)Common::swap32(_uData >> 8);
|
u16 SwappedData = (u16)Common::swap32(_uData >> 8);
|
||||||
|
@ -363,7 +334,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
{
|
{
|
||||||
// Correct
|
// Correct
|
||||||
mReadP = (u16)getbitsw(SwappedData, 8, 23);
|
mReadP = (u16)getbitsw(SwappedData, 8, 23);
|
||||||
if (mReadP >= BBAMEM_SIZE)
|
if (mReadP >= BBA_MEM_SIZE)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("\t\t[EEE]Illegal BBA address: 0x%04X", mReadP);
|
DEBUGPRINT("\t\t[EEE]Illegal BBA address: 0x%04X", mReadP);
|
||||||
//if(g::bouehr)
|
//if(g::bouehr)
|
||||||
|
@ -423,7 +394,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
case 0x5c: // These two go together
|
case 0x5c: // These two go together
|
||||||
break;
|
break;
|
||||||
case 0x31: // NWAYS - NWAY Status Register
|
case 0x31: // NWAYS - NWAY Status Register
|
||||||
// HACK
|
// HACK
|
||||||
activate();
|
activate();
|
||||||
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
||||||
case 0x09: // IR
|
case 0x09: // IR
|
||||||
|
@ -458,7 +429,7 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
||||||
}
|
}
|
||||||
if (mReadP != INVALID_P)
|
if (mReadP != INVALID_P)
|
||||||
{
|
{
|
||||||
if (mReadP + _uSize > BBAMEM_SIZE)
|
if (mReadP + _uSize > BBA_MEM_SIZE)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("\t[EEE]Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
|
DEBUGPRINT("\t[EEE]Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -471,7 +442,7 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
||||||
//DEBUGPRINT("Mem spot is 0x%02x uResult is 0x%x", 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",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;
|
||||||
|
@ -488,7 +459,7 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
||||||
|
|
||||||
void CEXIETHERNET::DMAWrite(u32 _uAddr, u32 _uSize)
|
void CEXIETHERNET::DMAWrite(u32 _uAddr, u32 _uSize)
|
||||||
{
|
{
|
||||||
if(mExpectVariableLengthImmWrite)
|
if (mExpectVariableLengthImmWrite)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("DMA Write: Address is 0x%x and size is 0x%x", _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));
|
||||||
|
@ -505,9 +476,9 @@ void CEXIETHERNET::DMAWrite(u32 _uAddr, u32 _uSize)
|
||||||
|
|
||||||
void CEXIETHERNET::DMARead(u32 _uAddr, u32 _uSize)
|
void CEXIETHERNET::DMARead(u32 _uAddr, u32 _uSize)
|
||||||
{
|
{
|
||||||
if(mReadP != INVALID_P)
|
if (mReadP != INVALID_P)
|
||||||
{
|
{
|
||||||
if(mReadP + _uSize > BBAMEM_SIZE)
|
if (mReadP + _uSize > BBA_MEM_SIZE)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
|
DEBUGPRINT("Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -39,123 +39,24 @@ inline u32 getbitsw(u32 dword, int start, int end) {
|
||||||
return (dword & makemaskw(start, end)) >> (31 - end);
|
return (dword & makemaskw(start, end)) >> (31 - end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container Class Stolen from Whinecube
|
void DEBUGPRINT(const char * format, ...);
|
||||||
template<class T> class SubContainer;
|
|
||||||
|
|
||||||
template<class T> class Container
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Container(size_t _size) {
|
|
||||||
b = 0;
|
|
||||||
allocate(_size);
|
|
||||||
}
|
|
||||||
Container(size_t _size, const T *data) {
|
|
||||||
b = 0;
|
|
||||||
allocate(size);
|
|
||||||
memcpy(a, data, _size);
|
|
||||||
}
|
|
||||||
~Container() {
|
|
||||||
if (a) /*if(_msize(a))*/ free(a);
|
|
||||||
}
|
|
||||||
void resize(size_t _size) {
|
|
||||||
if (b == _size)
|
|
||||||
return;
|
|
||||||
free(a);
|
|
||||||
allocate(_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*void insert(int before, void *src, size_t size) {
|
|
||||||
char *temp = a;
|
|
||||||
a = new char[b + size];
|
|
||||||
if(a == NULL)
|
|
||||||
BFE("Memory insert failed in container");
|
|
||||||
memcpy(a, temp, before);
|
|
||||||
memcpy(a+before, src, size);
|
|
||||||
memcpy(a+before+size, temp+before, b-before);
|
|
||||||
b += size;
|
|
||||||
delete temp;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
class SubContainer : public Container {
|
|
||||||
private:
|
|
||||||
SubContainer(void* ptr, size_t size) : Container(ptr, size) {}
|
|
||||||
friend class Container;
|
|
||||||
public:
|
|
||||||
~SubContainer() {
|
|
||||||
a = NULL;
|
|
||||||
b = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
SubContainer getSub(size_t pos) {
|
|
||||||
return SubContainer(((char*)a) + pos, b - pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T*() { return (T *)a; }
|
|
||||||
operator const T*() const { return (T *)a; }
|
|
||||||
T* p() { return (T *)a; }
|
|
||||||
const T* p() const { return (T *)a; }
|
|
||||||
T *operator->() { return (T *)a; }
|
|
||||||
size_t size() const { return b; }
|
|
||||||
void steal(Container<T> &src) {
|
|
||||||
resize(0); a = src.a; b = src.b;
|
|
||||||
src.a = NULL; src.b = 0;
|
|
||||||
}
|
|
||||||
void swap(Container<T> &other) {
|
|
||||||
T *ta = a; size_t tb = b;
|
|
||||||
a = other.a; b = other.b;
|
|
||||||
other.a = ta; other.b = tb;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void *a;
|
|
||||||
size_t b;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Container(const Container&);
|
|
||||||
Container &operator=(const Container&);
|
|
||||||
Container(void* ptr, size_t _size) : a(ptr), b(_size) {}
|
|
||||||
friend class SubContainer;
|
|
||||||
|
|
||||||
void allocate(size_t _size)
|
|
||||||
{
|
|
||||||
if (_size > (100*1024*1024)) // 100 MB cap
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
//DEGUB("Resize: %i -> %i = %i\n", b, size, g_con_total);
|
|
||||||
//if(size > 1000*K) {
|
|
||||||
//DEGUB("Megabyte Container resize!\n");
|
|
||||||
//}
|
|
||||||
|
|
||||||
b = _size;
|
|
||||||
if (_size == 0)
|
|
||||||
a = NULL;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a = malloc(_size);
|
|
||||||
//if(!_CrtIsValidHeapPointer(a))
|
|
||||||
//throw generic_fatal_exception("malloc failed in Container");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void DEBUGPRINT (const char * format, ...);
|
|
||||||
|
|
||||||
class WriteBuffer
|
class WriteBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WriteBuffer(u32 s) :_size(0)
|
WriteBuffer(u32 s) : _size(0)
|
||||||
{
|
{
|
||||||
_buffer = (u8*)malloc(s*sizeof(u8));
|
_buffer = (u8*)malloc(s*sizeof(u8));
|
||||||
ucapacity = s;
|
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!");
|
DEBUGPRINT("Write too large!");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,112 +72,55 @@ private:
|
||||||
u32 _size;
|
u32 _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
//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; _capacity = 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
|
_dbg_assert_(SP1, size < _capacity);
|
||||||
|
u8* bsrc = (u8*) src;
|
||||||
|
if (_write + size >= _capacity)
|
||||||
|
{
|
||||||
|
// wraparound
|
||||||
|
memcpy(_buffer + _write, src, _capacity - _write);
|
||||||
|
memcpy(_buffer, bsrc + (_capacity - _write), size - (_capacity - _write));
|
||||||
|
_write = size - (_capacity - _write);
|
||||||
|
} else {
|
||||||
|
memcpy(_buffer + _write, src, size);
|
||||||
|
_write += size;
|
||||||
|
}
|
||||||
|
//DEBUG_LOG(SP1, "CBWrote %i bytes", size);
|
||||||
|
}
|
||||||
|
// Aligns the write pointer to steps of 0x100, like the real BBA
|
||||||
|
void align() {
|
||||||
|
_write = (_write + 0xff) & ~0xff;
|
||||||
|
if(_write >= _capacity)
|
||||||
|
_write -= _capacity;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t _write;
|
size_t _write;
|
||||||
size_t _cap; //capacity
|
size_t _capacity;
|
||||||
u8 *_buffer;
|
u8 *_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CEXIETHERNET : public IEXIDevice
|
#define INVALID_P 0xFFFF
|
||||||
{
|
|
||||||
public:
|
|
||||||
CEXIETHERNET();
|
|
||||||
~CEXIETHERNET();
|
|
||||||
void SetCS(int _iCS);
|
|
||||||
bool IsPresent();
|
|
||||||
void Update();
|
|
||||||
bool IsInterruptSet();
|
|
||||||
void ImmWrite(u32 _uData, u32 _uSize);
|
|
||||||
u32 ImmRead(u32 _uSize);
|
|
||||||
void DMAWrite(u32 _uAddr, u32 _uSize);
|
|
||||||
void DMARead(u32 _uAddr, u32 _uSize);
|
|
||||||
|
|
||||||
//private:
|
|
||||||
// STATE_TO_SAVE
|
|
||||||
u32 m_uPosition;
|
|
||||||
u32 m_uCommand;
|
|
||||||
|
|
||||||
bool m_bInterruptSet;
|
|
||||||
u32 mWriteP, mReadP;
|
|
||||||
#define INVALID_P 0xFFFF
|
|
||||||
|
|
||||||
bool mExpectSpecialImmRead; //reset to false on deselect
|
|
||||||
u32 mSpecialImmData;
|
|
||||||
bool Activated;
|
|
||||||
|
|
||||||
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
|
||||||
bool mRBEmpty;
|
|
||||||
|
|
||||||
#define BBAMEM_SIZE 0x1000
|
|
||||||
u8 mBbaMem[BBAMEM_SIZE];
|
|
||||||
|
|
||||||
WriteBuffer mWriteBuffer;
|
|
||||||
CyclicBufferWriter mCbw;
|
|
||||||
|
|
||||||
bool mExpectVariableLengthImmWrite;
|
|
||||||
bool mReadyToSend;
|
|
||||||
unsigned int ID;
|
|
||||||
u8 RegisterBlock[0x1000];
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
CMD_ID = 0x00,
|
|
||||||
CMD_READ_REG = 0x01,
|
|
||||||
};
|
|
||||||
|
|
||||||
void recordSendComplete();
|
|
||||||
bool sendPacket(u8 *etherpckt, int size);
|
|
||||||
bool checkRecvBuffer();
|
|
||||||
bool handleRecvdPacket();
|
|
||||||
|
|
||||||
//TAP interface
|
|
||||||
bool activate();
|
|
||||||
bool CheckRecieved();
|
|
||||||
bool deactivate();
|
|
||||||
bool isActivated();
|
|
||||||
bool resume();
|
|
||||||
bool startRecv();
|
|
||||||
bool cbwriteDescriptor(u32 size);
|
|
||||||
|
|
||||||
|
|
||||||
volatile bool mWaiting;
|
|
||||||
Container<u8> mRecvBuffer;
|
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
|
||||||
DWORD mMtu;
|
|
||||||
OVERLAPPED mReadOverlapped;
|
|
||||||
DWORD mRecvBufferLength;
|
|
||||||
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
|
||||||
#else
|
|
||||||
u32 mRecvBufferLength;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
EXPECT_NONE = 0,
|
|
||||||
EXPECT_ID
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: convert into unions
|
// TODO: convert into unions
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
BBA_RECV_SIZE = 0x800,
|
||||||
|
BBA_MEM_SIZE = 0x1000,
|
||||||
|
|
||||||
CB_OFFSET = 0x100,
|
CB_OFFSET = 0x100,
|
||||||
CB_SIZE = (BBAMEM_SIZE - CB_OFFSET),
|
CB_SIZE = (BBA_MEM_SIZE - CB_OFFSET),
|
||||||
SIZEOF_RECV_DESCRIPTOR = 4,
|
SIZEOF_RECV_DESCRIPTOR = 4,
|
||||||
|
|
||||||
EXI_DEVTYPE_ETHER = 0x04020200,
|
EXI_DEVTYPE_ETHER = 0x04020200,
|
||||||
|
@ -330,7 +174,7 @@ enum
|
||||||
BBA_NWAYS_10TXF = 0x40,
|
BBA_NWAYS_10TXF = 0x40,
|
||||||
BBA_NWAYS_10TXH = 0x80,
|
BBA_NWAYS_10TXH = 0x80,
|
||||||
|
|
||||||
BBA_INTERRUPT_RECV = 0x02,
|
BBA_INTERRUPT_RECV = 0x02,
|
||||||
BBA_INTERRUPT_SENT = 0x04,
|
BBA_INTERRUPT_SENT = 0x04,
|
||||||
BBA_INTERRUPT_RECV_ERROR = 0x08,
|
BBA_INTERRUPT_RECV_ERROR = 0x08,
|
||||||
BBA_INTERRUPT_SEND_ERROR = 0x10,
|
BBA_INTERRUPT_SEND_ERROR = 0x10,
|
||||||
|
@ -341,4 +185,81 @@ enum
|
||||||
BBA_SI_ACTRL2 = 0x60
|
BBA_SI_ACTRL2 = 0x60
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
EXPECT_NONE = 0,
|
||||||
|
EXPECT_ID
|
||||||
|
};
|
||||||
|
|
||||||
|
class CEXIETHERNET : public IEXIDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CEXIETHERNET();
|
||||||
|
~CEXIETHERNET();
|
||||||
|
void SetCS(int _iCS);
|
||||||
|
bool IsPresent();
|
||||||
|
void Update();
|
||||||
|
bool IsInterruptSet();
|
||||||
|
void ImmWrite(u32 _uData, u32 _uSize);
|
||||||
|
u32 ImmRead(u32 _uSize);
|
||||||
|
void DMAWrite(u32 _uAddr, u32 _uSize);
|
||||||
|
void DMARead(u32 _uAddr, u32 _uSize);
|
||||||
|
|
||||||
|
//private:
|
||||||
|
// STATE_TO_SAVE
|
||||||
|
u32 m_uPosition;
|
||||||
|
u32 m_uCommand;
|
||||||
|
|
||||||
|
bool m_bInterruptSet;
|
||||||
|
u32 mWriteP, mReadP;
|
||||||
|
|
||||||
|
bool mExpectSpecialImmRead; //reset to false on deselect
|
||||||
|
u32 mSpecialImmData;
|
||||||
|
bool Activated;
|
||||||
|
|
||||||
|
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
||||||
|
bool mRBEmpty;
|
||||||
|
|
||||||
|
u8 mBbaMem[BBA_MEM_SIZE];
|
||||||
|
|
||||||
|
WriteBuffer mWriteBuffer;
|
||||||
|
CyclicBufferWriter mCbw;
|
||||||
|
|
||||||
|
bool mExpectVariableLengthImmWrite;
|
||||||
|
bool mReadyToSend;
|
||||||
|
u8 RegisterBlock[0x1000];
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CMD_ID = 0x00,
|
||||||
|
CMD_READ_REG = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
void recordSendComplete();
|
||||||
|
bool sendPacket(u8 *etherpckt, int size);
|
||||||
|
bool checkRecvBuffer();
|
||||||
|
bool handleRecvdPacket();
|
||||||
|
|
||||||
|
//TAP interface
|
||||||
|
bool activate();
|
||||||
|
bool CheckRecieved();
|
||||||
|
bool deactivate();
|
||||||
|
bool isActivated();
|
||||||
|
bool resume();
|
||||||
|
bool startRecv();
|
||||||
|
bool cbwriteDescriptor(u32 size);
|
||||||
|
|
||||||
|
|
||||||
|
volatile bool mWaiting;
|
||||||
|
u8 mRecvBuffer[BBA_RECV_SIZE];
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
||||||
|
DWORD mMtu;
|
||||||
|
OVERLAPPED mReadOverlapped;
|
||||||
|
DWORD mRecvBufferLength;
|
||||||
|
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
||||||
|
#else
|
||||||
|
u32 mRecvBufferLength;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue