summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutechre2021-03-22 22:18:13 +0100
committerGitHub2021-03-22 22:18:13 +0100
commitf3ce8bbd0c0a660488a9d193fe86f15209dc8b68 (patch)
treecd043bd5458cec7152794af6b14ff5274020b6a0
parent5ef784ab8af08b9629b573b3cfd25f21384771af (diff)
parentf6f3a910397afb769f84d1332014c4eda1fedebe (diff)
downloadpicogpsp-f3ce8bbd0c0a660488a9d193fe86f15209dc8b68.tar.gz
picogpsp-f3ce8bbd0c0a660488a9d193fe86f15209dc8b68.tar.bz2
picogpsp-f3ce8bbd0c0a660488a9d193fe86f15209dc8b68.zip
Merge pull request #114 from davidgfnet/master
Adding Normmatt's BIOS as a built-in BIOS
-rw-r--r--Makefile.common2
-rw-r--r--bios/README.md7
-rw-r--r--bios/open_gba_bios.binbin0 -> 16384 bytes
-rw-r--r--bios_data.S7
-rw-r--r--cpu.c18
-rw-r--r--gba_memory.h1
-rw-r--r--libretro.c100
-rw-r--r--libretro_core_options.h23
-rw-r--r--main.h14
9 files changed, 147 insertions, 25 deletions
diff --git a/Makefile.common b/Makefile.common
index 7e70627..0dcbedc 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1,6 +1,6 @@
INCFLAGS := -I$(CORE_DIR)/libretro -I$(CORE_DIR)/src
-SOURCES_ASM :=
+SOURCES_ASM := $(CORE_DIR)/bios_data.S
ifeq ($(HAVE_GRIFFIN), 1)
SOURCES_C := $(CORE_DIR)/gpsp_griffin.c
diff --git a/bios/README.md b/bios/README.md
new file mode 100644
index 0000000..64d6679
--- /dev/null
+++ b/bios/README.md
@@ -0,0 +1,7 @@
+
+This BIOS is an open source replacement for Nintendo's official BIOS.
+It was written originally by Normmatt and the VBA/VBA-M team, and its source
+code can be found at https://github.com/Nebuleon/ReGBA/tree/master/bios
+
+It is distributed under the GPL2 license (see repo)
+
diff --git a/bios/open_gba_bios.bin b/bios/open_gba_bios.bin
new file mode 100644
index 0000000..802982e
--- /dev/null
+++ b/bios/open_gba_bios.bin
Binary files differ
diff --git a/bios_data.S b/bios_data.S
new file mode 100644
index 0000000..9de9d8a
--- /dev/null
+++ b/bios_data.S
@@ -0,0 +1,7 @@
+
+.globl open_gba_bios_rom
+
+.data
+open_gba_bios_rom:
+ .incbin "bios/open_gba_bios.bin"
+
diff --git a/cpu.c b/cpu.c
index 2c93f38..11c947f 100644
--- a/cpu.c
+++ b/cpu.c
@@ -4297,13 +4297,23 @@ void init_cpu(void)
for(i = 0; i < 16; i++)
reg[i] = 0;
- reg[REG_SP] = 0x03007F00;
- reg[REG_PC] = 0x08000000;
- reg[REG_CPSR] = 0x0000001F;
reg[CPU_HALT_STATE] = CPU_ACTIVE;
- reg[CPU_MODE] = MODE_USER;
reg[CHANGED_PC_STATUS] = 0;
+ if (selected_boot_mode == boot_game) {
+ reg[REG_SP] = 0x03007F00;
+ reg[REG_PC] = 0x08000000;
+ reg[REG_CPSR] = 0x0000001F; // system mode
+ reg[CPU_MODE] = MODE_USER;
+ } else {
+ reg[REG_SP] = 0x03007F00;
+ reg[REG_PC] = 0x00000000;
+ reg[REG_CPSR] = 0x00000013 | 0xC0; // supervisor
+ reg[CPU_MODE] = MODE_SUPERVISOR;
+ }
+
+ // Stack pointers are set by BIOS, we set them
+ // nevertheless, should we not boot from BIOS
reg_mode[MODE_USER][5] = 0x03007F00;
reg_mode[MODE_IRQ][5] = 0x03007FA0;
reg_mode[MODE_FIQ][5] = 0x03007FA0;
diff --git a/gba_memory.h b/gba_memory.h
index 9352e88..eaa5bab 100644
--- a/gba_memory.h
+++ b/gba_memory.h
@@ -201,6 +201,7 @@ extern u32 gbc_sound_update;
extern u32 gbc_sound_wave_update;
extern dma_transfer_type dma[4];
+extern u8 open_gba_bios_rom[1024*16];
extern u32 bios_read_protect;
extern u16 palette_ram[512];
extern u16 oam_ram[512];
diff --git a/libretro.c b/libretro.c
index bc61977..334864c 100644
--- a/libretro.c
+++ b/libretro.c
@@ -65,6 +65,7 @@ static unsigned audio_buff_occupancy = 0;
static bool audio_buff_underrun = false;
static unsigned audio_latency = 0;
static bool update_audio_latency = false;
+static bios_type selected_bios = auto_detect;
static retro_log_printf_t log_cb;
static retro_video_refresh_t video_cb;
@@ -75,6 +76,7 @@ struct retro_perf_callback perf_cb;
int dynarec_enable;
int use_libretro_save_method = 0;
+boot_mode selected_boot_mode = boot_game;
u32 idle_loop_target_pc = 0xFFFFFFFF;
u32 iwram_stack_optimize = 1;
@@ -114,6 +116,25 @@ static void info_msg(const char* text)
log_cb(RETRO_LOG_INFO, "[gpSP]: %s\n", text);
}
+static void show_warning_message(const char* text, unsigned durationms) {
+ unsigned ifversion = 0;
+ if (!environ_cb(RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION, &ifversion) || ifversion >= 1) {
+ /* Use the new API to display messages */
+ struct retro_message_ext msg = {
+ .msg = text, .duration = durationms,
+ .priority = 2, .level = RETRO_LOG_WARN,
+ .target = RETRO_MESSAGE_TARGET_ALL,
+ .type = RETRO_MESSAGE_TYPE_NOTIFICATION,
+ .progress = -1,
+ };
+ environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg);
+ }
+ else {
+ struct retro_message msg = {.msg = text, .frames = durationms / 17};
+ environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
+ }
+}
+
/* Frameskip START */
static void audio_buff_status_cb(
@@ -348,8 +369,8 @@ static void video_run(void)
sceGuTexMode(GU_PSM_5650, 0, 0, GU_FALSE);
sceGuCopyImage(GU_PSM_5650, 0, 0, GBA_SCREEN_WIDTH, GBA_SCREEN_HEIGHT, GBA_SCREEN_WIDTH,
gba_screen_pixels_buf, 0, 0, GBA_SCREEN_WIDTH, texture_vram_p);
- sceGuTexImage(0, next_pow2(GBA_SCREEN_WIDTH), next_pow2(GBA_SCREEN_HEIGHT), GBA_SCREEN_WIDTH, texture_vram_p);
- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
+ sceGuTexImage(0, next_pow2(GBA_SCREEN_WIDTH), next_pow2(GBA_SCREEN_HEIGHT), GBA_SCREEN_WIDTH, texture_vram_p);
+ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
sceGuDisable(GU_BLEND);
sceGuFinish();
@@ -484,6 +505,8 @@ void retro_init(void)
audio_buff_underrun = false;
audio_latency = 0;
update_audio_latency = false;
+ selected_bios = auto_detect;
+ selected_boot_mode = boot_game;
}
void retro_deinit(void)
@@ -660,6 +683,32 @@ static void check_variables(int started_from_load)
dynarec_enable = 0;
#endif
+ if (started_from_load) {
+ var.key = "gpsp_bios";
+ var.value = 0;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (!strcmp(var.value, "auto"))
+ selected_bios = auto_detect;
+ else if (!strcmp(var.value, "builtin"))
+ selected_bios = builtin_bios;
+ else if (!strcmp(var.value, "official"))
+ selected_bios = official_bios;
+ }
+
+ var.key = "gpsp_boot_mode";
+ var.value = 0;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (!strcmp(var.value, "game"))
+ selected_boot_mode = boot_game;
+ else if (!strcmp(var.value, "bios"))
+ selected_boot_mode = boot_bios;
+ }
+ }
+
var.key = "gpsp_frameskip";
var.value = 0;
frameskip_type_prev = current_frameskip_type;
@@ -795,30 +844,41 @@ bool retro_load_game(const struct retro_game_info* info)
extract_directory(main_path, info->path, sizeof(main_path));
- if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
- strcpy(filename_bios, dir);
- else
- strcpy(filename_bios, main_path);
-
- strcat(filename_bios, "/gba_bios.bin");
-
-
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
strcpy(save_path, dir);
else
strcpy(save_path, main_path);
- if (load_bios(filename_bios) != 0)
+ if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
+ strcpy(filename_bios, dir);
+ else
+ strcpy(filename_bios, main_path);
+
+ bool bios_loaded = false;
+ printf("USE %d\n", (int)selected_bios);
+ if (selected_bios == auto_detect || selected_bios == official_bios)
{
- error_msg("Could not load BIOS image file.");
- return false;
+ bios_loaded = true;
+ strcat(filename_bios, "/gba_bios.bin");
+
+ if (load_bios(filename_bios) != 0)
+ {
+ if (selected_bios == official_bios)
+ show_warning_message("Could not load BIOS image file, using built-in BIOS", 2500);
+ bios_loaded = false;
+ }
+
+ if (bios_loaded && bios_rom[0] != 0x18)
+ {
+ if (selected_bios == official_bios)
+ show_warning_message("BIOS image seems incorrect, using built-in BIOS", 2500);
+ bios_loaded = false;
+ }
}
- if (bios_rom[0] != 0x18)
- {
- info_msg("You have an incorrect BIOS image.");
- info_msg("While many games will work fine, some will not.");
- info_msg("It is strongly recommended that you obtain the correct BIOS file.");
+ if (!bios_loaded) {
+ /* Load the built-in BIOS */
+ memcpy(bios_rom, open_gba_bios_rom, sizeof(bios_rom));
}
memset(gamepak_backup, -1, sizeof(gamepak_backup));
@@ -921,8 +981,8 @@ void retro_run(void)
input_poll_cb();
- /* Check whether current frame should
- * be skipped */
+ /* Check whether current frame should
+ * be skipped */
skip_next_frame = 0;
if (current_frameskip_type != no_frameskip)
diff --git a/libretro_core_options.h b/libretro_core_options.h
index b5b138d..d2b95fa 100644
--- a/libretro_core_options.h
+++ b/libretro_core_options.h
@@ -54,6 +54,29 @@ extern "C" {
struct retro_core_option_definition option_defs_us[] = {
{
+ "gpsp_bios",
+ "BIOS",
+ "Choose the BIOS image to use. The official BIOS must be provided by the user. Using a non-official (or builtin) BIOS might result in incompatibility problems with some games. Best results are to be achieved with the official Nintendo BIOS.",
+ {
+ { "auto", "Auto select" },
+ { "builtin", "Builtin BIOS" },
+ { "official", "Original BIOS" },
+ { NULL, NULL },
+ },
+ "auto"
+ },
+ {
+ "gpsp_boot_mode",
+ "Boot mode",
+ "Choose whether to boot the BIOS before the game or not. There's not much difference in either modes.",
+ {
+ { "game", "Boot to game" },
+ { "bios", "Boot to BIOS" },
+ { NULL, NULL },
+ },
+ "game"
+ },
+ {
"gpsp_frameskip",
"Frameskip",
"Skip frames to avoid audio buffer under-run (crackling). Improves performance at the expense of visual smoothness. 'Auto' skips frames when advised by the frontend. 'Auto (Threshold)' utilises the 'Frameskip Threshold (%)' setting. 'Fixed Interval' utilises the 'Frameskip Interval' setting.",
diff --git a/main.h b/main.h
index dbb839f..bdb29e3 100644
--- a/main.h
+++ b/main.h
@@ -64,6 +64,19 @@ typedef enum
fixed_interval_frameskip
} frameskip_type;
+typedef enum
+{
+ auto_detect = 0,
+ builtin_bios,
+ official_bios
+} bios_type;
+
+typedef enum
+{
+ boot_game = 0,
+ boot_bios
+} boot_mode;
+
extern u32 cpu_ticks;
extern u32 execute_cycles;
extern u32 global_cycles_per_instruction;
@@ -98,6 +111,7 @@ u32 file_length(FILE *fp);
extern u32 num_skipped_frames;
extern int dynarec_enable;
+extern boot_mode selected_boot_mode;
void change_ext(const char *src, char *buffer, const char *extension);