Let the core handle boot ROM selection

This commit is contained in:
Lior Halphon 2020-01-29 20:29:30 +02:00
parent 99d2c0258c
commit 48d3504de7
4 changed files with 92 additions and 20 deletions

View File

@ -74,8 +74,15 @@ enum model {
topMargin:(unsigned) topMargin bottomMargin: (unsigned) bottomMargin
exposure:(unsigned) exposure;
- (void) gotNewSample:(GB_sample_t *)sample;
- (void) loadBootROM:(GB_boot_rom_t)type;
@end
static void boot_rom_load(GB_gameboy_t *gb, GB_boot_rom_t type)
{
Document *self = (__bridge Document *)GB_get_user_data(gb);
[self loadBootROM: type];
}
static void vblank(GB_gameboy_t *gb)
{
Document *self = (__bridge Document *)GB_get_user_data(gb);
@ -209,6 +216,7 @@ static void audioCallback(GB_gameboy_t *gb, GB_sample_t *sample)
{
GB_init(&gb, [self internalModel]);
GB_set_user_data(&gb, (__bridge void *)(self));
GB_set_boot_rom_load_callback(&gb, (GB_boot_rom_load_callback_t)boot_rom_load);
GB_set_vblank_callback(&gb, (GB_vblank_callback_t) vblank);
GB_set_log_callback(&gb, (GB_log_callback_t) consoleLog);
GB_set_input_callback(&gb, (GB_input_callback_t) consoleInput);
@ -340,15 +348,19 @@ static void audioCallback(GB_gameboy_t *gb, GB_sample_t *sample)
GB_debugger_set_disabled(&gb, false);
}
- (void) loadBootROM
- (void) loadBootROM: (GB_boot_rom_t)type
{
static NSString * const boot_names[] = {@"dmg_boot", @"cgb_boot", @"agb_boot", @"sgb_boot"};
if ([self internalModel] == GB_MODEL_SGB2) {
GB_load_boot_rom(&gb, [[self bootROMPathForName:@"sgb2_boot"] UTF8String]);
}
else {
GB_load_boot_rom(&gb, [[self bootROMPathForName:boot_names[current_model - 1]] UTF8String]);
}
static NSString *const names[] = {
[GB_BOOT_ROM_DMG0] = @"dmg0_boot",
[GB_BOOT_ROM_DMG] = @"dmg_boot",
[GB_BOOT_ROM_MGB] = @"mgb_boot",
[GB_BOOT_ROM_SGB] = @"sgb_boot",
[GB_BOOT_ROM_SGB2] = @"sgb2_boot",
[GB_BOOT_ROM_CGB0] = @"cgb0_boot",
[GB_BOOT_ROM_CGB] = @"cgb_boot",
[GB_BOOT_ROM_AGB] = @"agb_boot",
};
GB_load_boot_rom(&gb, [[self bootROMPathForName:names[type]] UTF8String]);
}
- (IBAction)reset:(id)sender
@ -360,8 +372,6 @@ static void audioCallback(GB_gameboy_t *gb, GB_sample_t *sample)
current_model = (enum model)[sender tag];
}
[self loadBootROM];
if (!modelsChanging && [sender tag] == MODEL_NONE) {
GB_reset(&gb);
}

View File

@ -878,6 +878,36 @@ static void reset_ram(GB_gameboy_t *gb)
}
}
static void request_boot_rom(GB_gameboy_t *gb)
{
if (gb->boot_rom_load_callback) {
GB_boot_rom_t type = 0;
switch (gb->model) {
case GB_MODEL_DMG_B:
type = GB_BOOT_ROM_DMG;
break;
case GB_MODEL_SGB_NTSC:
case GB_MODEL_SGB_PAL:
case GB_MODEL_SGB_NTSC_NO_SFC:
case GB_MODEL_SGB_PAL_NO_SFC:
type = GB_BOOT_ROM_SGB;
break;
case GB_MODEL_SGB2:
case GB_MODEL_SGB2_NO_SFC:
type = GB_BOOT_ROM_SGB2;
break;
case GB_MODEL_CGB_C:
case GB_MODEL_CGB_E:
type = GB_BOOT_ROM_CGB;
break;
case GB_MODEL_AGB:
type = GB_BOOT_ROM_AGB;
break;
}
gb->boot_rom_load_callback(gb, type);
}
}
void GB_reset(GB_gameboy_t *gb)
{
uint32_t mbc_ram_size = gb->mbc_ram_size;
@ -948,6 +978,7 @@ void GB_reset(GB_gameboy_t *gb)
}
gb->magic = state_magic();
request_boot_rom(gb);
}
void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model)
@ -1093,3 +1124,9 @@ void GB_set_icd_vreset_callback(GB_gameboy_t *gb, GB_icd_vreset_callback_t callb
{
gb->icd_vreset_callback = callback;
}
void GB_set_boot_rom_load_callback(GB_gameboy_t *gb, GB_boot_rom_load_callback_t callback)
{
gb->boot_rom_load_callback = callback;
request_boot_rom(gb);
}

View File

@ -229,6 +229,17 @@ typedef enum {
GB_LOG_UNDERLINE_MASK = GB_LOG_DASHED_UNDERLINE | GB_LOG_UNDERLINE
} GB_log_attributes;
typedef enum {
GB_BOOT_ROM_DMG0,
GB_BOOT_ROM_DMG,
GB_BOOT_ROM_MGB,
GB_BOOT_ROM_SGB,
GB_BOOT_ROM_SGB2,
GB_BOOT_ROM_CGB0,
GB_BOOT_ROM_CGB,
GB_BOOT_ROM_AGB,
} GB_boot_rom_t;
#ifdef GB_INTERNAL
#define LCDC_PERIOD 70224
#define CPU_FREQUENCY 0x400000
@ -259,6 +270,7 @@ typedef void (*GB_joyp_write_callback_t)(GB_gameboy_t *gb, uint8_t value);
typedef void (*GB_icd_pixel_callback_t)(GB_gameboy_t *gb, uint8_t row);
typedef void (*GB_icd_hreset_callback_t)(GB_gameboy_t *gb);
typedef void (*GB_icd_vreset_callback_t)(GB_gameboy_t *gb);
typedef void (*GB_boot_rom_load_callback_t)(GB_gameboy_t *gb, GB_boot_rom_t type);
typedef struct {
bool state;
@ -553,6 +565,7 @@ struct GB_gameboy_internal_s {
GB_icd_vreset_callback_t icd_hreset_callback;
GB_icd_vreset_callback_t icd_vreset_callback;
GB_read_memory_callback_t read_memory_callback;
GB_boot_rom_load_callback_t boot_rom_load_callback;
/* IR */
long cycles_since_ir_change; // In 8MHz units
@ -706,6 +719,8 @@ void GB_set_rgb_encode_callback(GB_gameboy_t *gb, GB_rgb_encode_callback_t callb
void GB_set_infrared_callback(GB_gameboy_t *gb, GB_infrared_callback_t callback);
void GB_set_rumble_callback(GB_gameboy_t *gb, GB_rumble_callback_t callback);
void GB_set_update_input_hint_callback(GB_gameboy_t *gb, GB_update_input_hint_callback_t callback);
/* Called when a new boot ROM is needed. The callback should call GB_load_boot_rom or GB_load_boot_rom_from_buffer */
void GB_set_boot_rom_load_callback(GB_gameboy_t *gb, GB_boot_rom_load_callback_t callback);
void GB_set_palette(GB_gameboy_t *gb, const GB_palette_t *palette);

View File

@ -445,6 +445,24 @@ static bool handle_pending_command(void)
return false;
}
static void load_boot_rom(GB_gameboy_t *gb, GB_boot_rom_t type)
{
bool error = false;
start_capturing_logs();
static const char *const names[] = {
[GB_BOOT_ROM_DMG0] = "dmg0_boot.bin",
[GB_BOOT_ROM_DMG] = "dmg_boot.bin",
[GB_BOOT_ROM_MGB] = "mgb_boot.bin",
[GB_BOOT_ROM_SGB] = "sgb_boot.bin",
[GB_BOOT_ROM_SGB2] = "sgb2_boot.bin",
[GB_BOOT_ROM_CGB0] = "cgb0_boot.bin",
[GB_BOOT_ROM_CGB] = "cgb_boot.bin",
[GB_BOOT_ROM_AGB] = "agb_boot.bin",
};
GB_load_boot_rom(gb, resource_path(names[type]));
end_capturing_logs(true, error);
}
static void run(void)
{
SDL_ShowCursor(SDL_DISABLE);
@ -470,6 +488,7 @@ restart:
else {
GB_init(&gb, model);
GB_set_boot_rom_load_callback(&gb, load_boot_rom);
GB_set_vblank_callback(&gb, (GB_vblank_callback_t) vblank);
GB_set_pixels_output(&gb, active_pixel_buffer);
GB_set_rgb_encode_callback(&gb, rgb_encode);
@ -490,15 +509,6 @@ restart:
bool error = false;
start_capturing_logs();
const char * const boot_roms[] = {"dmg_boot.bin", "cgb_boot.bin", "agb_boot.bin", "sgb_boot.bin"};
const char *boot_rom = boot_roms[configuration.model];
if (configuration.model == MODEL_SGB && configuration.sgb_revision == SGB_2) {
boot_rom = "sgb2_boot.bin";
}
error = GB_load_boot_rom(&gb, resource_path(boot_rom));
end_capturing_logs(true, error);
start_capturing_logs();
error = GB_load_rom(&gb, filename);
end_capturing_logs(true, error);