mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 22:59:47 -06:00
Some cleanup of BBA code. No behavioral changes.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4500 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -384,7 +384,7 @@ bool CEXIETHERNET::startRecv()
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD res = ReadFile(mHAdapter, mRecvBuffer, (DWORD)mRecvBuffer.size(),
|
||||
DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE,
|
||||
&mRecvBufferLength, &mReadOverlapped);
|
||||
|
||||
if (res)
|
||||
|
@ -17,17 +17,16 @@
|
||||
|
||||
#include "Memmap.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "../Core.h"
|
||||
|
||||
#include "EXI_Device.h"
|
||||
#include "EXI_DeviceEthernet.h"
|
||||
|
||||
//#define SONICDEBUG
|
||||
#ifdef SONICDEBUG
|
||||
#define FILEDEBUG
|
||||
#ifdef FILEDEBUG
|
||||
FILE *ME = 0;
|
||||
#endif
|
||||
#endif
|
||||
void DEBUGPRINT (const char * format, ...)
|
||||
{
|
||||
char buffer[0x1000];
|
||||
@ -50,19 +49,17 @@ void DEBUGPRINT (const char * format, ...)
|
||||
|
||||
#define RISE(flags) ((SwappedData & (flags)) && !(mBbaMem[0x00] & (flags)))
|
||||
|
||||
int mPacketsSent = 0;
|
||||
u8 mac_address[6] = {0x00, 0x1A, 0x4D, 0x5E, 0x64, 0x2B}; // Looks Appropriate
|
||||
unsigned int Expecting;
|
||||
static u32 mPacketsSent = 0;
|
||||
static u8 mac_address[6] = {0x00, 0x09, 0xbf, 0x01, 0x00, 0xc1}; // (shuffle2) from my bba
|
||||
static u32 Expecting;
|
||||
|
||||
CEXIETHERNET::CEXIETHERNET() :
|
||||
m_uPosition(0),
|
||||
m_uCommand(0),
|
||||
mWriteBuffer(2048),
|
||||
mCbw(mBbaMem + CB_OFFSET, CB_SIZE),
|
||||
mRecvBuffer(2048)
|
||||
mCbw(mBbaMem + CB_OFFSET, CB_SIZE)
|
||||
{
|
||||
memset(mBbaMem, 0, BBAMEM_SIZE);
|
||||
ID = 0x04020200;
|
||||
memset(mBbaMem, 0, BBA_MEM_SIZE);
|
||||
mWriteP = INVALID_P;
|
||||
mReadP = INVALID_P;
|
||||
mWaiting = false;
|
||||
@ -93,32 +90,6 @@ CEXIETHERNET::~CEXIETHERNET()
|
||||
#endif
|
||||
}
|
||||
|
||||
void CyclicBufferWriter::write(void *src, size_t size)
|
||||
{
|
||||
assert(size < _cap);
|
||||
u8* bsrc = (u8*) src;
|
||||
if(_write + size >= _cap)
|
||||
{
|
||||
// wraparound
|
||||
memcpy(_buffer + _write, src, _cap - _write);
|
||||
memcpy(_buffer, bsrc + (_cap - _write), size - (_cap - _write));
|
||||
_write = size - (_cap - _write);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(_buffer + _write, src, size);
|
||||
_write += size;
|
||||
}
|
||||
//DEGUB("CBWrote %i bytes", size);
|
||||
}
|
||||
|
||||
void CyclicBufferWriter::align()
|
||||
{
|
||||
_write = (_write + 0xff) & ~0xff;
|
||||
if(_write >= _cap)
|
||||
_write -= _cap;
|
||||
}
|
||||
|
||||
void CEXIETHERNET::SetCS(int cs)
|
||||
{
|
||||
DEBUGPRINT("Set CS: %s Expect Variable write?: %s", cs ? "true" : "false", mExpectVariableLengthImmWrite ? "true" : "false");
|
||||
@ -200,7 +171,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||
}
|
||||
else if (mWriteP != INVALID_P)
|
||||
{
|
||||
if (mWriteP + _uSize > BBAMEM_SIZE)
|
||||
if (mWriteP + _uSize > BBA_MEM_SIZE)
|
||||
{
|
||||
DEBUGPRINT("[EEE]Write error: mWriteP + size = 0x%04X + %i", mWriteP, _uSize);
|
||||
exit(0);
|
||||
@ -212,7 +183,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||
case BBA_IR:
|
||||
{
|
||||
// Correct, we use swapped
|
||||
assert(_uSize == 1);
|
||||
_dbg_assert_(SP1, _uSize == 1);
|
||||
u32 SwappedData = Common::swap32(_uData);
|
||||
DEBUGPRINT("\t\t[INFO]BBA Interrupt reset 0x%02X & ~(0x%02X) => 0x%02X", mBbaMem[0x09], MAKE(u8, SwappedData), mBbaMem[0x09] & ~MAKE(u8, SwappedData));
|
||||
mBbaMem[BBA_IR] &= ~MAKE(u8, SwappedData);
|
||||
@ -231,7 +202,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||
}
|
||||
if (RISE(BBA_NCRA_SR) && isActivated())
|
||||
{
|
||||
DEBUGPRINT("\t\t[INFO]BBA Start Recieve");
|
||||
DEBUGPRINT("\t\t[INFO]BBA Start Receive");
|
||||
//exit(0);
|
||||
startRecv();
|
||||
}
|
||||
@ -271,14 +242,14 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||
break;
|
||||
case BBA_RRP: //RRP - Receive Buffer Read Page Pointer
|
||||
DEBUGPRINT("\t\t[INFO]RRP");
|
||||
assert(_uSize == 2 || _uSize == 1);
|
||||
_dbg_assert_(SP1, _uSize == 2 || _uSize == 1);
|
||||
mRBRPP = (u8)Common::swap32(_uData) << 8; //Whinecube: I hope this works with both write sizes.
|
||||
mRBEmpty = (mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET));
|
||||
checkRecvBuffer();
|
||||
break;
|
||||
case BBA_RWP: //RWP - Receive Buffer Write Page Pointer
|
||||
DEBUGPRINT("\t\t[INFO]RWP");
|
||||
assert(_uSize == 2 || _uSize == 1);
|
||||
_dbg_assert_(SP1, _uSize == 2 || _uSize == 1);
|
||||
DEBUGPRINT("\t\t\tThing is 0x%0X", (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
|
||||
// TODO: This assert FAILS!
|
||||
//assert(Common::swap32(_uData) == (u32)((u16)mCbw.p_write() + CB_OFFSET) >> 8);
|
||||
@ -363,7 +334,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
||||
{
|
||||
// Correct
|
||||
mReadP = (u16)getbitsw(SwappedData, 8, 23);
|
||||
if (mReadP >= BBAMEM_SIZE)
|
||||
if (mReadP >= BBA_MEM_SIZE)
|
||||
{
|
||||
DEBUGPRINT("\t\t[EEE]Illegal BBA address: 0x%04X", mReadP);
|
||||
//if(g::bouehr)
|
||||
@ -458,7 +429,7 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
||||
}
|
||||
if (mReadP != INVALID_P)
|
||||
{
|
||||
if (mReadP + _uSize > BBAMEM_SIZE)
|
||||
if (mReadP + _uSize > BBA_MEM_SIZE)
|
||||
{
|
||||
DEBUGPRINT("\t[EEE]Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
|
||||
exit(0);
|
||||
@ -507,7 +478,7 @@ void CEXIETHERNET::DMARead(u32 _uAddr, u32 _uSize)
|
||||
{
|
||||
if (mReadP != INVALID_P)
|
||||
{
|
||||
if(mReadP + _uSize > BBAMEM_SIZE)
|
||||
if (mReadP + _uSize > BBA_MEM_SIZE)
|
||||
{
|
||||
DEBUGPRINT("Read error: mReadP + size = 0x%04X + %i", mReadP, _uSize);
|
||||
return;
|
||||
|
@ -39,105 +39,6 @@ inline u32 getbitsw(u32 dword, int start, int end) {
|
||||
return (dword & makemaskw(start, end)) >> (31 - end);
|
||||
}
|
||||
|
||||
// Container Class Stolen from Whinecube
|
||||
template<class T> class SubContainer;
|
||||
|
||||
template<class T> class Container
|
||||
{
|
||||
public:
|
||||
Container(size_t _size) {
|
||||
b = 0;
|
||||
allocate(_size);
|
||||
}
|
||||
Container(size_t _size, const T *data) {
|
||||
b = 0;
|
||||
allocate(size);
|
||||
memcpy(a, data, _size);
|
||||
}
|
||||
~Container() {
|
||||
if (a) /*if(_msize(a))*/ free(a);
|
||||
}
|
||||
void resize(size_t _size) {
|
||||
if (b == _size)
|
||||
return;
|
||||
free(a);
|
||||
allocate(_size);
|
||||
}
|
||||
|
||||
/*void insert(int before, void *src, size_t size) {
|
||||
char *temp = a;
|
||||
a = new char[b + size];
|
||||
if(a == NULL)
|
||||
BFE("Memory insert failed in container");
|
||||
memcpy(a, temp, before);
|
||||
memcpy(a+before, src, size);
|
||||
memcpy(a+before+size, temp+before, b-before);
|
||||
b += size;
|
||||
delete temp;
|
||||
}*/
|
||||
|
||||
class SubContainer : public Container {
|
||||
private:
|
||||
SubContainer(void* ptr, size_t size) : Container(ptr, size) {}
|
||||
friend class Container;
|
||||
public:
|
||||
~SubContainer() {
|
||||
a = NULL;
|
||||
b = 0;
|
||||
}
|
||||
};
|
||||
SubContainer getSub(size_t pos) {
|
||||
return SubContainer(((char*)a) + pos, b - pos);
|
||||
}
|
||||
|
||||
operator T*() { return (T *)a; }
|
||||
operator const T*() const { return (T *)a; }
|
||||
T* p() { return (T *)a; }
|
||||
const T* p() const { return (T *)a; }
|
||||
T *operator->() { return (T *)a; }
|
||||
size_t size() const { return b; }
|
||||
void steal(Container<T> &src) {
|
||||
resize(0); a = src.a; b = src.b;
|
||||
src.a = NULL; src.b = 0;
|
||||
}
|
||||
void swap(Container<T> &other) {
|
||||
T *ta = a; size_t tb = b;
|
||||
a = other.a; b = other.b;
|
||||
other.a = ta; other.b = tb;
|
||||
}
|
||||
|
||||
protected:
|
||||
void *a;
|
||||
size_t b;
|
||||
|
||||
private:
|
||||
Container(const Container&);
|
||||
Container &operator=(const Container&);
|
||||
Container(void* ptr, size_t _size) : a(ptr), b(_size) {}
|
||||
friend class SubContainer;
|
||||
|
||||
void allocate(size_t _size)
|
||||
{
|
||||
if (_size > (100*1024*1024)) // 100 MB cap
|
||||
exit(0);
|
||||
|
||||
//DEGUB("Resize: %i -> %i = %i\n", b, size, g_con_total);
|
||||
//if(size > 1000*K) {
|
||||
//DEGUB("Megabyte Container resize!\n");
|
||||
//}
|
||||
|
||||
b = _size;
|
||||
if (_size == 0)
|
||||
a = NULL;
|
||||
else
|
||||
{
|
||||
a = malloc(_size);
|
||||
//if(!_CrtIsValidHeapPointer(a))
|
||||
//throw generic_fatal_exception("malloc failed in Container");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DEBUGPRINT(const char * format, ...);
|
||||
|
||||
class WriteBuffer
|
||||
@ -155,7 +56,7 @@ public:
|
||||
{
|
||||
if (_size + s >= ucapacity)
|
||||
{
|
||||
printf("Write too large!");
|
||||
DEBUGPRINT("Write too large!");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -175,108 +76,51 @@ private:
|
||||
class CyclicBufferWriter
|
||||
{
|
||||
public:
|
||||
CyclicBufferWriter(u8 *buffer, size_t cap)
|
||||
{
|
||||
_buffer = buffer; _cap = cap; _write = 0;
|
||||
CyclicBufferWriter(u8 *buffer, size_t cap) {
|
||||
_buffer = buffer; _capacity = 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
|
||||
void write(void *src, size_t size) {
|
||||
_dbg_assert_(SP1, size < _capacity);
|
||||
u8* bsrc = (u8*) src;
|
||||
if (_write + size >= _capacity)
|
||||
{
|
||||
// wraparound
|
||||
memcpy(_buffer + _write, src, _capacity - _write);
|
||||
memcpy(_buffer, bsrc + (_capacity - _write), size - (_capacity - _write));
|
||||
_write = size - (_capacity - _write);
|
||||
} else {
|
||||
memcpy(_buffer + _write, src, size);
|
||||
_write += size;
|
||||
}
|
||||
//DEBUG_LOG(SP1, "CBWrote %i bytes", size);
|
||||
}
|
||||
// Aligns the write pointer to steps of 0x100, like the real BBA
|
||||
void align() {
|
||||
_write = (_write + 0xff) & ~0xff;
|
||||
if(_write >= _capacity)
|
||||
_write -= _capacity;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t _write;
|
||||
size_t _cap; //capacity
|
||||
size_t _capacity;
|
||||
u8 *_buffer;
|
||||
};
|
||||
|
||||
class CEXIETHERNET : public IEXIDevice
|
||||
{
|
||||
public:
|
||||
CEXIETHERNET();
|
||||
~CEXIETHERNET();
|
||||
void SetCS(int _iCS);
|
||||
bool IsPresent();
|
||||
void Update();
|
||||
bool IsInterruptSet();
|
||||
void ImmWrite(u32 _uData, u32 _uSize);
|
||||
u32 ImmRead(u32 _uSize);
|
||||
void DMAWrite(u32 _uAddr, u32 _uSize);
|
||||
void DMARead(u32 _uAddr, u32 _uSize);
|
||||
|
||||
//private:
|
||||
// STATE_TO_SAVE
|
||||
u32 m_uPosition;
|
||||
u32 m_uCommand;
|
||||
|
||||
bool m_bInterruptSet;
|
||||
u32 mWriteP, mReadP;
|
||||
#define INVALID_P 0xFFFF
|
||||
|
||||
bool mExpectSpecialImmRead; //reset to false on deselect
|
||||
u32 mSpecialImmData;
|
||||
bool Activated;
|
||||
|
||||
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
||||
bool mRBEmpty;
|
||||
|
||||
#define BBAMEM_SIZE 0x1000
|
||||
u8 mBbaMem[BBAMEM_SIZE];
|
||||
|
||||
WriteBuffer mWriteBuffer;
|
||||
CyclicBufferWriter mCbw;
|
||||
|
||||
bool mExpectVariableLengthImmWrite;
|
||||
bool mReadyToSend;
|
||||
unsigned int ID;
|
||||
u8 RegisterBlock[0x1000];
|
||||
enum
|
||||
{
|
||||
CMD_ID = 0x00,
|
||||
CMD_READ_REG = 0x01,
|
||||
};
|
||||
|
||||
void recordSendComplete();
|
||||
bool sendPacket(u8 *etherpckt, int size);
|
||||
bool checkRecvBuffer();
|
||||
bool handleRecvdPacket();
|
||||
|
||||
//TAP interface
|
||||
bool activate();
|
||||
bool CheckRecieved();
|
||||
bool deactivate();
|
||||
bool isActivated();
|
||||
bool resume();
|
||||
bool startRecv();
|
||||
bool cbwriteDescriptor(u32 size);
|
||||
|
||||
|
||||
volatile bool mWaiting;
|
||||
Container<u8> mRecvBuffer;
|
||||
#ifdef _WIN32
|
||||
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
||||
DWORD mMtu;
|
||||
OVERLAPPED mReadOverlapped;
|
||||
DWORD mRecvBufferLength;
|
||||
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
||||
#else
|
||||
u32 mRecvBufferLength;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EXPECT_NONE = 0,
|
||||
EXPECT_ID
|
||||
};
|
||||
|
||||
// TODO: convert into unions
|
||||
enum
|
||||
{
|
||||
BBA_RECV_SIZE = 0x800,
|
||||
BBA_MEM_SIZE = 0x1000,
|
||||
|
||||
CB_OFFSET = 0x100,
|
||||
CB_SIZE = (BBAMEM_SIZE - CB_OFFSET),
|
||||
CB_SIZE = (BBA_MEM_SIZE - CB_OFFSET),
|
||||
SIZEOF_RECV_DESCRIPTOR = 4,
|
||||
|
||||
EXI_DEVTYPE_ETHER = 0x04020200,
|
||||
@ -341,4 +185,81 @@ enum
|
||||
BBA_SI_ACTRL2 = 0x60
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EXPECT_NONE = 0,
|
||||
EXPECT_ID
|
||||
};
|
||||
|
||||
class CEXIETHERNET : public IEXIDevice
|
||||
{
|
||||
public:
|
||||
CEXIETHERNET();
|
||||
~CEXIETHERNET();
|
||||
void SetCS(int _iCS);
|
||||
bool IsPresent();
|
||||
void Update();
|
||||
bool IsInterruptSet();
|
||||
void ImmWrite(u32 _uData, u32 _uSize);
|
||||
u32 ImmRead(u32 _uSize);
|
||||
void DMAWrite(u32 _uAddr, u32 _uSize);
|
||||
void DMARead(u32 _uAddr, u32 _uSize);
|
||||
|
||||
//private:
|
||||
// STATE_TO_SAVE
|
||||
u32 m_uPosition;
|
||||
u32 m_uCommand;
|
||||
|
||||
bool m_bInterruptSet;
|
||||
u32 mWriteP, mReadP;
|
||||
|
||||
bool mExpectSpecialImmRead; //reset to false on deselect
|
||||
u32 mSpecialImmData;
|
||||
bool Activated;
|
||||
|
||||
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
||||
bool mRBEmpty;
|
||||
|
||||
u8 mBbaMem[BBA_MEM_SIZE];
|
||||
|
||||
WriteBuffer mWriteBuffer;
|
||||
CyclicBufferWriter mCbw;
|
||||
|
||||
bool mExpectVariableLengthImmWrite;
|
||||
bool mReadyToSend;
|
||||
u8 RegisterBlock[0x1000];
|
||||
enum
|
||||
{
|
||||
CMD_ID = 0x00,
|
||||
CMD_READ_REG = 0x01,
|
||||
};
|
||||
|
||||
void recordSendComplete();
|
||||
bool sendPacket(u8 *etherpckt, int size);
|
||||
bool checkRecvBuffer();
|
||||
bool handleRecvdPacket();
|
||||
|
||||
//TAP interface
|
||||
bool activate();
|
||||
bool CheckRecieved();
|
||||
bool deactivate();
|
||||
bool isActivated();
|
||||
bool resume();
|
||||
bool startRecv();
|
||||
bool cbwriteDescriptor(u32 size);
|
||||
|
||||
|
||||
volatile bool mWaiting;
|
||||
u8 mRecvBuffer[BBA_RECV_SIZE];
|
||||
#ifdef _WIN32
|
||||
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
||||
DWORD mMtu;
|
||||
OVERLAPPED mReadOverlapped;
|
||||
DWORD mRecvBufferLength;
|
||||
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
||||
#else
|
||||
u32 mRecvBufferLength;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user