convert Wifi and WifiAP
This commit is contained in:
parent
76976fef30
commit
2bd09eafeb
|
@ -1212,7 +1212,7 @@ int ClassifyAddress7(u32 addr)
|
|||
}
|
||||
}
|
||||
|
||||
void WifiWrite32(u32 addr, u32 val)
|
||||
/*void WifiWrite32(u32 addr, u32 val)
|
||||
{
|
||||
Wifi::Write(addr, val & 0xFFFF);
|
||||
Wifi::Write(addr + 2, val >> 16);
|
||||
|
@ -1221,7 +1221,7 @@ void WifiWrite32(u32 addr, u32 val)
|
|||
u32 WifiRead32(u32 addr)
|
||||
{
|
||||
return (u32)Wifi::Read(addr) | ((u32)Wifi::Read(addr + 2) << 16);
|
||||
}
|
||||
}*/
|
||||
|
||||
template <typename T>
|
||||
void VRAMWrite(u32 addr, T val)
|
||||
|
@ -1358,7 +1358,8 @@ void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 0x04800000:
|
||||
// TODO: the wifi funcs also ought to check POWCNT
|
||||
/*case 0x04800000:
|
||||
if (addr < 0x04810000 && size >= 16)
|
||||
{
|
||||
switch (size | store)
|
||||
|
@ -1369,7 +1370,7 @@ void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size)
|
|||
case 33: return (void*)WifiWrite32;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;*/
|
||||
case 0x06000000:
|
||||
case 0x06800000:
|
||||
switch (size | store)
|
||||
|
|
29
src/NDS.cpp
29
src/NDS.cpp
|
@ -181,6 +181,7 @@ u16 RCnt;
|
|||
class SPU* SPU;
|
||||
class SPIHost* SPI;
|
||||
class RTC* RTC;
|
||||
class Wifi* Wifi;
|
||||
|
||||
bool Running;
|
||||
|
||||
|
@ -222,11 +223,11 @@ bool Init()
|
|||
SPU = new class SPU;
|
||||
SPI = new class SPIHost();
|
||||
RTC = new class RTC();
|
||||
Wifi = new class Wifi();
|
||||
|
||||
if (!NDSCart::Init()) return false;
|
||||
if (!GBACart::Init()) return false;
|
||||
if (!GPU::Init()) return false;
|
||||
if (!Wifi::Init()) return false;
|
||||
|
||||
if (!DSi::Init()) return false;
|
||||
|
||||
|
@ -253,11 +254,11 @@ void DeInit()
|
|||
delete SPU; SPU = nullptr;
|
||||
delete SPI; SPI = nullptr;
|
||||
delete RTC; RTC = nullptr;
|
||||
delete Wifi; Wifi = nullptr;
|
||||
|
||||
NDSCart::DeInit();
|
||||
GBACart::DeInit();
|
||||
GPU::DeInit();
|
||||
Wifi::DeInit();
|
||||
|
||||
DSi::DeInit();
|
||||
|
||||
|
@ -646,7 +647,7 @@ void Reset()
|
|||
SPU->Reset();
|
||||
SPI->Reset();
|
||||
RTC->Reset();
|
||||
Wifi::Reset();
|
||||
Wifi->Reset();
|
||||
|
||||
// TODO: move the SOUNDBIAS/degrade logic to SPU?
|
||||
|
||||
|
@ -848,7 +849,7 @@ bool DoSavestate(Savestate* file)
|
|||
SPU->DoSavestate(file);
|
||||
SPI->DoSavestate(file);
|
||||
RTC->DoSavestate(file);
|
||||
Wifi::DoSavestate(file);
|
||||
Wifi->DoSavestate(file);
|
||||
|
||||
if (ConsoleType == 1)
|
||||
DSi::DoSavestate(file);
|
||||
|
@ -858,7 +859,7 @@ bool DoSavestate(Savestate* file)
|
|||
GPU::SetPowerCnt(PowerControl9);
|
||||
|
||||
SPU->SetPowerCnt(PowerControl7 & 0x0001);
|
||||
Wifi::SetPowerCnt(PowerControl7 & 0x0002);
|
||||
Wifi->SetPowerCnt(PowerControl7 & 0x0002);
|
||||
}
|
||||
|
||||
#ifdef JIT_ENABLED
|
||||
|
@ -2542,8 +2543,8 @@ u8 ARM7Read8(u32 addr)
|
|||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return 0;
|
||||
if (addr & 0x1) return Wifi::Read(addr-1) >> 8;
|
||||
return Wifi::Read(addr) & 0xFF;
|
||||
if (addr & 0x1) return Wifi->Read(addr-1) >> 8;
|
||||
return Wifi->Read(addr) & 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2609,7 +2610,7 @@ u16 ARM7Read16(u32 addr)
|
|||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return 0;
|
||||
return Wifi::Read(addr);
|
||||
return Wifi->Read(addr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2675,7 +2676,7 @@ u32 ARM7Read32(u32 addr)
|
|||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return 0;
|
||||
return Wifi::Read(addr) | (Wifi::Read(addr+2) << 16);
|
||||
return Wifi->Read(addr) | (Wifi->Read(addr+2) << 16);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2818,7 +2819,7 @@ void ARM7Write16(u32 addr, u16 val)
|
|||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return;
|
||||
Wifi::Write(addr, val);
|
||||
Wifi->Write(addr, val);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -2898,8 +2899,8 @@ void ARM7Write32(u32 addr, u32 val)
|
|||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return;
|
||||
Wifi::Write(addr, val & 0xFFFF);
|
||||
Wifi::Write(addr+2, val >> 16);
|
||||
Wifi->Write(addr, val & 0xFFFF);
|
||||
Wifi->Write(addr+2, val >> 16);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -4332,7 +4333,7 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
|||
u16 change = PowerControl7 ^ val;
|
||||
PowerControl7 = val & 0x0003;
|
||||
SPU->SetPowerCnt(val & 0x0001);
|
||||
Wifi::SetPowerCnt(val & 0x0002);
|
||||
Wifi->SetPowerCnt(val & 0x0002);
|
||||
if (change & 0x0002) UpdateWifiTimings();
|
||||
}
|
||||
return;
|
||||
|
@ -4462,7 +4463,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
|||
u16 change = PowerControl7 ^ val;
|
||||
PowerControl7 = val & 0x0003;
|
||||
SPU->SetPowerCnt(val & 0x0001);
|
||||
Wifi::SetPowerCnt(val & 0x0002);
|
||||
Wifi->SetPowerCnt(val & 0x0002);
|
||||
if (change & 0x0002) UpdateWifiTimings();
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
class SPU;
|
||||
class SPIHost;
|
||||
class RTC;
|
||||
class Wifi;
|
||||
|
||||
namespace NDS
|
||||
{
|
||||
|
@ -253,6 +254,7 @@ extern u16 RCnt;
|
|||
extern class SPU* SPU;
|
||||
extern class SPIHost* SPI;
|
||||
extern class RTC* RTC;
|
||||
extern class Wifi* Wifi;
|
||||
|
||||
const u32 ARM7WRAMSize = 0x10000;
|
||||
extern u8* ARM7WRAM;
|
||||
|
|
197
src/Wifi.cpp
197
src/Wifi.cpp
|
@ -27,91 +27,19 @@
|
|||
using Platform::Log;
|
||||
using Platform::LogLevel;
|
||||
|
||||
namespace Wifi
|
||||
{
|
||||
|
||||
//#define WIFI_LOG printf
|
||||
#define WIFI_LOG(...) {}
|
||||
|
||||
#define PRINT_MAC(pf, mac) Log(LogLevel::Debug, "%s: %02X:%02X:%02X:%02X:%02X:%02X\n", pf, (mac)[0], (mac)[1], (mac)[2], (mac)[3], (mac)[4], (mac)[5]);
|
||||
|
||||
u8 RAM[0x2000];
|
||||
u16 IO[0x1000>>1];
|
||||
|
||||
#define IOPORT(x) IO[(x)>>1]
|
||||
#define IOPORT8(x) ((u8*)IO)[x]
|
||||
|
||||
// destination MACs for MP frames
|
||||
const u8 MPCmdMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x00};
|
||||
const u8 MPReplyMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x10};
|
||||
const u8 MPAckMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x03};
|
||||
|
||||
const int kTimerInterval = 8;
|
||||
const u32 kTimeCheckMask = ~(kTimerInterval - 1);
|
||||
|
||||
bool Enabled;
|
||||
bool PowerOn;
|
||||
|
||||
s32 TimerError;
|
||||
|
||||
u16 Random;
|
||||
|
||||
// general, always-on microsecond counter
|
||||
u64 USTimestamp;
|
||||
|
||||
u64 USCounter;
|
||||
u64 USCompare;
|
||||
bool BlockBeaconIRQ14;
|
||||
|
||||
u32 CmdCounter;
|
||||
|
||||
u8 BBRegs[0x100];
|
||||
u8 BBRegsRO[0x100];
|
||||
|
||||
u8 RFVersion;
|
||||
u32 RFRegs[0x40];
|
||||
|
||||
struct TXSlot
|
||||
{
|
||||
bool Valid;
|
||||
u16 Addr;
|
||||
u16 Length;
|
||||
u8 Rate;
|
||||
u8 CurPhase;
|
||||
int CurPhaseTime;
|
||||
u32 HalfwordTimeMask;
|
||||
};
|
||||
|
||||
TXSlot TXSlots[6];
|
||||
u8 TXBuffer[0x2000];
|
||||
|
||||
u8 RXBuffer[2048];
|
||||
u32 RXBufferPtr;
|
||||
int RXTime;
|
||||
u32 RXHalfwordTimeMask;
|
||||
|
||||
u32 ComStatus; // 0=waiting for packets 1=receiving 2=sending
|
||||
u32 TXCurSlot;
|
||||
u32 RXCounter;
|
||||
|
||||
int MPReplyTimer;
|
||||
u16 MPClientMask, MPClientFail;
|
||||
|
||||
u8 MPClientReplies[15*1024];
|
||||
|
||||
u16 MPLastSeqno;
|
||||
|
||||
bool MPInited;
|
||||
bool LANInited;
|
||||
|
||||
int USUntilPowerOn;
|
||||
bool ForcePowerOn;
|
||||
|
||||
// MULTIPLAYER SYNC APPARATUS
|
||||
bool IsMP;
|
||||
bool IsMPClient;
|
||||
u64 NextSync; // for clients: timestamp for next sync point
|
||||
u64 RXTimestamp;
|
||||
const u8 Wifi::MPCmdMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x00};
|
||||
const u8 Wifi::MPReplyMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x10};
|
||||
const u8 Wifi::MPAckMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x03};
|
||||
|
||||
// multiplayer host TX sequence:
|
||||
// 1. preamble
|
||||
|
@ -148,9 +76,20 @@ u64 RXTimestamp;
|
|||
// * TX errors (if applicable)
|
||||
|
||||
|
||||
bool Init()
|
||||
bool MACEqual(u8* a, const u8* b)
|
||||
{
|
||||
NDS::RegisterEventFunc(NDS::Event_Wifi, 0, USTimer);
|
||||
return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]);
|
||||
}
|
||||
|
||||
bool MACIsBroadcast(u8* a)
|
||||
{
|
||||
return (*(u32*)&a[0] == 0xFFFFFFFF) && (*(u16*)&a[4] == 0xFFFF);
|
||||
}
|
||||
|
||||
|
||||
Wifi::Wifi()
|
||||
{
|
||||
NDS::RegisterEventFunc(NDS::Event_Wifi, 0, MemberEventFunc(Wifi, USTimer));
|
||||
|
||||
//MPInited = false;
|
||||
//LANInited = false;
|
||||
|
@ -161,24 +100,22 @@ bool Init()
|
|||
Platform::LAN_Init();
|
||||
LANInited = true;
|
||||
|
||||
WifiAP::Init();
|
||||
|
||||
return true;
|
||||
WifiAP = new class WifiAP(this);
|
||||
}
|
||||
|
||||
void DeInit()
|
||||
Wifi::~Wifi()
|
||||
{
|
||||
if (MPInited)
|
||||
Platform::MP_DeInit();
|
||||
if (LANInited)
|
||||
Platform::LAN_DeInit();
|
||||
|
||||
WifiAP::DeInit();
|
||||
delete WifiAP; WifiAP = nullptr;
|
||||
|
||||
NDS::UnregisterEventFunc(NDS::Event_Wifi, 0);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
void Wifi::Reset()
|
||||
{
|
||||
memset(RAM, 0, 0x2000);
|
||||
memset(IO, 0, 0x1000);
|
||||
|
@ -277,10 +214,10 @@ void Reset()
|
|||
NextSync = 0;
|
||||
RXTimestamp = 0;
|
||||
|
||||
WifiAP::Reset();
|
||||
WifiAP->Reset();
|
||||
}
|
||||
|
||||
void DoSavestate(Savestate* file)
|
||||
void Wifi::DoSavestate(Savestate* file)
|
||||
{
|
||||
file->Section("WIFI");
|
||||
|
||||
|
@ -355,7 +292,7 @@ void DoSavestate(Savestate* file)
|
|||
}
|
||||
|
||||
|
||||
void ScheduleTimer(bool first)
|
||||
void Wifi::ScheduleTimer(bool first)
|
||||
{
|
||||
if (first) TimerError = 0;
|
||||
|
||||
|
@ -367,7 +304,7 @@ void ScheduleTimer(bool first)
|
|||
NDS::ScheduleEvent(NDS::Event_Wifi, !first, delay, 0, 0);
|
||||
}
|
||||
|
||||
void UpdatePowerOn()
|
||||
void Wifi::UpdatePowerOn()
|
||||
{
|
||||
bool on = Enabled;
|
||||
|
||||
|
@ -405,17 +342,14 @@ void UpdatePowerOn()
|
|||
}
|
||||
}
|
||||
|
||||
void SetPowerCnt(u32 val)
|
||||
void Wifi::SetPowerCnt(u32 val)
|
||||
{
|
||||
Enabled = val & (1<<1);
|
||||
UpdatePowerOn();
|
||||
}
|
||||
|
||||
|
||||
void PowerDown();
|
||||
void StartTX_Beacon();
|
||||
|
||||
void SetIRQ(u32 irq)
|
||||
void Wifi::SetIRQ(u32 irq)
|
||||
{
|
||||
u32 oldflags = IOPORT(W_IF) & IOPORT(W_IE);
|
||||
|
||||
|
@ -426,7 +360,7 @@ void SetIRQ(u32 irq)
|
|||
NDS::SetIRQ(1, NDS::IRQ_Wifi);
|
||||
}
|
||||
|
||||
void SetIRQ13()
|
||||
void Wifi::SetIRQ13()
|
||||
{
|
||||
SetIRQ(13);
|
||||
|
||||
|
@ -440,7 +374,7 @@ void SetIRQ13()
|
|||
}
|
||||
}
|
||||
|
||||
void SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced
|
||||
void Wifi::SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced
|
||||
{
|
||||
if (source != 2)
|
||||
IOPORT(W_BeaconCount1) = IOPORT(W_BeaconInterval);
|
||||
|
@ -469,7 +403,7 @@ void SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced
|
|||
IOPORT(W_ListenCount)--;
|
||||
}
|
||||
|
||||
void SetIRQ15()
|
||||
void Wifi::SetIRQ15()
|
||||
{
|
||||
SetIRQ(15);
|
||||
|
||||
|
@ -481,7 +415,7 @@ void SetIRQ15()
|
|||
}
|
||||
|
||||
|
||||
void SetStatus(u32 status)
|
||||
void Wifi::SetStatus(u32 status)
|
||||
{
|
||||
// TODO, eventually: states 2/4/7
|
||||
u16 rfpins[10] = {0x04, 0x84, 0, 0x46, 0, 0x84, 0x87, 0, 0x46, 0x04};
|
||||
|
@ -490,7 +424,7 @@ void SetStatus(u32 status)
|
|||
}
|
||||
|
||||
|
||||
void PowerDown()
|
||||
void Wifi::PowerDown()
|
||||
{
|
||||
IOPORT(W_TXReqRead) &= ~0x000F;
|
||||
IOPORT(W_PowerState) |= 0x0200;
|
||||
|
@ -504,20 +438,14 @@ void PowerDown()
|
|||
}
|
||||
|
||||
|
||||
bool MACEqual(const u8* a, const u8* b)
|
||||
{
|
||||
return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]);
|
||||
}
|
||||
|
||||
|
||||
int PreambleLen(int rate)
|
||||
int Wifi::PreambleLen(int rate)
|
||||
{
|
||||
if (rate == 1) return 192;
|
||||
if (IOPORT(W_Preamble) & 0x0004) return 96;
|
||||
return 192;
|
||||
}
|
||||
|
||||
u32 NumClients(u16 bitmask)
|
||||
u32 Wifi::NumClients(u16 bitmask)
|
||||
{
|
||||
u32 ret = 0;
|
||||
for (int i = 1; i < 16; i++)
|
||||
|
@ -527,14 +455,14 @@ u32 NumClients(u16 bitmask)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void IncrementTXCount(TXSlot* slot)
|
||||
void Wifi::IncrementTXCount(TXSlot* slot)
|
||||
{
|
||||
u8 cnt = RAM[slot->Addr + 0x4];
|
||||
if (cnt < 0xFF) cnt++;
|
||||
*(u16*)&RAM[slot->Addr + 0x4] = cnt;
|
||||
}
|
||||
|
||||
void ReportMPReplyErrors(u16 clientfail)
|
||||
void Wifi::ReportMPReplyErrors(u16 clientfail)
|
||||
{
|
||||
// TODO: do these trigger any IRQ?
|
||||
|
||||
|
@ -547,7 +475,7 @@ void ReportMPReplyErrors(u16 clientfail)
|
|||
}
|
||||
}
|
||||
|
||||
void TXSendFrame(TXSlot* slot, int num)
|
||||
void Wifi::TXSendFrame(TXSlot* slot, int num)
|
||||
{
|
||||
u32 noseqno = 0;
|
||||
|
||||
|
@ -597,7 +525,7 @@ void TXSendFrame(TXSlot* slot, int num)
|
|||
case 2:
|
||||
case 3:
|
||||
Platform::MP_SendPacket(TXBuffer, 12+len, USTimestamp);
|
||||
if (!IsMP) WifiAP::SendPacket(TXBuffer, 12+len);
|
||||
if (!IsMP) WifiAP->SendPacket(TXBuffer, 12+len);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -617,7 +545,7 @@ void TXSendFrame(TXSlot* slot, int num)
|
|||
}
|
||||
}
|
||||
|
||||
void StartTX_LocN(int nslot, int loc)
|
||||
void Wifi::StartTX_LocN(int nslot, int loc)
|
||||
{
|
||||
TXSlot* slot = &TXSlots[nslot];
|
||||
|
||||
|
@ -637,7 +565,7 @@ void StartTX_LocN(int nslot, int loc)
|
|||
slot->CurPhaseTime = PreambleLen(slot->Rate);
|
||||
}
|
||||
|
||||
void StartTX_Cmd()
|
||||
void Wifi::StartTX_Cmd()
|
||||
{
|
||||
TXSlot* slot = &TXSlots[1];
|
||||
|
||||
|
@ -672,7 +600,7 @@ void StartTX_Cmd()
|
|||
}
|
||||
}
|
||||
|
||||
void StartTX_Beacon()
|
||||
void Wifi::StartTX_Beacon()
|
||||
{
|
||||
TXSlot* slot = &TXSlots[4];
|
||||
|
||||
|
@ -691,7 +619,7 @@ void StartTX_Beacon()
|
|||
IOPORT(W_TXBusy) |= 0x0010;
|
||||
}
|
||||
|
||||
void FireTX()
|
||||
void Wifi::FireTX()
|
||||
{
|
||||
if (!(IOPORT(W_RXCnt) & 0x8000))
|
||||
return;
|
||||
|
@ -736,7 +664,7 @@ void FireTX()
|
|||
}
|
||||
}
|
||||
|
||||
void SendMPDefaultReply()
|
||||
void Wifi::SendMPDefaultReply()
|
||||
{
|
||||
u8 reply[12 + 28];
|
||||
|
||||
|
@ -766,7 +694,7 @@ void SendMPDefaultReply()
|
|||
WIFI_LOG("wifi: sent %d/40 bytes of MP default reply\n", txlen);
|
||||
}
|
||||
|
||||
void SendMPReply(u16 clienttime, u16 clientmask)
|
||||
void Wifi::SendMPReply(u16 clienttime, u16 clientmask)
|
||||
{
|
||||
TXSlot* slot = &TXSlots[5];
|
||||
|
||||
|
@ -827,7 +755,7 @@ void SendMPReply(u16 clienttime, u16 clientmask)
|
|||
IOPORT(W_TXBusy) |= 0x0080;
|
||||
}
|
||||
|
||||
void SendMPAck(u16 cmdcount, u16 clientfail)
|
||||
void Wifi::SendMPAck(u16 cmdcount, u16 clientfail)
|
||||
{
|
||||
u8 ack[12 + 32];
|
||||
|
||||
|
@ -873,10 +801,7 @@ void SendMPAck(u16 cmdcount, u16 clientfail)
|
|||
WIFI_LOG("wifi: sent %d/44 bytes of MP ack, %d %d\n", txlen, ComStatus, RXTime);
|
||||
}
|
||||
|
||||
bool CheckRX(int type);
|
||||
void MPClientReplyRX(int client);
|
||||
|
||||
bool ProcessTX(TXSlot* slot, int num)
|
||||
bool Wifi::ProcessTX(TXSlot* slot, int num)
|
||||
{
|
||||
slot->CurPhaseTime -= kTimerInterval;
|
||||
if (slot->CurPhaseTime > 0)
|
||||
|
@ -1137,7 +1062,7 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||
}
|
||||
|
||||
|
||||
inline void IncrementRXAddr(u16& addr, u16 inc = 2)
|
||||
inline void Wifi::IncrementRXAddr(u16& addr, u16 inc)
|
||||
{
|
||||
for (u32 i = 0; i < inc; i += 2)
|
||||
{
|
||||
|
@ -1148,7 +1073,7 @@ inline void IncrementRXAddr(u16& addr, u16 inc = 2)
|
|||
}
|
||||
}
|
||||
|
||||
void StartRX()
|
||||
void Wifi::StartRX()
|
||||
{
|
||||
u16 framelen = *(u16*)&RXBuffer[8];
|
||||
RXTime = framelen;
|
||||
|
@ -1176,7 +1101,7 @@ void StartRX()
|
|||
ComStatus |= 1;
|
||||
}
|
||||
|
||||
void FinishRX()
|
||||
void Wifi::FinishRX()
|
||||
{
|
||||
ComStatus &= ~0x1;
|
||||
RXCounter = 0;
|
||||
|
@ -1451,7 +1376,7 @@ void FinishRX()
|
|||
}
|
||||
}
|
||||
|
||||
void MPClientReplyRX(int client)
|
||||
void Wifi::MPClientReplyRX(int client)
|
||||
{
|
||||
if (IOPORT(W_PowerState) & 0x0300)
|
||||
return;
|
||||
|
@ -1492,7 +1417,7 @@ void MPClientReplyRX(int client)
|
|||
StartRX();
|
||||
}
|
||||
|
||||
bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
||||
bool Wifi::CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
||||
{
|
||||
if (IOPORT(W_PowerState) & 0x0300)
|
||||
return false;
|
||||
|
@ -1517,7 +1442,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
|||
{
|
||||
rxlen = Platform::MP_RecvPacket(RXBuffer, ×tamp);
|
||||
if ((rxlen <= 0) && (!IsMP))
|
||||
rxlen = WifiAP::RecvPacket(RXBuffer);
|
||||
rxlen = WifiAP->RecvPacket(RXBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1632,7 +1557,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
|||
}
|
||||
|
||||
|
||||
void MSTimer()
|
||||
void Wifi::MSTimer()
|
||||
{
|
||||
if (IOPORT(W_USCompareCnt))
|
||||
{
|
||||
|
@ -1656,7 +1581,7 @@ void MSTimer()
|
|||
}
|
||||
}
|
||||
|
||||
void USTimer(u32 param)
|
||||
void Wifi::USTimer(u32 param)
|
||||
{
|
||||
USTimestamp += kTimerInterval;
|
||||
|
||||
|
@ -1676,7 +1601,7 @@ void USTimer(u32 param)
|
|||
}
|
||||
|
||||
if (!(USTimestamp & 0x3FF & kTimeCheckMask))
|
||||
WifiAP::MSTimer();
|
||||
WifiAP->MSTimer();
|
||||
|
||||
bool switchOffPowerSaving = false;
|
||||
if (USUntilPowerOn < 0)
|
||||
|
@ -1839,7 +1764,7 @@ void USTimer(u32 param)
|
|||
}
|
||||
|
||||
|
||||
void RFTransfer_Type2()
|
||||
void Wifi::RFTransfer_Type2()
|
||||
{
|
||||
u32 id = (IOPORT(W_RFData2) >> 2) & 0x1F;
|
||||
|
||||
|
@ -1856,7 +1781,7 @@ void RFTransfer_Type2()
|
|||
}
|
||||
}
|
||||
|
||||
void RFTransfer_Type3()
|
||||
void Wifi::RFTransfer_Type3()
|
||||
{
|
||||
u32 id = (IOPORT(W_RFData1) >> 8) & 0x3F;
|
||||
|
||||
|
@ -1873,7 +1798,7 @@ void RFTransfer_Type3()
|
|||
}
|
||||
|
||||
|
||||
u16 Read(u32 addr)
|
||||
u16 Wifi::Read(u32 addr)
|
||||
{
|
||||
if (addr >= 0x04810000)
|
||||
return 0;
|
||||
|
@ -1976,7 +1901,7 @@ u16 Read(u32 addr)
|
|||
return IOPORT(addr&0xFFF);
|
||||
}
|
||||
|
||||
void Write(u32 addr, u16 val)
|
||||
void Wifi::Write(u32 addr, u16 val)
|
||||
{
|
||||
if (addr >= 0x04810000)
|
||||
return;
|
||||
|
@ -2331,14 +2256,12 @@ void Write(u32 addr, u16 val)
|
|||
}
|
||||
|
||||
|
||||
u8* GetMAC()
|
||||
u8* Wifi::GetMAC()
|
||||
{
|
||||
return (u8*)&IOPORT(W_MACAddr0);
|
||||
}
|
||||
|
||||
u8* GetBSSID()
|
||||
u8* Wifi::GetBSSID()
|
||||
{
|
||||
return (u8*)&IOPORT(W_BSSID0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
182
src/Wifi.h
182
src/Wifi.h
|
@ -21,11 +21,14 @@
|
|||
|
||||
#include "Savestate.h"
|
||||
|
||||
namespace Wifi
|
||||
{
|
||||
class WifiAP;
|
||||
|
||||
enum
|
||||
class Wifi
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
W_ID = 0x000,
|
||||
|
||||
W_ModeReset = 0x004,
|
||||
|
@ -150,49 +153,136 @@ enum
|
|||
W_RFStatus = 0x214,
|
||||
W_IFSet = 0x21C,
|
||||
W_RXTXAddr = 0x268,
|
||||
};
|
||||
|
||||
Wifi();
|
||||
~Wifi();
|
||||
void Reset();
|
||||
void DoSavestate(Savestate* file);
|
||||
|
||||
void SetPowerCnt(u32 val);
|
||||
|
||||
void USTimer(u32 param);
|
||||
|
||||
u16 Read(u32 addr);
|
||||
void Write(u32 addr, u16 val);
|
||||
|
||||
u8* GetMAC();
|
||||
u8* GetBSSID();
|
||||
|
||||
private:
|
||||
u8 RAM[0x2000];
|
||||
u16 IO[0x1000>>1];
|
||||
|
||||
static const u8 MPCmdMAC[6];
|
||||
static const u8 MPReplyMAC[6];
|
||||
static const u8 MPAckMAC[6];
|
||||
|
||||
static const int kTimerInterval = 8;
|
||||
static const u32 kTimeCheckMask = ~(kTimerInterval - 1);
|
||||
|
||||
bool Enabled;
|
||||
bool PowerOn;
|
||||
|
||||
s32 TimerError;
|
||||
|
||||
u16 Random;
|
||||
|
||||
// general, always-on microsecond counter
|
||||
u64 USTimestamp;
|
||||
|
||||
u64 USCounter;
|
||||
u64 USCompare;
|
||||
bool BlockBeaconIRQ14;
|
||||
|
||||
u32 CmdCounter;
|
||||
|
||||
u8 BBRegs[0x100];
|
||||
u8 BBRegsRO[0x100];
|
||||
|
||||
u8 RFVersion;
|
||||
u32 RFRegs[0x40];
|
||||
|
||||
struct TXSlot
|
||||
{
|
||||
bool Valid;
|
||||
u16 Addr;
|
||||
u16 Length;
|
||||
u8 Rate;
|
||||
u8 CurPhase;
|
||||
int CurPhaseTime;
|
||||
u32 HalfwordTimeMask;
|
||||
};
|
||||
|
||||
TXSlot TXSlots[6];
|
||||
u8 TXBuffer[0x2000];
|
||||
|
||||
u8 RXBuffer[2048];
|
||||
u32 RXBufferPtr;
|
||||
int RXTime;
|
||||
u32 RXHalfwordTimeMask;
|
||||
|
||||
u32 ComStatus; // 0=waiting for packets 1=receiving 2=sending
|
||||
u32 TXCurSlot;
|
||||
u32 RXCounter;
|
||||
|
||||
int MPReplyTimer;
|
||||
u16 MPClientMask, MPClientFail;
|
||||
|
||||
u8 MPClientReplies[15*1024];
|
||||
|
||||
u16 MPLastSeqno;
|
||||
|
||||
bool MPInited;
|
||||
bool LANInited;
|
||||
|
||||
int USUntilPowerOn;
|
||||
bool ForcePowerOn;
|
||||
|
||||
// MULTIPLAYER SYNC APPARATUS
|
||||
bool IsMP;
|
||||
bool IsMPClient;
|
||||
u64 NextSync; // for clients: timestamp for next sync point
|
||||
u64 RXTimestamp;
|
||||
|
||||
class WifiAP* WifiAP;
|
||||
|
||||
void ScheduleTimer(bool first);
|
||||
void UpdatePowerOn();
|
||||
|
||||
void SetIRQ(u32 irq);
|
||||
void SetIRQ13();
|
||||
void SetIRQ14(int source);
|
||||
void SetIRQ15();
|
||||
|
||||
void SetStatus(u32 status);
|
||||
void PowerDown();
|
||||
|
||||
int PreambleLen(int rate);
|
||||
u32 NumClients(u16 bitmask);
|
||||
void IncrementTXCount(TXSlot* slot);
|
||||
void ReportMPReplyErrors(u16 clientfail);
|
||||
|
||||
void TXSendFrame(TXSlot* slot, int num);
|
||||
void StartTX_LocN(int nslot, int loc);
|
||||
void StartTX_Cmd();
|
||||
void StartTX_Beacon();
|
||||
void FireTX();
|
||||
void SendMPDefaultReply();
|
||||
void SendMPReply(u16 clienttime, u16 clientmask);
|
||||
void SendMPAck(u16 cmdcount, u16 clientfail);
|
||||
bool ProcessTX(TXSlot* slot, int num);
|
||||
|
||||
void IncrementRXAddr(u16& addr, u16 inc = 2);
|
||||
void StartRX();
|
||||
void FinishRX();
|
||||
void MPClientReplyRX(int client);
|
||||
bool CheckRX(int type);
|
||||
|
||||
void MSTimer();
|
||||
|
||||
void RFTransfer_Type2();
|
||||
void RFTransfer_Type3();
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Event_RXCheck = 0,
|
||||
Event_IRQ15,
|
||||
Event_MSTimer,
|
||||
Event_RFWakeup,
|
||||
Event_RX,
|
||||
Event_TX,
|
||||
Event_MPClientSync,
|
||||
Event_RF,
|
||||
Event_BB,
|
||||
|
||||
Event_MAX
|
||||
};
|
||||
|
||||
struct SchedEvent
|
||||
{
|
||||
void (*Func)(u32 param);
|
||||
u64 Timestamp;
|
||||
u32 Param;
|
||||
};
|
||||
|
||||
|
||||
extern bool MPInited;
|
||||
|
||||
|
||||
bool Init();
|
||||
void DeInit();
|
||||
void Reset();
|
||||
void DoSavestate(Savestate* file);
|
||||
|
||||
void SetPowerCnt(u32 val);
|
||||
|
||||
void USTimer(u32 param);
|
||||
|
||||
u16 Read(u32 addr);
|
||||
void Write(u32 addr, u16 val);
|
||||
|
||||
u8* GetMAC();
|
||||
u8* GetBSSID();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,10 +30,9 @@
|
|||
using Platform::Log;
|
||||
using Platform::LogLevel;
|
||||
|
||||
namespace WifiAP
|
||||
{
|
||||
|
||||
const u8 APMac[6] = {AP_MAC};
|
||||
const char* WifiAP::APName = "melonAP";
|
||||
const u8 WifiAP::APMac[6] = {0x00, 0xF0, 0x77, 0x77, 0x77, 0x77};
|
||||
|
||||
#define PWRITE_8(p, v) *p++ = v;
|
||||
#define PWRITE_16(p, v) *(u16*)p = v; p += 2;
|
||||
|
@ -65,33 +64,19 @@ const u8 APMac[6] = {AP_MAC};
|
|||
#define PALIGN_4(p, base) while (PLEN(p,base) & 0x3) *p++ = 0xFF;
|
||||
|
||||
|
||||
u64 USCounter;
|
||||
|
||||
u16 SeqNo;
|
||||
|
||||
bool BeaconDue;
|
||||
|
||||
u8 PacketBuffer[2048];
|
||||
int PacketLen;
|
||||
int RXNum;
|
||||
|
||||
u8 LANBuffer[2048];
|
||||
|
||||
// this is a lazy AP, we only keep track of one client
|
||||
// 0=disconnected 1=authenticated 2=associated
|
||||
int ClientStatus;
|
||||
bool MACEqual(u8* a, const u8* b);
|
||||
bool MACIsBroadcast(u8* a);
|
||||
|
||||
|
||||
bool Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeInit()
|
||||
WifiAP::WifiAP(class Wifi* wifi) : Wifi(wifi)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
WifiAP::~WifiAP()
|
||||
{
|
||||
}
|
||||
|
||||
void WifiAP::Reset()
|
||||
{
|
||||
// random starting point for the counter
|
||||
USCounter = 0x428888000ULL;
|
||||
|
@ -107,18 +92,7 @@ void Reset()
|
|||
}
|
||||
|
||||
|
||||
bool MACEqual(u8* a, u8* b)
|
||||
{
|
||||
return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]);
|
||||
}
|
||||
|
||||
bool MACIsBroadcast(u8* a)
|
||||
{
|
||||
return (*(u32*)&a[0] == 0xFFFFFFFF) && (*(u16*)&a[4] == 0xFFFF);
|
||||
}
|
||||
|
||||
|
||||
void MSTimer()
|
||||
void WifiAP::MSTimer()
|
||||
{
|
||||
USCounter += 0x400;
|
||||
|
||||
|
@ -131,7 +105,7 @@ void MSTimer()
|
|||
}
|
||||
|
||||
|
||||
int HandleManagementFrame(u8* data, int len)
|
||||
int WifiAP::HandleManagementFrame(u8* data, int len)
|
||||
{
|
||||
// TODO: perfect this
|
||||
// noting that frames sent pre-auth/assoc don't have a proper BSSID
|
||||
|
@ -199,8 +173,8 @@ int HandleManagementFrame(u8* data, int len)
|
|||
PWRITE_16(p, 0x0021); // capability
|
||||
PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates
|
||||
PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel
|
||||
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(AP_NAME));
|
||||
memcpy(p, AP_NAME, strlen(AP_NAME)); p += strlen(AP_NAME);
|
||||
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(APName));
|
||||
memcpy(p, APName, strlen(APName)); p += strlen(APName);
|
||||
|
||||
PacketLen = PLEN(p, base);
|
||||
RXNum = 1;
|
||||
|
@ -282,7 +256,7 @@ int HandleManagementFrame(u8* data, int len)
|
|||
}
|
||||
|
||||
|
||||
int SendPacket(u8* data, int len)
|
||||
int WifiAP::SendPacket(u8* data, int len)
|
||||
{
|
||||
data += 12;
|
||||
|
||||
|
@ -330,7 +304,7 @@ int SendPacket(u8* data, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int RecvPacket(u8* data)
|
||||
int WifiAP::RecvPacket(u8* data)
|
||||
{
|
||||
if (BeaconDue)
|
||||
{
|
||||
|
@ -353,8 +327,8 @@ int RecvPacket(u8* data)
|
|||
PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates
|
||||
PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel
|
||||
PWRITE_8(p, 0x05); PWRITE_8(p, 0x04); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); // TIM
|
||||
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(AP_NAME));
|
||||
memcpy(p, AP_NAME, strlen(AP_NAME)); p += strlen(AP_NAME);
|
||||
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(APName));
|
||||
memcpy(p, APName, strlen(APName)); p += strlen(APName);
|
||||
|
||||
PALIGN_4(p, base);
|
||||
PWRITE_32(p, 0xDEADBEEF); // checksum. doesn't matter for now
|
||||
|
@ -394,7 +368,7 @@ int RecvPacket(u8* data)
|
|||
// check destination MAC
|
||||
if (!MACIsBroadcast(&LANBuffer[0]))
|
||||
{
|
||||
if (!MACEqual(&LANBuffer[0], Wifi::GetMAC()))
|
||||
if (!MACEqual(&LANBuffer[0], Wifi->GetMAC()))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -427,5 +401,3 @@ int RecvPacket(u8* data)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
44
src/WifiAP.h
44
src/WifiAP.h
|
@ -21,24 +21,44 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
namespace WifiAP
|
||||
class Wifi;
|
||||
|
||||
class WifiAP
|
||||
{
|
||||
public:
|
||||
WifiAP(Wifi* wifi);
|
||||
~WifiAP();
|
||||
void Reset();
|
||||
|
||||
#define AP_MAC 0x00, 0xF0, 0x77, 0x77, 0x77, 0x77
|
||||
#define AP_NAME "melonAP"
|
||||
static const char* APName;
|
||||
static const u8 APMac[6];
|
||||
|
||||
extern const u8 APMac[6];
|
||||
void MSTimer();
|
||||
|
||||
bool Init();
|
||||
void DeInit();
|
||||
void Reset();
|
||||
// packet format: 12-byte TX header + original 802.11 frame
|
||||
int SendPacket(u8* data, int len);
|
||||
int RecvPacket(u8* data);
|
||||
|
||||
void MSTimer();
|
||||
private:
|
||||
class Wifi* Wifi;
|
||||
|
||||
// packet format: 12-byte TX header + original 802.11 frame
|
||||
int SendPacket(u8* data, int len);
|
||||
int RecvPacket(u8* data);
|
||||
u64 USCounter;
|
||||
|
||||
}
|
||||
u16 SeqNo;
|
||||
|
||||
bool BeaconDue;
|
||||
|
||||
u8 PacketBuffer[2048];
|
||||
int PacketLen;
|
||||
int RXNum;
|
||||
|
||||
u8 LANBuffer[2048];
|
||||
|
||||
// this is a lazy AP, we only keep track of one client
|
||||
// 0=disconnected 1=authenticated 2=associated
|
||||
int ClientStatus;
|
||||
|
||||
int HandleManagementFrame(u8* data, int len);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue