* begin adding POWCNT2, only applies to wifi for now
* begin work on wifi scheduler
This commit is contained in:
parent
fb73b80674
commit
cc68017f52
43
src/NDS.cpp
43
src/NDS.cpp
|
@ -1198,6 +1198,25 @@ void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 para
|
|||
Reschedule(evt->Timestamp);
|
||||
}
|
||||
|
||||
void ScheduleEvent(u32 id, u64 timestamp, void (*func)(u32), u32 param)
|
||||
{
|
||||
if (SchedListMask & (1<<id))
|
||||
{
|
||||
printf("!! EVENT %d ALREADY SCHEDULED\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
SchedEvent* evt = &SchedList[id];
|
||||
|
||||
evt->Timestamp = timestamp;
|
||||
evt->Func = func;
|
||||
evt->Param = param;
|
||||
|
||||
SchedListMask |= (1<<id);
|
||||
|
||||
Reschedule(evt->Timestamp);
|
||||
}
|
||||
|
||||
void CancelEvent(u32 id)
|
||||
{
|
||||
SchedListMask &= ~(1<<id);
|
||||
|
@ -2396,6 +2415,7 @@ u8 ARM7Read8(u32 addr)
|
|||
case 0x04800000:
|
||||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return 0;
|
||||
if (addr & 0x1) return Wifi::Read(addr-1) >> 8;
|
||||
return Wifi::Read(addr) & 0xFF;
|
||||
}
|
||||
|
@ -2460,6 +2480,7 @@ u16 ARM7Read16(u32 addr)
|
|||
case 0x04800000:
|
||||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return 0;
|
||||
return Wifi::Read(addr);
|
||||
}
|
||||
break;
|
||||
|
@ -2523,6 +2544,7 @@ u32 ARM7Read32(u32 addr)
|
|||
case 0x04800000:
|
||||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return 0;
|
||||
return Wifi::Read(addr) | (Wifi::Read(addr+2) << 16);
|
||||
}
|
||||
break;
|
||||
|
@ -2663,6 +2685,7 @@ void ARM7Write16(u32 addr, u16 val)
|
|||
case 0x04800000:
|
||||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return;
|
||||
Wifi::Write(addr, val);
|
||||
return;
|
||||
}
|
||||
|
@ -2740,6 +2763,7 @@ void ARM7Write32(u32 addr, u32 val)
|
|||
case 0x04800000:
|
||||
if (addr < 0x04810000)
|
||||
{
|
||||
if (!(PowerControl7 & (1<<1))) return;
|
||||
Wifi::Write(addr, val & 0xFFFF);
|
||||
Wifi::Write(addr+2, val >> 16);
|
||||
return;
|
||||
|
@ -3751,6 +3775,7 @@ u8 ARM7IORead8(u32 addr)
|
|||
case 0x04000241: return WRAMCnt;
|
||||
|
||||
case 0x04000300: return PostFlag7;
|
||||
case 0x04000304: return PowerControl7;
|
||||
}
|
||||
|
||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||
|
@ -3833,7 +3858,9 @@ u16 ARM7IORead16(u32 addr)
|
|||
case 0x040001C2: return SPI::ReadData();
|
||||
|
||||
case 0x04000204: return ExMemCnt[1];
|
||||
case 0x04000206: return WifiWaitCnt;
|
||||
case 0x04000206:
|
||||
if (!(PowerControl7 & (1<<1))) return 0;
|
||||
return WifiWaitCnt;
|
||||
|
||||
case 0x04000208: return IME[1];
|
||||
case 0x04000210: return IE[1] & 0xFFFF;
|
||||
|
@ -3915,6 +3942,7 @@ u32 ARM7IORead32(u32 addr)
|
|||
case 0x04000210: return IE[1];
|
||||
case 0x04000214: return IF[1];
|
||||
|
||||
case 0x04000304: return PowerControl7;
|
||||
case 0x04000308: return ARM7BIOSProt;
|
||||
|
||||
case 0x04100000:
|
||||
|
@ -4143,6 +4171,7 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
|||
return;
|
||||
}
|
||||
case 0x04000206:
|
||||
if (!(PowerControl7 & (1<<1))) return;
|
||||
SetWifiWaitCnt(val);
|
||||
return;
|
||||
|
||||
|
@ -4158,7 +4187,11 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
|||
PostFlag7 = val & 0x01;
|
||||
return;
|
||||
|
||||
case 0x04000304: PowerControl7 = val; return;
|
||||
case 0x04000304:
|
||||
PowerControl7 = val & 0x0003;
|
||||
SPU::SetPowerCnt(val & 0x0001);
|
||||
Wifi::SetPowerCnt(val & 0x0002);
|
||||
return;
|
||||
|
||||
case 0x04000308:
|
||||
if (ARM7BIOSProt == 0)
|
||||
|
@ -4280,7 +4313,11 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
|||
case 0x04000210: IE[1] = val; UpdateIRQ(1); return;
|
||||
case 0x04000214: IF[1] &= ~val; UpdateIRQ(1); return;
|
||||
|
||||
case 0x04000304: PowerControl7 = val & 0xFFFF; return;
|
||||
case 0x04000304:
|
||||
PowerControl7 = val & 0x0003;
|
||||
SPU::SetPowerCnt(val & 0x0001);
|
||||
Wifi::SetPowerCnt(val & 0x0002);
|
||||
return;
|
||||
|
||||
case 0x04000308:
|
||||
if (ARM7BIOSProt == 0)
|
||||
|
|
|
@ -52,6 +52,8 @@ enum
|
|||
Event_DSi_CamTransfer,
|
||||
Event_DSi_DSP,
|
||||
|
||||
Event_WifiLegacy,
|
||||
|
||||
Event_MAX
|
||||
};
|
||||
|
||||
|
@ -263,6 +265,7 @@ void SetLidClosed(bool closed);
|
|||
void MicInputFrame(s16* data, int samples);
|
||||
|
||||
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param);
|
||||
void ScheduleEvent(u32 id, u64 timestamp, void (*func)(u32), u32 param);
|
||||
void CancelEvent(u32 id);
|
||||
|
||||
void debug(u32 p);
|
||||
|
|
|
@ -184,6 +184,12 @@ void DoSavestate(Savestate* file)
|
|||
}
|
||||
|
||||
|
||||
void SetPowerCnt(u32 val)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
void SetInterpolation(int type)
|
||||
{
|
||||
InterpType = type;
|
||||
|
|
|
@ -31,6 +31,8 @@ void Stop();
|
|||
|
||||
void DoSavestate(Savestate* file);
|
||||
|
||||
void SetPowerCnt(u32 val);
|
||||
|
||||
// 0=none 1=linear 2=cosine 3=cubic
|
||||
void SetInterpolation(int type);
|
||||
|
||||
|
|
313
src/Wifi.cpp
313
src/Wifi.cpp
|
@ -46,11 +46,20 @@ 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};
|
||||
|
||||
bool Enabled;
|
||||
bool PowerOn;
|
||||
|
||||
u16 Random;
|
||||
|
||||
// general, always-on microsecond counter
|
||||
u64 USTimestamp;
|
||||
|
||||
u64 SchedTimestamp;
|
||||
SchedEvent SchedList[Event_MAX];
|
||||
u32 SchedListMask;
|
||||
|
||||
const u32 kRXCheckPeriod = 512;
|
||||
|
||||
u64 USCounter;
|
||||
u64 USCompare;
|
||||
bool BlockBeaconIRQ14;
|
||||
|
@ -137,21 +146,35 @@ const u64 kMaxRunahead = 4096;
|
|||
// 4 = switching from TX to RX
|
||||
// 5 = MP host data sent, waiting for replies (RFPINS=0x0084)
|
||||
// 6 = RX
|
||||
// 7 = ??
|
||||
// 7 = switching from RX reply to TX ack
|
||||
// 8 = MP client sending reply, MP host sending ack (RFPINS=0x0046)
|
||||
// 9 = idle
|
||||
|
||||
|
||||
// wifi TODO:
|
||||
// * power saving
|
||||
// * RXSTAT, multiplay reply errors
|
||||
// * RXSTAT
|
||||
// * TX errors (if applicable)
|
||||
|
||||
|
||||
void UpdateTimers();
|
||||
void Reschedule();
|
||||
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param);
|
||||
void CancelEvent(u32 id);
|
||||
|
||||
void StartTX_Beacon();
|
||||
void PeriodicRXCheck(u32 time);
|
||||
|
||||
|
||||
bool Init()
|
||||
{
|
||||
MPInited = false;
|
||||
LANInited = false;
|
||||
//MPInited = false;
|
||||
//LANInited = false;
|
||||
|
||||
Platform::MP_Init();
|
||||
MPInited = true;
|
||||
|
||||
Platform::LAN_Init();
|
||||
LANInited = true;
|
||||
|
||||
WifiAP::Init();
|
||||
|
||||
|
@ -173,6 +196,9 @@ void Reset()
|
|||
memset(RAM, 0, 0x2000);
|
||||
memset(IO, 0, 0x1000);
|
||||
|
||||
Enabled = false;
|
||||
PowerOn = false;
|
||||
|
||||
Random = 1;
|
||||
|
||||
memset(BBRegs, 0, 0x100);
|
||||
|
@ -231,6 +257,10 @@ void Reset()
|
|||
USTimestamp = 0;
|
||||
RXTimestamp = 0;
|
||||
|
||||
SchedTimestamp = 0;
|
||||
memset(SchedList, 0, sizeof(SchedList));
|
||||
SchedListMask = 0;
|
||||
|
||||
USCounter = 0;
|
||||
USCompare = 0;
|
||||
BlockBeaconIRQ14 = false;
|
||||
|
@ -290,6 +320,178 @@ void DoSavestate(Savestate* file)
|
|||
}
|
||||
|
||||
|
||||
void UpdatePowerOn();
|
||||
|
||||
void SetPowerCnt(u32 val)
|
||||
{
|
||||
Enabled = val & (1<<1);
|
||||
UpdatePowerOn();
|
||||
}
|
||||
|
||||
|
||||
// wifi scheduling
|
||||
// NOTE: this is technically inaccurate
|
||||
// in the DS, the wifi system is driven by its own 22MHz clock, not by the system clock
|
||||
// but in melonDS, we do need to drive it from the system scheduler, so it stays in sync
|
||||
// with the rest of the system
|
||||
|
||||
inline u64 USToSysCycles(u64 us)
|
||||
{
|
||||
return (us * 33513982) / 1000000;
|
||||
}
|
||||
|
||||
inline u64 SysCyclesToUS(u64 sys)
|
||||
{
|
||||
return ((sys + 16) * 1000000) / 33513982;
|
||||
}
|
||||
|
||||
void UpdateTimers()
|
||||
{
|
||||
u64 oldts = SchedTimestamp;
|
||||
SchedTimestamp = SysCyclesToUS(NDS::GetSysClockCycles(0));
|
||||
u64 diff = SchedTimestamp - oldts;
|
||||
if (diff == 0) return;
|
||||
|
||||
USTimestamp += diff;
|
||||
|
||||
if (IOPORT(W_USCountCnt))
|
||||
{
|
||||
USCounter += diff;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePowerOn()
|
||||
{
|
||||
bool on = Enabled;
|
||||
|
||||
if (NDS::ConsoleType == 1)
|
||||
{
|
||||
// TODO for DSi:
|
||||
// * W_POWER_US doesn't work (atleast on DWM-W024)
|
||||
// * other registers like GPIO_WIFI may also control wifi power/clock
|
||||
// * turning wifi off via POWCNT2 while sending breaks further attempts at sending frames
|
||||
}
|
||||
else
|
||||
{
|
||||
on = on && ((IOPORT(W_PowerUS) & 0x1) == 0);
|
||||
}
|
||||
|
||||
if (on == PowerOn)
|
||||
return;
|
||||
|
||||
PowerOn = on;
|
||||
if (on)
|
||||
{
|
||||
printf("WIFI: ON\n");
|
||||
|
||||
u64 oldts = SchedTimestamp;
|
||||
SchedTimestamp = SysCyclesToUS(NDS::GetSysClockCycles(0));
|
||||
u64 diff = SchedTimestamp - oldts;
|
||||
|
||||
for (int i = 0; i < Event_MAX; i++)
|
||||
{
|
||||
if (!(SchedListMask & (1<<i)))
|
||||
continue;
|
||||
|
||||
if (SchedList[i].Timestamp >= oldts)
|
||||
{
|
||||
SchedList[i].Timestamp += diff;
|
||||
}
|
||||
}
|
||||
|
||||
ScheduleEvent(Event_RXCheck, false, kRXCheckPeriod, PeriodicRXCheck, 0);
|
||||
|
||||
Platform::MP_Begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WIFI: OFF\n");
|
||||
|
||||
CancelEvent(Event_RXCheck);
|
||||
|
||||
UpdateTimers();
|
||||
NDS::CancelEvent(NDS::Event_Wifi);
|
||||
|
||||
Platform::MP_End();
|
||||
}
|
||||
}
|
||||
|
||||
void RunEvents(u32 param)
|
||||
{
|
||||
UpdateTimers();
|
||||
//printf("[%016llX] RUN EVENTS, MASK=%08X\n", SchedTimestamp, SchedListMask);
|
||||
u32 mask = SchedListMask;
|
||||
for (int i = 0; i < Event_MAX; i++)
|
||||
{
|
||||
if (!mask) break;
|
||||
if (mask & 0x1)
|
||||
{
|
||||
if (SchedList[i].Timestamp <= SchedTimestamp)
|
||||
{
|
||||
SchedListMask &= ~(1<<i);
|
||||
SchedList[i].Func(SchedList[i].Param);
|
||||
}
|
||||
}
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Reschedule()
|
||||
{
|
||||
u64 next = UINT64_MAX;
|
||||
|
||||
u32 mask = SchedListMask;
|
||||
for (int i = 0; i < Event_MAX; i++)
|
||||
{
|
||||
if (!mask) break;
|
||||
if (mask & 0x1)
|
||||
{
|
||||
if (SchedList[i].Timestamp < next)
|
||||
next = SchedList[i].Timestamp;
|
||||
}
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
//printf("[%016llX] RESCHEDULE: NEXT TIMESTAMP = %016llX\n", SchedTimestamp, next);
|
||||
NDS::CancelEvent(NDS::Event_Wifi);
|
||||
NDS::ScheduleEvent(NDS::Event_Wifi, USToSysCycles(next), RunEvents, 0);
|
||||
}
|
||||
|
||||
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param)
|
||||
{
|
||||
if (SchedListMask & (1<<id))
|
||||
{
|
||||
printf("wifi: !! EVENT %d ALREADY SCHEDULED\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
SchedEvent* evt = &SchedList[id];
|
||||
|
||||
if (periodic)
|
||||
{
|
||||
evt->Timestamp += delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateTimers();
|
||||
evt->Timestamp = SchedTimestamp + delay;
|
||||
}
|
||||
|
||||
evt->Func = func;
|
||||
evt->Param = param;
|
||||
|
||||
SchedListMask |= (1<<id);
|
||||
//if(id==Event_MSTimer) printf("[%016llX] MSTIMER EVENT SCHEDULED: %d,%d , TIMESTAMP=%016llX\n", SchedTimestamp, periodic, delay, evt->Timestamp);
|
||||
Reschedule();
|
||||
}
|
||||
|
||||
void CancelEvent(u32 id)
|
||||
{
|
||||
SchedListMask &= ~(1<<id);
|
||||
}
|
||||
|
||||
|
||||
void PowerDown();
|
||||
|
||||
void SetIRQ(u32 irq)
|
||||
|
@ -346,7 +548,7 @@ void SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced
|
|||
IOPORT(W_ListenCount)--;
|
||||
}
|
||||
|
||||
void SetIRQ15()
|
||||
void SetIRQ15(u32 param)
|
||||
{
|
||||
SetIRQ(15);
|
||||
|
||||
|
@ -1343,7 +1545,18 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
|||
}
|
||||
|
||||
|
||||
void MSTimer()
|
||||
void PeriodicRXCheck(u32 time)
|
||||
{
|
||||
if (!time) WifiAP::MSTimer();
|
||||
|
||||
// TODO: actual RX check!!
|
||||
|
||||
time += kRXCheckPeriod;
|
||||
time &= 0x3FF;
|
||||
ScheduleEvent(Event_RXCheck, true, kRXCheckPeriod, PeriodicRXCheck, time);
|
||||
}
|
||||
|
||||
void MSTimer(u32 param)
|
||||
{
|
||||
if (IOPORT(W_USCompareCnt))
|
||||
{
|
||||
|
@ -1355,6 +1568,12 @@ void MSTimer()
|
|||
}
|
||||
|
||||
IOPORT(W_BeaconCount1)--;
|
||||
if (IOPORT(W_BeaconCount1) == ((IOPORT(W_PreBeacon) >> 10) + 1))
|
||||
{
|
||||
s32 delay = (IOPORT(W_BeaconCount1) << 10) - IOPORT(W_PreBeacon);
|
||||
CancelEvent(Event_IRQ15);
|
||||
ScheduleEvent(Event_IRQ15, false, delay, SetIRQ15, 0);
|
||||
}
|
||||
if (IOPORT(W_BeaconCount1) == 0)
|
||||
{
|
||||
SetIRQ14(1);
|
||||
|
@ -1365,11 +1584,18 @@ void MSTimer()
|
|||
IOPORT(W_BeaconCount2)--;
|
||||
if (IOPORT(W_BeaconCount2) == 0) SetIRQ13();
|
||||
}
|
||||
printf("MSTimer %016llX %016llX\n", SchedTimestamp, USCounter);
|
||||
ScheduleEvent(Event_MSTimer, true, 1024, MSTimer, 0);
|
||||
}
|
||||
|
||||
void USTimer(u32 param)
|
||||
{
|
||||
USTimestamp++;
|
||||
/*USTimestamp++;
|
||||
|
||||
u64 sys = NDS::GetSysClockCycles(0);
|
||||
u64 ts = SysCyclesToUS(sys);
|
||||
ts = USTimestamp - ts;
|
||||
printf("diff=%016llX\n", ts);
|
||||
|
||||
if (IsMPClient)
|
||||
{
|
||||
|
@ -1386,10 +1612,10 @@ void USTimer(u32 param)
|
|||
CheckRX(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
WifiAP::USTimer();
|
||||
//WifiAP::USTimer();
|
||||
|
||||
bool switchOffPowerSaving = false;
|
||||
if (USUntilPowerOn < 0)
|
||||
|
@ -1406,7 +1632,7 @@ void USTimer(u32 param)
|
|||
SetIRQ(11);
|
||||
}
|
||||
|
||||
if (IOPORT(W_USCountCnt))
|
||||
/*if (IOPORT(W_USCountCnt))
|
||||
{
|
||||
USCounter++;
|
||||
u32 uspart = (USCounter & 0x3FF);
|
||||
|
@ -1418,7 +1644,7 @@ void USTimer(u32 param)
|
|||
}
|
||||
|
||||
if (!uspart) MSTimer();
|
||||
}
|
||||
}*/
|
||||
|
||||
if (IOPORT(W_CmdCountCnt) & 0x0001)
|
||||
{
|
||||
|
@ -1590,8 +1816,10 @@ void USTimer(u32 param)
|
|||
|
||||
// TODO: make it more accurate, eventually
|
||||
// in the DS, the wifi system has its own 22MHz clock and doesn't use the system clock
|
||||
// measurement: 16715us per frame
|
||||
// calculation: 16715.113113088143330744761992174us per frame
|
||||
//NDS::ScheduleEvent(NDS::Event_Wifi, true, 33, USTimer, 0);
|
||||
NDS::ScheduleEvent(NDS::Event_Wifi, true, 34, USTimer, 0);
|
||||
NDS::ScheduleEvent(NDS::Event_WifiLegacy, true, 34, USTimer, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1654,10 +1882,10 @@ u16 Read(u32 addr)
|
|||
case W_Preamble:
|
||||
return IOPORT(W_Preamble) & 0x0003;
|
||||
|
||||
case W_USCount0: return (u16)(USCounter & 0xFFFF);
|
||||
case W_USCount1: return (u16)((USCounter >> 16) & 0xFFFF);
|
||||
case W_USCount2: return (u16)((USCounter >> 32) & 0xFFFF);
|
||||
case W_USCount3: return (u16)(USCounter >> 48);
|
||||
case W_USCount0: UpdateTimers(); return (u16)(USCounter & 0xFFFF);
|
||||
case W_USCount1: UpdateTimers(); return (u16)((USCounter >> 16) & 0xFFFF);
|
||||
case W_USCount2: UpdateTimers(); return (u16)((USCounter >> 32) & 0xFFFF);
|
||||
case W_USCount3: UpdateTimers(); return (u16)(USCounter >> 48);
|
||||
|
||||
case W_USCompare0: return (u16)(USCompare & 0xFFFF);
|
||||
case W_USCompare1: return (u16)((USCompare >> 16) & 0xFFFF);
|
||||
|
@ -1894,31 +2122,9 @@ void Write(u32 addr, u16 val)
|
|||
}
|
||||
break;
|
||||
case W_PowerUS:
|
||||
// schedule timer event when the clock is enabled
|
||||
// TODO: check whether this resets USCOUNT (and also which other events can reset it)
|
||||
if ((IOPORT(W_PowerUS) & 0x0001) && !(val & 0x0001))
|
||||
{
|
||||
printf("WIFI ON\n");
|
||||
NDS::ScheduleEvent(NDS::Event_Wifi, false, 33, USTimer, 0);
|
||||
if (!MPInited)
|
||||
{
|
||||
Platform::MP_Init();
|
||||
MPInited = true;
|
||||
}
|
||||
if (!LANInited)
|
||||
{
|
||||
Platform::LAN_Init();
|
||||
LANInited = true;
|
||||
}
|
||||
Platform::MP_Begin();
|
||||
}
|
||||
else if (!(IOPORT(W_PowerUS) & 0x0001) && (val & 0x0001))
|
||||
{
|
||||
printf("WIFI OFF\n");
|
||||
NDS::CancelEvent(NDS::Event_Wifi);
|
||||
Platform::MP_End();
|
||||
}
|
||||
break;
|
||||
IOPORT(W_PowerUS) = val & 0x0003;
|
||||
UpdatePowerOn();
|
||||
return;
|
||||
case W_PowerUnk:
|
||||
val &= 0x0003;
|
||||
//printf("writing power unk %x\n", val);
|
||||
|
@ -1928,16 +2134,29 @@ void Write(u32 addr, u16 val)
|
|||
val = 3;
|
||||
break;
|
||||
|
||||
case W_USCountCnt: val &= 0x0001; break;
|
||||
case W_USCountCnt:
|
||||
val &= 0x0001;
|
||||
if (val && (!IOPORT(W_USCountCnt)))
|
||||
{printf("[%016llX][%016llX] ON -> NEXT=%016llX\n", SchedTimestamp, USCounter, USCounter + 1024 - (USCounter & 0x3FF));
|
||||
ScheduleEvent(Event_MSTimer, false, 1024 - (USCounter & 0x3FF), MSTimer, 0);
|
||||
IOPORT(W_USCountCnt) = val;
|
||||
}
|
||||
else if ((!val) && IOPORT(W_USCountCnt))
|
||||
{
|
||||
UpdateTimers();printf("[%016llX][%016llX] OFF\n", SchedTimestamp, USCounter);
|
||||
IOPORT(W_USCountCnt) = val;
|
||||
CancelEvent(Event_MSTimer);
|
||||
}
|
||||
return;
|
||||
case W_USCompareCnt:
|
||||
if (val & 0x0002) SetIRQ14(2);
|
||||
val &= 0x0001;
|
||||
break;
|
||||
|
||||
case W_USCount0: USCounter = (USCounter & 0xFFFFFFFFFFFF0000) | (u64)val; return;
|
||||
case W_USCount1: USCounter = (USCounter & 0xFFFFFFFF0000FFFF) | ((u64)val << 16); return;
|
||||
case W_USCount2: USCounter = (USCounter & 0xFFFF0000FFFFFFFF) | ((u64)val << 32); return;
|
||||
case W_USCount3: USCounter = (USCounter & 0x0000FFFFFFFFFFFF) | ((u64)val << 48); return;
|
||||
case W_USCount0: UpdateTimers(); USCounter = (USCounter & 0xFFFFFFFFFFFF0000) | (u64)val; return;
|
||||
case W_USCount1: UpdateTimers(); USCounter = (USCounter & 0xFFFFFFFF0000FFFF) | ((u64)val << 16); return;
|
||||
case W_USCount2: UpdateTimers(); USCounter = (USCounter & 0xFFFF0000FFFFFFFF) | ((u64)val << 32); return;
|
||||
case W_USCount3: UpdateTimers(); USCounter = (USCounter & 0x0000FFFFFFFFFFFF) | ((u64)val << 48); return;
|
||||
|
||||
case W_USCompare0:
|
||||
USCompare = (USCompare & 0xFFFFFFFFFFFF0000) | (u64)(val & 0xFC00);
|
||||
|
|
23
src/Wifi.h
23
src/Wifi.h
|
@ -151,6 +151,27 @@ enum
|
|||
W_RXTXAddr = 0x268,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Event_RXCheck = 0,
|
||||
Event_IRQ15,
|
||||
Event_MSTimer,
|
||||
Event_PowerOn,
|
||||
Event_MPClientSync,
|
||||
Event_TRX,
|
||||
Event_RF,
|
||||
Event_BB,
|
||||
|
||||
Event_MAX
|
||||
};
|
||||
|
||||
struct SchedEvent
|
||||
{
|
||||
void (*Func)(u32 param);
|
||||
u64 Timestamp;
|
||||
u32 Param;
|
||||
};
|
||||
|
||||
|
||||
extern bool MPInited;
|
||||
|
||||
|
@ -160,7 +181,7 @@ void DeInit();
|
|||
void Reset();
|
||||
void DoSavestate(Savestate* file);
|
||||
|
||||
void StartTX_Beacon();
|
||||
void SetPowerCnt(u32 val);
|
||||
|
||||
void USTimer(u32 param);
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ bool MACIsBroadcast(u8* a)
|
|||
}
|
||||
|
||||
|
||||
// REMOVE ME!!
|
||||
void USTimer()
|
||||
{
|
||||
USCounter++;
|
||||
|
|
Loading…
Reference in New Issue