Merge pull request #682 from nadiaholmquist/slirp-merge
Merge slirp branch into master
This commit is contained in:
commit
dff14ca80a
|
@ -26,7 +26,7 @@ jobs:
|
|||
&& sudo rm /etc/apt/sources.list \
|
||||
&& sudo mv /etc/apt/sources.list{.new,} \
|
||||
&& sudo apt-get update \
|
||||
&& sudo apt-get install {gcc-10,g++-10,pkg-config}-aarch64-linux-gnu libsdl2-dev:arm64 qtbase5-dev:arm64
|
||||
&& sudo apt-get install {gcc-10,g++-10,pkg-config}-aarch64-linux-gnu libsdl2-dev:arm64 qtbase5-dev:arm64 libslirp-dev:arm64
|
||||
- name: Create build environment
|
||||
run: mkdir ${{runner.workspace}}/build
|
||||
- name: Configure
|
||||
|
|
|
@ -23,17 +23,15 @@ jobs:
|
|||
shell: bash
|
||||
working-directory: ${{runner.workspace}}
|
||||
run: | # Fetch a new version of CMake, because the default is too old.
|
||||
wget -nv https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz \
|
||||
&& tar -zxf cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz \
|
||||
&& sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list \
|
||||
sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list \
|
||||
&& sudo apt-get update \
|
||||
&& sudo apt-get install gtk+-3.0 libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qt5-default
|
||||
&& sudo apt-get install cmake libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qt5-default libslirp-dev
|
||||
- name: Create build environment
|
||||
run: mkdir ${{runner.workspace}}/build
|
||||
- name: Configure
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: ${{runner.workspace}}/cmake-$CMAKE_VERSION-Linux-x86_64/bin/cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
- name: Make
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
|
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
choco install msys2
|
||||
C:\tools\msys64\usr\bin\bash.exe -lc "pacman -Syuq --noconfirm"
|
||||
- name: Install dependencies
|
||||
run: C:\tools\msys64\usr\bin\bash.exe -lc "pacman -Sq --noconfirm git make mingw-w64-x86_64-{cmake,mesa,SDL2,qt5-static,toolchain}"
|
||||
run: C:\tools\msys64\usr\bin\bash.exe -lc "pacman -Sq --noconfirm git make mingw-w64-x86_64-{cmake,mesa,SDL2,qt5-static,libslirp,toolchain}"
|
||||
- name: Create build environment
|
||||
run: |
|
||||
New-Item -ItemType directory -Path ${{runner.workspace}}\melonDS\build
|
||||
|
|
|
@ -635,7 +635,10 @@ void ARMv5::CP15Write(u32 id, u32 val)
|
|||
|
||||
}
|
||||
|
||||
if ((id&0xF00)!=0x700)
|
||||
if ((id & 0xF00) == 0xF00) // test/debug shit?
|
||||
return;
|
||||
|
||||
if ((id & 0xF00) != 0x700)
|
||||
printf("unknown CP15 write op %03X %08X\n", id, val);
|
||||
}
|
||||
|
||||
|
@ -729,6 +732,9 @@ u32 ARMv5::CP15Read(u32 id)
|
|||
return ITCMSetting;
|
||||
}
|
||||
|
||||
if ((id & 0xF00) == 0xF00) // test/debug shit?
|
||||
return 0;
|
||||
|
||||
printf("unknown CP15 read op %03X\n", id);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -165,9 +165,37 @@ void ProcessBlock_CCM_Decrypt()
|
|||
//printf("AES-CCM: "); _printhex2(data, 16);
|
||||
|
||||
Swap16(data_rev, data);
|
||||
|
||||
AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16);
|
||||
for (int i = 0; i < 16; i++) CurMAC[i] ^= data_rev[i];
|
||||
AES_ECB_encrypt(&Ctx, CurMAC);
|
||||
|
||||
Swap16(data, data_rev);
|
||||
|
||||
//printf(" -> "); _printhex2(data, 16);
|
||||
|
||||
OutputFIFO->Write(*(u32*)&data[0]);
|
||||
OutputFIFO->Write(*(u32*)&data[4]);
|
||||
OutputFIFO->Write(*(u32*)&data[8]);
|
||||
OutputFIFO->Write(*(u32*)&data[12]);
|
||||
}
|
||||
|
||||
void ProcessBlock_CCM_Encrypt()
|
||||
{
|
||||
u8 data[16];
|
||||
u8 data_rev[16];
|
||||
|
||||
*(u32*)&data[0] = InputFIFO->Read();
|
||||
*(u32*)&data[4] = InputFIFO->Read();
|
||||
*(u32*)&data[8] = InputFIFO->Read();
|
||||
*(u32*)&data[12] = InputFIFO->Read();
|
||||
|
||||
//printf("AES-CCM: "); _printhex2(data, 16);
|
||||
|
||||
Swap16(data_rev, data);
|
||||
|
||||
for (int i = 0; i < 16; i++) CurMAC[i] ^= data_rev[i];
|
||||
AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16);
|
||||
AES_ECB_encrypt(&Ctx, CurMAC);
|
||||
|
||||
Swap16(data, data_rev);
|
||||
|
@ -232,7 +260,6 @@ void WriteCnt(u32 val)
|
|||
OutputDMASize = dmasize_out[(val >> 14) & 0x3];
|
||||
|
||||
AESMode = (val >> 28) & 0x3;
|
||||
if (AESMode == 1) printf("AES-CCM TODO\n");
|
||||
|
||||
if (val & (1<<24))
|
||||
{
|
||||
|
@ -245,6 +272,8 @@ void WriteCnt(u32 val)
|
|||
// transfer start (checkme)
|
||||
RemBlocks = BlkCnt >> 16;
|
||||
|
||||
if (AESMode == 0 && (!(val & (1<<20)))) printf("AES: CCM-DECRYPT MAC FROM WRFIFO, TODO\n");
|
||||
|
||||
if (RemBlocks > 0)
|
||||
{
|
||||
u8 key[16];
|
||||
|
@ -365,14 +394,9 @@ void Update()
|
|||
switch (AESMode)
|
||||
{
|
||||
case 0: ProcessBlock_CCM_Decrypt(); break;
|
||||
case 1: ProcessBlock_CCM_Encrypt(); break;
|
||||
case 2:
|
||||
case 3: ProcessBlock_CTR(); break;
|
||||
default:
|
||||
// dorp
|
||||
OutputFIFO->Write(InputFIFO->Read());
|
||||
OutputFIFO->Write(InputFIFO->Read());
|
||||
OutputFIFO->Write(InputFIFO->Read());
|
||||
OutputFIFO->Write(InputFIFO->Read());
|
||||
}
|
||||
|
||||
RemBlocks--;
|
||||
|
@ -398,6 +422,24 @@ void Update()
|
|||
if (CurMAC[15-i] != MAC[i]) Cnt &= ~(1<<21);
|
||||
}
|
||||
}
|
||||
else if (AESMode == 1)
|
||||
{
|
||||
Ctx.Iv[13] = 0x00;
|
||||
Ctx.Iv[14] = 0x00;
|
||||
Ctx.Iv[15] = 0x00;
|
||||
AES_CTR_xcrypt_buffer(&Ctx, CurMAC, 16);
|
||||
|
||||
u8 finalmac[16];
|
||||
Swap16(finalmac, CurMAC);
|
||||
|
||||
OutputFIFO->Write(*(u32*)&finalmac[0]);
|
||||
OutputFIFO->Write(*(u32*)&finalmac[4]);
|
||||
OutputFIFO->Write(*(u32*)&finalmac[8]);
|
||||
OutputFIFO->Write(*(u32*)&finalmac[12]);
|
||||
|
||||
// CHECKME
|
||||
Cnt &= ~(1<<21);
|
||||
}
|
||||
else
|
||||
{
|
||||
// CHECKME
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
|||
#include "DSi.h"
|
||||
#include "DSi_NWifi.h"
|
||||
#include "SPI.h"
|
||||
#include "WifiAP.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
const u8 CIS0[256] =
|
||||
|
@ -111,15 +113,37 @@ const u8 CIS1[256] =
|
|||
};
|
||||
|
||||
|
||||
// hax
|
||||
DSi_NWifi* hax_wifi;
|
||||
void triggerirq(u32 param)
|
||||
{
|
||||
hax_wifi->SetIRQ_F1_Counter(0);
|
||||
}
|
||||
DSi_NWifi* Ctx = nullptr;
|
||||
|
||||
|
||||
DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
|
||||
{
|
||||
// HACK
|
||||
// the mailboxes are supposed to be 0x80 bytes
|
||||
// however, as we do things instantly, emulating this is meaningless
|
||||
// and only adds complication
|
||||
for (int i = 0; i < 8; i++)
|
||||
Mailbox[i] = new FIFO<u8>(0x600);//0x80);
|
||||
|
||||
// extra mailbox acting as a bigger RX buffer
|
||||
Mailbox[8] = new FIFO<u8>(0x8000);
|
||||
|
||||
// this seems to control whether the firmware upload is done
|
||||
EEPROMReady = 0;
|
||||
|
||||
Ctx = this;
|
||||
}
|
||||
|
||||
DSi_NWifi::~DSi_NWifi()
|
||||
{
|
||||
for (int i = 0; i < 9; i++)
|
||||
delete Mailbox[i];
|
||||
|
||||
NDS::CancelEvent(NDS::Event_DSi_NWifi);
|
||||
Ctx = nullptr;
|
||||
}
|
||||
|
||||
void DSi_NWifi::Reset()
|
||||
{
|
||||
TransferCmd = 0xFFFFFFFF;
|
||||
RemSize = 0;
|
||||
|
@ -134,9 +158,8 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
|
|||
WindowReadAddr = 0;
|
||||
WindowWriteAddr = 0;
|
||||
|
||||
// TODO: check the actual mailbox size (presumably 0x200)
|
||||
for (int i = 0; i < 8; i++)
|
||||
Mailbox[i] = new FIFO<u8>(0x200);
|
||||
for (int i = 0; i < 9; i++)
|
||||
Mailbox[i]->Clear();
|
||||
|
||||
u8* mac = SPI_Firmware::GetWifiMAC();
|
||||
printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
|
@ -158,15 +181,17 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
|
|||
|
||||
*(u16*)&EEPROM[0x004] = chk;
|
||||
|
||||
EEPROMReady = 0;
|
||||
|
||||
// TODO: SDIO reset shouldn't reset this
|
||||
// this is reset by the internal reset register, and that also resets EEPROM init
|
||||
BootPhase = 0;
|
||||
}
|
||||
|
||||
DSi_NWifi::~DSi_NWifi()
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
delete Mailbox[i];
|
||||
ErrorMask = 0;
|
||||
ScanTimer = 0;
|
||||
|
||||
BeaconTimer = 0x10A2220ULL;
|
||||
ConnectionStatus = 0;
|
||||
|
||||
NDS::CancelEvent(NDS::Event_DSi_NWifi);
|
||||
}
|
||||
|
||||
|
||||
|
@ -283,6 +308,7 @@ u8 DSi_NWifi::F1_Read(u32 addr)
|
|||
if (addr < 0x100)
|
||||
{
|
||||
u8 ret = Mailbox[4]->Read();
|
||||
if (addr == 0xFF) DrainRXBuffer();
|
||||
UpdateIRQ_F1();
|
||||
return ret;
|
||||
}
|
||||
|
@ -348,6 +374,7 @@ u8 DSi_NWifi::F1_Read(u32 addr)
|
|||
else if (addr < 0x1000)
|
||||
{
|
||||
u8 ret = Mailbox[4]->Read();
|
||||
if (addr == 0xFFF) DrainRXBuffer();
|
||||
UpdateIRQ_F1();
|
||||
return ret;
|
||||
}
|
||||
|
@ -372,11 +399,12 @@ u8 DSi_NWifi::F1_Read(u32 addr)
|
|||
else
|
||||
{
|
||||
u8 ret = Mailbox[4]->Read();
|
||||
if (addr == 0x3FFF) DrainRXBuffer();
|
||||
UpdateIRQ_F1();
|
||||
return ret;
|
||||
}
|
||||
|
||||
printf("NWIFI: unknown func1 read %05X\n", addr);
|
||||
//printf("NWIFI: unknown func1 read %05X\n", addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -663,13 +691,13 @@ void DSi_NWifi::HandleCommand()
|
|||
switch (BootPhase)
|
||||
{
|
||||
case 0: return BMI_Command();
|
||||
case 1: return WMI_Command();
|
||||
case 1: return HTC_Command();
|
||||
case 2: return WMI_Command();
|
||||
}
|
||||
}
|
||||
|
||||
void DSi_NWifi::BMI_Command()
|
||||
{
|
||||
// HLE command handling stub
|
||||
u32 cmd = MB_Read32(0);
|
||||
|
||||
switch (cmd)
|
||||
|
@ -678,8 +706,8 @@ void DSi_NWifi::BMI_Command()
|
|||
{
|
||||
printf("BMI_DONE\n");
|
||||
EEPROMReady = 1; // GROSS FUCKING HACK
|
||||
u8 ready_msg[8] = {0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00};
|
||||
SendWMIFrame(ready_msg, 8, 0, 0x00, 0x0000);
|
||||
u8 ready_msg[6] = {0x0A, 0x00, 0x08, 0x06, 0x16, 0x00};
|
||||
SendWMIEvent(0, 0x0001, ready_msg, 6);
|
||||
BootPhase = 1;
|
||||
}
|
||||
return;
|
||||
|
@ -743,7 +771,7 @@ void DSi_NWifi::BMI_Command()
|
|||
{
|
||||
u32 len = MB_Read32(0);
|
||||
printf("BMI LZ write %08X\n", len);
|
||||
//FILE* f = fopen("wififirm.bin", "ab");
|
||||
//FILE* f = fopen("debug/wififirm.bin", "ab");
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
|
@ -762,15 +790,13 @@ void DSi_NWifi::BMI_Command()
|
|||
}
|
||||
}
|
||||
|
||||
void DSi_NWifi::WMI_Command()
|
||||
void DSi_NWifi::HTC_Command()
|
||||
{
|
||||
// HLE command handling stub
|
||||
u16 h0 = MB_Read16(0);
|
||||
u16 len = MB_Read16(0);
|
||||
u16 h2 = MB_Read16(0);
|
||||
|
||||
u16 cmd = MB_Read16(0);
|
||||
printf("WMI: cmd %04X\n", cmd);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
|
@ -778,59 +804,631 @@ void DSi_NWifi::WMI_Command()
|
|||
{
|
||||
u16 svc_id = MB_Read16(0);
|
||||
u16 conn_flags = MB_Read16(0);
|
||||
printf("service connect %04X %04X %04X\n", svc_id, conn_flags, MB_Read16(0));
|
||||
|
||||
u8 svc_resp[10];
|
||||
*(u16*)&svc_resp[0] = 0x0003;
|
||||
*(u16*)&svc_resp[2] = svc_id;
|
||||
svc_resp[4] = 0;
|
||||
svc_resp[5] = (svc_id & 0xFF) + 1;
|
||||
*(u16*)&svc_resp[6] = 0x0001;
|
||||
*(u16*)&svc_resp[8] = 0x0001;
|
||||
SendWMIFrame(svc_resp, 10, 0, 0x00, 0x0000);
|
||||
u8 svc_resp[8];
|
||||
// responses from hardware:
|
||||
// 0003 0100 00 01 0602 00 00
|
||||
// 0003 0101 00 02 0600 00 00
|
||||
// 0003 0102 00 03 0600 00 00
|
||||
// 0003 0103 00 04 0600 00 00
|
||||
// 0003 0104 00 05 0600 00 00
|
||||
*(u16*)&svc_resp[0] = svc_id;
|
||||
svc_resp[2] = 0;
|
||||
svc_resp[3] = (svc_id & 0xFF) + 1;
|
||||
*(u16*)&svc_resp[4] = (svc_id==0x0100) ? 0x0602 : 0x0600; // max message size
|
||||
*(u16*)&svc_resp[6] = 0x0000;
|
||||
SendWMIEvent(0, 0x0003, svc_resp, 8);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0004: // setup complete
|
||||
{
|
||||
u8 ready_evt[14];
|
||||
memset(ready_evt, 0, 14);
|
||||
*(u16*)&ready_evt[0] = 0x1001;
|
||||
memcpy(&ready_evt[2], SPI_Firmware::GetWifiMAC(), 6);
|
||||
ready_evt[8] = 0x02;
|
||||
*(u32*)&ready_evt[10] = 0x23000024;
|
||||
// ctrl[0] = trailer size
|
||||
// trailer[1] = trailer extra size
|
||||
// trailer[0] = trailer type???
|
||||
SendWMIFrame(ready_evt, 14, 1, 0x00, 0x0000);
|
||||
u8 ready_evt[12];
|
||||
memcpy(&ready_evt[0], SPI_Firmware::GetWifiMAC(), 6);
|
||||
ready_evt[6] = 0x02;
|
||||
ready_evt[7] = 0;
|
||||
*(u32*)&ready_evt[8] = 0x2300006C;
|
||||
SendWMIEvent(1, 0x1001, ready_evt, 12);
|
||||
|
||||
u8 regdomain_evt[4];
|
||||
*(u32*)®domain_evt[0] = 0x80000000 | (*(u16*)&EEPROM[0x008] & 0x0FFF);
|
||||
SendWMIEvent(1, 0x1006, regdomain_evt, 4);
|
||||
|
||||
BootPhase = 2;
|
||||
NDS::ScheduleEvent(NDS::Event_DSi_NWifi, true, 33611, MSTimer, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown WMI command %04X\n", cmd);
|
||||
printf("unknown HTC command %04X\n", cmd);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
printf("%02X ", Mailbox[0]->Read());
|
||||
if ((i&0xF)==0xF) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
MB_Drain(0);
|
||||
}
|
||||
|
||||
void DSi_NWifi::SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl)
|
||||
void DSi_NWifi::WMI_Command()
|
||||
{
|
||||
u32 wlen = 0;
|
||||
u16 h0 = MB_Read16(0);
|
||||
u16 len = MB_Read16(0);
|
||||
u16 h2 = MB_Read16(0);
|
||||
|
||||
Mailbox[4]->Write(ep); // eid
|
||||
Mailbox[4]->Write(flags); // flags
|
||||
MB_Write16(4, len); // payload length
|
||||
MB_Write16(4, ctrl); // ctrl
|
||||
wlen += 6;
|
||||
u8 ep = h0 & 0xFF;
|
||||
if (ep > 0x01) // data endpoints
|
||||
{
|
||||
WMI_SendPacket(len);
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 cmd = MB_Read16(0);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case 0x0001: // connect to network
|
||||
{
|
||||
WMI_ConnectToNetwork();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0003: // disconnect
|
||||
{
|
||||
if (ConnectionStatus != 1)
|
||||
printf("WMI: ?? trying to disconnect while not connected\n");
|
||||
|
||||
printf("WMI: disconnect\n");
|
||||
ConnectionStatus = 0;
|
||||
|
||||
u8 reply[11];
|
||||
*(u16*)&reply[0] = 3; // checkme
|
||||
memcpy(&reply[2], WifiAP::APMac, 6);
|
||||
reply[8] = 3; // disconnect reason (via cmd)
|
||||
reply[9] = 0; // assoc-response length (none here)
|
||||
reply[10] = 0; // we need atleast one byte here, even if there is no assoc-response
|
||||
SendWMIEvent(1, 0x1003, reply, 11);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0004: // synchronize
|
||||
{
|
||||
Mailbox[0]->Read();
|
||||
// TODO??
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0005: // create priority stream
|
||||
{
|
||||
// TODO???
|
||||
// there's a lot of crap in there.
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0007: // start scan
|
||||
{
|
||||
u32 forcefg = MB_Read32(0);
|
||||
u32 legacy = MB_Read32(0);
|
||||
u32 scantime = MB_Read32(0);
|
||||
u32 forceinterval = MB_Read32(0);
|
||||
u8 scantype = Mailbox[0]->Read();
|
||||
u8 nchannels = Mailbox[0]->Read();
|
||||
|
||||
printf("WMI: start scan, forceFG=%d, legacy=%d, scanTime=%d, interval=%d, scanType=%d, chan=%d\n",
|
||||
forcefg, legacy, scantime, forceinterval, scantype, nchannels);
|
||||
|
||||
if (ScanTimer > 0)
|
||||
{
|
||||
printf("!! CHECKME: START SCAN BUT WAS ALREADY SCANNING (%d)\n", ScanTimer);
|
||||
}
|
||||
|
||||
// checkme
|
||||
ScanTimer = scantime*5;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0008: // set scan params
|
||||
{
|
||||
// TODO: do something with the params!!
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0009: // set BSS filter
|
||||
{
|
||||
// TODO: do something with the params!!
|
||||
u8 bssfilter = Mailbox[0]->Read();
|
||||
Mailbox[0]->Read();
|
||||
Mailbox[0]->Read();
|
||||
Mailbox[0]->Read();
|
||||
u32 iemask = MB_Read32(0);
|
||||
|
||||
printf("WMI: set BSS filter, filter=%02X, iemask=%08X\n", bssfilter, iemask);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x000A: // set probed BSSID
|
||||
{
|
||||
u8 id = Mailbox[0]->Read();
|
||||
u8 flags = Mailbox[0]->Read();
|
||||
u8 len = Mailbox[0]->Read();
|
||||
|
||||
char ssid[33] = {0};
|
||||
for (int i = 0; i < len && i < 32; i++)
|
||||
ssid[i] = Mailbox[0]->Read();
|
||||
|
||||
// TODO: store it somewhere
|
||||
printf("WMI: set probed SSID: id=%d, flags=%02X, len=%d, SSID=%s\n", id, flags, len, ssid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x000D: // set disconnect timeout
|
||||
{
|
||||
Mailbox[0]->Read();
|
||||
// TODO??
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x000E: // get channel list
|
||||
{
|
||||
int nchan = 11; // TODO: customize??
|
||||
u8 reply[2 + (nchan*2) + 2];
|
||||
|
||||
reply[0] = 0;
|
||||
reply[1] = nchan;
|
||||
for (int i = 0; i < nchan; i++)
|
||||
*(u16*)&reply[2 + (i*2)] = 2412 + (i*5);
|
||||
*(u16*)&reply[2 + (nchan*2)] = 0;
|
||||
|
||||
SendWMIEvent(1, 0x000E, reply, 4+(nchan*2));
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0011: // set channel params
|
||||
{
|
||||
Mailbox[0]->Read();
|
||||
u8 scan = Mailbox[0]->Read();
|
||||
u8 phymode = Mailbox[0]->Read();
|
||||
u8 len = Mailbox[0]->Read();
|
||||
|
||||
u16 channels[32];
|
||||
for (int i = 0; i < len && i < 32; i++)
|
||||
channels[i] = MB_Read16(0);
|
||||
|
||||
// TODO: store it somewhere
|
||||
printf("WMI: set channel params: scan=%d, phymode=%d, len=%d, channels=", scan, phymode, len);
|
||||
for (int i = 0; i < len && i < 32; i++)
|
||||
printf("%d,", channels[i]);
|
||||
printf("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0012: // set power mode
|
||||
{
|
||||
Mailbox[0]->Read();
|
||||
// TODO??
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0017: // dummy?
|
||||
Mailbox[0]->Read();
|
||||
break;
|
||||
|
||||
case 0x0022: // set error bitmask
|
||||
{
|
||||
ErrorMask = MB_Read32(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x002E: // extension shit
|
||||
{
|
||||
u32 extcmd = MB_Read32(0);
|
||||
switch (extcmd)
|
||||
{
|
||||
case 0x2008: // 'heartbeat'??
|
||||
{
|
||||
u32 cookie = MB_Read32(0);
|
||||
u32 source = MB_Read32(0);
|
||||
|
||||
u8 reply[12];
|
||||
*(u32*)&reply[0] = 0x3007;
|
||||
*(u32*)&reply[4] = cookie;
|
||||
*(u32*)&reply[8] = source;
|
||||
|
||||
SendWMIEvent(1, 0x1010, reply, 12);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("WMI: unknown ext cmd 002E:%04X\n", extcmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x003D: // set keepalive interval
|
||||
{
|
||||
Mailbox[0]->Read();
|
||||
// TODO??
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0041: // 'WMI_SET_WSC_STATUS_CMD'
|
||||
{
|
||||
Mailbox[0]->Read();
|
||||
// TODO??
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0047: // cmd47 -- timer shenanigans??
|
||||
{
|
||||
//
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0048: // not supported by DSi??
|
||||
{
|
||||
MB_Read32(0);
|
||||
MB_Read32(0);
|
||||
Mailbox[0]->Read();
|
||||
Mailbox[0]->Read();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0049: // 'host exit notify'
|
||||
{
|
||||
//
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xF000: // set bitrate
|
||||
{
|
||||
// TODO!
|
||||
Mailbox[0]->Read();
|
||||
Mailbox[0]->Read();
|
||||
Mailbox[0]->Read();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown WMI command %04X (header: %04X:%04X:%04X)\n", cmd, h0, len, h2);
|
||||
for (int i = 0; i < len-2; i++)
|
||||
{
|
||||
printf("%02X ", Mailbox[0]->Read());
|
||||
if ((i&0xF)==0xF) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (h0 & (1<<8))
|
||||
SendWMIAck(ep);
|
||||
|
||||
MB_Drain(0);
|
||||
}
|
||||
|
||||
void DSi_NWifi::WMI_ConnectToNetwork()
|
||||
{
|
||||
u8 type = Mailbox[0]->Read();
|
||||
u8 auth11 = Mailbox[0]->Read();
|
||||
u8 auth = Mailbox[0]->Read();
|
||||
u8 pCryptoType = Mailbox[0]->Read();
|
||||
u8 pCryptoLen = Mailbox[0]->Read();
|
||||
u8 gCryptoType = Mailbox[0]->Read();
|
||||
u8 gCryptoLen = Mailbox[0]->Read();
|
||||
u8 ssidLen = Mailbox[0]->Read();
|
||||
|
||||
char ssid[33] = {0};
|
||||
for (int i = 0; i < 32; i++)
|
||||
ssid[i] = Mailbox[0]->Read();
|
||||
if (ssidLen <= 32)
|
||||
ssid[ssidLen] = '\0';
|
||||
|
||||
u16 channel = MB_Read16(0);
|
||||
|
||||
u8 bssid[6];
|
||||
*(u32*)&bssid[0] = MB_Read32(0);
|
||||
*(u16*)&bssid[4] = MB_Read16(0);
|
||||
|
||||
u32 flags = MB_Read32(0);
|
||||
|
||||
if ((type != 0x01) ||
|
||||
(auth11 != 0x01) ||
|
||||
(auth != 0x01) ||
|
||||
(pCryptoType != 0x01) ||
|
||||
(gCryptoType != 0x01) ||
|
||||
(memcmp(bssid, WifiAP::APMac, 6)))
|
||||
{
|
||||
printf("WMI_Connect: bad parameters\n");
|
||||
// TODO: send disconnect??
|
||||
return;
|
||||
}
|
||||
|
||||
printf("WMI: connecting to network %s\n", ssid);
|
||||
|
||||
u8 reply[20];
|
||||
|
||||
// hope this is right!
|
||||
*(u16*)&reply[0] = 2437; // channel
|
||||
memcpy(&reply[2], WifiAP::APMac, 6); // BSSID
|
||||
*(u16*)&reply[8] = 128; // listen interval
|
||||
*(u16*)&reply[10] = 128; // beacon interval
|
||||
*(u32*)&reply[12] = 0x01; // network type
|
||||
|
||||
reply[16] = 0x16; // beaconIeLen ???
|
||||
reply[17] = 0x2F; // assocReqLen
|
||||
reply[18] = 0x16; // assocRespLen
|
||||
reply[19] = 0; // ?????
|
||||
|
||||
SendWMIEvent(1, 0x1002, reply, 20);
|
||||
|
||||
ConnectionStatus = 1;
|
||||
}
|
||||
|
||||
void DSi_NWifi::WMI_SendPacket(u16 len)
|
||||
{
|
||||
if (ConnectionStatus != 1)
|
||||
{
|
||||
printf("WMI: !! trying to send shit while not connected\n");
|
||||
// TODO: report error??
|
||||
return;
|
||||
}
|
||||
|
||||
// header???
|
||||
// packets with bit1=1 are something special (sync??)
|
||||
// otherwise, ????
|
||||
// header is 001C on ARP frames, 0000 otherwise
|
||||
u16 hdr = MB_Read16(0);
|
||||
hdr = ((hdr & 0xFF00) >> 8) | ((hdr & 0x00FF) << 8);
|
||||
u16 type = hdr & 0x0003;
|
||||
|
||||
if (type == 2) // data sync
|
||||
{
|
||||
printf("WMI: data sync\n");
|
||||
|
||||
/*Mailbox[8]->Write(2); // eid
|
||||
Mailbox[8]->Write(0x00); // flags
|
||||
MB_Write16(8, 2); // data length
|
||||
Mailbox[8]->Write(0); //
|
||||
Mailbox[8]->Write(0); //
|
||||
MB_Write16(8, 0x0200); //
|
||||
|
||||
DrainRXBuffer();*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (type)
|
||||
{
|
||||
printf("WMI: special frame %04X len=%d\n", hdr, len);
|
||||
for (int i = 0; i < len-2; i++)
|
||||
{
|
||||
printf("%02X ", Mailbox[0]->Read());
|
||||
if ((i&0xF)==0xF) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("WMI: send packet, hdr=%04X, len=%d\n", hdr, len);
|
||||
|
||||
u8 dstmac[6];
|
||||
u8 srcmac[6];
|
||||
u16 plen;
|
||||
|
||||
*(u32*)&dstmac[0] = MB_Read32(0);
|
||||
*(u16*)&dstmac[4] = MB_Read16(0);
|
||||
*(u32*)&srcmac[0] = MB_Read32(0);
|
||||
*(u16*)&srcmac[4] = MB_Read16(0);
|
||||
plen = MB_Read16(0);
|
||||
plen = ((plen & 0xFF00) >> 8) | ((plen & 0x00FF) << 8);
|
||||
|
||||
if (plen > len-16)
|
||||
{
|
||||
printf("WMI: bad packet length %d > %d\n", plen, len-16);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 h0 = MB_Read32(0);
|
||||
u16 h1 = MB_Read16(0);
|
||||
|
||||
if (h0 != 0x0003AAAA || h1 != 0x0000)
|
||||
{
|
||||
printf("WMI: bad LLC/SLIP header\n");
|
||||
return;
|
||||
}
|
||||
|
||||
u16 ethertype = MB_Read16(0);
|
||||
|
||||
int lan_len = (plen - 8) + 14;
|
||||
|
||||
memcpy(&LANBuffer[0], dstmac, 6); // destination MAC
|
||||
memcpy(&LANBuffer[6], srcmac, 6); // source MAC
|
||||
*(u16*)&LANBuffer[12] = ethertype; // type
|
||||
for (int i = 0; i < lan_len-14; i++)
|
||||
{
|
||||
LANBuffer[14+i] = Mailbox[0]->Read();
|
||||
}
|
||||
|
||||
/*for (int i = 0; i < lan_len; i++)
|
||||
{
|
||||
printf("%02X ", LANBuffer[i]);
|
||||
if ((i&0xF)==0xF) printf("\n");
|
||||
}
|
||||
printf("\n");*/
|
||||
|
||||
Platform::LAN_SendPacket(LANBuffer, lan_len);
|
||||
}
|
||||
|
||||
void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len)
|
||||
{
|
||||
if (!Mailbox[8]->CanFit(6+len+2+8))
|
||||
{
|
||||
printf("NWifi: !! not enough space in RX buffer for WMI event %04X\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
Mailbox[8]->Write(ep); // eid
|
||||
Mailbox[8]->Write(0x02); // flags (trailer)
|
||||
MB_Write16(8, len+2+8); // data length (plus event ID and trailer)
|
||||
Mailbox[8]->Write(8); // trailer length
|
||||
Mailbox[8]->Write(0); //
|
||||
MB_Write16(8, id); // event ID
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
Mailbox[4]->Write(data[i]);
|
||||
wlen++;
|
||||
Mailbox[8]->Write(data[i]);
|
||||
}
|
||||
|
||||
for (; wlen & 0x7F; wlen++)
|
||||
Mailbox[4]->Write(0);
|
||||
// trailer
|
||||
Mailbox[8]->Write(0x02);
|
||||
Mailbox[8]->Write(0x06);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
|
||||
DrainRXBuffer();
|
||||
}
|
||||
|
||||
void DSi_NWifi::SendWMIAck(u8 ep)
|
||||
{
|
||||
if (!Mailbox[8]->CanFit(6+12))
|
||||
{
|
||||
printf("NWifi: !! not enough space in RX buffer for WMI ack (ep #%d)\n", ep);
|
||||
return;
|
||||
}
|
||||
|
||||
Mailbox[8]->Write(0); // eid
|
||||
Mailbox[8]->Write(0x02); // flags (trailer)
|
||||
MB_Write16(8, 0xC); // data length (plus trailer)
|
||||
Mailbox[8]->Write(0xC); // trailer length
|
||||
Mailbox[8]->Write(0); //
|
||||
|
||||
// credit report
|
||||
Mailbox[8]->Write(0x01);
|
||||
Mailbox[8]->Write(0x02);
|
||||
Mailbox[8]->Write(ep);
|
||||
Mailbox[8]->Write(0x01);
|
||||
|
||||
// lookahead
|
||||
Mailbox[8]->Write(0x02);
|
||||
Mailbox[8]->Write(0x06);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
Mailbox[8]->Write(0x00);
|
||||
|
||||
DrainRXBuffer();
|
||||
}
|
||||
|
||||
void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
|
||||
{
|
||||
if (!Mailbox[8]->CanFit(6+len+2+16))
|
||||
{
|
||||
printf("NWifi: !! not enough space in RX buffer for WMI BSSINFO event\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: check when version>=2 frame type is used?
|
||||
// I observed the version<2 variant on my DSi
|
||||
|
||||
Mailbox[8]->Write(1); // eid
|
||||
Mailbox[8]->Write(0x00); // flags
|
||||
MB_Write16(8, len+2+16); // data length (plus event ID and trailer)
|
||||
Mailbox[8]->Write(0xFF); // trailer length
|
||||
Mailbox[8]->Write(0xFF); //
|
||||
MB_Write16(8, 0x1004); // event ID
|
||||
|
||||
MB_Write16(8, 2437); // channel (6) (checkme!)
|
||||
Mailbox[8]->Write(type);
|
||||
Mailbox[8]->Write(0x1B); // 'snr'
|
||||
MB_Write16(8, 0xFFBC); // RSSI
|
||||
MB_Write32(8, *(u32*)&WifiAP::APMac[0]);
|
||||
MB_Write16(8, *(u16*)&WifiAP::APMac[4]);
|
||||
MB_Write32(8, 0); // ieMask
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
Mailbox[8]->Write(data[i]);
|
||||
}
|
||||
|
||||
DrainRXBuffer();
|
||||
}
|
||||
|
||||
void DSi_NWifi::CheckRX()
|
||||
{
|
||||
if (!Mailbox[8]->CanFit(2048))
|
||||
return;
|
||||
|
||||
int rxlen = Platform::LAN_RecvPacket(LANBuffer);
|
||||
if (rxlen > 0)
|
||||
{
|
||||
//printf("WMI packet recv %04X %04X %04X\n", *(u16*)&LANBuffer[0], *(u16*)&LANBuffer[2], *(u16*)&LANBuffer[4]);
|
||||
// check destination MAC
|
||||
if (*(u32*)&LANBuffer[0] != 0xFFFFFFFF || *(u16*)&LANBuffer[4] != 0xFFFF)
|
||||
{
|
||||
if (memcmp(&LANBuffer[0], &EEPROM[0x00A], 6))
|
||||
return;
|
||||
}
|
||||
|
||||
// check source MAC, in case we get a packet we just sent out
|
||||
if (!memcmp(&LANBuffer[6], &EEPROM[0x00A], 6))
|
||||
return;
|
||||
|
||||
// packet is good
|
||||
|
||||
printf("WMI: receive packet %04X, len=%d\n", *(u16*)&LANBuffer[12], rxlen);
|
||||
|
||||
/*for (int i = 0; i < rxlen; i++)
|
||||
{
|
||||
printf("%02X ", LANBuffer[i]);
|
||||
if ((i&0xF)==0xF) printf("\n");
|
||||
}
|
||||
printf("\n");*/
|
||||
|
||||
int datalen = rxlen - 14; // length of packet body
|
||||
|
||||
u16 hdr = 0x0000;
|
||||
//if (*(u16*)&LANBuffer[12] == 0x0608) // HAX!!!
|
||||
// hdr = 0x1C00;
|
||||
hdr = 0x80;
|
||||
|
||||
// TODO: not hardcode the endpoint ID!!
|
||||
u8 ep = 2;
|
||||
|
||||
Mailbox[8]->Write(ep);
|
||||
Mailbox[8]->Write(0x00);
|
||||
MB_Write16(8, 16 + 8 + datalen);
|
||||
Mailbox[8]->Write(0);
|
||||
Mailbox[8]->Write(0);
|
||||
|
||||
MB_Write16(8, hdr);
|
||||
MB_Write32(8, *(u32*)&LANBuffer[0]);
|
||||
MB_Write16(8, *(u16*)&LANBuffer[4]);
|
||||
MB_Write32(8, *(u32*)&LANBuffer[6]);
|
||||
MB_Write16(8, *(u16*)&LANBuffer[10]);
|
||||
u16 plen = datalen + 8;
|
||||
plen = ((plen & 0xFF00) >> 8) | ((plen & 0x00FF) << 8);
|
||||
MB_Write16(8, plen);
|
||||
|
||||
MB_Write16(8, 0xAAAA);
|
||||
MB_Write16(8, 0x0003);
|
||||
MB_Write16(8, 0x0000);
|
||||
MB_Write16(8, *(u16*)&LANBuffer[12]);
|
||||
|
||||
for (int i = 0; i < datalen; i++)
|
||||
Mailbox[8]->Write(LANBuffer[14+i]);
|
||||
|
||||
DrainRXBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -849,7 +1447,7 @@ u32 DSi_NWifi::WindowRead(u32 addr)
|
|||
// base address of EEPROM data
|
||||
// TODO find what the actual address is!
|
||||
return 0x1FFC00;
|
||||
case 0x58: return EEPROMReady; // hax
|
||||
case 0x58: return EEPROMReady;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -879,3 +1477,69 @@ void DSi_NWifi::WindowWrite(u32 addr, u32 val)
|
|||
{
|
||||
printf("NWifi: window write %08X %08X\n", addr, val);
|
||||
}
|
||||
|
||||
|
||||
void DSi_NWifi::_MSTimer()
|
||||
{
|
||||
BeaconTimer++;
|
||||
|
||||
if (ScanTimer > 0)
|
||||
{
|
||||
ScanTimer--;
|
||||
|
||||
// send a beacon
|
||||
if (!(BeaconTimer & 0x7F))
|
||||
{
|
||||
u8 beacon[] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // timestamp
|
||||
0x80, 0x00, // beacon interval
|
||||
0x21, 0x00, // capability,
|
||||
0x01, 0x08, 0x82, 0x84, 0x8B, 0x96, 0x0C, 0x12, 0x18, 0x24, // rates
|
||||
0x03, 0x01, 0x06, // channel
|
||||
0x05, 0x04, 0x00, 0x00, 0x00, 0x00, // TIM
|
||||
0x00, 0x07, 'm', 'e', 'l', 'o', 'n', 'A', 'P', // SSID
|
||||
};
|
||||
|
||||
SendWMIBSSInfo(0x01, beacon, sizeof(beacon));
|
||||
printf("send beacon\n");
|
||||
}
|
||||
|
||||
if (ScanTimer == 0)
|
||||
{
|
||||
u32 status = 0;
|
||||
SendWMIEvent(1, 0x100A, (u8*)&status, 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (ConnectionStatus == 1)
|
||||
{
|
||||
//if (Mailbox[4]->IsEmpty())
|
||||
CheckRX();
|
||||
}
|
||||
}
|
||||
|
||||
void DSi_NWifi::DrainRXBuffer()
|
||||
{
|
||||
while (Mailbox[8]->Level() >= 6)
|
||||
{
|
||||
u16 len = Mailbox[8]->Peek(2) | (Mailbox[8]->Peek(3) << 8);
|
||||
u32 totallen = len + 6;
|
||||
u32 required = (totallen + 0x7F) & ~0x7F;
|
||||
|
||||
if (!Mailbox[4]->CanFit(required))
|
||||
break;
|
||||
|
||||
u32 i = 0;
|
||||
for (; i < totallen; i++) Mailbox[4]->Write(Mailbox[8]->Read());
|
||||
for (; i < required; i++) Mailbox[4]->Write(0);
|
||||
}
|
||||
|
||||
UpdateIRQ_F1();
|
||||
}
|
||||
|
||||
void DSi_NWifi::MSTimer(u32 param)
|
||||
{
|
||||
Ctx->_MSTimer();
|
||||
NDS::ScheduleEvent(NDS::Event_DSi_NWifi, true, 33611, MSTimer, 0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -28,6 +28,8 @@ public:
|
|||
DSi_NWifi(DSi_SDHost* host);
|
||||
~DSi_NWifi();
|
||||
|
||||
void Reset();
|
||||
|
||||
void SendCMD(u8 cmd, u32 param);
|
||||
void SendACMD(u8 cmd, u32 param);
|
||||
|
||||
|
@ -35,6 +37,10 @@ public:
|
|||
|
||||
void SetIRQ_F1_Counter(u32 n);
|
||||
|
||||
void _MSTimer();
|
||||
|
||||
static void MSTimer(u32 param);
|
||||
|
||||
private:
|
||||
u32 TransferCmd;
|
||||
u32 TransferAddr;
|
||||
|
@ -60,9 +66,18 @@ private:
|
|||
|
||||
void HandleCommand();
|
||||
void BMI_Command();
|
||||
void HTC_Command();
|
||||
void WMI_Command();
|
||||
|
||||
void SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl);
|
||||
void WMI_ConnectToNetwork();
|
||||
void WMI_SendPacket(u16 len);
|
||||
|
||||
void SendWMIEvent(u8 ep, u16 id, u8* data, u32 len);
|
||||
void SendWMIAck(u8 ep);
|
||||
void SendWMIBSSInfo(u8 type, u8* data, u32 len);
|
||||
|
||||
void CheckRX();
|
||||
void DrainRXBuffer();
|
||||
|
||||
u32 WindowRead(u32 addr);
|
||||
void WindowWrite(u32 addr, u32 val);
|
||||
|
@ -102,7 +117,7 @@ private:
|
|||
while (!Mailbox[n]->IsEmpty()) Mailbox[n]->Read();
|
||||
}
|
||||
|
||||
FIFO<u8>* Mailbox[8];
|
||||
FIFO<u8>* Mailbox[9];
|
||||
|
||||
u8 F0_IRQEnable;
|
||||
u8 F0_IRQStatus;
|
||||
|
@ -116,6 +131,14 @@ private:
|
|||
u32 EEPROMReady;
|
||||
|
||||
u32 BootPhase;
|
||||
|
||||
u32 ErrorMask;
|
||||
u32 ScanTimer;
|
||||
|
||||
u64 BeaconTimer;
|
||||
u32 ConnectionStatus;
|
||||
|
||||
u8 LANBuffer[2048];
|
||||
};
|
||||
|
||||
#endif // DSI_NWIFI_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -112,8 +112,8 @@ void DSi_SDHost::Reset()
|
|||
|
||||
if (Ports[0]) delete Ports[0];
|
||||
if (Ports[1]) delete Ports[1];
|
||||
Ports[0] = NULL;
|
||||
Ports[1] = NULL;
|
||||
Ports[0] = nullptr;
|
||||
Ports[1] = nullptr;
|
||||
|
||||
if (Num == 0)
|
||||
{
|
||||
|
@ -135,6 +135,9 @@ void DSi_SDHost::Reset()
|
|||
|
||||
Ports[0] = nwifi;
|
||||
}
|
||||
|
||||
if (Ports[0]) Ports[0]->Reset();
|
||||
if (Ports[1]) Ports[1]->Reset();
|
||||
}
|
||||
|
||||
void DSi_SDHost::DoSavestate(Savestate* file)
|
||||
|
@ -205,6 +208,18 @@ void DSi_SDHost::SetCardIRQ()
|
|||
}
|
||||
}
|
||||
|
||||
void DSi_SDHost::UpdateCardIRQ(u16 oldmask)
|
||||
{
|
||||
u16 oldflags = CardIRQStatus & ~oldmask;
|
||||
u16 newflags = CardIRQStatus & ~CardIRQMask;
|
||||
|
||||
if ((oldflags == 0) && (newflags != 0)) // checkme
|
||||
{
|
||||
NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC);
|
||||
NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO_Data1 : NDS::IRQ2_DSi_SD_Data1);
|
||||
}
|
||||
}
|
||||
|
||||
void DSi_SDHost::SendResponse(u32 val, bool last)
|
||||
{
|
||||
*(u32*)&ResponseBuffer[6] = *(u32*)&ResponseBuffer[4];
|
||||
|
@ -448,6 +463,7 @@ u16 DSi_SDHost::Read(u32 addr)
|
|||
case 0x0F6: return 0; // MMC write protect (always 0)
|
||||
|
||||
case 0x100: return Data32IRQ;
|
||||
case 0x102: return 0;
|
||||
case 0x104: return BlockLen32;
|
||||
case 0x108: return BlockCount32;
|
||||
}
|
||||
|
@ -549,8 +565,8 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
|||
u32 oldmask = IRQMask;
|
||||
IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16);
|
||||
UpdateIRQ(oldmask);
|
||||
if (!DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(24); // checkme
|
||||
if (DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(25); // checkme
|
||||
//if (!DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(24); // checkme
|
||||
//if (DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(25); // checkme
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -571,8 +587,13 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
|||
CardIRQStatus &= val;
|
||||
return;
|
||||
case 0x038:
|
||||
CardIRQMask = val & 0xC007;
|
||||
SetCardIRQ();
|
||||
{
|
||||
u16 oldmask = CardIRQMask;
|
||||
CardIRQMask = val & 0xC007;
|
||||
UpdateCardIRQ(oldmask);
|
||||
}
|
||||
//CardIRQMask = val & 0xC007;
|
||||
//SetCardIRQ();
|
||||
return;
|
||||
|
||||
case 0x0D8:
|
||||
|
@ -592,6 +613,9 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
|||
SDOption = 0x40EE;
|
||||
// TODO: CARD_IRQ_STAT
|
||||
// TODO: FIFO16 shit
|
||||
|
||||
if (Ports[0]) Ports[0]->Reset();
|
||||
if (Ports[1]) Ports[1]->Reset();
|
||||
}
|
||||
SoftReset = 0x0006 | (val & 0x0001);
|
||||
return;
|
||||
|
@ -601,6 +625,7 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
|||
if (val & (1<<10)) DataFIFO32->Clear();
|
||||
DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1);
|
||||
return;
|
||||
case 0x102: return;
|
||||
case 0x104: BlockLen32 = val & 0x03FF; return;
|
||||
case 0x108: BlockCount32 = val; return;
|
||||
}
|
||||
|
@ -701,6 +726,16 @@ DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path
|
|||
File = Platform::OpenLocalFile(path, "w+b");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DSi_MMCStorage::~DSi_MMCStorage()
|
||||
{
|
||||
if (File) fclose(File);
|
||||
}
|
||||
|
||||
void DSi_MMCStorage::Reset()
|
||||
{
|
||||
// TODO: reset file access????
|
||||
|
||||
CSR = 0x00000100; // checkme
|
||||
|
||||
|
@ -723,11 +758,6 @@ DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path
|
|||
RWCommand = 0;
|
||||
}
|
||||
|
||||
DSi_MMCStorage::~DSi_MMCStorage()
|
||||
{
|
||||
if (File) fclose(File);
|
||||
}
|
||||
|
||||
void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
|
||||
{
|
||||
if (CSR & (1<<5))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
@ -95,6 +95,7 @@ private:
|
|||
void ClearIRQ(u32 irq);
|
||||
void SetIRQ(u32 irq);
|
||||
void UpdateIRQ(u32 oldmask);
|
||||
void UpdateCardIRQ(u16 oldmask);
|
||||
};
|
||||
|
||||
|
||||
|
@ -104,6 +105,8 @@ public:
|
|||
DSi_SDDevice(DSi_SDHost* host) { Host = host; IRQ = false; }
|
||||
~DSi_SDDevice() {}
|
||||
|
||||
virtual void Reset() = 0;
|
||||
|
||||
virtual void SendCMD(u8 cmd, u32 param) = 0;
|
||||
virtual void ContinueTransfer() = 0;
|
||||
|
||||
|
@ -120,6 +123,8 @@ public:
|
|||
DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path);
|
||||
~DSi_MMCStorage();
|
||||
|
||||
void Reset();
|
||||
|
||||
void SetCID(u8* cid) { memcpy(CID, cid, 16); }
|
||||
|
||||
void SendCMD(u8 cmd, u32 param);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016-2019 Arisotura
|
||||
Copyright 2016-2020 Arisotura
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
bool IsEmpty() { return NumOccupied == 0; }
|
||||
bool IsFull() { return NumOccupied >= NumEntries; }
|
||||
|
||||
bool CanFit(u32 num) { return ((NumOccupied + num) <= NumEntries); }
|
||||
|
||||
private:
|
||||
u32 NumEntries;
|
||||
T* Entries;
|
||||
|
|
|
@ -1815,14 +1815,14 @@ void debug(u32 param)
|
|||
}
|
||||
fclose(shit);*/
|
||||
FILE*
|
||||
/*shit = fopen("debug/dump9.bin", "wb");
|
||||
shit = fopen("debug/dump9.bin", "wb");
|
||||
for (u32 i = 0x02000000; i < 0x04000000; i+=4)
|
||||
{
|
||||
u32 val = DSi::ARM9Read32(i);
|
||||
fwrite(&val, 4, 1, shit);
|
||||
}
|
||||
fclose(shit);*/
|
||||
shit = fopen("debug/dump7_2.bin", "wb");
|
||||
fclose(shit);
|
||||
shit = fopen("debug/dump7.bin", "wb");
|
||||
for (u32 i = 0x02000000; i < 0x04000000; i+=4)
|
||||
{
|
||||
u32 val = DSi::ARM7Read32(i);
|
||||
|
|
|
@ -106,7 +106,6 @@ u8 BCD(u8 val)
|
|||
|
||||
void ByteIn(u8 val)
|
||||
{
|
||||
//printf("RTC IN: %02X\n", val);
|
||||
if (InputPos == 0)
|
||||
{
|
||||
if ((val & 0xF0) == 0x60)
|
||||
|
@ -175,7 +174,6 @@ void ByteIn(u8 val)
|
|||
case 0x70: Output[0] = FreeReg; break;
|
||||
}
|
||||
}
|
||||
InputPos++;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -221,8 +219,6 @@ void ByteIn(u8 val)
|
|||
if (InputPos == 1) FreeReg = val;
|
||||
break;
|
||||
}
|
||||
|
||||
InputPos++;
|
||||
}
|
||||
|
||||
|
||||
|
|
30
src/SPI.cpp
30
src/SPI.cpp
|
@ -162,22 +162,26 @@ void Reset()
|
|||
|
||||
UserSettings = userdata;
|
||||
|
||||
// fix touchscreen coords
|
||||
#if 0
|
||||
*(u16*)&Firmware[userdata+0x58] = 0;
|
||||
*(u16*)&Firmware[userdata+0x5A] = 0;
|
||||
Firmware[userdata+0x5C] = 0;
|
||||
Firmware[userdata+0x5D] = 0;
|
||||
*(u16*)&Firmware[userdata+0x5E] = 255<<4;
|
||||
*(u16*)&Firmware[userdata+0x60] = 191<<4;
|
||||
Firmware[userdata+0x62] = 255;
|
||||
Firmware[userdata+0x63] = 191;
|
||||
// TODO evetually: do this in DSi mode
|
||||
if (NDS::ConsoleType == 0)
|
||||
{
|
||||
// fix touchscreen coords
|
||||
*(u16*)&Firmware[userdata+0x58] = 0;
|
||||
*(u16*)&Firmware[userdata+0x5A] = 0;
|
||||
Firmware[userdata+0x5C] = 0;
|
||||
Firmware[userdata+0x5D] = 0;
|
||||
*(u16*)&Firmware[userdata+0x5E] = 255<<4;
|
||||
*(u16*)&Firmware[userdata+0x60] = 191<<4;
|
||||
Firmware[userdata+0x62] = 255;
|
||||
Firmware[userdata+0x63] = 191;
|
||||
|
||||
// disable autoboot
|
||||
//Firmware[userdata+0x64] &= 0xBF;
|
||||
// disable autoboot
|
||||
//Firmware[userdata+0x64] &= 0xBF;
|
||||
|
||||
*(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF);
|
||||
*(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// replace MAC address with random address
|
||||
// TODO: make optional?
|
||||
Firmware[0x36] = 0x00;
|
||||
|
|
|
@ -188,6 +188,8 @@ void Reset()
|
|||
IOPORT(0x000) = 0x1440;
|
||||
else if (console == 0x20)
|
||||
IOPORT(0x000) = 0xC340;
|
||||
else if (NDS::ConsoleType == 1 && console == 0x57)
|
||||
IOPORT(0x000) = 0xC340; // DSi has the modern DS-wifi variant
|
||||
else
|
||||
{
|
||||
printf("wifi: unknown console type %02X\n", console);
|
||||
|
|
|
@ -30,9 +30,6 @@
|
|||
namespace WifiAP
|
||||
{
|
||||
|
||||
#define AP_MAC 0x00, 0xF0, 0x77, 0x77, 0x77, 0x77
|
||||
#define AP_NAME "melonAP"
|
||||
|
||||
const u8 APMac[6] = {AP_MAC};
|
||||
|
||||
#define PWRITE_8(p, v) *p++ = v;
|
||||
|
@ -130,6 +127,18 @@ void USTimer()
|
|||
}
|
||||
}
|
||||
|
||||
void MSTimer()
|
||||
{
|
||||
USCounter += 0x400;
|
||||
|
||||
u32 chk = (u32)USCounter;
|
||||
if (!(chk & 0x1FC00))
|
||||
{
|
||||
// send beacon every 128ms
|
||||
BeaconDue = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int HandleManagementFrame(u8* data, int len)
|
||||
{
|
||||
|
|
|
@ -22,11 +22,17 @@
|
|||
namespace WifiAP
|
||||
{
|
||||
|
||||
#define AP_MAC 0x00, 0xF0, 0x77, 0x77, 0x77, 0x77
|
||||
#define AP_NAME "melonAP"
|
||||
|
||||
extern const u8 APMac[6];
|
||||
|
||||
bool Init();
|
||||
void DeInit();
|
||||
void Reset();
|
||||
|
||||
void USTimer();
|
||||
void MSTimer();
|
||||
|
||||
// packet format: 12-byte TX header + original 802.11 frame
|
||||
int SendPacket(u8* data, int len);
|
||||
|
|
|
@ -46,7 +46,9 @@ set(CMAKE_AUTORCC ON)
|
|||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Iconv REQUIRED)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
pkg_check_modules(SLIRP REQUIRED slirp)
|
||||
|
||||
if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL Release))
|
||||
add_executable(melonDS WIN32 ${SOURCES_QT_SDL})
|
||||
|
@ -57,15 +59,20 @@ endif()
|
|||
target_link_libraries(melonDS ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS})
|
||||
target_include_directories(melonDS PRIVATE ${SLIRP_INCLUDE_DIRS})
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..")
|
||||
target_link_libraries(melonDS core)
|
||||
|
||||
if (BUILD_STATIC)
|
||||
target_link_libraries(melonDS -static ${SDL2_LIBRARIES})
|
||||
target_link_libraries(melonDS -static ${SDL2_STATIC_LIBRARIES} ${SLIRP_STATIC_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(melonDS ${SDL2_LIBRARIES})
|
||||
target_link_libraries(melonDS ${SDL2_LIBRARIES} ${SLIRP_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (NOT Iconv_IS_BUILT_IN)
|
||||
target_link_libraries(melonDS iconv)
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1285,6 +1285,8 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
|
|||
{
|
||||
if (event->isAutoRepeat()) return;
|
||||
|
||||
if (event->key() == Qt::Key_F11) NDS::debug(0);
|
||||
|
||||
Input::KeyPress(event);
|
||||
}
|
||||
|
||||
|
@ -2083,12 +2085,12 @@ int CALLBACK WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdsho
|
|||
|
||||
if (argv_w) LocalFree(argv_w);
|
||||
|
||||
if (AttachConsole(ATTACH_PARENT_PROCESS))
|
||||
/*if (AttachConsole(ATTACH_PARENT_PROCESS))
|
||||
{
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
printf("\n");
|
||||
}
|
||||
}*/
|
||||
|
||||
int ret = main(argc, argv);
|
||||
|
||||
|
|
Loading…
Reference in New Issue