Emulate missing Vreset signal (SGB only for now) and ICD2 desyncing
This commit is contained in:
parent
42ef41182d
commit
9d0aadb83f
@ -393,7 +393,9 @@ static void render_pixel_if_possible(GB_gameboy_t *gb)
|
||||
pixel = ((gb->io_registers[GB_IO_BGP] >> (pixel << 1)) & 3);
|
||||
}
|
||||
if (gb->sgb) {
|
||||
gb->sgb->screen_buffer[gb->position_in_line + gb->current_line * WIDTH] = pixel;
|
||||
if (gb->current_lcd_line < LINES) {
|
||||
gb->sgb->screen_buffer[gb->position_in_line + gb->current_lcd_line * WIDTH] = pixel;
|
||||
}
|
||||
}
|
||||
else {
|
||||
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->background_palettes_rgb[fifo_item->palette * 4 + pixel];
|
||||
@ -407,7 +409,9 @@ static void render_pixel_if_possible(GB_gameboy_t *gb)
|
||||
pixel = ((gb->io_registers[oam_fifo_item->palette? GB_IO_OBP1 : GB_IO_OBP0] >> (pixel << 1)) & 3);
|
||||
}
|
||||
if (gb->sgb) {
|
||||
gb->sgb->screen_buffer[gb->position_in_line + gb->current_line * WIDTH] =pixel;
|
||||
if (gb->current_lcd_line < LINES) {
|
||||
gb->sgb->screen_buffer[gb->position_in_line + gb->current_lcd_line * WIDTH] = pixel;
|
||||
}
|
||||
}
|
||||
else {
|
||||
gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->sprite_palettes_rgb[oam_fifo_item->palette * 4 + pixel];
|
||||
@ -609,6 +613,7 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||
}
|
||||
|
||||
/* Todo: Merge this with the normal line routine */
|
||||
/* Todo: Needs actual rendering, affects SGB emulation */
|
||||
/* Handle the very first line 0 */
|
||||
gb->current_line = 0;
|
||||
gb->ly_for_comparison = 0;
|
||||
@ -642,7 +647,10 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||
gb->vram_read_blocked = true;
|
||||
gb->vram_write_blocked = true;
|
||||
gb->cgb_palettes_blocked = true;
|
||||
|
||||
gb->current_lcd_line++; // TODO: Verify timing
|
||||
if (gb->current_lcd_line == LINES) {
|
||||
display_vblank(gb);
|
||||
}
|
||||
/* TODO: How does the window affect this line? */
|
||||
gb->cycles_for_line += MODE3_LENGTH + (gb->io_registers[GB_IO_SCX] & 7) - 2;
|
||||
GB_SLEEP(gb, display, 3, MODE3_LENGTH + (gb->io_registers[GB_IO_SCX] & 7) - 2);
|
||||
@ -747,6 +755,10 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||
fifo_push_bg_row(&gb->bg_fifo, 0, 0, 0, false, false);
|
||||
/* Todo: find out actual access time of SCX */
|
||||
gb->position_in_line = - (gb->io_registers[GB_IO_SCX] & 7) - 8;
|
||||
gb->current_lcd_line++; // Todo: unverified timing
|
||||
if (gb->current_lcd_line == LINES) {
|
||||
display_vblank(gb);
|
||||
}
|
||||
gb->fetcher_x = ((gb->io_registers[GB_IO_SCX]) / 8) & 0x1f;
|
||||
gb->extra_penalty_for_sprite_at_0 = (gb->io_registers[GB_IO_SCX] & 7);
|
||||
|
||||
@ -961,6 +973,7 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||
gb->wy_diff = 0;
|
||||
gb->window_disabled_while_active = false;
|
||||
gb->current_line = 0;
|
||||
gb->current_lcd_line = -1; // TODO: not the correct timing
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,6 +432,7 @@ struct GB_gameboy_internal_s {
|
||||
/* The LCDC will skip the first frame it renders after turning it on.
|
||||
On the CGB, a frame is not skipped if the previous frame was skipped as well.
|
||||
See https://www.reddit.com/r/EmuDev/comments/6exyxu/ */
|
||||
/* TODO: Drop this and properly emulate the dropped vreset signal*/
|
||||
enum {
|
||||
GB_FRAMESKIP_LCD_TURNED_ON, // On a DMG, the LCD renders a blank screen during this state,
|
||||
// on a CGB, the previous frame is repeated (which might be
|
||||
@ -466,6 +467,7 @@ struct GB_gameboy_internal_s {
|
||||
uint8_t mode_for_interrupt;
|
||||
bool lyc_interrupt_line;
|
||||
bool cgb_palettes_blocked;
|
||||
uint8_t current_lcd_line; // The LCD can go out of sync since the vsync signal is skipped in some cases.
|
||||
);
|
||||
|
||||
/* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */
|
||||
|
@ -702,7 +702,10 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||
if ((value & 0x80) && !(gb->io_registers[GB_IO_LCDC] & 0x80)) {
|
||||
gb->display_cycles = 0;
|
||||
gb->display_state = 0;
|
||||
if (gb->frame_skip_state == GB_FRAMESKIP_SECOND_FRAME_RENDERED) {
|
||||
if (GB_is_sgb(gb)) {
|
||||
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
|
||||
}
|
||||
else if (gb->frame_skip_state == GB_FRAMESKIP_SECOND_FRAME_RENDERED) {
|
||||
gb->frame_skip_state = GB_FRAMESKIP_LCD_TURNED_ON;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user