wifi: take this shit further. complete wifi init
This commit is contained in:
parent
0918da7b00
commit
f7f4ff0519
20
src/DSi.cpp
20
src/DSi.cpp
|
@ -582,7 +582,7 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val)
|
||||||
|
|
||||||
|
|
||||||
u8 ARM9Read8(u32 addr)
|
u8 ARM9Read8(u32 addr)
|
||||||
{if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 8 9 %08X %08X\n", addr, NDS::GetPC(0));
|
{
|
||||||
switch (addr & 0xFF000000)
|
switch (addr & 0xFF000000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
@ -611,7 +611,7 @@ u8 ARM9Read8(u32 addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 ARM9Read16(u32 addr)
|
u16 ARM9Read16(u32 addr)
|
||||||
{if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 16 9 %08X %08X\n", addr, NDS::GetPC(0));
|
{
|
||||||
switch (addr & 0xFF000000)
|
switch (addr & 0xFF000000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
@ -640,8 +640,7 @@ u16 ARM9Read16(u32 addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ARM9Read32(u32 addr)
|
u32 ARM9Read32(u32 addr)
|
||||||
{if(addr==0x029D02D8) printf("READ SHITTY VTABLE: %08X\n", NDS::GetPC(0));
|
{
|
||||||
if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 32 9 %08X %08X\n", addr, NDS::GetPC(0));
|
|
||||||
switch (addr & 0xFF000000)
|
switch (addr & 0xFF000000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
@ -736,7 +735,7 @@ void ARM9Write16(u32 addr, u16 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM9Write32(u32 addr, u32 val)
|
void ARM9Write32(u32 addr, u32 val)
|
||||||
{if(addr==0x02B05E34) printf("VGONP. %08X, %08X\n", val, NDS::GetPC(0));
|
{
|
||||||
switch (addr & 0xFF000000)
|
switch (addr & 0xFF000000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
@ -792,8 +791,7 @@ bool ARM9GetMemRegion(u32 addr, bool write, NDS::MemRegion* region)
|
||||||
|
|
||||||
|
|
||||||
u8 ARM7Read8(u32 addr)
|
u8 ARM7Read8(u32 addr)
|
||||||
{if(addr>=0x3FFC400 && addr<0x3FFE728) printf("OGON 8 %08X %08X\n", addr, NDS::GetPC(1));
|
{
|
||||||
if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 8 7 %08X %08X\n", addr, NDS::GetPC(1));
|
|
||||||
switch (addr & 0xFF800000)
|
switch (addr & 0xFF800000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
@ -822,8 +820,7 @@ if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 8 7 %08X %08X\n", addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 ARM7Read16(u32 addr)
|
u16 ARM7Read16(u32 addr)
|
||||||
{if(addr>=0x3FFC400 && addr<0x3FFE728) printf("OGON 16 %08X %08X\n", addr, NDS::GetPC(1));
|
{
|
||||||
if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 16 7 %08X %08X\n", addr, NDS::GetPC(1));
|
|
||||||
switch (addr & 0xFF800000)
|
switch (addr & 0xFF800000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
@ -852,8 +849,7 @@ if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 16 7 %08X %08X\n", addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ARM7Read32(u32 addr)
|
u32 ARM7Read32(u32 addr)
|
||||||
{if(addr>=0x3FFC400 && addr<0x3FFE728) printf("OGON 32 %08X %08X\n", addr, NDS::GetPC(1));
|
{
|
||||||
if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 32 7 %08X %08X\n", addr, NDS::GetPC(1));
|
|
||||||
switch (addr & 0xFF800000)
|
switch (addr & 0xFF800000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
@ -882,7 +878,7 @@ if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 32 7 %08X %08X\n", addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM7Write8(u32 addr, u8 val)
|
void ARM7Write8(u32 addr, u8 val)
|
||||||
{if(addr==0x0228CD74) printf("RAKAKA %02X %08X\n", val, NDS::GetPC(1));
|
{
|
||||||
switch (addr & 0xFF800000)
|
switch (addr & 0xFF800000)
|
||||||
{
|
{
|
||||||
case 0x03000000:
|
case 0x03000000:
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "DSi.h"
|
#include "DSi.h"
|
||||||
#include "DSi_NWifi.h"
|
#include "DSi_NWifi.h"
|
||||||
|
#include "SPI.h"
|
||||||
|
|
||||||
|
|
||||||
const u8 CIS0[256] =
|
const u8 CIS0[256] =
|
||||||
|
@ -110,11 +111,25 @@ const u8 CIS1[256] =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// hax
|
||||||
|
DSi_NWifi* hax_wifi;
|
||||||
|
void triggerirq(u32 param)
|
||||||
|
{
|
||||||
|
hax_wifi->SetIRQ_F1_Counter(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
|
DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
|
||||||
{
|
{
|
||||||
TransferCmd = 0xFFFFFFFF;
|
TransferCmd = 0xFFFFFFFF;
|
||||||
RemSize = 0;
|
RemSize = 0;
|
||||||
|
|
||||||
|
F0_IRQEnable = 0;
|
||||||
|
F0_IRQStatus = 0;
|
||||||
|
|
||||||
|
F1_IRQEnable = 0; F1_IRQEnable_CPU = 0; F1_IRQEnable_Error = 0; F1_IRQEnable_Counter = 0;
|
||||||
|
F1_IRQStatus = 0; F1_IRQStatus_CPU = 0; F1_IRQStatus_Error = 0; F1_IRQStatus_Counter = 0;
|
||||||
|
|
||||||
WindowData = 0;
|
WindowData = 0;
|
||||||
WindowReadAddr = 0;
|
WindowReadAddr = 0;
|
||||||
WindowWriteAddr = 0;
|
WindowWriteAddr = 0;
|
||||||
|
@ -122,6 +137,30 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
|
||||||
// TODO: check the actual mailbox size (presumably 0x200)
|
// TODO: check the actual mailbox size (presumably 0x200)
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
Mailbox[i] = new FIFO<u8>(0x200);
|
Mailbox[i] = new FIFO<u8>(0x200);
|
||||||
|
|
||||||
|
u8* mac = SPI_Firmware::GetWifiMAC();
|
||||||
|
printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||||
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||||
|
|
||||||
|
memset(EEPROM, 0, 0x400);
|
||||||
|
|
||||||
|
*(u32*)&EEPROM[0x000] = 0x300;
|
||||||
|
*(u16*)&EEPROM[0x008] = 0x8348; // TODO: determine properly (country code)
|
||||||
|
memcpy(&EEPROM[0x00A], mac, 6);
|
||||||
|
*(u32*)&EEPROM[0x010] = 0x60000000;
|
||||||
|
|
||||||
|
memset(&EEPROM[0x03C], 0xFF, 0x70);
|
||||||
|
memset(&EEPROM[0x140], 0xFF, 0x8);
|
||||||
|
|
||||||
|
u16 chk = 0xFFFF;
|
||||||
|
for (int i = 0; i < 0x300; i+=2)
|
||||||
|
chk ^= *(u16*)&EEPROM[i];
|
||||||
|
|
||||||
|
*(u16*)&EEPROM[0x004] = chk;
|
||||||
|
|
||||||
|
EEPROMReady = 0;
|
||||||
|
|
||||||
|
BootPhase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSi_NWifi::~DSi_NWifi()
|
DSi_NWifi::~DSi_NWifi()
|
||||||
|
@ -131,6 +170,61 @@ DSi_NWifi::~DSi_NWifi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CHECKME
|
||||||
|
// can IRQ status bits be set when the corresponding IRQs are disabled in the enable register?
|
||||||
|
// otherwise, does disabling them clear the status register?
|
||||||
|
|
||||||
|
void DSi_NWifi::UpdateIRQ()
|
||||||
|
{
|
||||||
|
F0_IRQStatus = 0;
|
||||||
|
IRQ = false;
|
||||||
|
|
||||||
|
if (F1_IRQStatus & F1_IRQEnable)
|
||||||
|
F0_IRQStatus |= (1<<1);
|
||||||
|
|
||||||
|
if (F0_IRQEnable & (1<<0))
|
||||||
|
{
|
||||||
|
if (F0_IRQStatus & F0_IRQEnable)
|
||||||
|
IRQ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Host->SetCardIRQ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSi_NWifi::UpdateIRQ_F1()
|
||||||
|
{
|
||||||
|
F1_IRQStatus = 0;
|
||||||
|
|
||||||
|
if (!Mailbox[4]->IsEmpty()) F1_IRQStatus |= (1<<0);
|
||||||
|
if (!Mailbox[5]->IsEmpty()) F1_IRQStatus |= (1<<1);
|
||||||
|
if (!Mailbox[6]->IsEmpty()) F1_IRQStatus |= (1<<2);
|
||||||
|
if (!Mailbox[7]->IsEmpty()) F1_IRQStatus |= (1<<3);
|
||||||
|
if (F1_IRQStatus_Counter & F1_IRQEnable_Counter) F1_IRQStatus |= (1<<4);
|
||||||
|
if (F1_IRQStatus_CPU & F1_IRQEnable_CPU) F1_IRQStatus |= (1<<6);
|
||||||
|
if (F1_IRQStatus_Error & F1_IRQEnable_Error) F1_IRQStatus |= (1<<7);
|
||||||
|
|
||||||
|
UpdateIRQ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSi_NWifi::SetIRQ_F1_Counter(u32 n)
|
||||||
|
{
|
||||||
|
F1_IRQStatus_Counter |= (1<<n);
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSi_NWifi::ClearIRQ_F1_Counter(u32 n)
|
||||||
|
{
|
||||||
|
F1_IRQStatus_Counter &= ~(1<<n);
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSi_NWifi::SetIRQ_F1_CPU(u32 n)
|
||||||
|
{
|
||||||
|
F1_IRQStatus_CPU |= (1<<n);
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
u8 DSi_NWifi::F0_Read(u32 addr)
|
u8 DSi_NWifi::F0_Read(u32 addr)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
|
@ -141,6 +235,9 @@ u8 DSi_NWifi::F0_Read(u32 addr)
|
||||||
case 0x00002: return 0x02; // writable??
|
case 0x00002: return 0x02; // writable??
|
||||||
case 0x00003: return 0x02;
|
case 0x00003: return 0x02;
|
||||||
|
|
||||||
|
case 0x00004: return F0_IRQEnable;
|
||||||
|
case 0x00005: return F0_IRQStatus;
|
||||||
|
|
||||||
case 0x00008: return 0x17;
|
case 0x00008: return 0x17;
|
||||||
|
|
||||||
case 0x00009: return 0x00;
|
case 0x00009: return 0x00;
|
||||||
|
@ -169,32 +266,77 @@ u8 DSi_NWifi::F0_Read(u32 addr)
|
||||||
|
|
||||||
void DSi_NWifi::F0_Write(u32 addr, u8 val)
|
void DSi_NWifi::F0_Write(u32 addr, u8 val)
|
||||||
{
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x00004:
|
||||||
|
F0_IRQEnable = val;
|
||||||
|
UpdateIRQ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
printf("NWIFI: unknown func0 write %05X %02X\n", addr, val);
|
printf("NWIFI: unknown func0 write %05X %02X\n", addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u8 DSi_NWifi::F1_Read(u32 addr)
|
u8 DSi_NWifi::F1_Read(u32 addr)
|
||||||
{printf("F1 READ %05X\n", addr);
|
{
|
||||||
if (addr < 0x100)
|
if (addr < 0x100)
|
||||||
{
|
{
|
||||||
return Mailbox[4]->Read();
|
u8 ret = Mailbox[4]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else if (addr < 0x200)
|
else if (addr < 0x200)
|
||||||
{
|
{
|
||||||
return Mailbox[5]->Read();
|
u8 ret = Mailbox[5]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else if (addr < 0x300)
|
else if (addr < 0x300)
|
||||||
{
|
{
|
||||||
return Mailbox[6]->Read();
|
u8 ret = Mailbox[6]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else if (addr < 0x400)
|
else if (addr < 0x400)
|
||||||
{
|
{
|
||||||
return Mailbox[7]->Read();
|
u8 ret = Mailbox[7]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else if (addr < 0x800)
|
else if (addr < 0x800)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x00400: return F1_IRQStatus;
|
||||||
|
case 0x00401: return F1_IRQStatus_CPU;
|
||||||
|
case 0x00402: return F1_IRQStatus_Error;
|
||||||
|
case 0x00403: return F1_IRQStatus_Counter;
|
||||||
|
|
||||||
|
case 0x00405:
|
||||||
|
{
|
||||||
|
u8 ret = 0;
|
||||||
|
|
||||||
|
if (Mailbox[4]->Level() >= 4) ret |= (1<<0);
|
||||||
|
if (Mailbox[5]->Level() >= 4) ret |= (1<<1);
|
||||||
|
if (Mailbox[6]->Level() >= 4) ret |= (1<<2);
|
||||||
|
if (Mailbox[7]->Level() >= 4) ret |= (1<<3);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x00408: return Mailbox[4]->Peek(0);
|
||||||
|
case 0x00409: return Mailbox[4]->Peek(1);
|
||||||
|
case 0x0040A: return Mailbox[4]->Peek(2);
|
||||||
|
case 0x0040B: return Mailbox[4]->Peek(3);
|
||||||
|
|
||||||
|
case 0x00418: return F1_IRQEnable;
|
||||||
|
case 0x00419: return F1_IRQEnable_CPU;
|
||||||
|
case 0x0041A: return F1_IRQEnable_Error;
|
||||||
|
case 0x0041B: return F1_IRQEnable_Counter;
|
||||||
|
|
||||||
|
// GROSS FUCKING HACK
|
||||||
|
case 0x00440: ClearIRQ_F1_Counter(0); return 0;
|
||||||
case 0x00450: return 1; // HAX!!
|
case 0x00450: return 1; // HAX!!
|
||||||
|
|
||||||
case 0x00474: return WindowData & 0xFF;
|
case 0x00474: return WindowData & 0xFF;
|
||||||
|
@ -205,23 +347,33 @@ u8 DSi_NWifi::F1_Read(u32 addr)
|
||||||
}
|
}
|
||||||
else if (addr < 0x1000)
|
else if (addr < 0x1000)
|
||||||
{
|
{
|
||||||
return Mailbox[4]->Read();
|
u8 ret = Mailbox[4]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else if (addr < 0x1800)
|
else if (addr < 0x1800)
|
||||||
{
|
{
|
||||||
return Mailbox[5]->Read();
|
u8 ret = Mailbox[5]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else if (addr < 0x2000)
|
else if (addr < 0x2000)
|
||||||
{
|
{
|
||||||
return Mailbox[6]->Read();
|
u8 ret = Mailbox[6]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else if (addr < 0x2800)
|
else if (addr < 0x2800)
|
||||||
{
|
{
|
||||||
return Mailbox[7]->Read();
|
u8 ret = Mailbox[7]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Mailbox[4]->Read();
|
u8 ret = Mailbox[4]->Read();
|
||||||
|
UpdateIRQ_F1();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("NWIFI: unknown func1 read %05X\n", addr);
|
printf("NWIFI: unknown func1 read %05X\n", addr);
|
||||||
|
@ -229,36 +381,48 @@ u8 DSi_NWifi::F1_Read(u32 addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSi_NWifi::F1_Write(u32 addr, u8 val)
|
void DSi_NWifi::F1_Write(u32 addr, u8 val)
|
||||||
{printf("F1 WRITE %05X %02X\n", addr, val);
|
{
|
||||||
if (addr < 0x100)
|
if (addr < 0x100)
|
||||||
{
|
{
|
||||||
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
|
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
|
||||||
Mailbox[0]->Write(val);
|
Mailbox[0]->Write(val);
|
||||||
if (addr == 0xFF) BMI_Command();
|
if (addr == 0xFF) HandleCommand();
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (addr < 0x200)
|
else if (addr < 0x200)
|
||||||
{
|
{
|
||||||
if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
|
if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
|
||||||
Mailbox[1]->Write(val);
|
Mailbox[1]->Write(val);
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (addr < 0x300)
|
else if (addr < 0x300)
|
||||||
{
|
{
|
||||||
if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
|
if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
|
||||||
Mailbox[2]->Write(val);
|
Mailbox[2]->Write(val);
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (addr < 0x400)
|
else if (addr < 0x400)
|
||||||
{
|
{
|
||||||
if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
|
if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
|
||||||
Mailbox[3]->Write(val);
|
Mailbox[3]->Write(val);
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (addr < 0x800)
|
else if (addr < 0x800)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x00418: F1_IRQEnable = val; UpdateIRQ_F1(); return;
|
||||||
|
case 0x00419: F1_IRQEnable_CPU = val; UpdateIRQ_F1(); return;
|
||||||
|
case 0x0041A: F1_IRQEnable_Error = val; UpdateIRQ_F1(); return;
|
||||||
|
case 0x0041B: F1_IRQEnable_Counter = val; UpdateIRQ_F1(); return;
|
||||||
|
|
||||||
|
// GROSS FUCKING HACK
|
||||||
|
case 0x00440: ClearIRQ_F1_Counter(0); return;
|
||||||
|
|
||||||
case 0x00474: WindowData = (WindowData & 0xFFFFFF00) | val; return;
|
case 0x00474: WindowData = (WindowData & 0xFFFFFF00) | val; return;
|
||||||
case 0x00475: WindowData = (WindowData & 0xFFFF00FF) | (val << 8); return;
|
case 0x00475: WindowData = (WindowData & 0xFFFF00FF) | (val << 8); return;
|
||||||
case 0x00476: WindowData = (WindowData & 0xFF00FFFF) | (val << 16); return;
|
case 0x00476: WindowData = (WindowData & 0xFF00FFFF) | (val << 16); return;
|
||||||
|
@ -285,32 +449,37 @@ void DSi_NWifi::F1_Write(u32 addr, u8 val)
|
||||||
{
|
{
|
||||||
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
|
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
|
||||||
Mailbox[0]->Write(val);
|
Mailbox[0]->Write(val);
|
||||||
if (addr == 0xFFF) BMI_Command();
|
if (addr == 0xFFF) HandleCommand();
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (addr < 0x1800)
|
else if (addr < 0x1800)
|
||||||
{
|
{
|
||||||
if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
|
if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
|
||||||
Mailbox[1]->Write(val);
|
Mailbox[1]->Write(val);
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (addr < 0x2000)
|
else if (addr < 0x2000)
|
||||||
{
|
{
|
||||||
if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
|
if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
|
||||||
Mailbox[2]->Write(val);
|
Mailbox[2]->Write(val);
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (addr < 0x2800)
|
else if (addr < 0x2800)
|
||||||
{
|
{
|
||||||
if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
|
if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
|
||||||
Mailbox[3]->Write(val);
|
Mailbox[3]->Write(val);
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
|
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
|
||||||
Mailbox[0]->Write(val);
|
Mailbox[0]->Write(val);
|
||||||
if (addr == 0x3FFF) BMI_Command(); // CHECKME
|
if (addr == 0x3FFF) HandleCommand(); // CHECKME
|
||||||
|
UpdateIRQ_F1();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +512,7 @@ void DSi_NWifi::SDIO_Write(u32 func, u32 addr, u8 val)
|
||||||
|
|
||||||
|
|
||||||
void DSi_NWifi::SendCMD(u8 cmd, u32 param)
|
void DSi_NWifi::SendCMD(u8 cmd, u32 param)
|
||||||
{printf("NWIFI CMD %d %08X %08X\n", cmd, param, NDS::GetPC(1));
|
{
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case 52: // IO_RW_DIRECT
|
case 52: // IO_RW_DIRECT
|
||||||
|
@ -426,6 +595,8 @@ void DSi_NWifi::ReadBlock()
|
||||||
u32 func = (TransferCmd >> 28) & 0x7;
|
u32 func = (TransferCmd >> 28) & 0x7;
|
||||||
u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize;
|
u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize;
|
||||||
|
|
||||||
|
len = Host->GetTransferrableLen(len);
|
||||||
|
|
||||||
u8 data[0x200];
|
u8 data[0x200];
|
||||||
|
|
||||||
for (u32 i = 0; i < len; i++)
|
for (u32 i = 0; i < len; i++)
|
||||||
|
@ -437,7 +608,7 @@ void DSi_NWifi::ReadBlock()
|
||||||
TransferAddr &= 0x1FFFF; // checkme
|
TransferAddr &= 0x1FFFF; // checkme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Host->SendData(data, len);
|
len = Host->SendData(data, len);
|
||||||
|
|
||||||
if (RemSize > 0)
|
if (RemSize > 0)
|
||||||
{
|
{
|
||||||
|
@ -454,8 +625,10 @@ void DSi_NWifi::WriteBlock()
|
||||||
u32 func = (TransferCmd >> 28) & 0x7;
|
u32 func = (TransferCmd >> 28) & 0x7;
|
||||||
u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize;
|
u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize;
|
||||||
|
|
||||||
|
len = Host->GetTransferrableLen(len);
|
||||||
|
|
||||||
u8 data[0x200];
|
u8 data[0x200];
|
||||||
if (Host->ReceiveData(data, len))
|
if (len = Host->ReceiveData(data, len))
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < len; i++)
|
for (u32 i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
|
@ -479,14 +652,32 @@ void DSi_NWifi::WriteBlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DSi_NWifi::HandleCommand()
|
||||||
|
{
|
||||||
|
switch (BootPhase)
|
||||||
|
{
|
||||||
|
case 0: return BMI_Command();
|
||||||
|
case 1: return WMI_Command();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DSi_NWifi::BMI_Command()
|
void DSi_NWifi::BMI_Command()
|
||||||
{
|
{
|
||||||
// HLE command handling stub
|
// HLE command handling stub
|
||||||
u32 cmd = MB_Read32(0);
|
u32 cmd = MB_Read32(0);
|
||||||
printf("BMI: cmd %08X\n", cmd);
|
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
|
case 0x01: // BMI_DONE
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
BootPhase = 1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
case 0x03: // BMI_WRITE_MEMORY
|
case 0x03: // BMI_WRITE_MEMORY
|
||||||
{
|
{
|
||||||
u32 addr = MB_Read32(0);
|
u32 addr = MB_Read32(0);
|
||||||
|
@ -546,23 +737,124 @@ void DSi_NWifi::BMI_Command()
|
||||||
{
|
{
|
||||||
u32 len = MB_Read32(0);
|
u32 len = MB_Read32(0);
|
||||||
printf("BMI LZ write %08X\n", len);
|
printf("BMI LZ write %08X\n", len);
|
||||||
|
//FILE* f = fopen("wififirm.bin", "ab");
|
||||||
|
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
u8 val = Mailbox[0]->Read();
|
u8 val = Mailbox[0]->Read();
|
||||||
|
|
||||||
// TODO: do something with it!!
|
// TODO: do something with it!!
|
||||||
|
//fwrite(&val, 1, 1, f);
|
||||||
}
|
}
|
||||||
|
//fclose(f);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unknown BMI command %08X\n", cmd);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DSi_NWifi::WMI_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)
|
||||||
|
{
|
||||||
|
case 0x0002: // service connect
|
||||||
|
{
|
||||||
|
u16 svc_id = MB_Read16(0);
|
||||||
|
u16 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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unknown WMI command %04X\n", cmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MB_Drain(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSi_NWifi::SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl)
|
||||||
|
{
|
||||||
|
u32 wlen = 0;
|
||||||
|
|
||||||
|
Mailbox[4]->Write(ep); // eid
|
||||||
|
Mailbox[4]->Write(flags); // flags
|
||||||
|
MB_Write16(4, len); // payload length
|
||||||
|
MB_Write16(4, ctrl); // ctrl
|
||||||
|
wlen += 6;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
Mailbox[4]->Write(data[i]);
|
||||||
|
wlen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; wlen & 0x7F; wlen++)
|
||||||
|
Mailbox[4]->Write(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
u32 DSi_NWifi::WindowRead(u32 addr)
|
u32 DSi_NWifi::WindowRead(u32 addr)
|
||||||
{
|
{
|
||||||
printf("NWifi: window read %08X\n", addr);
|
printf("NWifi: window read %08X\n", addr);
|
||||||
|
|
||||||
|
if ((addr & 0xFFFF00) == 0x520000)
|
||||||
|
{
|
||||||
|
// RAM host interest area
|
||||||
|
// TODO: different base based on hardware version
|
||||||
|
|
||||||
|
switch (addr & 0xFF)
|
||||||
|
{
|
||||||
|
case 0x54:
|
||||||
|
// base address of EEPROM data
|
||||||
|
// TODO find what the actual address is!
|
||||||
|
return 0x1FFC00;
|
||||||
|
case 0x58: return EEPROMReady; // hax
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hax
|
||||||
|
if ((addr & 0x1FFC00) == 0x1FFC00)
|
||||||
|
{
|
||||||
|
return *(u32*)&EEPROM[addr & 0x3FF];
|
||||||
|
}
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x40EC: // chip ID
|
case 0x40EC: // chip ID
|
||||||
|
|
|
@ -33,11 +33,19 @@ public:
|
||||||
|
|
||||||
void ContinueTransfer();
|
void ContinueTransfer();
|
||||||
|
|
||||||
|
void SetIRQ_F1_Counter(u32 n);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 TransferCmd;
|
u32 TransferCmd;
|
||||||
u32 TransferAddr;
|
u32 TransferAddr;
|
||||||
u32 RemSize;
|
u32 RemSize;
|
||||||
|
|
||||||
|
void UpdateIRQ();
|
||||||
|
void UpdateIRQ_F1();
|
||||||
|
//void SetIRQ_F1_Counter(u32 n);
|
||||||
|
void ClearIRQ_F1_Counter(u32 n);
|
||||||
|
void SetIRQ_F1_CPU(u32 n);
|
||||||
|
|
||||||
u8 F0_Read(u32 addr);
|
u8 F0_Read(u32 addr);
|
||||||
void F0_Write(u32 addr, u8 val);
|
void F0_Write(u32 addr, u8 val);
|
||||||
|
|
||||||
|
@ -50,11 +58,28 @@ private:
|
||||||
void ReadBlock();
|
void ReadBlock();
|
||||||
void WriteBlock();
|
void WriteBlock();
|
||||||
|
|
||||||
|
void HandleCommand();
|
||||||
void BMI_Command();
|
void BMI_Command();
|
||||||
|
void WMI_Command();
|
||||||
|
|
||||||
|
void SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl);
|
||||||
|
|
||||||
u32 WindowRead(u32 addr);
|
u32 WindowRead(u32 addr);
|
||||||
void WindowWrite(u32 addr, u32 val);
|
void WindowWrite(u32 addr, u32 val);
|
||||||
|
|
||||||
|
u16 MB_Read16(int n)
|
||||||
|
{
|
||||||
|
u16 ret = Mailbox[n]->Read();
|
||||||
|
ret |= (Mailbox[n]->Read() << 8);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MB_Write16(int n, u16 val)
|
||||||
|
{
|
||||||
|
Mailbox[n]->Write(val & 0xFF); val >>= 8;
|
||||||
|
Mailbox[n]->Write(val & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
u32 MB_Read32(int n)
|
u32 MB_Read32(int n)
|
||||||
{
|
{
|
||||||
u32 ret = Mailbox[n]->Read();
|
u32 ret = Mailbox[n]->Read();
|
||||||
|
@ -72,9 +97,25 @@ private:
|
||||||
Mailbox[n]->Write(val & 0xFF);
|
Mailbox[n]->Write(val & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MB_Drain(int n)
|
||||||
|
{
|
||||||
|
while (!Mailbox[n]->IsEmpty()) Mailbox[n]->Read();
|
||||||
|
}
|
||||||
|
|
||||||
FIFO<u8>* Mailbox[8];
|
FIFO<u8>* Mailbox[8];
|
||||||
|
|
||||||
|
u8 F0_IRQEnable;
|
||||||
|
u8 F0_IRQStatus;
|
||||||
|
|
||||||
|
u8 F1_IRQEnable, F1_IRQEnable_CPU, F1_IRQEnable_Error, F1_IRQEnable_Counter;
|
||||||
|
u8 F1_IRQStatus, F1_IRQStatus_CPU, F1_IRQStatus_Error, F1_IRQStatus_Counter;
|
||||||
|
|
||||||
u32 WindowData, WindowReadAddr, WindowWriteAddr;
|
u32 WindowData, WindowReadAddr, WindowWriteAddr;
|
||||||
|
|
||||||
|
u8 EEPROM[0x400];
|
||||||
|
u32 EEPROMReady;
|
||||||
|
|
||||||
|
u32 BootPhase;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DSI_NWIFI_H
|
#endif // DSI_NWIFI_H
|
||||||
|
|
113
src/DSi_SD.cpp
113
src/DSi_SD.cpp
|
@ -73,6 +73,10 @@ void DSi_SDHost::Reset()
|
||||||
IRQStatus = 0;
|
IRQStatus = 0;
|
||||||
IRQMask = 0x8B7F031D;
|
IRQMask = 0x8B7F031D;
|
||||||
|
|
||||||
|
CardIRQStatus = 0;
|
||||||
|
CardIRQMask = 0xC007;
|
||||||
|
CardIRQCtl = 0;
|
||||||
|
|
||||||
DataCtl = 0;
|
DataCtl = 0;
|
||||||
Data32IRQ = 0;
|
Data32IRQ = 0;
|
||||||
DataMode = 0;
|
DataMode = 0;
|
||||||
|
@ -145,6 +149,25 @@ void DSi_SDHost::SetIRQ(u32 irq)
|
||||||
if (irq == 24 || irq == 25) UpdateData32IRQ();
|
if (irq == 24 || irq == 25) UpdateData32IRQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DSi_SDHost::SetCardIRQ()
|
||||||
|
{
|
||||||
|
if (!(CardIRQCtl & (1<<0))) return;
|
||||||
|
|
||||||
|
u16 oldflags = CardIRQStatus & ~CardIRQMask;
|
||||||
|
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
||||||
|
|
||||||
|
if (dev->IRQ) CardIRQStatus |= (1<<0);
|
||||||
|
else CardIRQStatus &= ~(1<<0);
|
||||||
|
|
||||||
|
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)
|
void DSi_SDHost::SendResponse(u32 val, bool last)
|
||||||
{
|
{
|
||||||
*(u32*)&ResponseBuffer[6] = *(u32*)&ResponseBuffer[4];
|
*(u32*)&ResponseBuffer[6] = *(u32*)&ResponseBuffer[4];
|
||||||
|
@ -166,10 +189,10 @@ void DSi_SDHost::FinishSend(u32 param)
|
||||||
//if (param & 0x2) host->SetIRQ(2);
|
//if (param & 0x2) host->SetIRQ(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSi_SDHost::SendData(u8* data, u32 len)
|
u32 DSi_SDHost::SendData(u8* data, u32 len)
|
||||||
{
|
{
|
||||||
printf("%s: data RX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask);
|
printf("%s: data RX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask);
|
||||||
if (len != BlockLen16) printf("!! BAD BLOCKLEN\n");
|
if (len != BlockLen16) { printf("!! BAD BLOCKLEN\n"); len = BlockLen16; }
|
||||||
|
|
||||||
bool last = (BlockCountInternal == 0);
|
bool last = (BlockCountInternal == 0);
|
||||||
|
|
||||||
|
@ -187,6 +210,8 @@ void DSi_SDHost::SendData(u8* data, u32 len)
|
||||||
u32 param = Num | (last << 1);
|
u32 param = Num | (last << 1);
|
||||||
NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer,
|
NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer,
|
||||||
false, 512, FinishSend, param);
|
false, 512, FinishSend, param);
|
||||||
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSi_SDHost::FinishReceive(u32 param)
|
void DSi_SDHost::FinishReceive(u32 param)
|
||||||
|
@ -200,16 +225,16 @@ void DSi_SDHost::FinishReceive(u32 param)
|
||||||
if (dev) dev->ContinueTransfer();
|
if (dev) dev->ContinueTransfer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSi_SDHost::ReceiveData(u8* data, u32 len)
|
u32 DSi_SDHost::ReceiveData(u8* data, u32 len)
|
||||||
{
|
{
|
||||||
printf("%s: data TX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask);
|
printf("%s: data TX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask);
|
||||||
if (len != BlockLen16) printf("!! BAD BLOCKLEN\n");
|
if (len != BlockLen16) { printf("!! BAD BLOCKLEN\n"); len = BlockLen16; }
|
||||||
|
|
||||||
u32 f = CurFIFO;
|
u32 f = CurFIFO;
|
||||||
if ((DataFIFO[f]->Level() << 1) < len)
|
if ((DataFIFO[f]->Level() << 1) < len)
|
||||||
{
|
{
|
||||||
printf("%s: FIFO not full enough for a transfer (%d / %d)\n", SD_DESC, DataFIFO[f]->Level()<<1, len);
|
printf("%s: FIFO not full enough for a transfer (%d / %d)\n", SD_DESC, DataFIFO[f]->Level()<<1, len);
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
||||||
|
@ -240,7 +265,13 @@ bool DSi_SDHost::ReceiveData(u8* data, u32 len)
|
||||||
BlockCountInternal--;
|
BlockCountInternal--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 DSi_SDHost::GetTransferrableLen(u32 len)
|
||||||
|
{
|
||||||
|
if (len > BlockLen16) len = BlockLen16; // checkme
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,6 +309,10 @@ u16 DSi_SDHost::Read(u32 addr)
|
||||||
|
|
||||||
case 0x02C: return 0; // TODO
|
case 0x02C: return 0; // TODO
|
||||||
|
|
||||||
|
case 0x034: return CardIRQCtl;
|
||||||
|
case 0x036: return CardIRQStatus;
|
||||||
|
case 0x038: return CardIRQMask;
|
||||||
|
|
||||||
case 0x030: // FIFO16
|
case 0x030: // FIFO16
|
||||||
{
|
{
|
||||||
// TODO: decrement BlockLen????
|
// TODO: decrement BlockLen????
|
||||||
|
@ -389,7 +424,7 @@ u32 DSi_SDHost::ReadFIFO32()
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
int morp = 0;
|
||||||
void DSi_SDHost::Write(u32 addr, u16 val)
|
void DSi_SDHost::Write(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
//if(Num)printf("SDIO WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
|
//if(Num)printf("SDIO WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
|
||||||
|
@ -470,6 +505,20 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 0x034:
|
||||||
|
CardIRQCtl = val & 0x0305;
|
||||||
|
printf("[%d] CardIRQCtl = %04X\n", Num, val);
|
||||||
|
SetCardIRQ();
|
||||||
|
return;
|
||||||
|
case 0x036:
|
||||||
|
CardIRQStatus &= val;
|
||||||
|
return;
|
||||||
|
case 0x038:
|
||||||
|
CardIRQMask = val & 0xC007;
|
||||||
|
printf("[%d] CardIRQMask = %04X\n", Num, val);
|
||||||
|
SetCardIRQ();
|
||||||
|
return;
|
||||||
|
|
||||||
case 0x0D8:
|
case 0x0D8:
|
||||||
DataCtl = (val & 0x0022);
|
DataCtl = (val & 0x0022);
|
||||||
DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1);
|
DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1);
|
||||||
|
@ -729,42 +778,54 @@ void DSi_MMCStorage::ContinueTransfer()
|
||||||
{
|
{
|
||||||
if (RWCommand == 0) return;
|
if (RWCommand == 0) return;
|
||||||
|
|
||||||
|
u32 len = 0;
|
||||||
|
|
||||||
switch (RWCommand)
|
switch (RWCommand)
|
||||||
{
|
{
|
||||||
case 18:
|
case 18:
|
||||||
ReadBlock(RWAddress);
|
len = ReadBlock(RWAddress);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 25:
|
case 25:
|
||||||
WriteBlock(RWAddress);
|
len = WriteBlock(RWAddress);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWAddress += BlockSize;
|
RWAddress += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSi_MMCStorage::ReadBlock(u64 addr)
|
u32 DSi_MMCStorage::ReadBlock(u64 addr)
|
||||||
{
|
{
|
||||||
if (!File) return;
|
|
||||||
|
|
||||||
printf("SD/MMC: reading block @ %08X, len=%08X\n", addr, BlockSize);
|
printf("SD/MMC: reading block @ %08X, len=%08X\n", addr, BlockSize);
|
||||||
|
|
||||||
u8 data[0x200];
|
u32 len = BlockSize;
|
||||||
fseek(File, addr, SEEK_SET);
|
len = Host->GetTransferrableLen(len);
|
||||||
fread(data, 1, BlockSize, File);
|
|
||||||
Host->SendData(data, BlockSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSi_MMCStorage::WriteBlock(u64 addr)
|
|
||||||
{
|
|
||||||
if (!File) return;
|
|
||||||
|
|
||||||
printf("SD/MMC: write block @ %08X, len=%08X\n", addr, BlockSize);
|
|
||||||
|
|
||||||
u8 data[0x200];
|
u8 data[0x200];
|
||||||
if (Host->ReceiveData(data, BlockSize))
|
if (File)
|
||||||
{
|
{
|
||||||
fseek(File, addr, SEEK_SET);
|
fseek(File, addr, SEEK_SET);
|
||||||
fwrite(data, 1, BlockSize, File);
|
fread(data, 1, len, File);
|
||||||
}
|
}
|
||||||
|
return Host->SendData(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 DSi_MMCStorage::WriteBlock(u64 addr)
|
||||||
|
{
|
||||||
|
printf("SD/MMC: write block @ %08X, len=%08X\n", addr, BlockSize);
|
||||||
|
|
||||||
|
u32 len = BlockSize;
|
||||||
|
len = Host->GetTransferrableLen(len);
|
||||||
|
|
||||||
|
u8 data[0x200];
|
||||||
|
if (len = Host->ReceiveData(data, len))
|
||||||
|
{
|
||||||
|
if (File)
|
||||||
|
{
|
||||||
|
fseek(File, addr, SEEK_SET);
|
||||||
|
fwrite(data, 1, len, File);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
19
src/DSi_SD.h
19
src/DSi_SD.h
|
@ -39,8 +39,11 @@ public:
|
||||||
static void FinishSend(u32 param);
|
static void FinishSend(u32 param);
|
||||||
static void FinishReceive(u32 param);
|
static void FinishReceive(u32 param);
|
||||||
void SendResponse(u32 val, bool last);
|
void SendResponse(u32 val, bool last);
|
||||||
void SendData(u8* data, u32 len);
|
u32 SendData(u8* data, u32 len);
|
||||||
bool ReceiveData(u8* data, u32 len);
|
u32 ReceiveData(u8* data, u32 len);
|
||||||
|
u32 GetTransferrableLen(u32 len);
|
||||||
|
|
||||||
|
void SetCardIRQ();
|
||||||
|
|
||||||
u16 Read(u32 addr);
|
u16 Read(u32 addr);
|
||||||
void Write(u32 addr, u16 val);
|
void Write(u32 addr, u16 val);
|
||||||
|
@ -58,6 +61,10 @@ private:
|
||||||
u32 IRQStatus; // IF
|
u32 IRQStatus; // IF
|
||||||
u32 IRQMask; // ~IE
|
u32 IRQMask; // ~IE
|
||||||
|
|
||||||
|
u16 CardIRQStatus;
|
||||||
|
u16 CardIRQMask;
|
||||||
|
u16 CardIRQCtl;
|
||||||
|
|
||||||
u16 DataCtl;
|
u16 DataCtl;
|
||||||
u16 Data32IRQ;
|
u16 Data32IRQ;
|
||||||
u32 DataMode; // 0=16bit 1=32bit
|
u32 DataMode; // 0=16bit 1=32bit
|
||||||
|
@ -83,12 +90,14 @@ private:
|
||||||
class DSi_SDDevice
|
class DSi_SDDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DSi_SDDevice(DSi_SDHost* host) { Host = host; }
|
DSi_SDDevice(DSi_SDHost* host) { Host = host; IRQ = false; }
|
||||||
~DSi_SDDevice() {}
|
~DSi_SDDevice() {}
|
||||||
|
|
||||||
virtual void SendCMD(u8 cmd, u32 param) = 0;
|
virtual void SendCMD(u8 cmd, u32 param) = 0;
|
||||||
virtual void ContinueTransfer() = 0;
|
virtual void ContinueTransfer() = 0;
|
||||||
|
|
||||||
|
bool IRQ;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DSi_SDHost* Host;
|
DSi_SDHost* Host;
|
||||||
};
|
};
|
||||||
|
@ -127,8 +136,8 @@ private:
|
||||||
|
|
||||||
void SetState(u32 state) { CSR &= ~(0xF << 9); CSR |= (state << 9); }
|
void SetState(u32 state) { CSR &= ~(0xF << 9); CSR |= (state << 9); }
|
||||||
|
|
||||||
void ReadBlock(u64 addr);
|
u32 ReadBlock(u64 addr);
|
||||||
void WriteBlock(u64 addr);
|
u32 WriteBlock(u64 addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DSI_SD_H
|
#endif // DSI_SD_H
|
||||||
|
|
|
@ -89,6 +89,15 @@ public:
|
||||||
return Entries[ReadPos];
|
return Entries[ReadPos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T Peek(u32 offset)
|
||||||
|
{
|
||||||
|
u32 pos = ReadPos + offset;
|
||||||
|
if (pos >= NumEntries)
|
||||||
|
pos -= NumEntries;
|
||||||
|
|
||||||
|
return Entries[pos];
|
||||||
|
}
|
||||||
|
|
||||||
u32 Level() { return NumOccupied; }
|
u32 Level() { return NumOccupied; }
|
||||||
bool IsEmpty() { return NumOccupied == 0; }
|
bool IsEmpty() { return NumOccupied == 0; }
|
||||||
bool IsFull() { return NumOccupied >= NumEntries; }
|
bool IsFull() { return NumOccupied >= NumEntries; }
|
||||||
|
|
|
@ -45,6 +45,7 @@ enum
|
||||||
// DSi
|
// DSi
|
||||||
Event_DSi_SDMMCTransfer,
|
Event_DSi_SDMMCTransfer,
|
||||||
Event_DSi_SDIOTransfer,
|
Event_DSi_SDIOTransfer,
|
||||||
|
Event_DSi_NWifi,
|
||||||
|
|
||||||
Event_MAX
|
Event_MAX
|
||||||
};
|
};
|
||||||
|
|
|
@ -225,6 +225,7 @@ void SetupDirectBoot()
|
||||||
u8 GetConsoleType() { return Firmware[0x1D]; }
|
u8 GetConsoleType() { return Firmware[0x1D]; }
|
||||||
u8 GetWifiVersion() { return Firmware[0x2F]; }
|
u8 GetWifiVersion() { return Firmware[0x2F]; }
|
||||||
u8 GetRFVersion() { return Firmware[0x40]; }
|
u8 GetRFVersion() { return Firmware[0x40]; }
|
||||||
|
u8* GetWifiMAC() { return &Firmware[0x36]; }
|
||||||
|
|
||||||
u8 Read()
|
u8 Read()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue