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,114 +257,117 @@ 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] = {
// TODO:
// - Update existing overrides
// - Add overrides for eeprom 8192 size
//romtitle, romid flash save rtc mirror bios //romtitle, romid flash save rtc mirror bios
{"2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA)", "BLFE", 0, 1, 0, 0, 0}, {"2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA)", "BLFE", 8192, 1, 0, 0, 0},
{"2 Games in 1 - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA)", "BUFE", 0, 1, 0, 0, 0}, {"2 Games in 1 - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA)", "BUFE", 8192, 1, 0, 0, 0},
{"Boktai - The Sun Is in Your Hand (Europe)(En,Fr,De,Es,It)", "U3IP", 0, 0, 1, 0, 0}, {"Boktai - The Sun Is in Your Hand (Europe)(En,Fr,De,Es,It)", "U3IP", 8192, 1, 1, 0, 0},
{"Boktai - The Sun Is in Your Hand (USA)", "U3IE", 0, 0, 1, 0, 0}, {"Boktai - The Sun Is in Your Hand (USA)", "U3IE", 8192, 1, 1, 0, 0},
{"Boktai 2 - Solar Boy Django (USA)", "U32E", 0, 0, 1, 0, 0}, {"Boktai 2 - Solar Boy Django (USA)", "U32E", 8192, 1, 1, 0, 0},
{"Boktai 2 - Solar Boy Django (Europe)(En,Fr,De,Es,It)", "U32P", 0, 0, 1, 0, 0}, {"Boktai 2 - Solar Boy Django (Europe)(En,Fr,De,Es,It)", "U32P", 8192, 1, 1, 0, 0},
{"Bokura no Taiyou - Taiyou Action RPG (Japan)", "U3IJ", 0, 0, 1, 0, 0}, {"Bokura no Taiyou - Taiyou Action RPG (Japan)", "U3IJ", 0, 1, 1, 0, 0},
{"Card e-Reader+ (Japan)", "PSAJ", 131072, 0, 0, 0, 0}, {"Card e-Reader+ (Japan)", "PSAJ", 131072, 0, 0, 0, 0},
{"Classic NES Series - Bomberman (USA, Europe)", "FBME", 0, 1, 0, 1, 0}, {"Classic NES Series - Bomberman (USA, Europe)", "FBME", 0, 1, 0, 1, 0},
{"Classic NES Series - Castlevania (USA, Europe)", "FADE", 0, 1, 0, 1, 0}, {"Classic NES Series - Castlevania (USA, Europe)", "FADE", 0, 1, 0, 1, 0},
{"Classic NES Series - Donkey Kong (USA, Europe)", "FDKE", 0, 1, 0, 1, 0}, {"Classic NES Series - Donkey Kong (USA, Europe)", "FDKE", 0, 1, 0, 1, 0},
{"Classic NES Series - Dr. Mario (USA, Europe)", "FDME", 0, 1, 0, 1, 0}, {"Classic NES Series - Dr. Mario (USA, Europe)", "FDME", 0, 1, 0, 1, 0},
{"Classic NES Series - Excitebike (USA, Europe)", "FEBE", 0, 1, 0, 1, 0}, {"Classic NES Series - Excitebike (USA, Europe)", "FEBE", 8192, 1, 0, 1, 0},
{"Classic NES Series - Legend of Zelda (USA, Europe)", "FZLE", 0, 1, 0, 1, 0}, //{"Classic NES Series - Legend of Zelda (USA, Europe)", "FZLE", 8192, 1, 0, 1, 0},
{"Classic NES Series - Ice Climber (USA, Europe)", "FICE", 0, 1, 0, 1, 0}, {"Classic NES Series - Ice Climber (USA, Europe)", "FICE", 0, 1, 0, 1, 0},
{"Classic NES Series - Metroid (USA, Europe)", "FMRE", 0, 1, 0, 1, 0}, {"Classic NES Series - Metroid (USA, Europe)", "FMRE", 0, 1, 0, 1, 0},
{"Classic NES Series - Pac-Man (USA, Europe)", "FP7E", 0, 1, 0, 1, 0}, {"Classic NES Series - Pac-Man (USA, Europe)", "FP7E", 0, 1, 0, 1, 0},
{"Classic NES Series - Super Mario Bros. (USA, Europe)", "FSME", 0, 1, 0, 1, 0}, {"Classic NES Series - Super Mario Bros. (USA, Europe)", "FSME", 0, 1, 0, 1, 0},
{"Classic NES Series - Xevious (USA, Europe)", "FXVE", 0, 1, 0, 1, 0}, {"Classic NES Series - Xevious (USA, Europe)", "FXVE", 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 - Zelda II - The Adventure of Link (USA, Europe)", "FLBE", 8192, 1, 0, 1, 0},
{"Digi Communication 2 - Datou! Black Gemagema Dan (Japan)", "BDKJ", 0, 1, 0, 0, 0}, {"Digi Communication 2 - Datou! Black Gemagema Dan (Japan)", "BDKJ", 8192, 1, 0, 0, 0},
{"e-Reader (USA)", "PSAE", 131072, 0, 0, 0, 0}, {"e-Reader (USA)", "PSAE", 131072, 0, 0, 0, 0},
{"Dragon Ball GT - Transformation (USA)", "BT4E", 0, 1, 0, 0, 0}, {"Dragon Ball GT - Transformation (USA)", "BT4E", 8192, 1, 0, 0, 0},
{"Dragon Ball Z - Buu's Fury (USA)", "BG3E", 0, 1, 0, 0, 0}, {"Dragon Ball Z - Buu's Fury (USA)", "BG3E", 8192, 1, 0, 0, 0},
{"Dragon Ball Z - Taiketsu (Europe)(En,Fr,De,Es,It)", "BDBP", 0, 1, 0, 0, 0}, {"Dragon Ball Z - Taiketsu (Europe)(En,Fr,De,Es,It)", "BDBP", 0, 1, 0, 0, 0},
{"Dragon Ball Z - Taiketsu (USA)", "BDBE", 0, 1, 0, 0, 0}, {"Dragon Ball Z - Taiketsu (USA)", "BDBE", 0, 1, 0, 0, 0},
{"Dragon Ball Z - The Legacy of Goku II International (Japan)", "ALFJ", 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 II (Europe)(En,Fr,De,Es,It)", "ALFP", 0, 1, 0, 0, 0}, {"Dragon Ball Z - The Legacy of Goku II (Europe)(En,Fr,De,Es,It)", "ALFP", 8192, 1, 0, 0, 0},
{"Dragon Ball Z - The Legacy of Goku II (USA)", "ALFE", 0, 1, 0, 0, 0}, {"Dragon Ball Z - The Legacy of Goku II (USA)", "ALFE", 8192, 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 (Europe)(En,Fr,De,Es,It)", "ALGP", 0, 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 (USA)", "ALGE", 131072, 1, 0, 0, 0},
{"F-Zero - Climax (Japan)", "BFTJ", 131072, 0, 0, 0, 0}, {"F-Zero - Climax (Japan)", "BFTJ", 131072, 3, 0, 0, 0},
{"Famicom Mini Vol. 01 - Super Mario Bros. (Japan)", "FMBJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 01 - Super Mario Bros. (Japan)", "FMBJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 12 - Clu Clu Land (Japan)", "FCLJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 12 - Clu Clu Land (Japan)", "FCLJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 13 - Balloon Fight (Japan)", "FBFJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 13 - Balloon Fight (Japan)", "FBFJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 14 - Wrecking Crew (Japan)", "FWCJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 14 - Wrecking Crew (Japan)", "FWCJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 15 - Dr. Mario (Japan)", "FDMJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 15 - Dr. Mario (Japan)", "FDMJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 16 - Dig Dug (Japan)", "FTBJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 16 - Dig Dug (Japan)", "FDDJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 17 - Takahashi Meijin no Boukenjima (Japan)", "FTBJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 17 - Takahashi Meijin no Boukenjima (Japan)", "FTBJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 18 - Makaimura (Japan)", "FMKJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 18 - Makaimura (Japan)", "FMKJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 19 - Twin Bee (Japan)", "FTWJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 19 - Twin Bee (Japan)", "FTWJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 20 - Ganbare Goemon! Karakuri Douchuu (Japan)", "FGGJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 20 - Ganbare Goemon! Karakuri Douchuu (Japan)", "FGGJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 21 - Super Mario Bros. 2 (Japan)", "FM2J", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 21 - Super Mario Bros. 2 (Japan)", "FM2J", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 22 - Nazo no Murasame Jou (Japan)", "FNMJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 22 - Nazo no Murasame Jou (Japan)", "FNMJ", 0, 1, 0, 1, 0},
{"Famicom Mini Vol. 23 - Metroid (Japan)", "FMRJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 23 - Metroid (Japan)", "FMRJ", 8192, 1, 0, 1, 0},
{"Famicom Mini Vol. 24 - Hikari Shinwa - Palthena no Kagami (Japan)", "FPTJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 24 - Hikari Shinwa - Palthena no Kagami (Japan)", "FPTJ", 8192, 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. 25 - The Legend of Zelda 2 - Link no Bouken (Japan)","FLBJ",8192, 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. 26 - Famicom Mukashi Banashi - Shin Onigashima - Zen Kou Hen (Japan)","FFMJ",0,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. 27 - Famicom Tantei Club - Kieta Koukeisha - Zen Kou Hen (Japan)","FTKJ",0,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. 28 - Famicom Tantei Club Part II - Ushiro ni Tatsu Shoujo - Zen Kou Hen (Japan)","FTUJ",0,1,0,1,0},
{"Famicom Mini Vol. 29 - Akumajou Dracula (Japan)", "FADJ", 0, 1, 0, 1, 0}, {"Famicom Mini Vol. 29 - Akumajou Dracula (Japan)", "FADJ", 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. 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan)","FSDJ",8192,1, 0, 1, 0},
{"Game Boy Wars Advance 1+2 (Japan)", "BGWJ", 131072, 0, 0, 0, 0}, {"Game Boy Wars Advance 1+2 (Japan)", "BGWJ", 131072, 3, 0, 0, 0},
{"Golden Sun - The Lost Age (USA)", "AGFE", 65536, 0, 0, 1, 0}, {"Golden Sun - The Lost Age (USA)", "AGFE", 65536, 3, 0, 0, 0},
{"Golden Sun (USA)", "AGSE", 65536, 0, 0, 1, 0}, {"Golden Sun (USA)", "AGSE", 65536, 3, 0, 0, 0},
{"Iridion II (Europe) (En,Fr,De)", "AI2P", 0, 5, 0, 0, 0}, {"Iridion II (Europe) (En,Fr,De)", "AI2P", 0, 5, 0, 0, 0},
{"Iridion II (USA)", "AI2E", 0, 5, 0, 0, 0}, {"Iridion II (USA)", "AI2E", 0, 5, 0, 0, 0},
{"Koro Koro Puzzle - Happy Panechu! (Japan)", "KHPJ", 0, 4, 0, 0, 0}, {"Koro Koro Puzzle - Happy Panechu! (Japan)", "KHPJ", 0, 4, 0, 0, 0},
{"Mario vs. Donkey Kong (Europe)", "BM5P", 0, 3, 0, 0, 0}, {"Mario vs. Donkey Kong (Europe)", "BM5P", 65536, 3, 0, 0, 0},
{"Pocket Monsters - Emerald (Japan)", "BPEJ", 131072, 0, 1, 0, 0}, {"Pocket Monsters - Emerald (Japan)", "BPEJ", 131072, 3, 1, 0, 0},
{"Pocket Monsters - Fire Red (Japan)", "BPRJ", 131072, 0, 0, 0, 0}, {"Pocket Monsters - Fire Red (Japan)", "BPRJ", 131072, 3, 0, 0, 0},
{"Pocket Monsters - Leaf Green (Japan)", "BPGJ", 131072, 0, 0, 0, 0}, {"Pocket Monsters - Leaf Green (Japan)", "BPGJ", 131072, 3, 0, 0, 0},
{"Pocket Monsters - Ruby (Japan)", "AXVJ", 131072, 0, 1, 0, 0}, //{"Pocket Monsters - Ruby (Japan)", "AXVJ", 131072, 3, 1, 0, 0},
{"Pocket Monsters - Sapphire (Japan)", "AXPJ", 131072, 0, 1, 0, 0}, {"Pocket Monsters - Sapphire (Japan)", "AXPJ", 131072, 3, 1, 0, 0},
{"Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia)", "B24E", 131072, 0, 0, 0, 0}, {"Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia)", "B24E", 131072, 3, 0, 0, 0},
{"Pokemon Mystery Dungeon - Red Rescue Team (En,Fr,De,Es,It)", "B24P", 131072, 0, 0, 0, 0}, {"Pokemon Mystery Dungeon - Red Rescue Team (En,Fr,De,Es,It)", "B24P", 131072, 3, 0, 0, 0},
{"Pokemon - Blattgruene Edition (Germany)", "BPGD", 131072, 0, 0, 0, 0}, {"Pokemon - Blattgruene Edition (Germany)", "BPGD", 131072, 3, 0, 0, 0},
{"Pokemon - Edicion Rubi (Spain)", "AXVS", 131072, 0, 1, 0, 0}, {"Pokemon - Edicion Rubi (Spain)", "AXVS", 131072, 3, 1, 0, 0},
{"Pokemon - Edicion Esmeralda (Spain)", "BPES", 131072, 0, 1, 0, 0}, {"Pokemon - Edicion Esmeralda (Spain)", "BPES", 131072, 3, 1, 0, 0},
{"Pokemon - Edicion Rojo Fuego (Spain)", "BPRS", 131072, 1, 0, 0, 0}, {"Pokemon - Edicion Rojo Fuego (Spain)", "BPRS", 131072, 3, 0, 0, 0},
{"Pokemon - Edicion Verde Hoja (Spain)", "BPGS", 131072, 1, 0, 0, 0}, {"Pokemon - Edicion Verde Hoja (Spain)", "BPGS", 131072, 3, 0, 0, 0},
{"Pokemon - Eidicion Zafiro (Spain)", "AXPS", 131072, 0, 1, 0, 0}, {"Pokemon - Eidicion Zafiro (Spain)", "AXPS", 131072, 3, 1, 0, 0},
{"Pokemon - Emerald Version (USA, Europe)", "BPEE", 131072, 0, 1, 0, 0}, {"Pokemon - Emerald Version (USA, Europe)", "BPEE", 131072, 3, 1, 0, 0},
{"Pokemon - Feuerrote Edition (Germany)", "BPRD", 131072, 0, 0, 0, 0}, {"Pokemon - Feuerrote Edition (Germany)", "BPRD", 131072, 3, 0, 0, 0},
{"Pokemon - Fire Red Version (USA, Europe)", "BPRE", 131072, 0, 0, 0, 0}, {"Pokemon - Fire Red Version (USA, Europe)", "BPRE", 131072, 3, 0, 0, 0},
{"Pokemon - Leaf Green Version (USA, Europe)", "BPGE", 131072, 0, 0, 0, 0}, {"Pokemon - Leaf Green Version (USA, Europe)", "BPGE", 131072, 3, 0, 0, 0},
{"Pokemon - Rubin Edition (Germany)", "AXVD", 131072, 0, 1, 0, 0}, {"Pokemon - Rubin Edition (Germany)", "AXVD", 131072, 3, 1, 0, 0},
{"Pokemon - Ruby Version (USA, Europe)", "AXVE", 131072, 0, 1, 0, 0}, {"Pokemon - Ruby Version (USA, Europe)", "AXVE", 131072, 3, 1, 0, 0},
{"Pokemon - Sapphire Version (USA, Europe)", "AXPE", 131072, 0, 1, 0, 0}, {"Pokemon - Sapphire Version (USA, Europe)", "AXPE", 131072, 3, 1, 0, 0},
{"Pokemon - Saphir Edition (Germany)", "AXPD", 131072, 0, 1, 0, 0}, {"Pokemon - Saphir Edition (Germany)", "AXPD", 131072, 3, 1, 0, 0},
{"Pokemon - Smaragd Edition (Germany)", "BPED", 131072, 0, 1, 0, 0}, {"Pokemon - Smaragd Edition (Germany)", "BPED", 131072, 3, 1, 0, 0},
{"Pokemon - Version Emeraude (France)", "BPEF", 131072, 0, 1, 0, 0}, {"Pokemon - Version Emeraude (France)", "BPEF", 131072, 3, 1, 0, 0},
{"Pokemon - Version Rouge Feu (France)", "BPRF", 131072, 0, 0, 0, 0}, {"Pokemon - Version Rouge Feu (France)", "BPRF", 131072, 3, 0, 0, 0},
{"Pokemon - Version Rubis (France)", "AXVF", 131072, 0, 1, 0, 0}, {"Pokemon - Version Rubis (France)", "AXVF", 131072, 3, 1, 0, 0},
{"Pokemon - Version Saphir (France)", "AXPF", 131072, 0, 1, 0, 0}, {"Pokemon - Version Saphir (France)", "AXPF", 131072, 3, 1, 0, 0},
{"Pokemon - Version Vert Feuille (France)", "BPGF", 131072, 0, 0, 0, 0}, {"Pokemon - Version Vert Feuille (France)", "BPGF", 131072, 3, 0, 0, 0},
{"Pokemon - Versione Rubino (Italy)", "AXVI", 131072, 0, 1, 0, 0}, {"Pokemon - Versione Rubino (Italy)", "AXVI", 131072, 3, 1, 0, 0},
{"Pokemon - Versione Rosso Fuoco (Italy)", "BPRI", 131072, 0, 0, 0, 0}, {"Pokemon - Versione Rosso Fuoco (Italy)", "BPRI", 131072, 3, 0, 0, 0},
{"Pokemon - Versione Smeraldo (Italy)", "BPEI", 131072, 0, 1, 0, 0}, {"Pokemon - Versione Smeraldo (Italy)", "BPEI", 131072, 3, 1, 0, 0},
{"Pokemon - Versione Verde Foglia (Italy)", "BPGI", 131072, 0, 0, 0, 0}, {"Pokemon - Versione Verde Foglia (Italy)", "BPGI", 131072, 3, 0, 0, 0},
{"Pokemon - Versione Zaffiro (Italy)", "AXPI", 131072, 0, 1, 0, 0}, {"Pokemon - Versione Zaffiro (Italy)", "AXPI", 131072, 3, 1, 0, 0},
{"Rockman EXE 4.5 - Real Operation (Japan)", "BR4J", 0, 0, 1, 0, 0}, {"Rockman EXE 4.5 - Real Operation (Japan)", "BR4J", 0, 0, 1, 0, 0},
{"Rocky (Europe)(En,Fr,De,Es,It)", "AROP", 0, 1, 0, 0, 0}, {"Rocky (Europe)(En,Fr,De,Es,It)", "AROP", 0, 1, 0, 0, 0},
{"Rocky (USA)(En,Fr,De,Es,It)", "AR8e", 0, 1, 0, 0, 0}, {"Rocky (USA)(En,Fr,De,Es,It)", "AR8e", 0, 1, 0, 0, 0},
{"Sennen Kazoku (Japan)", "BKAJ", 131072, 0, 1, 0, 0}, {"Sennen Kazoku (Japan)", "BKAJ", 131072, 3, 1, 0, 0},
{"Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)", "U33J", 0, 1, 1, 0, 0}, {"Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)", "U33J", 8192, 1, 1, 0, 0},
{"Super Mario Advance 4 (Japan)", "AX4J", 131072, 0, 0, 0, 0}, {"Super Mario Advance 4 (Japan)", "AX4J", 131072, 3, 0, 0, 0},
{"Super Mario Advance 4 - Super Mario Bros. 3 (Europe)(En,Fr,De,Es,It)","AX4P", 131072, 0, 0, 0, 0}, {"Super Mario Advance 4 - Super Mario Bros. 3 (Europe)(En,Fr,De,Es,It)","AX4P", 131072, 3, 0, 0, 0},
{"Super Mario Advance 4 - Super Mario Bros 3 - Super Mario Advance 4 v1.1 (USA)","AX4E",131072,0,0,0,0}, {"Super Mario Advance 4 - Super Mario Bros 3 - Super Mario Advance 4 v1.1 (USA)","AX4E",131072,3,0,0,0},
{"Top Gun - Combat Zones (USA)(En,Fr,De,Es,It)", "A2YE", 0, 5, 0, 0, 0}, {"Top Gun - Combat Zones (USA)(En,Fr,De,Es,It)", "A2YE", 0, 5, 0, 0, 0},
{"Yoshi's Universal Gravitation (Europe)(En,Fr,De,Es,It)", "KYGP", 0, 4, 0, 0, 0}, {"Yoshi's Universal Gravitation (Europe)(En,Fr,De,Es,It)", "KYGP", 0, 4, 0, 0, 0},
{"Yoshi no Banyuuinryoku (Japan)", "KYGJ", 0, 4, 0, 0, 0}, {"Yoshi no Banyuuinryoku (Japan)", "KYGJ", 0, 4, 0, 0, 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