diff --git a/arm9/source/driveMenu.cpp b/arm9/source/driveMenu.cpp index 78b5e35..7c8c54d 100644 --- a/arm9/source/driveMenu.cpp +++ b/arm9/source/driveMenu.cpp @@ -264,10 +264,10 @@ void driveMenu (void) { romTitle[1][0] = 0; romSize[1] = 0; } - if (((io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || (isRegularDS && !flashcardMounted && romTitle[1][0] != 0)) + if (((io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || ramdriveMounted || (isRegularDS && !flashcardMounted && romTitle[1][0] != 0)) || (isDSiMode() && !arm7SCFGLocked && !(REG_SCFG_MC & BIT(0)))) { dmOperations.push_back(DriveMenuOperation::ndsCard); - if(romTitle[0][0] == 0 && ((io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || !flashcardMounted) && !isRegularDS) { + if(romTitle[0][0] == 0 && ((io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || !flashcardMounted || ramdriveMounted) && !isRegularDS) { sNDSHeaderExt ndsHeader; cardInit(&ndsHeader); tonccpy(romTitle[0], ndsHeader.gameTitle, 12); @@ -364,7 +364,7 @@ void driveMenu (void) { screenMode = 1; break; } - } else if (dmOperations[dmCursorPosition] == DriveMenuOperation::ndsCard && (sdMounted || flashcardMounted || romTitle[1][0] != 0)) { + } else if (dmOperations[dmCursorPosition] == DriveMenuOperation::ndsCard && (sdMounted || flashcardMounted || ramdriveMounted || romTitle[1][0] != 0)) { ndsCardDump(); } else if (dmOperations[dmCursorPosition] == DriveMenuOperation::ramDrive && ramdriveMounted) { currentDrive = Drive::ramDrive; diff --git a/arm9/source/driveOperations.cpp b/arm9/source/driveOperations.cpp index dcb9524..3cfa499 100644 --- a/arm9/source/driveOperations.cpp +++ b/arm9/source/driveOperations.cpp @@ -53,6 +53,14 @@ u64 fatSize = 0; u64 imgSize = 0; u32 ramdSize = 0; +const char* getDefaultDrivePath(void) { + if(sdMounted) + return "sd"; + if(flashcardMounted) + return "fat"; + return "ram"; +} + const char* getDrivePath(void) { switch (currentDrive) { case Drive::sdCard: @@ -339,13 +347,18 @@ void flashcardUnmount(void) { } void ramdriveMount(bool ram32MB) { + //alloc 1 mb of ram, leaving 3 for the program + baseSectors = 0x800; + ramdSectors = 0x800; + ramdLocMep = nullptr; if(isDSiMode() || REG_SCFG_EXT != 0) { ramdSectors = ram32MB ? 0xE000 : 0x6000; - - fatMountSimple("ram", &io_ram_drive); + ramdLocMep = ram32MB ? (u8*)0x0D000000 : nullptr; + baseSectors = 0x6000; } else if (isRegularDS) { - ramdSectors = 0x8 + 0x4000; - ramdLocMep = (u8*)0x09000000; + auto mepBaseSectors = 0x8; + auto mepRamdSectors = mepBaseSectors + 0x4000; + auto mepRamdLocMep = (u8*)0x09000000; if (*(u16*)(0x020000C0) != 0x334D && *(u16*)(0x020000C0) != 0x3647 && *(u16*)(0x020000C0) != 0x4353 && *(u16*)(0x020000C0) != 0x5A45) { *(u16*)(0x020000C0) = 0; // Clear Slot-2 flashcard flag @@ -382,17 +395,21 @@ void ramdriveMount(bool ram32MB) { } if (*(u16*)(0x020000C0) == 0x334D || *(u16*)(0x020000C0) == 0x3647 || *(u16*)(0x020000C0) == 0x4353) { - ramdLocMep = (u8*)0x08000000; - ramdSectors = 0x8 + 0x10000; + mepRamdLocMep = (u8*)0x08000000; + mepRamdSectors = mepBaseSectors + 0x10000; } else if (*(u16*)(0x020000C0) == 0x5A45) { - ramdLocMep = (u8*)0x08000000; - ramdSectors = 0x8 + 0x8000; + mepRamdLocMep = (u8*)0x08000000; + mepRamdSectors = mepBaseSectors + 0x8000; } if (*(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1) { - fatMountSimple("ram", &io_ram_drive); + baseSectors = mepBaseSectors; + ramdSectors = mepRamdSectors; + ramdLocMep = mepRamdLocMep; } } + + fatMountSimple("ram", &io_ram_drive); ramdriveMounted = (access("ram:/", F_OK) == 0); @@ -478,7 +495,7 @@ bool driveRemoved(Drive drive) { case Drive::flashcard: return isDSiMode() ? REG_SCFG_MC & BIT(0) : !flashcardMounted; case Drive::ramDrive: - return (isDSiMode() || REG_SCFG_EXT != 0) ? !ramdriveMounted : !(*(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1); + return (isDSiMode() || REG_SCFG_EXT != 0 || ramdLocMep == nullptr) ? !ramdriveMounted : !(*(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1); case Drive::nand: return !nandMounted; case Drive::nandPhoto: diff --git a/arm9/source/driveOperations.h b/arm9/source/driveOperations.h index 8299afd..c958279 100644 --- a/arm9/source/driveOperations.h +++ b/arm9/source/driveOperations.h @@ -38,6 +38,7 @@ extern u64 fatSize; extern u64 imgSize; extern u32 ramdSize; +extern const char* getDefaultDrivePath(void); extern const char* getDrivePath(void); extern Drive getDriveFromPath(const char *path); diff --git a/arm9/source/dumpOperations.cpp b/arm9/source/dumpOperations.cpp index dd2ba69..67a891b 100644 --- a/arm9/source/dumpOperations.cpp +++ b/arm9/source/dumpOperations.cpp @@ -45,8 +45,8 @@ DumpOption dumpMenu(std::vector allowedOptions, const char *dumpName int optionOffset = 0; char dumpToStr[256]; - if(sdMounted || flashcardMounted) - snprintf(dumpToStr, sizeof(dumpToStr), STR_DUMP_TO.c_str(), dumpName, sdMounted ? "sd" : "fat"); + if(sdMounted || flashcardMounted || ramdriveMounted) + snprintf(dumpToStr, sizeof(dumpToStr), STR_DUMP_TO.c_str(), dumpName, getDefaultDrivePath()); else snprintf(dumpToStr, sizeof(dumpToStr), STR_DUMP_TO_GBA.c_str(), dumpName); @@ -459,7 +459,7 @@ bool readFromGbaCart() { decompress(compressedBuffer, finalBuffer, LZ77); char destPath[256]; - sprintf(destPath, "%s:/gm9i/out/%s.sav", (sdMounted ? "sd" : "fat"), fileName); + sprintf(destPath, "%s:/gm9i/out/%s.sav", getDefaultDrivePath(), fileName); FILE *destinationFile = fopen(destPath, "wb"); if(destinationFile) { fwrite(finalBuffer, 1, size, destinationFile); @@ -541,7 +541,7 @@ void ndsCardSaveDump(const char* filename) { buffer = new unsigned char[size]; cardReadEeprom(0, buffer, size, type); } - if(sdMounted || flashcardMounted) { + if(sdMounted || flashcardMounted || ramdriveMounted) { FILE *out = fopen(filename, "wb"); if(out) { fwrite(buffer, 1, size, out); @@ -796,7 +796,7 @@ void ndsCardDump(void) { int cardInited = cardInit(&ndsCardHeader); if(cardInited == 0) { - if(sdMounted || flashcardMounted) { + if(sdMounted || flashcardMounted || ramdriveMounted) { allowedOptions.push_back(DumpOption::allTrimmed); allowedOptions.push_back(DumpOption::rom); allowedOptions.push_back(DumpOption::romTrimmed); @@ -805,12 +805,12 @@ void ndsCardDump(void) { nandSave = cardNandGetSaveSize() != 0; } - if((spiSave && (sdMounted || flashcardMounted || cardEepromGetSizeFixed() <= (1 << 20))) || (nandSave && (sdMounted || flashcardMounted))) { + if(ramdriveMounted || (spiSave && (sdMounted || flashcardMounted || cardEepromGetSizeFixed() <= (1 << 20))) || (nandSave && (sdMounted || flashcardMounted))) { allowedOptions.push_back(DumpOption::save); allowedBitfield |= DumpOption::save; } } - if(sdMounted || flashcardMounted) { + if(sdMounted || flashcardMounted || ramdriveMounted) { allowedBitfield |= DumpOption::metadata; allowedOptions.push_back(DumpOption::metadata); } @@ -846,10 +846,10 @@ void ndsCardDump(void) { strcat(fileName, "_trim"); // Ensure directories exist - if((dumpOption & allowedBitfield) != DumpOption::none && (sdMounted || flashcardMounted)) { + if((dumpOption & allowedBitfield) != DumpOption::none && (sdMounted || flashcardMounted || ramdriveMounted)) { char folderPath[2][256]; - sprintf(folderPath[0], "%s:/gm9i", (sdMounted ? "sd" : "fat")); - sprintf(folderPath[1], "%s:/gm9i/out", (sdMounted ? "sd" : "fat")); + sprintf(folderPath[0], "%s:/gm9i", getDefaultDrivePath()); + sprintf(folderPath[1], "%s:/gm9i/out", getDefaultDrivePath()); if (access(folderPath[0], F_OK) != 0) { font->clear(false); font->print(firstCol, 0, false, STR_CREATING_DIRECTORY, alignStart); @@ -882,7 +882,7 @@ void ndsCardDump(void) { // Dump! char destPath[256]; - sprintf(destPath, "%s:/gm9i/out/%s.nds", (sdMounted ? "sd" : "fat"), fileName); + sprintf(destPath, "%s:/gm9i/out/%s.nds", getDefaultDrivePath(), fileName); u32 currentSize = romSize; FILE* destinationFile = fopen(destPath, "wb"); if (destinationFile) { @@ -928,8 +928,8 @@ void ndsCardDump(void) { // Dump save if ((dumpOption & allowedBitfield) & DumpOption::save) { char destPath[256]; - sprintf(destPath, "%s:/gm9i/out/%s.sav", (sdMounted ? "sd" : "fat"), fileName); - ndsCardSaveDump((sdMounted || flashcardMounted) ? destPath : fileName); + sprintf(destPath, "%s:/gm9i/out/%s.sav", getDefaultDrivePath(), fileName); + ndsCardSaveDump((sdMounted || flashcardMounted || ramdriveMounted) ? destPath : fileName); } // Dump metadata @@ -939,7 +939,7 @@ void ndsCardDump(void) { font->update(false); char destPath[256]; - sprintf(destPath, "%s:/gm9i/out/%s.txt", (sdMounted ? "sd" : "fat"), fileName); + sprintf(destPath, "%s:/gm9i/out/%s.txt", getDefaultDrivePath(), fileName); FILE* destinationFile = fopen(destPath, "wb"); if (destinationFile) { fprintf(destinationFile, @@ -1145,8 +1145,8 @@ void gbaCartDump(void) { // Ensure directories exist if((dumpOption & allowedBitfield) != DumpOption::none) { char folderPath[2][256]; - sprintf(folderPath[0], "%s:/gm9i", (sdMounted ? "sd" : "fat")); - sprintf(folderPath[1], "%s:/gm9i/out", (sdMounted ? "sd" : "fat")); + sprintf(folderPath[0], "%s:/gm9i", getDefaultDrivePath()); + sprintf(folderPath[1], "%s:/gm9i/out", getDefaultDrivePath()); if (access(folderPath[0], F_OK) != 0) { font->clear(false); font->print(firstCol, 0, false, STR_CREATING_DIRECTORY, alignStart); @@ -1284,7 +1284,7 @@ void gbaCartDump(void) { font->update(false); char destPath[256]; - sprintf(destPath, "%s:/gm9i/out/%s.txt", (sdMounted ? "sd" : "fat"), fileName); + sprintf(destPath, "%s:/gm9i/out/%s.txt", getDefaultDrivePath(), fileName); FILE* destinationFile = fopen(destPath, "wb"); if (destinationFile) { fprintf(destinationFile, diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index ec0b1a1..4a6f769 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -86,6 +86,15 @@ int main(int argc, char **argv) { defaultExceptionHandler(); + sysSetCartOwner (BUS_OWNER_ARM9); // Allow arm9 to access GBA ROM + + // Immediately mount RAM drive to ensure we have all the heap available + auto ram32MB = []{ + *(vu32*)(0x0DFFFE0C) = 0x474D3969; + return *(vu32*)(0x0DFFFE0C) == 0x474D3969; + }(); + ramdriveMount(ram32MB); + std::string filename; bool yHeld = false; @@ -148,8 +157,6 @@ int main(int argc, char **argv) { font->print(-2, -2, false, "Mounting drive(s)...", Alignment::right); font->update(false); - sysSetCartOwner (BUS_OWNER_ARM9); // Allow arm9 to access GBA ROM - if (isDSiMode() || !isRegularDS) { fifoSetValue32Handler(FIFO_USER_04, sdStatusHandler, nullptr); if (!sdRemoved) { @@ -159,9 +166,6 @@ int main(int argc, char **argv) { if (isDSiMode()) { scanKeys(); yHeld = (keysHeld() & KEY_Y); - *(vu32*)(0x0DFFFE0C) = 0x474D3969; // Check for 32MB of RAM - bool ram32MB = *(vu32*)(0x0DFFFE0C) == 0x474D3969; - ramdriveMount(ram32MB); if (ram32MB) { is3DS = fifoGetValue32(FIFO_USER_05) != 0xD2; } @@ -176,9 +180,6 @@ int main(int argc, char **argv) { fwrite((void*)0x2FFFD00, 1, 8, cidFile); fclose(cidFile);*/ } else if (REG_SCFG_EXT != 0) { - *(vu32*)(0x0DFFFE0C) = 0x474D3969; // Check for 32MB of RAM - bool ram32MB = *(vu32*)(0x0DFFFE0C) == 0x474D3969; - ramdriveMount(ram32MB); if (ram32MB) { is3DS = fifoGetValue32(FIFO_USER_05) != 0xD2; } @@ -233,9 +234,8 @@ int main(int argc, char **argv) { nandMount(); // Returns corrupt data for some reason } - } else if (isRegularDS && (io_dldi_data->ioInterface.features & FEATURE_SLOT_NDS)) { - ramdriveMount(false); } + if (!isDSiMode() || !yHeld) { flashcardMounted = flashcardMount(); flashcardMountSkipped = false; diff --git a/arm9/source/ramd.c b/arm9/source/ramd.c index 3e2236e..e9c4ffc 100644 --- a/arm9/source/ramd.c +++ b/arm9/source/ramd.c @@ -13,6 +13,7 @@ const static u8 bootSector[] = { 'I', 'V', 'E', ' ', ' ', ' ', 'F', 'A', 'T' }; +u32 baseSectors = 0; u32 ramdSectors = 0; u8* ramdLoc = (u8*)NULL; u8* ramdLocMep = (u8*)NULL; @@ -20,10 +21,13 @@ const u16 bootSectorSignature = 0xAA55; bool ramd_startup() { if(isDSiMode() || REG_SCFG_EXT != 0) { - ramdLoc = (u8*)malloc(0x6000 * SECTOR_SIZE); + ramdLoc = (u8*)malloc(baseSectors * SECTOR_SIZE); } else { - ramdLoc = (u8*)calloc(0x8 * SECTOR_SIZE, 1); - toncset(ramdLocMep, 0, (ramdSectors - 0x8) * SECTOR_SIZE); // Fill MEP with 00 to avoid displaying weird files + ramdLoc = (u8*)calloc(baseSectors * SECTOR_SIZE, 1); + if(ramdLoc == NULL) + return false; + if(ramdLocMep != NULL) + toncset(ramdLocMep, 0, (ramdSectors - baseSectors) * SECTOR_SIZE); // Fill MEP with 00 to avoid displaying weird files } tonccpy(ramdLoc, bootSector, sizeof(bootSector)); @@ -34,21 +38,15 @@ bool ramd_startup() { } bool ramd_is_inserted() { - return isDSiMode() || REG_SCFG_EXT != 0 || *(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1; + return ramdLoc != NULL; } bool ramd_read_sectors(sec_t sector, sec_t numSectors, void *buffer) { for(int i = 0; i < numSectors; i++, sector++) { - if(isDSiMode() || REG_SCFG_EXT != 0) { - if(sector < 0x6000) { - tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE); - } else if(sector <= 0xE000) { - tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), SECTOR_SIZE); - } - } else if(sector < 0x8) { + if(sector < baseSectors) { tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE); - } else if(sector <= ramdSectors - 0x8) { - tonccpy(buffer + (i * SECTOR_SIZE), ramdLocMep + ((sector - 0x8) * SECTOR_SIZE), SECTOR_SIZE); + } else if(sector < ramdSectors) { + tonccpy(buffer + (i * SECTOR_SIZE), ramdLocMep + ((sector - baseSectors) * SECTOR_SIZE), SECTOR_SIZE); } else { return false; } @@ -59,16 +57,10 @@ bool ramd_read_sectors(sec_t sector, sec_t numSectors, void *buffer) { bool ramd_write_sectors(sec_t sector, sec_t numSectors, const void *buffer) { for(int i = 0; i < numSectors; i++, sector++) { - if(isDSiMode() || REG_SCFG_EXT != 0) { - if(sector < 0x6000) { - tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE); - } else if(sector <= 0xE000) { - tonccpy((void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE); - } - } else if(sector < 0x8) { + if(sector < baseSectors) { tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE); - } else if(sector <= ramdSectors - 0x8) { - tonccpy(ramdLocMep + ((sector - 0x8) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE); + } else if(sector < ramdSectors) { + tonccpy(ramdLocMep + ((sector - baseSectors) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE); } else { return false; } diff --git a/arm9/source/ramd.h b/arm9/source/ramd.h index 63f4633..496f62f 100644 --- a/arm9/source/ramd.h +++ b/arm9/source/ramd.h @@ -4,6 +4,7 @@ #include #include +extern u32 baseSectors; extern u32 ramdSectors; extern u8* ramdLocMep; diff --git a/arm9/source/titleManager.cpp b/arm9/source/titleManager.cpp index cce384f..42a70af 100644 --- a/arm9/source/titleManager.cpp +++ b/arm9/source/titleManager.cpp @@ -63,7 +63,7 @@ void dumpTitle(TitleInfo &title) { snprintf(dumpName, sizeof(dumpName), "%s_%s_%02X", title.gameTitle, title.gameCode, title.romVersion); char dumpToStr[256]; - snprintf(dumpToStr, sizeof(dumpToStr), STR_DUMP_TO.c_str(), dumpName, sdMounted ? "sd" : "fat"); + snprintf(dumpToStr, sizeof(dumpToStr), STR_DUMP_TO.c_str(), dumpName, getDefaultDrivePath()); int y = font->calcHeight(dumpToStr) + 1; @@ -131,14 +131,14 @@ void dumpTitle(TitleInfo &title) { // Ensure directories exist char folderPath[16]; - sprintf(folderPath, "%s:/gm9i", (sdMounted ? "sd" : "fat")); + sprintf(folderPath, "%s:/gm9i", getDefaultDrivePath()); if (access(folderPath, F_OK) != 0) { font->clear(false); font->print(firstCol, 0, false, STR_CREATING_DIRECTORY, alignStart); font->update(false); mkdir(folderPath, 0777); } - sprintf(folderPath, "%s:/gm9i/out", (sdMounted ? "sd" : "fat")); + sprintf(folderPath, "%s:/gm9i/out", getDefaultDrivePath()); if (access(folderPath, F_OK) != 0) { font->clear(false); font->print(firstCol, 0, false, STR_CREATING_DIRECTORY, alignStart); @@ -150,31 +150,31 @@ void dumpTitle(TitleInfo &title) { char inpath[64], outpath[64]; if((selectedOption & TitleDumpOption::rom) && (allowedBitfield & TitleDumpOption::rom)) { snprintf(inpath, sizeof(inpath), "%s/content/%02x%02x%02x%02x.app", title.path.c_str(), title.appVersion[0], title.appVersion[1], title.appVersion[2], title.appVersion[3]); - snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.nds", sdMounted ? "sd" : "fat", dumpName); + snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.nds", getDefaultDrivePath(), dumpName); fcopy(inpath, outpath); } if((selectedOption & TitleDumpOption::publicSave) && (allowedBitfield & TitleDumpOption::publicSave)) { snprintf(inpath, sizeof(inpath), "%s/data/public.sav", title.path.c_str()); - snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.pub", sdMounted ? "sd" : "fat", dumpName); + snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.pub", getDefaultDrivePath(), dumpName); fcopy(inpath, outpath); } if((selectedOption & TitleDumpOption::privateSave) && (allowedBitfield & TitleDumpOption::privateSave)) { snprintf(inpath, sizeof(inpath), "%s/data/private.sav", title.path.c_str()); - snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.prv", sdMounted ? "sd" : "fat", dumpName); + snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.prv", getDefaultDrivePath(), dumpName); fcopy(inpath, outpath); } if((selectedOption & TitleDumpOption::bannerSave) && (allowedBitfield & TitleDumpOption::bannerSave)) { snprintf(inpath, sizeof(inpath), "%s/data/banner.sav", title.path.c_str()); - snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.bnr", sdMounted ? "sd" : "fat", dumpName); + snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.bnr", getDefaultDrivePath(), dumpName); fcopy(inpath, outpath); } if((selectedOption & TitleDumpOption::tmd) && (allowedBitfield & TitleDumpOption::tmd)) { snprintf(inpath, sizeof(inpath), "%s/content/title.tmd", title.path.c_str()); - snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.tmd", sdMounted ? "sd" : "fat", dumpName); + snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.tmd", getDefaultDrivePath(), dumpName); fcopy(inpath, outpath); }