From dd94cd5e77e32ae86c51bbe2a738ea8a04dbf7be Mon Sep 17 00:00:00 2001 From: RocketRobz Date: Tue, 14 Jul 2020 17:26:05 -0600 Subject: [PATCH] Ntr sd access (#61) * Port SD code from nds-bootstrap Currently freezes on `mounting drive(s)...` * Disable NAND mounting for now * Derp fix, and add verbose output * NAND and SD access now work --- arm7/source/main.c | 6 +- arm7/source/my_sdmmc.c | 576 ++++++++++++++++++++++++++++++++ arm7/source/my_system.c | 53 +++ arm9/source/driveOperations.cpp | 4 +- arm9/source/main.cpp | 6 +- 5 files changed, 638 insertions(+), 7 deletions(-) create mode 100644 arm7/source/my_sdmmc.c create mode 100644 arm7/source/my_system.c diff --git a/arm7/source/main.c b/arm7/source/main.c index af815be..ae17f86 100644 --- a/arm7/source/main.c +++ b/arm7/source/main.c @@ -30,6 +30,8 @@ #include #include +void my_installSystemFIFO(void); + unsigned int * SCFG_EXT=(unsigned int*)0x4004008; //--------------------------------------------------------------------------------- @@ -112,7 +114,7 @@ int main() { SetYtrigger(80); - installSystemFIFO(); + my_installSystemFIFO(); irqSet(IRQ_VCOUNT, VcountHandler); irqSet(IRQ_VBLANK, VblankHandler); @@ -162,7 +164,7 @@ int main() { exitflag = true; } if (*(u32*)(0x2FFFD0C) == 0x454D4D43) { - sdmmc_nand_cid((u32*)0x2FFD7BC); // Get eMMC CID + my_sdmmc_get_cid(true, (u32*)0x2FFD7BC); // Get eMMC CID *(u32*)(0x2FFFD0C) = 0; } *(u8*)(0x2FFFD08) = ((*(vu32*)(0x400481C) & BIT(3)) || !(*(vu32*)(0x400481C) & BIT(5))); // Set if there's no SD inserted diff --git a/arm7/source/my_sdmmc.c b/arm7/source/my_sdmmc.c new file mode 100644 index 0000000..4769753 --- /dev/null +++ b/arm7/source/my_sdmmc.c @@ -0,0 +1,576 @@ +#include +#include +#include +#include +#include +#include + +#include + +static struct mmcdevice deviceSD; +static struct mmcdevice deviceNAND; + +/*mmcdevice *getMMCDevice(int drive) { + if(drive==0) return &deviceNAND; + return &deviceSD; +} +*/ + +//--------------------------------------------------------------------------------- +int my_geterror(struct mmcdevice *ctx) { +//--------------------------------------------------------------------------------- + //if(ctx->error == 0x4) return -1; + //else return 0; + return (ctx->error << 29) >> 31; +} + + +//--------------------------------------------------------------------------------- +void my_setTarget(struct mmcdevice *ctx) { +//--------------------------------------------------------------------------------- + sdmmc_mask16(REG_SDPORTSEL,0x3,(u16)ctx->devicenumber); + setckl(ctx->clk); + if (ctx->SDOPT == 0) { + sdmmc_mask16(REG_SDOPT, 0, 0x8000); + } else { + sdmmc_mask16(REG_SDOPT, 0x8000, 0); + } + +} + + +//--------------------------------------------------------------------------------- +void my_sdmmc_send_command(struct mmcdevice *ctx, uint32_t cmd, uint32_t args) { +//--------------------------------------------------------------------------------- + int i; + bool getSDRESP = (cmd << 15) >> 31; + uint16_t flags = (cmd << 15) >> 31; + const bool readdata = cmd & 0x20000; + const bool writedata = cmd & 0x40000; + + if(readdata || writedata) + { + flags |= TMIO_STAT0_DATAEND; + } + + ctx->error = 0; + while((sdmmc_read16(REG_SDSTATUS1) & TMIO_STAT1_CMD_BUSY)); //mmc working? + sdmmc_write16(REG_SDIRMASK0,0); + sdmmc_write16(REG_SDIRMASK1,0); + sdmmc_write16(REG_SDSTATUS0,0); + sdmmc_write16(REG_SDSTATUS1,0); +#ifdef DATA32_SUPPORT +// if(readdata)sdmmc_mask16(REG_DATACTL32, 0x1000, 0x800); +// if(writedata)sdmmc_mask16(REG_DATACTL32, 0x800, 0x1000); +// sdmmc_mask16(REG_DATACTL32,0x1800,2); +#else + sdmmc_mask16(REG_DATACTL32,0x1800,0); +#endif + sdmmc_write16(REG_SDCMDARG0,args &0xFFFF); + sdmmc_write16(REG_SDCMDARG1,args >> 16); + sdmmc_write16(REG_SDCMD,cmd &0xFFFF); + + uint32_t size = ctx->size; + uint16_t *dataPtr = (uint16_t*)ctx->data; + uint32_t *dataPtr32 = (uint32_t*)ctx->data; + + bool useBuf = ( NULL != dataPtr ); + bool useBuf32 = (useBuf && (0 == (3 & ((uint32_t)dataPtr)))); + + uint16_t status0 = 0; + + while(1) { + volatile uint16_t status1 = sdmmc_read16(REG_SDSTATUS1); +#ifdef DATA32_SUPPORT + volatile uint16_t ctl32 = sdmmc_read16(REG_SDDATACTL32); + if((ctl32 & 0x100)) +#else + if((status1 & TMIO_STAT1_RXRDY)) +#endif + { + if(readdata) { + if(useBuf) { + sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0); + if(size > 0x1FF) { +#ifdef DATA32_SUPPORT + if(useBuf32) { + for(i = 0; i<0x200; i+=4) { + *dataPtr32++ = sdmmc_read32(REG_SDFIFO32); + } + } else { +#endif + for(i = 0; i<0x200; i+=2) { + *dataPtr++ = sdmmc_read16(REG_SDFIFO); + } +#ifdef DATA32_SUPPORT + } +#endif + size -= 0x200; + } + } + + sdmmc_mask16(REG_SDDATACTL32, 0x800, 0); + } + } +#ifdef DATA32_SUPPORT + if(!(ctl32 & 0x200)) +#else + if((status1 & TMIO_STAT1_TXRQ)) +#endif + { + if(writedata) { + if(useBuf) { + sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0); + //sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_TXRQ); + if(size > 0x1FF) { +#ifdef DATA32_SUPPORT + for(i = 0; i<0x200; i+=4) { + sdmmc_write32(REG_SDFIFO32,*dataPtr32++); + } +#else + for(i = 0; i<0x200; i+=2) { + sdmmc_write16(REG_SDFIFO,*dataPtr++); + } +#endif + size -= 0x200; + } + } + + sdmmc_mask16(REG_SDDATACTL32, 0x1000, 0); + } + } + if(status1 & TMIO_MASK_GW) { + ctx->error |= 4; + break; + } + + if(!(status1 & TMIO_STAT1_CMD_BUSY)) { + status0 = sdmmc_read16(REG_SDSTATUS0); + if(sdmmc_read16(REG_SDSTATUS0) & TMIO_STAT0_CMDRESPEND) { + ctx->error |= 0x1; + } + if(status0 & TMIO_STAT0_DATAEND) { + ctx->error |= 0x2; + } + + if((status0 & flags) == flags) + break; + } + } + ctx->stat0 = sdmmc_read16(REG_SDSTATUS0); + ctx->stat1 = sdmmc_read16(REG_SDSTATUS1); + sdmmc_write16(REG_SDSTATUS0,0); + sdmmc_write16(REG_SDSTATUS1,0); + + if(getSDRESP != 0) { + ctx->ret[0] = sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1) << 16); + ctx->ret[1] = sdmmc_read16(REG_SDRESP2) | (sdmmc_read16(REG_SDRESP3) << 16); + ctx->ret[2] = sdmmc_read16(REG_SDRESP4) | (sdmmc_read16(REG_SDRESP5) << 16); + ctx->ret[3] = sdmmc_read16(REG_SDRESP6) | (sdmmc_read16(REG_SDRESP7) << 16); + } +} + + +//--------------------------------------------------------------------------------- +int my_sdmmc_cardinserted() { +//--------------------------------------------------------------------------------- + return 1; //my_sdmmc_cardready; +} + + +static bool my_sdmmc_controller_initialised = false; + +//--------------------------------------------------------------------------------- +void my_sdmmc_controller_init( bool force_init ) { +//--------------------------------------------------------------------------------- + + if (!force_init && my_sdmmc_controller_initialised) return; + + deviceSD.isSDHC = 0; + deviceSD.SDOPT = 0; + deviceSD.res = 0; + deviceSD.initarg = 0; + deviceSD.clk = 0x80; + deviceSD.devicenumber = 0; + + deviceNAND.isSDHC = 0; + deviceNAND.SDOPT = 0; + deviceNAND.res = 0; + deviceNAND.initarg = 1; + deviceNAND.clk = 0x80; + deviceNAND.devicenumber = 1; + + *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xF7FFu; + *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xEFFFu; +#ifdef DATA32_SUPPORT + *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u; +#else + *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) |= 0x402u; +#endif + *(vu16*)(SDMMC_BASE + REG_SDDATACTL) = (*(vu16*)(SDMMC_BASE + REG_SDDATACTL) & 0xFFDD) | 2; +#ifdef DATA32_SUPPORT + *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFFu; + *(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDFu; + *(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 512; +#else + *(vu16*)(SDMMC_BASE + REG_SDDATACTL32) &= 0xFFFDu; + *(vu16*)(SDMMC_BASE + REG_SDDATACTL) &= 0xFFDDu; + *(vu16*)(SDMMC_BASE + REG_SDBLKLEN32) = 0; +#endif + *(vu16*)(SDMMC_BASE + REG_SDBLKCOUNT32) = 1; + *(vu16*)(SDMMC_BASE + REG_SDRESET) &= 0xFFFEu; + *(vu16*)(SDMMC_BASE + REG_SDRESET) |= 1u; + *(vu16*)(SDMMC_BASE + REG_SDIRMASK0) |= TMIO_MASK_ALL; + *(vu16*)(SDMMC_BASE + REG_SDIRMASK1) |= TMIO_MASK_ALL>>16; + *(vu16*)(SDMMC_BASE + 0x0fc) |= 0xDBu; //SDCTL_RESERVED7 + *(vu16*)(SDMMC_BASE + 0x0fe) |= 0xDBu; //SDCTL_RESERVED8 + *(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu; +#ifdef DATA32_SUPPORT + *(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x20; + *(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EE; +#else + *(vu16*)(SDMMC_BASE + REG_SDCLKCTL) = 0x40; //Nintendo sets this to 0x20 + *(vu16*)(SDMMC_BASE + REG_SDOPT) = 0x40EB; //Nintendo sets this to 0x40EE +#endif + *(vu16*)(SDMMC_BASE + REG_SDPORTSEL) &= 0xFFFCu; + *(vu16*)(SDMMC_BASE + REG_SDBLKLEN) = 512; + *(vu16*)(SDMMC_BASE + REG_SDSTOP) = 0; + + my_sdmmc_controller_initialised = true; + + my_setTarget(&deviceSD); +} + +//--------------------------------------------------------------------------------- +static u32 calcSDSize(u8* csd, int type) { +//--------------------------------------------------------------------------------- + u32 result = 0; + if (type == -1) type = csd[14] >> 6; + switch (type) { + case 0: + { + u32 block_len = csd[9] & 0xf; + block_len = 1 << block_len; + u32 mult = (csd[4] >> 7) | ((csd[5] & 3) << 1); + mult = 1 << (mult + 2); + result = csd[8] & 3; + result = (result << 8) | csd[7]; + result = (result << 2) | (csd[6] >> 6); + result = (result + 1) * mult * block_len / 512; + } + break; + case 1: + result = csd[7] & 0x3f; + result = (result << 8) | csd[6]; + result = (result << 8) | csd[5]; + result = (result + 1) * 1024; + break; + } + return result; +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_sdcard_init() { +//--------------------------------------------------------------------------------- + my_setTarget(&deviceSD); + swiDelay(0xF000); + + // card reset + my_sdmmc_send_command(&deviceSD,0,0); + + // CMD8 0x1AA + my_sdmmc_send_command(&deviceSD,0x10408,0x1AA); + u32 temp = (deviceSD.error & 0x1) << 0x1E; + + u32 temp2 = 0; + do { + do { + // CMD55 + my_sdmmc_send_command(&deviceSD,0x10437,deviceSD.initarg << 0x10); + // ACMD41 + my_sdmmc_send_command(&deviceSD,0x10769,0x00FF8000 | temp); + temp2 = 1; + } while ( !(deviceSD.error & 1) ); + + } while((deviceSD.ret[0] & 0x80000000) == 0); + + if(!((deviceSD.ret[0] >> 30) & 1) || !temp) + temp2 = 0; + + deviceSD.isSDHC = temp2; + + my_sdmmc_send_command(&deviceSD,0x10602,0); + if (deviceSD.error & 0x4) return -1; + + my_sdmmc_send_command(&deviceSD,0x10403,0); + if (deviceSD.error & 0x4) return -1; + deviceSD.initarg = deviceSD.ret[0] >> 0x10; + + my_sdmmc_send_command(&deviceSD,0x10609,deviceSD.initarg << 0x10); + if (deviceSD.error & 0x4) return -1; + + deviceSD.total_size = calcSDSize((u8*)&deviceSD.ret[0],-1); + deviceSD.clk = 1; + setckl(1); + + my_sdmmc_send_command(&deviceSD,0x10507,deviceSD.initarg << 0x10); + if (deviceSD.error & 0x4) return -1; + + // CMD55 + my_sdmmc_send_command(&deviceSD,0x10437,deviceSD.initarg << 0x10); + if (deviceSD.error & 0x4) return -1; + + // ACMD42 + my_sdmmc_send_command(&deviceSD,0x1076A,0x0); + if (deviceSD.error & 0x4) return -1; + + // CMD55 + my_sdmmc_send_command(&deviceSD,0x10437,deviceSD.initarg << 0x10); + if (deviceSD.error & 0x4) return -1; + + deviceSD.SDOPT = 1; + my_sdmmc_send_command(&deviceSD,0x10446,0x2); + if (deviceSD.error & 0x4) return -1; + + my_sdmmc_send_command(&deviceSD,0x1040D,deviceSD.initarg << 0x10); + if (deviceSD.error & 0x4) return -1; + + my_sdmmc_send_command(&deviceSD,0x10410,0x200); + if (deviceSD.error & 0x4) return -1; + deviceSD.clk |= 0x200; + + return 0; + +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_nand_init() { +//--------------------------------------------------------------------------------- + my_setTarget(&deviceNAND); + swiDelay(0xF000); + + my_sdmmc_send_command(&deviceNAND,0,0); + + do { + do { + my_sdmmc_send_command(&deviceNAND,0x10701,0x100000); + } while ( !(deviceNAND.error & 1) ); + } + while((deviceNAND.ret[0] & 0x80000000) == 0); + + my_sdmmc_send_command(&deviceNAND,0x10602,0x0); + if((deviceNAND.error & 0x4))return -1; + + my_sdmmc_send_command(&deviceNAND,0x10403,deviceNAND.initarg << 0x10); + if((deviceNAND.error & 0x4))return -1; + + my_sdmmc_send_command(&deviceNAND,0x10609,deviceNAND.initarg << 0x10); + if((deviceNAND.error & 0x4))return -1; + + deviceNAND.total_size = calcSDSize((uint8_t*)&deviceNAND.ret[0],0); + deviceNAND.clk = 1; + setckl(1); + + my_sdmmc_send_command(&deviceNAND,0x10407,deviceNAND.initarg << 0x10); + if((deviceNAND.error & 0x4))return -1; + + deviceNAND.SDOPT = 1; + + my_sdmmc_send_command(&deviceNAND,0x10506,0x3B70100); + if((deviceNAND.error & 0x4))return -1; + + my_sdmmc_send_command(&deviceNAND,0x10506,0x3B90100); + if((deviceNAND.error & 0x4))return -1; + + my_sdmmc_send_command(&deviceNAND,0x1040D,deviceNAND.initarg << 0x10); + if((deviceNAND.error & 0x4))return -1; + + my_sdmmc_send_command(&deviceNAND,0x10410,0x200); + if((deviceNAND.error & 0x4))return -1; + + deviceNAND.clk |= 0x200; + + my_setTarget(&deviceSD); + + return 0; +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_readsectors(struct mmcdevice *device, u32 sector_no, u32 numsectors, void *out) { +//--------------------------------------------------------------------------------- + if (device->isSDHC == 0) sector_no <<= 9; + my_setTarget(device); + sdmmc_write16(REG_SDSTOP,0x100); + +#ifdef DATA32_SUPPORT + sdmmc_write16(REG_SDBLKCOUNT32,numsectors); + sdmmc_write16(REG_SDBLKLEN32,0x200); +#endif + + sdmmc_write16(REG_SDBLKCOUNT,numsectors); + device->data = out; + device->size = numsectors << 9; + my_sdmmc_send_command(device,0x33C12,sector_no); + my_setTarget(&deviceSD); + return my_geterror(device); +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_writesectors(struct mmcdevice *device, u32 sector_no, u32 numsectors, void *in) { +//--------------------------------------------------------------------------------- + if (device->isSDHC == 0) + sector_no <<= 9; + my_setTarget(device); + sdmmc_write16(REG_SDSTOP,0x100); + +#ifdef DATA32_SUPPORT + sdmmc_write16(REG_SDBLKCOUNT32,numsectors); + sdmmc_write16(REG_SDBLKLEN32,0x200); +#endif + + sdmmc_write16(REG_SDBLKCOUNT,numsectors); + device->data = in; + device->size = numsectors << 9; + my_sdmmc_send_command(device,0x52C19,sector_no); + my_setTarget(&deviceSD); + return my_geterror(device); +} + +//--------------------------------------------------------------------------------- +void my_sdmmc_get_cid(int devicenumber, u32 *cid) { +//--------------------------------------------------------------------------------- + + struct mmcdevice *device = (devicenumber == 1 ? &deviceNAND : &deviceSD); + + int oldIME = enterCriticalSection(); + + my_setTarget(device); + + // use cmd7 to put sd card in standby mode + // CMD7 + my_sdmmc_send_command(device, 0x10507, 0); + + // get sd card info + // use cmd10 to read CID + my_sdmmc_send_command(device, 0x1060A, device->initarg << 0x10); + + for(int i = 0; i < 4; ++i) + cid[i] = device->ret[i]; + + // put sd card back to transfer mode + // CMD7 + my_sdmmc_send_command(device, 0x10507, device->initarg << 0x10); + + leaveCriticalSection(oldIME); +} + +//--------------------------------------------------------------------------------- +void my_sdmmcMsgHandler(int bytes, void *user_data) { +//--------------------------------------------------------------------------------- + FifoMessage msg; + int retval = 0; + + fifoGetDatamsg(FIFO_SDMMC, bytes, (u8*)&msg); + + int oldIME = enterCriticalSection(); + switch (msg.type) { + + case SDMMC_SD_READ_SECTORS: + retval = my_sdmmc_readsectors(&deviceSD, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer); + break; + case SDMMC_SD_WRITE_SECTORS: + retval = my_sdmmc_writesectors(&deviceSD, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer); + break; + case SDMMC_NAND_READ_SECTORS: + retval = my_sdmmc_readsectors(&deviceNAND, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer); + break; + case SDMMC_NAND_WRITE_SECTORS: + retval = my_sdmmc_writesectors(&deviceNAND, msg.sdParams.startsector, msg.sdParams.numsectors, msg.sdParams.buffer); + break; + } + + leaveCriticalSection(oldIME); + + fifoSendValue32(FIFO_SDMMC, retval); +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_nand_startup() { +//--------------------------------------------------------------------------------- + my_sdmmc_controller_init(false); + return my_sdmmc_nand_init(); +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_sd_startup() { +//--------------------------------------------------------------------------------- + my_sdmmc_controller_init(false); + return my_sdmmc_sdcard_init(); +} + +//--------------------------------------------------------------------------------- +void my_sdmmcValueHandler(u32 value, void* user_data) { +//--------------------------------------------------------------------------------- + int result = 0; + int sdflag = 0; + int oldIME = enterCriticalSection(); + + switch(value) { + + case SDMMC_HAVE_SD: + result = sdmmc_read16(REG_SDSTATUS0); + break; + + case SDMMC_SD_START: + sdflag = 1; + /* Falls through. */ + case SDMMC_NAND_START: + if (sdmmc_read16(REG_SDSTATUS0) == 0) { + result = 1; + } else { + result = (sdflag == 1 ) ? my_sdmmc_sd_startup() : my_sdmmc_nand_startup(); + } + break; + + case SDMMC_SD_IS_INSERTED: + result = my_sdmmc_cardinserted(); + break; + + case SDMMC_SD_STOP: + break; + + case SDMMC_NAND_SIZE: + result = deviceNAND.total_size; + break; + } + + leaveCriticalSection(oldIME); + + fifoSendValue32(FIFO_SDMMC, result); +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, void *out) { +//--------------------------------------------------------------------------------- + return my_sdmmc_readsectors(&deviceSD, sector_no, numsectors, out); +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, void *in) { +//--------------------------------------------------------------------------------- + return my_sdmmc_writesectors(&deviceSD, sector_no, numsectors, in); +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, void *out) { +//--------------------------------------------------------------------------------- + return my_sdmmc_readsectors(&deviceNAND, sector_no, numsectors, out); +} + +//--------------------------------------------------------------------------------- +int my_sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, void *in) { +//--------------------------------------------------------------------------------- + return my_sdmmc_writesectors(&deviceNAND, sector_no, numsectors, in); +} + + diff --git a/arm7/source/my_system.c b/arm7/source/my_system.c new file mode 100644 index 0000000..2c241d3 --- /dev/null +++ b/arm7/source/my_system.c @@ -0,0 +1,53 @@ +/*--------------------------------------------------------------------------------- + + Copyright (C) 2005 - 2010 + Michael Noland (joat) + Jason Rogers (Dovoto) + Dave Murphy (WinterMute) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any + damages arising from the use of this software. + + Permission is granted to anyone to use this software for any + purpose, including commercial applications, and to alter it and + redistribute it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source + distribution. + +---------------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include + +void powerValueHandler(u32 value, void* user_data); +void my_sdmmcMsgHandler(int bytes, void *user_data); +void my_sdmmcValueHandler(u32 value, void* user_data); +void firmwareMsgHandler(int bytes, void *user_data); + +//--------------------------------------------------------------------------------- +void my_installSystemFIFO(void) { +//--------------------------------------------------------------------------------- + + fifoSetValue32Handler(FIFO_PM, powerValueHandler, 0); + //if (isDSiMode()) { + fifoSetValue32Handler(FIFO_SDMMC, my_sdmmcValueHandler, 0); + fifoSetDatamsgHandler(FIFO_SDMMC, my_sdmmcMsgHandler, 0); + //} + fifoSetDatamsgHandler(FIFO_FIRMWARE, firmwareMsgHandler, 0); + +} + + diff --git a/arm9/source/driveOperations.cpp b/arm9/source/driveOperations.cpp index 61087e8..1e34278 100644 --- a/arm9/source/driveOperations.cpp +++ b/arm9/source/driveOperations.cpp @@ -152,7 +152,7 @@ TWL_CODE void nandUnmount(void) { nandMounted = false; } -TWL_CODE bool sdMount(void) { +bool sdMount(void) { fatMountSimple("sd", get_io_dsisd()); if (sdFound()) { sdMountedDone = true; @@ -167,7 +167,7 @@ TWL_CODE bool sdMount(void) { return false; } -TWL_CODE void sdUnmount(void) { +void sdUnmount(void) { fatUnmount("sd"); sdLabel[0] = '\0'; sdSize = 0; diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index 07d33bc..79b68dc 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -201,14 +201,14 @@ int main(int argc, char **argv) { sysSetCartOwner (BUS_OWNER_ARM9); // Allow arm9 to access GBA ROM + if (*(u8*)(0x2FFFD08) == 0) { + sdMounted = sdMount(); + } if (isDSiMode()) { scanKeys(); if (keysHeld() & KEY_Y) { yHeld = true; } - if (*(u8*)(0x2FFFD08) == 0) { - sdMounted = sdMount(); - } ramdrive1Mount(); *(vu32*)(0x0DFFFE0C) = 0x474D3969; // Check for 32MB of RAM if (*(vu32*)(0x0DFFFE0C) == 0x474D3969) {