From daf50fcdbed4a5f9a570b138093c2c91b454b519 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Tue, 26 Jun 2018 21:40:59 +0800 Subject: [PATCH] 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. --- src/gba/EEprom.cpp | 13 +- src/gba/EEprom.h | 3 +- src/gba/Flash.cpp | 9 -- src/gba/Flash.h | 3 +- src/libretro/UtilRetro.cpp | 3 +- src/libretro/libretro.cpp | 314 ++++++++++++++++++------------------- 6 files changed, 155 insertions(+), 190 deletions(-) diff --git a/src/gba/EEprom.cpp b/src/gba/EEprom.cpp index 6f9695de..371e2a7e 100644 --- a/src/gba/EEprom.cpp +++ b/src/gba/EEprom.cpp @@ -11,13 +11,7 @@ int eepromByte = 0; int eepromBits = 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]; -#endif uint8_t eepromBuffer[16]; bool eepromInUse = false; @@ -36,11 +30,7 @@ variable_desc eepromSaveData[] = { void eepromInit() { -#ifdef __LIBRETRO__ - memset(eepromData, 255, 0x2000); -#else memset(eepromData, 255, sizeof(eepromData)); -#endif } void eepromReset() @@ -122,10 +112,9 @@ int eepromRead(uint32_t /* address */) return 0; } case EEPROM_READDATA2: { - int data = 0; int address = eepromAddress << 3; int mask = 1 << (7 - (eepromBits & 7)); - data = (eepromData[address + eepromByte] & mask) ? 1 : 0; + int data = (eepromData[address + eepromByte] & mask) ? 1 : 0; eepromBits++; if ((eepromBits & 7) == 0) eepromByte++; diff --git a/src/gba/EEprom.h b/src/gba/EEprom.h index 54abeb2c..3e6f1cd2 100644 --- a/src/gba/EEprom.h +++ b/src/gba/EEprom.h @@ -6,13 +6,12 @@ #ifdef __LIBRETRO__ extern void eepromSaveGame(uint8_t*& data); extern void eepromReadGame(const uint8_t*& data, int version); -extern uint8_t* eepromData; #else // !__LIBRETRO__ extern void eepromSaveGame(gzFile _gzFile); extern void eepromReadGame(gzFile _gzFile, int version); extern void eepromReadGameSkip(gzFile _gzFile, int version); -extern uint8_t eepromData[0x2000]; #endif +extern uint8_t eepromData[0x2000]; extern int eepromRead(uint32_t address); extern void eepromWrite(uint32_t address, uint8_t value); extern void eepromInit(); diff --git a/src/gba/Flash.cpp b/src/gba/Flash.cpp index 72e0c8c7..23af03ff 100644 --- a/src/gba/Flash.cpp +++ b/src/gba/Flash.cpp @@ -18,12 +18,7 @@ #define FLASH_PROGRAM 8 #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]; -#endif int flashState = FLASH_READ_ARRAY; int flashReadState = FLASH_READ_ARRAY; @@ -58,11 +53,7 @@ static variable_desc flashSaveData3[] = { void flashInit() { -#ifdef __LIBRETRO__ - memset(flashSaveMemory, 0xff, 0x20000); -#else memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory)); -#endif } void flashReset() diff --git a/src/gba/Flash.h b/src/gba/Flash.h index f17a827d..7f88290e 100644 --- a/src/gba/Flash.h +++ b/src/gba/Flash.h @@ -8,13 +8,12 @@ #ifdef __LIBRETRO__ extern void flashSaveGame(uint8_t*& data); extern void flashReadGame(const uint8_t*& data, int); -extern uint8_t* flashSaveMemory; #else extern void flashSaveGame(gzFile _gzFile); extern void flashReadGame(gzFile _gzFile, int version); extern void flashReadGameSkip(gzFile _gzFile, int version); -extern uint8_t flashSaveMemory[FLASH_128K_SZ]; #endif +extern uint8_t flashSaveMemory[FLASH_128K_SZ]; extern uint8_t flashRead(uint32_t address); extern void flashWrite(uint32_t address, uint8_t byte); extern void flashDelayedWrite(uint32_t address, uint8_t byte); diff --git a/src/libretro/UtilRetro.cpp b/src/libretro/UtilRetro.cpp index 03b18d76..d59b786e 100644 --- a/src/libretro/UtilRetro.cpp +++ b/src/libretro/UtilRetro.cpp @@ -186,7 +186,7 @@ void utilGBAFindSave(const int size) { bool rtcFound_ = false; int detectedSaveType = 0; - int flashSize_ = 0x8000; + int flashSize_ = 0x10000; uint32_t *p = (uint32_t *)&rom[0]; uint32_t *end = (uint32_t *)(&rom[0] + size); @@ -204,6 +204,7 @@ void utilGBAFindSave(const int size) if (detectedSaveType == 0 || detectedSaveType == 1 || detectedSaveType == 4) { detectedSaveType = 2; + flashSize_ = 0x8000; } } } else if (d == 0x53414C46) { diff --git a/src/libretro/libretro.cpp b/src/libretro/libretro.cpp index 15f7eb43..ac61d025 100644 --- a/src/libretro/libretro.cpp +++ b/src/libretro/libretro.cpp @@ -47,9 +47,6 @@ static bool can_dupe = false; int emulating = 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 bool usebios = false; @@ -74,7 +71,12 @@ void (*dbgSignal)(int sig, int number); void* retro_get_memory_data(unsigned id) { 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) return workRAM; 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) { 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) return 0x40000; if (id == RETRO_MEMORY_VIDEO_RAM) @@ -95,44 +102,6 @@ size_t retro_get_memory_size(unsigned id) 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) { return RETRO_API_VERSION; @@ -262,8 +231,6 @@ void retro_init(void) #endif 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); if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) log_cb = log.log; @@ -290,121 +257,124 @@ static unsigned serialize_size = 0; typedef struct { char romtitle[256]; char romid[5]; - int flashSize; - int saveType; + int flashSize; // also can override eeprom size + int saveType; // 0auto 1eeprom 2sram 3flash 4sensor+eeprom 5none int rtcEnabled; int mirroringEnabled; int useBios; } ini_t; static const ini_t gbaover[256] = { - //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 - Buu's Fury + Dragon Ball GT - Transformation (USA)", "BUFE", 0, 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 (USA)", "U3IE", 0, 0, 1, 0, 0}, - {"Boktai 2 - Solar Boy Django (USA)", "U32E", 0, 0, 1, 0, 0}, - {"Boktai 2 - Solar Boy Django (Europe)(En,Fr,De,Es,It)", "U32P", 0, 0, 1, 0, 0}, - {"Bokura no Taiyou - Taiyou Action RPG (Japan)", "U3IJ", 0, 0, 1, 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 - 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 - 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 - Legend of Zelda (USA, Europe)", "FZLE", 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 - 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 - 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}, - {"Digi Communication 2 - Datou! Black Gemagema Dan (Japan)", "BDKJ", 0, 1, 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 Z - Buu's Fury (USA)", "BG3E", 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 - The Legacy of Goku II International (Japan)", "ALFJ", 0, 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 (USA)", "ALFE", 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}, - {"F-Zero - Climax (Japan)", "BFTJ", 131072, 0, 0, 0, 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. 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. 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. 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. 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. 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. 23 - Metroid (Japan)", "FMRJ", 0, 1, 0, 1, 0}, - {"Famicom Mini Vol. 24 - Hikari Shinwa - Palthena no Kagami (Japan)", "FPTJ", 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. 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. 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. 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan)","FSDJ",0,1, 0, 1, 0}, - {"Game Boy Wars Advance 1+2 (Japan)", "BGWJ", 131072, 0, 0, 0, 0}, - {"Golden Sun - The Lost Age (USA)", "AGFE", 65536, 0, 0, 1, 0}, - {"Golden Sun (USA)", "AGSE", 65536, 0, 0, 1, 0}, - {"Iridion II (Europe) (En,Fr,De)", "AI2P", 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}, - {"Mario vs. Donkey Kong (Europe)", "BM5P", 0, 3, 0, 0, 0}, - {"Pocket Monsters - Emerald (Japan)", "BPEJ", 131072, 0, 1, 0, 0}, - {"Pocket Monsters - Fire Red (Japan)", "BPRJ", 131072, 0, 0, 0, 0}, - {"Pocket Monsters - Leaf Green (Japan)", "BPGJ", 131072, 0, 0, 0, 0}, - {"Pocket Monsters - Ruby (Japan)", "AXVJ", 131072, 0, 1, 0, 0}, - {"Pocket Monsters - Sapphire (Japan)", "AXPJ", 131072, 0, 1, 0, 0}, - {"Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia)", "B24E", 131072, 0, 0, 0, 0}, - {"Pokemon Mystery Dungeon - Red Rescue Team (En,Fr,De,Es,It)", "B24P", 131072, 0, 0, 0, 0}, - {"Pokemon - Blattgruene Edition (Germany)", "BPGD", 131072, 0, 0, 0, 0}, - {"Pokemon - Edicion Rubi (Spain)", "AXVS", 131072, 0, 1, 0, 0}, - {"Pokemon - Edicion Esmeralda (Spain)", "BPES", 131072, 0, 1, 0, 0}, - {"Pokemon - Edicion Rojo Fuego (Spain)", "BPRS", 131072, 1, 0, 0, 0}, - {"Pokemon - Edicion Verde Hoja (Spain)", "BPGS", 131072, 1, 0, 0, 0}, - {"Pokemon - Eidicion Zafiro (Spain)", "AXPS", 131072, 0, 1, 0, 0}, - {"Pokemon - Emerald Version (USA, Europe)", "BPEE", 131072, 0, 1, 0, 0}, - {"Pokemon - Feuerrote Edition (Germany)", "BPRD", 131072, 0, 0, 0, 0}, - {"Pokemon - Fire Red Version (USA, Europe)", "BPRE", 131072, 0, 0, 0, 0}, - {"Pokemon - Leaf Green Version (USA, Europe)", "BPGE", 131072, 0, 0, 0, 0}, - {"Pokemon - Rubin Edition (Germany)", "AXVD", 131072, 0, 1, 0, 0}, - {"Pokemon - Ruby Version (USA, Europe)", "AXVE", 131072, 0, 1, 0, 0}, - {"Pokemon - Sapphire Version (USA, Europe)", "AXPE", 131072, 0, 1, 0, 0}, - {"Pokemon - Saphir Edition (Germany)", "AXPD", 131072, 0, 1, 0, 0}, - {"Pokemon - Smaragd Edition (Germany)", "BPED", 131072, 0, 1, 0, 0}, - {"Pokemon - Version Emeraude (France)", "BPEF", 131072, 0, 1, 0, 0}, - {"Pokemon - Version Rouge Feu (France)", "BPRF", 131072, 0, 0, 0, 0}, - {"Pokemon - Version Rubis (France)", "AXVF", 131072, 0, 1, 0, 0}, - {"Pokemon - Version Saphir (France)", "AXPF", 131072, 0, 1, 0, 0}, - {"Pokemon - Version Vert Feuille (France)", "BPGF", 131072, 0, 0, 0, 0}, - {"Pokemon - Versione Rubino (Italy)", "AXVI", 131072, 0, 1, 0, 0}, - {"Pokemon - Versione Rosso Fuoco (Italy)", "BPRI", 131072, 0, 0, 0, 0}, - {"Pokemon - Versione Smeraldo (Italy)", "BPEI", 131072, 0, 1, 0, 0}, - {"Pokemon - Versione Verde Foglia (Italy)", "BPGI", 131072, 0, 0, 0, 0}, - {"Pokemon - Versione Zaffiro (Italy)", "AXPI", 131072, 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 (USA)(En,Fr,De,Es,It)", "AR8e", 0, 1, 0, 0, 0}, - {"Sennen Kazoku (Japan)", "BKAJ", 131072, 0, 1, 0, 0}, - {"Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)", "U33J", 0, 1, 1, 0, 0}, - {"Super Mario Advance 4 (Japan)", "AX4J", 131072, 0, 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 - Super Mario Advance 4 v1.1 (USA)","AX4E",131072,0,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 no Banyuuinryoku (Japan)", "KYGJ", 0, 4, 0, 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} + // TODO: + // - Update existing overrides + // - Add overrides for eeprom 8192 size + //romtitle, romid flash save rtc mirror bios + {"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", 8192, 1, 0, 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", 8192, 1, 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", 8192, 1, 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}, + {"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 - 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 - Excitebike (USA, Europe)", "FEBE", 8192, 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 - 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 - 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 - Zelda II - The Adventure of Link (USA, Europe)", "FLBE", 8192, 1, 0, 1, 0}, + {"Digi Communication 2 - Datou! Black Gemagema Dan (Japan)", "BDKJ", 8192, 1, 0, 0, 0}, + {"e-Reader (USA)", "PSAE", 131072, 0, 0, 0, 0}, + {"Dragon Ball GT - Transformation (USA)", "BT4E", 8192, 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 (USA)", "BDBE", 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", 8192, 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 (USA)", "ALGE", 131072, 1, 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. 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. 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. 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. 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. 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. 22 - Nazo no Murasame Jou (Japan)", "FNMJ", 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", 8192, 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. 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. 29 - Akumajou Dracula (Japan)", "FADJ", 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, 3, 0, 0, 0}, + {"Golden Sun - The Lost Age (USA)", "AGFE", 65536, 3, 0, 0, 0}, + {"Golden Sun (USA)", "AGSE", 65536, 3, 0, 0, 0}, + {"Iridion II (Europe) (En,Fr,De)", "AI2P", 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}, + {"Mario vs. Donkey Kong (Europe)", "BM5P", 65536, 3, 0, 0, 0}, + {"Pocket Monsters - Emerald (Japan)", "BPEJ", 131072, 3, 1, 0, 0}, + {"Pocket Monsters - Fire Red (Japan)", "BPRJ", 131072, 3, 0, 0, 0}, + {"Pocket Monsters - Leaf Green (Japan)", "BPGJ", 131072, 3, 0, 0, 0}, + //{"Pocket Monsters - Ruby (Japan)", "AXVJ", 131072, 3, 1, 0, 0}, + {"Pocket Monsters - Sapphire (Japan)", "AXPJ", 131072, 3, 1, 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, 3, 0, 0, 0}, + {"Pokemon - Blattgruene Edition (Germany)", "BPGD", 131072, 3, 0, 0, 0}, + {"Pokemon - Edicion Rubi (Spain)", "AXVS", 131072, 3, 1, 0, 0}, + {"Pokemon - Edicion Esmeralda (Spain)", "BPES", 131072, 3, 1, 0, 0}, + {"Pokemon - Edicion Rojo Fuego (Spain)", "BPRS", 131072, 3, 0, 0, 0}, + {"Pokemon - Edicion Verde Hoja (Spain)", "BPGS", 131072, 3, 0, 0, 0}, + {"Pokemon - Eidicion Zafiro (Spain)", "AXPS", 131072, 3, 1, 0, 0}, + {"Pokemon - Emerald Version (USA, Europe)", "BPEE", 131072, 3, 1, 0, 0}, + {"Pokemon - Feuerrote Edition (Germany)", "BPRD", 131072, 3, 0, 0, 0}, + {"Pokemon - Fire Red Version (USA, Europe)", "BPRE", 131072, 3, 0, 0, 0}, + {"Pokemon - Leaf Green Version (USA, Europe)", "BPGE", 131072, 3, 0, 0, 0}, + {"Pokemon - Rubin Edition (Germany)", "AXVD", 131072, 3, 1, 0, 0}, + {"Pokemon - Ruby Version (USA, Europe)", "AXVE", 131072, 3, 1, 0, 0}, + {"Pokemon - Sapphire Version (USA, Europe)", "AXPE", 131072, 3, 1, 0, 0}, + {"Pokemon - Saphir Edition (Germany)", "AXPD", 131072, 3, 1, 0, 0}, + {"Pokemon - Smaragd Edition (Germany)", "BPED", 131072, 3, 1, 0, 0}, + {"Pokemon - Version Emeraude (France)", "BPEF", 131072, 3, 1, 0, 0}, + {"Pokemon - Version Rouge Feu (France)", "BPRF", 131072, 3, 0, 0, 0}, + {"Pokemon - Version Rubis (France)", "AXVF", 131072, 3, 1, 0, 0}, + {"Pokemon - Version Saphir (France)", "AXPF", 131072, 3, 1, 0, 0}, + {"Pokemon - Version Vert Feuille (France)", "BPGF", 131072, 3, 0, 0, 0}, + {"Pokemon - Versione Rubino (Italy)", "AXVI", 131072, 3, 1, 0, 0}, + {"Pokemon - Versione Rosso Fuoco (Italy)", "BPRI", 131072, 3, 0, 0, 0}, + {"Pokemon - Versione Smeraldo (Italy)", "BPEI", 131072, 3, 1, 0, 0}, + {"Pokemon - Versione Verde Foglia (Italy)", "BPGI", 131072, 3, 0, 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}, + {"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}, + {"Sennen Kazoku (Japan)", "BKAJ", 131072, 3, 1, 0, 0}, + {"Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)", "U33J", 8192, 1, 1, 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, 3, 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}, + {"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 - 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; @@ -416,7 +386,7 @@ static void load_image_preferences(void) "EEPROM", "SRAM", "FLASH", - "SENSOR+EEPROM", + "SENSOR + EEPROM", "NONE" }; @@ -429,7 +399,8 @@ static void load_image_preferences(void) buffer[4] = 0; cpuSaveType = 0; - flashSize = 0x8000; + flashSize = 0x10000; + eepromSize = 512; rtcEnabled = false; mirroringEnable = false; @@ -451,24 +422,32 @@ static void load_image_preferences(void) if (log_cb) 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; + 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; } - if (!cpuSaveType/* && !found*/) { + if (!cpuSaveType) { utilGBAFindSave(romSize); } if (log_cb) { 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]); + 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); } } @@ -506,7 +485,11 @@ static void gba_init(void) CPUInit(biosfile, usebios); + // CPUReset() will reset eepromSize to 512. + // Save current eepromSize override then restore after CPUReset() + int tmp = eepromSize; CPUReset(); + eepromSize = tmp; uint8_t* state_buf = (uint8_t*)malloc(2000000); serialize_size = CPUWriteState(state_buf, 2000000); @@ -530,7 +513,10 @@ void retro_deinit(void) void retro_reset(void) { + // save current eepromSize + int tmp = eepromSize; CPUReset(); + eepromSize = tmp; } #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[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 */ - 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].flags=RETRO_MEMDESC_CONST; desc[4].start=0x0A000000; desc[4].select=0; desc[4].len=romSize; desc[4].ptr=rom;//ROM mirror 1