Merge pull request #114 from davidgfnet/master
Adding Normmatt's BIOS as a built-in BIOS
This commit is contained in:
commit
f3ce8bbd0c
|
@ -1,6 +1,6 @@
|
||||||
INCFLAGS := -I$(CORE_DIR)/libretro -I$(CORE_DIR)/src
|
INCFLAGS := -I$(CORE_DIR)/libretro -I$(CORE_DIR)/src
|
||||||
|
|
||||||
SOURCES_ASM :=
|
SOURCES_ASM := $(CORE_DIR)/bios_data.S
|
||||||
|
|
||||||
ifeq ($(HAVE_GRIFFIN), 1)
|
ifeq ($(HAVE_GRIFFIN), 1)
|
||||||
SOURCES_C := $(CORE_DIR)/gpsp_griffin.c
|
SOURCES_C := $(CORE_DIR)/gpsp_griffin.c
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
.globl open_gba_bios_rom
|
||||||
|
|
||||||
|
.data
|
||||||
|
open_gba_bios_rom:
|
||||||
|
.incbin "bios/open_gba_bios.bin"
|
||||||
|
|
18
cpu.c
18
cpu.c
|
@ -4297,13 +4297,23 @@ void init_cpu(void)
|
||||||
for(i = 0; i < 16; i++)
|
for(i = 0; i < 16; i++)
|
||||||
reg[i] = 0;
|
reg[i] = 0;
|
||||||
|
|
||||||
reg[REG_SP] = 0x03007F00;
|
|
||||||
reg[REG_PC] = 0x08000000;
|
|
||||||
reg[REG_CPSR] = 0x0000001F;
|
|
||||||
reg[CPU_HALT_STATE] = CPU_ACTIVE;
|
reg[CPU_HALT_STATE] = CPU_ACTIVE;
|
||||||
reg[CPU_MODE] = MODE_USER;
|
|
||||||
reg[CHANGED_PC_STATUS] = 0;
|
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_USER][5] = 0x03007F00;
|
||||||
reg_mode[MODE_IRQ][5] = 0x03007FA0;
|
reg_mode[MODE_IRQ][5] = 0x03007FA0;
|
||||||
reg_mode[MODE_FIQ][5] = 0x03007FA0;
|
reg_mode[MODE_FIQ][5] = 0x03007FA0;
|
||||||
|
|
|
@ -201,6 +201,7 @@ extern u32 gbc_sound_update;
|
||||||
extern u32 gbc_sound_wave_update;
|
extern u32 gbc_sound_wave_update;
|
||||||
extern dma_transfer_type dma[4];
|
extern dma_transfer_type dma[4];
|
||||||
|
|
||||||
|
extern u8 open_gba_bios_rom[1024*16];
|
||||||
extern u32 bios_read_protect;
|
extern u32 bios_read_protect;
|
||||||
extern u16 palette_ram[512];
|
extern u16 palette_ram[512];
|
||||||
extern u16 oam_ram[512];
|
extern u16 oam_ram[512];
|
||||||
|
|
100
libretro.c
100
libretro.c
|
@ -65,6 +65,7 @@ static unsigned audio_buff_occupancy = 0;
|
||||||
static bool audio_buff_underrun = false;
|
static bool audio_buff_underrun = false;
|
||||||
static unsigned audio_latency = 0;
|
static unsigned audio_latency = 0;
|
||||||
static bool update_audio_latency = false;
|
static bool update_audio_latency = false;
|
||||||
|
static bios_type selected_bios = auto_detect;
|
||||||
|
|
||||||
static retro_log_printf_t log_cb;
|
static retro_log_printf_t log_cb;
|
||||||
static retro_video_refresh_t video_cb;
|
static retro_video_refresh_t video_cb;
|
||||||
|
@ -75,6 +76,7 @@ struct retro_perf_callback perf_cb;
|
||||||
|
|
||||||
int dynarec_enable;
|
int dynarec_enable;
|
||||||
int use_libretro_save_method = 0;
|
int use_libretro_save_method = 0;
|
||||||
|
boot_mode selected_boot_mode = boot_game;
|
||||||
|
|
||||||
u32 idle_loop_target_pc = 0xFFFFFFFF;
|
u32 idle_loop_target_pc = 0xFFFFFFFF;
|
||||||
u32 iwram_stack_optimize = 1;
|
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);
|
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 */
|
/* Frameskip START */
|
||||||
|
|
||||||
static void audio_buff_status_cb(
|
static void audio_buff_status_cb(
|
||||||
|
@ -348,8 +369,8 @@ static void video_run(void)
|
||||||
sceGuTexMode(GU_PSM_5650, 0, 0, GU_FALSE);
|
sceGuTexMode(GU_PSM_5650, 0, 0, GU_FALSE);
|
||||||
sceGuCopyImage(GU_PSM_5650, 0, 0, GBA_SCREEN_WIDTH, GBA_SCREEN_HEIGHT, GBA_SCREEN_WIDTH,
|
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);
|
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);
|
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);
|
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
|
||||||
sceGuDisable(GU_BLEND);
|
sceGuDisable(GU_BLEND);
|
||||||
|
|
||||||
sceGuFinish();
|
sceGuFinish();
|
||||||
|
@ -484,6 +505,8 @@ void retro_init(void)
|
||||||
audio_buff_underrun = false;
|
audio_buff_underrun = false;
|
||||||
audio_latency = 0;
|
audio_latency = 0;
|
||||||
update_audio_latency = false;
|
update_audio_latency = false;
|
||||||
|
selected_bios = auto_detect;
|
||||||
|
selected_boot_mode = boot_game;
|
||||||
}
|
}
|
||||||
|
|
||||||
void retro_deinit(void)
|
void retro_deinit(void)
|
||||||
|
@ -660,6 +683,32 @@ static void check_variables(int started_from_load)
|
||||||
dynarec_enable = 0;
|
dynarec_enable = 0;
|
||||||
#endif
|
#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.key = "gpsp_frameskip";
|
||||||
var.value = 0;
|
var.value = 0;
|
||||||
frameskip_type_prev = current_frameskip_type;
|
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));
|
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)
|
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
|
||||||
strcpy(save_path, dir);
|
strcpy(save_path, dir);
|
||||||
else
|
else
|
||||||
strcpy(save_path, main_path);
|
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.");
|
bios_loaded = true;
|
||||||
return false;
|
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)
|
if (!bios_loaded) {
|
||||||
{
|
/* Load the built-in BIOS */
|
||||||
info_msg("You have an incorrect BIOS image.");
|
memcpy(bios_rom, open_gba_bios_rom, sizeof(bios_rom));
|
||||||
info_msg("While many games will work fine, some will not.");
|
|
||||||
info_msg("It is strongly recommended that you obtain the correct BIOS file.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(gamepak_backup, -1, sizeof(gamepak_backup));
|
memset(gamepak_backup, -1, sizeof(gamepak_backup));
|
||||||
|
@ -921,8 +981,8 @@ void retro_run(void)
|
||||||
|
|
||||||
input_poll_cb();
|
input_poll_cb();
|
||||||
|
|
||||||
/* Check whether current frame should
|
/* Check whether current frame should
|
||||||
* be skipped */
|
* be skipped */
|
||||||
skip_next_frame = 0;
|
skip_next_frame = 0;
|
||||||
|
|
||||||
if (current_frameskip_type != no_frameskip)
|
if (current_frameskip_type != no_frameskip)
|
||||||
|
|
|
@ -53,6 +53,29 @@ extern "C" {
|
||||||
* frontend language definition */
|
* frontend language definition */
|
||||||
|
|
||||||
struct retro_core_option_definition option_defs_us[] = {
|
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",
|
"gpsp_frameskip",
|
||||||
"Frameskip",
|
"Frameskip",
|
||||||
|
|
14
main.h
14
main.h
|
@ -64,6 +64,19 @@ typedef enum
|
||||||
fixed_interval_frameskip
|
fixed_interval_frameskip
|
||||||
} frameskip_type;
|
} 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 cpu_ticks;
|
||||||
extern u32 execute_cycles;
|
extern u32 execute_cycles;
|
||||||
extern u32 global_cycles_per_instruction;
|
extern u32 global_cycles_per_instruction;
|
||||||
|
@ -98,6 +111,7 @@ u32 file_length(FILE *fp);
|
||||||
|
|
||||||
extern u32 num_skipped_frames;
|
extern u32 num_skipped_frames;
|
||||||
extern int dynarec_enable;
|
extern int dynarec_enable;
|
||||||
|
extern boot_mode selected_boot_mode;
|
||||||
|
|
||||||
void change_ext(const char *src, char *buffer, const char *extension);
|
void change_ext(const char *src, char *buffer, const char *extension);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue