mirror of
https://github.com/suloku/savegame-manager.git
synced 2026-09-13 13:36:48 -05:00
- fix detection of infrared-enabled devices
- add (preliminary) support for unknown hardware IDs - fix broken file selector on some flash cards (was an malloc issue) - add support for 2MB saves (I do not know if this save type exists, but I vaguely remember seeing it somewhere) - fix for situations where the game is not recognized e.g. due to bad contacts - Band Brothers DX/Jam With the Band is now officially NOT supported (yet another unknown piece of hardware) - Personal Trainer: Walking/Walk with me is now officially supported (1 MB Flash (wow) + infrared device) - update readme file
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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).");
|
||||
//
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user