Merge pull request #114 from davidgfnet/master

Adding Normmatt's BIOS as a built-in BIOS
This commit is contained in:
Autechre 2021-03-22 22:18:13 +01:00 committed by GitHub
commit f3ce8bbd0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 147 additions and 25 deletions

View File

@ -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

7
bios/README.md Normal file
View File

@ -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)

BIN
bios/open_gba_bios.bin Normal file

Binary file not shown.

7
bios_data.S Normal file
View File

@ -0,0 +1,7 @@
.globl open_gba_bios_rom
.data
open_gba_bios_rom:
.incbin "bios/open_gba_bios.bin"

18
cpu.c
View File

@ -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;

View File

@ -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];

View File

@ -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)

View File

@ -53,6 +53,29 @@ extern "C" {
* frontend language definition */
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",

14
main.h
View File

@ -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);