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;
|
||||
}
|
||||
|
||||
DWORD res = ReadFile(mHAdapter, mRecvBuffer, (DWORD)mRecvBuffer.size(),
|
||||
DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE,
|
||||
&mRecvBufferLength, &mReadOverlapped);
|
||||
|
||||
if (res)
|
||||
|
|
|
@ -17,32 +17,31 @@
|
|||
|
||||
#include "Memmap.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "../Core.h"
|
||||
|
||||
#include "EXI_Device.h"
|
||||
#include "EXI_DeviceEthernet.h"
|
||||
|
||||
//#define SONICDEBUG
|
||||
#ifdef SONICDEBUG
|
||||
#define FILEDEBUG
|
||||
#ifdef FILEDEBUG
|
||||
FILE *ME = 0;
|
||||
#endif
|
||||
#endif
|
||||
void DEBUGPRINT (const char * format, ...)
|
||||
{
|
||||
char buffer[0x1000];
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vsprintf (buffer,format, args);
|
||||
#ifdef SONICDEBUG
|
||||
#ifdef FILEDEBUG
|
||||
fprintf(ME, "%s\n", buffer);
|
||||
#endif
|
||||
printf("%s\n", buffer);
|
||||
#else
|
||||
INFO_LOG(SP1, buffer);
|
||||
#endif
|
||||
va_end (args);
|
||||
va_start(args, format);
|
||||
vsprintf(buffer,format, args);
|
||||
#ifdef SONICDEBUG
|
||||
#ifdef FILEDEBUG
|
||||
fprintf(ME, "%s\n", buffer);
|
||||
#endif
|
||||
printf("%s\n", buffer);
|
||||
#else
|
||||
INFO_LOG(SP1, buffer);
|
||||
#endif
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,19 +49,17 @@ void DEBUGPRINT (const char * format, ...)
|
|||
|
||||
#define RISE(flags) ((SwappedData & (flags)) && !(mBbaMem[0x00] & (flags)))
|
||||
|
||||
int mPacketsSent = 0;
|
||||
u8 mac_address[6] = {0x00, 0x1A, 0x4D, 0x5E, 0x64, 0x2B}; // Looks Appropriate
|
||||
unsigned int Expecting;
|
||||
static u32 mPacketsSent = 0;
|
||||
static u8 mac_address[6] = {0x00, 0x09, 0xbf, 0x01, 0x00, 0xc1}; // (shuffle2) from my bba
|
||||
static u32 Expecting;
|
||||
|
||||
CEXIETHERNET::CEXIETHERNET() :
|
||||
m_uPosition(0),
|
||||
m_uCommand(0),
|
||||
mWriteBuffer(2048),
|
||||
mCbw(mBbaMem + CB_OFFSET, CB_SIZE),
|
||||
mRecvBuffer(2048)
|
||||
mCbw(mBbaMem + CB_OFFSET, CB_SIZE)
|
||||
{
|
||||
memset(mBbaMem, 0, BBAMEM_SIZE);
|
||||
ID = 0x04020200;
|
||||
memset(mBbaMem, 0, BBA_MEM_SIZE);
|
||||
mWriteP = INVALID_P;
|
||||
mReadP = INVALID_P;
|
||||
mWaiting = false;
|
||||
|
@ -74,16 +71,16 @@ CEXIETHERNET::CEXIETHERNET() :
|
|||
mHRecvEvent = INVALID_HANDLE_VALUE;
|
||||
mHReadWait = INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
|
||||
|
||||
mRecvBufferLength = 0;
|
||||
|
||||
|
||||
mExpectSpecialImmRead = false;
|
||||
|
||||
|
||||
Expecting = EXPECT_NONE;
|
||||
mExpectVariableLengthImmWrite = false;
|
||||
#ifdef FILEDEBUG
|
||||
#ifdef FILEDEBUG
|
||||
ME = fopen("Debug.txt", "wb");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
CEXIETHERNET::~CEXIETHERNET()
|
||||
|
@ -93,32 +90,6 @@ CEXIETHERNET::~CEXIETHERNET()
|
|||
#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)
|
||||
{
|
||||
DEBUGPRINT("Set CS: %s Expect Variable write?: %s", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false");
|
||||
|
@ -155,10 +126,10 @@ bool CEXIETHERNET::IsInterruptSet()
|
|||
return m_bInterruptSet;
|
||||
}
|
||||
|
||||
void CEXIETHERNET::recordSendComplete()
|
||||
void CEXIETHERNET::recordSendComplete()
|
||||
{
|
||||
mBbaMem[BBA_NCRA] &= ~0x06;
|
||||
if(mBbaMem[BBA_IMR] & BBA_INTERRUPT_SENT)
|
||||
if (mBbaMem[BBA_IMR] & BBA_INTERRUPT_SENT)
|
||||
{
|
||||
mBbaMem[BBA_IR] |= BBA_INTERRUPT_SENT;
|
||||
DEBUGPRINT("\t\tBBA Send interrupt raised");
|
||||
|
@ -170,9 +141,9 @@ void CEXIETHERNET::recordSendComplete()
|
|||
mPacketsSent++;
|
||||
}
|
||||
|
||||
bool CEXIETHERNET::checkRecvBuffer()
|
||||
bool CEXIETHERNET::checkRecvBuffer()
|
||||
{
|
||||
if(mRecvBufferLength != 0)
|
||||
if (mRecvBufferLength != 0)
|
||||
{
|
||||
handleRecvdPacket();
|
||||
}
|
||||
|
@ -185,12 +156,12 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
if (mExpectVariableLengthImmWrite)
|
||||
{
|
||||
DEBUGPRINT("\t[INFO]Variable length IMM write");
|
||||
if(_uSize == 4)
|
||||
if (_uSize == 4)
|
||||
{
|
||||
// Correct
|
||||
_uData = Common::swap32(_uData);
|
||||
}
|
||||
else if(_uSize == 2)
|
||||
else if (_uSize == 2)
|
||||
{
|
||||
// Correct
|
||||
_uData = (u16)Common::swap32(_uData);
|
||||
|
@ -198,27 +169,27 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
mWriteBuffer.write(_uSize, &_uData);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
exit(0);
|
||||
}
|
||||
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)
|
||||
{
|
||||
case BBA_IR:
|
||||
case BBA_IR:
|
||||
{
|
||||
// Correct, we use swapped
|
||||
assert(_uSize == 1);
|
||||
_dbg_assert_(SP1, _uSize == 1);
|
||||
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));
|
||||
mBbaMem[BBA_IR] &= ~MAKE(u8, SwappedData);
|
||||
break;
|
||||
}
|
||||
case BBA_NCRA:
|
||||
case BBA_NCRA:
|
||||
{
|
||||
DEBUGPRINT("\t\t[INFO]BBA_NCRA");
|
||||
// Correct, we use the swap here
|
||||
|
@ -231,7 +202,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
}
|
||||
if (RISE(BBA_NCRA_SR) && isActivated())
|
||||
{
|
||||
DEBUGPRINT("\t\t[INFO]BBA Start Recieve");
|
||||
DEBUGPRINT("\t\t[INFO]BBA Start Receive");
|
||||
//exit(0);
|
||||
startRecv();
|
||||
}
|
||||
|
@ -249,72 +220,72 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
}
|
||||
mBbaMem[BBA_NCRA] = MAKE(u8, SwappedData);
|
||||
}
|
||||
break;
|
||||
case BBA_NWAYC:
|
||||
DEBUGPRINT("\t\t[INFO]BBA_NWAYC");
|
||||
if(Common::swap32(_uData) & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA))
|
||||
break;
|
||||
case BBA_NWAYC:
|
||||
DEBUGPRINT("\t\t[INFO]BBA_NWAYC");
|
||||
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
|
||||
//should placate libogc
|
||||
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);
|
||||
}
|
||||
DEBUGPRINT("Not activate!");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case BBA_RRP: //RRP - Receive Buffer Read Page Pointer
|
||||
DEBUGPRINT("\t\t[INFO]RRP");
|
||||
assert(_uSize == 2 || _uSize == 1);
|
||||
mRBRPP = (u8)Common::swap32(_uData) << 8; //Whinecube: I hope this works with both write sizes.
|
||||
mRBEmpty = (mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET));
|
||||
checkRecvBuffer();
|
||||
break;
|
||||
case BBA_RWP: //RWP - Receive Buffer Write Page Pointer
|
||||
DEBUGPRINT("\t\t[INFO]RWP");
|
||||
assert(_uSize == 2 || _uSize == 1);
|
||||
DEBUGPRINT("\t\t\tThing is 0x%0X", (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
|
||||
// TODO: This assert FAILS!
|
||||
//assert(Common::swap32(_uData) == (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
|
||||
break;
|
||||
case BBA_NWAYS:
|
||||
DEBUGPRINT("[ERR]Call to BBA_NWAYS directly!");
|
||||
exit(0);
|
||||
break;
|
||||
case BBA_SI_ACTRL2:
|
||||
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);
|
||||
u32 SwappedData = 0;
|
||||
if(_uSize == 4 || _uSize == 1)
|
||||
break;
|
||||
case BBA_RRP: //RRP - Receive Buffer Read Page Pointer
|
||||
DEBUGPRINT("\t\t[INFO]RRP");
|
||||
_dbg_assert_(SP1, _uSize == 2 || _uSize == 1);
|
||||
mRBRPP = (u8)Common::swap32(_uData) << 8; //Whinecube: I hope this works with both write sizes.
|
||||
mRBEmpty = (mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET));
|
||||
checkRecvBuffer();
|
||||
break;
|
||||
case BBA_RWP: //RWP - Receive Buffer Write Page Pointer
|
||||
DEBUGPRINT("\t\t[INFO]RWP");
|
||||
_dbg_assert_(SP1, _uSize == 2 || _uSize == 1);
|
||||
DEBUGPRINT("\t\t\tThing is 0x%0X", (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
|
||||
// TODO: This assert FAILS!
|
||||
//assert(Common::swap32(_uData) == (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
|
||||
break;
|
||||
case BBA_NWAYS:
|
||||
DEBUGPRINT("[ERR]Call to BBA_NWAYS directly!");
|
||||
exit(0);
|
||||
break;
|
||||
case BBA_SI_ACTRL2:
|
||||
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);
|
||||
u32 SwappedData = 0;
|
||||
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
|
||||
// Size of 4 untested Though
|
||||
SwappedData = Common::swap32(_uData);
|
||||
if(_uSize == 4)
|
||||
{
|
||||
DEBUGPRINT("\t\t\tData is 0x%08x", SwappedData);
|
||||
//exit(0);
|
||||
}
|
||||
DEBUGPRINT("\t\t\tData is 0x%08x", SwappedData);
|
||||
//exit(0);
|
||||
}
|
||||
else if( _uSize == 2)
|
||||
{
|
||||
//Correct
|
||||
SwappedData = (u16)(_uData >> 16);
|
||||
//DEBUGPRINT("\t\t\tData is 0x%04x", SwappedData);
|
||||
}
|
||||
//u32 SwappedData = _uData;
|
||||
memcpy(mBbaMem + mWriteP, &SwappedData, _uSize);
|
||||
mWriteP = mWriteP + _uSize;
|
||||
}
|
||||
else if ( _uSize == 2)
|
||||
{
|
||||
//Correct
|
||||
SwappedData = (u16)(_uData >> 16);
|
||||
//DEBUGPRINT("\t\t\tData is 0x%04x", SwappedData);
|
||||
}
|
||||
//u32 SwappedData = _uData;
|
||||
memcpy(mBbaMem + mWriteP, &SwappedData, _uSize);
|
||||
mWriteP = mWriteP + _uSize;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (_uSize == 2 && _uData == 0)
|
||||
else if (_uSize == 2 && _uData == 0)
|
||||
{
|
||||
// Device ID Request
|
||||
// 100% this returns correctly
|
||||
|
@ -333,7 +304,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
u32 SwappedData = _uData;
|
||||
mWriteP = (u8)getbitsw(SwappedData, 16, 23);
|
||||
}
|
||||
else //size == 2
|
||||
else //size == 2
|
||||
{
|
||||
// Correct, Size of 1 untested, should be correct.
|
||||
u16 SwappedData = (u16)Common::swap32(_uData >> 8);
|
||||
|
@ -341,13 +312,13 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
}
|
||||
//Write of size 4 data 0xc0006000 causes write pointer to be set to 0x0000 when swapped.
|
||||
// When not swapped, the write pointer is set to 0x0060
|
||||
if (mWriteP == 0x48)
|
||||
if (mWriteP == 0x48)
|
||||
{
|
||||
mWriteBuffer.clear();
|
||||
mExpectVariableLengthImmWrite = true;
|
||||
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", _uSize, mWriteP);
|
||||
//exit(0);
|
||||
|
@ -356,29 +327,29 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
}
|
||||
else if ((_uSize == 4 && (_uData & 0xC0000000) == 0x80000000) || (_uSize == 2 && ((u16)Common::swap32(_uData >> 8) & 0x4000) == 0x0000))
|
||||
{
|
||||
|
||||
|
||||
u32 SwappedData = _uData;
|
||||
// Read from BBA Register!
|
||||
if(_uSize == 4)
|
||||
if(_uSize == 4)
|
||||
{
|
||||
// Correct
|
||||
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);
|
||||
//if(g::bouehr)
|
||||
exit(0);
|
||||
//return EXI_UNHANDLED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
//Correct
|
||||
//size == 2
|
||||
mReadP = (u8)Common::swap32(_uData);
|
||||
}
|
||||
DEBUGPRINT("\t[INFO]Read from BBA register! 0x%X", mReadP);
|
||||
switch (mReadP)
|
||||
switch (mReadP)
|
||||
{
|
||||
case 0x20: //MAC address
|
||||
DEBUGPRINT("\t\t[INFO]Mac Address!");
|
||||
|
@ -423,7 +394,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
case 0x5c: // These two go together
|
||||
break;
|
||||
case 0x31: // NWAYS - NWAY Status Register
|
||||
// HACK
|
||||
// HACK
|
||||
activate();
|
||||
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
||||
case 0x09: // IR
|
||||
|
@ -449,16 +420,16 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
||||
{
|
||||
DEBUGPRINT("IMM Read, size 0x%x", _uSize);
|
||||
if (mExpectSpecialImmRead)
|
||||
if (mExpectSpecialImmRead)
|
||||
{
|
||||
// 100% that this returns correctly
|
||||
DEBUGPRINT("\t[INFO]special IMMRead");
|
||||
mExpectSpecialImmRead = false;
|
||||
return mSpecialImmData;
|
||||
}
|
||||
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);
|
||||
exit(0);
|
||||
|
@ -467,11 +438,11 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
|||
memcpy(&uResult, mBbaMem + mReadP, _uSize);
|
||||
// TODO: We do as well?
|
||||
uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem...
|
||||
|
||||
|
||||
//DEBUGPRINT("Mem spot is 0x%02x uResult is 0x%x", mBbaMem[mReadP], uResult);
|
||||
/*#ifndef _WIN32
|
||||
if(CheckRecieved())
|
||||
startRecv();
|
||||
startRecv();
|
||||
#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));
|
||||
mReadP = mReadP + _uSize;
|
||||
|
@ -488,13 +459,13 @@ u32 CEXIETHERNET::ImmRead(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);
|
||||
mWriteBuffer.write(_uSize, Memory::GetPointer(_uAddr));
|
||||
return;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGPRINT("Unhandled BBA DMA write: %i, 0x%08X", _uSize, _uAddr);
|
||||
//if(g::bouehr)
|
||||
|
@ -503,11 +474,11 @@ 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);
|
||||
return;
|
||||
|
@ -519,8 +490,8 @@ void CEXIETHERNET::DMARead(u32 _uAddr, u32 _uSize)
|
|||
//exit(0);
|
||||
mReadP = mReadP + _uSize;
|
||||
return;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGPRINT("Unhandled BBA DMA read: %i, 0x%08X", _uSize, _uAddr);
|
||||
//if(g::bouehr)
|
||||
|
|
|
@ -39,123 +39,24 @@ inline u32 getbitsw(u32 dword, int start, int end) {
|
|||
return (dword & makemaskw(start, end)) >> (31 - end);
|
||||
}
|
||||
|
||||
// Container Class Stolen from Whinecube
|
||||
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, ...);
|
||||
void DEBUGPRINT(const char * format, ...);
|
||||
|
||||
class WriteBuffer
|
||||
{
|
||||
public:
|
||||
WriteBuffer(u32 s) :_size(0)
|
||||
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 capacity() const { return ucapacity; }
|
||||
void write(u32 s, const void *src)
|
||||
{
|
||||
if (_size + s >= ucapacity)
|
||||
{
|
||||
printf("Write too large!");
|
||||
DEBUGPRINT("Write too large!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -171,112 +72,55 @@ private:
|
|||
u32 _size;
|
||||
};
|
||||
|
||||
//Doesn't contain error checks for wraparound writes
|
||||
// Doesn't contain error checks for wraparound writes
|
||||
class CyclicBufferWriter
|
||||
{
|
||||
public:
|
||||
CyclicBufferWriter(u8 *buffer, size_t cap)
|
||||
{
|
||||
_buffer = buffer; _cap = cap; _write = 0;
|
||||
CyclicBufferWriter(u8 *buffer, size_t cap) {
|
||||
_buffer = buffer; _capacity = cap; _write = 0;
|
||||
}
|
||||
|
||||
size_t p_write() const { return _write; }
|
||||
void reset() { _write = 0; }
|
||||
|
||||
void write(void *src, size_t size);
|
||||
void align(); //aligns the write pointer to steps of 0x100, like the real BBA
|
||||
void write(void *src, size_t size) {
|
||||
_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:
|
||||
size_t _write;
|
||||
size_t _cap; //capacity
|
||||
size_t _capacity;
|
||||
u8 *_buffer;
|
||||
};
|
||||
|
||||
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;
|
||||
#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
|
||||
};
|
||||
#define INVALID_P 0xFFFF
|
||||
|
||||
// TODO: convert into unions
|
||||
enum
|
||||
{
|
||||
BBA_RECV_SIZE = 0x800,
|
||||
BBA_MEM_SIZE = 0x1000,
|
||||
|
||||
CB_OFFSET = 0x100,
|
||||
CB_SIZE = (BBAMEM_SIZE - CB_OFFSET),
|
||||
CB_SIZE = (BBA_MEM_SIZE - CB_OFFSET),
|
||||
SIZEOF_RECV_DESCRIPTOR = 4,
|
||||
|
||||
EXI_DEVTYPE_ETHER = 0x04020200,
|
||||
|
@ -286,7 +130,7 @@ enum
|
|||
BBA_NCRA_ST0 = 0x02, // ST0, Start transmit command/status
|
||||
BBA_NCRA_ST1 = 0x04, // ST1, "
|
||||
BBA_NCRA_SR = 0x08, // SR, Start Receive
|
||||
|
||||
|
||||
BBA_NCRB = 0x01, // Network Control Register B, RW
|
||||
BBA_NCRB_PR = 0x01, // PR, Promiscuous Mode
|
||||
BBA_NCRB_CA = 0x02, // CA, Capture Effect Mode
|
||||
|
@ -300,7 +144,7 @@ enum
|
|||
BBA_NCRB_2_PACKETS_PER_INT = 0x40, // 0 1
|
||||
BBA_NCRB_4_PACKETS_PER_INT = 0x80, // 1 0
|
||||
BBA_NCRB_8_PACKETS_PER_INT = 0xC0, // 1 1
|
||||
|
||||
|
||||
BBA_IMR = 0x08, // Interrupt Mask Register, RW, 00h
|
||||
|
||||
BBA_IR = 0x09, // Interrupt Register, RW, 00h
|
||||
|
@ -330,7 +174,7 @@ enum
|
|||
BBA_NWAYS_10TXF = 0x40,
|
||||
BBA_NWAYS_10TXH = 0x80,
|
||||
|
||||
BBA_INTERRUPT_RECV = 0x02,
|
||||
BBA_INTERRUPT_RECV = 0x02,
|
||||
BBA_INTERRUPT_SENT = 0x04,
|
||||
BBA_INTERRUPT_RECV_ERROR = 0x08,
|
||||
BBA_INTERRUPT_SEND_ERROR = 0x10,
|
||||
|
@ -341,4 +185,81 @@ enum
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue