aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ARMJIT_Memory.cpp9
-rw-r--r--src/NDS.cpp29
-rw-r--r--src/NDS.h2
-rw-r--r--src/Wifi.cpp197
-rw-r--r--src/Wifi.h410
-rw-r--r--src/WifiAP.cpp60
-rw-r--r--src/WifiAP.h44
7 files changed, 380 insertions, 371 deletions
diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp
index 7a1781e..b1673ab 100644
--- a/src/ARMJIT_Memory.cpp
+++ b/src/ARMJIT_Memory.cpp
@@ -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)
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 3fd8f4c..2fdbf63 100644
--- a/src/NDS.cpp
+++ b/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;
diff --git a/src/NDS.h b/src/NDS.h
index cffcd5d..4b556c6 100644
--- a/src/NDS.h
+++ b/src/NDS.h
@@ -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;
diff --git a/src/Wifi.cpp b/src/Wifi.cpp
index 3716b4c..1486b40 100644
--- a/src/Wifi.cpp
+++ b/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)
+{
+ 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, USTimer);
+ 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, &timestamp);
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);
}
-
-}
diff --git a/src/Wifi.h b/src/Wifi.h
index e357039..5a4f839 100644
--- a/src/Wifi.h
+++ b/src/Wifi.h
@@ -21,178 +21,268 @@
#include "Savestate.h"
-namespace Wifi
-{
+class WifiAP;
-enum
+class Wifi
{
- W_ID = 0x000,
-
- W_ModeReset = 0x004,
- W_ModeWEP = 0x006,
- W_TXStatCnt = 0x008,
- W_IF = 0x010,
- W_IE = 0x012,
-
- W_MACAddr0 = 0x018,
- W_MACAddr1 = 0x01A,
- W_MACAddr2 = 0x01C,
- W_BSSID0 = 0x020,
- W_BSSID1 = 0x022,
- W_BSSID2 = 0x024,
- W_AIDLow = 0x028,
- W_AIDFull = 0x02A,
-
- W_TXRetryLimit = 0x02C,
- W_RXCnt = 0x030,
- W_WEPCnt = 0x032,
-
- W_PowerUS = 0x036,
- W_PowerTX = 0x038,
- W_PowerState = 0x03C,
- W_PowerForce = 0x040,
- W_PowerUnk = 0x48,
-
- W_Random = 0x044,
-
- W_RXBufBegin = 0x050,
- W_RXBufEnd = 0x052,
- W_RXBufWriteCursor = 0x054,
- W_RXBufWriteAddr = 0x056,
- W_RXBufReadAddr = 0x058,
- W_RXBufReadCursor = 0x05A,
- W_RXBufCount = 0x05C,
- W_RXBufDataRead = 0x060,
- W_RXBufGapAddr = 0x062,
- W_RXBufGapSize = 0x064,
-
- W_TXBufWriteAddr = 0x068,
- W_TXBufCount = 0x06C,
- W_TXBufDataWrite = 0x070,
- W_TXBufGapAddr = 0x074,
- W_TXBufGapSize = 0x076,
-
- W_TXSlotBeacon = 0x080,
- W_TXBeaconTIM = 0x084,
- W_ListenCount = 0x088,
- W_BeaconInterval = 0x08C,
- W_ListenInterval = 0x08E,
- W_TXSlotCmd = 0x090,
- W_TXSlotReply1 = 0x094,
- W_TXSlotReply2 = 0x098,
- W_TXSlotLoc1 = 0x0A0,
- W_TXSlotLoc2 = 0x0A4,
- W_TXSlotLoc3 = 0x0A8,
- W_TXReqReset = 0x0AC,
- W_TXReqSet = 0x0AE,
- W_TXReqRead = 0x0B0,
- W_TXSlotReset = 0x0B4,
- W_TXBusy = 0x0B6,
- W_TXStat = 0x0B8,
- W_Preamble = 0x0BC,
- W_CmdTotalTime = 0x0C0,
- W_CmdReplyTime = 0x0C4,
- W_RXFilter = 0x0D0,
- W_RXLenCrop = 0x0DA,
- W_RXFilter2 = 0x0E0,
-
- W_USCountCnt = 0x0E8,
- W_USCompareCnt = 0x0EA,
- W_CmdCountCnt = 0x0EE,
-
- W_USCount0 = 0x0F8,
- W_USCount1 = 0x0FA,
- W_USCount2 = 0x0FC,
- W_USCount3 = 0x0FE,
- W_USCompare0 = 0x0F0,
- W_USCompare1 = 0x0F2,
- W_USCompare2 = 0x0F4,
- W_USCompare3 = 0x0F6,
-
- W_ContentFree = 0x10C,
- W_PreBeacon = 0x110,
- W_CmdCount = 0x118,
- W_BeaconCount1 = 0x11C,
- W_BeaconCount2 = 0x134,
-
- W_BBCnt = 0x158,
- W_BBWrite = 0x15A,
- W_BBRead = 0x15C,
- W_BBBusy = 0x15E,
- W_BBMode = 0x160,
- W_BBPower = 0x168,
-
- W_RFData2 = 0x17C,
- W_RFData1 = 0x17E,
- W_RFBusy = 0x180,
- W_RFCnt = 0x184,
-
- W_TXHeaderCnt = 0x194,
- W_RFPins = 0x19C,
-
- W_RXStatIncIF = 0x1A8,
- W_RXStatIncIE = 0x1AA,
- W_RXStatHalfIF = 0x1AC,
- W_RXStatHalfIE = 0x1AE,
- W_TXErrorCount = 0x1C0,
- W_RXCount = 0x1C4,
-
- W_CMDStat0 = 0x1D0,
- W_CMDStat1 = 0x1D2,
- W_CMDStat2 = 0x1D4,
- W_CMDStat3 = 0x1D6,
- W_CMDStat4 = 0x1D8,
- W_CMDStat5 = 0x1DA,
- W_CMDStat6 = 0x1DC,
- W_CMDStat7 = 0x1DE,
-
- W_TXSeqNo = 0x210,
- W_RFStatus = 0x214,
- W_IFSet = 0x21C,
- W_RXTXAddr = 0x268,
-};
+public:
+
+ enum
+ {
+ W_ID = 0x000,
+
+ W_ModeReset = 0x004,
+ W_ModeWEP = 0x006,
+ W_TXStatCnt = 0x008,
+ W_IF = 0x010,
+ W_IE = 0x012,
+
+ W_MACAddr0 = 0x018,
+ W_MACAddr1 = 0x01A,
+ W_MACAddr2 = 0x01C,
+ W_BSSID0 = 0x020,
+ W_BSSID1 = 0x022,
+ W_BSSID2 = 0x024,
+ W_AIDLow = 0x028,
+ W_AIDFull = 0x02A,
+
+ W_TXRetryLimit = 0x02C,
+ W_RXCnt = 0x030,
+ W_WEPCnt = 0x032,
+
+ W_PowerUS = 0x036,
+ W_PowerTX = 0x038,
+ W_PowerState = 0x03C,
+ W_PowerForce = 0x040,
+ W_PowerUnk = 0x48,
+
+ W_Random = 0x044,
+
+ W_RXBufBegin = 0x050,
+ W_RXBufEnd = 0x052,
+ W_RXBufWriteCursor = 0x054,
+ W_RXBufWriteAddr = 0x056,
+ W_RXBufReadAddr = 0x058,
+ W_RXBufReadCursor = 0x05A,
+ W_RXBufCount = 0x05C,
+ W_RXBufDataRead = 0x060,
+ W_RXBufGapAddr = 0x062,
+ W_RXBufGapSize = 0x064,
+
+ W_TXBufWriteAddr = 0x068,
+ W_TXBufCount = 0x06C,
+ W_TXBufDataWrite = 0x070,
+ W_TXBufGapAddr = 0x074,
+ W_TXBufGapSize = 0x076,
+
+ W_TXSlotBeacon = 0x080,
+ W_TXBeaconTIM = 0x084,
+ W_ListenCount = 0x088,
+ W_BeaconInterval = 0x08C,
+ W_ListenInterval = 0x08E,
+ W_TXSlotCmd = 0x090,
+ W_TXSlotReply1 = 0x094,
+ W_TXSlotReply2 = 0x098,
+ W_TXSlotLoc1 = 0x0A0,
+ W_TXSlotLoc2 = 0x0A4,
+ W_TXSlotLoc3 = 0x0A8,
+ W_TXReqReset = 0x0AC,
+ W_TXReqSet = 0x0AE,
+ W_TXReqRead = 0x0B0,
+ W_TXSlotReset = 0x0B4,
+ W_TXBusy = 0x0B6,
+ W_TXStat = 0x0B8,
+ W_Preamble = 0x0BC,
+ W_CmdTotalTime = 0x0C0,
+ W_CmdReplyTime = 0x0C4,
+ W_RXFilter = 0x0D0,
+ W_RXLenCrop = 0x0DA,
+ W_RXFilter2 = 0x0E0,
+
+ W_USCountCnt = 0x0E8,
+ W_USCompareCnt = 0x0EA,
+ W_CmdCountCnt = 0x0EE,
+
+ W_USCount0 = 0x0F8,
+ W_USCount1 = 0x0FA,
+ W_USCount2 = 0x0FC,
+ W_USCount3 = 0x0FE,
+ W_USCompare0 = 0x0F0,
+ W_USCompare1 = 0x0F2,
+ W_USCompare2 = 0x0F4,
+ W_USCompare3 = 0x0F6,
+
+ W_ContentFree = 0x10C,
+ W_PreBeacon = 0x110,
+ W_CmdCount = 0x118,
+ W_BeaconCount1 = 0x11C,
+ W_BeaconCount2 = 0x134,
+
+ W_BBCnt = 0x158,
+ W_BBWrite = 0x15A,
+ W_BBRead = 0x15C,
+ W_BBBusy = 0x15E,
+ W_BBMode = 0x160,
+ W_BBPower = 0x168,
+
+ W_RFData2 = 0x17C,
+ W_RFData1 = 0x17E,
+ W_RFBusy = 0x180,
+ W_RFCnt = 0x184,
+
+ W_TXHeaderCnt = 0x194,
+ W_RFPins = 0x19C,
+
+ W_RXStatIncIF = 0x1A8,
+ W_RXStatIncIE = 0x1AA,
+ W_RXStatHalfIF = 0x1AC,
+ W_RXStatHalfIE = 0x1AE,
+ W_TXErrorCount = 0x1C0,
+ W_RXCount = 0x1C4,
+
+ W_CMDStat0 = 0x1D0,
+ W_CMDStat1 = 0x1D2,
+ W_CMDStat2 = 0x1D4,
+ W_CMDStat3 = 0x1D6,
+ W_CMDStat4 = 0x1D8,
+ W_CMDStat5 = 0x1DA,
+ W_CMDStat6 = 0x1DC,
+ W_CMDStat7 = 0x1DE,
+
+ W_TXSeqNo = 0x210,
+ 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];
-enum
-{
- Event_RXCheck = 0,
- Event_IRQ15,
- Event_MSTimer,
- Event_RFWakeup,
- Event_RX,
- Event_TX,
- Event_MPClientSync,
- Event_RF,
- Event_BB,
-
- Event_MAX
-};
+ u8 RXBuffer[2048];
+ u32 RXBufferPtr;
+ int RXTime;
+ u32 RXHalfwordTimeMask;
-struct SchedEvent
-{
- void (*Func)(u32 param);
- u64 Timestamp;
- u32 Param;
-};
+ u32 ComStatus; // 0=waiting for packets 1=receiving 2=sending
+ u32 TXCurSlot;
+ u32 RXCounter;
+
+ int MPReplyTimer;
+ u16 MPClientMask, MPClientFail;
+ u8 MPClientReplies[15*1024];
-extern bool MPInited;
+ u16 MPLastSeqno;
+ bool MPInited;
+ bool LANInited;
-bool Init();
-void DeInit();
-void Reset();
-void DoSavestate(Savestate* file);
+ int USUntilPowerOn;
+ bool ForcePowerOn;
-void SetPowerCnt(u32 val);
+ // MULTIPLAYER SYNC APPARATUS
+ bool IsMP;
+ bool IsMPClient;
+ u64 NextSync; // for clients: timestamp for next sync point
+ u64 RXTimestamp;
-void USTimer(u32 param);
+ class WifiAP* WifiAP;
-u16 Read(u32 addr);
-void Write(u32 addr, u16 val);
+ void ScheduleTimer(bool first);
+ void UpdatePowerOn();
-u8* GetMAC();
-u8* GetBSSID();
+ 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();
+};
#endif
diff --git a/src/WifiAP.cpp b/src/WifiAP.cpp
index c9cccea..9107a81 100644
--- a/src/WifiAP.cpp
+++ b/src/WifiAP.cpp
@@ -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;
+bool MACEqual(u8* a, const u8* b);
+bool MACIsBroadcast(u8* a);
-u8 LANBuffer[2048];
-// this is a lazy AP, we only keep track of one client
-// 0=disconnected 1=authenticated 2=associated
-int ClientStatus;
-
-
-bool Init()
+WifiAP::WifiAP(class Wifi* wifi) : Wifi(wifi)
{
- return true;
}
-void DeInit()
+WifiAP::~WifiAP()
{
}
-void Reset()
+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;
}
-
-}
diff --git a/src/WifiAP.h b/src/WifiAP.h
index 04dbfa8..717e1c6 100644
--- a/src/WifiAP.h
+++ b/src/WifiAP.h
@@ -21,24 +21,44 @@
#include "types.h"
-namespace WifiAP
+class Wifi;
+
+class WifiAP
{
+public:
+ WifiAP(Wifi* wifi);
+ ~WifiAP();
+ void Reset();
+
+ static const char* APName;
+ static const u8 APMac[6];
+
+ void MSTimer();
+
+ // packet format: 12-byte TX header + original 802.11 frame
+ int SendPacket(u8* data, int len);
+ int RecvPacket(u8* data);
+
+private:
+ class Wifi* Wifi;
+
+ u64 USCounter;
-#define AP_MAC 0x00, 0xF0, 0x77, 0x77, 0x77, 0x77
-#define AP_NAME "melonAP"
+ u16 SeqNo;
-extern const u8 APMac[6];
+ bool BeaconDue;
-bool Init();
-void DeInit();
-void Reset();
+ u8 PacketBuffer[2048];
+ int PacketLen;
+ int RXNum;
-void MSTimer();
+ u8 LANBuffer[2048];
-// packet format: 12-byte TX header + original 802.11 frame
-int SendPacket(u8* data, int len);
-int RecvPacket(u8* data);
+ // 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