mirror of https://github.com/LIJI32/SameBoy.git
Accurate emulation of frame parity
This commit is contained in:
parent
a9c01d35fc
commit
4cf3b3c948
|
@ -97,8 +97,7 @@ static void fifo_overlay_object_row(GB_fifo_t *fifo, uint8_t lower, uint8_t uppe
|
|||
#define WIDTH (160)
|
||||
#define BORDERED_WIDTH 256
|
||||
#define BORDERED_HEIGHT 224
|
||||
#define FRAME_LENGTH (LCDC_PERIOD)
|
||||
#define VIRTUAL_LINES (FRAME_LENGTH / LINE_LENGTH) // = 154
|
||||
#define VIRTUAL_LINES (LCDC_PERIOD / LINE_LENGTH) // = 154
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t y;
|
||||
|
@ -1380,12 +1379,28 @@ static inline uint8_t x_for_object_match(GB_gameboy_t *gb)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void update_frame_parity(GB_gameboy_t *gb)
|
||||
{
|
||||
if (gb->model <= GB_MODEL_CGB_E) {
|
||||
gb->is_odd_frame ^= true;
|
||||
}
|
||||
else {
|
||||
// Faster than division, it's normally only once
|
||||
while (gb->frame_parity_ticks > LCDC_PERIOD * 2) {
|
||||
gb->frame_parity_ticks -= LCDC_PERIOD * 2;
|
||||
gb->is_odd_frame ^= true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: It seems that the STAT register's mode bits are always "late" by 4 T-cycles.
|
||||
The PPU logic can be greatly simplified if that delay is simply emulated.
|
||||
*/
|
||||
void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force)
|
||||
{
|
||||
gb->frame_parity_ticks += cycles;
|
||||
|
||||
if (unlikely((gb->io_registers[GB_IO_LCDC] & GB_LCDC_ENABLE) && (signed)(gb->cycles_for_line * 2 + cycles + gb->display_cycles) > LINE_LENGTH * 2)) {
|
||||
unsigned first_batch = (LINE_LENGTH * 2 - gb->cycles_for_line * 2 + gb->display_cycles);
|
||||
GB_display_run(gb, first_batch, force);
|
||||
|
@ -1470,13 +1485,12 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force)
|
|||
if (gb->cycles_since_vblank_callback < LCDC_PERIOD) {
|
||||
GB_SLEEP(gb, display, 1, LCDC_PERIOD - gb->cycles_since_vblank_callback);
|
||||
}
|
||||
update_frame_parity(gb); // TODO: test actual timing
|
||||
GB_display_vblank(gb, GB_VBLANK_TYPE_LCD_OFF);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
gb->is_odd_frame = false;
|
||||
|
||||
|
||||
if (!GB_is_cgb(gb)) {
|
||||
GB_SLEEP(gb, display, 23, 1);
|
||||
}
|
||||
|
@ -2001,7 +2015,7 @@ skip_slow_mode_3:
|
|||
}
|
||||
else {
|
||||
if (!GB_is_sgb(gb) || gb->current_lcd_line < LINES) {
|
||||
gb->is_odd_frame ^= true;
|
||||
update_frame_parity(gb); // TODO: test actual timing
|
||||
GB_display_vblank(gb, GB_VBLANK_TYPE_NORMAL_FRAME);
|
||||
}
|
||||
gb->frame_skip_state = GB_FRAMESKIP_FIRST_FRAME_RENDERED;
|
||||
|
@ -2009,7 +2023,7 @@ skip_slow_mode_3:
|
|||
}
|
||||
else {
|
||||
if (!GB_is_sgb(gb) || gb->current_lcd_line < LINES) {
|
||||
gb->is_odd_frame ^= true;
|
||||
update_frame_parity(gb); // TODO: test actual timing
|
||||
GB_display_vblank(gb, GB_VBLANK_TYPE_NORMAL_FRAME);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1762,6 +1762,8 @@ static void GB_reset_internal(GB_gameboy_t *gb, bool quick)
|
|||
}
|
||||
|
||||
GB_set_internal_div_counter(gb, 8);
|
||||
/* TODO: AGS-101 is inverted in comparison to AGS-001 and AGB */
|
||||
gb->is_odd_frame = gb->model > GB_MODEL_CGB_E;
|
||||
|
||||
#ifndef GB_DISABLE_DEBUGGER
|
||||
if (gb->nontrivial_jump_state) {
|
||||
|
|
|
@ -644,6 +644,7 @@ struct GB_gameboy_internal_s {
|
|||
bool disable_window_pixel_insertion_glitch;
|
||||
bool insert_bg_pixel;
|
||||
uint8_t cpu_vram_bus;
|
||||
uint32_t frame_parity_ticks;
|
||||
)
|
||||
|
||||
GB_SECTION(accessory,
|
||||
|
|
|
@ -1504,6 +1504,10 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||
gb->lcd_status_callback(gb, false);
|
||||
}
|
||||
gb->double_speed_alignment = 0;
|
||||
if (gb->model <= GB_MODEL_CGB_E) {
|
||||
/* TODO: Verify this, it's a bit... odd */
|
||||
gb->is_odd_frame ^= true;
|
||||
}
|
||||
GB_timing_sync(gb);
|
||||
GB_lcd_off(gb);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ vec4 texture_relative(sampler2D t, vec2 pos, vec2 offset)
|
|||
{filter}
|
||||
|
||||
|
||||
#define BLEND_BIAS (2.0/5.0)
|
||||
#define BLEND_BIAS (1.0/3.0)
|
||||
|
||||
#define DISABLED 0
|
||||
#define SIMPLE 1
|
||||
|
|
|
@ -50,7 +50,7 @@ __attribute__((unused)) static inline float4 texture_relative(texture2d<half> t,
|
|||
#line 1
|
||||
{filter}
|
||||
|
||||
#define BLEND_BIAS (2.0/5.0)
|
||||
#define BLEND_BIAS (1.0/3.0)
|
||||
|
||||
enum frame_blending_mode {
|
||||
DISABLED,
|
||||
|
|
Loading…
Reference in New Issue