aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/DSi_NWifi.cpp293
-rw-r--r--src/DSi_NWifi.h16
2 files changed, 306 insertions, 3 deletions
diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp
index 4e5d26d..5236551 100644
--- a/src/DSi_NWifi.cpp
+++ b/src/DSi_NWifi.cpp
@@ -22,9 +22,98 @@
#include "DSi_NWifi.h"
+const u8 CIS0[256] =
+{
+ 0x01, 0x03, 0xD9, 0x01, 0xFF,
+ 0x20, 0x04, 0x71, 0x02, 0x00, 0x02,
+ 0x21, 0x02, 0x0C, 0x00,
+ 0x22, 0x04, 0x00, 0x00, 0x08, 0x32,
+ 0x1A, 0x05, 0x01, 0x01, 0x00, 0x02, 0x07,
+ 0x1B, 0x08, 0xC1, 0x41, 0x30, 0x30, 0xFF, 0xFF, 0x32, 0x00,
+ 0x14, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+};
+
+const u8 CIS1[256] =
+{
+ 0x20, 0x04, 0x71, 0x02, 0x00, 0x02,
+ 0x21, 0x02, 0x0C, 0x00,
+ 0x22, 0x2A, 0x01,
+ 0x01, 0x11,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08,
+ 0x00, 0x00, 0xFF, 0x80,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x0A,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x80, 0x01, 0x06,
+ 0x81, 0x01, 0x07,
+ 0x82, 0x01, 0xDF,
+ 0xFF,
+ 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+
DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
{
- //
+ TransferCmd = 0xFFFFFFFF;
+ RemSize = 0;
}
DSi_NWifi::~DSi_NWifi()
@@ -33,8 +122,149 @@ DSi_NWifi::~DSi_NWifi()
}
+u8 DSi_NWifi::F0_Read(u32 addr)
+{
+ switch (addr)
+ {
+ case 0x00000: return 0x11;
+ case 0x00001: return 0x00;
+
+ case 0x00002: return 0x02; // writable??
+ case 0x00003: return 0x02;
+
+ case 0x00008: return 0x17;
+
+ case 0x00009: return 0x00;
+ case 0x0000A: return 0x10;
+ case 0x0000B: return 0x00;
+
+ case 0x00012: return 0x03;
+
+ case 0x00109: return 0x00;
+ case 0x0010A: return 0x11;
+ case 0x0010B: return 0x00;
+ }
+
+ if (addr >= 0x01000 && addr < 0x01100)
+ {
+ return CIS0[addr & 0xFF];
+ }
+ if (addr >= 0x01100 && addr < 0x01200)
+ {
+ return CIS1[addr & 0xFF];
+ }
+
+ printf("NWIFI: unknown func0 read %05X\n", addr);
+ return 0;
+}
+
+void DSi_NWifi::F0_Write(u32 addr, u8 val)
+{
+ printf("NWIFI: unknown func0 write %05X %02X\n", addr, val);
+}
+
+
+u8 DSi_NWifi::F1_Read(u32 addr)
+{
+ switch (addr)
+ {
+ }
+
+ printf("NWIFI: unknown func1 read %05X\n", addr);
+ return 0;
+}
+
+void DSi_NWifi::F1_Write(u32 addr, u8 val)
+{
+ printf("NWIFI: unknown func1 write %05X %02X\n", addr, val);
+}
+
+
+u8 DSi_NWifi::SDIO_Read(u32 func, u32 addr)
+{
+ switch (func)
+ {
+ case 0: return F0_Read(addr);
+ }
+
+ printf("NWIFI: unknown SDIO read %d %05X\n", func, addr);
+ return 0;
+}
+
+void DSi_NWifi::SDIO_Write(u32 func, u32 addr, u8 val)
+{
+ switch (func)
+ {
+ case 0: return F0_Write(addr, val);
+ }
+
+ printf("NWIFI: unknown SDIO write %d %05X %02X\n", func, addr, val);
+}
+
+
void DSi_NWifi::SendCMD(u8 cmd, u32 param)
{
+ switch (cmd)
+ {
+ case 52: // IO_RW_DIRECT
+ {
+ u32 func = (param >> 28) & 0x7;
+ u32 addr = (param >> 9) & 0x1FFFF;
+
+ if (param & (1<<31))
+ {
+ // write
+
+ u8 val = param & 0xFF;
+ SDIO_Write(func, addr, val);
+ if (param & (1<<27))
+ val = SDIO_Read(func, addr); // checkme
+ Host->SendResponse(val | 0x1000, true);
+ }
+ else
+ {
+ // read
+
+ u8 val = SDIO_Read(func, addr);
+ Host->SendResponse(val | 0x1000, true);
+ }
+ }
+ return;
+
+ case 53: // IO_RW_EXTENDED
+ {
+ u32 addr = (param >> 9) & 0x1FFFF;
+
+ TransferCmd = param;
+ TransferAddr = addr;
+ if (param & (1<<27))
+ {
+ RemSize = (param & 0x1FF) << 9; // checkme
+ }
+ else
+ {
+ RemSize = (param & 0x1FF);
+ if (!RemSize) RemSize = 0x200;
+ }
+
+ if (param & (1<<31))
+ {
+ // write
+
+ WriteBlock();
+ Host->SendResponse(0x1000, true);
+ }
+ else
+ {
+ // read
+
+ ReadBlock();
+ Host->SendResponse(0x1000, true);
+ }
+ }
+ return;
+ }
+
printf("NWIFI: unknown CMD %d %08X\n", cmd, param);
}
@@ -45,5 +275,64 @@ void DSi_NWifi::SendACMD(u8 cmd, u32 param)
void DSi_NWifi::ContinueTransfer()
{
- //
+ if (TransferCmd & (1<<31))
+ WriteBlock();
+ else
+ ReadBlock();
+}
+
+void DSi_NWifi::ReadBlock()
+{
+ u32 func = (TransferCmd >> 28) & 0x7;
+ u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize;
+
+ u8 data[0x200];
+
+ for (u32 i = 0; i < len; i++)
+ {
+ data[i] = SDIO_Read(func, TransferAddr);
+ if (TransferCmd & (1<<26))
+ {
+ TransferAddr++;
+ TransferAddr &= 0x1FFFF; // checkme
+ }
+ }
+ Host->SendData(data, len);
+
+ if (RemSize > 0)
+ {
+ RemSize -= len;
+ if (RemSize == 0)
+ {
+ // TODO?
+ }
+ }
+}
+
+void DSi_NWifi::WriteBlock()
+{
+ u32 func = (TransferCmd >> 28) & 0x7;
+ u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize;
+
+ u8 data[0x200];
+ Host->ReceiveData(data, len);
+
+ for (u32 i = 0; i < len; i++)
+ {
+ SDIO_Write(func, TransferAddr, data[i]);
+ if (TransferCmd & (1<<26))
+ {
+ TransferAddr++;
+ TransferAddr &= 0x1FFFF; // checkme
+ }
+ }
+
+ if (RemSize > 0)
+ {
+ RemSize -= len;
+ if (RemSize == 0)
+ {
+ // TODO?
+ }
+ }
}
diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h
index 34c3dd4..5d61951 100644
--- a/src/DSi_NWifi.h
+++ b/src/DSi_NWifi.h
@@ -33,7 +33,21 @@ public:
void ContinueTransfer();
private:
- //
+ u32 TransferCmd;
+ u32 TransferAddr;
+ u32 RemSize;
+
+ u8 F0_Read(u32 addr);
+ void F0_Write(u32 addr, u8 val);
+
+ u8 F1_Read(u32 addr);
+ void F1_Write(u32 addr, u8 val);
+
+ u8 SDIO_Read(u32 func, u32 addr);
+ void SDIO_Write(u32 func, u32 addr, u8 val);
+
+ void ReadBlock();
+ void WriteBlock();
};
#endif // DSI_NWIFI_H