diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp new file mode 100644 index 0000000000..14dcb3db6d --- /dev/null +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2003-2009 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "../Memmap.h" +#include "../EXI_Device.h" +#include "../EXI_DeviceEthernet.h" +bool CEXIETHERNET::deactivate() +{ + return true; + // TODO: Actually deactivate +} +bool CEXIETHERNET::isActivated() +{ + return false; + //TODO: Never Activated Yet! +} + +bool CEXIETHERNET::activate() { + if(isActivated()) + return true; + else + return false; + //TODO: Activate Device! +} diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp new file mode 100644 index 0000000000..14dcb3db6d --- /dev/null +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2003-2009 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "../Memmap.h" +#include "../EXI_Device.h" +#include "../EXI_DeviceEthernet.h" +bool CEXIETHERNET::deactivate() +{ + return true; + // TODO: Actually deactivate +} +bool CEXIETHERNET::isActivated() +{ + return false; + //TODO: Never Activated Yet! +} + +bool CEXIETHERNET::activate() { + if(isActivated()) + return true; + else + return false; + //TODO: Activate Device! +} diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp index 198e0bd5b3..3961a30944 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp @@ -17,6 +17,7 @@ #include "Memmap.h" +#include #include "../Core.h" #include "EXI_Device.h" @@ -69,7 +70,8 @@ unsigned int Expecting; CEXIETHERNET::CEXIETHERNET() : m_uPosition(0), m_uCommand(0), - mWriteBuffer(2048) + mWriteBuffer(2048), + mCbw(mBbaMem + CB_OFFSET, CB_SIZE) { ID = 0x04020200; mWriteP = INVALID_P; @@ -77,6 +79,8 @@ CEXIETHERNET::CEXIETHERNET() : mReadyToSend = false; Activated = false; + mRecvBufferLength = 0; + mExpectSpecialImmRead = false; Expecting = EXPECT_NONE; @@ -112,11 +116,6 @@ bool CEXIETHERNET::IsInterruptSet() { return false; } -bool CEXIETHERNET::isActivated() -{ - // Todo: Return actual check - return Activated; -} void CEXIETHERNET::recordSendComplete() { @@ -153,7 +152,19 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size) //exit(0); return true; } - +bool CEXIETHERNET::handleRecvdPacket() +{ + DEBUGPRINT(" Handle received Packet!\n"); + exit(0); +} +bool CEXIETHERNET::checkRecvBuffer() +{ + if(mRecvBufferLength != 0) + { + handleRecvdPacket(); + } + return true; +} void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) { DEBUGPRINT( "IMM Write, size 0x%x, data 0x%x mWriteP 0x%x\n", _uSize, _uData, mWriteP); @@ -174,13 +185,18 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) switch (mWriteP) { case 0x09: - DEBUGPRINT( "\t[INFO]mWriteP is %x\n", mWriteP); + { //BBADEGUB("BBA Interrupt reset 0x%02X & ~(0x%02X) => 0x%02X\n", mBbaMem[0x09], MAKE(BYTE, data), mBbaMem[0x09] & ~MAKE(BYTE, data)); //assert(_uSize == 1); // TODO: Should we swap our data? - mBbaMem[0x09] &= ~MAKE(u8, _uData); - exit(0); + // With _uData not swapped, it becomes 0 when the data is 0xff000000 + // With _uData swapped, it becomes 0 as well. Who knows the right way? + u32 SwappedData = Common::swap32(_uData); + mBbaMem[0x09] &= ~MAKE(u8, SwappedData); + DEBUGPRINT( "\t[INFO]mWriteP is %x. mBbaMem[0x09] is 0x%x\n", mWriteP, mBbaMem[0x09]); + //exit(0); break; + } case BBA_NCRA: { u32 SwappedData = Common::swap32(_uData); @@ -217,28 +233,27 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) } break; case BBA_NWAYC: - DEBUGPRINT( "\t[INFO]mWriteP is %x\n", mWriteP); - exit(0); - /*if(data & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA)) + DEBUGPRINT( "\t[INFO]BBA_NWAYCn"); + if(_uData & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA)) { - HWGLE(activate()); + 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; - }*/ + } break; case 0x18: //RRP - Receive Buffer Read Page Pointer - DEBUGPRINT( "\t[INFO]mWriteP is %x\n", mWriteP); - exit(0); - /*MYASSERT(size == 2 || size == 1); - mRBRPP = (BYTE)data << 8; //I hope this works with both write sizes. - mRBEmpty = mRBRPP == ((WORD)mCbw.p_write() + CB_OFFSET); - HWGLE(checkRecvBuffer());*/ + DEBUGPRINT( "\t[INFO]RRP\n"); + //exit(0); + assert(_uSize == 2 || _uSize == 1); + mRBRPP = (u8)_uData << 8; //Whinecube: I hope this works with both write sizes. + mRBEmpty = mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET); + checkRecvBuffer(); break; - case 0x16: //RWP - DEBUGPRINT( "\t[INFO]mWriteP is %x\n", mWriteP); - exit(0); + case 0x16: //RWP - Receive Buffer Write Page Pointer + DEBUGPRINT( "\t[INFO]RWP\n"); + //exit(0); /*MYASSERT(size == 2 || size == 1); MYASSERT(data == DWORD((WORD)mCbw.p_write() + CB_OFFSET) >> 8);*/ break; @@ -255,6 +270,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) { // Device ID Request // 100% this returns correctly + DEBUGPRINT( "\t[INFO]Request Dev ID\n"); mSpecialImmData = EXI_DEVTYPE_ETHER; mExpectSpecialImmRead = true; return; @@ -350,7 +366,8 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize) return; } DEBUGPRINT( "\t[EEE]Not expecting ImmWrite of size %d\n", _uSize); - exit(0); + DEBUGPRINT( "\t\t[INFO] SKIPPING!\n"); + //exit(0); } u32 CEXIETHERNET::ImmRead(u32 _uSize) diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h index d84aeff2ef..fc724b3718 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h @@ -46,6 +46,26 @@ private: u32 _size; }; +//Doesn't contain error checks for wraparound writes +class CyclicBufferWriter +{ + public: + CyclicBufferWriter(u8 *buffer, size_t cap) + { + _buffer = buffer; _cap = 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 + private: + size_t _write; + size_t _cap; //capacity + u8 *_buffer; +}; + class CEXIETHERNET : public IEXIDevice { public: @@ -54,7 +74,6 @@ public: bool IsPresent(); void Update(); bool IsInterruptSet(); - bool isActivated(); void ImmWrite(u32 _uData, u32 _uSize); u32 ImmRead(u32 _uSize); void DMAWrite(u32 _uAddr, u32 _uSize); @@ -72,10 +91,16 @@ private: u32 mSpecialImmData; bool Activated; + u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer + bool mRBEmpty; + + u32 mRecvBufferLength; + #define BBAMEM_SIZE 0x1000 u8 mBbaMem[BBAMEM_SIZE]; WriteBuffer mWriteBuffer; + CyclicBufferWriter mCbw; bool mExpectVariableLengthImmWrite; bool mReadyToSend; @@ -88,6 +113,13 @@ private: void recordSendComplete(); bool sendPacket(u8 *etherpckt, int size); + bool checkRecvBuffer(); + bool handleRecvdPacket(); + + //TAP interface + bool activate(); + bool deactivate(); + bool isActivated(); }; enum { diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript index 2011b8cb26..97a2bf7d5c 100644 --- a/Source/Core/Core/Src/SConscript +++ b/Source/Core/Core/Src/SConscript @@ -42,6 +42,7 @@ files = ["ActionReplay.cpp", "HW/EXI_DeviceMemoryCard.cpp", "HW/EXI_DeviceMic.cpp", "HW/EXI_DeviceEthernet.cpp", + "HW/BBA-TAP/TAP_Unix.cpp", "HW/GPFifo.cpp", "HW/HW.cpp", "HW/Memmap.cpp",