Source code for the 0.2.2 release (2-12-2011).

This commit is contained in:
msiewert76@gmail.com 2011-04-25 20:09:15 +00:00
parent 97bdcc76ad
commit fb9eb21cf4
12 changed files with 366 additions and 113 deletions

View File

@ -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

View File

@ -32,7 +32,8 @@
using std::max;
extern u8 data[0x8000];
extern u8 *data;
extern u32 size_buf;
// ========================================================

View File

@ -26,6 +26,8 @@
#include <nds.h>
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);
}

View File

@ -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)

View File

@ -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 ;

View File

@ -23,29 +23,47 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <nds.h>
#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;
}

View File

@ -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

View File

@ -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

View File

@ -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<<shift), LEN, type);
// does not fit into memory: insecure mode
if (insecure) {
//char bums[512];
//sprintf(bums, "addr = %x", (i << 9)+(j << shift));
displayPrintState("Writing save (insecure!)");
//displayPrintState(bums);
for (int j = 0; j < 1 << (9-shift); j++) {
auxspi_write_data((i << 9)+(j << shift), ((u8*)pdata)+(j<<shift), LEN, type);
}
}
pdata += 512;
}
if (!insecure) {
displayMessage("Got file, now writing to game");
if (type == 3) {
displayPrintState("Formating Flash chip");
auxspi_erase();
}
for (int i = 0; i < (1 << (size - shift)); i++) {
displayPrintState("Writing save");
displayProgressBar(i+1, 1 << (size - shift));
auxspi_write_data(i << shift, ((u8*)data)+(i<<shift), LEN, type);
}
}
FtpClose(ndata);
@ -664,3 +723,19 @@ void hwEraseGBA()
{
// TODO: implement chip erase!
}
// -------------------------------------------------
uint32 hwGrab3in1()
{
uint32 ime = enterCriticalSection();
sysSetBusOwners(true, true);
chip_reset();
OpenNorWrite();
return ime;
}
void hwRelease3in1(uint32 ime)
{
CloseNorWrite();
leaveCriticalSection(ime);
}

View File

@ -54,6 +54,9 @@ void hwRestore3in1();
void hwRestore3in1_b(uint32 size_file);
void hwErase();
void hwBackupDSi();
void hwRestoreDSi();
void hwBackupFTP();
void hwRestoreFTP();
@ -63,4 +66,7 @@ void hwEraseGBA();
void hwFormatNor(uint32 page, uint32 count);
uint32 hwGrab3in1();
void hwRelease3in1(uint32 ime);
#endif

View File

@ -36,6 +36,8 @@
#include <dirent.h>
#include <algorithm>
#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) {

View File

@ -1 +1 @@
<Project name="Savegame Manager"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="arm9" path="arm9\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="build" path="build\"><File path=".map"></File><File path="auxspi.d"></File><File path="auxspi.o"></File><File path="auxspi_core.d"></File><File path="auxspi_core.o"></File><File path="display.d"></File><File path="display.o"></File><File path="dsCard.d"></File><File path="dsCard.o"></File><File path="dsi.d"></File><File path="dsi.o"></File><File path="fileselect.d"></File><File path="fileselect.o"></File><File path="ftplib.d"></File><File path="ftplib.o"></File><File path="gba.d"></File><File path="gba.o"></File><File path="hardware.d"></File><File path="hardware.o"></File><File path="ini.d"></File><File path="ini.o"></File><File path="main.d"></File><File path="main.o"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="auxspi.cpp"></File><File path="auxspi.h"></File><File path="auxspi_core.cpp"></File><File path="display.cpp"></File><File path="display.h"></File><File path="dsCard.cpp"></File><File path="dsCard.h"></File><File path="dsi.cpp"></File><File path="dsi.h"></File><File path="fileselect.cpp"></File><File path="fileselect.h"></File><File path="ftplib.c"></File><File path="ftplib.h"></File><File path="gba.cpp"></File><File path="gba.h"></File><File path="hardware.cpp"></File><File path="hardware.h"></File><File path="headings.i"></File><File path="ini.cpp"></File><File path="ini.h"></File><File path="iniconfig.h"></File><File path="iniheadings.h"></File><File path="inikeys.h"></File><File path="inilist.h"></File><File path="keys.i"></File><File path="libini.h"></File><File path="list.i"></File><File path="main.cpp"></File><File path="types.i"></File></MagicFolder><File path="Makefile"></File><File path="savegame_manager.arm9.elf"></File></MagicFolder><File path="Makefile"></File></Project>
<Project name="Savegame Manager"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="arm9" path="arm9\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="build" path="build\"><File path=".map"></File><File path="auxspi.d"></File><File path="auxspi.o"></File><File path="auxspi_core.d"></File><File path="auxspi_core.o"></File><File path="display.d"></File><File path="display.o"></File><File path="dsCard.d"></File><File path="dsCard.o"></File><File path="dsi.d"></File><File path="dsi.o"></File><File path="fileselect.d"></File><File path="fileselect.o"></File><File path="ftplib.d"></File><File path="ftplib.o"></File><File path="gba.d"></File><File path="gba.o"></File><File path="hardware.d"></File><File path="hardware.o"></File><File path="ini.d"></File><File path="ini.o"></File><File path="main.d"></File><File path="main.o"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="auxspi.cpp"></File><File path="auxspi.h"></File><File path="auxspi_core.cpp"></File><File path="display.cpp"></File><File path="display.h"></File><File path="dsCard.cpp"></File><File path="dsCard.h"></File><File path="dsi.cpp"></File><File path="dsi.h"></File><File path="fileselect.cpp"></File><File path="fileselect.h"></File><File path="ftplib.c"></File><File path="ftplib.h"></File><File path="gba.cpp"></File><File path="gba.h"></File><File path="globals.h"></File><File path="hardware.cpp"></File><File path="hardware.h"></File><File path="headings.i"></File><File path="ini.cpp"></File><File path="ini.h"></File><File path="iniconfig.h"></File><File path="iniheadings.h"></File><File path="inikeys.h"></File><File path="inilist.h"></File><File path="keys.i"></File><File path="libini.h"></File><File path="list.i"></File><File path="main.cpp"></File><File path="types.i"></File></MagicFolder><File path="Makefile"></File><File path="savegame_manager.arm9.elf"></File></MagicFolder><File path="Makefile"></File></Project>