diff --git a/.gitignore b/.gitignore index f93f40f4e..67a3bffbb 100644 --- a/.gitignore +++ b/.gitignore @@ -106,4 +106,8 @@ build/ #!.vscode/launch.json #!.vscode/extensions.json retail/nitrofiles/cardengine_arm7.bin +retail/nitrofiles/cardengine_arm9_dldi.bin +retail/nitrofiles/cardengine_arm9_reloc.bin +retail/nitrofiles/cardengine_arm9_sdk5.bin +retail/nitrofiles/cardengine_arm9_sdk5_dldi.bin retail/nitrofiles/load.bin diff --git a/retail/Makefile b/retail/Makefile index 3b1e56525..edc1820cb 100644 --- a/retail/Makefile +++ b/retail/Makefile @@ -204,8 +204,7 @@ clean: @$(MAKE) -C cardengine/arm9 clean @$(MAKE) -C cardengine/arm9_reloc clean @$(MAKE) -C cardengine/arm9_sdk5 clean - @$(MAKE) -C cardengine/arm9_sdk5_reloc clean - @$(MAKE) -C cardengine/arm9_sdk5_gsdd clean + @$(MAKE) -C cardengine/arm9_sdk5_dldi clean @$(MAKE) -C bootloader clean $(DATA): diff --git a/retail/arm9/include/configuration.h b/retail/arm9/include/configuration.h index 1dd3d3f8a..42bbb0ad8 100644 --- a/retail/arm9/include/configuration.h +++ b/retail/arm9/include/configuration.h @@ -25,13 +25,12 @@ typedef struct configuration { bool boostVram; bool gameSoftReset; bool forceSleepPatch; + bool volumeFix; bool preciseVolumeControl; - bool soundFix; bool logging; bool initDisc; - bool dldiPatchNds; - int argc; - const char** argv; //const char* argv[ARG_MAX]; + bool gameOnFlashcard; + bool saveOnFlashcard; u32 backlightMode; } configuration; diff --git a/retail/arm9/source/conf_sd.cpp b/retail/arm9/source/conf_sd.cpp index 633fd67ec..f63280e36 100644 --- a/retail/arm9/source/conf_sd.cpp +++ b/retail/arm9/source/conf_sd.cpp @@ -189,19 +189,29 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) { mkdir("sd:/_nds/nds-bootstrap", 0777); mkdir("sd:/_nds/nds-bootstrap/patchOffsetCache", 0777); mkdir("sd:/_nds/nds-bootstrap/fatTable", 0777); - if (conf->ndsPath[0] == 'f' && conf->ndsPath[1] == 'a' && conf->ndsPath[2] == 't') { - conf->dldiPatchNds = true; + if (flashcardFound) { mkdir("fat:/_nds", 0777); mkdir("fat:/_nds/nds-bootstrap", 0777); mkdir("fat:/_nds/nds-bootstrap/patchOffsetCache", 0777); mkdir("fat:/_nds/nds-bootstrap/fatTable", 0777); } - nitroFSInit(bootstrapPath); + conf->gameOnFlashcard = (conf->ndsPath[0] == 'f' && conf->ndsPath[1] == 'a' && conf->ndsPath[2] == 't'); + conf->saveOnFlashcard = (conf->savPath[0] == 'f' && conf->savPath[1] == 'a' && conf->savPath[2] == 't'); + + if ((strncmp (bootstrapPath, "sd:/", 4) != 0) && (strncmp (bootstrapPath, "fat:/", 5) != 0)) { + //bootstrapPath = "sd:/_nds/nds-bootstrap-release.nds"; + bootstrapPath = "sd:/_nds/nds-bootstrap-nightly.nds"; + } + if (!nitroFSInit(bootstrapPath)) { + consoleDemoInit(); + printf("nitroFSInit failed!\n"); + return -1; + } // Load ce7 binary FILE* cebin = fopen("nitro:/cardengine_arm7.bin", "rb"); - fread((void*)CARDENGINE_ARM7_BUFFERED_LOCATION, 1, 0x10000, cebin); + fread((void*)CARDENGINE_ARM7_BUFFERED_LOCATION, 1, 0x12000, cebin); fclose(cebin); // Load reloc ce9 binary @@ -232,41 +242,6 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) { conf->saveSize = getFileSize(conf->savPath); conf->cheatSize = getFileSize("sd:/_nds/nds-bootstrap/cheatData.bin"); - conf->argc = 0; - conf->argv = (const char**)malloc(ARG_MAX); - if (strcasecmp(conf->ndsPath + strlen(conf->ndsPath) - 5, ".argv") == 0) { - FILE* argfile = fopen(conf->ndsPath, "rb"); - - char str[PATH_MAX]; - char* pstr; - const char* seps = "\n\r\t "; - - while (fgets(str, PATH_MAX, argfile)) { - // Find comment and end string there - if ((pstr = strchr(str, '#'))) { - *pstr = '\0'; - } - - // Tokenize arguments - pstr = strtok(str, seps); - - while (pstr != NULL) { - conf->argv[conf->argc] = strdup(pstr); - ++conf->argc; - - pstr = strtok(NULL, seps); - } - } - fclose(argfile); - - free(conf->ndsPath); - conf->ndsPath = strdup(conf->argv[0]); - } else { - conf->argv[0] = strdup(conf->ndsPath); - conf->argc = 1; //++conf->argc; - } - realloc(conf->argv, conf->argc*sizeof(const char*)); - // Please wait screen FILE* bootstrapImage = fopen("nitro:/pleasewait.bmp", "rb"); if (bootstrapImage) { diff --git a/retail/arm9/source/main.cpp b/retail/arm9/source/main.cpp index 632cd228f..e05934972 100644 --- a/retail/arm9/source/main.cpp +++ b/retail/arm9/source/main.cpp @@ -43,10 +43,10 @@ void* load_bin[0x10000]; std::string patchOffsetCacheFilePath; std::string fatTableFilePath; -/* typedef struct { +typedef struct { char gameTitle[12]; //!< 12 characters for the game title. char gameCode[4]; //!< 4 characters for the game code. -} sNDSHeaderTitleCodeOnly; */ +} sNDSHeaderTitleCodeOnly; //extern bool logging; //bool logging = false; @@ -154,9 +154,8 @@ static inline void debugConf(configuration* conf) { dbg_printf("forceSleepPatch: %s\n", btoa(conf->forceSleepPatch)); dbg_printf("logging: %s\n", btoa(conf->logging)); dbg_printf("initDisc: %s\n", btoa(conf->initDisc)); - dbg_printf("dldiPatchNds: %s\n", btoa(conf->dldiPatchNds)); - //dbg_printf("argc: %lu\n", conf->argc); - //const char** argv; + dbg_printf("gameOnFlashcard: %s\n", btoa(conf->gameOnFlashcard)); + dbg_printf("saveOnFlashcard: %s\n", btoa(conf->saveOnFlashcard)); dbg_printf("backlightMode: %lX\n", conf->backlightMode); } @@ -194,81 +193,78 @@ static int runNdsFile(configuration* conf) { // adjust TSC[1:26h] and TSC[1:27h] // for certain gamecodes - /*FILE* f_nds_file = fopen(conf->ndsPath, "rb"); + FILE* f_nds_file = fopen(conf->ndsPath, "rb"); char romTid[5]; fseek(f_nds_file, offsetof(sNDSHeaderTitleCodeOnly, gameCode), SEEK_SET); fread(romTid, 1, 4, f_nds_file); - romTid[4] = 0; - romTid[3] = 0; - //romTid[2] = 0; // SDK 5 - //romTid[1] = 0; // SDK 5 fclose(f_nds_file); - // SDK 5 - //if (strcmp(romTid, "I") != 0) { - // fifoSendValue32(FIFO_USER_08, 1); // Disable Slot-1 access for games with no built-in infrared port - //} - - if (strcmp(romTid, "ABX") == 0 // NTR-ABXE Bomberman Land Touch! - || strcmp(romTid, "YO9") == 0 // NTR-YO9J Bokura no TV Game Kentei - Pikotto! Udedameshi - || strcmp(romTid, "ALH") == 0 // NTR-ALHE Flushed Away - || strcmp(romTid, "ACC") == 0 // NTR-ACCE Cooking Mama - || strcmp(romTid, "YCQ") == 0 // NTR-YCQE Cooking Mama 2 - Dinner with Friends - || strcmp(romTid, "YYK") == 0 // NTR-YYKE Trauma Center - Under the Knife 2 - || strcmp(romTid, "AZW") == 0 // NTR-AZWE WarioWare - Touched! - || strcmp(romTid, "AKA") == 0 // NTR-AKAE Rub Rabbits!, The - || strcmp(romTid, "AN9") == 0 // NTR-AN9E Little Mermaid - Ariel's Undersea Adventure, The - || strcmp(romTid, "AKE") == 0 // NTR-AKEJ Keroro Gunsou - Enshuu da Yo! Zenin Shuugou Part 2 - || strcmp(romTid, "YFS") == 0 // NTR-YFSJ Frogman Show - DS Datte, Shouganaijanai, The - || strcmp(romTid, "YG8") == 0 // NTR-YG8E Yu-Gi-Oh! World Championship 2008 - || strcmp(romTid, "AY7") == 0 // NTR-AY7E Yu-Gi-Oh! World Championship 2007 - || strcmp(romTid, "YON") == 0 // NTR-YONJ Minna no DS Seminar - Kantan Ongakuryoku - || strcmp(romTid, "A5H") == 0 // NTR-A5HE Interactive Storybook DS - Series 2 - || strcmp(romTid, "A5I") == 0 // NTR-A5IE Interactive Storybook DS - Series 3 - || strcmp(romTid, "AMH") == 0 // NTR-AMHE Metroid Prime Hunters - || strcmp(romTid, "A3T") == 0 // NTR-A3TE Tak - The Great Juju Challenge - || strcmp(romTid, "YBO") == 0 // NTR-YBOE Boogie - || strcmp(romTid, "ADA") == 0 // NTR-ADAE PKMN Diamond - || strcmp(romTid, "APA") == 0 // NTR-APAE PKMN Pearl - || strcmp(romTid, "CPU") == 0 // NTR-CPUE PKMN Platinum - || strcmp(romTid, "APY") == 0 // NTR-APYE Puyo Pop Fever - || strcmp(romTid, "AWH") == 0 // NTR-AWHE Bubble Bobble Double Shot - || strcmp(romTid, "AXB") == 0 // NTR-AXBJ Daigassou! Band Brothers DX - || strcmp(romTid, "A4U") == 0 // NTR-A4UJ Wi-Fi Taiou - Morita Shogi - || strcmp(romTid, "A8N") == 0 // NTR-A8NE Planet Puzzle League - || strcmp(romTid, "ABJ") == 0 // NTR-ABJE Harvest Moon DS - Island of Happiness - || strcmp(romTid, "ABN") == 0 // NTR-ABNE Bomberman Story DS - || strcmp(romTid, "ACL") == 0 // NTR-ACLE Custom Robo Arena - || strcmp(romTid, "ART") == 0 // NTR-ARTJ Shin Lucky Star Moe Drill - Tabidachi - || strcmp(romTid, "AVT") == 0 // NTR-AVTJ Kou Rate Ura Mahjong Retsuden Mukoubuchi - Goburei, Shuuryou desu ne - || strcmp(romTid, "AWY") == 0 // NTR-AWYJ Wi-Fi Taiou - Gensen Table Game DS - || strcmp(romTid, "AXJ") == 0 // NTR-AXJE Dungeon Explorer - Warriors of Ancient Arts - || strcmp(romTid, "AYK") == 0 // NTR-AYKJ Wi-Fi Taiou - Yakuman DS - || strcmp(romTid, "YB2") == 0 // NTR-YB2E Bomberman Land Touch! 2 - || strcmp(romTid, "YB3") == 0 // NTR-YB3E Harvest Moon DS - Sunshine Islands - || strcmp(romTid, "YCH") == 0 // NTR-YCHJ Kousoku Card Battle - Card Hero - || strcmp(romTid, "YFE") == 0 // NTR-YFEE Fire Emblem - Shadow Dragon - || strcmp(romTid, "YGD") == 0 // NTR-YGDE Diary Girl - || strcmp(romTid, "YKR") == 0 // NTR-YKRJ Culdcept DS - || strcmp(romTid, "YRM") == 0 // NTR-YRME My Secret World by Imagine - || strcmp(romTid, "YW2") == 0 // NTR-YW2E Advance Wars - Days of Ruin - || strcmp(romTid, "AJU") == 0 // NTR-AJUJ Jump! Ultimate Stars - || strcmp(romTid, "ACZ") == 0 // NTR-ACZE Cars - || strcmp(romTid, "AHD") == 0 // NTR-AHDE Jam Sessions - || strcmp(romTid, "ANR") == 0 // NTR-ANRE Naruto - Saikyou Ninja Daikesshu 3 - || strcmp(romTid, "YT3") == 0 // NTR-YT3E Tamagotchi Connection - Corner Shop 3 - || strcmp(romTid, "AVI") == 0 // NTR-AVIJ Kodomo no Tame no Yomi Kikase - Ehon de Asobou 1-Kan - || strcmp(romTid, "AV2") == 0 // NTR-AV2J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 2-Kan - || strcmp(romTid, "AV3") == 0 // NTR-AV3J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 3-Kan - || strcmp(romTid, "AV4") == 0 // NTR-AV4J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 4-Kan - || strcmp(romTid, "AV5") == 0 // NTR-AV5J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 5-Kan - || strcmp(romTid, "AV6") == 0 // NTR-AV6J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 6-Kan - || strcmp(romTid, "YNZ") == 0 // NTR-YNZE Petz - Dogz Fashion - ) - { - fifoSendValue32(FIFO_MAXMOD, 1); // Special setting (when found special gamecode) - }*/ + static const char list[][4] = { + "ABX", // NTR-ABXE Bomberman Land Touch! + "YO9", // NTR-YO9J Bokura no TV Game Kentei - Pikotto! Udedameshi + "ALH", // NTR-ALHE Flushed Away + "ACC", // NTR-ACCE Cooking Mama + "YCQ", // NTR-YCQE Cooking Mama 2 - Dinner with Friends + "YYK", // NTR-YYKE Trauma Center - Under the Knife 2 + "AZW", // NTR-AZWE WarioWare - Touched! + "AKA", // NTR-AKAE Rub Rabbits!, The + "AN9", // NTR-AN9E Little Mermaid - Ariel's Undersea Adventure, The + "AKE", // NTR-AKEJ Keroro Gunsou - Enshuu da Yo! Zenin Shuugou Part 2 + "YFS", // NTR-YFSJ Frogman Show - DS Datte, Shouganaijanai, The + "YG8", // NTR-YG8E Yu-Gi-Oh! World Championship 2008 + "AY7", // NTR-AY7E Yu-Gi-Oh! World Championship 2007 + "YON", // NTR-YONJ Minna no DS Seminar - Kantan Ongakuryoku + "A5H", // NTR-A5HE Interactive Storybook DS - Series 2 + "A5I", // NTR-A5IE Interactive Storybook DS - Series 3 + "AMH", // NTR-AMHE Metroid Prime Hunters + "A3T", // NTR-A3TE Tak - The Great Juju Challenge + "YBO", // NTR-YBOE Boogie + "ADA", // NTR-ADAE PKMN Diamond + "APA", // NTR-APAE PKMN Pearl + "CPU", // NTR-CPUE PKMN Platinum + "APY", // NTR-APYE Puyo Pop Fever + "AWH", // NTR-AWHE Bubble Bobble Double Shot + "AXB", // NTR-AXBJ Daigassou! Band Brothers DX + "A4U", // NTR-A4UJ Wi-Fi Taiou - Morita Shogi + "A8N", // NTR-A8NE Planet Puzzle League + "ABJ", // NTR-ABJE Harvest Moon DS - Island of Happiness + "ABN", // NTR-ABNE Bomberman Story DS + "ACL", // NTR-ACLE Custom Robo Arena + "ART", // NTR-ARTJ Shin Lucky Star Moe Drill - Tabidachi + "AVT", // NTR-AVTJ Kou Rate Ura Mahjong Retsuden Mukoubuchi - Goburei, Shuuryou desu ne + "AWY", // NTR-AWYJ Wi-Fi Taiou - Gensen Table Game DS + "AXJ", // NTR-AXJE Dungeon Explorer - Warriors of Ancient Arts + "AYK", // NTR-AYKJ Wi-Fi Taiou - Yakuman DS + "YB2", // NTR-YB2E Bomberman Land Touch! 2 + "YB3", // NTR-YB3E Harvest Moon DS - Sunshine Islands + "YCH", // NTR-YCHJ Kousoku Card Battle - Card Hero + "YFE", // NTR-YFEE Fire Emblem - Shadow Dragon + "YGD", // NTR-YGDE Diary Girl + "YKR", // NTR-YKRJ Culdcept DS + "YRM", // NTR-YRME My Secret World by Imagine + "YW2", // NTR-YW2E Advance Wars - Days of Ruin + "AJU", // NTR-AJUJ Jump! Ultimate Stars + "ACZ", // NTR-ACZE Cars + "AHD", // NTR-AHDE Jam Sessions + "ANR", // NTR-ANRE Naruto - Saikyou Ninja Daikesshu 3 + "YT3", // NTR-YT3E Tamagotchi Connection - Corner Shop 3 + "AVI", // NTR-AVIJ Kodomo no Tame no Yomi Kikase - Ehon de Asobou 1-Kan + "AV2", // NTR-AV2J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 2-Kan + "AV3", // NTR-AV3J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 3-Kan + "AV4", // NTR-AV4J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 4-Kan + "AV5", // NTR-AV5J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 5-Kan + "AV6", // NTR-AV6J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 6-Kan + "YNZ", // NTR-YNZE Petz - Dogz Fashion + }; + + for (unsigned int i = 0; i < sizeof(list) / sizeof(list[0]); i++) { + if (memcmp(romTid, list[i], 3) == 0) { + // Found a match. + conf->volumeFix = true; // Special setting (when found special gamecode) + break; + } + } // Boost CPU if (conf->boostCpu) { @@ -307,7 +303,7 @@ static int runNdsFile(configuration* conf) { debugConf(conf); - if (strcasecmp(conf->ndsPath + strlen(conf->ndsPath) - 4, ".nds") != 0 || conf->argc == 0) { + if (strcasecmp(conf->ndsPath + strlen(conf->ndsPath) - 4, ".nds") != 0) { dbg_printf("No NDS file specified\n"); if (debug) { dopause(); @@ -369,20 +365,6 @@ static int runNdsFile(configuration* conf) { clusterFatTable = stFatTable.st_ino; } - if (conf->argc <= 0 || !conf->argv) { - // Construct a command line if we weren't supplied with one - if (!getcwd(filePath, PATH_MAX)) { - return -3; - } - pathLen = strlen(filePath); - strcpy(filePath + pathLen, conf->ndsPath); - //args[0] = filePath; - //conf->argv = args; - memset(conf->argv, 0, conf->argc*sizeof(const char*)); - conf->argv[0] = filePath; - conf->argc = 1; - } - //bool havedsiSD = false; //bool havedsiSD = (argv[0][0] == 's' && argv[0][1] == 'd'); @@ -402,7 +384,6 @@ static int runNdsFile(configuration* conf) { int main(int argc, char** argv) { configuration* conf = (configuration*)malloc(sizeof(configuration)); conf->initDisc = true; - conf->dldiPatchNds = false; int status = loadFromSD(conf, argv[0]); @@ -417,7 +398,6 @@ int main(int argc, char** argv) { if (status != 0) { free(conf->ndsPath); free(conf->savPath); - free(conf->argv); free(conf); stop(); diff --git a/retail/arm9/source/nds_loader_arm9.c b/retail/arm9/source/nds_loader_arm9.c index 01643afd5..31cf030a8 100644 --- a/retail/arm9/source/nds_loader_arm9.c +++ b/retail/arm9/source/nds_loader_arm9.c @@ -228,40 +228,6 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS) return true; } -int loadArgs(int argc, const char** argv) { - // Give arguments to loader - - char* argStart = (char*)lc0 + lc0->argStart; - argStart = (char*)(((int)argStart + 3) & ~3); // Align to word - u16* argData = (u16*)argStart; - int argSize = 0; - u16 argTempVal = 0; - - for (; argc > 0 && *argv; ++argv, --argc) { - for (const char* argChar = *argv; *argChar != 0; ++argChar, ++argSize) { - if (argSize & 1) { - argTempVal |= (*argChar) << 8; - *argData = argTempVal; - ++argData; - } else { - argTempVal = *argChar; - } - } - if (argSize & 1) { - *argData = argTempVal; - ++argData; - } - argTempVal = 0; - ++argSize; - } - *argData = argTempVal; - - lc0->argStart = (u32)argStart - (u32)lc0; - lc0->argSize = argSize; - - return true; -} - void runNds(const void* loader, u32 loaderSize, u32 cluster, u32 saveCluster, u32 cheatCluster, u32 patchOffsetCacheCluster, u32 fatTableCluster, configuration* conf) { nocashMessage("runNds"); @@ -280,13 +246,8 @@ void runNds(const void* loader, u32 loaderSize, u32 cluster, u32 saveCluster, u3 lc0->storedFileCluster = cluster; lc0->initDisc = conf->initDisc; - lc0->gameOnFlashcard = conf->dldiPatchNds; - - loadArgs(conf->argc, conf->argv); - for (int i = 0; i < conf->argc; ++i) { - free((void*)conf->argv[i]); - } - free(conf->argv); + lc0->gameOnFlashcard = conf->gameOnFlashcard; + lc0->saveOnFlashcard = conf->saveOnFlashcard; lc0->saveFileCluster = saveCluster; lc0->romSize = conf->romSize; @@ -306,15 +267,16 @@ void runNds(const void* loader, u32 loaderSize, u32 cluster, u32 saveCluster, u3 lc0->boostVram = conf->boostVram; lc0->gameSoftReset = conf->gameSoftReset; lc0->forceSleepPatch = conf->forceSleepPatch; + lc0->volumeFix = conf->volumeFix; lc0->preciseVolumeControl = conf->preciseVolumeControl; lc0->logging = conf->logging; free(conf); - if(conf->dldiPatchNds) { + if(conf->gameOnFlashcard || conf->saveOnFlashcard) { // Patch the loader with a DLDI for the card if (!dldiPatchLoader ((data_t*)lc0, loaderSize, conf->initDisc)) { - return 3; + return; } } diff --git a/retail/bootloader/include/hook.h b/retail/bootloader/include/hook.h index d63ef011e..e5b0dc351 100644 --- a/retail/bootloader/include/hook.h +++ b/retail/bootloader/include/hook.h @@ -37,6 +37,7 @@ int hookNdsRetailArm7( u32 cheatFileCluster, u32 cheatSize, u32 gameOnFlashcard, + u32 saveOnFlashcard, u32 language, u32 dsiMode, // SDK5 u32 ROMinRAM, @@ -49,6 +50,8 @@ int hookNdsRetailArm9( cardengineArm9* ce9, const module_params_t* moduleParams, u32 fileCluster, + u32 saveCluster, + u32 saveOnFlashcard, u32 ROMinRAM, u32 dsiMode, // SDK5 u32 enableExceptionHandler, diff --git a/retail/bootloader/source/arm7/hook_arm7.c b/retail/bootloader/source/arm7/hook_arm7.c index a5fbf3317..ed3d1c534 100644 --- a/retail/bootloader/source/arm7/hook_arm7.c +++ b/retail/bootloader/source/arm7/hook_arm7.c @@ -97,6 +97,7 @@ int hookNdsRetailArm7( u32 cheatFileCluster, u32 cheatSize, u32 gameOnFlashcard, + u32 saveOnFlashcard, u32 language, u32 dsiMode, // SDK 5 u32 ROMinRAM, @@ -205,6 +206,7 @@ int hookNdsRetailArm7( ce7->moduleParams = moduleParams; ce7->fileCluster = fileCluster; ce7->gameOnFlashcard = gameOnFlashcard; + ce7->saveOnFlashcard = saveOnFlashcard; ce7->language = language; ce7->gottenSCFGExt = REG_SCFG_EXT; // Pass unlocked SCFG before locking it ce7->dsiMode = dsiMode; // SDK 5 @@ -216,8 +218,8 @@ int hookNdsRetailArm7( const char* romTid = getRomTid(ndsHeader); *vblankHandler = ce7->patches->vblankHandler; - if (strncmp(romTid, "UOR", 3) == 0 - || strncmp(romTid, "UXB", 3) == 0 + if ((strncmp(romTid, "UOR", 3) == 0 && !saveOnFlashcard) + || (strncmp(romTid, "UXB", 3) == 0 && !saveOnFlashcard) || (!ROMinRAM && !gameOnFlashcard)) { *timer0Handler = ce7->patches->timer0Handler; *timer1Handler = ce7->patches->timer1Handler; diff --git a/retail/bootloader/source/arm7/hook_arm9.c b/retail/bootloader/source/arm7/hook_arm9.c index 96a4d3223..53ee9d937 100644 --- a/retail/bootloader/source/arm7/hook_arm9.c +++ b/retail/bootloader/source/arm7/hook_arm9.c @@ -7,84 +7,12 @@ #include "find.h" #include "cardengine_header_arm9.h" - -static const int MAX_HANDLER_LEN = 50; - -// same as arm7 -static const u32 handlerStartSig[5] = { - 0xe92d4000, // push {lr} - 0xe3a0c301, // mov ip, #0x4000000 - 0xe28cce21, // add ip, ip, #0x210 - 0xe51c1008, // ldr r1, [ip, #-8] - 0xe3510000 // cmp r1, #0 -}; - -// same as arm7 -static const u32 handlerEndSig[4] = { - 0xe59f1008, // ldr r1, [pc, #8] (IRQ Vector table address) - 0xe7910100, // ldr r0, [r1, r0, lsl #2] - 0xe59fe004, // ldr lr, [pc, #4] (IRQ return address) - 0xe12fff10 // bx r0 -}; - -static u32* hookInterruptHandler(const u32* start, size_t size) { - // Find the start of the handler - u32* addr = findOffset( - start, size, - handlerStartSig, 5 - ); - if (!addr) { - dbg_printf("ERR_HOOK_9 : handlerStartSig\n"); - return NULL; - } - - dbg_printf("handlerStartSig\n"); - dbg_hexa(addr); - dbg_printf("\n"); - - // Find the end of the handler - addr = findOffset( - addr, MAX_HANDLER_LEN*sizeof(u32), - handlerEndSig, 4 - ); - if (!addr) { - dbg_printf("ERR_HOOK_9 : handlerEndSig\n"); - return NULL; - } - - - - dbg_printf("handlerEndSig\n"); - dbg_hexa(addr); - dbg_printf("\n"); - - // Now find the IRQ vector table - // Make addr point to the vector table address pointer within the IRQ handler - addr += sizeof(handlerEndSig)/sizeof(handlerEndSig[0]); - - // Use relative and absolute addresses to find the location of the table in RAM - u32 tableAddr = addr[0]; - dbg_printf("tableAddr\n"); - dbg_hexa(tableAddr); - dbg_printf("\n"); - - u32 returnAddr = addr[1]; - dbg_printf("returnAddr\n"); - dbg_hexa(returnAddr); - dbg_printf("\n"); - - u32* actualReturnAddr = addr + 2; - u32* actualTableAddr = actualReturnAddr + (tableAddr - returnAddr)/sizeof(u32); - - // The first entry in the table is for the Vblank handler, which is what we want - return tableAddr; - // 2 LCD V-Counter Match -} - int hookNdsRetailArm9( cardengineArm9* ce9, const module_params_t* moduleParams, u32 fileCluster, + u32 saveCluster, + u32 saveOnFlashcard, u32 ROMinRAM, u32 dsiMode, // SDK 5 u32 enableExceptionHandler, @@ -94,32 +22,13 @@ int hookNdsRetailArm9( ce9->moduleParams = moduleParams; ce9->fileCluster = fileCluster; + ce9->saveCluster = saveCluster; + ce9->saveOnFlashcard = saveOnFlashcard; ce9->ROMinRAM = ROMinRAM; ce9->dsiMode = dsiMode; // SDK 5 ce9->enableExceptionHandler = enableExceptionHandler; ce9->consoleModel = consoleModel; - u32* tableAddr = hookInterruptHandler((u32*)ndsHeader->arm9destination, 0x00300000); - - if (!tableAddr) { - dbg_printf("ERR_HOOK_9\n"); - return ERR_HOOK; - } - - dbg_printf("hookLocation arm9: "); - dbg_hexa((u32)tableAddr); - dbg_printf("\n\n"); - - /*u32* vblankHandler = hookLocation; - u32* dma0Handler = hookLocation + 8; - u32* dma1Handler = hookLocation + 9; - u32* dma2Handler = hookLocation + 10; - u32* dma3Handler = hookLocation + 11; - u32* ipcSyncHandler = hookLocation + 16; - u32* cardCompletionIrq = hookLocation + 19;*/ - - ce9->irqTable = tableAddr; - nocashMessage("ERR_NONE"); return ERR_NONE; } diff --git a/retail/bootloader/source/arm7/load_crt0.s b/retail/bootloader/source/arm7/load_crt0.s index 738a701e6..99fc4cbdb 100644 --- a/retail/bootloader/source/arm7/load_crt0.s +++ b/retail/bootloader/source/arm7/load_crt0.s @@ -26,8 +26,7 @@ .global storedFileCluster .global initDisc .global gameOnFlashcard - .global argStart - .global argSize + .global saveOnFlashcard .global dsiSD .global saveFileCluster .global romSize @@ -47,6 +46,7 @@ .global boostVram .global gameSoftReset .global forceSleepPatch + .global volumeFix .global preciseVolumeControl .global logging @--------------------------------------------------------------------------------- @@ -63,10 +63,7 @@ initDisc: .word 0x00000001 @ init the disc by default gameOnFlashcard: .word 0x00000000 -@ Used for passing arguments to the loaded app -argStart: - .word _end - _start -argSize: +saveOnFlashcard: .word 0x00000000 dldiOffset: .word 0x00000000 @@ -108,6 +105,8 @@ gameSoftReset: .word 0x00000000 forceSleepPatch: .word 0x00000000 +volumeFix: + .word 0x00000000 preciseVolumeControl: .word 0x00000000 logging: diff --git a/retail/bootloader/source/arm7/main.arm7.c b/retail/bootloader/source/arm7/main.arm7.c index ce027622f..09669be6c 100644 --- a/retail/bootloader/source/arm7/main.arm7.c +++ b/retail/bootloader/source/arm7/main.arm7.c @@ -75,9 +75,7 @@ extern void arm7clearRAM(void); extern u32 storedFileCluster; extern u32 initDisc; extern u32 gameOnFlashcard; -//extern u32 argStart; -//extern u32 argSize; -//extern u32 dsiSD; +extern u32 saveOnFlashcard; extern u32 saveFileCluster; extern u32 romSize; extern u32 saveSize; @@ -95,8 +93,8 @@ extern u32 consoleModel; extern u32 romread_LED; extern u32 gameSoftReset; //extern u32 forceSleepPatch; +extern u32 volumeFix; extern u32 preciseVolumeControl; -extern u32 soundFix; extern u32 boostVram; extern u32 logging; @@ -165,7 +163,7 @@ static void resetMemory_ARM7(void) { toncset((u32*)0x02000000, 0, 0x3F4000); // clear most of EWRAM - except before 0x023F4000, which has the arm9 code toncset((u32*)0x02400000, 0, 0x380000); // clear other part of EWRAM - except before nds-bootstrap images toncset((u32*)0x027B0000, 0, 0x20000); // clear other part of EWRAM - except before ce7 binary and some ce9 binaries - toncset((u32*)0x027F0000, 0, 0x810000); // clear part of EWRAM + toncset((u32*)0x027F8000, 0, 0x808000); // clear part of EWRAM REG_IE = 0; REG_IF = ~0; *(vu32*)(0x04000000 - 4) = 0; // IRQ_HANDLER ARM7 version @@ -174,25 +172,11 @@ static void resetMemory_ARM7(void) { } static void NDSTouchscreenMode(void) { - //unsigned char * *(unsigned char*)0x40001C0= (unsigned char*)0x40001C0; - //unsigned char * *(unsigned char*)0x40001C0byte2=(unsigned char*)0x40001C1; - //unsigned char * *(unsigned char*)0x40001C2= (unsigned char*)0x40001C2; - //unsigned char * I2C_DATA= (unsigned char*)0x4004500; - //unsigned char * I2C_CNT= (unsigned char*)0x4004501; - u8 volLevel; - //if (fifoCheckValue32(FIFO_MAXMOD)) { - // // special setting (when found special gamecode) - // volLevel = 0xAC; - //} else { - // normal setting (for any other gamecodes) - volLevel = 0xA7; - //} - - if (REG_SCFG_EXT == 0) { - volLevel += 0x13; - } + // 0xAC: special setting (when found special gamecode) + // 0xA7: normal setting (for any other gamecodes) + volLevel = volumeFix ? 0xAC : 0xA7; // Touchscreen cdcReadReg (0x63, 0x00); @@ -281,7 +265,7 @@ static void NDSTouchscreenMode(void) { cdcWriteReg(CDC_SOUND, 0x28, 0x4E); cdcWriteReg(CDC_SOUND, 0x29, 0x4E); cdcWriteReg(CDC_SOUND, 0x24, 0x9E); - cdcWriteReg(CDC_SOUND, 0x24, 0x9E); + cdcWriteReg(CDC_SOUND, 0x25, 0x9E); cdcWriteReg(CDC_SOUND, 0x20, 0xD4); cdcWriteReg(CDC_SOUND, 0x2A, 0x14); cdcWriteReg(CDC_SOUND, 0x2B, 0x14); @@ -296,13 +280,50 @@ static void NDSTouchscreenMode(void) { cdcWriteReg(CDC_SOUND, 0x21, 0x20); cdcWriteReg(CDC_SOUND, 0x22, 0xF0); cdcReadReg (CDC_SOUND, 0x22); - cdcWriteReg(CDC_SOUND, 0x22, 0xF0); + cdcWriteReg(CDC_SOUND, 0x22, 0x00); cdcWriteReg(CDC_CONTROL, 0x52, 0x80); cdcWriteReg(CDC_CONTROL, 0x51, 0x00); + + // Set remaining values + cdcWriteReg(CDC_CONTROL, 0x03, 0x44); + cdcWriteReg(CDC_CONTROL, 0x0D, 0x00); + cdcWriteReg(CDC_CONTROL, 0x0E, 0x80); + cdcWriteReg(CDC_CONTROL, 0x0F, 0x80); + cdcWriteReg(CDC_CONTROL, 0x10, 0x08); + cdcWriteReg(CDC_CONTROL, 0x14, 0x80); + cdcWriteReg(CDC_CONTROL, 0x15, 0x80); + cdcWriteReg(CDC_CONTROL, 0x16, 0x04); + cdcWriteReg(CDC_CONTROL, 0x1A, 0x01); + cdcWriteReg(CDC_CONTROL, 0x1E, 0x01); + cdcWriteReg(CDC_CONTROL, 0x24, 0x80); + cdcWriteReg(CDC_CONTROL, 0x33, 0x34); + cdcWriteReg(CDC_CONTROL, 0x34, 0x32); + cdcWriteReg(CDC_CONTROL, 0x35, 0x12); + cdcWriteReg(CDC_CONTROL, 0x36, 0x03); + cdcWriteReg(CDC_CONTROL, 0x37, 0x02); + cdcWriteReg(CDC_CONTROL, 0x38, 0x03); + cdcWriteReg(CDC_CONTROL, 0x3C, 0x19); + cdcWriteReg(CDC_CONTROL, 0x3D, 0x05); + cdcWriteReg(CDC_CONTROL, 0x44, 0x0F); + cdcWriteReg(CDC_CONTROL, 0x45, 0x38); + cdcWriteReg(CDC_CONTROL, 0x49, 0x00); + cdcWriteReg(CDC_CONTROL, 0x4A, 0x00); + cdcWriteReg(CDC_CONTROL, 0x4B, 0xEE); + cdcWriteReg(CDC_CONTROL, 0x4C, 0x10); + cdcWriteReg(CDC_CONTROL, 0x4D, 0xD8); + cdcWriteReg(CDC_CONTROL, 0x4E, 0x7E); + cdcWriteReg(CDC_CONTROL, 0x4F, 0xE3); + cdcWriteReg(CDC_CONTROL, 0x58, 0x7F); + cdcWriteReg(CDC_CONTROL, 0x74, 0xD2); + cdcWriteReg(CDC_CONTROL, 0x75, 0x2C); + cdcWriteReg(CDC_SOUND, 0x22, 0x70); + cdcWriteReg(CDC_SOUND, 0x2C, 0x20); + + // Finish up! cdcReadReg (CDC_TOUCHCNT, 0x02); cdcWriteReg(CDC_TOUCHCNT, 0x02, 0x98); cdcWriteReg(0xFF, 0x05, 0x00); //writeTSC(0x00, 0xFF); - + // Power management writePowerManagement(PM_READ_REGISTER, 0x00); //*(unsigned char*)0x40001C2 = 0x80, 0x00; // read PWR[0] ;<-- also part of TSC ! writePowerManagement(PM_CONTROL_REG, 0x0D); //*(unsigned char*)0x40001C2 = 0x00, 0x0D; // PWR[0]=0Dh ;<-- also part of TSC ! @@ -658,7 +679,7 @@ int arm7_main(void) { return -1; } - if (gameOnFlashcard) { + if (gameOnFlashcard || saveOnFlashcard) { sdRead = false; // Init Slot-1 card if (!FAT_InitFiles(initDisc, 0)) { @@ -717,21 +738,26 @@ int arm7_main(void) { tonccpy((char*)ROM_FILE_LOCATION, (char*)0x27C0000, sizeof(aFile)); } if (gameOnFlashcard) { - romFile->fatTableCache = 0x2700000; + romFile->fatTableCache = (u32*)0x2700000; // Change fatTableCache addr for ce9 usage tonccpy((char*)ROM_FILE_LOCATION_MAINMEM, (char*)ROM_FILE_LOCATION, sizeof(aFile)); } - if (gameOnFlashcard) sdRead = true; + sdRead = (saveOnFlashcard ? false : true); // Sav file aFile* savFile = (aFile*)SAV_FILE_LOCATION; *savFile = getFileFromCluster(saveFileCluster); - if (savFile->firstCluster != CLUSTER_FREE && !gameOnFlashcard) { - if (fatTableEmpty) { - buildFatTableCache(savFile, 0); // Bugged, if ROM is being loaded from flashcard - } else { - tonccpy((char*)SAV_FILE_LOCATION, (char*)0x27C0020, sizeof(aFile)); + if (savFile->firstCluster != CLUSTER_FREE) { + if (saveOnFlashcard) { + tonccpy((char*)SAV_FILE_LOCATION_MAINMEM, (char*)SAV_FILE_LOCATION, sizeof(aFile)); + } + if (!gameOnFlashcard) { + if (fatTableEmpty) { + buildFatTableCache(savFile, 0); // Bugged, if ROM is being loaded from flashcard + } else { + tonccpy((char*)SAV_FILE_LOCATION, (char*)0x27C0020, sizeof(aFile)); + } } } @@ -754,7 +780,8 @@ int arm7_main(void) { fileRead((char*)0x3700000, fatTableFile, 0x200, 0x80000, 0); } if (gameOnFlashcard) { - tonccpy((char*)0x2700000, (char*)0x3700000, 0x7FFE0); + tonccpy((char*)0x2700000, (char*)0x3700000, 0x7FFC0); + romFile->fatTableCache = (u32*)0x3700000; // Revert back for ce7 usage } toncset((u32*)0x027C0000, 0, 0x400); @@ -766,11 +793,6 @@ int arm7_main(void) { int errorCode; - if (REG_SCFG_EXT == 0) { - NDSTouchscreenMode(); - *(u16*)0x4000500 = 0x807F; - } - tDSiHeader dsiHeaderTemp; // Load the NDS file @@ -789,16 +811,21 @@ int arm7_main(void) { ensureBinaryDecompressed(&dsiHeaderTemp.ndshdr, moduleParams, foundModuleParams); - // If possible, set to load ROM into RAM - u32 ROMinRAM = isROMLoadableInRAM(&dsiHeaderTemp.ndshdr, moduleParams, consoleModel); - vu32* arm9StartAddress = storeArm9StartAddress(&dsiHeaderTemp.ndshdr, moduleParams); ndsHeader = loadHeader(&dsiHeaderTemp, moduleParams, dsiModeConfirmed); my_readUserSettings(ndsHeader); // Header has to be loaded first + if (!dsiModeConfirmed || !ROMsupportsDsiMode(&dsiHeaderTemp.ndshdr)) { + NDSTouchscreenMode(); + *(u16*)0x4000500 = 0x807F; + } + + // If possible, set to load ROM into RAM + u32 ROMinRAM = isROMLoadableInRAM(&dsiHeaderTemp.ndshdr, moduleParams, consoleModel); + + const char* romTid = getRomTid(ndsHeader); if (!dsiModeConfirmed) { - const char* romTid = getRomTid(ndsHeader); if ( strncmp(romTid, "APD", 3) != 0 // Pokemon Dash ) { @@ -808,16 +835,23 @@ int arm7_main(void) { nocashMessage("Trying to patch the card...\n"); - tonccpy((u32*)CARDENGINE_ARM7_LOCATION, (u32*)CARDENGINE_ARM7_BUFFERED_LOCATION, 0x10000); - toncset((u32*)CARDENGINE_ARM7_BUFFERED_LOCATION, 0, 0x10000); + tonccpy((u32*)CARDENGINE_ARM7_LOCATION, (u32*)CARDENGINE_ARM7_BUFFERED_LOCATION, 0x12000); + if(gameOnFlashcard || saveOnFlashcard) { + if (!dldiPatchBinary((data_t*)CARDENGINE_ARM7_LOCATION, 0x12000)) { + nocashMessage("ce7 DLDI patch failed"); + dbg_printf("ce7 DLDI patch failed"); + dbg_printf("\n"); + errorOutput(); + } + } if (isSdk5(moduleParams)) { if(gameOnFlashcard && !ROMinRAM) { ce9Location = CARDENGINE_ARM9_SDK5_DLDI_LOCATION; tonccpy((u32*)CARDENGINE_ARM9_SDK5_DLDI_LOCATION, (u32*)CARDENGINE_ARM9_SDK5_DLDI_BUFFERED_LOCATION, 0x7000); if (!dldiPatchBinary((data_t*)(ce9Location), 0x7000)) { - nocashMessage("DLDI patch failed"); - dbg_printf("DLDI patch failed"); + nocashMessage("ce9 DLDI patch failed"); + dbg_printf("ce9 DLDI patch failed"); dbg_printf("\n"); errorOutput(); } @@ -829,37 +863,33 @@ int arm7_main(void) { ce9Location = CARDENGINE_ARM9_DLDI_LOCATION; tonccpy((u32*)CARDENGINE_ARM9_DLDI_LOCATION, (u32*)CARDENGINE_ARM9_DLDI_BUFFERED_LOCATION, 0x7000); if (!dldiPatchBinary((data_t*)(ce9Location), 0x7000)) { - nocashMessage("DLDI patch failed"); - dbg_printf("DLDI patch failed"); + nocashMessage("ce9 DLDI patch failed"); + dbg_printf("ce9 DLDI patch failed"); dbg_printf("\n"); errorOutput(); } } else if (ceCached) { - const char* romTid = getRomTid(ndsHeader); if (strncmp(romTid, "ACV", 3) == 0 // Castlevania DOS || strncmp(romTid, "A2L", 3) == 0 // Anno 1701: Dawn of Discovery ) { ce9Location = CARDENGINE_ARM9_CACHED_LOCATION; - tonccpy((u32*)ce9Location, CARDENGINE_ARM9_RELOC_BUFFERED_LOCATION, 0x3000); + tonccpy((u32*)ce9Location, (u32*)CARDENGINE_ARM9_RELOC_BUFFERED_LOCATION, 0x3000); relocate_ce9(CARDENGINE_ARM9_LOCATION,ce9Location,0x3000); } else ce9Location = patchHeapPointer(moduleParams, ndsHeader); if(ce9Location) { - tonccpy((u32*)ce9Location, CARDENGINE_ARM9_RELOC_BUFFERED_LOCATION, 0x3000); + tonccpy((u32*)ce9Location, (u32*)CARDENGINE_ARM9_RELOC_BUFFERED_LOCATION, 0x3000); relocate_ce9(CARDENGINE_ARM9_LOCATION,ce9Location,0x3000); } else { ce9Location = CARDENGINE_ARM9_LOCATION; - tonccpy((u32*)CARDENGINE_ARM9_LOCATION, CARDENGINE_ARM9_RELOC_BUFFERED_LOCATION, 0x3000); + tonccpy((u32*)CARDENGINE_ARM9_LOCATION, cardengine_arm9_bin, cardengine_arm9_bin_size); } } else { ce9Location = CARDENGINE_ARM9_LOCATION; tonccpy((u32*)CARDENGINE_ARM9_LOCATION, cardengine_arm9_bin, cardengine_arm9_bin_size); } - toncset((u32*)CARDENGINE_ARM9_DLDI_BUFFERED_LOCATION, 0, 0x10000); - - const char* romTid = getRomTid(ndsHeader); if ( strncmp(romTid, "AMQ", 3) == 0 // MvDK2 ) { @@ -896,6 +926,7 @@ int arm7_main(void) { cheatFileCluster, cheatSize, gameOnFlashcard, + saveOnFlashcard, language, dsiModeConfirmed, ROMinRAM, @@ -925,6 +956,8 @@ int arm7_main(void) { (cardengineArm9*)ce9Location, moduleParams, romFile->firstCluster, + savFile->firstCluster, + saveOnFlashcard, ROMinRAM, dsiModeConfirmed, supportsExceptionHandler(ndsHeader), @@ -939,6 +972,9 @@ int arm7_main(void) { } } + toncset((u32*)CARDENGINE_ARM7_BUFFERED_LOCATION, 0, 0x28000); + + arm9_boostVram = boostVram; diff --git a/retail/bootloader/source/arm7/patch_arm9.c b/retail/bootloader/source/arm7/patch_arm9.c index 5b35a46a8..35175921e 100644 --- a/retail/bootloader/source/arm7/patch_arm9.c +++ b/retail/bootloader/source/arm7/patch_arm9.c @@ -626,7 +626,6 @@ void relocate_ce9(u32 default_location, u32 current_location, u32 size) { ce9->patches->cacheFlushRef = (u32*)((u32)ce9->patches->cacheFlushRef - default_location + current_location); ce9->patches->terminateForPullOutRef = (u32*)((u32)ce9->patches->terminateForPullOutRef - default_location + current_location); ce9->patches->pdash_read = (u32*)((u32)ce9->patches->pdash_read - default_location + current_location); - ce9->patches->ipcSyncHandlerRef = (u32*)((u32)ce9->patches->ipcSyncHandlerRef - default_location + current_location); ce9->thumbPatches->card_read_arm9 = (u32*)((u32)ce9->thumbPatches->card_read_arm9 - default_location + current_location); ce9->thumbPatches->card_pull_out_arm9 = (u32*)((u32)ce9->thumbPatches->card_pull_out_arm9 - default_location + current_location); ce9->thumbPatches->card_id_arm9 = (u32*)((u32)ce9->thumbPatches->card_id_arm9 - default_location + current_location); diff --git a/retail/cardengine/arm7/cardengine.ld.in b/retail/cardengine/arm7/cardengine.ld.in index 6e1442111..cdb41d3e3 100644 --- a/retail/cardengine/arm7/cardengine.ld.in +++ b/retail/cardengine/arm7/cardengine.ld.in @@ -6,7 +6,7 @@ OUTPUT_ARCH(arm) MEMORY { - vram : ORIGIN = CARDENGINE_ARM7_LOCATION, LENGTH = 64K /* WRAM A */ + vram : ORIGIN = CARDENGINE_ARM7_LOCATION, LENGTH = 72K /* WRAM A */ } __vram_start = ORIGIN(vram); diff --git a/retail/cardengine/arm7/source/card_engine_header.s b/retail/cardengine/arm7/source/card_engine_header.s index b69bcd8b4..92cf996a3 100644 --- a/retail/cardengine/arm7/source/card_engine_header.s +++ b/retail/cardengine/arm7/source/card_engine_header.s @@ -16,6 +16,7 @@ .global fileCluster .global saveCluster .global gameOnFlashcard +.global saveOnFlashcard .global language .global gottenSCFGExt .global dsiMode @@ -52,6 +53,8 @@ cardStruct: .word 0x00000000 gameOnFlashcard: .word 0x00000000 +saveOnFlashcard: + .word 0x00000000 language: .word 0x00000000 gottenSCFGExt: diff --git a/retail/cardengine/arm7/source/cardengine.c b/retail/cardengine/arm7/source/cardengine.c index 07bd59b80..e82ba9898 100644 --- a/retail/cardengine/arm7/source/cardengine.c +++ b/retail/cardengine/arm7/source/cardengine.c @@ -54,8 +54,9 @@ extern u32 fileCluster; extern u32 saveCluster; extern module_params_t* moduleParams; extern u32 gameOnFlashcard; +extern u32 saveOnFlashcard; extern u32 language; -extern u32 gottenSCFGExt; +//extern u32 gottenSCFGExt; extern u32 dsiMode; extern u32 ROMinRAM; extern u32 consoleModel; @@ -65,7 +66,7 @@ extern u32 preciseVolumeControl; vu32* volatile sharedAddr = (vu32*)CARDENGINE_SHARED_ADDRESS; -bool sdRead = true; // Unused, but added to prevent errors +bool sdRead = true; static bool initialized = false; //static bool initializedIRQ = false; @@ -124,7 +125,13 @@ static void initialize(void) { sdmmc_init(); SD_Init(); } + sdRead = true; // Switch to SD FAT_InitFiles(false, 0); + if (gameOnFlashcard || saveOnFlashcard) { + sdRead = false; // Switch to flashcard + FAT_InitFiles(true, 0); + sdRead = true; // Switch to SD + } //romFile = getFileFromCluster(fileCluster); //buildFatTableCache(&romFile, 0); #ifdef DEBUG @@ -488,7 +495,7 @@ static void runCardEngineCheckResume(void) { if(readOngoing) { if(resume_cardRead_arm9()) { - *(vu32*)(0x027FFB14) = 0; + *(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) = 0; } } unlockMutex(&cardEgnineCommandMutex); @@ -520,29 +527,33 @@ static void runCardEngineCheck(void) { i2cWriteRegister(0x4A, 0x11, 0x01); }*/ - if (*(vu32*)(0x027FFB14) == (vu32)0x026FF800) { + if (*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x026FF800) { + sdRead = true; log_arm9(); - *(vu32*)(0x027FFB14) = 0; + *(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) = 0; } - if ((*(vu32*)(0x027FFB14) == (vu32)0x025FFB08) || (*(vu32*)(0x027FFB14) == (vu32)0x025FFB0A)) { - dmaLed = (*(vu32*)(0x027FFB14) == (vu32)0x025FFB0A); + if ((*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x025FFB08) || (*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x025FFB0A)) { + sdRead = true; + dmaLed = (*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x025FFB0A); if(start_cardRead_arm9()) { - *(vu32*)(0x027FFB14) = 0; + *(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) = 0; } } - if (*(vu32*)(0x027FFB14) == (vu32)0x025FFC01) { - dmaLed = (*(vu32*)(0x027FFB14) == (vu32)0x025FFC01); + if (*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x025FFC01) { + sdRead = true; + dmaLed = (*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x025FFC01); nandRead(); - *(vu32*)(0x027FFB14) = 0; + *(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) = 0; } - if (*(vu32*)(0x027FFB14) == (vu32)0x025FFC02) { - dmaLed = (*(vu32*)(0x027FFB14) == (vu32)0x025FFC02); + if (*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x025FFC02) { + sdRead = true; + dmaLed = (*(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) == (vu32)0x025FFC02); nandWrite(); - *(vu32*)(0x027FFB14) = 0; + *(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) = 0; } /*if (*(vu32*)(0x027FFB14) == (vu32)0x020FF800) { @@ -551,7 +562,7 @@ static void runCardEngineCheck(void) { }*/ } else { if(resume_cardRead_arm9()) { - *(vu32*)(0x027FFB14) = 0; + *(vu32*)(CARDENGINE_SHARED_ADDRESS+0xC) = 0; } } unlockMutex(&cardEgnineCommandMutex); @@ -666,178 +677,6 @@ void myIrqHandlerVBlank(void) { } } - if (gottenSCFGExt == 0) { - // Control volume with the - and + buttons. - u8 volLevel; - u8 i2cVolLevel = i2cReadRegister(0x4A, 0x40); - if (consoleModel >= 2) { - switch(i2cVolLevel) { - case 0x00: - case 0x01: - default: - volLevel = 0; - break; - case 0x02: - case 0x03: - volLevel = 1; - break; - case 0x04: - case 0x05: - volLevel = 2; - break; - case 0x06: - case 0x07: - volLevel = 3; - break; - case 0x08: - case 0x09: - volLevel = 4; - break; - case 0x0A: - case 0x0B: - volLevel = 5; - break; - case 0x0C: - case 0x0D: - volLevel = 6; - break; - case 0x0E: - case 0x0F: - volLevel = 7; - break; - case 0x10: - case 0x11: - volLevel = 8; - break; - case 0x12: - case 0x13: - volLevel = 9; - break; - case 0x14: - case 0x15: - volLevel = 10; - break; - case 0x16: - case 0x17: - volLevel = 11; - break; - case 0x18: - case 0x19: - volLevel = 12; - break; - case 0x1A: - case 0x1B: - volLevel = 13; - break; - case 0x1C: - case 0x1D: - volLevel = 14; - break; - case 0x1E: - case 0x1F: - volLevel = 15; - break; - } - } else { - switch(i2cVolLevel) { - case 0x00: - case 0x01: - default: - volLevel = 0; - break; - case 0x02: - case 0x03: - volLevel = 1; - break; - case 0x04: - volLevel = 2; - break; - case 0x05: - volLevel = 3; - break; - case 0x06: - volLevel = 4; - break; - case 0x07: - volLevel = 6; - break; - case 0x08: - volLevel = 8; - break; - case 0x09: - volLevel = 10; - break; - case 0x0A: - volLevel = 12; - break; - case 0x0B: - volLevel = 15; - break; - case 0x0C: - volLevel = 17; - break; - case 0x0D: - volLevel = 21; - break; - case 0x0E: - volLevel = 24; - break; - case 0x0F: - volLevel = 28; - break; - case 0x10: - volLevel = 32; - break; - case 0x11: - volLevel = 36; - break; - case 0x12: - volLevel = 40; - break; - case 0x13: - volLevel = 45; - break; - case 0x14: - volLevel = 50; - break; - case 0x15: - volLevel = 55; - break; - case 0x16: - volLevel = 60; - break; - case 0x17: - volLevel = 66; - break; - case 0x18: - volLevel = 71; - break; - case 0x19: - volLevel = 78; - break; - case 0x1A: - volLevel = 85; - break; - case 0x1B: - volLevel = 91; - break; - case 0x1C: - volLevel = 100; - break; - case 0x1D: - volLevel = 113; - break; - case 0x1E: - volLevel = 120; - break; - case 0x1F: - volLevel = 127; - break; - } - } - REG_MASTER_VOLUME = volLevel; - } - if (consoleModel < 2) { if (preciseVolumeControl && romread_LED == 0) { // Precise volume adjustment (for DSi) @@ -884,8 +723,8 @@ void myIrqHandlerVBlank(void) { cheat_engine_start(); const char* romTid = getRomTid(ndsHeader); - if (strncmp(romTid, "UOR", 3) == 0 - || strncmp(romTid, "UXB", 3) == 0 + if ((strncmp(romTid, "UOR", 3) == 0 && !saveOnFlashcard) + || (strncmp(romTid, "UXB", 3) == 0 && !saveOnFlashcard) || (!ROMinRAM && !gameOnFlashcard)) { runCardEngineCheck(); } @@ -948,12 +787,13 @@ bool eepromRead(u32 src, void *dst, u32 len) { dbg_hexa(len); #endif - if (isSdEjected()) { + if (!saveOnFlashcard && isSdEjected()) { return false; } if (tryLockMutex(&saveMutex)) { initialize(); + sdRead = (saveOnFlashcard ? false : true); fileRead(dst, *savFile, src, len, -1); unlockMutex(&saveMutex); } @@ -972,12 +812,13 @@ bool eepromPageWrite(u32 dst, const void *src, u32 len) { dbg_hexa(len); #endif - if (isSdEjected()) { + if (!saveOnFlashcard && isSdEjected()) { return false; } if (tryLockMutex(&saveMutex)) { initialize(); + sdRead = (saveOnFlashcard ? false : true); if (saveTimer == 0) { i2cWriteRegister(0x4A, 0x12, 0x01); // When we're saving, power button does nothing, in order to prevent corruption. } @@ -1000,12 +841,13 @@ bool eepromPageProg(u32 dst, const void *src, u32 len) { dbg_hexa(len); #endif - if (isSdEjected()) { + if (!saveOnFlashcard && isSdEjected()) { return false; } if (tryLockMutex(&saveMutex)) { initialize(); + sdRead = (saveOnFlashcard ? false : true); if (saveTimer == 0) { i2cWriteRegister(0x4A, 0x12, 0x01); // When we're saving, power button does nothing, in order to prevent corruption. } @@ -1039,7 +881,7 @@ bool eepromPageErase (u32 dst) { dbg_printf("\narm7 eepromPageErase\n"); #endif - if (isSdEjected()) { + if (!saveOnFlashcard && isSdEjected()) { return false; } @@ -1106,7 +948,6 @@ Existing/known ROM IDs are: C2h,F0h,00h,90h 3DS Macronix 4GB ROM CTR-P-ABRJ Biohazard Revelations FFh,FFh,FFh,FFh None (no cartridge inserted) */ -bool cardInitialized = false; u32 cardId(void) { #ifdef DEBUG dbg_printf("\ncardId\n"); @@ -1119,8 +960,6 @@ u32 cardId(void) { //if (cardInitialized && strncmp(getRomTid(ndsHeader), "BO5", 3) == 0) cardid = 0xFF000000; // golden sun //if (cardInitialized && strncmp(getRomTid(ndsHeader), "BO5", 3) == 0) cardid = 0x000000FF; // golden sun - cardInitialized= true; - #ifdef DEBUG dbg_hexa(cardid); #endif @@ -1144,10 +983,9 @@ bool cardRead(u32 dma, u32 src, void *dst, u32 len) { if (ROMinRAM) { tonccpy(dst, romLocation + src, len); - } else if (gameOnFlashcard) { - return true; } else { initialize(); + sdRead = (gameOnFlashcard ? false : true); cardReadLED(true); // When a file is loading, turn on LED for card read indicator //ndmaUsed = false; #ifdef DEBUG diff --git a/retail/cardengine/arm7/source/my_dldi.s b/retail/cardengine/arm7/source/my_dldi.s index 80cf08d5f..844cc9d6f 100644 --- a/retail/cardengine/arm7/source/my_dldi.s +++ b/retail/cardengine/arm7/source/my_dldi.s @@ -32,6 +32,73 @@ __mydldi_start: +#ifndef NO_DLDI + +@--------------------------------------------------------------------------------- +@ Driver patch file standard header -- 16 bytes +#ifdef STANDARD_DLDI + .word 0xBF8DA5ED @ Magic number to identify this region +#else + .word 0xBF8DA5EE @ Magic number to identify this region +#endif + .asciz " Chishm" @ Identifying Magic string (8 bytes with null terminator) + .byte 0x01 @ Version number + .byte 0x0e @ 16KiB @ Log [base-2] of the size of this driver in bytes. + .byte 0x00 @ Sections to fix + .byte 0x0e @ 16KiB @ Log [base-2] of the allocated space in bytes. + +@--------------------------------------------------------------------------------- +@ Text identifier - can be anything up to 47 chars + terminating null -- 16 bytes + .align 4 + .asciz "Loader (No interface)" + +@--------------------------------------------------------------------------------- +@ Offsets to important sections within the data -- 32 bytes + .align 6 + .word __mydldi_start @ data start + .word _dldi_end @ data end + .word 0x00000000 @ Interworking glue start -- Needs address fixing + .word 0x00000000 @ Interworking glue end + .word 0x00000000 @ GOT start -- Needs address fixing + .word 0x00000000 @ GOT end + .word 0x00000000 @ bss start -- Needs setting to zero + .word 0x00000000 @ bss end +@--------------------------------------------------------------------------------- +@ IO_INTERFACE data -- 32 bytes +__myio_dldi: + .ascii "DLDI" @ ioType + .word 0x00000000 @ Features + .word __mydldi_startup @ + .word _DLDI_isInserted @ + .word _DLDI_readSectors @ Function pointers to standard device driver functions + .word _DLDI_writeSectors @ + .word _DLDI_clearStatus @ + .word _DLDI_shutdown @ + + +@--------------------------------------------------------------------------------- + +__mydldi_startup: +_DLDI_isInserted: +_DLDI_readSectors: +_DLDI_writeSectors: +_DLDI_clearStatus: +_DLDI_shutdown: + mov r0, #0x00 @ Return false for every function + bx lr + + + +@--------------------------------------------------------------------------------- + .align + .pool + + .space (__mydldi_start + 16384) - . @ Fill to 16KiB + +_dldi_end: + .end +@--------------------------------------------------------------------------------- +#else @--------------------------------------------------------------------------------- @ IO_INTERFACE data -- 32 bytes __myio_dldi: @@ -53,3 +120,5 @@ _DLDI_shutdown: mov r0, #0x00 @ Return false for every function bx lr + +#endif diff --git a/retail/cardengine/arm9/source/card_engine_header.s b/retail/cardengine/arm9/source/card_engine_header.s index 38624e518..5edf02701 100644 --- a/retail/cardengine/arm9/source/card_engine_header.s +++ b/retail/cardengine/arm9/source/card_engine_header.s @@ -22,6 +22,10 @@ moduleParams: .word 0x00000000 fileCluster: .word 0x00000000 +saveCluster: + .word 0x00000000 +saveOnFlashcard: + .word 0x00000000 cardStruct0: .word 0x00000000 cacheStruct: @@ -34,8 +38,6 @@ enableExceptionHandler: .word 0x00000000 consoleModel: .word 0x00000000 -irqTable: - .word 0x00000000 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -58,7 +60,6 @@ patches: needFlushDCCache: .word 0x0 .word pdash_read -.word ipcSyncHandler thumbPatches: .word thumb_card_read_arm9 .word thumb_card_pull_out_arm9 @@ -160,7 +161,6 @@ card_dma_arm9: ldmfd sp!, {r1-r11,pc} - mov r0, #0 bx lr _blx_r6_stub_card_read_dma: bx r6 @@ -224,7 +224,6 @@ thumb_card_dma_arm9: bl _blx_r6_stub_thumb_card_read_dma pop {r1-r7, pc} - mov r0, #0 bx lr _blx_r6_stub_thumb_card_read_dma: bx r6 @@ -372,24 +371,6 @@ thumb_card_pull: .arm -ipcSyncHandler: -@ Hook the return address, then go back to the original function - stmdb sp!, {lr} - adr lr, code_handler_start_ipc - ldr r0, intr_ipc_orig_return - bx r0 - -code_handler_start_ipc: - push {r0-r12} - ldr r3, =myIrqHandlerIPC - bl _blx_r3_stub_start_ipc @ jump to myIrqHandler - - @ exit after return - b exit -_blx_r3_stub_start_ipc: - bx r3 -.pool - .global callSleepThumb .type callSleepThumb STT_FUNC callSleepThumb: diff --git a/retail/cardengine/arm9/source/cardengine.c b/retail/cardengine/arm9/source/cardengine.c index 26f37ef0b..35727a256 100644 --- a/retail/cardengine/arm9/source/cardengine.c +++ b/retail/cardengine/arm9/source/cardengine.c @@ -63,6 +63,7 @@ static tNDSHeader* ndsHeader = (tNDSHeader*)NDS_HEADER; #ifdef DLDI static aFile* romFile = (aFile*)ROM_FILE_LOCATION_MAINMEM; +static aFile* savFile = (aFile*)SAV_FILE_LOCATION_MAINMEM; bool sdRead = false; #else @@ -151,7 +152,7 @@ static void waitForArm7(void) { } } -static bool IPC_SYNC_hooked = false; +/*static bool IPC_SYNC_hooked = false; static void hookIPC_SYNC(void) { if (!IPC_SYNC_hooked) { u32* ipcSyncHandler = ce9->irqTable + 16; @@ -175,7 +176,7 @@ static void disableIPCSYNC(void) { REG_IPC_SYNC &= !IPC_SYNC_IRQ_ENABLE; REG_IE &= !IRQ_IPC_SYNC; leaveCriticalSection(oldIME); -} +}*/ static void clearIcache (void) { // Seems to have no effect @@ -393,12 +394,13 @@ u32 cardReadDma() { && !(((int)src) & 511) ) { dmaLed = true; + #ifndef DLDI if (ce9->patches->sleepRef || ce9->thumbPatches->sleepRef) // so far dma is useless without sleep method available { isDma = true; - hookIPC_SYNC(); - enableIPCSYNC(); + //hookIPC_SYNC(); + //enableIPCSYNC(); /*if (len < THRESHOLD_CACHE_FLUSH) { int oldIME = enterCriticalSection(); @@ -424,6 +426,7 @@ u32 cardReadDma() { dma=4; clearIcache(); } + #endif } else { dmaLed = false; isDma = false; @@ -444,8 +447,8 @@ int cardReadPDash(vu32* volatile cardStruct, u32 src, u8* dst, u32 len) { dmaLed = true; - hookIPC_SYNC(); - enableIPCSYNC(); + //hookIPC_SYNC(); + //enableIPCSYNC(); accessCounter++; while(len > 0) { @@ -642,6 +645,13 @@ void cardPullOut(void) { } u32 nandRead(void* memory,void* flash,u32 len,u32 dma) { + if (ce9->saveOnFlashcard) { +#ifdef DLDI + fileRead(memory, *savFile, flash, len, -1); +#endif + return 0; + } + // Send a command to the ARM7 to read the nand save u32 commandNandRead = 0x025FFC01; @@ -656,6 +666,13 @@ u32 nandRead(void* memory,void* flash,u32 len,u32 dma) { } u32 nandWrite(void* memory,void* flash,u32 len,u32 dma) { + if (ce9->saveOnFlashcard) { +#ifdef DLDI + fileWrite(memory, *savFile, flash, len, -1); +#endif + return 0; + } + // Send a command to the ARM7 to read the nand save u32 commandNandWrite = 0x025FFC02; diff --git a/retail/cardengine/arm9_sdk5/source/card_engine_header.s b/retail/cardengine/arm9_sdk5/source/card_engine_header.s index ea290a017..64565e348 100644 --- a/retail/cardengine/arm9_sdk5/source/card_engine_header.s +++ b/retail/cardengine/arm9_sdk5/source/card_engine_header.s @@ -22,6 +22,10 @@ moduleParams: .word 0x00000000 fileCluster: .word 0x00000000 +saveCluster: + .word 0x00000000 +saveOnFlashcard: + .word 0x00000000 cardStruct0: .word 0x00000000 cacheStruct: diff --git a/retail/common/include/cardengine_header_arm7.h b/retail/common/include/cardengine_header_arm7.h index 8bcb7f633..1e4d4e134 100644 --- a/retail/common/include/cardengine_header_arm7.h +++ b/retail/common/include/cardengine_header_arm7.h @@ -69,6 +69,7 @@ typedef struct cardengineArm7 { u32 fileCluster; u32 cardStruct; u32 gameOnFlashcard; + u32 saveOnFlashcard; u32 language; //u8 u32 gottenSCFGExt; u32 dsiMode; diff --git a/retail/common/include/cardengine_header_arm9.h b/retail/common/include/cardengine_header_arm9.h index bf1509005..27b847df7 100644 --- a/retail/common/include/cardengine_header_arm9.h +++ b/retail/common/include/cardengine_header_arm9.h @@ -23,7 +23,6 @@ typedef struct cardengineArm9Patches { u32* swi02; u32 needFlushDCCache; u32* pdash_read; - u32* ipcSyncHandlerRef; } __attribute__ ((__packed__)) cardengineArm9Patches; @@ -56,14 +55,14 @@ typedef struct cardengineArm9 { u32 intr_ipc_orig_return; const module_params_t* moduleParams; u32 fileCluster; + u32 saveCluster; + u32 saveOnFlashcard; u32 cardStruct0; u32 cacheStruct; u32 ROMinRAM; u32 dsiMode; u32 enableExceptionHandler; u32 consoleModel; - u32 irqTable; - u32 asyncPrefetch; } __attribute__ ((__packed__)) cardengineArm9; #endif // CARDENGINE_HEADER_ARM9_H diff --git a/retail/common/include/load_crt0.h b/retail/common/include/load_crt0.h index 7dc80690b..a46182aa8 100644 --- a/retail/common/include/load_crt0.h +++ b/retail/common/include/load_crt0.h @@ -10,8 +10,7 @@ typedef struct loadCrt0 { u32 storedFileCluster; u32 initDisc; u32 gameOnFlashcard; - u32 argStart; - u32 argSize; + u32 saveOnFlashcard; u32 dldiOffset; u32 dsiSD; u32 saveFileCluster; @@ -32,6 +31,7 @@ typedef struct loadCrt0 { u32 boostVram; u32 gameSoftReset; u32 forceSleepPatch; + u32 volumeFix; u32 preciseVolumeControl; u32 logging; u32 cardengine_arm9_offset; //cardengineArm9* cardengine_arm9; diff --git a/retail/common/include/locations.h b/retail/common/include/locations.h index 01ff538e1..0c3a5d7e0 100644 --- a/retail/common/include/locations.h +++ b/retail/common/include/locations.h @@ -4,16 +4,17 @@ #define EXCEPTION_STACK_LOCATION 0x23EFFFC #define ROM_FILE_LOCATION 0x37D5000 -#define ROM_FILE_LOCATION_MAINMEM 0x277FFE0 +#define ROM_FILE_LOCATION_MAINMEM 0x277FFC0 #define SAV_FILE_LOCATION (ROM_FILE_LOCATION + 32) //+ sizeof(aFile) +#define SAV_FILE_LOCATION_MAINMEM 0x277FFE0 #define LOAD_CRT0_LOCATION 0x06860000 // LCDC_BANK_D #define CARDENGINE_ARM7_BUFFERED_LOCATION 0x027D0000 -#define CARDENGINE_ARM9_RELOC_BUFFERED_LOCATION 0x027E0000 -#define CARDENGINE_ARM9_DLDI_BUFFERED_LOCATION 0x027E3000 -#define CARDENGINE_ARM9_SDK5_BUFFERED_LOCATION 0x027EA000 -#define CARDENGINE_ARM9_SDK5_DLDI_BUFFERED_LOCATION 0x027ED000 +#define CARDENGINE_ARM9_RELOC_BUFFERED_LOCATION 0x027E2000 +#define CARDENGINE_ARM9_DLDI_BUFFERED_LOCATION 0x027E5000 +#define CARDENGINE_ARM9_SDK5_BUFFERED_LOCATION 0x027EC000 +#define CARDENGINE_ARM9_SDK5_DLDI_BUFFERED_LOCATION 0x027EF000 #define CARDENGINE_ARM7_LOCATION 0x037C0000 #define CARDENGINE_ARM9_LOCATION 0x02700000 @@ -23,7 +24,7 @@ #define CARDENGINE_ARM9_SDK5_DLDI_LOCATION 0x023F9000 #define CARDENGINE_ARM9_GSDD_LOCATION 0x037F0000 // WRAM-A slot 0 -#define CARDENGINE_SHARED_ADDRESS 0x027FFB08 +#define CARDENGINE_SHARED_ADDRESS 0x027FFB0C //#define TEMP_MEM 0x02FFE000 // __DSiHeader