mirror of https://github.com/LIJI32/SameBoy.git
Add quick reset API (Closes #506)
This commit is contained in:
parent
9b202c670e
commit
5d5ff1702e
|
@ -53,6 +53,8 @@ enum model {
|
|||
MODEL_AGB,
|
||||
MODEL_SGB,
|
||||
MODEL_MGB,
|
||||
|
||||
MODEL_QUICK_RESET = -1,
|
||||
};
|
||||
|
||||
@interface Document ()
|
||||
|
@ -253,6 +255,7 @@ static void infraredStateChanged(GB_gameboy_t *gb, bool on)
|
|||
return (GB_model_t)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBDMGModel"];
|
||||
|
||||
case MODEL_NONE:
|
||||
case MODEL_QUICK_RESET:
|
||||
case MODEL_CGB:
|
||||
return (GB_model_t)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBCGBModel"];
|
||||
|
||||
|
@ -623,7 +626,12 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
current_model = (enum model)[sender tag];
|
||||
}
|
||||
|
||||
GB_switch_model_and_reset(&gb, [self internalModel]);
|
||||
if ([sender tag] == MODEL_QUICK_RESET) {
|
||||
GB_quick_reset(&gb);
|
||||
}
|
||||
else {
|
||||
GB_switch_model_and_reset(&gb, [self internalModel]);
|
||||
}
|
||||
|
||||
if (old_width != GB_get_screen_width(&gb)) {
|
||||
[self.view screenSizeChanged];
|
||||
|
@ -631,7 +639,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
|
||||
[self updateMinSize];
|
||||
|
||||
if ([sender tag] != 0) {
|
||||
if ([sender tag] > MODEL_NONE) {
|
||||
/* User explictly selected a model, save the preference */
|
||||
[[NSUserDefaults standardUserDefaults] setBool:current_model == MODEL_DMG forKey:@"EmulateDMG"];
|
||||
[[NSUserDefaults standardUserDefaults] setBool:current_model == MODEL_SGB forKey:@"EmulateSGB"];
|
||||
|
@ -1176,7 +1184,7 @@ static bool is_path_writeable(const char *path)
|
|||
[(NSMenuItem *)anItem setState:self.isPaused];
|
||||
return !GB_debugger_is_stopped(&gb);
|
||||
}
|
||||
else if ([anItem action] == @selector(reset:) && anItem.tag != MODEL_NONE) {
|
||||
else if ([anItem action] == @selector(reset:) && anItem.tag != MODEL_NONE && anItem.tag != MODEL_QUICK_RESET) {
|
||||
[(NSMenuItem *)anItem setState:anItem.tag == current_model];
|
||||
}
|
||||
else if ([anItem action] == @selector(interrupt:)) {
|
||||
|
|
|
@ -202,6 +202,12 @@
|
|||
<action selector="reset:" target="-1" id="DKW-Bd-h3v"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Quick Reset" tag="-1" alternate="YES" keyEquivalent="r" id="uPG-01-49E">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="reset:" target="-1" id="VV1-VP-L7g"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Pause" keyEquivalent="p" id="4K4-hw-R7Q">
|
||||
<connections>
|
||||
<action selector="togglePause:" target="-1" id="osW-wt-QAa"/>
|
||||
|
|
59
Core/gb.c
59
Core/gb.c
|
@ -1604,6 +1604,10 @@ static void reset_ram(GB_gameboy_t *gb)
|
|||
GB_palette_changed(gb, false, i * 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gb->cartridge_type->has_battery) {
|
||||
memset(gb->mbc_ram, 0xFF, gb->mbc_ram_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void request_boot_rom(GB_gameboy_t *gb)
|
||||
|
@ -1646,8 +1650,29 @@ static void request_boot_rom(GB_gameboy_t *gb)
|
|||
}
|
||||
}
|
||||
|
||||
void GB_reset(GB_gameboy_t *gb)
|
||||
static void GB_reset_internal(GB_gameboy_t *gb, bool quick)
|
||||
{
|
||||
struct {
|
||||
uint8_t hram[sizeof(gb->hram)];
|
||||
uint8_t background_palettes_data[sizeof(gb->background_palettes_data)];
|
||||
uint8_t object_palettes_data[sizeof(gb->object_palettes_data)];
|
||||
uint8_t oam[sizeof(gb->oam)];
|
||||
uint8_t extra_oam[sizeof(gb->extra_oam)];
|
||||
uint8_t dma, obp0, obp1;
|
||||
} *preserved_state = NULL;
|
||||
|
||||
if (quick) {
|
||||
preserved_state = alloca(sizeof(*preserved_state));
|
||||
memcpy(preserved_state->hram, gb->hram, sizeof(gb->hram));
|
||||
memcpy(preserved_state->background_palettes_data, gb->background_palettes_data, sizeof(gb->background_palettes_data));
|
||||
memcpy(preserved_state->object_palettes_data, gb->object_palettes_data, sizeof(gb->object_palettes_data));
|
||||
memcpy(preserved_state->oam, gb->oam, sizeof(gb->oam));
|
||||
memcpy(preserved_state->extra_oam, gb->extra_oam, sizeof(gb->extra_oam));
|
||||
preserved_state->dma = gb->io_registers[GB_IO_DMA];
|
||||
preserved_state->obp0 = gb->io_registers[GB_IO_OBP0];
|
||||
preserved_state->obp1 = gb->io_registers[GB_IO_OBP1];
|
||||
}
|
||||
|
||||
uint32_t mbc_ram_size = gb->mbc_ram_size;
|
||||
GB_model_t model = gb->model;
|
||||
GB_update_clock_rate(gb);
|
||||
|
@ -1679,14 +1704,9 @@ void GB_reset(GB_gameboy_t *gb)
|
|||
|
||||
update_dmg_palette(gb);
|
||||
}
|
||||
reset_ram(gb);
|
||||
|
||||
gb->serial_mask = 0x80;
|
||||
gb->io_registers[GB_IO_SC] = 0x7E;
|
||||
|
||||
/* These are not deterministic, but 00 (CGB) and FF (DMG) are the most common initial values by far */
|
||||
gb->io_registers[GB_IO_DMA] = gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = GB_is_cgb(gb)? 0x00 : 0xFF;
|
||||
|
||||
gb->accessed_oam_row = -1;
|
||||
gb->dma_current_dest = 0xA1;
|
||||
|
||||
|
@ -1718,10 +1738,37 @@ void GB_reset(GB_gameboy_t *gb)
|
|||
gb->nontrivial_jump_state = NULL;
|
||||
}
|
||||
|
||||
if (!quick) {
|
||||
reset_ram(gb);
|
||||
/* These are not deterministic, but 00 (CGB) and FF (DMG) are the most common initial values by far.
|
||||
The retain their previous values on quick resets */
|
||||
gb->io_registers[GB_IO_DMA] = gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = GB_is_cgb(gb)? 0x00 : 0xFF;
|
||||
}
|
||||
else {
|
||||
memcpy(gb->hram, preserved_state->hram, sizeof(gb->hram));
|
||||
memcpy(gb->background_palettes_data, preserved_state->background_palettes_data, sizeof(gb->background_palettes_data));
|
||||
memcpy(gb->object_palettes_data, preserved_state->object_palettes_data, sizeof(gb->object_palettes_data));
|
||||
memcpy(gb->oam, preserved_state->oam, sizeof(gb->oam));
|
||||
memcpy(gb->extra_oam, preserved_state->extra_oam, sizeof(gb->extra_oam));
|
||||
gb->io_registers[GB_IO_DMA] = preserved_state->dma;
|
||||
gb->io_registers[GB_IO_OBP0] = preserved_state->obp0;
|
||||
gb->io_registers[GB_IO_OBP1] = preserved_state->obp1;
|
||||
}
|
||||
|
||||
gb->magic = state_magic();
|
||||
request_boot_rom(gb);
|
||||
}
|
||||
|
||||
void GB_reset(GB_gameboy_t *gb)
|
||||
{
|
||||
GB_reset_internal(gb, false);
|
||||
}
|
||||
|
||||
void GB_quick_reset(GB_gameboy_t *gb)
|
||||
{
|
||||
GB_reset_internal(gb, true);
|
||||
}
|
||||
|
||||
void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model)
|
||||
{
|
||||
gb->model = model;
|
||||
|
|
|
@ -881,6 +881,7 @@ bool GB_is_sgb(GB_gameboy_t *gb); // Returns true if the model is SGB or SGB2
|
|||
bool GB_is_hle_sgb(GB_gameboy_t *gb); // Returns true if the model is SGB or SGB2 and the SFC/SNES side is HLE'd
|
||||
GB_model_t GB_get_model(GB_gameboy_t *gb);
|
||||
void GB_reset(GB_gameboy_t *gb);
|
||||
void GB_quick_reset(GB_gameboy_t *gb); // Similar to the cart reset line
|
||||
void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model);
|
||||
|
||||
/* Returns the time passed, in 8MHz ticks. */
|
||||
|
|
23
Core/mbc.c
23
Core/mbc.c
|
@ -196,12 +196,9 @@ void GB_configure_cart(GB_gameboy_t *gb)
|
|||
}
|
||||
}
|
||||
|
||||
if (gb->mbc_ram) {
|
||||
free(gb->mbc_ram);
|
||||
gb->mbc_ram = NULL;
|
||||
gb->mbc_ram_size = 0;
|
||||
}
|
||||
|
||||
size_t old_mbc_ram_size = gb->mbc_ram_size;
|
||||
gb->mbc_ram_size = 0;
|
||||
|
||||
if (gb->cartridge_type->has_ram) {
|
||||
if (gb->cartridge_type->mbc_type == GB_MBC2) {
|
||||
gb->mbc_ram_size = 0x200;
|
||||
|
@ -224,12 +221,16 @@ void GB_configure_cart(GB_gameboy_t *gb)
|
|||
}
|
||||
}
|
||||
|
||||
if (gb->mbc_ram_size) {
|
||||
gb->mbc_ram = malloc(gb->mbc_ram_size);
|
||||
if (gb->mbc_ram && old_mbc_ram_size != gb->mbc_ram_size) {
|
||||
free(gb->mbc_ram);
|
||||
gb->mbc_ram = NULL;
|
||||
}
|
||||
|
||||
if (gb->mbc_ram_size && !gb->mbc_ram) {
|
||||
gb->mbc_ram = malloc(gb->mbc_ram_size);
|
||||
/* Todo: Some games assume unintialized MBC RAM is 0xFF. It this true for all cartridge types? */
|
||||
memset(gb->mbc_ram, 0xFF, gb->mbc_ram_size);
|
||||
}
|
||||
|
||||
/* Todo: Some games assume unintialized MBC RAM is 0xFF. It this true for all cartridge types? */
|
||||
memset(gb->mbc_ram, 0xFF, gb->mbc_ram_size);
|
||||
}
|
||||
|
||||
/* MBC1 has at least 3 types of wiring (We currently support two (Standard and 4bit-MBC1M) of these).
|
||||
|
|
Loading…
Reference in New Issue