mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-26 15:50:00 -06:00
wifi:
* rework and clean up frame transfer code * disable melonAP during local multiplayer comm
This commit is contained in:
191
src/Wifi.cpp
191
src/Wifi.cpp
@ -85,6 +85,7 @@ struct TXSlot
|
|||||||
};
|
};
|
||||||
|
|
||||||
TXSlot TXSlots[6];
|
TXSlot TXSlots[6];
|
||||||
|
u8 TXBuffer[0x2000];
|
||||||
|
|
||||||
u8 RXBuffer[2048];
|
u8 RXBuffer[2048];
|
||||||
u32 RXBufferPtr;
|
u32 RXBufferPtr;
|
||||||
@ -107,6 +108,7 @@ int USUntilPowerOn;
|
|||||||
bool ForcePowerOn;
|
bool ForcePowerOn;
|
||||||
|
|
||||||
// MULTIPLAYER SYNC APPARATUS
|
// MULTIPLAYER SYNC APPARATUS
|
||||||
|
bool IsMP;
|
||||||
bool IsMPClient;
|
bool IsMPClient;
|
||||||
u64 NextSync; // for clients: timestamp for next sync point
|
u64 NextSync; // for clients: timestamp for next sync point
|
||||||
u64 RXTimestamp;
|
u64 RXTimestamp;
|
||||||
@ -242,6 +244,7 @@ void Reset()
|
|||||||
BlockBeaconIRQ14 = false;
|
BlockBeaconIRQ14 = false;
|
||||||
|
|
||||||
memset(TXSlots, 0, sizeof(TXSlots));
|
memset(TXSlots, 0, sizeof(TXSlots));
|
||||||
|
memset(TXBuffer, 0, sizeof(TXBuffer));
|
||||||
ComStatus = 0;
|
ComStatus = 0;
|
||||||
TXCurSlot = -1;
|
TXCurSlot = -1;
|
||||||
RXCounter = 0;
|
RXCounter = 0;
|
||||||
@ -261,6 +264,7 @@ void Reset()
|
|||||||
USUntilPowerOn = 0;
|
USUntilPowerOn = 0;
|
||||||
ForcePowerOn = false;
|
ForcePowerOn = false;
|
||||||
|
|
||||||
|
IsMP = false;
|
||||||
IsMPClient = false;
|
IsMPClient = false;
|
||||||
NextSync = 0;
|
NextSync = 0;
|
||||||
RXTimestamp = 0;
|
RXTimestamp = 0;
|
||||||
@ -314,6 +318,8 @@ void DoSavestate(Savestate* file)
|
|||||||
file->Var32(&slot->HalfwordTimeMask);
|
file->Var32(&slot->HalfwordTimeMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file->VarArray(TXBuffer, sizeof(TXBuffer));
|
||||||
|
|
||||||
file->VarArray(RXBuffer, sizeof(RXBuffer));
|
file->VarArray(RXBuffer, sizeof(RXBuffer));
|
||||||
file->Var32(&RXBufferPtr);
|
file->Var32(&RXBufferPtr);
|
||||||
file->Var32((u32*)&RXTime);
|
file->Var32((u32*)&RXTime);
|
||||||
@ -332,6 +338,7 @@ void DoSavestate(Savestate* file)
|
|||||||
file->Var32((u32*)&USUntilPowerOn);
|
file->Var32((u32*)&USUntilPowerOn);
|
||||||
file->Bool32(&ForcePowerOn);
|
file->Bool32(&ForcePowerOn);
|
||||||
|
|
||||||
|
file->Bool32(&IsMP);
|
||||||
file->Bool32(&IsMPClient);
|
file->Bool32(&IsMPClient);
|
||||||
file->Var64(&NextSync);
|
file->Var64(&NextSync);
|
||||||
file->Var64(&RXTimestamp);
|
file->Var64(&RXTimestamp);
|
||||||
@ -530,16 +537,73 @@ void ReportMPReplyErrors(u16 clientfail)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreTXAdjust(TXSlot* slot, int num)
|
void TXSendFrame(TXSlot* slot, int num)
|
||||||
{
|
{
|
||||||
u32 noseqno = 0;
|
u32 noseqno = 0;
|
||||||
if (num == 1) noseqno = (IOPORT(W_TXSlotCmd) & 0x4000);
|
|
||||||
|
if (RAM[slot->Addr + 0x4])
|
||||||
|
{
|
||||||
|
noseqno = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (num == 1) noseqno = (IOPORT(W_TXSlotCmd) & 0x4000) ? 1:0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!noseqno)
|
if (!noseqno)
|
||||||
{
|
{
|
||||||
*(u16*)&RAM[slot->Addr + 0xC + 22] = IOPORT(W_TXSeqNo) << 4;
|
if (!(IOPORT(W_TXHeaderCnt) & (1<<2)))
|
||||||
|
*(u16*)&RAM[slot->Addr + 0xC + 22] = IOPORT(W_TXSeqNo) << 4;
|
||||||
IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF;
|
IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 framectl = *(u16*)&RAM[slot->Addr + 0xC];
|
||||||
|
if (framectl & (1<<14))
|
||||||
|
{
|
||||||
|
// WEP frame
|
||||||
|
// TODO: what happens when sending a WEP frame while WEP processing is off?
|
||||||
|
// TODO: some form of actual WEP processing?
|
||||||
|
// for now we just set the WEP FCS to a nonzero value, because some games require it
|
||||||
|
|
||||||
|
if (IOPORT(W_WEPCnt) & (1<<15))
|
||||||
|
{
|
||||||
|
u32 wep_fcs = (slot->Addr + 0xC + slot->Length - 7) & ~0x1;
|
||||||
|
*(u32*)&RAM[wep_fcs] = 0x22334466;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = slot->Length;
|
||||||
|
if ((slot->Addr + len) > 0x1FF4)
|
||||||
|
len = 0x1FF4 - slot->Addr;
|
||||||
|
|
||||||
|
memcpy(TXBuffer, &RAM[slot->Addr], 12+len);
|
||||||
|
|
||||||
|
if (noseqno == 2)
|
||||||
|
*(u16*)&TXBuffer[0xC] |= (1<<11);
|
||||||
|
|
||||||
|
switch (num)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
Platform::MP_SendPacket(TXBuffer, 12+len, USTimestamp);
|
||||||
|
if (!IsMP) WifiAP::SendPacket(TXBuffer, 12+len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
Platform::MP_SendCmd(TXBuffer, 12+len, USTimestamp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
IncrementTXCount(slot);
|
||||||
|
Platform::MP_SendReply(TXBuffer, 12+len, USTimestamp, IOPORT(W_AIDLow));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
*(u64*)&TXBuffer[0xC + 24] = USCounter;
|
||||||
|
Platform::MP_SendPacket(TXBuffer, 12+len, USTimestamp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartTX_LocN(int nslot, int loc)
|
void StartTX_LocN(int nslot, int loc)
|
||||||
@ -549,6 +613,8 @@ void StartTX_LocN(int nslot, int loc)
|
|||||||
if (IOPORT(W_TXSlotLoc1 + (loc*4)) & 0x7000)
|
if (IOPORT(W_TXSlotLoc1 + (loc*4)) & 0x7000)
|
||||||
Log(LogLevel::Warn, "wifi: unusual loc%d bits set %04X\n", loc, IOPORT(W_TXSlotLoc1 + (loc*4)));
|
Log(LogLevel::Warn, "wifi: unusual loc%d bits set %04X\n", loc, IOPORT(W_TXSlotLoc1 + (loc*4)));
|
||||||
|
|
||||||
|
slot->Valid = true;
|
||||||
|
|
||||||
slot->Addr = (IOPORT(W_TXSlotLoc1 + (loc*4)) & 0x0FFF) << 1;
|
slot->Addr = (IOPORT(W_TXSlotLoc1 + (loc*4)) & 0x0FFF) << 1;
|
||||||
slot->Length = *(u16*)&RAM[slot->Addr + 0xA] & 0x3FFF;
|
slot->Length = *(u16*)&RAM[slot->Addr + 0xA] & 0x3FFF;
|
||||||
|
|
||||||
@ -567,6 +633,8 @@ void StartTX_Cmd()
|
|||||||
if (IOPORT(W_TXSlotCmd) & 0x3000)
|
if (IOPORT(W_TXSlotCmd) & 0x3000)
|
||||||
Log(LogLevel::Warn,"wifi: !! unusual TXSLOT_CMD bits set %04X\n", IOPORT(W_TXSlotCmd));
|
Log(LogLevel::Warn,"wifi: !! unusual TXSLOT_CMD bits set %04X\n", IOPORT(W_TXSlotCmd));
|
||||||
|
|
||||||
|
slot->Valid = true;
|
||||||
|
|
||||||
slot->Addr = (IOPORT(W_TXSlotCmd) & 0x0FFF) << 1;
|
slot->Addr = (IOPORT(W_TXSlotCmd) & 0x0FFF) << 1;
|
||||||
slot->Length = *(u16*)&RAM[slot->Addr + 0xA] & 0x3FFF;
|
slot->Length = *(u16*)&RAM[slot->Addr + 0xA] & 0x3FFF;
|
||||||
|
|
||||||
@ -595,6 +663,8 @@ void StartTX_Beacon()
|
|||||||
{
|
{
|
||||||
TXSlot* slot = &TXSlots[4];
|
TXSlot* slot = &TXSlots[4];
|
||||||
|
|
||||||
|
slot->Valid = true;
|
||||||
|
|
||||||
slot->Addr = (IOPORT(W_TXSlotBeacon) & 0x0FFF) << 1;
|
slot->Addr = (IOPORT(W_TXSlotBeacon) & 0x0FFF) << 1;
|
||||||
slot->Length = *(u16*)&RAM[slot->Addr + 0xA] & 0x3FFF;
|
slot->Length = *(u16*)&RAM[slot->Addr + 0xA] & 0x3FFF;
|
||||||
|
|
||||||
@ -716,21 +786,13 @@ void SendMPReply(u16 clienttime, u16 clientmask)
|
|||||||
slot->Valid = false;
|
slot->Valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (RAM[slot->Addr+4] > 0)
|
|
||||||
// printf("REPLY RETRY COUNTER %d (%04X)\n", RAM[slot->Addr+4], IOPORT(W_TXSlotReply2));
|
|
||||||
|
|
||||||
// this seems to be set upon IRQ0
|
// this seems to be set upon IRQ0
|
||||||
// TODO: how does it behave if the packet addr is changed before it gets sent? (maybe just not possible)
|
// TODO: how does it behave if the packet addr is changed before it gets sent? (maybe just not possible)
|
||||||
if (slot->Valid)
|
if (slot->Valid)
|
||||||
{
|
{
|
||||||
//*(u16*)&RAM[slot->Addr + 0x4] = 0x0001;
|
|
||||||
IncrementTXCount(slot);
|
|
||||||
|
|
||||||
slot->CurPhase = 0;
|
slot->CurPhase = 0;
|
||||||
PreTXAdjust(slot, 5);
|
|
||||||
|
|
||||||
int txlen = Platform::MP_SendReply(&RAM[slot->Addr], 12 + slot->Length, USTimestamp, IOPORT(W_AIDLow));
|
TXSendFrame(slot, 5);
|
||||||
WIFI_LOG("wifi: sent %d/%d bytes of MP reply\n", txlen, 12 + slot->Length);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -804,15 +866,6 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||||||
|
|
||||||
u32 curclient = 1 << nclient;
|
u32 curclient = 1 << nclient;
|
||||||
|
|
||||||
/*if (CheckRX(1))
|
|
||||||
{
|
|
||||||
// we received a reply, mark it as such
|
|
||||||
// TODO: is any received packet considered a good reply?
|
|
||||||
// hardware probably requires a specific frame-control and/or destination MAC
|
|
||||||
|
|
||||||
MPClientFail &= ~curclient;
|
|
||||||
}
|
|
||||||
else printf("REPLY %04X NOT RECEIVED\n");*/
|
|
||||||
if (!(MPClientFail & curclient))
|
if (!(MPClientFail & curclient))
|
||||||
MPClientReplyRX(nclient);
|
MPClientReplyRX(nclient);
|
||||||
|
|
||||||
@ -831,23 +884,7 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||||||
SetIRQ(7);
|
SetIRQ(7);
|
||||||
|
|
||||||
if (num == 5)
|
if (num == 5)
|
||||||
{
|
|
||||||
// MP reply slot
|
|
||||||
// setup needs to be done now as port 098 can get changed in the meantime
|
|
||||||
|
|
||||||
SetStatus(8);
|
SetStatus(8);
|
||||||
|
|
||||||
//slot->Addr = (IOPORT(W_TXSlotReply2) & 0x0FFF) << 1;
|
|
||||||
//slot->Length = *(u16*)&RAM[slot->Addr + 0xA] & 0x3FFF;
|
|
||||||
|
|
||||||
/*u8 rate = RAM[slot->Addr + 0x8];
|
|
||||||
if (rate == 0x14) slot->Rate = 2;
|
|
||||||
else slot->Rate = 1;*/
|
|
||||||
|
|
||||||
// TODO: duration should be set by hardware
|
|
||||||
// doesn't seem to be important
|
|
||||||
//RAM[slot->Addr + 0xC + 2] = 0x00F0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
SetStatus(3);
|
SetStatus(3);
|
||||||
|
|
||||||
@ -866,68 +903,19 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||||||
slot->CurPhase = 1;
|
slot->CurPhase = 1;
|
||||||
slot->CurPhaseTime = len;
|
slot->CurPhaseTime = len;
|
||||||
|
|
||||||
u16 framectl = *(u16*)&RAM[slot->Addr + 0xC];
|
|
||||||
if (framectl & (1<<14))
|
|
||||||
{
|
|
||||||
// WEP frame
|
|
||||||
// TODO: what happens when sending a WEP frame while WEP processing is off?
|
|
||||||
// TODO: some form of actual WEP processing?
|
|
||||||
// for now we just set the WEP FCS to a nonzero value, because some games require it
|
|
||||||
|
|
||||||
if (IOPORT(W_WEPCnt) & (1<<15))
|
|
||||||
{
|
|
||||||
u32 wep_fcs = (slot->Addr + 0xC + slot->Length - 7) & ~0x1;
|
|
||||||
*(u32*)&RAM[wep_fcs] = 0x22334466;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 oldts;
|
|
||||||
if (num == 4)
|
|
||||||
{
|
|
||||||
// beacon timestamp
|
|
||||||
oldts = *(u64*)&RAM[slot->Addr + 0xC + 24];
|
|
||||||
*(u64*)&RAM[slot->Addr + 0xC + 24] = USCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((num != 5) && (RAM[slot->Addr+4] > 0))
|
|
||||||
Log(LogLevel::Debug, "SLOT %d RETRY COUNTER %d\n", num, RAM[slot->Addr+4]);
|
|
||||||
|
|
||||||
// set TX addr
|
// set TX addr
|
||||||
IOPORT(W_RXTXAddr) = slot->Addr >> 1;
|
IOPORT(W_RXTXAddr) = slot->Addr >> 1;
|
||||||
|
|
||||||
if (num == 1)
|
if (num != 5)
|
||||||
{
|
{
|
||||||
PreTXAdjust(slot, num);
|
TXSendFrame(slot, num);
|
||||||
|
|
||||||
// send
|
|
||||||
int txlen = Platform::MP_SendCmd(&RAM[slot->Addr], 12 + slot->Length, USTimestamp);
|
|
||||||
WIFI_LOG("wifi: sent %d/%d bytes of slot%d packet, addr=%04X, framectl=%04X, %04X %04X\n",
|
|
||||||
txlen, slot->Length+12, num, slot->Addr, *(u16*)&RAM[slot->Addr + 0xC],
|
|
||||||
*(u16*)&RAM[slot->Addr + 0x24], *(u16*)&RAM[slot->Addr + 0x26]);
|
|
||||||
}
|
|
||||||
else if (num == 5)
|
|
||||||
{
|
|
||||||
// send
|
|
||||||
/*int txlen = Platform::MP_SendReply(&RAM[slot->Addr], 12 + slot->Length, USTimestamp, IOPORT(W_AIDLow));
|
|
||||||
WIFI_LOG("wifi: sent %d/%d bytes of slot%d packet, addr=%04X, framectl=%04X, %04X %04X\n",
|
|
||||||
txlen, slot->Length+12, num, slot->Addr, *(u16*)&RAM[slot->Addr + 0xC],
|
|
||||||
*(u16*)&RAM[slot->Addr + 0x24], *(u16*)&RAM[slot->Addr + 0x26]);*/
|
|
||||||
}
|
|
||||||
else //if (num != 5)
|
|
||||||
{
|
|
||||||
PreTXAdjust(slot, num);
|
|
||||||
|
|
||||||
// send
|
|
||||||
int txlen = Platform::MP_SendPacket(&RAM[slot->Addr], 12 + slot->Length, USTimestamp);
|
|
||||||
WIFI_LOG("wifi: sent %d/%d bytes of slot%d packet, addr=%04X, framectl=%04X, %04X %04X\n",
|
|
||||||
txlen, slot->Length+12, num, slot->Addr, *(u16*)&RAM[slot->Addr + 0xC],
|
|
||||||
*(u16*)&RAM[slot->Addr + 0x24], *(u16*)&RAM[slot->Addr + 0x26]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the packet is being sent via LOC1..3, send it to the AP
|
// if the packet is being sent via LOC1..3, send it to the AP
|
||||||
// any packet sent via CMD/REPLY/BEACON isn't going to have much use outside of local MP
|
// any packet sent via CMD/REPLY/BEACON isn't going to have much use outside of local MP
|
||||||
if (num == 0 || num == 2 || num == 3)
|
if (num == 0 || num == 2 || num == 3)
|
||||||
{
|
{
|
||||||
|
u16 framectl = *(u16*)&RAM[slot->Addr + 0xC];
|
||||||
if ((framectl & 0x00FF) == 0x0010)
|
if ((framectl & 0x00FF) == 0x0010)
|
||||||
{
|
{
|
||||||
u16 aid = *(u16*)&RAM[slot->Addr + 0xC + 24 + 4];
|
u16 aid = *(u16*)&RAM[slot->Addr + 0xC + 24 + 4];
|
||||||
@ -938,16 +926,10 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||||||
if (IsMPClient)
|
if (IsMPClient)
|
||||||
{
|
{
|
||||||
Log(LogLevel::Info, "[CLIENT] deauth\n");
|
Log(LogLevel::Info, "[CLIENT] deauth\n");
|
||||||
|
IsMP = false;
|
||||||
IsMPClient = false;
|
IsMPClient = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiAP::SendPacket(&RAM[slot->Addr], 12 + slot->Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num == 4)
|
|
||||||
{
|
|
||||||
*(u64*)&RAM[slot->Addr + 0xC + 24] = oldts;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -957,10 +939,6 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||||||
SetIRQ(7);
|
SetIRQ(7);
|
||||||
SetStatus(8);
|
SetStatus(8);
|
||||||
|
|
||||||
//SendMPDefaultReply();
|
|
||||||
|
|
||||||
//slot->Addr = 0;
|
|
||||||
//slot->Length = 28;
|
|
||||||
slot->CurPhase = 11;
|
slot->CurPhase = 11;
|
||||||
slot->CurPhaseTime = 28*4;
|
slot->CurPhaseTime = 28*4;
|
||||||
slot->HalfwordTimeMask = 0xFFFFFFFF;
|
slot->HalfwordTimeMask = 0xFFFFFFFF;
|
||||||
@ -984,7 +962,6 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||||||
SetStatus(5);
|
SetStatus(5);
|
||||||
|
|
||||||
u16 clientmask = *(u16*)&RAM[slot->Addr + 12 + 24 + 2] & 0xFFFE;
|
u16 clientmask = *(u16*)&RAM[slot->Addr + 12 + 24 + 2] & 0xFFFE;
|
||||||
//MPNumReplies = NumClients(clientmask);
|
|
||||||
MPReplyTimer = 16 + PreambleLen(slot->Rate);
|
MPReplyTimer = 16 + PreambleLen(slot->Rate);
|
||||||
MPClientMask = clientmask;
|
MPClientMask = clientmask;
|
||||||
MPClientFail = clientmask;
|
MPClientFail = clientmask;
|
||||||
@ -1085,7 +1062,8 @@ bool ProcessTX(TXSlot* slot, int num)
|
|||||||
|
|
||||||
// this is set to indicate which clients failed to reply
|
// this is set to indicate which clients failed to reply
|
||||||
*(u16*)&RAM[slot->Addr + 0x2] = MPClientFail;
|
*(u16*)&RAM[slot->Addr + 0x2] = MPClientFail;
|
||||||
IncrementTXCount(slot);
|
if (!MPClientFail)
|
||||||
|
IncrementTXCount(slot);
|
||||||
|
|
||||||
IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF;
|
IOPORT(W_TXSeqNo) = (IOPORT(W_TXSeqNo) + 1) & 0x0FFF;
|
||||||
|
|
||||||
@ -1497,7 +1475,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
|||||||
if (type == 0)
|
if (type == 0)
|
||||||
{
|
{
|
||||||
rxlen = Platform::MP_RecvPacket(RXBuffer, ×tamp);
|
rxlen = Platform::MP_RecvPacket(RXBuffer, ×tamp);
|
||||||
if (rxlen <= 0)
|
if ((rxlen <= 0) && (!IsMP))
|
||||||
rxlen = WifiAP::RecvPacket(RXBuffer);
|
rxlen = WifiAP::RecvPacket(RXBuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1507,6 +1485,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
|||||||
{
|
{
|
||||||
// host is gone
|
// host is gone
|
||||||
// TODO: make this more resilient
|
// TODO: make this more resilient
|
||||||
|
IsMP = false;
|
||||||
IsMPClient = false;
|
IsMPClient = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1556,6 +1535,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
|||||||
{
|
{
|
||||||
Log(LogLevel::Debug, "[CLIENT %01X] host sync=%016llX\n", aid&0xF, timestamp);
|
Log(LogLevel::Debug, "[CLIENT %01X] host sync=%016llX\n", aid&0xF, timestamp);
|
||||||
|
|
||||||
|
IsMP = true;
|
||||||
IsMPClient = true;
|
IsMPClient = true;
|
||||||
USTimestamp = timestamp;
|
USTimestamp = timestamp;
|
||||||
NextSync = RXTimestamp + (framelen * (txrate==0x14 ? 4:8));
|
NextSync = RXTimestamp + (framelen * (txrate==0x14 ? 4:8));
|
||||||
@ -1566,6 +1546,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
|||||||
}
|
}
|
||||||
else if (((framectl & 0x00FF) == 0x00C0) && timestamp && macgood && IsMPClient)
|
else if (((framectl & 0x00FF) == 0x00C0) && timestamp && macgood && IsMPClient)
|
||||||
{
|
{
|
||||||
|
IsMP = false;
|
||||||
IsMPClient = false;
|
IsMPClient = false;
|
||||||
NextSync = 0;
|
NextSync = 0;
|
||||||
|
|
||||||
@ -2251,6 +2232,10 @@ void Write(u32 addr, u16 val)
|
|||||||
val &= 0x0FFF;
|
val &= 0x0FFF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case W_TXSlotBeacon:
|
||||||
|
IsMP = (val & 0x8000) != 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case W_TXSlotCmd:
|
case W_TXSlotCmd:
|
||||||
if (CmdCounter == 0)
|
if (CmdCounter == 0)
|
||||||
val = (val & 0x7FFF) | (IOPORT(W_TXSlotCmd) & 0x8000);
|
val = (val & 0x7FFF) | (IOPORT(W_TXSlotCmd) & 0x8000);
|
||||||
|
Reference in New Issue
Block a user