diff --git a/arm9/source/auxspi.cpp b/arm9/source/auxspi.cpp index c60a96c..d5f2967 100644 --- a/arm9/source/auxspi.cpp +++ b/arm9/source/auxspi.cpp @@ -51,15 +51,24 @@ uint8 jedec_table(uint32 id) // 1 MB case 0x204014: return 0x14; + // 2 MB (not sure if this exists, but I vaguely remember something...) + case 0x204015: + return 0x15; // 8 MB (Band Brothers DX) + case 0x202017: // which one? (more work is required to unlock this save chip!) case 0x204017: return 0x17; - default: - return 0; + default: { + for (int i = 0; i < EXTRA_ARRAY_SIZE; i++) { + if (extra_id[i] == id) + return extra_size[i]; + } + return 0; // unknown save type! + } }; } -uint8 type2_size() +uint8 type2_size(bool ir = false) { static const uint32 offset0 = (8*1024-1); // 8KB static const uint32 offset1 = (2*8*1024-1); // 16KB @@ -67,12 +76,12 @@ uint8 type2_size() u8 buf2; // +8k data read -> read u8 buf3; // +0k ~data write u8 buf4; // +8k data new comp buf2 - auxspi_read_data(offset0, &buf1, 1, 2); - auxspi_read_data(offset1, &buf2, 1, 2); + auxspi_read_data(offset0, &buf1, 1, 2, ir); + auxspi_read_data(offset1, &buf2, 1, 2, ir); buf3=~buf1; - auxspi_write_data(offset0, &buf3, 1, 2); - auxspi_read_data (offset1, &buf4, 1, 2); - auxspi_write_data(offset0, &buf1, 1, 2); + auxspi_write_data(offset0, &buf3, 1, 2, ir); + auxspi_read_data (offset1, &buf4, 1, 2, ir); + auxspi_write_data(offset0, &buf1, 1, 2, ir); if(buf4!=buf2) // +8k return 0x0d; // 8KB(64kbit) else @@ -89,6 +98,7 @@ uint8 auxspi_save_type(bool ir) if ((sr & 0xfd) == 0xF0 && (jedec == 0x00ffffff)) return 1; if ((sr & 0xfd) == 0x00 && (jedec == 0x00ffffff)) return 2; if ((sr & 0xfd) == 0x00 && (jedec != 0x00ffffff)) return 3; // should also cover Pokemon HG/SS + // TODO: add support for Band Brothers DX (as soon as I know how) return 0; } @@ -100,13 +110,13 @@ uint32 auxspi_save_size(bool ir) uint8 auxspi_save_size_log_2(bool ir) { - uint8 type = auxspi_save_type(); + uint8 type = auxspi_save_type(ir); // TESTME: "ir" was missing, should fix recent issues switch (type) { case 1: return 0x09; // 512 bytes break; case 2: - return type2_size(); + return type2_size(ir); break; case 3: return jedec_table(auxspi_save_jedec_id(ir)); @@ -127,6 +137,7 @@ uint32 auxspi_save_jedec_id(bool ir) id |= auxspi_read() << 8; id |= auxspi_read(); auxspi_close(); + return id; } @@ -174,12 +185,10 @@ void auxspi_read_data(uint32 addr, uint8* buf, uint16 cnt, uint8 type, bool ir) void auxspi_write_data(uint32 addr, uint8 *buf, uint16 cnt, uint8 type, bool ir) { -/* if (type == 0) type = auxspi_save_type(); if (type == 0) return; - */ uint32 addr_end = addr + cnt; int i; @@ -223,8 +232,6 @@ void auxspi_write_data(uint32 addr, uint8 *buf, uint16 cnt, uint8 type, bool ir) } auxspi_close_lite(); - // wait for programming to finish - //auxspi_wait_wip(); // wait programming to finish if (ir) auxspi_disable_infrared(); @@ -270,7 +277,6 @@ void auxspi_erase(bool ir) auxspi_close_lite(); // wait for programming to finish - //auxspi_wait_wip(); if (ir) auxspi_disable_infrared(); auxspi_open(0); diff --git a/arm9/source/auxspi_core.inc b/arm9/source/auxspi_core.inc index ec2565e..81ec5af 100644 --- a/arm9/source/auxspi_core.inc +++ b/arm9/source/auxspi_core.inc @@ -36,7 +36,7 @@ inline void auxspi_wait_busy() inline void auxspi_open(uint8 device) { - REG_AUXSPICNT = 0xa040 | (device & 3); + REG_AUXSPICNT = 0xa040 | (device & 3) | 3; auxspi_wait_busy(); } diff --git a/arm9/source/fileselect.cpp b/arm9/source/fileselect.cpp index daadd4d..1fc31ee 100644 --- a/arm9/source/fileselect.cpp +++ b/arm9/source/fileselect.cpp @@ -178,10 +178,6 @@ void fileSelect(const char *startdir, char *out_dir, char *out_fname, netbuf *bu ftpGetFileList("/", buf, num_files); else fileGetFileList(startdir, num_files); - if (num_files == 0) { - displayMessage("ERROR"); - while(1); - } filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel); while (!select) { diff --git a/arm9/source/globals.cpp b/arm9/source/globals.cpp index 4e2c166..cc8808c 100644 --- a/arm9/source/globals.cpp +++ b/arm9/source/globals.cpp @@ -45,3 +45,6 @@ u32 mode = 0; u32 ezflash = 0; int slot2 = 0; + +u32 extra_id[EXTRA_ARRAY_SIZE]; +u8 extra_size[EXTRA_ARRAY_SIZE]; diff --git a/arm9/source/globals.h b/arm9/source/globals.h index 02196cc..85bcbd5 100644 --- a/arm9/source/globals.h +++ b/arm9/source/globals.h @@ -51,4 +51,10 @@ extern u32 ezflash; extern int slot2; +// this should be enough for the forseeable future +#define EXTRA_ARRAY_SIZE 16 + +extern u32 extra_id[EXTRA_ARRAY_SIZE]; +extern u8 extra_size[EXTRA_ARRAY_SIZE]; + #endif // GLOBALS_H \ No newline at end of file diff --git a/arm9/source/hardware.cpp b/arm9/source/hardware.cpp index c24413d..01505d9 100644 --- a/arm9/source/hardware.cpp +++ b/arm9/source/hardware.cpp @@ -57,7 +57,6 @@ static u32 pitch = 0x40000; // --------------------------------------------------------------------- -// FIXME: after the slot 1 detection was factored out, swap_cart no longer has perfect accuracy! bool swap_cart() { sNDSHeader nds; @@ -74,12 +73,15 @@ bool swap_cart() // don't try to dump a flash card if (slot_1_type == 2) continue; + sysSetBusOwners(true, true); // this will break DLDI on the Cyclops Evolution, but we need it anyway. cardReadHeader((u8*)&nds); displayPrintUpper(); - if (!nds.gameTitle[0]) + if (!nds.gameTitle[0]) { + displayMessage2A(STR_HW_CARD_UNREADABLE, false); continue; + } return true; } @@ -104,7 +106,19 @@ u32 get_slot1_type() if (size1 > 0) return 0; - // No save size test returned a save chip, so it must be a flash card. + // No save size test returned a save chip, so it must be a flash card, + // or a type 3 save with an unknown JEDEC ID. Unfortunately, due to + // different behaviour of flash cards, we can't test for this case, + // or the flash card may be recognised as "type 3 game". + /* + u32 id2 = auxspi_save_jedec_id(true); + u32 id1 = auxspi_save_jedec_id(false); + if (id2 != 0x00ffffff) + return 1; + if (id1 != 0x00ffffff) + return 0; + */ + return 2; } diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index 42031d2..5eb312b 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -328,6 +328,21 @@ bool loadIniFile(char* path) ini_close(ini); + // load additional Flash chip signatures (JEDEC IDs) + ini_locateHeading(ini, "new chips"); + for (int i = 0; i < EXTRA_ARRAY_SIZE; i++) { + int tmp; + sprintf(txt, "%i-id", i); + ini_locateKey(ini, txt); + ini_readInt(ini, &tmp); + extra_id[i] = (u32)tmp; + // + sprintf(txt, "%i-size", i); + ini_locateKey(ini, txt); + ini_readInt(ini, &tmp); + extra_size[i] = tmp; + } + // delete temp file (which is a remnant of inilib) remove("/tmpfile"); @@ -357,12 +372,12 @@ bool has_argv(int argc, char* argv[]) char *arg0 = argv[0]; // test for possible "/path", "fat*:/path" and "sd:/*". if (*arg0 == 'f') - if (strncasecmp(argv[0], "fat:/", 5) || strncasecmp(argv[0], "fat1:/", 6) - || strncasecmp(argv[0], "fat2:/", 6)) + if (!strncasecmp(argv[0], "fat:/", 5) || !strncasecmp(argv[0], "fat1:/", 6) + || !strncasecmp(argv[0], "fat2:/", 6)) return true; if (*arg0 == 's') - if (strncasecmp(argv[0], "sd:/", 4)) + if (!strncasecmp(argv[0], "sd:/", 4)) return true; if (*arg0 == '/') @@ -381,34 +396,37 @@ int main(int argc, char* argv[]) // detect hardware mode = hwDetect(); - // Init DLDI (file system driver), skip for mode == 4,5 which already calls this during - // hardware initialisation - if (mode < 4) { - int fat = fatInitDefault(); - if (fat == 0) { - displayMessage2A(STR_BOOT_DLDI_ERROR,true); - while (1); - } + // Init DLDI (file system driver) + int fat = fatInitDefault(); + if (fat == 0) { + displayMessage2A(STR_BOOT_DLDI_ERROR,true); + while (1); } // Load the ini file with the FTP settings and more options + for (int i = 0; i < EXTRA_ARRAY_SIZE; i++) { + extra_id[i] = 0xff000000; + extra_size[i] = 0; + } if (has_argv(argc, argv)) loadIniFile(argv[0]); else loadIniFile(0); + // load strings + stringsLoadFile(0); + // prepare the global data buffer data = (u8*)malloc(size_buf); - // This should not be required, but better safe than sorry. On the DS, it *might* be + // On my Cyclops, no 2MB buffer is available after loading strings! bad memory management? + // Anyway, we can't do anything except for the following (which restricts the usefulness + // of FTP safe mode) // possible that no continuous 2 MB are available. - if (data == NULL) { + while (data == NULL) { size_buf >>= 1; data = (u8*)malloc(size_buf); } - // load strings - stringsLoadFile(0); - // okay, we got our HW identified; now branch to the corresponding main function/event handler switch (mode) { case 1: diff --git a/arm9/source/strings.cpp b/arm9/source/strings.cpp index 3fd5190..e75a2a3 100644 --- a/arm9/source/strings.cpp +++ b/arm9/source/strings.cpp @@ -78,6 +78,7 @@ bool stringsLoadFile(const char *fname) ADD_STRING(STR_BOOT_DLDI_ERROR,"DLDI initialisation error!"); // ADD_STRING(STR_HW_SWAP_CARD,"Please take out Slot 1\nflash card and insert a game\n\nPress A when done."); + ADD_STRING(STR_HW_CARD_UNREADABLE,"I can't read the game\ninserted in slot 1.\nPlease eject and retry."); ADD_STRING(STR_HW_WRONG_GAME,"This game has a save chip\nthat is smaller than the\nsave you are going to\nwrite. Please insert a\ndifferent game.\n\nPress A when done."); ADD_STRING(STR_HW_PLEASE_REBOOT,"Done! Please power off\n(and restart if you want\nto do more)."); // diff --git a/savegame_manager.odt b/savegame_manager.odt index 25d10c6..212d05d 100644 Binary files a/savegame_manager.odt and b/savegame_manager.odt differ