Libretro: Remove workaround for save file handling

For the most part, save types should now be identified during rom loading and then allow libretro to correctly use flash or eeprom save types and save size.
This commit is contained in:
retro-wertz 2018-06-26 21:40:59 +08:00 committed by Rafael Kitover
parent c1f281b7ba
commit daf50fcdbe
6 changed files with 155 additions and 190 deletions

View File

@ -11,13 +11,7 @@ int eepromByte = 0;
int eepromBits = 0; int eepromBits = 0;
int eepromAddress = 0; int eepromAddress = 0;
#ifdef __LIBRETRO__
// Workaround for broken-by-design GBA save semantics
extern uint8_t libretro_save_buf[0x20000 + 0x2000];
uint8_t* eepromData = libretro_save_buf + 0x20000;
#else
uint8_t eepromData[0x2000]; uint8_t eepromData[0x2000];
#endif
uint8_t eepromBuffer[16]; uint8_t eepromBuffer[16];
bool eepromInUse = false; bool eepromInUse = false;
@ -36,11 +30,7 @@ variable_desc eepromSaveData[] = {
void eepromInit() void eepromInit()
{ {
#ifdef __LIBRETRO__
memset(eepromData, 255, 0x2000);
#else
memset(eepromData, 255, sizeof(eepromData)); memset(eepromData, 255, sizeof(eepromData));
#endif
} }
void eepromReset() void eepromReset()
@ -122,10 +112,9 @@ int eepromRead(uint32_t /* address */)
return 0; return 0;
} }
case EEPROM_READDATA2: { case EEPROM_READDATA2: {
int data = 0;
int address = eepromAddress << 3; int address = eepromAddress << 3;
int mask = 1 << (7 - (eepromBits & 7)); int mask = 1 << (7 - (eepromBits & 7));
data = (eepromData[address + eepromByte] & mask) ? 1 : 0; int data = (eepromData[address + eepromByte] & mask) ? 1 : 0;
eepromBits++; eepromBits++;
if ((eepromBits & 7) == 0) if ((eepromBits & 7) == 0)
eepromByte++; eepromByte++;

View File

@ -6,13 +6,12 @@
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern void eepromSaveGame(uint8_t*& data); extern void eepromSaveGame(uint8_t*& data);
extern void eepromReadGame(const uint8_t*& data, int version); extern void eepromReadGame(const uint8_t*& data, int version);
extern uint8_t* eepromData;
#else // !__LIBRETRO__ #else // !__LIBRETRO__
extern void eepromSaveGame(gzFile _gzFile); extern void eepromSaveGame(gzFile _gzFile);
extern void eepromReadGame(gzFile _gzFile, int version); extern void eepromReadGame(gzFile _gzFile, int version);
extern void eepromReadGameSkip(gzFile _gzFile, int version); extern void eepromReadGameSkip(gzFile _gzFile, int version);
extern uint8_t eepromData[0x2000];
#endif #endif
extern uint8_t eepromData[0x2000];
extern int eepromRead(uint32_t address); extern int eepromRead(uint32_t address);
extern void eepromWrite(uint32_t address, uint8_t value); extern void eepromWrite(uint32_t address, uint8_t value);
extern void eepromInit(); extern void eepromInit();

View File

@ -18,12 +18,7 @@
#define FLASH_PROGRAM 8 #define FLASH_PROGRAM 8
#define FLASH_SETBANK 9 #define FLASH_SETBANK 9
#ifdef __LIBRETRO__
extern uint8_t libretro_save_buf[0x20000 + 0x2000];
uint8_t* flashSaveMemory = libretro_save_buf;
#else
uint8_t flashSaveMemory[FLASH_128K_SZ]; uint8_t flashSaveMemory[FLASH_128K_SZ];
#endif
int flashState = FLASH_READ_ARRAY; int flashState = FLASH_READ_ARRAY;
int flashReadState = FLASH_READ_ARRAY; int flashReadState = FLASH_READ_ARRAY;
@ -58,11 +53,7 @@ static variable_desc flashSaveData3[] = {
void flashInit() void flashInit()
{ {
#ifdef __LIBRETRO__
memset(flashSaveMemory, 0xff, 0x20000);
#else
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory)); memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
#endif
} }
void flashReset() void flashReset()

View File

@ -8,13 +8,12 @@
#ifdef __LIBRETRO__ #ifdef __LIBRETRO__
extern void flashSaveGame(uint8_t*& data); extern void flashSaveGame(uint8_t*& data);
extern void flashReadGame(const uint8_t*& data, int); extern void flashReadGame(const uint8_t*& data, int);
extern uint8_t* flashSaveMemory;
#else #else
extern void flashSaveGame(gzFile _gzFile); extern void flashSaveGame(gzFile _gzFile);
extern void flashReadGame(gzFile _gzFile, int version); extern void flashReadGame(gzFile _gzFile, int version);
extern void flashReadGameSkip(gzFile _gzFile, int version); extern void flashReadGameSkip(gzFile _gzFile, int version);
extern uint8_t flashSaveMemory[FLASH_128K_SZ];
#endif #endif
extern uint8_t flashSaveMemory[FLASH_128K_SZ];
extern uint8_t flashRead(uint32_t address); extern uint8_t flashRead(uint32_t address);
extern void flashWrite(uint32_t address, uint8_t byte); extern void flashWrite(uint32_t address, uint8_t byte);
extern void flashDelayedWrite(uint32_t address, uint8_t byte); extern void flashDelayedWrite(uint32_t address, uint8_t byte);

View File

@ -186,7 +186,7 @@ void utilGBAFindSave(const int size)
{ {
bool rtcFound_ = false; bool rtcFound_ = false;
int detectedSaveType = 0; int detectedSaveType = 0;
int flashSize_ = 0x8000; int flashSize_ = 0x10000;
uint32_t *p = (uint32_t *)&rom[0]; uint32_t *p = (uint32_t *)&rom[0];
uint32_t *end = (uint32_t *)(&rom[0] + size); uint32_t *end = (uint32_t *)(&rom[0] + size);
@ -204,6 +204,7 @@ void utilGBAFindSave(const int size)
if (detectedSaveType == 0 || detectedSaveType == 1 if (detectedSaveType == 0 || detectedSaveType == 1
|| detectedSaveType == 4) { || detectedSaveType == 4) {
detectedSaveType = 2; detectedSaveType = 2;
flashSize_ = 0x8000;
} }
} }
} else if (d == 0x53414C46) { } else if (d == 0x53414C46) {

View File

@ -47,9 +47,6 @@ static bool can_dupe = false;
int emulating = 0; int emulating = 0;
static int retropad_layout = 0; static int retropad_layout = 0;
uint8_t libretro_save_buf[0x20000 + 0x2000]; /* Workaround for broken-by-design GBA save semantics. */
static unsigned libretro_save_size = sizeof(libretro_save_buf);
static char biosfile[1024] = {0}; static char biosfile[1024] = {0};
static bool usebios = false; static bool usebios = false;
@ -74,7 +71,12 @@ void (*dbgSignal)(int sig, int number);
void* retro_get_memory_data(unsigned id) void* retro_get_memory_data(unsigned id)
{ {
if (id == RETRO_MEMORY_SAVE_RAM) if (id == RETRO_MEMORY_SAVE_RAM)
return libretro_save_buf; {
if ((saveType == 1) | (saveType == 4))
return eepromData;
if ((saveType == 2) | (saveType == 3))
return flashSaveMemory;
}
if (id == RETRO_MEMORY_SYSTEM_RAM) if (id == RETRO_MEMORY_SYSTEM_RAM)
return workRAM; return workRAM;
if (id == RETRO_MEMORY_VIDEO_RAM) if (id == RETRO_MEMORY_VIDEO_RAM)
@ -86,7 +88,12 @@ void* retro_get_memory_data(unsigned id)
size_t retro_get_memory_size(unsigned id) size_t retro_get_memory_size(unsigned id)
{ {
if (id == RETRO_MEMORY_SAVE_RAM) if (id == RETRO_MEMORY_SAVE_RAM)
return libretro_save_size; {
if ((saveType == 1) | (saveType == 4))
return eepromSize;
if ((saveType == 2) | (saveType == 3))
return flashSize;
}
if (id == RETRO_MEMORY_SYSTEM_RAM) if (id == RETRO_MEMORY_SYSTEM_RAM)
return 0x40000; return 0x40000;
if (id == RETRO_MEMORY_VIDEO_RAM) if (id == RETRO_MEMORY_VIDEO_RAM)
@ -95,44 +102,6 @@ size_t retro_get_memory_size(unsigned id)
return 0; return 0;
} }
static bool scan_area(const uint8_t* data, unsigned size)
{
for (unsigned i = 0; i < size; i++)
if (data[i] != 0xff)
return true;
return false;
}
static void adjust_save_ram()
{
if (scan_area(libretro_save_buf, 512) && !scan_area(libretro_save_buf + 512, sizeof(libretro_save_buf) - 512)) {
libretro_save_size = 512;
if (log_cb)
log_cb(RETRO_LOG_INFO, "Detecting EEprom 8kbit\n");
} else if (scan_area(libretro_save_buf, 0x2000) && !scan_area(libretro_save_buf + 0x2000, sizeof(libretro_save_buf) - 0x2000)) {
libretro_save_size = 0x2000;
if (log_cb)
log_cb(RETRO_LOG_INFO, "Detecting EEprom 64kbit\n");
}
else if (scan_area(libretro_save_buf, 0x10000) && !scan_area(libretro_save_buf + 0x10000, sizeof(libretro_save_buf) - 0x10000)) {
libretro_save_size = 0x10000;
if (log_cb)
log_cb(RETRO_LOG_INFO, "Detecting Flash 512kbit\n");
} else if (scan_area(libretro_save_buf, 0x20000) && !scan_area(libretro_save_buf + 0x20000, sizeof(libretro_save_buf) - 0x20000)) {
libretro_save_size = 0x20000;
if (log_cb)
log_cb(RETRO_LOG_INFO, "Detecting Flash 1Mbit\n");
} else if (log_cb)
log_cb(RETRO_LOG_INFO, "Did not detect any particular SRAM type.\n");
if (libretro_save_size == 512 || libretro_save_size == 0x2000)
eepromData = libretro_save_buf;
else if (libretro_save_size == 0x10000 || libretro_save_size == 0x20000)
flashSaveMemory = libretro_save_buf;
}
unsigned retro_api_version(void) unsigned retro_api_version(void)
{ {
return RETRO_API_VERSION; return RETRO_API_VERSION;
@ -262,8 +231,6 @@ void retro_init(void)
#endif #endif
struct retro_log_callback log; struct retro_log_callback log;
memset(libretro_save_buf, 0xff, sizeof(libretro_save_buf));
adjust_save_ram();
environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &can_dupe); environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &can_dupe);
if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
log_cb = log.log; log_cb = log.log;
@ -290,121 +257,124 @@ static unsigned serialize_size = 0;
typedef struct { typedef struct {
char romtitle[256]; char romtitle[256];
char romid[5]; char romid[5];
int flashSize; int flashSize; // also can override eeprom size
int saveType; int saveType; // 0auto 1eeprom 2sram 3flash 4sensor+eeprom 5none
int rtcEnabled; int rtcEnabled;
int mirroringEnabled; int mirroringEnabled;
int useBios; int useBios;
} ini_t; } ini_t;
static const ini_t gbaover[256] = { static const ini_t gbaover[256] = {
//romtitle, romid flash save rtc mirror bios // TODO:
{"2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA)", "BLFE", 0, 1, 0, 0, 0}, // - Update existing overrides
{"2 Games in 1 - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA)", "BUFE", 0, 1, 0, 0, 0}, // - Add overrides for eeprom 8192 size
{"Boktai - The Sun Is in Your Hand (Europe)(En,Fr,De,Es,It)", "U3IP", 0, 0, 1, 0, 0}, //romtitle, romid flash save rtc mirror bios
{"Boktai - The Sun Is in Your Hand (USA)", "U3IE", 0, 0, 1, 0, 0}, {"2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA)", "BLFE", 8192, 1, 0, 0, 0},
{"Boktai 2 - Solar Boy Django (USA)", "U32E", 0, 0, 1, 0, 0}, {"2 Games in 1 - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA)", "BUFE", 8192, 1, 0, 0, 0},
{"Boktai 2 - Solar Boy Django (Europe)(En,Fr,De,Es,It)", "U32P", 0, 0, 1, 0, 0}, {"Boktai - The Sun Is in Your Hand (Europe)(En,Fr,De,Es,It)", "U3IP", 8192, 1, 1, 0, 0},
{"Bokura no Taiyou - Taiyou Action RPG (Japan)", "U3IJ", 0, 0, 1, 0, 0}, {"Boktai - The Sun Is in Your Hand (USA)", "U3IE", 8192, 1, 1, 0, 0},
{"Card e-Reader+ (Japan)", "PSAJ", 131072, 0, 0, 0, 0}, {"Boktai 2 - Solar Boy Django (USA)", "U32E", 8192, 1, 1, 0, 0},
{"Classic NES Series - Bomberman (USA, Europe)", "FBME", 0, 1, 0, 1, 0}, {"Boktai 2 - Solar Boy Django (Europe)(En,Fr,De,Es,It)", "U32P", 8192, 1, 1, 0, 0},
{"Classic NES Series - Castlevania (USA, Europe)", "FADE", 0, 1, 0, 1, 0}, {"Bokura no Taiyou - Taiyou Action RPG (Japan)", "U3IJ", 0, 1, 1, 0, 0},
{"Classic NES Series - Donkey Kong (USA, Europe)", "FDKE", 0, 1, 0, 1, 0}, {"Card e-Reader+ (Japan)", "PSAJ", 131072, 0, 0, 0, 0},
{"Classic NES Series - Dr. Mario (USA, Europe)", "FDME", 0, 1, 0, 1, 0}, {"Classic NES Series - Bomberman (USA, Europe)", "FBME", 0, 1, 0, 1, 0},
{"Classic NES Series - Excitebike (USA, Europe)", "FEBE", 0, 1, 0, 1, 0}, {"Classic NES Series - Castlevania (USA, Europe)", "FADE", 0, 1, 0, 1, 0},
{"Classic NES Series - Legend of Zelda (USA, Europe)", "FZLE", 0, 1, 0, 1, 0}, {"Classic NES Series - Donkey Kong (USA, Europe)", "FDKE", 0, 1, 0, 1, 0},
{"Classic NES Series - Ice Climber (USA, Europe)", "FICE", 0, 1, 0, 1, 0}, {"Classic NES Series - Dr. Mario (USA, Europe)", "FDME", 0, 1, 0, 1, 0},
{"Classic NES Series - Metroid (USA, Europe)", "FMRE", 0, 1, 0, 1, 0}, {"Classic NES Series - Excitebike (USA, Europe)", "FEBE", 8192, 1, 0, 1, 0},
{"Classic NES Series - Pac-Man (USA, Europe)", "FP7E", 0, 1, 0, 1, 0}, //{"Classic NES Series - Legend of Zelda (USA, Europe)", "FZLE", 8192, 1, 0, 1, 0},
{"Classic NES Series - Super Mario Bros. (USA, Europe)", "FSME", 0, 1, 0, 1, 0}, {"Classic NES Series - Ice Climber (USA, Europe)", "FICE", 0, 1, 0, 1, 0},
{"Classic NES Series - Xevious (USA, Europe)", "FXVE", 0, 1, 0, 1, 0}, {"Classic NES Series - Metroid (USA, Europe)", "FMRE", 0, 1, 0, 1, 0},
{"Classic NES Series - Zelda II - The Adventure of Link (USA, Europe)", "FLBE", 0, 1, 0, 1, 0}, {"Classic NES Series - Pac-Man (USA, Europe)", "FP7E", 0, 1, 0, 1, 0},
{"Digi Communication 2 - Datou! Black Gemagema Dan (Japan)", "BDKJ", 0, 1, 0, 0, 0}, {"Classic NES Series - Super Mario Bros. (USA, Europe)", "FSME", 0, 1, 0, 1, 0},
{"e-Reader (USA)", "PSAE", 131072, 0, 0, 0, 0}, {"Classic NES Series - Xevious (USA, Europe)", "FXVE", 0, 1, 0, 1, 0},
{"Dragon Ball GT - Transformation (USA)", "BT4E", 0, 1, 0, 0, 0}, {"Classic NES Series - Zelda II - The Adventure of Link (USA, Europe)", "FLBE", 8192, 1, 0, 1, 0},
{"Dragon Ball Z - Buu's Fury (USA)", "BG3E", 0, 1, 0, 0, 0}, {"Digi Communication 2 - Datou! Black Gemagema Dan (Japan)", "BDKJ", 8192, 1, 0, 0, 0},
{"Dragon Ball Z - Taiketsu (Europe)(En,Fr,De,Es,It)", "BDBP", 0, 1, 0, 0, 0}, {"e-Reader (USA)", "PSAE", 131072, 0, 0, 0, 0},
{"Dragon Ball Z - Taiketsu (USA)", "BDBE", 0, 1, 0, 0, 0}, {"Dragon Ball GT - Transformation (USA)", "BT4E", 8192, 1, 0, 0, 0},
{"Dragon Ball Z - The Legacy of Goku II International (Japan)", "ALFJ", 0, 1, 0, 0, 0}, {"Dragon Ball Z - Buu's Fury (USA)", "BG3E", 8192, 1, 0, 0, 0},
{"Dragon Ball Z - The Legacy of Goku II (Europe)(En,Fr,De,Es,It)", "ALFP", 0, 1, 0, 0, 0}, {"Dragon Ball Z - Taiketsu (Europe)(En,Fr,De,Es,It)", "BDBP", 0, 1, 0, 0, 0},
{"Dragon Ball Z - The Legacy of Goku II (USA)", "ALFE", 0, 1, 0, 0, 0}, {"Dragon Ball Z - Taiketsu (USA)", "BDBE", 0, 1, 0, 0, 0},
{"Dragon Ball Z - The Legacy Of Goku (Europe)(En,Fr,De,Es,It)", "ALGP", 0, 1, 0, 0, 0}, {"Dragon Ball Z - The Legacy of Goku II International (Japan)", "ALFJ", 8192, 1, 0, 0, 0},
{"Dragon Ball Z - The Legacy of Goku (USA)", "ALGE", 131072, 1, 0, 0, 0}, {"Dragon Ball Z - The Legacy of Goku II (Europe)(En,Fr,De,Es,It)", "ALFP", 8192, 1, 0, 0, 0},
{"F-Zero - Climax (Japan)", "BFTJ", 131072, 0, 0, 0, 0}, {"Dragon Ball Z - The Legacy of Goku II (USA)", "ALFE", 8192, 1, 0, 0, 0},
{"Famicom Mini Vol. 01 - Super Mario Bros. (Japan)", "FMBJ", 0, 1, 0, 1, 0}, {"Dragon Ball Z - The Legacy Of Goku (Europe)(En,Fr,De,Es,It)", "ALGP", 0, 1, 0, 0, 0},
{"Famicom Mini Vol. 12 - Clu Clu Land (Japan)", "FCLJ", 0, 1, 0, 1, 0}, {"Dragon Ball Z - The Legacy of Goku (USA)", "ALGE", 131072, 1, 0, 0, 0},
{"Famicom Mini Vol. 13 - Balloon Fight (Japan)", "FBFJ", 0, 1, 0, 1, 0}, {"F-Zero - Climax (Japan)", "BFTJ", 131072, 3, 0, 0, 0},
{"Famicom Mini Vol. 14 - Wrecking Crew (Japan)", "FWCJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 01 - Super Mario Bros. (Japan)", "FMBJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 15 - Dr. Mario (Japan)", "FDMJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 12 - Clu Clu Land (Japan)", "FCLJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 16 - Dig Dug (Japan)", "FTBJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 13 - Balloon Fight (Japan)", "FBFJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 17 - Takahashi Meijin no Boukenjima (Japan)", "FTBJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 14 - Wrecking Crew (Japan)", "FWCJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 18 - Makaimura (Japan)", "FMKJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 15 - Dr. Mario (Japan)", "FDMJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 19 - Twin Bee (Japan)", "FTWJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 16 - Dig Dug (Japan)", "FDDJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 20 - Ganbare Goemon! Karakuri Douchuu (Japan)", "FGGJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 17 - Takahashi Meijin no Boukenjima (Japan)", "FTBJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 21 - Super Mario Bros. 2 (Japan)", "FM2J", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 18 - Makaimura (Japan)", "FMKJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 22 - Nazo no Murasame Jou (Japan)", "FNMJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 19 - Twin Bee (Japan)", "FTWJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 23 - Metroid (Japan)", "FMRJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 20 - Ganbare Goemon! Karakuri Douchuu (Japan)", "FGGJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 24 - Hikari Shinwa - Palthena no Kagami (Japan)", "FPTJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 21 - Super Mario Bros. 2 (Japan)", "FM2J", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 25 - The Legend of Zelda 2 - Link no Bouken (Japan)","FLBJ",0, 1, 0, 1, 0}, {"Famicom Mini Vol. 22 - Nazo no Murasame Jou (Japan)", "FNMJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 26 - Famicom Mukashi Banashi - Shin Onigashima - Zen Kou Hen (Japan)","FFMJ",0,1,0, 1, 0}, {"Famicom Mini Vol. 23 - Metroid (Japan)", "FMRJ", 8192, 1, 0, 1, 0},
{"Famicom Mini Vol. 27 - Famicom Tantei Club - Kieta Koukeisha - Zen Kou Hen (Japan)","FTKJ",0,1,0, 1, 0}, {"Famicom Mini Vol. 24 - Hikari Shinwa - Palthena no Kagami (Japan)", "FPTJ", 8192, 1, 0, 1, 0},
{"Famicom Mini Vol. 28 - Famicom Tantei Club Part II - Ushiro ni Tatsu Shoujo - Zen Kou Hen (Japan)","FTUJ",0,1,0,1,0}, {"Famicom Mini Vol. 25 - The Legend of Zelda 2 - Link no Bouken (Japan)","FLBJ",8192, 1, 0, 1, 0},
{"Famicom Mini Vol. 29 - Akumajou Dracula (Japan)", "FADJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 26 - Famicom Mukashi Banashi - Shin Onigashima - Zen Kou Hen (Japan)","FFMJ",0,1,0, 1, 0},
{"Famicom Mini Vol. 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan)","FSDJ",0,1, 0, 1, 0}, {"Famicom Mini Vol. 27 - Famicom Tantei Club - Kieta Koukeisha - Zen Kou Hen (Japan)","FTKJ",0,1,0, 1, 0},
{"Game Boy Wars Advance 1+2 (Japan)", "BGWJ", 131072, 0, 0, 0, 0}, {"Famicom Mini Vol. 28 - Famicom Tantei Club Part II - Ushiro ni Tatsu Shoujo - Zen Kou Hen (Japan)","FTUJ",0,1,0,1,0},
{"Golden Sun - The Lost Age (USA)", "AGFE", 65536, 0, 0, 1, 0}, {"Famicom Mini Vol. 29 - Akumajou Dracula (Japan)", "FADJ", 0, 1, 0, 1, 0},
{"Golden Sun (USA)", "AGSE", 65536, 0, 0, 1, 0}, {"Famicom Mini Vol. 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan)","FSDJ",8192,1, 0, 1, 0},
{"Iridion II (Europe) (En,Fr,De)", "AI2P", 0, 5, 0, 0, 0}, {"Game Boy Wars Advance 1+2 (Japan)", "BGWJ", 131072, 3, 0, 0, 0},
{"Iridion II (USA)", "AI2E", 0, 5, 0, 0, 0}, {"Golden Sun - The Lost Age (USA)", "AGFE", 65536, 3, 0, 0, 0},
{"Koro Koro Puzzle - Happy Panechu! (Japan)", "KHPJ", 0, 4, 0, 0, 0}, {"Golden Sun (USA)", "AGSE", 65536, 3, 0, 0, 0},
{"Mario vs. Donkey Kong (Europe)", "BM5P", 0, 3, 0, 0, 0}, {"Iridion II (Europe) (En,Fr,De)", "AI2P", 0, 5, 0, 0, 0},
{"Pocket Monsters - Emerald (Japan)", "BPEJ", 131072, 0, 1, 0, 0}, {"Iridion II (USA)", "AI2E", 0, 5, 0, 0, 0},
{"Pocket Monsters - Fire Red (Japan)", "BPRJ", 131072, 0, 0, 0, 0}, {"Koro Koro Puzzle - Happy Panechu! (Japan)", "KHPJ", 0, 4, 0, 0, 0},
{"Pocket Monsters - Leaf Green (Japan)", "BPGJ", 131072, 0, 0, 0, 0}, {"Mario vs. Donkey Kong (Europe)", "BM5P", 65536, 3, 0, 0, 0},
{"Pocket Monsters - Ruby (Japan)", "AXVJ", 131072, 0, 1, 0, 0}, {"Pocket Monsters - Emerald (Japan)", "BPEJ", 131072, 3, 1, 0, 0},
{"Pocket Monsters - Sapphire (Japan)", "AXPJ", 131072, 0, 1, 0, 0}, {"Pocket Monsters - Fire Red (Japan)", "BPRJ", 131072, 3, 0, 0, 0},
{"Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia)", "B24E", 131072, 0, 0, 0, 0}, {"Pocket Monsters - Leaf Green (Japan)", "BPGJ", 131072, 3, 0, 0, 0},
{"Pokemon Mystery Dungeon - Red Rescue Team (En,Fr,De,Es,It)", "B24P", 131072, 0, 0, 0, 0}, //{"Pocket Monsters - Ruby (Japan)", "AXVJ", 131072, 3, 1, 0, 0},
{"Pokemon - Blattgruene Edition (Germany)", "BPGD", 131072, 0, 0, 0, 0}, {"Pocket Monsters - Sapphire (Japan)", "AXPJ", 131072, 3, 1, 0, 0},
{"Pokemon - Edicion Rubi (Spain)", "AXVS", 131072, 0, 1, 0, 0}, {"Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia)", "B24E", 131072, 3, 0, 0, 0},
{"Pokemon - Edicion Esmeralda (Spain)", "BPES", 131072, 0, 1, 0, 0}, {"Pokemon Mystery Dungeon - Red Rescue Team (En,Fr,De,Es,It)", "B24P", 131072, 3, 0, 0, 0},
{"Pokemon - Edicion Rojo Fuego (Spain)", "BPRS", 131072, 1, 0, 0, 0}, {"Pokemon - Blattgruene Edition (Germany)", "BPGD", 131072, 3, 0, 0, 0},
{"Pokemon - Edicion Verde Hoja (Spain)", "BPGS", 131072, 1, 0, 0, 0}, {"Pokemon - Edicion Rubi (Spain)", "AXVS", 131072, 3, 1, 0, 0},
{"Pokemon - Eidicion Zafiro (Spain)", "AXPS", 131072, 0, 1, 0, 0}, {"Pokemon - Edicion Esmeralda (Spain)", "BPES", 131072, 3, 1, 0, 0},
{"Pokemon - Emerald Version (USA, Europe)", "BPEE", 131072, 0, 1, 0, 0}, {"Pokemon - Edicion Rojo Fuego (Spain)", "BPRS", 131072, 3, 0, 0, 0},
{"Pokemon - Feuerrote Edition (Germany)", "BPRD", 131072, 0, 0, 0, 0}, {"Pokemon - Edicion Verde Hoja (Spain)", "BPGS", 131072, 3, 0, 0, 0},
{"Pokemon - Fire Red Version (USA, Europe)", "BPRE", 131072, 0, 0, 0, 0}, {"Pokemon - Eidicion Zafiro (Spain)", "AXPS", 131072, 3, 1, 0, 0},
{"Pokemon - Leaf Green Version (USA, Europe)", "BPGE", 131072, 0, 0, 0, 0}, {"Pokemon - Emerald Version (USA, Europe)", "BPEE", 131072, 3, 1, 0, 0},
{"Pokemon - Rubin Edition (Germany)", "AXVD", 131072, 0, 1, 0, 0}, {"Pokemon - Feuerrote Edition (Germany)", "BPRD", 131072, 3, 0, 0, 0},
{"Pokemon - Ruby Version (USA, Europe)", "AXVE", 131072, 0, 1, 0, 0}, {"Pokemon - Fire Red Version (USA, Europe)", "BPRE", 131072, 3, 0, 0, 0},
{"Pokemon - Sapphire Version (USA, Europe)", "AXPE", 131072, 0, 1, 0, 0}, {"Pokemon - Leaf Green Version (USA, Europe)", "BPGE", 131072, 3, 0, 0, 0},
{"Pokemon - Saphir Edition (Germany)", "AXPD", 131072, 0, 1, 0, 0}, {"Pokemon - Rubin Edition (Germany)", "AXVD", 131072, 3, 1, 0, 0},
{"Pokemon - Smaragd Edition (Germany)", "BPED", 131072, 0, 1, 0, 0}, {"Pokemon - Ruby Version (USA, Europe)", "AXVE", 131072, 3, 1, 0, 0},
{"Pokemon - Version Emeraude (France)", "BPEF", 131072, 0, 1, 0, 0}, {"Pokemon - Sapphire Version (USA, Europe)", "AXPE", 131072, 3, 1, 0, 0},
{"Pokemon - Version Rouge Feu (France)", "BPRF", 131072, 0, 0, 0, 0}, {"Pokemon - Saphir Edition (Germany)", "AXPD", 131072, 3, 1, 0, 0},
{"Pokemon - Version Rubis (France)", "AXVF", 131072, 0, 1, 0, 0}, {"Pokemon - Smaragd Edition (Germany)", "BPED", 131072, 3, 1, 0, 0},
{"Pokemon - Version Saphir (France)", "AXPF", 131072, 0, 1, 0, 0}, {"Pokemon - Version Emeraude (France)", "BPEF", 131072, 3, 1, 0, 0},
{"Pokemon - Version Vert Feuille (France)", "BPGF", 131072, 0, 0, 0, 0}, {"Pokemon - Version Rouge Feu (France)", "BPRF", 131072, 3, 0, 0, 0},
{"Pokemon - Versione Rubino (Italy)", "AXVI", 131072, 0, 1, 0, 0}, {"Pokemon - Version Rubis (France)", "AXVF", 131072, 3, 1, 0, 0},
{"Pokemon - Versione Rosso Fuoco (Italy)", "BPRI", 131072, 0, 0, 0, 0}, {"Pokemon - Version Saphir (France)", "AXPF", 131072, 3, 1, 0, 0},
{"Pokemon - Versione Smeraldo (Italy)", "BPEI", 131072, 0, 1, 0, 0}, {"Pokemon - Version Vert Feuille (France)", "BPGF", 131072, 3, 0, 0, 0},
{"Pokemon - Versione Verde Foglia (Italy)", "BPGI", 131072, 0, 0, 0, 0}, {"Pokemon - Versione Rubino (Italy)", "AXVI", 131072, 3, 1, 0, 0},
{"Pokemon - Versione Zaffiro (Italy)", "AXPI", 131072, 0, 1, 0, 0}, {"Pokemon - Versione Rosso Fuoco (Italy)", "BPRI", 131072, 3, 0, 0, 0},
{"Rockman EXE 4.5 - Real Operation (Japan)", "BR4J", 0, 0, 1, 0, 0}, {"Pokemon - Versione Smeraldo (Italy)", "BPEI", 131072, 3, 1, 0, 0},
{"Rocky (Europe)(En,Fr,De,Es,It)", "AROP", 0, 1, 0, 0, 0}, {"Pokemon - Versione Verde Foglia (Italy)", "BPGI", 131072, 3, 0, 0, 0},
{"Rocky (USA)(En,Fr,De,Es,It)", "AR8e", 0, 1, 0, 0, 0}, {"Pokemon - Versione Zaffiro (Italy)", "AXPI", 131072, 3, 1, 0, 0},
{"Sennen Kazoku (Japan)", "BKAJ", 131072, 0, 1, 0, 0}, {"Rockman EXE 4.5 - Real Operation (Japan)", "BR4J", 0, 0, 1, 0, 0},
{"Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)", "U33J", 0, 1, 1, 0, 0}, {"Rocky (Europe)(En,Fr,De,Es,It)", "AROP", 0, 1, 0, 0, 0},
{"Super Mario Advance 4 (Japan)", "AX4J", 131072, 0, 0, 0, 0}, {"Rocky (USA)(En,Fr,De,Es,It)", "AR8e", 0, 1, 0, 0, 0},
{"Super Mario Advance 4 - Super Mario Bros. 3 (Europe)(En,Fr,De,Es,It)","AX4P", 131072, 0, 0, 0, 0}, {"Sennen Kazoku (Japan)", "BKAJ", 131072, 3, 1, 0, 0},
{"Super Mario Advance 4 - Super Mario Bros 3 - Super Mario Advance 4 v1.1 (USA)","AX4E",131072,0,0,0,0}, {"Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)", "U33J", 8192, 1, 1, 0, 0},
{"Top Gun - Combat Zones (USA)(En,Fr,De,Es,It)", "A2YE", 0, 5, 0, 0, 0}, {"Super Mario Advance 4 (Japan)", "AX4J", 131072, 3, 0, 0, 0},
{"Yoshi's Universal Gravitation (Europe)(En,Fr,De,Es,It)", "KYGP", 0, 4, 0, 0, 0}, {"Super Mario Advance 4 - Super Mario Bros. 3 (Europe)(En,Fr,De,Es,It)","AX4P", 131072, 3, 0, 0, 0},
{"Yoshi no Banyuuinryoku (Japan)", "KYGJ", 0, 4, 0, 0, 0}, {"Super Mario Advance 4 - Super Mario Bros 3 - Super Mario Advance 4 v1.1 (USA)","AX4E",131072,3,0,0,0},
{"Yoshi - Topsy-Turvy (USA)", "KYGE", 0, 1, 0, 0, 0}, {"Top Gun - Combat Zones (USA)(En,Fr,De,Es,It)", "A2YE", 0, 5, 0, 0, 0},
{"Yu-Gi-Oh! GX - Duel Academy (USA)", "BYGE", 0, 2, 0, 0, 1}, {"Yoshi's Universal Gravitation (Europe)(En,Fr,De,Es,It)", "KYGP", 0, 4, 0, 0, 0},
{"Yu-Gi-Oh! - Ultimate Masters - 2006 (Europe)(En,Jp,Fr,De,Es,It)", "BY6P", 0, 2, 0, 0, 0}, {"Yoshi no Banyuuinryoku (Japan)", "KYGJ", 0, 4, 0, 0, 0},
{"Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)", "U32J", 0, 0, 1, 0, 0} {"Yoshi - Topsy-Turvy (USA)", "KYGE", 0, 1, 0, 0, 0},
{"Yu-Gi-Oh! GX - Duel Academy (USA)", "BYGE", 0, 2, 0, 0, 1},
{"Yu-Gi-Oh! - Ultimate Masters - 2006 (Europe)(En,Jp,Fr,De,Es,It)", "BY6P", 0, 2, 0, 0, 0},
{"Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)", "U32J", 0, 0, 1, 0, 0}
}; };
static int romSize = 0; static int romSize = 0;
@ -416,7 +386,7 @@ static void load_image_preferences(void)
"EEPROM", "EEPROM",
"SRAM", "SRAM",
"FLASH", "FLASH",
"SENSOR+EEPROM", "SENSOR + EEPROM",
"NONE" "NONE"
}; };
@ -429,7 +399,8 @@ static void load_image_preferences(void)
buffer[4] = 0; buffer[4] = 0;
cpuSaveType = 0; cpuSaveType = 0;
flashSize = 0x8000; flashSize = 0x10000;
eepromSize = 512;
rtcEnabled = false; rtcEnabled = false;
mirroringEnable = false; mirroringEnable = false;
@ -451,24 +422,32 @@ static void load_image_preferences(void)
if (log_cb) if (log_cb)
log_cb(RETRO_LOG_INFO, "Found ROM in vba-over list.\n"); log_cb(RETRO_LOG_INFO, "Found ROM in vba-over list.\n");
rtcEnabled = gbaover[found_no].rtcEnabled;
if (gbaover[found_no].flashSize != 0)
flashSize = gbaover[found_no].flashSize;
cpuSaveType = gbaover[found_no].saveType; cpuSaveType = gbaover[found_no].saveType;
if (gbaover[found_no].flashSize != 0) {
size_t size = gbaover[found_no].flashSize;
if ((cpuSaveType == 3) && ((size == 65536) || (size == 131072)))
flashSize = size;
else if ((cpuSaveType == 1) && (size == 8192))
eepromSize = 0x2000;
}
rtcEnabled = gbaover[found_no].rtcEnabled;
mirroringEnable = gbaover[found_no].mirroringEnabled; mirroringEnable = gbaover[found_no].mirroringEnabled;
} }
if (!cpuSaveType/* && !found*/) { if (!cpuSaveType) {
utilGBAFindSave(romSize); utilGBAFindSave(romSize);
} }
if (log_cb) { if (log_cb) {
log_cb(RETRO_LOG_INFO, "RTC = %d.\n", rtcEnabled); log_cb(RETRO_LOG_INFO, "RTC = %d.\n", rtcEnabled);
log_cb(RETRO_LOG_INFO, "flashSize = %d.\n", flashSize);
log_cb(RETRO_LOG_INFO, "cpuSaveType = %s.\n", savetype[cpuSaveType]); log_cb(RETRO_LOG_INFO, "cpuSaveType = %s.\n", savetype[cpuSaveType]);
if (cpuSaveType == 3)
log_cb(RETRO_LOG_INFO, "flashSize = %d.\n", flashSize);
if (cpuSaveType == 1)
log_cb(RETRO_LOG_INFO, "eepromSize = %d.\n", eepromSize);
log_cb(RETRO_LOG_INFO, "mirroringEnable = %d.\n", mirroringEnable); log_cb(RETRO_LOG_INFO, "mirroringEnable = %d.\n", mirroringEnable);
} }
} }
@ -506,7 +485,11 @@ static void gba_init(void)
CPUInit(biosfile, usebios); CPUInit(biosfile, usebios);
// CPUReset() will reset eepromSize to 512.
// Save current eepromSize override then restore after CPUReset()
int tmp = eepromSize;
CPUReset(); CPUReset();
eepromSize = tmp;
uint8_t* state_buf = (uint8_t*)malloc(2000000); uint8_t* state_buf = (uint8_t*)malloc(2000000);
serialize_size = CPUWriteState(state_buf, 2000000); serialize_size = CPUWriteState(state_buf, 2000000);
@ -530,7 +513,10 @@ void retro_deinit(void)
void retro_reset(void) void retro_reset(void)
{ {
// save current eepromSize
int tmp = eepromSize;
CPUReset(); CPUReset();
eepromSize = tmp;
} }
#define MAX_BUTTONS 10 #define MAX_BUTTONS 10
@ -909,7 +895,7 @@ bool retro_load_game(const struct retro_game_info *game)
desc[0].start=0x03000000; desc[0].select=0xFF000000; desc[0].len=0x8000; desc[0].ptr=internalRAM;//fast WRAM desc[0].start=0x03000000; desc[0].select=0xFF000000; desc[0].len=0x8000; desc[0].ptr=internalRAM;//fast WRAM
desc[1].start=0x02000000; desc[1].select=0xFF000000; desc[1].len=0x40000; desc[1].ptr=workRAM;//slow WRAM desc[1].start=0x02000000; desc[1].select=0xFF000000; desc[1].len=0x40000; desc[1].ptr=workRAM;//slow WRAM
/* TODO: if SRAM is flash, use start=0 addrspace="S" instead */ /* TODO: if SRAM is flash, use start=0 addrspace="S" instead */
desc[2].start=0x0E000000; desc[2].select=0; desc[2].len=libretro_save_size; desc[2].ptr=flashSaveMemory;//SRAM desc[2].start=0x0E000000; desc[2].select=0; desc[2].len=flashSize; desc[2].ptr=flashSaveMemory;//SRAM
desc[3].start=0x08000000; desc[3].select=0; desc[3].len=romSize; desc[3].ptr=rom;//ROM desc[3].start=0x08000000; desc[3].select=0; desc[3].len=romSize; desc[3].ptr=rom;//ROM
desc[3].flags=RETRO_MEMDESC_CONST; desc[3].flags=RETRO_MEMDESC_CONST;
desc[4].start=0x0A000000; desc[4].select=0; desc[4].len=romSize; desc[4].ptr=rom;//ROM mirror 1 desc[4].start=0x0A000000; desc[4].select=0; desc[4].len=romSize; desc[4].ptr=rom;//ROM mirror 1