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
This commit is contained in:
Sonicadvance1 2009-05-11 20:19:12 +00:00
parent e7af5a31bd
commit ad0db37fab
5 changed files with 152 additions and 26 deletions

View File

@ -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!
}

View File

@ -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!
}

View File

@ -17,6 +17,7 @@
#include "Memmap.h" #include "Memmap.h"
#include <assert.h>
#include "../Core.h" #include "../Core.h"
#include "EXI_Device.h" #include "EXI_Device.h"
@ -69,7 +70,8 @@ unsigned int Expecting;
CEXIETHERNET::CEXIETHERNET() : CEXIETHERNET::CEXIETHERNET() :
m_uPosition(0), m_uPosition(0),
m_uCommand(0), m_uCommand(0),
mWriteBuffer(2048) mWriteBuffer(2048),
mCbw(mBbaMem + CB_OFFSET, CB_SIZE)
{ {
ID = 0x04020200; ID = 0x04020200;
mWriteP = INVALID_P; mWriteP = INVALID_P;
@ -77,6 +79,8 @@ CEXIETHERNET::CEXIETHERNET() :
mReadyToSend = false; mReadyToSend = false;
Activated = false; Activated = false;
mRecvBufferLength = 0;
mExpectSpecialImmRead = false; mExpectSpecialImmRead = false;
Expecting = EXPECT_NONE; Expecting = EXPECT_NONE;
@ -112,11 +116,6 @@ bool CEXIETHERNET::IsInterruptSet()
{ {
return false; return false;
} }
bool CEXIETHERNET::isActivated()
{
// Todo: Return actual check
return Activated;
}
void CEXIETHERNET::recordSendComplete() void CEXIETHERNET::recordSendComplete()
{ {
@ -153,7 +152,19 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
//exit(0); //exit(0);
return true; 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) 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, data 0x%x mWriteP 0x%x\n", _uSize, _uData, mWriteP);
@ -174,13 +185,18 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
switch (mWriteP) switch (mWriteP)
{ {
case 0x09: 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)); //BBADEGUB("BBA Interrupt reset 0x%02X & ~(0x%02X) => 0x%02X\n", mBbaMem[0x09], MAKE(BYTE, data), mBbaMem[0x09] & ~MAKE(BYTE, data));
//assert(_uSize == 1); //assert(_uSize == 1);
// TODO: Should we swap our data? // TODO: Should we swap our data?
mBbaMem[0x09] &= ~MAKE(u8, _uData); // With _uData not swapped, it becomes 0 when the data is 0xff000000
exit(0); // 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; break;
}
case BBA_NCRA: case BBA_NCRA:
{ {
u32 SwappedData = Common::swap32(_uData); u32 SwappedData = Common::swap32(_uData);
@ -217,28 +233,27 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
} }
break; break;
case BBA_NWAYC: case BBA_NWAYC:
DEBUGPRINT( "\t[INFO]mWriteP is %x\n", mWriteP); DEBUGPRINT( "\t[INFO]BBA_NWAYCn");
exit(0); if(_uData & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA))
/*if(data & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA))
{ {
HWGLE(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 | mBbaMem[BBA_NWAYS] = BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY |
BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF; BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF;
}*/ }
break; break;
case 0x18: //RRP - Receive Buffer Read Page Pointer case 0x18: //RRP - Receive Buffer Read Page Pointer
DEBUGPRINT( "\t[INFO]mWriteP is %x\n", mWriteP); DEBUGPRINT( "\t[INFO]RRP\n");
exit(0); //exit(0);
/*MYASSERT(size == 2 || size == 1); assert(_uSize == 2 || _uSize == 1);
mRBRPP = (BYTE)data << 8; //I hope this works with both write sizes. mRBRPP = (u8)_uData << 8; //Whinecube: I hope this works with both write sizes.
mRBEmpty = mRBRPP == ((WORD)mCbw.p_write() + CB_OFFSET); mRBEmpty = mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET);
HWGLE(checkRecvBuffer());*/ checkRecvBuffer();
break; break;
case 0x16: //RWP case 0x16: //RWP - Receive Buffer Write Page Pointer
DEBUGPRINT( "\t[INFO]mWriteP is %x\n", mWriteP); DEBUGPRINT( "\t[INFO]RWP\n");
exit(0); //exit(0);
/*MYASSERT(size == 2 || size == 1); /*MYASSERT(size == 2 || size == 1);
MYASSERT(data == DWORD((WORD)mCbw.p_write() + CB_OFFSET) >> 8);*/ MYASSERT(data == DWORD((WORD)mCbw.p_write() + CB_OFFSET) >> 8);*/
break; break;
@ -255,6 +270,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
{ {
// Device ID Request // Device ID Request
// 100% this returns correctly // 100% this returns correctly
DEBUGPRINT( "\t[INFO]Request Dev ID\n");
mSpecialImmData = EXI_DEVTYPE_ETHER; mSpecialImmData = EXI_DEVTYPE_ETHER;
mExpectSpecialImmRead = true; mExpectSpecialImmRead = true;
return; return;
@ -350,7 +366,8 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
return; return;
} }
DEBUGPRINT( "\t[EEE]Not expecting ImmWrite of size %d\n", _uSize); 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) u32 CEXIETHERNET::ImmRead(u32 _uSize)

View File

@ -46,6 +46,26 @@ private:
u32 _size; 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 class CEXIETHERNET : public IEXIDevice
{ {
public: public:
@ -54,7 +74,6 @@ public:
bool IsPresent(); bool IsPresent();
void Update(); void Update();
bool IsInterruptSet(); bool IsInterruptSet();
bool isActivated();
void ImmWrite(u32 _uData, u32 _uSize); void ImmWrite(u32 _uData, u32 _uSize);
u32 ImmRead(u32 _uSize); u32 ImmRead(u32 _uSize);
void DMAWrite(u32 _uAddr, u32 _uSize); void DMAWrite(u32 _uAddr, u32 _uSize);
@ -72,10 +91,16 @@ private:
u32 mSpecialImmData; u32 mSpecialImmData;
bool Activated; bool Activated;
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
bool mRBEmpty;
u32 mRecvBufferLength;
#define BBAMEM_SIZE 0x1000 #define BBAMEM_SIZE 0x1000
u8 mBbaMem[BBAMEM_SIZE]; u8 mBbaMem[BBAMEM_SIZE];
WriteBuffer mWriteBuffer; WriteBuffer mWriteBuffer;
CyclicBufferWriter mCbw;
bool mExpectVariableLengthImmWrite; bool mExpectVariableLengthImmWrite;
bool mReadyToSend; bool mReadyToSend;
@ -88,6 +113,13 @@ private:
void recordSendComplete(); void recordSendComplete();
bool sendPacket(u8 *etherpckt, int size); bool sendPacket(u8 *etherpckt, int size);
bool checkRecvBuffer();
bool handleRecvdPacket();
//TAP interface
bool activate();
bool deactivate();
bool isActivated();
}; };
enum { enum {

View File

@ -42,6 +42,7 @@ files = ["ActionReplay.cpp",
"HW/EXI_DeviceMemoryCard.cpp", "HW/EXI_DeviceMemoryCard.cpp",
"HW/EXI_DeviceMic.cpp", "HW/EXI_DeviceMic.cpp",
"HW/EXI_DeviceEthernet.cpp", "HW/EXI_DeviceEthernet.cpp",
"HW/BBA-TAP/TAP_Unix.cpp",
"HW/GPFifo.cpp", "HW/GPFifo.cpp",
"HW/HW.cpp", "HW/HW.cpp",
"HW/Memmap.cpp", "HW/Memmap.cpp",