From 57ae06fe66fbc8cc22be441ea26516d2502e2cdc Mon Sep 17 00:00:00 2001 From: Sonicadvance1 Date: Sun, 24 May 2009 11:05:30 +0000 Subject: [PATCH] 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 --- Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp | 87 ++++++++++++------- .../Core/Core/Src/HW/EXI_DeviceEthernet.cpp | 63 +++++++------- Source/Core/Core/Src/HW/EXI_DeviceEthernet.h | 6 +- 3 files changed, 89 insertions(+), 67 deletions(-) diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp index 87a9cfa337..67d9d70556 100644 --- a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp @@ -65,6 +65,7 @@ bool CEXIETHERNET::activate() { } #endif DEBUGPRINT("Returned Socket name is: %s\n", ifr.ifr_name); + resume(); return true; } @@ -72,48 +73,74 @@ bool CEXIETHERNET::CheckRecieved() { if(!isActivated()) return false; - char RBuffer[2048]; // Bigger than MTU, but w/e - int Size = recv(fd, RBuffer, 2048, MSG_PEEK); - if(Size == -1) - { - DEBUGPRINT("Recieve check failed with %d\n", errno); - return false; + int i; + int maxfd; + int retval; + struct timeval tv; + int timeout = 3; // 3 seconds will kill him + 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) - DEBUGPRINT("Have waiting Packet of size %d\n", Size); + return false; +} +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; } - bool CEXIETHERNET::startRecv() { DEBUGPRINT("Start Receive!\n"); - exit(0); - /*if(!isActivated()) + //exit(0); + if(!isActivated()) return false;// Should actually be an assert + if(!CheckRecieved()) // Check if we have data + return false; // Nope DEBUGPRINT("startRecv... "); if(mWaiting) { DEBUGPRINT("already waiting\n"); return true; } - DWORD BytesRead = 0; - DWORD *Buffer = (DWORD *)malloc(2048); // Should be enough - DWORD res = ReadFile(mHAdapter, Buffer, BytesRead, - &mRecvBufferLength, &mReadOverlapped); - mRecvBuffer.write(BytesRead, Buffer); - free(Buffer); - 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; - } + u32 BytesRead = 0; + u8 B[2]; + int Num = 0; + while(read(fd, B, 1)) + { + DEBUGPRINT("Read 1 Byte!\n"); + mRecvBuffer.write(1, B); + Num++; } - return true;*/ + DEBUGPRINT("Read %d bytes\n", Num); + return true; } bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size) { diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp index 96042abc90..056798e756 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp @@ -45,18 +45,17 @@ void DEBUGPRINT (const char * format, ...) #define RISE(flags) ((SwappedData & (flags)) && !(mBbaMem[0x00] & (flags))) 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; CEXIETHERNET::CEXIETHERNET() : m_uPosition(0), m_uCommand(0), mWriteBuffer(2048), -#ifdef _WIN32 - mRecvBuffer(2048), -#endif - mCbw(mBbaMem + CB_OFFSET, CB_SIZE) + mCbw(mBbaMem + CB_OFFSET, CB_SIZE), + mRecvBuffer(2048) { + memset(mBbaMem, 0, BBAMEM_SIZE); ID = 0x04020200; mWriteP = INVALID_P; mReadP = INVALID_P; @@ -80,8 +79,8 @@ CEXIETHERNET::CEXIETHERNET() : void CEXIETHERNET::SetCS(int cs) { - DEBUGPRINT("Set CS: %s\n", cs ? "true" : "false"); - if (!cs) + DEBUGPRINT("Set CS: %s Expect Variable write?: %s\n", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false"); + if (cs) { if (mExpectVariableLengthImmWrite) { @@ -135,9 +134,11 @@ bool CEXIETHERNET::checkRecvBuffer() } 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) { + DEBUGPRINT("\t[INFO]Variable length IMM write\n"); // TODO: Use Swapped or unswapped? if(_uSize == 4) { @@ -163,7 +164,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) { 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); // TODO: Should we swap our data? // 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 = _uData; mBbaMem[BBA_IR] &= ~MAKE(u8, SwappedData); - DEBUGPRINT( "\t\t[INFO]mWriteP is %x. mBbaMem[0x09] is 0x%x\n", mWriteP, mBbaMem[0x09]); //exit(0); break; } case BBA_NCRA: { // Correct, we use the swap here - u32 SwappedData = Common::swap32(_uData); + u32 SwappedData = (u8)Common::swap32(_uData); //u32 SwappedData = _uData; // TODO: Should we swap our data? if (RISE(BBA_NCRA_RESET)) @@ -218,8 +218,9 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) activate(); //say we've successfully negotiated for 10 Mbit full duplex //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; case BBA_RRP: //RRP - Receive Buffer Read Page Pointer 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); break; case BBA_NWAYS: - DEBUGPRINT(" Call to BBA_NWAYS directly!\n"); + DEBUGPRINT("[ERR]Call to BBA_NWAYS directly!\n"); exit(0); break; case BBA_SI_ACTRL2: @@ -259,16 +260,22 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) mExpectSpecialImmRead = true; 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 - //DEBUGPRINT( "\t[INFO]Write to BBA register!\n"); - //u32 SwappedData = Common::swap32(_uData); - u32 SwappedData = _uData; + DEBUGPRINT( "\t[INFO]Write to BBA register!\n"); + + // Dunno if this is correct TODO if (_uSize == 4) + { + u32 SwappedData = _uData; mWriteP = (u8)getbitsw(SwappedData, 16, 23); + } else //size == 2 + { + u16 SwappedData = (u16)Common::swap32(_uData >> 8); 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. // When not swapped, the write pointer is set to 0x0060 if (mWriteP == 0x48) @@ -284,15 +291,14 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) } 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 u32 SwappedData = _uData; // Read from BBA Register! if(_uSize == 4) { - mReadP = (u32)getbitsw(SwappedData, 8, 23); + mReadP = (u16)getbitsw(SwappedData, 8, 23); if (mReadP >= BBAMEM_SIZE) { DEBUGPRINT( "\t\t[EEE]Illegal BBA address: 0x%04X\n", mReadP); @@ -303,14 +309,13 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) } else { //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 - // Before that, it does request the MAC address if it's unswapped + DEBUGPRINT( "\t[INFO]Read from BBA register! 0x%X\n", mReadP); switch (mReadP) { case 0x20: //MAC address - //DEBUGPRINT( "\t\t[INFO]Mac Address!\n"); + DEBUGPRINT( "\t\t[INFO]Mac Address!\n"); memcpy(mBbaMem + mReadP, mac_address, 6); break; case 0x01: //Revision ID @@ -354,7 +359,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, 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) { // 100% that this returns correctly @@ -370,14 +375,6 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize) exit(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); // TODO: We do as well? uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem... diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h index 706a4095c8..ac05b1d8c9 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h @@ -113,9 +113,6 @@ private: u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer bool mRBEmpty; -#ifndef _WIN32 - u32 mRecvBufferLength; -#endif #define BBAMEM_SIZE 0x1000 u8 mBbaMem[BBAMEM_SIZE]; @@ -146,11 +143,12 @@ private: bool startRecv(); volatile bool mWaiting; + WriteBuffer mRecvBuffer; + u32 mRecvBufferLength; #ifdef _WIN32 HANDLE mHAdapter, mHRecvEvent, mHReadWait; DWORD mMtu; OVERLAPPED mReadOverlapped; - WriteBuffer mRecvBuffer; DWORD mRecvBufferLength; static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired); #endif