Found out why I was getting unexpected IMM writes. I'm retarded, thank you very much
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3280 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
e97315d0ff
commit
57ae06fe66
|
@ -65,6 +65,7 @@ bool CEXIETHERNET::activate() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DEBUGPRINT("Returned Socket name is: %s\n", ifr.ifr_name);
|
DEBUGPRINT("Returned Socket name is: %s\n", ifr.ifr_name);
|
||||||
|
resume();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -72,48 +73,74 @@ bool CEXIETHERNET::CheckRecieved()
|
||||||
{
|
{
|
||||||
if(!isActivated())
|
if(!isActivated())
|
||||||
return false;
|
return false;
|
||||||
char RBuffer[2048]; // Bigger than MTU, but w/e
|
int i;
|
||||||
int Size = recv(fd, RBuffer, 2048, MSG_PEEK);
|
int maxfd;
|
||||||
if(Size == -1)
|
int retval;
|
||||||
{
|
struct timeval tv;
|
||||||
DEBUGPRINT("Recieve check failed with %d\n", errno);
|
int timeout = 3; // 3 seconds will kill him
|
||||||
return false;
|
fd_set mask;
|
||||||
|
|
||||||
|
/* Find the largest file descriptor */
|
||||||
|
maxfd = fd;
|
||||||
|
|
||||||
|
/* Check the file descriptors for available data */
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* Set up the mask of file descriptors */
|
||||||
|
FD_ZERO(&mask);
|
||||||
|
|
||||||
|
FD_SET(fd, &mask);
|
||||||
|
|
||||||
|
/* Set up the timeout */
|
||||||
|
tv.tv_sec = timeout/1000;
|
||||||
|
tv.tv_usec = (timeout%1000)*1000;
|
||||||
|
|
||||||
|
/* Look! */
|
||||||
|
retval = select(maxfd+1, &mask, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
/* Mark all file descriptors ready that have data available */
|
||||||
|
if ( retval > 0 ) {
|
||||||
|
if ( FD_ISSET(fd, &mask) )
|
||||||
|
{
|
||||||
|
DEBUGPRINT("\t\t\t\tWe have data!\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(Size != 0)
|
return false;
|
||||||
DEBUGPRINT("Have waiting Packet of size %d\n", Size);
|
}
|
||||||
|
bool CEXIETHERNET::resume() {
|
||||||
|
if(!isActivated())
|
||||||
|
return true;
|
||||||
|
DEBUGPRINT("BBA resume\n");
|
||||||
|
if(mBbaMem[BBA_NCRA] & BBA_NCRA_SR) {
|
||||||
|
startRecv();
|
||||||
|
}
|
||||||
|
DEBUGPRINT("BBA resume complete\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::startRecv() {
|
bool CEXIETHERNET::startRecv() {
|
||||||
DEBUGPRINT("Start Receive!\n");
|
DEBUGPRINT("Start Receive!\n");
|
||||||
exit(0);
|
//exit(0);
|
||||||
/*if(!isActivated())
|
if(!isActivated())
|
||||||
return false;// Should actually be an assert
|
return false;// Should actually be an assert
|
||||||
|
if(!CheckRecieved()) // Check if we have data
|
||||||
|
return false; // Nope
|
||||||
DEBUGPRINT("startRecv... ");
|
DEBUGPRINT("startRecv... ");
|
||||||
if(mWaiting) {
|
if(mWaiting) {
|
||||||
DEBUGPRINT("already waiting\n");
|
DEBUGPRINT("already waiting\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
DWORD BytesRead = 0;
|
u32 BytesRead = 0;
|
||||||
DWORD *Buffer = (DWORD *)malloc(2048); // Should be enough
|
u8 B[2];
|
||||||
DWORD res = ReadFile(mHAdapter, Buffer, BytesRead,
|
int Num = 0;
|
||||||
&mRecvBufferLength, &mReadOverlapped);
|
while(read(fd, B, 1))
|
||||||
mRecvBuffer.write(BytesRead, Buffer);
|
{
|
||||||
free(Buffer);
|
DEBUGPRINT("Read 1 Byte!\n");
|
||||||
if(res) { //Operation completed immediately
|
mRecvBuffer.write(1, B);
|
||||||
DEBUGPRINT("completed, res %i\n", res);
|
Num++;
|
||||||
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;*/
|
DEBUGPRINT("Read %d bytes\n", Num);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,18 +45,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;
|
int mPacketsSent = 0;
|
||||||
u8 mac_address[6] = {0x4D, 0xFF, 0x11, 0x88, 0xF1, 0x76};
|
u8 mac_address[6] = {'D', 'O', 'L', 'P', 'H', 'I'}; // Looks Appropriate
|
||||||
unsigned int Expecting;
|
unsigned int Expecting;
|
||||||
|
|
||||||
CEXIETHERNET::CEXIETHERNET() :
|
CEXIETHERNET::CEXIETHERNET() :
|
||||||
m_uPosition(0),
|
m_uPosition(0),
|
||||||
m_uCommand(0),
|
m_uCommand(0),
|
||||||
mWriteBuffer(2048),
|
mWriteBuffer(2048),
|
||||||
#ifdef _WIN32
|
mCbw(mBbaMem + CB_OFFSET, CB_SIZE),
|
||||||
mRecvBuffer(2048),
|
mRecvBuffer(2048)
|
||||||
#endif
|
|
||||||
mCbw(mBbaMem + CB_OFFSET, CB_SIZE)
|
|
||||||
{
|
{
|
||||||
|
memset(mBbaMem, 0, BBAMEM_SIZE);
|
||||||
ID = 0x04020200;
|
ID = 0x04020200;
|
||||||
mWriteP = INVALID_P;
|
mWriteP = INVALID_P;
|
||||||
mReadP = INVALID_P;
|
mReadP = INVALID_P;
|
||||||
|
@ -80,8 +79,8 @@ CEXIETHERNET::CEXIETHERNET() :
|
||||||
|
|
||||||
void CEXIETHERNET::SetCS(int cs)
|
void CEXIETHERNET::SetCS(int cs)
|
||||||
{
|
{
|
||||||
DEBUGPRINT("Set CS: %s\n", cs ? "true" : "false");
|
DEBUGPRINT("Set CS: %s Expect Variable write?: %s\n", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false");
|
||||||
if (!cs)
|
if (cs)
|
||||||
{
|
{
|
||||||
if (mExpectVariableLengthImmWrite)
|
if (mExpectVariableLengthImmWrite)
|
||||||
{
|
{
|
||||||
|
@ -135,9 +134,11 @@ bool CEXIETHERNET::checkRecvBuffer()
|
||||||
}
|
}
|
||||||
void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
{
|
{
|
||||||
//DEBUGPRINT( "IMM Write, size 0x%x, data 0x%x mWriteP 0x%x\n", _uSize, _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");
|
||||||
// TODO: Use Swapped or unswapped?
|
// TODO: Use Swapped or unswapped?
|
||||||
if(_uSize == 4)
|
if(_uSize == 4)
|
||||||
{
|
{
|
||||||
|
@ -163,7 +164,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
{
|
{
|
||||||
case BBA_IR:
|
case BBA_IR:
|
||||||
{
|
{
|
||||||
//BBADEGUB("BBA Interrupt reset 0x%02X & ~(0x%02X) => 0x%02X\n", mBbaMem[0x09], MAKE(BYTE, data), mBbaMem[0x09] & ~MAKE(BYTE, data));
|
DEBUGPRINT("\t\t[INFO]BBA Interrupt reset 0x%02X & ~(0x%02X) => 0x%02X\n", mBbaMem[0x09], MAKE(u8, _uData), mBbaMem[0x09] & ~MAKE(u8, _uData));
|
||||||
//assert(_uSize == 1);
|
//assert(_uSize == 1);
|
||||||
// TODO: Should we swap our data?
|
// TODO: Should we swap our data?
|
||||||
// With _uData not swapped, it becomes 0 when the data is 0xff000000
|
// With _uData not swapped, it becomes 0 when the data is 0xff000000
|
||||||
|
@ -171,14 +172,13 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
//u32 SwappedData = Common::swap32(_uData);
|
//u32 SwappedData = Common::swap32(_uData);
|
||||||
u32 SwappedData = _uData;
|
u32 SwappedData = _uData;
|
||||||
mBbaMem[BBA_IR] &= ~MAKE(u8, SwappedData);
|
mBbaMem[BBA_IR] &= ~MAKE(u8, SwappedData);
|
||||||
DEBUGPRINT( "\t\t[INFO]mWriteP is %x. mBbaMem[0x09] is 0x%x\n", mWriteP, mBbaMem[0x09]);
|
|
||||||
//exit(0);
|
//exit(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BBA_NCRA:
|
case BBA_NCRA:
|
||||||
{
|
{
|
||||||
// Correct, we use the swap here
|
// Correct, we use the swap here
|
||||||
u32 SwappedData = Common::swap32(_uData);
|
u32 SwappedData = (u8)Common::swap32(_uData);
|
||||||
//u32 SwappedData = _uData;
|
//u32 SwappedData = _uData;
|
||||||
// TODO: Should we swap our data?
|
// TODO: Should we swap our data?
|
||||||
if (RISE(BBA_NCRA_RESET))
|
if (RISE(BBA_NCRA_RESET))
|
||||||
|
@ -218,8 +218,9 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
activate();
|
activate();
|
||||||
//say we've successfully negotiated for 10 Mbit full duplex
|
//say we've successfully negotiated for 10 Mbit full duplex
|
||||||
//should placate libogc
|
//should placate libogc
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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\n");
|
||||||
|
@ -236,7 +237,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
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(" Call to BBA_NWAYS directly!\n");
|
DEBUGPRINT("[ERR]Call to BBA_NWAYS directly!\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
case BBA_SI_ACTRL2:
|
case BBA_SI_ACTRL2:
|
||||||
|
@ -259,16 +260,22 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
mExpectSpecialImmRead = true;
|
mExpectSpecialImmRead = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((_uSize == 4 && (_uData & 0xC0000000) == 0xC0000000) || (_uSize == 2 && (_uData & 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!\n");
|
||||||
//u32 SwappedData = Common::swap32(_uData);
|
|
||||||
u32 SwappedData = _uData;
|
// Dunno if this is correct TODO
|
||||||
if (_uSize == 4)
|
if (_uSize == 4)
|
||||||
|
{
|
||||||
|
u32 SwappedData = _uData;
|
||||||
mWriteP = (u8)getbitsw(SwappedData, 16, 23);
|
mWriteP = (u8)getbitsw(SwappedData, 16, 23);
|
||||||
|
}
|
||||||
else //size == 2
|
else //size == 2
|
||||||
|
{
|
||||||
|
u16 SwappedData = (u16)Common::swap32(_uData >> 8);
|
||||||
mWriteP = (u8)getbitsw(SwappedData & ~0x4000, 16, 23); //Whinecube : Dunno about this...
|
mWriteP = (u8)getbitsw(SwappedData & ~0x4000, 16, 23); //Whinecube : Dunno about this...
|
||||||
|
}
|
||||||
//Write of size 4 data 0xc0006000 causes write pointer to be set to 0x0000 when swapped.
|
//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
|
// When not swapped, the write pointer is set to 0x0060
|
||||||
if (mWriteP == 0x48)
|
if (mWriteP == 0x48)
|
||||||
|
@ -284,15 +291,14 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((_uSize == 4 && (_uData & 0xC0000000) == 0x80000000) || (_uSize == 2 && (_uData & 0x4000) == 0x0000))
|
else if ((_uSize == 4 && (_uData & 0xC0000000) == 0x80000000) || (_uSize == 2 && ((u16)Common::swap32(_uData >> 8) & 0x4000) == 0x0000))
|
||||||
{
|
{
|
||||||
//DEBUGPRINT( "\t[INFO]Read from BBA register!\n");
|
|
||||||
// Non-Swapped is the correct way
|
// Non-Swapped is the correct way
|
||||||
u32 SwappedData = _uData;
|
u32 SwappedData = _uData;
|
||||||
// Read from BBA Register!
|
// Read from BBA Register!
|
||||||
if(_uSize == 4)
|
if(_uSize == 4)
|
||||||
{
|
{
|
||||||
mReadP = (u32)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\n", mReadP);
|
||||||
|
@ -303,14 +309,13 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //size == 2
|
{ //size == 2
|
||||||
mReadP = (u16)getbitsw(SwappedData, 16, 23);
|
mReadP = (u8)getbitsw(SwappedData, 16, 23);
|
||||||
}
|
}
|
||||||
// With the data not swapped,after a few reads, nReadP is always 0 in Mario Kart: DD; Size always 2
|
DEBUGPRINT( "\t[INFO]Read from BBA register! 0x%X\n", mReadP);
|
||||||
// Before that, it does request the MAC address if it's unswapped
|
|
||||||
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!\n");
|
||||||
memcpy(mBbaMem + mReadP, mac_address, 6);
|
memcpy(mBbaMem + mReadP, mac_address, 6);
|
||||||
break;
|
break;
|
||||||
case 0x01: //Revision ID
|
case 0x01: //Revision ID
|
||||||
|
@ -354,7 +359,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
|
|
||||||
u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
||||||
{
|
{
|
||||||
//DEBUGPRINT( "IMM Read, size 0x%x\n", _uSize);
|
DEBUGPRINT( "IMM Read, size 0x%x\n", _uSize);
|
||||||
if (mExpectSpecialImmRead)
|
if (mExpectSpecialImmRead)
|
||||||
{
|
{
|
||||||
// 100% that this returns correctly
|
// 100% that this returns correctly
|
||||||
|
@ -370,14 +375,6 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
u32 uResult = 0;
|
u32 uResult = 0;
|
||||||
switch(mReadP)
|
|
||||||
{
|
|
||||||
case BBA_NWAYS: // Bit of a hack
|
|
||||||
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
memcpy(&uResult, mBbaMem + mReadP, _uSize);
|
memcpy(&uResult, mBbaMem + mReadP, _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...
|
||||||
|
|
|
@ -113,9 +113,6 @@ private:
|
||||||
|
|
||||||
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
||||||
bool mRBEmpty;
|
bool mRBEmpty;
|
||||||
#ifndef _WIN32
|
|
||||||
u32 mRecvBufferLength;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BBAMEM_SIZE 0x1000
|
#define BBAMEM_SIZE 0x1000
|
||||||
u8 mBbaMem[BBAMEM_SIZE];
|
u8 mBbaMem[BBAMEM_SIZE];
|
||||||
|
@ -146,11 +143,12 @@ private:
|
||||||
bool startRecv();
|
bool startRecv();
|
||||||
|
|
||||||
volatile bool mWaiting;
|
volatile bool mWaiting;
|
||||||
|
WriteBuffer mRecvBuffer;
|
||||||
|
u32 mRecvBufferLength;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
||||||
DWORD mMtu;
|
DWORD mMtu;
|
||||||
OVERLAPPED mReadOverlapped;
|
OVERLAPPED mReadOverlapped;
|
||||||
WriteBuffer mRecvBuffer;
|
|
||||||
DWORD mRecvBufferLength;
|
DWORD mRecvBufferLength;
|
||||||
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue