From 06716794a1d69512312e1dc251b9762d27b15c8d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 24 Jul 2019 18:48:52 +0200 Subject: [PATCH] lots of things. attempting to make wifi init work. not there yet. --- src/DSi.cpp | 55 +++++++++--- src/DSi_AES.cpp | 23 +++++ src/DSi_NWifi.cpp | 214 ++++++++++++++++++++++++++++++++++++++++++---- src/DSi_NWifi.h | 27 ++++++ src/DSi_SD.cpp | 70 +++++++++++---- src/DSi_SD.h | 2 +- src/NDS.h | 3 +- 7 files changed, 344 insertions(+), 50 deletions(-) diff --git a/src/DSi.cpp b/src/DSi.cpp index 26a67f4e..aed6b89f 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -73,6 +73,7 @@ u64 ConsoleID; u8 eMMC_CID[16]; u8 ITCMInit[0x8000]; +u8 ARM7Init[0x3C00]; bool Init() @@ -120,6 +121,9 @@ void Reset() memcpy(NDS::ARM9->ITCM, ITCMInit, 0x8000); + for (u32 i = 0; i < 0x3C00; i+=4) + ARM7Write32(0x03FFC400+i, *(u32*)&ARM7Init[i]); + DSi_I2C::Reset(); DSi_AES::Reset(); @@ -138,9 +142,16 @@ void Reset() NDS::MapSharedWRAM(3); - // TEST - u8 derp[16] = {0xE5, 0xCC, 0x5A, 0x8B, 0x56, 0xD0, 0xC9, 0x72, 0x9C, 0x17, 0xE8, 0xDC, 0x39, 0x12, 0x36, 0xA9}; - for (int i = 0; i < 16; i+=4) ARM7Write32(0x03FFC580+i, *(u32*)&derp[i]); + u32 eaddr = 0x03FFE6E4; + ARM7Write32(eaddr+0x00, *(u32*)&eMMC_CID[0]); + ARM7Write32(eaddr+0x04, *(u32*)&eMMC_CID[4]); + ARM7Write32(eaddr+0x08, *(u32*)&eMMC_CID[8]); + ARM7Write32(eaddr+0x0C, *(u32*)&eMMC_CID[12]); + ARM7Write16(eaddr+0x2C, 0x0001); + ARM7Write16(eaddr+0x2E, 0x0001); + ARM7Write16(eaddr+0x3C, 0x0100); + ARM7Write16(eaddr+0x3E, 0x40E0); + ARM7Write16(eaddr+0x42, 0x0001); } bool LoadBIOS() @@ -328,19 +339,31 @@ bool LoadNAND() } memset(ITCMInit, 0, 0x8000); + memset(ARM7Init, 0, 0x3C00); - f = fopen("dsikeys.bin", "rb"); + f = fopen("initmem9.bin", "rb"); if (f) { // first 0x2524 bytes are loaded to 0x01FFC400 u32 dstaddr = 0x01FFC400; - fread(&ITCMInit[dstaddr & 0x7FFF], 0x2524, 1, f); + fread(&ITCMInit[dstaddr & 0x7FFF], /*0x2524*/0x3C00, 1, f); fclose(f); } else { - printf("DSi keys not found\n"); + printf("DSi ARM9 meminit not found\n"); + } + + f = fopen("initmem7.bin", "rb"); + if (f) + { + fread(ARM7Init, 0x3C00, 1, f); + fclose(f); + } + else + { + printf("DSi ARM7 meminit not found\n"); } return true; @@ -559,7 +582,7 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val) u8 ARM9Read8(u32 addr) -{ +{if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 8 9 %08X %08X\n", addr, NDS::GetPC(0)); switch (addr & 0xFF000000) { case 0x03000000: @@ -588,7 +611,7 @@ u8 ARM9Read8(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) { case 0x03000000: @@ -617,7 +640,8 @@ u16 ARM9Read16(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) { case 0x03000000: @@ -712,7 +736,7 @@ void ARM9Write16(u32 addr, u16 val) } void ARM9Write32(u32 addr, u32 val) -{ +{if(addr==0x02B05E34) printf("VGONP. %08X, %08X\n", val, NDS::GetPC(0)); switch (addr & 0xFF000000) { case 0x03000000: @@ -768,7 +792,8 @@ bool ARM9GetMemRegion(u32 addr, bool write, NDS::MemRegion* region) 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) { case 0x03000000: @@ -797,7 +822,8 @@ u8 ARM7Read8(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) { case 0x03000000: @@ -826,7 +852,8 @@ u16 ARM7Read16(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) { case 0x03000000: @@ -855,7 +882,7 @@ u32 ARM7Read32(u32 addr) } void ARM7Write8(u32 addr, u8 val) -{ +{if(addr==0x0228CD74) printf("RAKAKA %02X %08X\n", val, NDS::GetPC(1)); switch (addr & 0xFF800000) { case 0x03000000: diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index 8ae90821..4aa97bc1 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -22,6 +22,7 @@ #include "DSi_AES.h" #include "FIFO.h" #include "tiny-AES-c/aes.hpp" +#include "Platform.h" namespace DSi_AES @@ -130,6 +131,7 @@ void Reset() // initialize keys, as per GBAtek +#if 0 // slot 0: modcrypt *(u32*)&KeyX[0][0] = 0x746E694E; *(u32*)&KeyX[0][4] = 0x6F646E65; @@ -148,6 +150,27 @@ void Reset() *(u32*)&KeyY[3][0] = 0x0AB9DC76; *(u32*)&KeyY[3][4] = 0xBD4DC4D3; *(u32*)&KeyY[3][8] = 0x202DDD1D; +#endif + FILE* f = Platform::OpenLocalFile("aeskeys.bin", "rb"); + if (f) + { + fread(KeyNormal[0], 16, 1, f); + fread(KeyX[0], 16, 1, f); + fread(KeyY[0], 16, 1, f); + fread(KeyNormal[1], 16, 1, f); + fread(KeyX[1], 16, 1, f); + fread(KeyY[1], 16, 1, f); + fread(KeyNormal[2], 16, 1, f); + fread(KeyX[2], 16, 1, f); + fread(KeyY[2], 16, 1, f); + fread(KeyNormal[3], 16, 1, f); + fread(KeyX[3], 16, 1, f); + fread(KeyY[3], 16, 1, f); + + fclose(f); + } + else + printf("AES: aeskeys.bin not found\n"); } diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 52365516..e0591fb4 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -114,11 +114,20 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host) { TransferCmd = 0xFFFFFFFF; RemSize = 0; + + WindowData = 0; + WindowReadAddr = 0; + WindowWriteAddr = 0; + + // TODO: check the actual mailbox size (presumably 0x200) + for (int i = 0; i < 8; i++) + Mailbox[i] = new FIFO(0x200); } DSi_NWifi::~DSi_NWifi() { - // + for (int i = 0; i < 8; i++) + delete Mailbox[i]; } @@ -165,9 +174,54 @@ void DSi_NWifi::F0_Write(u32 addr, u8 val) u8 DSi_NWifi::F1_Read(u32 addr) -{ - switch (addr) +{printf("F1 READ %05X\n", addr); + if (addr < 0x100) { + return Mailbox[4]->Read(); + } + else if (addr < 0x200) + { + return Mailbox[5]->Read(); + } + else if (addr < 0x300) + { + return Mailbox[6]->Read(); + } + else if (addr < 0x400) + { + return Mailbox[7]->Read(); + } + else if (addr < 0x800) + { + switch (addr) + { + case 0x00450: return 1; // HAX!! + + case 0x00474: return WindowData & 0xFF; + case 0x00475: return (WindowData >> 8) & 0xFF; + case 0x00476: return (WindowData >> 16) & 0xFF; + case 0x00477: return WindowData >> 24; + } + } + else if (addr < 0x1000) + { + return Mailbox[4]->Read(); + } + else if (addr < 0x1800) + { + return Mailbox[5]->Read(); + } + else if (addr < 0x2000) + { + return Mailbox[6]->Read(); + } + else if (addr < 0x2800) + { + return Mailbox[7]->Read(); + } + else + { + return Mailbox[4]->Read(); } printf("NWIFI: unknown func1 read %05X\n", addr); @@ -175,7 +229,91 @@ u8 DSi_NWifi::F1_Read(u32 addr) } void DSi_NWifi::F1_Write(u32 addr, u8 val) -{ +{printf("F1 WRITE %05X %02X\n", addr, val); + if (addr < 0x100) + { + if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); + Mailbox[0]->Write(val); + if (addr == 0xFF) BMI_Command(); + return; + } + else if (addr < 0x200) + { + if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n"); + Mailbox[1]->Write(val); + return; + } + else if (addr < 0x300) + { + if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n"); + Mailbox[2]->Write(val); + return; + } + else if (addr < 0x400) + { + if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n"); + Mailbox[3]->Write(val); + return; + } + else if (addr < 0x800) + { + switch (addr) + { + case 0x00474: WindowData = (WindowData & 0xFFFFFF00) | val; return; + case 0x00475: WindowData = (WindowData & 0xFFFF00FF) | (val << 8); return; + case 0x00476: WindowData = (WindowData & 0xFF00FFFF) | (val << 16); return; + case 0x00477: WindowData = (WindowData & 0x00FFFFFF) | (val << 24); return; + + case 0x00478: + WindowWriteAddr = (WindowWriteAddr & 0xFFFFFF00) | val; + WindowWrite(); + return; + case 0x00479: WindowWriteAddr = (WindowWriteAddr & 0xFFFF00FF) | (val << 8); return; + case 0x0047A: WindowWriteAddr = (WindowWriteAddr & 0xFF00FFFF) | (val << 16); return; + case 0x0047B: WindowWriteAddr = (WindowWriteAddr & 0x00FFFFFF) | (val << 24); return; + + case 0x0047C: + WindowReadAddr = (WindowReadAddr & 0xFFFFFF00) | val; + WindowRead(); + return; + case 0x0047D: WindowReadAddr = (WindowReadAddr & 0xFFFF00FF) | (val << 8); return; + case 0x0047E: WindowReadAddr = (WindowReadAddr & 0xFF00FFFF) | (val << 16); return; + case 0x0047F: WindowReadAddr = (WindowReadAddr & 0x00FFFFFF) | (val << 24); return; + } + } + else if (addr < 0x1000) + { + if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); + Mailbox[0]->Write(val); + if (addr == 0xFFF) BMI_Command(); + return; + } + else if (addr < 0x1800) + { + if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n"); + Mailbox[1]->Write(val); + return; + } + else if (addr < 0x2000) + { + if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n"); + Mailbox[2]->Write(val); + return; + } + else if (addr < 0x2800) + { + if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n"); + Mailbox[3]->Write(val); + return; + } + else + { + if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); + Mailbox[0]->Write(val); + if (addr == 0x3FFF) BMI_Command(); // CHECKME + return; + } + printf("NWIFI: unknown func1 write %05X %02X\n", addr, val); } @@ -185,6 +323,7 @@ u8 DSi_NWifi::SDIO_Read(u32 func, u32 addr) switch (func) { case 0: return F0_Read(addr); + case 1: return F1_Read(addr); } printf("NWIFI: unknown SDIO read %d %05X\n", func, addr); @@ -196,6 +335,7 @@ void DSi_NWifi::SDIO_Write(u32 func, u32 addr, u8 val) switch (func) { case 0: return F0_Write(addr, val); + case 1: return F1_Write(addr, val); } printf("NWIFI: unknown SDIO write %d %05X %02X\n", func, addr, val); @@ -203,7 +343,7 @@ void DSi_NWifi::SDIO_Write(u32 func, u32 addr, u8 val) void DSi_NWifi::SendCMD(u8 cmd, u32 param) -{ +{printf("NWIFI CMD %d %08X %08X\n", cmd, param, NDS::GetPC(1)); switch (cmd) { case 52: // IO_RW_DIRECT @@ -315,24 +455,62 @@ void DSi_NWifi::WriteBlock() u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize; u8 data[0x200]; - Host->ReceiveData(data, len); - - for (u32 i = 0; i < len; i++) + if (Host->ReceiveData(data, len)) { - SDIO_Write(func, TransferAddr, data[i]); - if (TransferCmd & (1<<26)) + for (u32 i = 0; i < len; i++) { - TransferAddr++; - TransferAddr &= 0x1FFFF; // checkme + SDIO_Write(func, TransferAddr, data[i]); + if (TransferCmd & (1<<26)) + { + TransferAddr++; + TransferAddr &= 0x1FFFF; // checkme + } } - } - if (RemSize > 0) - { - RemSize -= len; - if (RemSize == 0) + if (RemSize > 0) { - // TODO? + RemSize -= len; + if (RemSize == 0) + { + // TODO? + } } } } + + +void DSi_NWifi::BMI_Command() +{ + // HLE command handling stub + u32 cmd = MB_Read32(0); + printf("BMI: cmd %08X\n", cmd); + + switch (cmd) + { + case 0x08: // BMI_GET_TARGET_ID + MB_Write32(4, 0xFFFFFFFF); + MB_Write32(4, 0x0000000C); + MB_Write32(4, 0x20000118); + MB_Write32(4, 0x00000002); + return; + } +} + + +void DSi_NWifi::WindowRead() +{ + printf("NWifi: window read %08X\n", WindowReadAddr); + + switch (WindowReadAddr) + { + case 0x40EC: WindowData = 0x02000001; return; + + // SOC_RESET_CAUSE + case 0x40C0: WindowData = 2; return; + } +} + +void DSi_NWifi::WindowWrite() +{ + printf("NWifi: window write %08X %08X\n", WindowWriteAddr, WindowData); +} diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h index 5d61951c..4ec010e5 100644 --- a/src/DSi_NWifi.h +++ b/src/DSi_NWifi.h @@ -20,6 +20,7 @@ #define DSI_NWIFI_H #include "DSi_SD.h" +#include "FIFO.h" class DSi_NWifi : public DSi_SDDevice { @@ -48,6 +49,32 @@ private: void ReadBlock(); void WriteBlock(); + + void BMI_Command(); + + void WindowRead(); + void WindowWrite(); + + u32 MB_Read32(int n) + { + u32 ret = Mailbox[n]->Read(); + ret |= (Mailbox[n]->Read() << 8); + ret |= (Mailbox[n]->Read() << 16); + ret |= (Mailbox[n]->Read() << 24); + return ret; + } + + 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); + } + + FIFO* Mailbox[8]; + + u32 WindowData, WindowReadAddr, WindowWriteAddr; }; #endif // DSI_NWIFI_H diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index 6e73df5d..c9edd788 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -185,7 +185,8 @@ void DSi_SDHost::SendData(u8* data, u32 len) // but if IRQ24 is thrown instantly, the handler clears IRQ0 before the // send-command function starts polling IRQ status u32 param = Num | (last << 1); - NDS::ScheduleEvent(NDS::Event_DSi_SDTransfer, false, 512, FinishSend, param); + NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + false, 512, FinishSend, param); } void DSi_SDHost::FinishReceive(u32 param) @@ -199,13 +200,19 @@ void DSi_SDHost::FinishReceive(u32 param) if (dev) dev->ContinueTransfer(); } -void DSi_SDHost::ReceiveData(u8* data, u32 len) +bool 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); if (len != BlockLen16) printf("!! BAD BLOCKLEN\n"); - DSi_SDDevice* dev = Ports[PortSelect & 0x1]; u32 f = CurFIFO; + 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); + return false; + } + + DSi_SDDevice* dev = Ports[PortSelect & 0x1]; for (u32 i = 0; i < len; i += 2) *(u16*)&data[i] = DataFIFO[f]->Read(); @@ -213,7 +220,7 @@ void DSi_SDHost::ReceiveData(u8* data, u32 len) if (BlockCountInternal <= 1) { - printf("%s: data32 TX complete", SD_DESC); + printf("%s: data TX complete", SD_DESC); if (StopAction & (1<<8)) { @@ -232,12 +239,14 @@ void DSi_SDHost::ReceiveData(u8* data, u32 len) { BlockCountInternal--; } + + return true; } u16 DSi_SDHost::Read(u32 addr) { - //printf("SDMMC READ %08X %08X\n", addr, NDS::GetPC(1)); + //if(Num)printf("SDIO READ %08X %08X\n", addr, NDS::GetPC(1)); switch (addr & 0x1FF) { @@ -383,7 +392,7 @@ u32 DSi_SDHost::ReadFIFO32() void DSi_SDHost::Write(u32 addr, u16 val) { - //printf("SDMMC WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1)); + //if(Num)printf("SDIO WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1)); switch (addr & 0x1FF) { @@ -421,7 +430,11 @@ void DSi_SDHost::Write(u32 addr, u16 val) case 0x01C: IRQStatus &= (val | 0xFFFF0000); return; case 0x01E: IRQStatus &= ((val << 16) | 0xFFFF); return; case 0x020: IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D); return; - case 0x022: IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16); return; + case 0x022: + IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16); + if (!DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(24); // checkme + if (DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(25); // checkme + return; case 0x024: SDClock = val & 0x03FF; return; case 0x026: @@ -430,6 +443,33 @@ void DSi_SDHost::Write(u32 addr, u16 val) return; case 0x028: SDOption = val & 0xC1FF; return; + case 0x030: // FIFO16 + { + DSi_SDDevice* dev = Ports[PortSelect & 0x1]; + u32 f = CurFIFO; + if (DataFIFO[f]->IsFull()) + { + // TODO + printf("!!!! %s FIFO FULL\n", SD_DESC); + return; + } + + DataFIFO[f]->Write(val); + + if (DataFIFO[f]->Level() < (BlockLen16>>1)) + { + ClearIRQ(25); + SetIRQ(24); + return; + } + + // we completed one block, send it to the SD card + // TODO measure the actual delay!! + NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + false, 2048, FinishReceive, Num); + } + return; + case 0x0D8: DataCtl = (val & 0x0022); DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1); @@ -494,13 +534,9 @@ void DSi_SDHost::WriteFIFO32(u32 val) } // we completed one block, send it to the SD card - - //ClearIRQ(24); - //SetIRQ(25); - - //if (dev) dev->ContinueTransfer(); // TODO measure the actual delay!! - NDS::ScheduleEvent(NDS::Event_DSi_SDTransfer, false, 2048, FinishReceive, Num); + NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + false, 2048, FinishReceive, Num); } @@ -726,7 +762,9 @@ void DSi_MMCStorage::WriteBlock(u64 addr) printf("SD/MMC: write block @ %08X, len=%08X\n", addr, BlockSize); u8 data[0x200]; - Host->ReceiveData(data, BlockSize); - fseek(File, addr, SEEK_SET); - fwrite(data, 1, BlockSize, File); + if (Host->ReceiveData(data, BlockSize)) + { + fseek(File, addr, SEEK_SET); + fwrite(data, 1, BlockSize, File); + } } diff --git a/src/DSi_SD.h b/src/DSi_SD.h index 855dd5ed..22475d6c 100644 --- a/src/DSi_SD.h +++ b/src/DSi_SD.h @@ -40,7 +40,7 @@ public: static void FinishReceive(u32 param); void SendResponse(u32 val, bool last); void SendData(u8* data, u32 len); - void ReceiveData(u8* data, u32 len); + bool ReceiveData(u8* data, u32 len); u16 Read(u32 addr); void Write(u32 addr, u16 val); diff --git a/src/NDS.h b/src/NDS.h index 850e829e..e32908b9 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -43,7 +43,8 @@ enum Event_Sqrt, // DSi - Event_DSi_SDTransfer, + Event_DSi_SDMMCTransfer, + Event_DSi_SDIOTransfer, Event_MAX };