diff --git a/gba_memory.c b/gba_memory.c index 7badef57..731d232a 100644 --- a/gba_memory.c +++ b/gba_memory.c @@ -2540,37 +2540,40 @@ static s32 load_gamepak_raw(const char *name) } u32 load_gamepak(const struct retro_game_info* info, const char *name, - int force_rtc, int force_rumble, int force_serial) + int force_rtc, int force_rumble, int force_serial, + int force_flash_size) { - gamepak_info_t gpinfo; - - if (load_gamepak_raw(name)) - return -1; - - // Buffer 0 always has the first 1MB chunk of the ROM - memset(&gpinfo, 0, sizeof(gpinfo)); - memcpy(gpinfo.gamepak_title, &gamepak_buffers[0][0xA0], 12); - memcpy(gpinfo.gamepak_code, &gamepak_buffers[0][0xAC], 4); - memcpy(gpinfo.gamepak_maker, &gamepak_buffers[0][0xB0], 2); - - idle_loop_target_pc = 0xFFFFFFFF; - translation_gate_targets = 0; - flash_device_id = FLASH_DEVICE_MACRONIX_64KB; - flash_bank_cnt = FLASH_SIZE_64KB; - rtc_enabled = false; - rumble_enabled = false; - backup_type_reset = BACKUP_UNKN; - serial_mode = force_serial; - - load_game_config_over(&gpinfo); - - // Forced RTC / Rumble modes, override the autodetect logic. - if (force_rtc != FEAT_AUTODETECT) - rtc_enabled = (force_rtc == FEAT_ENABLE); - if (force_rumble != FEAT_AUTODETECT) - rumble_enabled = (force_rumble == FEAT_ENABLE); - - return 0; + gamepak_info_t gpinfo; + + if (load_gamepak_raw(name)) + return -1; + + // Buffer 0 always has the first 1MB chunk of the ROM + memset(&gpinfo, 0, sizeof(gpinfo)); + memcpy(gpinfo.gamepak_title, &gamepak_buffers[0][0xA0], 12); + memcpy(gpinfo.gamepak_code, &gamepak_buffers[0][0xAC], 4); + memcpy(gpinfo.gamepak_maker, &gamepak_buffers[0][0xB0], 2); + + idle_loop_target_pc = 0xFFFFFFFF; + translation_gate_targets = 0; + flash_device_id = FLASH_DEVICE_MACRONIX_64KB; + flash_bank_cnt = FLASH_SIZE_64KB; + rtc_enabled = false; + rumble_enabled = false; + backup_type_reset = BACKUP_UNKN; + serial_mode = force_serial; + + load_game_config_over(&gpinfo); + + // Forced RTC / Rumble / Flash modes, override the autodetect logic. + if (force_rtc != FEAT_AUTODETECT) + rtc_enabled = (force_rtc == FEAT_ENABLE); + if (force_rumble != FEAT_AUTODETECT) + rumble_enabled = (force_rumble == FEAT_ENABLE); + if (force_flash_size != FEAT_AUTODETECT) + flash_bank_cnt = force_flash_size; + + return 0; } s32 load_bios(char *name) diff --git a/gba_memory.h b/gba_memory.h index c97e77f0..6cd3838d 100644 --- a/gba_memory.h +++ b/gba_memory.h @@ -246,7 +246,8 @@ extern char gamepak_filename[512]; cpu_alert_type dma_transfer(unsigned dma_chan, int *cycles); u8 *memory_region(u32 address, u32 *memory_limit); u32 load_gamepak(const struct retro_game_info* info, const char *name, - int force_rtc, int force_rumble, int force_serial); + int force_rtc, int force_rumble, int force_serial, + int force_flash_size); s32 load_bios(char *name); void init_memory(void); void init_gamepak_buffer(void); diff --git a/libretro/libretro.c b/libretro/libretro.c index 6afa60dd..ad958434 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -94,6 +94,7 @@ int sprite_limit = 1; static int rtc_mode = FEAT_AUTODETECT; static int rumble_mode = FEAT_AUTODETECT; +static int flash_size_setting = FEAT_AUTODETECT; static int serial_setting = SERIAL_MODE_AUTO; u32 idle_loop_target_pc = 0xFFFFFFFF; @@ -905,6 +906,18 @@ static void check_variables(bool started_from_load) else rumble_mode = FEAT_AUTODETECT; } + + var.key = "gpsp_flash_size"; + var.value = 0; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (!strcmp(var.value, "64kb")) + flash_size_setting = FLASH_SIZE_64KB; + else if (!strcmp(var.value, "128kb")) + flash_size_setting = FLASH_SIZE_128KB; + else + flash_size_setting = FEAT_AUTODETECT; + } } var.key = "gpsp_sprlim"; @@ -1108,7 +1121,7 @@ bool retro_load_game(const struct retro_game_info* info) } memset(gamepak_backup, 0xff, sizeof(gamepak_backup)); - if (load_gamepak(info, info->path, rtc_mode, rumble_mode, serial_setting) != 0) + if (load_gamepak(info, info->path, rtc_mode, rumble_mode, serial_setting, flash_size_setting) != 0) { error_msg("Could not load the game file."); return false; diff --git a/libretro/libretro_core_options.h b/libretro/libretro_core_options.h index 098db767..ffe68cf3 100644 --- a/libretro/libretro_core_options.h +++ b/libretro/libretro_core_options.h @@ -136,6 +136,18 @@ struct retro_core_option_definition option_defs_us[] = { }, "auto" }, + { + "gpsp_flash_size", + "Save flash size", + "Sets the size of the flash memory for the emulated cartridge. Autodetect uses a ROM database that works with most commercial titles. You might want to force a particular size when using homebrew or ROM hacks that support or require it.", + { + { "auto", NULL }, + { "64kb", NULL }, + { "128kb", NULL }, + { NULL, NULL }, + }, + "auto" + }, { "gpsp_frameskip", "Frameskip",