Skip to content

Commit

Permalink
Improve PPU timings in CGB revision 0 to C. These revisions are no lo…
Browse files Browse the repository at this point in the history
…nger marked as experimental.
  • Loading branch information
LIJI32 committed Jul 7, 2024
1 parent a4525c3 commit c3e3fb9
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 99 deletions.
8 changes: 4 additions & 4 deletions Cocoa/Preferences.xib
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,10 @@
<font key="font" metaFont="menu"/>
<menu key="menu" autoenablesItems="NO" id="bbF-hB-Hv7">
<items>
<menuItem title="CPU CGB 0 (Experimental)" tag="512" id="2Uk-u3-6Gw"/>
<menuItem title="CPU CGB A (Experimental)" tag="513" id="axv-yk-RWM"/>
<menuItem title="CPU CGB B (Experimental)" tag="514" id="NtJ-oo-IM2"/>
<menuItem title="CPU CGB C (Experimental)" tag="515" id="9YL-u8-12z"/>
<menuItem title="CPU CGB 0" tag="512" id="2Uk-u3-6Gw"/>
<menuItem title="CPU CGB A" tag="513" id="axv-yk-RWM"/>
<menuItem title="CPU CGB B" tag="514" id="NtJ-oo-IM2"/>
<menuItem title="CPU CGB C" tag="515" id="9YL-u8-12z"/>
<menuItem title="CPU CGB D" tag="516" id="c76-oF-fkU"/>
<menuItem title="CPU CGB E" state="on" tag="517" id="3lF-1Q-2SS"/>
</items>
Expand Down
24 changes: 4 additions & 20 deletions Core/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,6 @@ void GB_STAT_update(GB_gameboy_t *gb)

bool previous_interrupt_line = gb->stat_interrupt_line;
/* Set LY=LYC bit */
/* TODO: This behavior might not be correct for CGB revisions other than C and E */
if (gb->ly_for_comparison != (uint16_t)-1 || gb->model <= GB_MODEL_CGB_C) {
if (gb->ly_for_comparison == gb->io_registers[GB_IO_LYC]) {
gb->lyc_interrupt_line = true;
Expand Down Expand Up @@ -734,11 +733,6 @@ static inline void dma_sync(GB_gameboy_t *gb, unsigned *cycles)
}
}

/* All verified CGB timings are based on CGB CPU E. CGB CPUs >= D are known to have
slightly different timings than CPUs <= C.
Todo: Add support to CPU C and older */

static inline uint8_t fetcher_y(GB_gameboy_t *gb)
{
return gb->wx_triggered? gb->window_y : gb->current_line + gb->io_registers[GB_IO_SCY];
Expand Down Expand Up @@ -1464,7 +1458,6 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force)
GB_STATE(gb, display, 27);
GB_STATE(gb, display, 28);
GB_STATE(gb, display, 29);
GB_STATE(gb, display, 30);
GB_STATE(gb, display, 31);
GB_STATE(gb, display, 32);
GB_STATE(gb, display, 33);
Expand Down Expand Up @@ -1538,8 +1531,8 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force)
GB_SLEEP(gb, display, 37, 2);

gb->cgb_palettes_blocked = true;
gb->cycles_for_line += (GB_is_cgb(gb) && gb->model <= GB_MODEL_CGB_C)? 2 : 3;
GB_SLEEP(gb, display, 38, (GB_is_cgb(gb) && gb->model <= GB_MODEL_CGB_C)? 2 : 3);
gb->cycles_for_line += 3;
GB_SLEEP(gb, display, 38, 3);

gb->vram_read_blocked = true;
gb->vram_write_blocked = true;
Expand Down Expand Up @@ -1665,12 +1658,8 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force)
GB_STAT_update(gb);


uint8_t idle_cycles = 3;
if (GB_is_cgb(gb) && gb->model <= GB_MODEL_CGB_C) {
idle_cycles = 2;
}
gb->cycles_for_line += idle_cycles;
GB_SLEEP(gb, display, 10, idle_cycles);
gb->cycles_for_line += 3;
GB_SLEEP(gb, display, 10, 3);

gb->cgb_palettes_blocked = true;
gb->cycles_for_line += 2;
Expand Down Expand Up @@ -1902,11 +1891,6 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force)
}
gb->wx_triggered = false;

if (GB_is_cgb(gb) && gb->model <= GB_MODEL_CGB_C) {
gb->cycles_for_line++;
GB_SLEEP(gb, display, 30, 1);
}

if (!gb->cgb_double_speed) {
gb->io_registers[GB_IO_STAT] &= ~3;
gb->mode_for_interrupt = 0;
Expand Down
44 changes: 18 additions & 26 deletions Core/sm83_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,16 @@ static void cycle_write(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
}

case GB_CONFLICT_PALETTE_CGB: {
GB_advance_cycles(gb, gb->pending_cycles - 2);
GB_write_memory(gb, addr, value);
gb->pending_cycles = 6;
if (gb->model >= GB_MODEL_CGB_D) {
GB_advance_cycles(gb, gb->pending_cycles - 2);
GB_write_memory(gb, addr, value);
gb->pending_cycles = 6;
}
else {
GB_advance_cycles(gb, gb->pending_cycles - 1);
GB_write_memory(gb, addr, value);
gb->pending_cycles = 5;
}
break;
}

Expand Down Expand Up @@ -263,25 +270,13 @@ static void cycle_write(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
case GB_CONFLICT_LCDC_CGB: {
uint8_t old = gb->io_registers[GB_IO_LCDC];
if ((~value & old) & GB_LCDC_TILE_SEL) {
// TODO: This is different is because my timing is off in CGB ≤ C
if (gb->model > GB_MODEL_CGB_C) {
GB_advance_cycles(gb, gb->pending_cycles);
GB_write_memory(gb, addr, value ^ GB_LCDC_TILE_SEL); // Write with the old TILE_SET first
gb->tile_sel_glitch = true;
GB_advance_cycles(gb, 1);
gb->tile_sel_glitch = false;
GB_write_memory(gb, addr, value);
gb->pending_cycles = 3;
}
else {
GB_advance_cycles(gb, gb->pending_cycles - 1);
GB_write_memory(gb, addr, value ^ GB_LCDC_TILE_SEL); // Write with the old TILE_SET first
gb->tile_sel_glitch = true;
GB_advance_cycles(gb, 1);
gb->tile_sel_glitch = false;
GB_write_memory(gb, addr, value);
gb->pending_cycles = 4;
}
GB_advance_cycles(gb, gb->pending_cycles);
GB_write_memory(gb, addr, value ^ GB_LCDC_TILE_SEL); // Write with the old TILE_SET first
gb->tile_sel_glitch = true;
GB_advance_cycles(gb, 1);
gb->tile_sel_glitch = false;
GB_write_memory(gb, addr, value);
gb->pending_cycles = 3;
}
else {
GB_advance_cycles(gb, gb->pending_cycles);
Expand All @@ -292,10 +287,7 @@ static void cycle_write(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
}
case GB_CONFLICT_LCDC_CGB_DOUBLE: {
uint8_t old = gb->io_registers[GB_IO_LCDC];
// TODO: This is wrong for CGB ≤ C for TILE_SEL, BG_EN and BG_MAP.
// PPU timings for these models appear to be wrong and it'd make more sense to fix those first than hacking
// around them.

// TODO: Verify for CGB ≤ C for BG_EN and OBJ_EN.
// TODO: This condition is different from single speed mode. Why? What about odd modes?
if ((value ^ old) & GB_LCDC_TILE_SEL) {
GB_advance_cycles(gb, gb->pending_cycles - 2);
Expand Down
8 changes: 4 additions & 4 deletions SDL/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -982,10 +982,10 @@ static void cycle_cgb_revision_backwards(unsigned index)
static const char *current_cgb_revision_string(unsigned index)
{
return GB_inline_const(const char *[], {
"CPU CGB 0 (Exp.)",
"CPU CGB A (Exp.)",
"CPU CGB B (Exp.)",
"CPU CGB C (Exp.)",
"CPU CGB 0",
"CPU CGB A",
"CPU CGB B",
"CPU CGB C",
"CPU CGB D",
"CPU CGB E",
})
Expand Down
12 changes: 6 additions & 6 deletions iOS/GBSettingsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,12 @@ + (UIImage *)previewImageForTheme:(NSString *)theme
@{@"type": typeRadio, @"pref": @"GBSGBModel", @"title": @"Super Game Boy 2", @"value": @(GB_MODEL_SGB2),},
]),
QUICK_SUBMENU(@"Game Boy Color", @[
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB 0 (Experimental)", @"value": @(GB_MODEL_CGB_0),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB A (Experimental)", @"value": @(GB_MODEL_CGB_A),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB B (Experimental)", @"value": @(GB_MODEL_CGB_B),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB C (Experimental)", @"value": @(GB_MODEL_CGB_C),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB D", @"value": @(GB_MODEL_CGB_D),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB E", @"value": @(GB_MODEL_CGB_E),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB 0", @"value": @(GB_MODEL_CGB_0),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB A", @"value": @(GB_MODEL_CGB_A),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB B", @"value": @(GB_MODEL_CGB_B),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB C", @"value": @(GB_MODEL_CGB_C),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB D", @"value": @(GB_MODEL_CGB_D),},
@{@"type": typeRadio, @"pref": @"GBCGBModel", @"title": @"CPU CGB E", @"value": @(GB_MODEL_CGB_E),},
]),
QUICK_SUBMENU(@"Game Boy Advance", @[
@{@"type": typeDisabled, @"title": @"CPU AGB 0 (Early GBA)",},
Expand Down
78 changes: 39 additions & 39 deletions libretro/libretro_core_options.inc
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,19 @@ struct retro_core_option_v2_definition option_defs_us[] = {
NULL,
"system",
{
{ "Auto", "Auto Detect DMG/CGB" },
{ "Auto (SGB)", "Auto Detect DMG/SGB/CGB" },
{ "Game Boy", "Game Boy (DMG-CPU B)" },
{ "Game Boy Pocket", "Game Boy Pocket/Light" },
{ "Game Boy Color 0", "Game Boy Color (CPU CGB 0) (Experimental)" },
{ "Game Boy Color A", "Game Boy Color (CPU CGB A) (Experimental)" },
{ "Game Boy Color B", "Game Boy Color (CPU CGB B) (Experimental)" },
{ "Game Boy Color C", "Game Boy Color (CPU CGB C) (Experimental)" },
{ "Game Boy Color D", "Game Boy Color (CPU CGB D)" },
{ "Game Boy Color", "Game Boy Color (CPU CGB E)" },
{ "Game Boy Advance", "Game Boy Advance (CPU AGB A)" },
{ "Game Boy Player", "Game Boy Player (CPU AGB A)" },
{ "Super Game Boy", "Super Game Boy NTSC" },
{ "Auto", "Auto Detect DMG/CGB" },
{ "Auto (SGB)", "Auto Detect DMG/SGB/CGB" },
{ "Game Boy", "Game Boy (DMG-CPU B)" },
{ "Game Boy Pocket", "Game Boy Pocket/Light" },
{ "Game Boy Color 0", "Game Boy Color (CPU CGB 0)" },
{ "Game Boy Color A", "Game Boy Color (CPU CGB A)" },
{ "Game Boy Color B", "Game Boy Color (CPU CGB B)" },
{ "Game Boy Color C", "Game Boy Color (CPU CGB C)" },
{ "Game Boy Color D", "Game Boy Color (CPU CGB D)" },
{ "Game Boy Color", "Game Boy Color (CPU CGB E)" },
{ "Game Boy Advance", "Game Boy Advance (CPU AGB A)" },
{ "Game Boy Player", "Game Boy Player (CPU AGB A)" },
{ "Super Game Boy", "Super Game Boy NTSC" },
{ "Super Game Boy PAL", NULL },
{ "Super Game Boy 2", NULL },
{ NULL, NULL },
Expand Down Expand Up @@ -328,19 +328,19 @@ struct retro_core_option_v2_definition option_defs_us[] = {
NULL,
"system",
{
{ "Auto", "Auto Detect DMG/CGB" },
{ "Auto (SGB)", "Auto Detect DMG/SGB/CGB" },
{ "Game Boy", "Game Boy (DMG-CPU B)" },
{ "Game Boy Pocket", "Game Boy Pocket/Light" },
{ "Game Boy Color 0", "Game Boy Color (CPU CGB 0) (Experimental)" },
{ "Game Boy Color A", "Game Boy Color (CPU CGB A) (Experimental)" },
{ "Game Boy Color B", "Game Boy Color (CPU CGB B) (Experimental)" },
{ "Game Boy Color C", "Game Boy Color (CPU CGB C) (Experimental)" },
{ "Game Boy Color D", "Game Boy Color (CPU CGB D)" },
{ "Game Boy Color", "Game Boy Color (CPU CGB E)" },
{ "Game Boy Advance", "Game Boy Advance (CPU AGB A)" },
{ "Game Boy Player", "Game Boy Player (CPU AGB A)" },
{ "Super Game Boy", "Super Game Boy NTSC" },
{ "Auto", "Auto Detect DMG/CGB" },
{ "Auto (SGB)", "Auto Detect DMG/SGB/CGB" },
{ "Game Boy", "Game Boy (DMG-CPU B)" },
{ "Game Boy Pocket", "Game Boy Pocket/Light" },
{ "Game Boy Color 0", "Game Boy Color (CPU CGB 0)" },
{ "Game Boy Color A", "Game Boy Color (CPU CGB A)" },
{ "Game Boy Color B", "Game Boy Color (CPU CGB B)" },
{ "Game Boy Color C", "Game Boy Color (CPU CGB C)" },
{ "Game Boy Color D", "Game Boy Color (CPU CGB D)" },
{ "Game Boy Color", "Game Boy Color (CPU CGB E)" },
{ "Game Boy Advance", "Game Boy Advance (CPU AGB A)" },
{ "Game Boy Player", "Game Boy Player (CPU AGB A)" },
{ "Super Game Boy", "Super Game Boy NTSC" },
{ "Super Game Boy PAL", NULL },
{ "Super Game Boy 2", NULL },
{ NULL, NULL },
Expand Down Expand Up @@ -370,19 +370,19 @@ struct retro_core_option_v2_definition option_defs_us[] = {
NULL,
"system",
{
{ "Auto", "Auto Detect DMG/CGB" },
{ "Auto (SGB)", "Auto Detect DMG/SGB/CGB" },
{ "Game Boy", "Game Boy (DMG-CPU B)" },
{ "Game Boy Pocket", "Game Boy Pocket/Light" },
{ "Game Boy Color 0", "Game Boy Color (CPU CGB 0) (Experimental)" },
{ "Game Boy Color A", "Game Boy Color (CPU CGB A) (Experimental)" },
{ "Game Boy Color B", "Game Boy Color (CPU CGB B) (Experimental)" },
{ "Game Boy Color C", "Game Boy Color (CPU CGB C) (Experimental)" },
{ "Game Boy Color D", "Game Boy Color (CPU CGB D)" },
{ "Game Boy Color", "Game Boy Color (CPU CGB E)" },
{ "Game Boy Advance", "Game Boy Advance (CPU AGB A)" },
{ "Game Boy Player", "Game Boy Player (CPU AGB A)" },
{ "Super Game Boy", "Super Game Boy NTSC" },
{ "Auto", "Auto Detect DMG/CGB" },
{ "Auto (SGB)", "Auto Detect DMG/SGB/CGB" },
{ "Game Boy", "Game Boy (DMG-CPU B)" },
{ "Game Boy Pocket", "Game Boy Pocket/Light" },
{ "Game Boy Color 0", "Game Boy Color (CPU CGB 0)" },
{ "Game Boy Color A", "Game Boy Color (CPU CGB A)" },
{ "Game Boy Color B", "Game Boy Color (CPU CGB B)" },
{ "Game Boy Color C", "Game Boy Color (CPU CGB C)" },
{ "Game Boy Color D", "Game Boy Color (CPU CGB D)" },
{ "Game Boy Color", "Game Boy Color (CPU CGB E)" },
{ "Game Boy Advance", "Game Boy Advance (CPU AGB A)" },
{ "Game Boy Player", "Game Boy Player (CPU AGB A)" },
{ "Super Game Boy", "Super Game Boy NTSC" },
{ "Super Game Boy PAL", NULL },
{ "Super Game Boy 2", NULL },
{ NULL, NULL },
Expand Down

0 comments on commit c3e3fb9

Please sign in to comment.