From ad0db37fab9358586fb6ea1417b1241ebe95a87e Mon Sep 17 00:00:00 2001 From: Sonicadvance1 Date: Mon, 11 May 2009 20:19:12 +0000 Subject: [PATCH] More work. Going to seperate the TAP interface from the actual BBA emulation just like in Whinecube. The Unix and Win32 code will most likely be different, so I've seperated the files in to two to make it easier. Someone will need to add TAP_Win32.cpp to the Windows build or you won't be able to compile in Windows anymore. Both Mario Kart: DD and PSO run with BBA enabled, but it does nothing yet due to no actual networking going anywhere. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3204 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp | 38 +++++++++++ Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp | 38 +++++++++++ .../Core/Core/Src/HW/EXI_DeviceEthernet.cpp | 67 ++++++++++++------- Source/Core/Core/Src/HW/EXI_DeviceEthernet.h | 34 +++++++++- Source/Core/Core/Src/SConscript | 1 + 5 files changed, 152 insertions(+), 26 deletions(-) create mode 100644 Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp create mode 100644 Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp 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",