diff --git a/arm9/Makefile b/arm9/Makefile index 9e35932..c097994 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -41,6 +41,7 @@ LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- LIBS := -lfat -ldswifi9 -lnds9 +#LIBS := -L../../../../libfat-src-1.0.9/lib -lfatx -ldswifi9 -lnds9x #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/arm9/source/auxspi.cpp b/arm9/source/auxspi.cpp index e805643..6fa740d 100644 --- a/arm9/source/auxspi.cpp +++ b/arm9/source/auxspi.cpp @@ -32,7 +32,8 @@ using std::max; -extern u8 data[0x8000]; +extern u8 *data; +extern u32 size_buf; // ======================================================== diff --git a/arm9/source/auxspi_core.cpp b/arm9/source/auxspi_core.cpp index 9670f7a..853d3ca 100644 --- a/arm9/source/auxspi_core.cpp +++ b/arm9/source/auxspi_core.cpp @@ -26,6 +26,8 @@ #include +extern int ir_delay; + inline void auxspi_wait_busy() { while (REG_AUXSPICNT & 0x80); @@ -78,8 +80,8 @@ inline uint16 auxspi_read_16() inline void auxspi_disable_infrared_core() { auxspi_open(0); - swiDelay(1000); + swiDelay(ir_delay); auxspi_open(2); auxspi_write(0); - swiDelay(1000); + swiDelay(ir_delay); } diff --git a/arm9/source/display.cpp b/arm9/source/display.cpp index fadc931..1ff1436 100644 --- a/arm9/source/display.cpp +++ b/arm9/source/display.cpp @@ -36,6 +36,8 @@ #include "auxspi_core.cpp" +#include "globals.h" + PrintConsole upperScreen; PrintConsole lowerScreen; @@ -55,7 +57,7 @@ void displayInit() consoleInit(&lowerScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true); consoleSelect(&upperScreen); - iprintf("\n\n\n\n\nDS savegame manager\nVersion 0.2.1 Beta\nBy Pokedoc"); + iprintf("\n\n\n\n\nDS savegame manager\nVersion 0.2.2 Beta\nBy Pokedoc"); displayPrintState("Press (B) to continue"); while (!(keysCurrent() & KEY_B)); @@ -80,7 +82,7 @@ void displayPrintUpper() iprintf("Special :\n"); iprintf("--- SLOT 2 ---------------------"); if (dstype > 0) - iprintf("This device has no Slot-2"); + iprintf("This device has no Slot-2\n"); else { iprintf("Game ID :\n"); iprintf("Game name:\n"); @@ -100,6 +102,24 @@ void displayPrintUpper() sNDSHeader nds; if (!flash_card) cardReadHeader((uint8*)&nds); + // search for the correct header + /* + for (int i = 0; i < 0x1000000; i++) + { + char *test = (char*)0x02000000; + if ((test[0]=='C')&&(test[1]=='P')&&(test[2]=='U')&&(test[3]=='D')) { + iprintf("found!"); + while(1); + } + test++; + } + */ + //nds = NDS_HEADER; + /* + if (nds.gameTitle[0] == 0xff) + // DSi + nds = NDS_HEADER; + */ char name[MAXPATHLEN]; // 0) print the mode @@ -194,8 +214,12 @@ void displayPrintUpper() if (ezflash) { if (ezflash == 0x89168916) sprintf(name, "3in1 (512M)"); + else if (ezflash == 0x227E2218) + sprintf(name, "3in1 (256M V2)"); + else if (ezflash == 0x227E2202) + sprintf(name, "3in1 (256M V1)"); else - sprintf(name, "3in1 (256M)"); + sprintf(name, "3in1 (unknown type)"); } else if (gba) sprintf(name, "%.4s", (char*)0x080000ac); else if (slot2) diff --git a/arm9/source/dsCard.cpp b/arm9/source/dsCard.cpp index 3b120bb..45b620a 100644 --- a/arm9/source/dsCard.cpp +++ b/arm9/source/dsCard.cpp @@ -103,6 +103,7 @@ void SetSerialMode() } uint32 ReadNorFlashID() { + // This function was damaged on the origonal sample, "ID mode" was never left. It is fixed now. vuint16 id1,id2,id3,id4; ID=0; //check intel 512M 3in1 card @@ -134,29 +135,66 @@ uint32 ReadNorFlashID() id1 = *((vuint16 *)(FlashBase+0x2)) ; id2 = *((vuint16 *)(FlashBase+0x2002)) ; - if( (id1!=0x227E)|| (id2!=0x227E)) + if( (id1!=0x227E)|| (id2!=0x227E)) { + *((vuint16 *)(FlashBase+0x555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x2AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x555*2)) = 0xf0 ; + + *((vuint16 *)(FlashBase+0x1555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x12AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x1555*2)) = 0xf0 ; + return 0; + } id1 = *((vuint16 *)(FlashBase+0xE*2)) ; id2 = *((vuint16 *)(FlashBase+0x100e*2)) ; if(id1==0x2218 && id2==0x2218) //H6H6 { + *((vuint16 *)(FlashBase+0x555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x2AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x555*2)) = 0xf0 ; + + *((vuint16 *)(FlashBase+0x1555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x12AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x1555*2)) = 0xf0 ; ID = 0x227E2218; return 0x227E2218; } if(id1==0x2202 && id2==0x2202) //VZ064 { + *((vuint16 *)(FlashBase+0x555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x2AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x555*2)) = 0xf0 ; + + *((vuint16 *)(FlashBase+0x1555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x12AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x1555*2)) = 0xf0 ; ID = 0x227E2202; return 0x227E2202; } if(id1==0x2202 && id2==0x2220) //VZ064 { + *((vuint16 *)(FlashBase+0x555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x2AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x555*2)) = 0xf0 ; + + *((vuint16 *)(FlashBase+0x1555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x12AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x1555*2)) = 0xf0 ; ID = 0x227E2202; return 0x227E2202; } if(id1==0x2202 && id2==0x2215) //VZ064 { + *((vuint16 *)(FlashBase+0x555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x2AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x555*2)) = 0xf0 ; + + *((vuint16 *)(FlashBase+0x1555*2)) = 0xAA ; + *((vuint16 *)(FlashBase+0x12AA*2)) = 0x55 ; + *((vuint16 *)(FlashBase+0x1555*2)) = 0xf0 ; ID = 0x227E2202; return 0x227E2202; } @@ -196,6 +234,12 @@ void Block_EraseIntel(u32 blockAdd) OpenNorWrite(); b512=true; } + else + { + CloseNorWrite(); + SetRompage(0); + OpenNorWrite(); + } if(blockAdd==0) { for(loop=0;loop<0x40000;loop+=0x10000) @@ -397,6 +441,11 @@ void ReadNorFlash(u8* pBuf,u32 address,u16 len) address-=0x2000000; b512=true; } + else + { + CloseNorWrite(); + SetRompage(0); + } Enable_Arm7DS(); OpenNorWrite(); if(ID==0x89168916) @@ -520,6 +569,9 @@ void WriteNorFlash(u32 address,u8 *buffer,u32 size) WriteNorFlashINTEL(address,buffer,size); return; } + CloseNorWrite(); + SetRompage(0); + OpenNorWrite(); vu16 v1,v2; register u32 loopwrite ; vu16* buf = (vu16*)buffer ; diff --git a/arm9/source/dsi.cpp b/arm9/source/dsi.cpp index 0a2826f..f0fe961 100644 --- a/arm9/source/dsi.cpp +++ b/arm9/source/dsi.cpp @@ -23,29 +23,47 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include +#include "display.h" #include "dsi.h" bool isDsi() { +#if 0 // This code attempts to identify an application running in DSi mode. We // make use of the fact that the DSi has 16 MB of memory, while the DS // only has 4 MB. Since the Chinese iQue DS has 8 MB, we will read above // this boundary. u32 test = *(u32*)0x02800000; // this is 8 MB into the main memory + /* u32 test2 = *(u32*)0x02000000; // this is 8 MB into the main memory + char txt[128]; + sprintf(txt, "%x %x", test, test2); + displayMessage(txt); + while(1); + if (test == 0x00000000) return false; if (test == test2) return false; + */ // Try writing to this address. If the value is accepted, we are on a DSi in DSi mode. *(u32*)0x02800000 = 0x12345678; - if (*(u32*)0x02800000 == 0x12345678) + if (*(u32*)0x02800000 == 0x12345678) { + *(u32*)0x02800000 == test; return true; + } // The memory address does not exist, so we are on a DS (or a DSi in DS mode) return false; +#endif +#define SCFG_MODE (*(vu8*)0x4004000) + if(SCFG_MODE) + return (REG_DSIMODE != 0) ? true : false; + + return false; } diff --git a/arm9/source/fileselect.cpp b/arm9/source/fileselect.cpp index 1100644..20e19d6 100644 --- a/arm9/source/fileselect.cpp +++ b/arm9/source/fileselect.cpp @@ -40,14 +40,15 @@ #include "fileselect.h" -extern u8 data[0x8000]; +extern u8 *data; +extern u32 size_buf; // --------------------------------------------------------------------------------- void ftpGetFileList(const char *dir, netbuf *ctrl, uint32 &num) { char *buf = (char*)data; - memset(buf, 0, 0x8000); - FtpDirBuf((char*)data, 0x8000, "/", ctrl); + memset(buf, 0, size_buf); + FtpDirBuf((char*)data, size_buf, "/", ctrl); //FtpDir("/dir.txt", "/", ctrl); char *ptr = buf; // scan pointer char *ptr2 = buf; // write pointer diff --git a/arm9/source/globals.h b/arm9/source/globals.h new file mode 100644 index 0000000..22cbd4d --- /dev/null +++ b/arm9/source/globals.h @@ -0,0 +1,35 @@ +/* + * savegame_manager: a tool to backup and restore savegames from Nintendo + * DS cartridges. Nintendo DS and all derivative names are trademarks + * by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash. + * + * globals.h: global varibles, defines etc. + * + * Copyright (C) Pokedoc (2011) + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GLOBALS_H +#define GLOBALS_H + +// TODO +//#define NDS_HEADER *(sNDSHeader*) 0x023ffe00 + +extern u8 *data; +extern u32 size_buf; + +#endif // GLOBALS_H \ No newline at end of file diff --git a/arm9/source/hardware.cpp b/arm9/source/hardware.cpp index ce27253..c7ef295 100644 --- a/arm9/source/hardware.cpp +++ b/arm9/source/hardware.cpp @@ -38,6 +38,7 @@ #include "dsCard.h" #include "ftplib.h" #include "gba.h" +#include "globals.h" #include "hardware.h" @@ -49,6 +50,8 @@ using namespace std; uint32 boot; +static u32 pitch = 0x40000; + bool flash_card = true; // the homebrew will always start with a FC inserted bool with_infrared = false; // ... which does not have an IR device @@ -57,7 +60,6 @@ extern char ftp_user[64]; extern char ftp_pass[64]; extern int ftp_port; -u8 data[0x8000]; // --------------------------------------------------------------------- bool swap_cart() @@ -114,51 +116,90 @@ bool is_flash_card() return flash_card; } +bool swap_card_game(uint32 size) +{ + return false; +} + // -------------------------------------------------------- void hwFormatNor(uint32 page, uint32 count) { - chip_reset(); - OpenNorWrite(); + uint32 ime = hwGrab3in1(); SetSerialMode(); displayPrintState("Formating NOR memory"); displayProgressBar(0, count); - for (int i = page; i < page+count; i++) { + for (uint32 i = page; i < page+count; i++) { Block_Erase(i << 18); - displayProgressBar(i+1, count); + displayProgressBar(i+1-page, count); } - CloseNorWrite(); + hwRelease3in1(ime); +} + +// -------------------------------------------------------- +void hwBackupDSi() +{ + hwBackupFTP(); +} + +void hwRestoreDSi() +{ + // TODO: test! + char path[256]; + char fname[256] = ""; + fileSelect("sd:/", path, fname, 0, true, false); } // -------------------------------------------------------- void hwBackup3in1() { + swap_cart(); + displayPrintUpper(); + uint8 size = auxspi_save_size_log_2(); int size_blocks = 1 << max(0, (int8(size) - 18)); // ... in units of 0x40000 bytes - that's 256 kB uint8 type = auxspi_save_type(); - // EZFlash Vi needs this line - sysSetBusOwners(true, true); + displayPrintState("Format NOR"); hwFormatNor(0, size_blocks); // Dump save and write it to NOR - chip_reset(); - OpenNorWrite(); - SetSerialMode(); displayPrintState("Writing save to NOR"); + // TODO: test smaller write size! if (size < 15) size_blocks = 1; else size_blocks = 1 << (uint8(size) - 15); + u8 *test = (u8*)malloc(0x8000); + u32 LEN = min(1 << size, 0x8000); + for (int i = 0; i < size_blocks; i++) { displayProgressBar(i+1, size_blocks); - auxspi_read_data(i << 15, data, 0x8000, type); - WriteNorFlash(i << 15, data, 0x8000); + auxspi_read_data(i << 15, data, LEN, type); + // TODO: pull out "setserialmode" + uint32 ime = hwGrab3in1(); + SetSerialMode(); + WriteNorFlash((i << 15) + pitch, data, LEN); + hwRelease3in1(ime); + for (int j = 0; j < 4; j++) { + uint32 ime = hwGrab3in1(); + ReadNorFlash(test, (i << 15) + pitch, LEN); + hwRelease3in1(ime); + } + if (*((vuint16 *)(FlashBase+0x2002)) == 0x227E) { + displayMessage("ERROR: ID mode active!"); + while(1); + } + if (memcmp(test, data, LEN)) { + displayMessage("ERROR: verifying NOR failed"); + while(1); + } } - CloseNorWrite(); + free(test); - // Write a flag to tell the app what happens on restart + // Write a flag to tell the app what happens on restart. + // This is necessary, since some DLDI drivers cease working after swapping a card. sNDSHeader nds; - cardReadHeader((u8*)&nds); + cardReadHeader((u8*)&nds); // on a Cyclops Evolution, this call *will* mess up your DLDI driver! dsCardData data2; memset(&data2, 0, sizeof(data2)); data2.data[0] = RS_BACKUP; @@ -169,7 +210,7 @@ void hwBackup3in1() WriteSram(0x0a000000, (u8*)&data2, sizeof(data2)); char txt[128]; sprintf(txt, "%.12s", &nds.gameTitle[0]); - + displayMessage("Save has been written to 3in1.\nPlease power off and restart\nthis tool."); while(1) {}; @@ -177,8 +218,6 @@ void hwBackup3in1() void hwDump3in1(uint32 size, const char *gamename) { - displayPrintState("Writing file to flash card"); - u32 size_blocks = 1 << max(0, (uint8(size) - 18)); char path[256]; @@ -201,6 +240,7 @@ void hwDump3in1(uint32 size, const char *gamename) sprintf(fullpath, "%s/%s", path, fname); displayMessage(fname); + displayPrintState("Writing save to flash card"); FILE *file = fopen(fullpath, "wb"); if (size < 15) size_blocks = 1; @@ -208,10 +248,10 @@ void hwDump3in1(uint32 size, const char *gamename) size_blocks = 1 << (uint8(size) - 15); for (u32 i = 0; i < size_blocks; i++) { displayProgressBar(i+1, size_blocks); - u32 LEN = 0x8000; - // EZFlash Vi needs this line - sysSetBusOwners(true, true); - ReadNorFlash(data, i << 15, LEN); + u32 LEN = min((u32)0x8000, (u32)1 << size); + uint32 ime = hwGrab3in1(); + ReadNorFlash(data, (i << 15) + pitch, LEN); + hwRelease3in1(ime); fwrite(data, 1, LEN, file); } fclose(file); @@ -239,47 +279,40 @@ void hwRestore3in1() } int size_blocks = 1 << max(0, int8(size) - 18); // ... in units of 0x40000 bytes - that's 256 kB - // EZFlash Vi needs this line - sysSetBusOwners(true, true); - hwFormatNor(0, size_blocks); + hwFormatNor(1, size_blocks); + displayPrintState("Writing save to NOR"); // Read save and write it to NOR - chip_reset(); - OpenNorWrite(); - SetSerialMode(); - displayPrintState("Writing save to NOR"); if (size < 15) size_blocks = 1; else size_blocks = 1 << (uint8(size) - 15); + u8 *test = (u8*)malloc(0x8000); + uint32 LEN = min(1 << size, 0x8000); + for (int i = 0; i < size_blocks; i++) { - displayProgressBar(i+1, size_blocks); - fread(data, 1, 0x8000, file); - // EZFlash Vi needs this line - sysSetBusOwners(true, true); - WriteNorFlash(i << 15, data, 0x8000); + displayProgressBar(i, size_blocks); + fread(data, 1, LEN, file); + uint32 ime = hwGrab3in1(); + SetSerialMode(); + WriteNorFlash((i << 15) + pitch, data, LEN); + ReadNorFlash(test, (i << 15) + pitch, LEN); + hwRelease3in1(ime); + if (*((vuint16 *)(FlashBase+0x2002)) == 0x227E) { + displayMessage("ERROR: ID mode active!"); + while(1); + } + if (int err = memcmp(test, data, LEN)) { + char txt[128]; + sprintf(txt, "ERROR: NOR %x/%x: %x -> %x", abs(err), LEN, data[err], test[err]); + displayMessage(txt); + while(1); + } } - CloseNorWrite(); fclose(file); + free(test); - // FIXME: for some weird reason, reading the save written to NOR right now managed to mangle - // precisely 2 bytes in my HG save, but not in my Platinum one. Therefore, we need to - // make this a two-stage process as well, to prevent this weitd glitch. - // (It appears in two different hardware revisions of the 3in1!) - - // Write a flag to tell the app what happens on restart - sNDSHeader nds; - cardReadHeader((u8*)&nds); - dsCardData data2; - memset(&data2, 0, sizeof(data2)); - data2.data[0] = RS_BACKUP; - data2.data[1] = 0; - data2.data[2] = size; - data2.data[3] = 0xbad00bad; - WriteSram(0x0a000000, (u8*)&data2, sizeof(data2)); - - displayMessage("Thanks to some crazy bug,\nyou will need to restart your\nDS and this app. Sorry."); - while(0); + hwRestore3in1_b(size); } void hwRestore3in1_b(uint32 size_file) @@ -287,9 +320,6 @@ void hwRestore3in1_b(uint32 size_file) // Third, swap in a new game uint32 size = auxspi_save_size_log_2(); while ((size_file < size) || flash_card) { - //char txt[33]; - //sprintf(txt, "%i, %i (%i)", size_file, size, flash_card); - //displayPrintState(txt); displayPrintState("File too small or no save chip!"); swap_cart(); size = auxspi_save_size_log_2(); @@ -321,17 +351,14 @@ void hwRestore3in1_b(uint32 size_file) LEN = 1 << shift; num_blocks = 1 << (size - shift); - chip_reset(); - OpenNorWrite(); for (unsigned int i = 0; i < num_blocks; i++) { if (i % (num_blocks >> 6) == 0) displayProgressBar(i+1, num_blocks); - // EZFlash Vi needs this line - //sysSetBusOwners(true, true); - ReadNorFlash(data, i << shift, LEN); + uint32 ime = hwGrab3in1(); + ReadNorFlash(data, (i << shift) + pitch, LEN); + hwRelease3in1(ime); auxspi_write_data(i << shift, data, LEN, type); } - CloseNorWrite(); displayProgressBar(1, 1); @@ -502,9 +529,6 @@ void hwRestoreFTP() displayMessage("Please select a file name to\nrestore."); displayPrintState("FTP: dir"); fileSelect("/", fdir, fname, buf, true, false); - /*char fn[512]; - displayMessage(fname); - while(1);*/ // Third: swap card swap_cart(); @@ -512,16 +536,12 @@ void hwRestoreFTP() uint8 size = auxspi_save_size_log_2(); int size_blocks = 1 << (size - 9); // ... in units of 512 bytes uint8 type = auxspi_save_type(); - if (type == 3) { - displayPrintState("Formating Flash chip"); - auxspi_erase(); - } + // Fourth: read file displayPrintState(""); FtpChdir(fdir, buf); sprintf(fullname, "Reading file:\n%s%s", fdir, fname); displayMessage(fullname); - FtpAccess(fname, FTPLIB_FILE_READ, FTPLIB_IMAGE, buf, &ndata); u32 LEN = 0, num_blocks = 0, shift = 0; switch (type) { case 1: @@ -539,16 +559,55 @@ void hwRestoreFTP() LEN = 1 << shift; int num_blocks_ftp = 1 << (size - 9); num_blocks = 1 << (size - shift); + + // if our save is small enough to fit in memory, use secure mode (i.e. read full file before erasing anything + bool insecure = ((1 << size) > size_buf); + if (insecure) { +#if 0 + displayMessage("Save larger than available RAM.\nRestoring will be dangerous!\n\nPress Start + Select to proceed"); + while (!(keysCurrent() & (KEY_START | KEY_SELECT))); +#else + displayMessage("Save larger than available RAM.\nRestoring is buggy, so\nI will stop here.\n(Try Rudolphs tools.)"); + while (1); +#endif + } + if ((type == 3) && (insecure)) { + displayPrintState("Formating Flash chip"); + auxspi_erase(); + } + FtpAccess(fname, FTPLIB_FILE_READ, FTPLIB_IMAGE, buf, &ndata); + u8 *pdata = data; for (int i = 0; i < num_blocks_ftp; i++) { displayProgressBar(i+1, num_blocks_ftp); int out; - if ((out = FtpRead((u8*)data, 512, ndata)) < 512) { + if ((out = FtpRead((u8*)pdata, 512, ndata)) < 512) { char dings[512]; sprintf(dings, "Error: requested 512, got %i", out); + displayPrintState(dings); while(1); } - for (int j = 0; j < 1 << (9-shift); j++) { - auxspi_write_data((i << 9)+(j << shift), ((u8*)data)+(j< +#include + #include "gba.h" #include "dsi.h" #include "display.h" @@ -45,6 +47,10 @@ #include "libini.h" +u8 *data; +u32 size_buf; + +using std::max; uint32 ezflash = 0; @@ -57,6 +63,7 @@ char ftp_ip[16] = "ftp_ip"; char ftp_user[64] = "ftp_user"; char ftp_pass[64] = "ftp_pass"; int ftp_port = 0; +int ir_delay = 1000; char bootdir[256] = "/"; @@ -64,6 +71,36 @@ char bootdir[256] = "/"; // ============================================================================ void mode_dsi() { + // TODO: test is SD card is present! + + // use 3in1 to buffer data + displayPrintState(""); + displayPrintUpper(); + displayPrintLower(); + + touchPosition touchXY; + while(1) { + swiWaitForVBlank(); + touchRead(&touchXY); + + // backup + if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) { + hwBackupDSi(); + } + + // restore + if ((touchXY.py > 8*8) && (touchXY.py < 8*16)) { + hwRestoreDSi(); + } + + // erase + if ((touchXY.py > 8*16) && (touchXY.py < 8*24)) { + swap_cart(); + displayPrintUpper(); + hwErase(); + } + } + // DSi mode, does nothing at the moment displayPrintState("DSi mode - still unsupported!"); while (1); @@ -136,8 +173,6 @@ void mode_3in1() // backup if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) { - swap_cart(); - displayPrintUpper(); hwBackup3in1(); } @@ -192,8 +227,6 @@ void mode_gba() void mode_wifi() { - displayPrintUpper(); - // use 3in1 to buffer data displayPrintState(""); displayPrintUpper(); @@ -268,39 +301,44 @@ int main(int argc, char* argv[]) ini_readString(ini, ftp_pass, 64); ini_locateKey(ini, "ftp_port"); ini_readInt(ini, &ftp_port); + ini_locateKey(ini, "ir_delay"); + ini_readInt(ini, &ir_delay); + ir_delay = max(ir_delay, 1000); ini_close(ini); - //displayPrintState(ftp_user); - //while (1); // Identify hardware and branch to corresponding mode displayPrintState("Identifying hardware..."); - // EZFlash Vi needs this line - sysSetBusOwners(true, true); - OpenNorWrite(); - ezflash = ReadNorFlashID(); - CloseNorWrite(); - // First attempt to identify the DSi. Read address > 8 MB - dstype = isDsi() ? 1 : 0; // DS/DSL, no idea how to identify DSi etc. - gba = gbaIsGame(); + + // Identify DSi (i.e. memory capacity) + if (isDsi()) { + dstype = 1; + size_buf = 1 << 23; // 8 MB + } else { + dstype = 0; + size_buf = 1 << 21; // 2 MB + //size_buf = 1 << 14; // 32 kB - TESTING ONLY! + } + data = (u8*)malloc(size_buf); + + // don't try to identify Slot-2 in DSi mode. + if (dstype == 0) { + uint32 ime = enterCriticalSection(); + sysSetBusOwners(true, true); + OpenNorWrite(); + ezflash = ReadNorFlashID(); + CloseNorWrite(); + leaveCriticalSection(ime); + chip_reset(); + + gba = gbaIsGame(); + } // Try to identify slot-2 device. Try opening slot-2 root directory - // Nope, does not work: CyclopsDS mounts itself on fat1, fat2, fat3,... (didn't test more) - /* - DIR* pdir = opendir("fat2:/"); - struct dirent *pent; - if (pdir) { - pent=readdir(pdir); - if (pent) - //char fullname[256]; - displayMessage(pent->d_name); - //slot2=true; - } - */ if (argv[0][3] == '2') slot2 = true; if (dstype == 1) { - // DSi/DSiXL, will branch to SD-card mode when cracked. + // DSi/DSiXL, branch to SD-card mode when cracked. mode = 3; mode_dsi(); } else if (slot2) { diff --git a/savegame_manager.pnproj b/savegame_manager.pnproj index 34f5d22..7dba031 100644 --- a/savegame_manager.pnproj +++ b/savegame_manager.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file