make FIFO size static whene possible

This commit is contained in:
RSDuck 2020-12-30 23:37:46 +01:00
parent 162a0f4fb6
commit fa4363ede6
9 changed files with 409 additions and 367 deletions

View File

@ -38,8 +38,8 @@ bool OutputFlush;
u32 InputDMASize, OutputDMASize; u32 InputDMASize, OutputDMASize;
u32 AESMode; u32 AESMode;
FIFO<u32>* InputFIFO; FIFO<u32, 16> InputFIFO;
FIFO<u32>* OutputFIFO; FIFO<u32, 16> OutputFIFO;
u8 IV[16]; u8 IV[16];
@ -91,9 +91,6 @@ void ROL16(u8* val, u32 n)
bool Init() bool Init()
{ {
InputFIFO = new FIFO<u32>(16);
OutputFIFO = new FIFO<u32>(16);
const u8 zero[16] = {0}; const u8 zero[16] = {0};
AES_init_ctx_iv(&Ctx, zero, zero); AES_init_ctx_iv(&Ctx, zero, zero);
@ -102,8 +99,6 @@ bool Init()
void DeInit() void DeInit()
{ {
delete InputFIFO;
delete OutputFIFO;
} }
void Reset() void Reset()
@ -119,8 +114,8 @@ void Reset()
OutputDMASize = 0; OutputDMASize = 0;
AESMode = 0; AESMode = 0;
InputFIFO->Clear(); InputFIFO.Clear();
OutputFIFO->Clear(); OutputFIFO.Clear();
memset(IV, 0, sizeof(IV)); memset(IV, 0, sizeof(IV));
@ -164,10 +159,10 @@ void ProcessBlock_CCM_Decrypt()
u8 data[16]; u8 data[16];
u8 data_rev[16]; u8 data_rev[16];
*(u32*)&data[0] = InputFIFO->Read(); *(u32*)&data[0] = InputFIFO.Read();
*(u32*)&data[4] = InputFIFO->Read(); *(u32*)&data[4] = InputFIFO.Read();
*(u32*)&data[8] = InputFIFO->Read(); *(u32*)&data[8] = InputFIFO.Read();
*(u32*)&data[12] = InputFIFO->Read(); *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CCM: "); _printhex2(data, 16); //printf("AES-CCM: "); _printhex2(data, 16);
@ -181,10 +176,10 @@ void ProcessBlock_CCM_Decrypt()
//printf(" -> "); _printhex2(data, 16); //printf(" -> "); _printhex2(data, 16);
OutputFIFO->Write(*(u32*)&data[0]); OutputFIFO.Write(*(u32*)&data[0]);
OutputFIFO->Write(*(u32*)&data[4]); OutputFIFO.Write(*(u32*)&data[4]);
OutputFIFO->Write(*(u32*)&data[8]); OutputFIFO.Write(*(u32*)&data[8]);
OutputFIFO->Write(*(u32*)&data[12]); OutputFIFO.Write(*(u32*)&data[12]);
} }
void ProcessBlock_CCM_Encrypt() void ProcessBlock_CCM_Encrypt()
@ -192,10 +187,10 @@ void ProcessBlock_CCM_Encrypt()
u8 data[16]; u8 data[16];
u8 data_rev[16]; u8 data_rev[16];
*(u32*)&data[0] = InputFIFO->Read(); *(u32*)&data[0] = InputFIFO.Read();
*(u32*)&data[4] = InputFIFO->Read(); *(u32*)&data[4] = InputFIFO.Read();
*(u32*)&data[8] = InputFIFO->Read(); *(u32*)&data[8] = InputFIFO.Read();
*(u32*)&data[12] = InputFIFO->Read(); *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CCM: "); _printhex2(data, 16); //printf("AES-CCM: "); _printhex2(data, 16);
@ -209,10 +204,10 @@ void ProcessBlock_CCM_Encrypt()
//printf(" -> "); _printhex2(data, 16); //printf(" -> "); _printhex2(data, 16);
OutputFIFO->Write(*(u32*)&data[0]); OutputFIFO.Write(*(u32*)&data[0]);
OutputFIFO->Write(*(u32*)&data[4]); OutputFIFO.Write(*(u32*)&data[4]);
OutputFIFO->Write(*(u32*)&data[8]); OutputFIFO.Write(*(u32*)&data[8]);
OutputFIFO->Write(*(u32*)&data[12]); OutputFIFO.Write(*(u32*)&data[12]);
} }
void ProcessBlock_CTR() void ProcessBlock_CTR()
@ -220,10 +215,10 @@ void ProcessBlock_CTR()
u8 data[16]; u8 data[16];
u8 data_rev[16]; u8 data_rev[16];
*(u32*)&data[0] = InputFIFO->Read(); *(u32*)&data[0] = InputFIFO.Read();
*(u32*)&data[4] = InputFIFO->Read(); *(u32*)&data[4] = InputFIFO.Read();
*(u32*)&data[8] = InputFIFO->Read(); *(u32*)&data[8] = InputFIFO.Read();
*(u32*)&data[12] = InputFIFO->Read(); *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CTR: "); _printhex2(data, 16); //printf("AES-CTR: "); _printhex2(data, 16);
@ -233,10 +228,10 @@ void ProcessBlock_CTR()
//printf(" -> "); _printhex(data, 16); //printf(" -> "); _printhex(data, 16);
OutputFIFO->Write(*(u32*)&data[0]); OutputFIFO.Write(*(u32*)&data[0]);
OutputFIFO->Write(*(u32*)&data[4]); OutputFIFO.Write(*(u32*)&data[4]);
OutputFIFO->Write(*(u32*)&data[8]); OutputFIFO.Write(*(u32*)&data[8]);
OutputFIFO->Write(*(u32*)&data[12]); OutputFIFO.Write(*(u32*)&data[12]);
} }
@ -244,8 +239,8 @@ u32 ReadCnt()
{ {
u32 ret = Cnt; u32 ret = Cnt;
ret |= InputFIFO->Level(); ret |= InputFIFO.Level();
ret |= (OutputFIFO->Level() << 5); ret |= (OutputFIFO.Level() << 5);
return ret; return ret;
} }
@ -341,9 +336,9 @@ void WriteBlkCnt(u32 val)
u32 ReadOutputFIFO() u32 ReadOutputFIFO()
{ {
if (OutputFIFO->IsEmpty()) printf("!!! AES OUTPUT FIFO EMPTY\n"); if (OutputFIFO.IsEmpty()) printf("!!! AES OUTPUT FIFO EMPTY\n");
u32 ret = OutputFIFO->Read(); u32 ret = OutputFIFO.Read();
if (Cnt & (1<<31)) if (Cnt & (1<<31))
{ {
@ -352,17 +347,17 @@ u32 ReadOutputFIFO()
} }
else else
{ {
if (OutputFIFO->Level() > 0) if (OutputFIFO.Level() > 0)
DSi::CheckNDMAs(1, 0x2B); DSi::CheckNDMAs(1, 0x2B);
else else
DSi::StopNDMAs(1, 0x2B); DSi::StopNDMAs(1, 0x2B);
if (OutputMACDue && OutputFIFO->Level() <= 12) if (OutputMACDue && OutputFIFO.Level() <= 12)
{ {
OutputFIFO->Write(*(u32*)&OutputMAC[0]); OutputFIFO.Write(*(u32*)&OutputMAC[0]);
OutputFIFO->Write(*(u32*)&OutputMAC[4]); OutputFIFO.Write(*(u32*)&OutputMAC[4]);
OutputFIFO->Write(*(u32*)&OutputMAC[8]); OutputFIFO.Write(*(u32*)&OutputMAC[8]);
OutputFIFO->Write(*(u32*)&OutputMAC[12]); OutputFIFO.Write(*(u32*)&OutputMAC[12]);
OutputMACDue = false; OutputMACDue = false;
} }
} }
@ -374,9 +369,9 @@ void WriteInputFIFO(u32 val)
{ {
// TODO: add some delay to processing // TODO: add some delay to processing
if (InputFIFO->IsFull()) printf("!!! AES INPUT FIFO FULL\n"); if (InputFIFO.IsFull()) printf("!!! AES INPUT FIFO FULL\n");
InputFIFO->Write(val); InputFIFO.Write(val);
if (!(Cnt & (1<<31))) return; if (!(Cnt & (1<<31))) return;
@ -387,7 +382,7 @@ void CheckInputDMA()
{ {
if (RemBlocks == 0) return; if (RemBlocks == 0) return;
if (InputFIFO->Level() <= InputDMASize) if (InputFIFO.Level() <= InputDMASize)
{ {
// trigger input DMA // trigger input DMA
DSi::CheckNDMAs(1, 0x2A); DSi::CheckNDMAs(1, 0x2A);
@ -398,7 +393,7 @@ void CheckInputDMA()
void CheckOutputDMA() void CheckOutputDMA()
{ {
if (OutputFIFO->Level() >= OutputDMASize) if (OutputFIFO.Level() >= OutputDMASize)
{ {
// trigger output DMA // trigger output DMA
DSi::CheckNDMAs(1, 0x2B); DSi::CheckNDMAs(1, 0x2B);
@ -407,7 +402,7 @@ void CheckOutputDMA()
void Update() void Update()
{ {
while (InputFIFO->Level() >= 4 && OutputFIFO->Level() <= 12 && RemBlocks > 0) while (InputFIFO.Level() >= 4 && OutputFIFO.Level() <= 12 && RemBlocks > 0)
{ {
switch (AESMode) switch (AESMode)
{ {
@ -463,7 +458,7 @@ void Update()
if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES); if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES);
DSi::StopNDMAs(1, 0x2A); DSi::StopNDMAs(1, 0x2A);
if (OutputFIFO->Level() > 0) if (!OutputFIFO.IsEmpty())
DSi::CheckNDMAs(1, 0x2B); DSi::CheckNDMAs(1, 0x2B);
else else
DSi::StopNDMAs(1, 0x2B); DSi::StopNDMAs(1, 0x2B);

View File

@ -116,18 +116,20 @@ const u8 CIS1[256] =
DSi_NWifi* Ctx = nullptr; DSi_NWifi* Ctx = nullptr;
DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host) DSi_NWifi::DSi_NWifi(DSi_SDHost* host)
{ : DSi_SDDevice(host),
Mailbox
{
// HACK // HACK
// the mailboxes are supposed to be 0x80 bytes // the mailboxes are supposed to be 0x80 bytes
// however, as we do things instantly, emulating this is meaningless // however, as we do things instantly, emulating this is meaningless
// and only adds complication // and only adds complication
for (int i = 0; i < 8; i++) DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600),
Mailbox[i] = new FIFO<u8>(0x600);//0x80); DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600),
// mailbox 8: extra mailbox acting as a bigger RX buffer
// extra mailbox acting as a bigger RX buffer DynamicFIFO<u8>(0x8000)
Mailbox[8] = new FIFO<u8>(0x8000); }
{
// this seems to control whether the firmware upload is done // this seems to control whether the firmware upload is done
EEPROMReady = 0; EEPROMReady = 0;
@ -136,9 +138,6 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
DSi_NWifi::~DSi_NWifi() DSi_NWifi::~DSi_NWifi()
{ {
for (int i = 0; i < 9; i++)
delete Mailbox[i];
NDS::CancelEvent(NDS::Event_DSi_NWifi); NDS::CancelEvent(NDS::Event_DSi_NWifi);
Ctx = nullptr; Ctx = nullptr;
} }
@ -159,7 +158,7 @@ void DSi_NWifi::Reset()
WindowWriteAddr = 0; WindowWriteAddr = 0;
for (int i = 0; i < 9; i++) for (int i = 0; i < 9; i++)
Mailbox[i]->Clear(); Mailbox[i].Clear();
u8* mac = SPI_Firmware::GetWifiMAC(); u8* mac = SPI_Firmware::GetWifiMAC();
printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
@ -250,10 +249,10 @@ void DSi_NWifi::UpdateIRQ_F1()
{ {
F1_IRQStatus = 0; F1_IRQStatus = 0;
if (!Mailbox[4]->IsEmpty()) F1_IRQStatus |= (1<<0); if (!Mailbox[4].IsEmpty()) F1_IRQStatus |= (1<<0);
if (!Mailbox[5]->IsEmpty()) F1_IRQStatus |= (1<<1); if (!Mailbox[5].IsEmpty()) F1_IRQStatus |= (1<<1);
if (!Mailbox[6]->IsEmpty()) F1_IRQStatus |= (1<<2); if (!Mailbox[6].IsEmpty()) F1_IRQStatus |= (1<<2);
if (!Mailbox[7]->IsEmpty()) F1_IRQStatus |= (1<<3); if (!Mailbox[7].IsEmpty()) F1_IRQStatus |= (1<<3);
if (F1_IRQStatus_Counter & F1_IRQEnable_Counter) F1_IRQStatus |= (1<<4); 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_CPU & F1_IRQEnable_CPU) F1_IRQStatus |= (1<<6);
if (F1_IRQStatus_Error & F1_IRQEnable_Error) F1_IRQStatus |= (1<<7); if (F1_IRQStatus_Error & F1_IRQEnable_Error) F1_IRQStatus |= (1<<7);
@ -337,26 +336,26 @@ u8 DSi_NWifi::F1_Read(u32 addr)
{ {
if (addr < 0x100) if (addr < 0x100)
{ {
u8 ret = Mailbox[4]->Read(); u8 ret = Mailbox[4].Read();
if (addr == 0xFF) DrainRXBuffer(); if (addr == 0xFF) DrainRXBuffer();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x200) else if (addr < 0x200)
{ {
u8 ret = Mailbox[5]->Read(); u8 ret = Mailbox[5].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x300) else if (addr < 0x300)
{ {
u8 ret = Mailbox[6]->Read(); u8 ret = Mailbox[6].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x400) else if (addr < 0x400)
{ {
u8 ret = Mailbox[7]->Read(); u8 ret = Mailbox[7].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
@ -373,18 +372,18 @@ u8 DSi_NWifi::F1_Read(u32 addr)
{ {
u8 ret = 0; u8 ret = 0;
if (Mailbox[4]->Level() >= 4) ret |= (1<<0); if (Mailbox[4].Level() >= 4) ret |= (1<<0);
if (Mailbox[5]->Level() >= 4) ret |= (1<<1); if (Mailbox[5].Level() >= 4) ret |= (1<<1);
if (Mailbox[6]->Level() >= 4) ret |= (1<<2); if (Mailbox[6].Level() >= 4) ret |= (1<<2);
if (Mailbox[7]->Level() >= 4) ret |= (1<<3); if (Mailbox[7].Level() >= 4) ret |= (1<<3);
return ret; return ret;
} }
case 0x00408: return Mailbox[4]->Peek(0); case 0x00408: return Mailbox[4].Peek(0);
case 0x00409: return Mailbox[4]->Peek(1); case 0x00409: return Mailbox[4].Peek(1);
case 0x0040A: return Mailbox[4]->Peek(2); case 0x0040A: return Mailbox[4].Peek(2);
case 0x0040B: return Mailbox[4]->Peek(3); case 0x0040B: return Mailbox[4].Peek(3);
case 0x00418: return F1_IRQEnable; case 0x00418: return F1_IRQEnable;
case 0x00419: return F1_IRQEnable_CPU; case 0x00419: return F1_IRQEnable_CPU;
@ -403,32 +402,32 @@ u8 DSi_NWifi::F1_Read(u32 addr)
} }
else if (addr < 0x1000) else if (addr < 0x1000)
{ {
u8 ret = Mailbox[4]->Read(); u8 ret = Mailbox[4].Read();
if (addr == 0xFFF) DrainRXBuffer(); if (addr == 0xFFF) DrainRXBuffer();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x1800) else if (addr < 0x1800)
{ {
u8 ret = Mailbox[5]->Read(); u8 ret = Mailbox[5].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x2000) else if (addr < 0x2000)
{ {
u8 ret = Mailbox[6]->Read(); u8 ret = Mailbox[6].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x2800) else if (addr < 0x2800)
{ {
u8 ret = Mailbox[7]->Read(); u8 ret = Mailbox[7].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else else
{ {
u8 ret = Mailbox[4]->Read(); u8 ret = Mailbox[4].Read();
if (addr == 0x3FFF) DrainRXBuffer(); if (addr == 0x3FFF) DrainRXBuffer();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
@ -442,30 +441,30 @@ void DSi_NWifi::F1_Write(u32 addr, u8 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) HandleCommand(); if (addr == 0xFF) HandleCommand();
UpdateIRQ_F1(); 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(); 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(); 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(); UpdateIRQ_F1();
return; return;
} }
@ -505,37 +504,37 @@ void DSi_NWifi::F1_Write(u32 addr, u8 val)
} }
else if (addr < 0x1000) else if (addr < 0x1000)
{ {
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) HandleCommand(); if (addr == 0xFFF) HandleCommand();
UpdateIRQ_F1(); 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(); 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(); 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(); 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) HandleCommand(); // CHECKME if (addr == 0x3FFF) HandleCommand(); // CHECKME
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
@ -750,7 +749,7 @@ void DSi_NWifi::BMI_Command()
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!!
} }
@ -804,7 +803,7 @@ void DSi_NWifi::BMI_Command()
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); //fwrite(&val, 1, 1, f);
@ -873,7 +872,7 @@ void DSi_NWifi::HTC_Command()
printf("unknown HTC command %04X\n", cmd); printf("unknown HTC command %04X\n", cmd);
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
printf("%02X ", Mailbox[0]->Read()); printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n"); if ((i&0xF)==0xF) printf("\n");
} }
printf("\n"); printf("\n");
@ -926,7 +925,7 @@ void DSi_NWifi::WMI_Command()
case 0x0004: // synchronize case 0x0004: // synchronize
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
@ -944,8 +943,8 @@ void DSi_NWifi::WMI_Command()
u32 legacy = MB_Read32(0); u32 legacy = MB_Read32(0);
u32 scantime = MB_Read32(0); u32 scantime = MB_Read32(0);
u32 forceinterval = MB_Read32(0); u32 forceinterval = MB_Read32(0);
u8 scantype = Mailbox[0]->Read(); u8 scantype = Mailbox[0].Read();
u8 nchannels = 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", printf("WMI: start scan, forceFG=%d, legacy=%d, scanTime=%d, interval=%d, scanType=%d, chan=%d\n",
forcefg, legacy, scantime, forceinterval, scantype, nchannels); forcefg, legacy, scantime, forceinterval, scantype, nchannels);
@ -969,10 +968,10 @@ void DSi_NWifi::WMI_Command()
case 0x0009: // set BSS filter case 0x0009: // set BSS filter
{ {
// TODO: do something with the params!! // TODO: do something with the params!!
u8 bssfilter = Mailbox[0]->Read(); u8 bssfilter = Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
u32 iemask = MB_Read32(0); u32 iemask = MB_Read32(0);
printf("WMI: set BSS filter, filter=%02X, iemask=%08X\n", bssfilter, iemask); printf("WMI: set BSS filter, filter=%02X, iemask=%08X\n", bssfilter, iemask);
@ -981,13 +980,13 @@ void DSi_NWifi::WMI_Command()
case 0x000A: // set probed BSSID case 0x000A: // set probed BSSID
{ {
u8 id = Mailbox[0]->Read(); u8 id = Mailbox[0].Read();
u8 flags = Mailbox[0]->Read(); u8 flags = Mailbox[0].Read();
u8 len = Mailbox[0]->Read(); u8 len = Mailbox[0].Read();
char ssid[33] = {0}; char ssid[33] = {0};
for (int i = 0; i < len && i < 32; i++) for (int i = 0; i < len && i < 32; i++)
ssid[i] = Mailbox[0]->Read(); ssid[i] = Mailbox[0].Read();
// TODO: store it somewhere // TODO: store it somewhere
printf("WMI: set probed SSID: id=%d, flags=%02X, len=%d, SSID=%s\n", id, flags, len, ssid); printf("WMI: set probed SSID: id=%d, flags=%02X, len=%d, SSID=%s\n", id, flags, len, ssid);
@ -996,7 +995,7 @@ void DSi_NWifi::WMI_Command()
case 0x000D: // set disconnect timeout case 0x000D: // set disconnect timeout
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
@ -1018,10 +1017,10 @@ void DSi_NWifi::WMI_Command()
case 0x0011: // set channel params case 0x0011: // set channel params
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
u8 scan = Mailbox[0]->Read(); u8 scan = Mailbox[0].Read();
u8 phymode = Mailbox[0]->Read(); u8 phymode = Mailbox[0].Read();
u8 len = Mailbox[0]->Read(); u8 len = Mailbox[0].Read();
u16 channels[32]; u16 channels[32];
for (int i = 0; i < len && i < 32; i++) for (int i = 0; i < len && i < 32; i++)
@ -1037,13 +1036,13 @@ void DSi_NWifi::WMI_Command()
case 0x0012: // set power mode case 0x0012: // set power mode
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
case 0x0017: // dummy? case 0x0017: // dummy?
Mailbox[0]->Read(); Mailbox[0].Read();
break; break;
case 0x0022: // set error bitmask case 0x0022: // set error bitmask
@ -1080,14 +1079,14 @@ void DSi_NWifi::WMI_Command()
case 0x003D: // set keepalive interval case 0x003D: // set keepalive interval
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
case 0x0041: // 'WMI_SET_WSC_STATUS_CMD' case 0x0041: // 'WMI_SET_WSC_STATUS_CMD'
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
@ -1102,8 +1101,8 @@ void DSi_NWifi::WMI_Command()
{ {
MB_Read32(0); MB_Read32(0);
MB_Read32(0); MB_Read32(0);
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
} }
break; break;
@ -1116,9 +1115,9 @@ void DSi_NWifi::WMI_Command()
case 0xF000: // set bitrate case 0xF000: // set bitrate
{ {
// TODO! // TODO!
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
} }
break; break;
@ -1126,7 +1125,7 @@ void DSi_NWifi::WMI_Command()
printf("unknown WMI command %04X (header: %04X:%04X:%04X)\n", cmd, h0, len, h2); printf("unknown WMI command %04X (header: %04X:%04X:%04X)\n", cmd, h0, len, h2);
for (int i = 0; i < len-2; i++) for (int i = 0; i < len-2; i++)
{ {
printf("%02X ", Mailbox[0]->Read()); printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n"); if ((i&0xF)==0xF) printf("\n");
} }
printf("\n"); printf("\n");
@ -1142,18 +1141,18 @@ void DSi_NWifi::WMI_Command()
void DSi_NWifi::WMI_ConnectToNetwork() void DSi_NWifi::WMI_ConnectToNetwork()
{ {
u8 type = Mailbox[0]->Read(); u8 type = Mailbox[0].Read();
u8 auth11 = Mailbox[0]->Read(); u8 auth11 = Mailbox[0].Read();
u8 auth = Mailbox[0]->Read(); u8 auth = Mailbox[0].Read();
u8 pCryptoType = Mailbox[0]->Read(); u8 pCryptoType = Mailbox[0].Read();
u8 pCryptoLen = Mailbox[0]->Read(); u8 pCryptoLen = Mailbox[0].Read();
u8 gCryptoType = Mailbox[0]->Read(); u8 gCryptoType = Mailbox[0].Read();
u8 gCryptoLen = Mailbox[0]->Read(); u8 gCryptoLen = Mailbox[0].Read();
u8 ssidLen = Mailbox[0]->Read(); u8 ssidLen = Mailbox[0].Read();
char ssid[33] = {0}; char ssid[33] = {0};
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
ssid[i] = Mailbox[0]->Read(); ssid[i] = Mailbox[0].Read();
if (ssidLen <= 32) if (ssidLen <= 32)
ssid[ssidLen] = '\0'; ssid[ssidLen] = '\0';
@ -1219,11 +1218,11 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
{ {
printf("WMI: data sync\n"); printf("WMI: data sync\n");
/*Mailbox[8]->Write(2); // eid /*Mailbox[8].Write(2); // eid
Mailbox[8]->Write(0x00); // flags Mailbox[8].Write(0x00); // flags
MB_Write16(8, 2); // data length MB_Write16(8, 2); // data length
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
MB_Write16(8, 0x0200); // MB_Write16(8, 0x0200); //
DrainRXBuffer();*/ DrainRXBuffer();*/
@ -1235,7 +1234,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
printf("WMI: special frame %04X len=%d\n", hdr, len); printf("WMI: special frame %04X len=%d\n", hdr, len);
for (int i = 0; i < len-2; i++) for (int i = 0; i < len-2; i++)
{ {
printf("%02X ", Mailbox[0]->Read()); printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n"); if ((i&0xF)==0xF) printf("\n");
} }
printf("\n"); printf("\n");
@ -1279,7 +1278,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
*(u16*)&LANBuffer[12] = ethertype; // type *(u16*)&LANBuffer[12] = ethertype; // type
for (int i = 0; i < lan_len-14; i++) for (int i = 0; i < lan_len-14; i++)
{ {
LANBuffer[14+i] = Mailbox[0]->Read(); LANBuffer[14+i] = Mailbox[0].Read();
} }
/*for (int i = 0; i < lan_len; i++) /*for (int i = 0; i < lan_len; i++)
@ -1294,73 +1293,73 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len) void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len)
{ {
if (!Mailbox[8]->CanFit(6+len+2+8)) if (!Mailbox[8].CanFit(6+len+2+8))
{ {
printf("NWifi: !! not enough space in RX buffer for WMI event %04X\n", id); printf("NWifi: !! not enough space in RX buffer for WMI event %04X\n", id);
return; return;
} }
Mailbox[8]->Write(ep); // eid Mailbox[8].Write(ep); // eid
Mailbox[8]->Write(0x02); // flags (trailer) Mailbox[8].Write(0x02); // flags (trailer)
MB_Write16(8, len+2+8); // data length (plus event ID and trailer) MB_Write16(8, len+2+8); // data length (plus event ID and trailer)
Mailbox[8]->Write(8); // trailer length Mailbox[8].Write(8); // trailer length
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
MB_Write16(8, id); // event ID MB_Write16(8, id); // event ID
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
Mailbox[8]->Write(data[i]); Mailbox[8].Write(data[i]);
} }
// trailer // trailer
Mailbox[8]->Write(0x02); Mailbox[8].Write(0x02);
Mailbox[8]->Write(0x06); 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);
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(); DrainRXBuffer();
} }
void DSi_NWifi::SendWMIAck(u8 ep) void DSi_NWifi::SendWMIAck(u8 ep)
{ {
if (!Mailbox[8]->CanFit(6+12)) if (!Mailbox[8].CanFit(6+12))
{ {
printf("NWifi: !! not enough space in RX buffer for WMI ack (ep #%d)\n", ep); printf("NWifi: !! not enough space in RX buffer for WMI ack (ep #%d)\n", ep);
return; return;
} }
Mailbox[8]->Write(0); // eid Mailbox[8].Write(0); // eid
Mailbox[8]->Write(0x02); // flags (trailer) Mailbox[8].Write(0x02); // flags (trailer)
MB_Write16(8, 0xC); // data length (plus trailer) MB_Write16(8, 0xC); // data length (plus trailer)
Mailbox[8]->Write(0xC); // trailer length Mailbox[8].Write(0xC); // trailer length
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
// credit report // credit report
Mailbox[8]->Write(0x01); Mailbox[8].Write(0x01);
Mailbox[8]->Write(0x02); Mailbox[8].Write(0x02);
Mailbox[8]->Write(ep); Mailbox[8].Write(ep);
Mailbox[8]->Write(0x01); Mailbox[8].Write(0x01);
// lookahead // lookahead
Mailbox[8]->Write(0x02); Mailbox[8].Write(0x02);
Mailbox[8]->Write(0x06); 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);
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(); DrainRXBuffer();
} }
void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len) void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
{ {
if (!Mailbox[8]->CanFit(6+len+2+16)) if (!Mailbox[8].CanFit(6+len+2+16))
{ {
printf("NWifi: !! not enough space in RX buffer for WMI BSSINFO event\n"); printf("NWifi: !! not enough space in RX buffer for WMI BSSINFO event\n");
return; return;
@ -1369,16 +1368,16 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
// TODO: check when version>=2 frame type is used? // TODO: check when version>=2 frame type is used?
// I observed the version<2 variant on my DSi // I observed the version<2 variant on my DSi
Mailbox[8]->Write(1); // eid Mailbox[8].Write(1); // eid
Mailbox[8]->Write(0x00); // flags Mailbox[8].Write(0x00); // flags
MB_Write16(8, len+2+16); // data length (plus event ID and trailer) MB_Write16(8, len+2+16); // data length (plus event ID and trailer)
Mailbox[8]->Write(0xFF); // trailer length Mailbox[8].Write(0xFF); // trailer length
Mailbox[8]->Write(0xFF); // Mailbox[8].Write(0xFF); //
MB_Write16(8, 0x1004); // event ID MB_Write16(8, 0x1004); // event ID
MB_Write16(8, 2437); // channel (6) (checkme!) MB_Write16(8, 2437); // channel (6) (checkme!)
Mailbox[8]->Write(type); Mailbox[8].Write(type);
Mailbox[8]->Write(0x1B); // 'snr' Mailbox[8].Write(0x1B); // 'snr'
MB_Write16(8, 0xFFBC); // RSSI MB_Write16(8, 0xFFBC); // RSSI
MB_Write32(8, *(u32*)&WifiAP::APMac[0]); MB_Write32(8, *(u32*)&WifiAP::APMac[0]);
MB_Write16(8, *(u16*)&WifiAP::APMac[4]); MB_Write16(8, *(u16*)&WifiAP::APMac[4]);
@ -1386,7 +1385,7 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
Mailbox[8]->Write(data[i]); Mailbox[8].Write(data[i]);
} }
DrainRXBuffer(); DrainRXBuffer();
@ -1394,7 +1393,7 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
void DSi_NWifi::CheckRX() void DSi_NWifi::CheckRX()
{ {
if (!Mailbox[8]->CanFit(2048)) if (!Mailbox[8].CanFit(2048))
return; return;
int rxlen = Platform::LAN_RecvPacket(LANBuffer); int rxlen = Platform::LAN_RecvPacket(LANBuffer);
@ -1433,11 +1432,11 @@ void DSi_NWifi::CheckRX()
// TODO: not hardcode the endpoint ID!! // TODO: not hardcode the endpoint ID!!
u8 ep = 2; u8 ep = 2;
Mailbox[8]->Write(ep); Mailbox[8].Write(ep);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
MB_Write16(8, 16 + 8 + datalen); MB_Write16(8, 16 + 8 + datalen);
Mailbox[8]->Write(0); Mailbox[8].Write(0);
Mailbox[8]->Write(0); Mailbox[8].Write(0);
MB_Write16(8, hdr); MB_Write16(8, hdr);
MB_Write32(8, *(u32*)&LANBuffer[0]); MB_Write32(8, *(u32*)&LANBuffer[0]);
@ -1454,7 +1453,7 @@ void DSi_NWifi::CheckRX()
MB_Write16(8, *(u16*)&LANBuffer[12]); MB_Write16(8, *(u16*)&LANBuffer[12]);
for (int i = 0; i < datalen; i++) for (int i = 0; i < datalen; i++)
Mailbox[8]->Write(LANBuffer[14+i]); Mailbox[8].Write(LANBuffer[14+i]);
DrainRXBuffer(); DrainRXBuffer();
} }
@ -1541,25 +1540,25 @@ void DSi_NWifi::_MSTimer()
if (ConnectionStatus == 1) if (ConnectionStatus == 1)
{ {
//if (Mailbox[4]->IsEmpty()) //if (Mailbox[4].IsEmpty())
CheckRX(); CheckRX();
} }
} }
void DSi_NWifi::DrainRXBuffer() void DSi_NWifi::DrainRXBuffer()
{ {
while (Mailbox[8]->Level() >= 6) while (Mailbox[8].Level() >= 6)
{ {
u16 len = Mailbox[8]->Peek(2) | (Mailbox[8]->Peek(3) << 8); u16 len = Mailbox[8].Peek(2) | (Mailbox[8].Peek(3) << 8);
u32 totallen = len + 6; u32 totallen = len + 6;
u32 required = (totallen + 0x7F) & ~0x7F; u32 required = (totallen + 0x7F) & ~0x7F;
if (!Mailbox[4]->CanFit(required)) if (!Mailbox[4].CanFit(required))
break; break;
u32 i = 0; u32 i = 0;
for (; i < totallen; i++) Mailbox[4]->Write(Mailbox[8]->Read()); for (; i < totallen; i++) Mailbox[4].Write(Mailbox[8].Read());
for (; i < required; i++) Mailbox[4]->Write(0); for (; i < required; i++) Mailbox[4].Write(0);
} }
UpdateIRQ_F1(); UpdateIRQ_F1();

View File

@ -84,40 +84,40 @@ private:
u16 MB_Read16(int n) u16 MB_Read16(int n)
{ {
u16 ret = Mailbox[n]->Read(); u16 ret = Mailbox[n].Read();
ret |= (Mailbox[n]->Read() << 8); ret |= (Mailbox[n].Read() << 8);
return ret; return ret;
} }
void MB_Write16(int n, u16 val) void MB_Write16(int n, u16 val)
{ {
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); 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();
ret |= (Mailbox[n]->Read() << 8); ret |= (Mailbox[n].Read() << 8);
ret |= (Mailbox[n]->Read() << 16); ret |= (Mailbox[n].Read() << 16);
ret |= (Mailbox[n]->Read() << 24); ret |= (Mailbox[n].Read() << 24);
return ret; return ret;
} }
void MB_Write32(int n, u32 val) void MB_Write32(int n, u32 val)
{ {
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); Mailbox[n].Write(val & 0xFF);
} }
void MB_Drain(int n) void MB_Drain(int n)
{ {
while (!Mailbox[n]->IsEmpty()) Mailbox[n]->Read(); while (!Mailbox[n].IsEmpty()) Mailbox[n].Read();
} }
FIFO<u8>* Mailbox[9]; DynamicFIFO<u8> Mailbox[9];
u8 F0_IRQEnable; u8 F0_IRQEnable;
u8 F0_IRQStatus; u8 F0_IRQStatus;

View File

@ -52,20 +52,12 @@ DSi_SDHost::DSi_SDHost(u32 num)
{ {
Num = num; Num = num;
DataFIFO[0] = new FIFO<u16>(0x100);
DataFIFO[1] = new FIFO<u16>(0x100);
DataFIFO32 = new FIFO<u32>(0x80);
Ports[0] = NULL; Ports[0] = NULL;
Ports[1] = NULL; Ports[1] = NULL;
} }
DSi_SDHost::~DSi_SDHost() DSi_SDHost::~DSi_SDHost()
{ {
delete DataFIFO[0];
delete DataFIFO[1];
delete DataFIFO32;
if (Ports[0]) delete Ports[0]; if (Ports[0]) delete Ports[0];
if (Ports[1]) delete Ports[1]; if (Ports[1]) delete Ports[1];
} }
@ -89,10 +81,10 @@ void DSi_SDHost::Reset()
Param = 0; Param = 0;
memset(ResponseBuffer, 0, sizeof(ResponseBuffer)); memset(ResponseBuffer, 0, sizeof(ResponseBuffer));
DataFIFO[0]->Clear(); DataFIFO[0].Clear();
DataFIFO[1]->Clear(); DataFIFO[1].Clear();
CurFIFO = 0; CurFIFO = 0;
DataFIFO32->Clear(); DataFIFO32.Clear();
IRQStatus = 0; IRQStatus = 0;
IRQMask = 0x8B7F031D; IRQMask = 0x8B7F031D;
@ -160,8 +152,8 @@ void DSi_SDHost::UpdateData32IRQ()
oldflags &= (Data32IRQ >> 11); oldflags &= (Data32IRQ >> 11);
Data32IRQ &= ~0x0300; Data32IRQ &= ~0x0300;
if (DataFIFO32->Level() >= (BlockLen32>>2)) Data32IRQ |= (1<<8); if (DataFIFO32.Level() >= (BlockLen32>>2)) Data32IRQ |= (1<<8);
if (!DataFIFO32->IsEmpty()) Data32IRQ |= (1<<9); if (!DataFIFO32.IsEmpty()) Data32IRQ |= (1<<9);
u32 newflags = ((Data32IRQ >> 8) & 0x1) | (((~Data32IRQ) >> 8) & 0x2); u32 newflags = ((Data32IRQ >> 8) & 0x1) | (((~Data32IRQ) >> 8) & 0x2);
newflags &= (Data32IRQ >> 11); newflags &= (Data32IRQ >> 11);
@ -256,7 +248,7 @@ u32 DSi_SDHost::DataRX(u8* data, u32 len)
u32 f = CurFIFO ^ 1; u32 f = CurFIFO ^ 1;
for (u32 i = 0; i < len; i += 2) for (u32 i = 0; i < len; i += 2)
DataFIFO[f]->Write(*(u16*)&data[i]); DataFIFO[f].Write(*(u16*)&data[i]);
//CurFIFO = f; //CurFIFO = f;
//SetIRQ(24); //SetIRQ(24);
@ -304,9 +296,9 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
if (DataMode == 1) if (DataMode == 1)
{ {
if ((DataFIFO32->Level() << 2) < len) if ((DataFIFO32.Level() << 2) < len)
{ {
if (DataFIFO32->IsEmpty()) if (DataFIFO32.IsEmpty())
{ {
SetIRQ(25); SetIRQ(25);
DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); DSi::CheckNDMAs(1, Num ? 0x29 : 0x28);
@ -316,16 +308,16 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
// drain FIFO32 into FIFO16 // drain FIFO32 into FIFO16
if (!DataFIFO[f]->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO32 INTO FIFO16 BUT IT CONTAINS SHIT ALREADY\n"); if (!DataFIFO[f].IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO32 INTO FIFO16 BUT IT CONTAINS SHIT ALREADY\n");
for (;;) for (;;)
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if ((DataFIFO[f]->Level() << 1) >= BlockLen16) break; if ((DataFIFO[f].Level() << 1) >= BlockLen16) break;
if (DataFIFO32->IsEmpty()) break; if (DataFIFO32.IsEmpty()) break;
u32 val = DataFIFO32->Read(); u32 val = DataFIFO32.Read();
DataFIFO[f]->Write(val & 0xFFFF); DataFIFO[f].Write(val & 0xFFFF);
DataFIFO[f]->Write(val >> 16); DataFIFO[f].Write(val >> 16);
} }
UpdateData32IRQ(); UpdateData32IRQ();
@ -335,15 +327,15 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
} }
else else
{ {
if ((DataFIFO[f]->Level() << 1) < len) if ((DataFIFO[f].Level() << 1) < len)
{ {
if (DataFIFO[f]->IsEmpty()) SetIRQ(25); if (DataFIFO[f].IsEmpty()) SetIRQ(25);
return 0; return 0;
} }
} }
for (u32 i = 0; i < len; i += 2) for (u32 i = 0; i < len; i += 2)
*(u16*)&data[i] = DataFIFO[f]->Read(); *(u16*)&data[i] = DataFIFO[f].Read();
CurFIFO ^= 1; CurFIFO ^= 1;
BlockCountInternal--; BlockCountInternal--;
@ -392,13 +384,13 @@ void DSi_SDHost::CheckTX()
if (DataMode == 1) if (DataMode == 1)
{ {
if ((DataFIFO32->Level() << 2) < BlockLen32) if ((DataFIFO32.Level() << 2) < BlockLen32)
return; return;
} }
else else
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if ((DataFIFO[f]->Level() << 1) < BlockLen16) if ((DataFIFO[f].Level() << 1) < BlockLen16)
return; return;
} }
@ -481,7 +473,7 @@ u16 DSi_SDHost::Read(u32 addr)
u16 DSi_SDHost::ReadFIFO16() u16 DSi_SDHost::ReadFIFO16()
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if (DataFIFO[f]->IsEmpty()) if (DataFIFO[f].IsEmpty())
{ {
// TODO // TODO
// on hardware it seems to wrap around. underflow bit is set upon the first 'empty' read. // on hardware it seems to wrap around. underflow bit is set upon the first 'empty' read.
@ -489,9 +481,9 @@ u16 DSi_SDHost::ReadFIFO16()
} }
DSi_SDDevice* dev = Ports[PortSelect & 0x1]; DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u16 ret = DataFIFO[f]->Read(); u16 ret = DataFIFO[f].Read();
if (DataFIFO[f]->IsEmpty()) if (DataFIFO[f].IsEmpty())
{ {
CheckRX(); CheckRX();
} }
@ -503,16 +495,16 @@ u32 DSi_SDHost::ReadFIFO32()
{ {
if (DataMode != 1) return 0; if (DataMode != 1) return 0;
if (DataFIFO32->IsEmpty()) if (DataFIFO32.IsEmpty())
{ {
// TODO // TODO
return 0; return 0;
} }
DSi_SDDevice* dev = Ports[PortSelect & 0x1]; DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u32 ret = DataFIFO32->Read(); u32 ret = DataFIFO32.Read();
if (DataFIFO32->IsEmpty()) if (DataFIFO32.IsEmpty())
{ {
CheckRX(); CheckRX();
} }
@ -628,7 +620,7 @@ void DSi_SDHost::Write(u32 addr, u16 val)
case 0x100: case 0x100:
Data32IRQ = (val & 0x1802) | (Data32IRQ & 0x0300); Data32IRQ = (val & 0x1802) | (Data32IRQ & 0x0300);
if (val & (1<<10)) DataFIFO32->Clear(); if (val & (1<<10)) DataFIFO32.Clear();
DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1); DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1);
return; return;
case 0x102: return; case 0x102: return;
@ -643,14 +635,14 @@ void DSi_SDHost::WriteFIFO16(u16 val)
{ {
DSi_SDDevice* dev = Ports[PortSelect & 0x1]; DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u32 f = CurFIFO; u32 f = CurFIFO;
if (DataFIFO[f]->IsFull()) if (DataFIFO[f].IsFull())
{ {
// TODO // TODO
printf("!!!! %s FIFO (16) FULL\n", SD_DESC); printf("!!!! %s FIFO (16) FULL\n", SD_DESC);
return; return;
} }
DataFIFO[f]->Write(val); DataFIFO[f].Write(val);
CheckTX(); CheckTX();
} }
@ -659,14 +651,14 @@ void DSi_SDHost::WriteFIFO32(u32 val)
{ {
if (DataMode != 1) return; if (DataMode != 1) return;
if (DataFIFO32->IsFull()) if (DataFIFO32.IsFull())
{ {
// TODO // TODO
printf("!!!! %s FIFO (32) FULL\n", SD_DESC); printf("!!!! %s FIFO (32) FULL\n", SD_DESC);
return; return;
} }
DataFIFO32->Write(val); DataFIFO32.Write(val);
CheckTX(); CheckTX();
@ -679,21 +671,21 @@ void DSi_SDHost::UpdateFIFO32()
if (DataMode != 1) return; if (DataMode != 1) return;
if (!DataFIFO32->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO16 INTO FIFO32 BUT IT CONTAINS SHIT ALREADY\n"); if (!DataFIFO32.IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO16 INTO FIFO32 BUT IT CONTAINS SHIT ALREADY\n");
for (;;) for (;;)
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if ((DataFIFO32->Level() << 2) >= BlockLen32) break; if ((DataFIFO32.Level() << 2) >= BlockLen32) break;
if (DataFIFO[f]->IsEmpty()) break; if (DataFIFO[f].IsEmpty()) break;
u32 val = DataFIFO[f]->Read(); u32 val = DataFIFO[f].Read();
val |= (DataFIFO[f]->Read() << 16); val |= (DataFIFO[f].Read() << 16);
DataFIFO32->Write(val); DataFIFO32.Write(val);
} }
UpdateData32IRQ(); UpdateData32IRQ();
if ((DataFIFO32->Level() << 2) >= BlockLen32) if ((DataFIFO32.Level() << 2) >= BlockLen32)
{ {
DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); DSi::CheckNDMAs(1, Num ? 0x29 : 0x28);
} }
@ -704,8 +696,8 @@ void DSi_SDHost::CheckSwapFIFO()
// check whether we can swap the FIFOs // check whether we can swap the FIFOs
u32 f = CurFIFO; u32 f = CurFIFO;
bool cur_empty = (DataMode == 1) ? DataFIFO32->IsEmpty() : DataFIFO[f]->IsEmpty(); bool cur_empty = (DataMode == 1) ? DataFIFO32.IsEmpty() : DataFIFO[f].IsEmpty();
if (cur_empty && ((DataFIFO[f^1]->Level() << 1) >= BlockLen16)) if (cur_empty && ((DataFIFO[f^1].Level() << 1) >= BlockLen16))
{ {
CurFIFO ^= 1; CurFIFO ^= 1;
} }

View File

@ -85,12 +85,12 @@ private:
u32 Param; u32 Param;
u16 ResponseBuffer[8]; u16 ResponseBuffer[8];
FIFO<u16>* DataFIFO[2];
u32 CurFIFO; // FIFO accessible for read/write
FIFO<u32>* DataFIFO32;
DSi_SDDevice* Ports[2]; DSi_SDDevice* Ports[2];
u32 CurFIFO; // FIFO accessible for read/write
FIFO<u16, 0x100> DataFIFO[2];
FIFO<u32, 0x80> DataFIFO32;
void UpdateData32IRQ(); void UpdateData32IRQ();
void ClearIRQ(u32 irq); void ClearIRQ(u32 irq);
void SetIRQ(u32 irq); void SetIRQ(u32 irq);

View File

@ -21,18 +21,95 @@
#include "types.h" #include "types.h"
template<typename T> template<typename T, u32 NumEntries>
class FIFO class FIFO
{ {
public: public:
FIFO(u32 num) void Clear()
{
NumOccupied = 0;
ReadPos = 0;
WritePos = 0;
memset(&Entries[ReadPos], 0, sizeof(T));
}
void DoSavestate(Savestate* file)
{
file->Var32(&NumOccupied);
file->Var32(&ReadPos);
file->Var32(&WritePos);
file->VarArray(Entries, sizeof(T)*NumEntries);
}
void Write(T val)
{
if (IsFull()) return;
Entries[WritePos] = val;
WritePos++;
if (WritePos >= NumEntries)
WritePos = 0;
NumOccupied++;
}
T Read()
{
T ret = Entries[ReadPos];
if (IsEmpty())
return ret;
ReadPos++;
if (ReadPos >= NumEntries)
ReadPos = 0;
NumOccupied--;
return ret;
}
T Peek()
{
return Entries[ReadPos];
}
T Peek(u32 offset)
{
u32 pos = ReadPos + offset;
if (pos >= NumEntries)
pos -= NumEntries;
return Entries[pos];
}
u32 Level() { return NumOccupied; }
bool IsEmpty() { return NumOccupied == 0; }
bool IsFull() { return NumOccupied >= NumEntries; }
bool CanFit(u32 num) { return ((NumOccupied + num) <= NumEntries); }
private:
T Entries[NumEntries] = {0};
u32 NumOccupied = 0;
u32 ReadPos = 0, WritePos = 0;
};
template<typename T>
class DynamicFIFO
{
public:
DynamicFIFO(u32 num)
{ {
NumEntries = num; NumEntries = num;
Entries = new T[num]; Entries = new T[num];
Clear(); Clear();
} }
~FIFO() ~DynamicFIFO()
{ {
delete[] Entries; delete[] Entries;
} }

View File

@ -147,10 +147,10 @@ typedef union
} CmdFIFOEntry; } CmdFIFOEntry;
FIFO<CmdFIFOEntry>* CmdFIFO; FIFO<CmdFIFOEntry, 256> CmdFIFO;
FIFO<CmdFIFOEntry>* CmdPIPE; FIFO<CmdFIFOEntry, 4> CmdPIPE;
FIFO<CmdFIFOEntry>* CmdStallQueue; FIFO<CmdFIFOEntry, 64> CmdStallQueue;
u32 NumCommands, CurCommand, ParamCount, TotalParams; u32 NumCommands, CurCommand, ParamCount, TotalParams;
@ -277,20 +277,11 @@ u32 FlushAttributes;
bool Init() bool Init()
{ {
CmdFIFO = new FIFO<CmdFIFOEntry>(256);
CmdPIPE = new FIFO<CmdFIFOEntry>(4);
CmdStallQueue = new FIFO<CmdFIFOEntry>(64);
return true; return true;
} }
void DeInit() void DeInit()
{ {
delete CmdFIFO;
delete CmdPIPE;
delete CmdStallQueue;
} }
void ResetRenderingState() void ResetRenderingState()
@ -314,10 +305,10 @@ void ResetRenderingState()
void Reset() void Reset()
{ {
CmdFIFO->Clear(); CmdFIFO.Clear();
CmdPIPE->Clear(); CmdPIPE.Clear();
CmdStallQueue->Clear(); CmdStallQueue.Clear();
NumCommands = 0; NumCommands = 0;
CurCommand = 0; CurCommand = 0;
@ -395,8 +386,8 @@ void DoSavestate(Savestate* file)
{ {
file->Section("GP3D"); file->Section("GP3D");
CmdFIFO->DoSavestate(file); CmdFIFO.DoSavestate(file);
CmdPIPE->DoSavestate(file); CmdPIPE.DoSavestate(file);
file->Var32(&NumCommands); file->Var32(&NumCommands);
file->Var32(&CurCommand); file->Var32(&CurCommand);
@ -593,7 +584,9 @@ void DoSavestate(Savestate* file)
} }
} }
CmdStallQueue->DoSavestate(file); // probably not worth storing the vblank-latched Renderxxxxxx variables
CmdStallQueue.DoSavestate(file);
file->Var32((u32*)&VertexPipeline); file->Var32((u32*)&VertexPipeline);
file->Var32((u32*)&NormalPipeline); file->Var32((u32*)&NormalPipeline);
file->Var32((u32*)&PolygonPipeline); file->Var32((u32*)&PolygonPipeline);
@ -1731,24 +1724,24 @@ void VecTest(u32* params)
void CmdFIFOWrite(CmdFIFOEntry& entry) void CmdFIFOWrite(CmdFIFOEntry& entry)
{ {
if (CmdFIFO->IsEmpty() && !CmdPIPE->IsFull()) if (CmdFIFO.IsEmpty() && !CmdPIPE.IsFull())
{ {
CmdPIPE->Write(entry); CmdPIPE.Write(entry);
} }
else else
{ {
if (CmdFIFO->IsFull()) if (CmdFIFO.IsFull())
{ {
// store it to the stall queue. stall the system. // store it to the stall queue. stall the system.
// worst case is if a STMxx opcode causes this, which is why our stall queue // worst case is if a STMxx opcode causes this, which is why our stall queue
// has 64 entries. this is less complicated than trying to make STMxx stall-able. // has 64 entries. this is less complicated than trying to make STMxx stall-able.
CmdStallQueue->Write(entry); CmdStallQueue.Write(entry);
NDS::GXFIFOStall(); NDS::GXFIFOStall();
return; return;
} }
CmdFIFO->Write(entry); CmdFIFO.Write(entry);
} }
GXStat |= (1<<27); GXStat |= (1<<27);
@ -1767,27 +1760,27 @@ void CmdFIFOWrite(CmdFIFOEntry& entry)
CmdFIFOEntry CmdFIFORead() CmdFIFOEntry CmdFIFORead()
{ {
CmdFIFOEntry ret = CmdPIPE->Read(); CmdFIFOEntry ret = CmdPIPE.Read();
if (CmdPIPE->Level() <= 2) if (CmdPIPE.Level() <= 2)
{ {
if (!CmdFIFO->IsEmpty()) if (!CmdFIFO.IsEmpty())
CmdPIPE->Write(CmdFIFO->Read()); CmdPIPE.Write(CmdFIFO.Read());
if (!CmdFIFO->IsEmpty()) if (!CmdFIFO.IsEmpty())
CmdPIPE->Write(CmdFIFO->Read()); CmdPIPE.Write(CmdFIFO.Read());
// empty stall queue if needed // empty stall queue if needed
// CmdFIFO should not be full at this point. // CmdFIFO should not be full at this point.
if (!CmdStallQueue->IsEmpty()) if (!CmdStallQueue.IsEmpty())
{ {
while (!CmdStallQueue->IsEmpty()) while (!CmdStallQueue.IsEmpty())
{ {
if (CmdFIFO->IsFull()) break; if (CmdFIFO.IsFull()) break;
CmdFIFOEntry entry = CmdStallQueue->Read(); CmdFIFOEntry entry = CmdStallQueue.Read();
CmdFIFOWrite(entry); CmdFIFOWrite(entry);
} }
if (CmdStallQueue->IsEmpty()) if (CmdStallQueue.IsEmpty())
NDS::GXFIFOUnstall(); NDS::GXFIFOUnstall();
} }
@ -2451,7 +2444,7 @@ void FinishWork(s32 cycles)
void Run() void Run()
{ {
if (!GeometryEnabled || FlushRequest || if (!GeometryEnabled || FlushRequest ||
(CmdPIPE->IsEmpty() && !(GXStat & (1<<27)))) (CmdPIPE.IsEmpty() && !(GXStat & (1<<27))))
{ {
Timestamp = NDS::ARM9Timestamp >> NDS::ARM9ClockShift; Timestamp = NDS::ARM9Timestamp >> NDS::ARM9ClockShift;
return; return;
@ -2463,7 +2456,7 @@ void Run()
if (CycleCount <= 0) if (CycleCount <= 0)
{ {
while (CycleCount <= 0 && !CmdPIPE->IsEmpty()) while (CycleCount <= 0 && !CmdPIPE.IsEmpty())
{ {
if (NumPushPopCommands == 0) GXStat &= ~(1<<14); if (NumPushPopCommands == 0) GXStat &= ~(1<<14);
if (NumTestCommands == 0) GXStat &= ~(1<<0); if (NumTestCommands == 0) GXStat &= ~(1<<0);
@ -2472,7 +2465,7 @@ void Run()
} }
} }
if (CycleCount <= 0 && CmdPIPE->IsEmpty()) if (CycleCount <= 0 && CmdPIPE.IsEmpty())
{ {
if (GXStat & (1<<27)) FinishWork(-CycleCount); if (GXStat & (1<<27)) FinishWork(-CycleCount);
else CycleCount = 0; else CycleCount = 0;
@ -2488,8 +2481,8 @@ void CheckFIFOIRQ()
bool irq = false; bool irq = false;
switch (GXStat >> 30) switch (GXStat >> 30)
{ {
case 1: irq = (CmdFIFO->Level() < 128); break; case 1: irq = (CmdFIFO.Level() < 128); break;
case 2: irq = CmdFIFO->IsEmpty(); break; case 2: irq = CmdFIFO.IsEmpty(); break;
} }
if (irq) NDS::SetIRQ(0, NDS::IRQ_GXFIFO); if (irq) NDS::SetIRQ(0, NDS::IRQ_GXFIFO);
@ -2498,7 +2491,7 @@ void CheckFIFOIRQ()
void CheckFIFODMA() void CheckFIFODMA()
{ {
if (CmdFIFO->Level() < 128) if (CmdFIFO.Level() < 128)
NDS::CheckDMAs(0, 0x07); NDS::CheckDMAs(0, 0x07);
} }
@ -2705,7 +2698,7 @@ u8 Read8(u32 addr)
{ {
Run(); Run();
u32 fifolevel = CmdFIFO->Level(); u32 fifolevel = CmdFIFO.Level();
return fifolevel & 0xFF; return fifolevel & 0xFF;
} }
@ -2713,7 +2706,7 @@ u8 Read8(u32 addr)
{ {
Run(); Run();
u32 fifolevel = CmdFIFO->Level(); u32 fifolevel = CmdFIFO.Level();
return ((GXStat >> 24) & 0xFF) | return ((GXStat >> 24) & 0xFF) |
(fifolevel >> 8) | (fifolevel >> 8) |
@ -2748,7 +2741,7 @@ u16 Read16(u32 addr)
{ {
Run(); Run();
u32 fifolevel = CmdFIFO->Level(); u32 fifolevel = CmdFIFO.Level();
return (GXStat >> 16) | return (GXStat >> 16) |
fifolevel | fifolevel |
@ -2784,7 +2777,7 @@ u32 Read32(u32 addr)
{ {
Run(); Run();
u32 fifolevel = CmdFIFO->Level(); u32 fifolevel = CmdFIFO.Level();
return GXStat | return GXStat |
((PosMatrixStackPointer & 0x1F) << 8) | ((PosMatrixStackPointer & 0x1F) << 8) |

View File

@ -139,8 +139,8 @@ u32 DMA9Fill[4];
u16 IPCSync9, IPCSync7; u16 IPCSync9, IPCSync7;
u16 IPCFIFOCnt9, IPCFIFOCnt7; u16 IPCFIFOCnt9, IPCFIFOCnt7;
FIFO<u32>* IPCFIFO9; // FIFO in which the ARM9 writes FIFO<u32, 16> IPCFIFO9; // FIFO in which the ARM9 writes
FIFO<u32>* IPCFIFO7; FIFO<u32, 16> IPCFIFO7;
u16 DivCnt; u16 DivCnt;
u32 DivNumerator[2]; u32 DivNumerator[2];
@ -190,9 +190,6 @@ bool Init()
DMAs[6] = new DMA(1, 2); DMAs[6] = new DMA(1, 2);
DMAs[7] = new DMA(1, 3); DMAs[7] = new DMA(1, 3);
IPCFIFO9 = new FIFO<u32>(16);
IPCFIFO7 = new FIFO<u32>(16);
if (!NDSCart::Init()) return false; if (!NDSCart::Init()) return false;
if (!GBACart::Init()) return false; if (!GBACart::Init()) return false;
if (!GPU::Init()) return false; if (!GPU::Init()) return false;
@ -220,9 +217,6 @@ void DeInit()
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
delete DMAs[i]; delete DMAs[i];
delete IPCFIFO9;
delete IPCFIFO7;
NDSCart::DeInit(); NDSCart::DeInit();
GBACart::DeInit(); GBACart::DeInit();
GPU::DeInit(); GPU::DeInit();
@ -557,8 +551,8 @@ void Reset()
IPCSync7 = 0; IPCSync7 = 0;
IPCFIFOCnt9 = 0; IPCFIFOCnt9 = 0;
IPCFIFOCnt7 = 0; IPCFIFOCnt7 = 0;
IPCFIFO9->Clear(); IPCFIFO9.Clear();
IPCFIFO7->Clear(); IPCFIFO7.Clear();
DivCnt = 0; DivCnt = 0;
SqrtCnt = 0; SqrtCnt = 0;
@ -736,8 +730,8 @@ bool DoSavestate(Savestate* file)
file->Var16(&IPCSync7); file->Var16(&IPCSync7);
file->Var16(&IPCFIFOCnt9); file->Var16(&IPCFIFOCnt9);
file->Var16(&IPCFIFOCnt7); file->Var16(&IPCFIFOCnt7);
IPCFIFO9->DoSavestate(file); IPCFIFO9.DoSavestate(file);
IPCFIFO7->DoSavestate(file); IPCFIFO7.DoSavestate(file);
file->Var16(&DivCnt); file->Var16(&DivCnt);
file->Var16(&SqrtCnt); file->Var16(&SqrtCnt);
@ -2899,10 +2893,10 @@ u16 ARM9IORead16(u32 addr)
case 0x04000184: case 0x04000184:
{ {
u16 val = IPCFIFOCnt9; u16 val = IPCFIFOCnt9;
if (IPCFIFO9->IsEmpty()) val |= 0x0001; if (IPCFIFO9.IsEmpty()) val |= 0x0001;
else if (IPCFIFO9->IsFull()) val |= 0x0002; else if (IPCFIFO9.IsFull()) val |= 0x0002;
if (IPCFIFO7->IsEmpty()) val |= 0x0100; if (IPCFIFO7.IsEmpty()) val |= 0x0100;
else if (IPCFIFO7->IsFull()) val |= 0x0200; else if (IPCFIFO7.IsFull()) val |= 0x0200;
return val; return val;
} }
@ -3057,22 +3051,22 @@ u32 ARM9IORead32(u32 addr)
if (IPCFIFOCnt9 & 0x8000) if (IPCFIFOCnt9 & 0x8000)
{ {
u32 ret; u32 ret;
if (IPCFIFO7->IsEmpty()) if (IPCFIFO7.IsEmpty())
{ {
IPCFIFOCnt9 |= 0x4000; IPCFIFOCnt9 |= 0x4000;
ret = IPCFIFO7->Peek(); ret = IPCFIFO7.Peek();
} }
else else
{ {
ret = IPCFIFO7->Read(); ret = IPCFIFO7.Read();
if (IPCFIFO7->IsEmpty() && (IPCFIFOCnt7 & 0x0004)) if (IPCFIFO7.IsEmpty() && (IPCFIFOCnt7 & 0x0004))
SetIRQ(1, IRQ_IPCSendDone); SetIRQ(1, IRQ_IPCSendDone);
} }
return ret; return ret;
} }
else else
return IPCFIFO7->Peek(); return IPCFIFO7.Peek();
case 0x04100010: case 0x04100010:
if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData(); if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData();
@ -3238,10 +3232,10 @@ void ARM9IOWrite16(u32 addr, u16 val)
case 0x04000184: case 0x04000184:
if (val & 0x0008) if (val & 0x0008)
IPCFIFO9->Clear(); IPCFIFO9.Clear();
if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9->IsEmpty()) if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9.IsEmpty())
SetIRQ(0, IRQ_IPCSendDone); SetIRQ(0, IRQ_IPCSendDone);
if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7->IsEmpty())) if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7.IsEmpty()))
SetIRQ(0, IRQ_IPCRecv); SetIRQ(0, IRQ_IPCRecv);
if (val & 0x4000) if (val & 0x4000)
IPCFIFOCnt9 &= ~0x4000; IPCFIFOCnt9 &= ~0x4000;
@ -3407,12 +3401,12 @@ void ARM9IOWrite32(u32 addr, u32 val)
case 0x04000188: case 0x04000188:
if (IPCFIFOCnt9 & 0x8000) if (IPCFIFOCnt9 & 0x8000)
{ {
if (IPCFIFO9->IsFull()) if (IPCFIFO9.IsFull())
IPCFIFOCnt9 |= 0x4000; IPCFIFOCnt9 |= 0x4000;
else else
{ {
bool wasempty = IPCFIFO9->IsEmpty(); bool wasempty = IPCFIFO9.IsEmpty();
IPCFIFO9->Write(val); IPCFIFO9.Write(val);
if ((IPCFIFOCnt7 & 0x0400) && wasempty) if ((IPCFIFOCnt7 & 0x0400) && wasempty)
SetIRQ(1, IRQ_IPCRecv); SetIRQ(1, IRQ_IPCRecv);
} }
@ -3590,10 +3584,10 @@ u16 ARM7IORead16(u32 addr)
case 0x04000184: case 0x04000184:
{ {
u16 val = IPCFIFOCnt7; u16 val = IPCFIFOCnt7;
if (IPCFIFO7->IsEmpty()) val |= 0x0001; if (IPCFIFO7.IsEmpty()) val |= 0x0001;
else if (IPCFIFO7->IsFull()) val |= 0x0002; else if (IPCFIFO7.IsFull()) val |= 0x0002;
if (IPCFIFO9->IsEmpty()) val |= 0x0100; if (IPCFIFO9.IsEmpty()) val |= 0x0100;
else if (IPCFIFO9->IsFull()) val |= 0x0200; else if (IPCFIFO9.IsFull()) val |= 0x0200;
return val; return val;
} }
@ -3689,22 +3683,22 @@ u32 ARM7IORead32(u32 addr)
if (IPCFIFOCnt7 & 0x8000) if (IPCFIFOCnt7 & 0x8000)
{ {
u32 ret; u32 ret;
if (IPCFIFO9->IsEmpty()) if (IPCFIFO9.IsEmpty())
{ {
IPCFIFOCnt7 |= 0x4000; IPCFIFOCnt7 |= 0x4000;
ret = IPCFIFO9->Peek(); ret = IPCFIFO9.Peek();
} }
else else
{ {
ret = IPCFIFO9->Read(); ret = IPCFIFO9.Read();
if (IPCFIFO9->IsEmpty() && (IPCFIFOCnt9 & 0x0004)) if (IPCFIFO9.IsEmpty() && (IPCFIFOCnt9 & 0x0004))
SetIRQ(0, IRQ_IPCSendDone); SetIRQ(0, IRQ_IPCSendDone);
} }
return ret; return ret;
} }
else else
return IPCFIFO9->Peek(); return IPCFIFO9.Peek();
case 0x04100010: case 0x04100010:
if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData(); if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData();
@ -3841,10 +3835,10 @@ void ARM7IOWrite16(u32 addr, u16 val)
case 0x04000184: case 0x04000184:
if (val & 0x0008) if (val & 0x0008)
IPCFIFO7->Clear(); IPCFIFO7.Clear();
if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7->IsEmpty()) if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7.IsEmpty())
SetIRQ(1, IRQ_IPCSendDone); SetIRQ(1, IRQ_IPCSendDone);
if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9->IsEmpty())) if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9.IsEmpty()))
SetIRQ(1, IRQ_IPCRecv); SetIRQ(1, IRQ_IPCRecv);
if (val & 0x4000) if (val & 0x4000)
IPCFIFOCnt7 &= ~0x4000; IPCFIFOCnt7 &= ~0x4000;
@ -3977,12 +3971,12 @@ void ARM7IOWrite32(u32 addr, u32 val)
case 0x04000188: case 0x04000188:
if (IPCFIFOCnt7 & 0x8000) if (IPCFIFOCnt7 & 0x8000)
{ {
if (IPCFIFO7->IsFull()) if (IPCFIFO7.IsFull())
IPCFIFOCnt7 |= 0x4000; IPCFIFOCnt7 |= 0x4000;
else else
{ {
bool wasempty = IPCFIFO7->IsEmpty(); bool wasempty = IPCFIFO7.IsEmpty();
IPCFIFO7->Write(val); IPCFIFO7.Write(val);
if ((IPCFIFOCnt9 & 0x0400) && wasempty) if ((IPCFIFOCnt9 & 0x0400) && wasempty)
SetIRQ(0, IRQ_IPCRecv); SetIRQ(0, IRQ_IPCRecv);
} }

View File

@ -48,7 +48,7 @@ const u32 kClientIP = kSubnet | 0x10;
const u8 kServerMAC[6] = {0x00, 0xAB, 0x33, 0x28, 0x99, 0x44}; const u8 kServerMAC[6] = {0x00, 0xAB, 0x33, 0x28, 0x99, 0x44};
FIFO<u32>* RXBuffer = nullptr; FIFO<u32, (0x8000 >> 2)> RXBuffer;
u32 IPv4ID; u32 IPv4ID;
@ -86,16 +86,16 @@ void RXEnqueue(const void* buf, int len)
int alignedlen = (len + 3) & ~3; int alignedlen = (len + 3) & ~3;
int totallen = alignedlen + 4; int totallen = alignedlen + 4;
if (!RXBuffer->CanFit(totallen >> 2)) if (!RXBuffer.CanFit(totallen >> 2))
{ {
printf("slirp: !! NOT ENOUGH SPACE IN RX BUFFER\n"); printf("slirp: !! NOT ENOUGH SPACE IN RX BUFFER\n");
return; return;
} }
u32 header = (alignedlen & 0xFFFF) | (len << 16); u32 header = (alignedlen & 0xFFFF) | (len << 16);
RXBuffer->Write(header); RXBuffer.Write(header);
for (int i = 0; i < alignedlen; i += 4) for (int i = 0; i < alignedlen; i += 4)
RXBuffer->Write(((u32*)buf)[i>>2]); RXBuffer.Write(((u32*)buf)[i>>2]);
} }
ssize_t SlirpCbSendPacket(const void* buf, size_t len, void* opaque) ssize_t SlirpCbSendPacket(const void* buf, size_t len, void* opaque)
@ -202,8 +202,6 @@ bool Init()
//FDListSize = 0; //FDListSize = 0;
//memset(FDList, 0, sizeof(FDList)); //memset(FDList, 0, sizeof(FDList));
RXBuffer = new FIFO<u32>(0x8000 >> 2);
SlirpConfig cfg; SlirpConfig cfg;
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
cfg.version = 1; cfg.version = 1;
@ -228,12 +226,6 @@ void DeInit()
slirp_cleanup(Ctx); slirp_cleanup(Ctx);
Ctx = nullptr; Ctx = nullptr;
} }
if (RXBuffer)
{
delete RXBuffer;
RXBuffer = nullptr;
}
} }
@ -530,13 +522,13 @@ int RecvPacket(u8* data)
slirp_pollfds_poll(Ctx, res<0, SlirpCbGetREvents, nullptr); slirp_pollfds_poll(Ctx, res<0, SlirpCbGetREvents, nullptr);
} }
if (!RXBuffer->IsEmpty()) if (!RXBuffer.IsEmpty())
{ {
u32 header = RXBuffer->Read(); u32 header = RXBuffer.Read();
u32 len = header & 0xFFFF; u32 len = header & 0xFFFF;
for (int i = 0; i < len; i += 4) for (int i = 0; i < len; i += 4)
((u32*)data)[i>>2] = RXBuffer->Read(); ((u32*)data)[i>>2] = RXBuffer.Read();
ret = header >> 16; ret = header >> 16;
} }