Skip to content

Commit a0daabd

Browse files
committed
Get a little bit further with multiplayer
1 parent d0a9206 commit a0daabd

File tree

4 files changed

+145
-78
lines changed

4 files changed

+145
-78
lines changed

src/memory.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,7 @@ template <typename T> T Memory::ioRead7(uint32_t address)
11081108
DEF_IO32(0x4100000, data = core->ipc.readIpcFifoRecv(1)) // IPCFIFORECV (ARM7)
11091109
DEF_IO32(0x4100010, data = core->cartridgeNds.readRomDataIn(1)) // ROMDATAIN (ARM7)
11101110
DEF_IO16(0x4800006, data = core->wifi.readWModeWep()) // W_MODE_WEP
1111+
DEF_IO16(0x4800008, data = core->wifi.readWTxstatCnt()) // W_TXSTAT_CNT
11111112
DEF_IO16(0x4800010, data = core->wifi.readWIrf()) // W_IF
11121113
DEF_IO16(0x4800012, data = core->wifi.readWIe()) // W_IE
11131114
DEF_IO16(0x4800018, data = core->wifi.readWMacaddr(0)) // W_MACADDR_0
@@ -1141,8 +1142,17 @@ template <typename T> T Memory::ioRead7(uint32_t address)
11411142
DEF_IO16(0x48000A4, data = core->wifi.readWTxbufLoc(2)) // W_TXBUF_LOC2
11421143
DEF_IO16(0x48000A8, data = core->wifi.readWTxbufLoc(3)) // W_TXBUF_LOC3
11431144
DEF_IO16(0x48000B0, data = core->wifi.readWTxreqRead()) // W_TXREQ_READ
1145+
DEF_IO16(0x48000B8, data = core->wifi.readWTxstat()) // W_TXSTAT
11441146
DEF_IO16(0x48000E8, data = core->wifi.readWUsCountcnt()) // W_US_COUNTCNT
11451147
DEF_IO16(0x48000EA, data = core->wifi.readWUsComparecnt()) // W_US_COMPARECNT
1148+
DEF_IO16(0x48000F0, data = core->wifi.readWUsCompare(0)) // W_US_COMPARE0
1149+
DEF_IO16(0x48000F2, data = core->wifi.readWUsCompare(1)) // W_US_COMPARE1
1150+
DEF_IO16(0x48000F4, data = core->wifi.readWUsCompare(2)) // W_US_COMPARE2
1151+
DEF_IO16(0x48000F6, data = core->wifi.readWUsCompare(3)) // W_US_COMPARE3
1152+
DEF_IO16(0x48000F8, data = core->wifi.readWUsCount(0)) // W_US_COUNT0
1153+
DEF_IO16(0x48000FA, data = core->wifi.readWUsCount(1)) // W_US_COUNT1
1154+
DEF_IO16(0x48000FC, data = core->wifi.readWUsCount(2)) // W_US_COUNT2
1155+
DEF_IO16(0x48000FE, data = core->wifi.readWUsCount(3)) // W_US_COUNT3
11461156
DEF_IO16(0x4800110, data = core->wifi.readWPreBeacon()) // W_PRE_BEACON
11471157
DEF_IO16(0x480011C, data = core->wifi.readWBeaconCount()) // W_BEACON_COUNT
11481158
DEF_IO16(0x4800120, data = core->wifi.readWConfig(0)) // W_CONFIG_120
@@ -1162,6 +1172,7 @@ template <typename T> T Memory::ioRead7(uint32_t address)
11621172
DEF_IO16(0x4800150, data = core->wifi.readWConfig(13)) // W_CONFIG_150
11631173
DEF_IO16(0x4800154, data = core->wifi.readWConfig(14)) // W_CONFIG_154
11641174
DEF_IO16(0x480015C, data = core->wifi.readWBbRead()) // W_BB_READ
1175+
DEF_IO16(0x4800210, data = core->wifi.readWTxSeqno()) // W_TX_SEQNO
11651176

11661177
default:
11671178
// Handle unknown reads by returning nothing
@@ -1704,6 +1715,7 @@ template <typename T> void Memory::ioWrite7(uint32_t address, T value)
17041715
DEF_IO32(0x4000518, core->spu.writeSndCapDad(1, IOWR_PARAMS)) // SNDCAP1DAD
17051716
DEF_IO16(0x400051C, core->spu.writeSndCapLen(1, IOWR_PARAMS)) // SNDCAP1LEN
17061717
DEF_IO16(0x4800006, core->wifi.writeWModeWep(IOWR_PARAMS)) // W_MODE_WEP
1718+
DEF_IO16(0x4800008, core->wifi.writeWTxstatCnt(IOWR_PARAMS)) // W_TXSTAT_CNT
17071719
DEF_IO16(0x4800010, core->wifi.writeWIrf(IOWR_PARAMS)) // W_IF
17081720
DEF_IO16(0x4800012, core->wifi.writeWIe(IOWR_PARAMS)) // W_IE
17091721
DEF_IO16(0x4800018, core->wifi.writeWMacaddr(0, IOWR_PARAMS)) // W_MACADDR_0
@@ -1739,6 +1751,14 @@ template <typename T> void Memory::ioWrite7(uint32_t address, T value)
17391751
DEF_IO16(0x48000AE, core->wifi.writeWTxreqSet(IOWR_PARAMS)) // W_TXREQ_SET
17401752
DEF_IO16(0x48000E8, core->wifi.writeWUsCountcnt(IOWR_PARAMS)) // W_US_COUNTCNT
17411753
DEF_IO16(0x48000EA, core->wifi.writeWUsComparecnt(IOWR_PARAMS)) // W_US_COMPARECNT
1754+
DEF_IO16(0x48000F0, core->wifi.writeWUsCompare(0, IOWR_PARAMS)) // W_US_COMPARE0
1755+
DEF_IO16(0x48000F2, core->wifi.writeWUsCompare(1, IOWR_PARAMS)) // W_US_COMPARE1
1756+
DEF_IO16(0x48000F4, core->wifi.writeWUsCompare(2, IOWR_PARAMS)) // W_US_COMPARE2
1757+
DEF_IO16(0x48000F6, core->wifi.writeWUsCompare(3, IOWR_PARAMS)) // W_US_COMPARE3
1758+
DEF_IO16(0x48000F8, core->wifi.writeWUsCount(0, IOWR_PARAMS)) // W_US_COUNT0
1759+
DEF_IO16(0x48000FA, core->wifi.writeWUsCount(1, IOWR_PARAMS)) // W_US_COUNT1
1760+
DEF_IO16(0x48000FC, core->wifi.writeWUsCount(2, IOWR_PARAMS)) // W_US_COUNT2
1761+
DEF_IO16(0x48000FE, core->wifi.writeWUsCount(3, IOWR_PARAMS)) // W_US_COUNT3
17421762
DEF_IO16(0x4800110, core->wifi.writeWPreBeacon(IOWR_PARAMS)) // W_PRE_BEACON
17431763
DEF_IO16(0x480011C, core->wifi.writeWBeaconCount(IOWR_PARAMS)) // W_BEACON_COUNT
17441764
DEF_IO16(0x4800120, core->wifi.writeWConfig(0, IOWR_PARAMS)) // W_CONFIG_120

src/spi.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ bool Spi::loadFirmware()
8787
{
8888
// Increment the MAC address based on the instance ID
8989
// This allows instances to be detected as separate systems
90-
firmware[0x36] += core->id;
90+
firmware[0x3B] += core->id;
9191

9292
// Recalculate the WiFi config CRC
9393
uint16_t crc = crc16(0, &firmware[0x2C], 0x138);
@@ -110,12 +110,12 @@ bool Spi::loadFirmware()
110110
// Set some WiFi config data
111111
firmware[0x2C] = 0x38; // Config length, byte 1
112112
firmware[0x2D] = 0x01; // Config length, byte 2
113-
firmware[0x36] = core->id; // MAC address, byte 1
113+
firmware[0x36] = 0x00; // MAC address, byte 1
114114
firmware[0x37] = 0x09; // MAC address, byte 2
115115
firmware[0x38] = 0xBF; // MAC address, byte 3
116116
firmware[0x39] = 0x12; // MAC address, byte 4
117117
firmware[0x3A] = 0x34; // MAC address, byte 5
118-
firmware[0x3B] = 0x56; // MAC address, byte 6
118+
firmware[0x3B] = core->id; // MAC address, byte 6
119119
firmware[0x3C] = 0xFE; // Enabled channels, byte 1
120120
firmware[0x3D] = 0x3F; // Enabled channels, byte 2
121121

src/wifi.cpp

+73-37
Original file line numberDiff line numberDiff line change
@@ -151,28 +151,28 @@ void Wifi::countMs()
151151
{
152152
// Process any queued packets
153153
if (!packets.empty())
154-
processPackets();
154+
receivePackets();
155155

156156
if (wUsCountcnt) // Counter enable
157157
{
158-
// Trigger a pre-beacon interrupt at the pre-beacon timestamp
159-
if (wBeaconCount == wPreBeacon)
158+
// Decrement the beacon counter and trigger an interrupt if the pre-beacon value matches
159+
if (--wBeaconCount == wPreBeacon && wUsComparecnt)
160160
sendInterrupt(15);
161161

162-
// Decrement the beacon millisecond counter and handle underflows
163-
if (--wBeaconCount == 0)
162+
// Increment the main counter by a millisecond and handle compare events
163+
if ((wUsCount += 0x400) == wUsCompare || wBeaconCount == 0)
164164
{
165-
// Trigger a beacon transfer and reload the millisecond counter
166-
if ((wTxbufLoc[4] & BIT(15)) && (wTxreqRead & BIT(4)))
167-
transfer(4);
165+
// Reload the beacon counter and trigger an interrupt with transmission if enabled
168166
wBeaconCount = wBeaconInt;
169-
170-
// Trigger an immediate beacon interrupt if enabled
171167
if (wUsComparecnt)
168+
{
172169
sendInterrupt(14);
170+
if ((wTxbufLoc[4] & BIT(15)) && (wTxreqRead & BIT(4)))
171+
transmitPacket(4);
172+
}
173173
}
174174

175-
// Trigger a post-beacon interrupt when the counter reaches zero
175+
// Decrement the post-beacon counter until it reaches zero; then trigger an interrupt
176176
if (wPostBeacon && --wPostBeacon == 0)
177177
sendInterrupt(13);
178178
}
@@ -201,69 +201,87 @@ void Wifi::sendInterrupt(int bit)
201201
}
202202
}
203203

204-
void Wifi::processPackets()
204+
void Wifi::receivePackets()
205205
{
206+
// Start receiving packets
207+
sendInterrupt(6);
206208
mutex.lock();
207209

208210
// Write all queued packets to the circular buffer
209-
for (size_t i = 0; i < packets.size(); i++)
211+
for (uint32_t i = 0; i < packets.size(); i++)
210212
{
211213
uint16_t size = (packets[i][4] + 12) / 2;
212-
213-
for (size_t j = 0; j < size; j++)
214+
for (uint32_t j = 0; j < size; j++)
214215
{
215216
// Write a half-word of the packet to memory
216217
core->memory.write<uint16_t>(1, 0x4804000 + wRxbufWrcsr, packets[i][j]);
217218

218219
// Increment the circular buffer address
219220
wRxbufWrcsr += 2;
220-
if ((wRxbufBegin & 0x1FFE) != (wRxbufEnd & 0x1FFE))
221-
wRxbufWrcsr = (wRxbufBegin & 0x1FFE) + (wRxbufWrcsr - (wRxbufBegin & 0x1FFE)) % ((wRxbufEnd & 0x1FFE) - (wRxbufBegin & 0x1FFE));
222-
wRxbufWrcsr &= 0x1FFE;
221+
if (int bufSize = (wRxbufEnd & 0x1FFE) - (wRxbufBegin & 0x1FFE))
222+
wRxbufWrcsr = ((wRxbufBegin & 0x1FFE) + (wRxbufWrcsr - (wRxbufBegin & 0x1FFE)) % bufSize) & 0x1FFE;
223223
}
224224

225225
delete[] packets[i];
226-
227-
// Trigger a receive complete interrupt
228-
sendInterrupt(0);
229226
}
230227

228+
// Finish receiving packets
231229
packets.clear();
232230
mutex.unlock();
231+
sendInterrupt(0);
233232
}
234233

235-
void Wifi::transfer(int index)
234+
void Wifi::transmitPacket(int index)
236235
{
237236
uint16_t address = (wTxbufLoc[index] & 0xFFF) << 1;
238237
uint16_t size = core->memory.read<uint16_t>(1, 0x4804000 + address + 0x0A) + 8;
239-
LOG("Sending packet on channel %d with size 0x%X\n", index, size);
238+
printf("Instance %d sending packet on channel %d with size 0x%X\n", core->id, index, size);
240239

240+
// Start transmitting a packet
241+
sendInterrupt(7);
241242
mutex.lock();
242243

243-
for (size_t i = 0; i < connections.size(); i++)
244+
for (uint32_t i = 0; i < connections.size(); i++)
244245
{
245246
// Read the packet from memory
246247
uint16_t *data = new uint16_t[size / 2];
247-
for (size_t j = 0; j < size; j += 2)
248+
for (uint32_t j = 0; j < size; j += 2)
248249
data[j / 2] = core->memory.read<uint16_t>(1, 0x4804000 + address + j);
249250

250-
// Set the packet size in the outgoing header
251-
data[4] = size - 12;
251+
// Fill out the hardware RX header
252+
data[0] = 0x8010 | (index == 4); // Frame type
253+
data[1] = 0x0040; // Something?
254+
data[3] = 0x0010; // Transfer rate
255+
data[4] = size - 12; // Data length
256+
data[5] = 0x00FF; // Signal strength
257+
258+
// Set and update the IEEE sequence number if enabled
259+
if (index == 4 || !(wTxbufLoc[index] & BIT(13)))
260+
data[17] = (wTxSeqno++) << 4;
252261

253262
// Add the packet to the queue
254263
connections[i]->mutex.lock();
255264
connections[i]->packets.push_back(data);
256265
connections[i]->mutex.unlock();
257266
}
258267

268+
// Finish transmitting a packet
259269
mutex.unlock();
270+
sendInterrupt(1);
260271

261272
// Clear the enable flag for non-beacons
262273
if (index != 4)
263274
wTxbufLoc[index] &= ~BIT(15);
264275

265-
// Trigger a transmit complete interrupt
266-
sendInterrupt(1);
276+
// Update transmission status based on type and certain bits
277+
switch (index)
278+
{
279+
case 0: wTxstat = (wTxstatCnt & BIT(14)) ? 0x0801 : 0x0001; break; // CMD
280+
case 1: wTxstat = (wTxbufLoc[1] & BIT(12)) ? 0x0701 : 0x0001; break; // LOC1
281+
case 2: wTxstat = (wTxbufLoc[2] & BIT(12)) ? 0x1701 : 0x1001; break; // LOC2
282+
case 3: wTxstat = (wTxbufLoc[3] & BIT(12)) ? 0x2701 : 0x2001; break; // LOC3
283+
case 4: wTxstat = (wTxstatCnt & BIT(15)) ? 0x0301 : 0x0001; break; // BEACON
284+
}
267285
}
268286

269287
void Wifi::writeWModeWep(uint16_t mask, uint16_t value)
@@ -272,6 +290,13 @@ void Wifi::writeWModeWep(uint16_t mask, uint16_t value)
272290
wModeWep = (wModeWep & ~mask) | (value & mask);
273291
}
274292

293+
void Wifi::writeWTxstatCnt(uint16_t mask, uint16_t value)
294+
{
295+
// Write to the W_TXSTAT_CNT register
296+
mask &= 0xF000;
297+
wTxstatCnt = (wTxstatCnt & ~mask) | (value & mask);
298+
}
299+
275300
void Wifi::writeWIrf(uint16_t mask, uint16_t value)
276301
{
277302
// Write to the W_IF register
@@ -447,7 +472,7 @@ void Wifi::writeWTxbufLoc(int index, uint16_t mask, uint16_t value)
447472

448473
// Send a packet to connected cores if triggered for non-beacons
449474
if (index != 4 && (wTxbufLoc[index] & BIT(15)) && (wTxreqRead & BIT(index)))
450-
transfer(index);
475+
transmitPacket(index);
451476
}
452477

453478
void Wifi::writeWBeaconInt(uint16_t mask, uint16_t value)
@@ -475,10 +500,8 @@ void Wifi::writeWTxreqSet(uint16_t mask, uint16_t value)
475500

476501
// Send a packet to connected cores if triggered for non-beacons
477502
for (int i = 0; i < 4; i++)
478-
{
479503
if ((wTxbufLoc[i] & BIT(15)) && (wTxreqRead & BIT(i)))
480-
transfer(i);
481-
}
504+
transmitPacket(i);
482505
}
483506

484507
void Wifi::writeWUsCountcnt(uint16_t mask, uint16_t value)
@@ -499,6 +522,21 @@ void Wifi::writeWUsComparecnt(uint16_t mask, uint16_t value)
499522
sendInterrupt(14);
500523
}
501524

525+
void Wifi::writeWUsCompare(int index, uint16_t mask, uint16_t value)
526+
{
527+
// Write to part of the W_US_COMPARE register
528+
int shift = index * 16;
529+
mask &= (index ? 0xFFFF : 0xFC00);
530+
wUsCompare = (wUsCompare & ~(uint64_t(mask) << shift)) | (uint64_t(value & mask) << shift);
531+
}
532+
533+
void Wifi::writeWUsCount(int index, uint16_t mask, uint16_t value)
534+
{
535+
// Write to part of the W_US_COUNT register
536+
int shift = index * 16;
537+
wUsCount = (wUsCount & ~(uint64_t(mask) << shift)) | (uint64_t(value & mask) << shift);
538+
}
539+
502540
void Wifi::writeWPreBeacon(uint16_t mask, uint16_t value)
503541
{
504542
// Write to the W_PRE_BEACON register
@@ -580,13 +618,11 @@ uint16_t Wifi::readWRxbufRdData()
580618
// Increment the read address
581619
if ((wRxbufRdAddr += 2) == wRxbufGap)
582620
wRxbufRdAddr += wRxbufGapdisp << 1;
583-
if ((wRxbufBegin & 0x1FFE) != (wRxbufEnd & 0x1FFE))
584-
wRxbufRdAddr = (wRxbufBegin & 0x1FFE) + (wRxbufRdAddr - (wRxbufBegin & 0x1FFE)) % ((wRxbufEnd & 0x1FFE) - (wRxbufBegin & 0x1FFE));
585-
wRxbufRdAddr &= 0x1FFF;
621+
if (int bufSize = (wRxbufEnd & 0x1FFE) - (wRxbufBegin & 0x1FFE))
622+
wRxbufRdAddr = ((wRxbufBegin & 0x1FFE) + (wRxbufRdAddr - (wRxbufBegin & 0x1FFE)) % bufSize) & 0x1FFE;
586623

587624
// Decrement the read counter and trigger an interrupt at the end
588625
if (wRxbufCount > 0 && --wRxbufCount == 0)
589626
sendInterrupt(9);
590-
591627
return value;
592628
}

0 commit comments

Comments
 (0)