From 10038ec76dfb09f4bc753aa3d42037ff65bffb18 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Thu, 18 Jul 2019 23:08:16 +0300 Subject: [PATCH] Emulate ICD desyncing --- bsnes/gb/Core/display.c | 20 ++++++++++---------- bsnes/sfc/coprocessor/icd/icd.cpp | 7 ++++--- bsnes/sfc/coprocessor/icd/icd.hpp | 5 +++-- bsnes/sfc/coprocessor/icd/interface.cpp | 15 ++++++++------- bsnes/sfc/coprocessor/icd/serialization.cpp | 3 ++- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/bsnes/gb/Core/display.c b/bsnes/gb/Core/display.c index 0143f2b1..2bf00ba9 100644 --- a/bsnes/gb/Core/display.c +++ b/bsnes/gb/Core/display.c @@ -127,13 +127,13 @@ static void display_vblank(GB_gameboy_t *gb) if (GB_is_hle_sgb(gb)) { GB_sgb_render(gb); } - + if (gb->turbo) { if (GB_timing_sync_turbo(gb)) { return; } } - + if (!gb->disable_rendering && ((!(gb->io_registers[GB_IO_LCDC] & 0x80) || gb->stopped) || gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON)) { /* LCD is off, set screen to white or black (if LCD is on in stop mode) */ if (gb->sgb) { @@ -423,8 +423,7 @@ static void render_pixel_if_possible(GB_gameboy_t *gb) gb->screen[gb->position_in_line + gb->current_line * WIDTH] = gb->sprite_palettes_rgb[oam_fifo_item->palette * 4 + pixel]; } } - - /* byuu: gotta do this later so it's only done once ... you'll probably wanna refactor this somehow :/ */ + if (gb->model & GB_MODEL_NO_SFC_BIT) { if (gb->icd_pixel_callback) { gb->icd_pixel_callback(gb, icd_pixel); @@ -770,7 +769,13 @@ 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 + + // Todo: unverified timing + gb->current_lcd_line++; + if (gb->icd_hreset_callback) { + gb->icd_hreset_callback(gb); + } + if (gb->current_lcd_line == LINES && GB_is_sgb(gb)) { display_vblank(gb); } @@ -910,11 +915,6 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles) } GB_SLEEP(gb, display, 11, LINE_LENGTH - gb->cycles_for_line); gb->mode_for_interrupt = 2; - - /* TODO: Can this timing even be verified? */ - if (gb->icd_hreset_callback) { - gb->icd_hreset_callback(gb); - } } /* Lines 144 - 152 */ diff --git a/bsnes/sfc/coprocessor/icd/icd.cpp b/bsnes/sfc/coprocessor/icd/icd.cpp index 7d93a4bc..4d9afe85 100644 --- a/bsnes/sfc/coprocessor/icd/icd.cpp +++ b/bsnes/sfc/coprocessor/icd/icd.cpp @@ -16,7 +16,6 @@ namespace SameBoy { static auto vreset(GB_gameboy_t*) -> void { icd.ly = 0; - icd.ppuScanline(); } static auto icd_pixel(GB_gameboy_t*, uint8_t pixel) -> void { @@ -122,7 +121,8 @@ auto ICD::power() -> void { readBank = 0; readAddress = 0; writeBank = 0; - writeAddress = 0; + writeX = 0; + writeY = 0; packetSize = 0; joypID = 3; @@ -148,7 +148,8 @@ auto ICD::reset() -> void { readBank = 0; readAddress = 0; writeBank = 0; - writeAddress = 0; + writeX = 0; + writeY = 0; packetSize = 0; joypID = 3; diff --git a/bsnes/sfc/coprocessor/icd/icd.hpp b/bsnes/sfc/coprocessor/icd/icd.hpp index 4aa6a714..718887f5 100644 --- a/bsnes/sfc/coprocessor/icd/icd.hpp +++ b/bsnes/sfc/coprocessor/icd/icd.hpp @@ -61,7 +61,8 @@ private: uint readBank; uint readAddress; uint writeBank; - uint writeAddress; + uint writeX; + uint writeY; struct Information { uint pathID = 0; @@ -73,7 +74,7 @@ public: //as the offsets of all member variables will be wrong compared to what the C SameBoy code expects. GB_gameboy_t sameboy; uint32_t bitmap[160 * 144]; - uint ly = 0; + uint8_t ly = 0; }; extern ICD icd; diff --git a/bsnes/sfc/coprocessor/icd/interface.cpp b/bsnes/sfc/coprocessor/icd/interface.cpp index 0407649d..b9be5838 100644 --- a/bsnes/sfc/coprocessor/icd/interface.cpp +++ b/bsnes/sfc/coprocessor/icd/interface.cpp @@ -1,18 +1,19 @@ auto ICD::ppuScanline() -> void { - if(ly > 143) return; //Vblank - if((ly & 7) == 0) { + if(++writeY == 8) { writeBank = (writeBank + 1) & 3; - writeAddress = 0; + writeY = 0; } + writeX = 0; } auto ICD::ppuOutput(uint2 color) -> void { - uint y = writeAddress / 160; - uint x = writeAddress % 160; - uint addr = writeBank * 512 + y * 2 + x / 8 * 16; + if(writeX >= 160) return; // Unverified behavior + if(writeY >= 8) return; // Should never happen + + uint addr = writeBank * 512 + writeY * 2 + writeX / 8 * 16; output[addr + 0] = (output[addr + 0] << 1) | !!(color & 1); output[addr + 1] = (output[addr + 1] << 1) | !!(color & 2); - writeAddress = (writeAddress + 1) % 1280; + writeX++; } auto ICD::apuOutput(float left, float right) -> void { diff --git a/bsnes/sfc/coprocessor/icd/serialization.cpp b/bsnes/sfc/coprocessor/icd/serialization.cpp index a0ce490d..75eff3c8 100644 --- a/bsnes/sfc/coprocessor/icd/serialization.cpp +++ b/bsnes/sfc/coprocessor/icd/serialization.cpp @@ -38,5 +38,6 @@ auto ICD::serialize(serializer& s) -> void { s.integer(readBank); s.integer(readAddress); s.integer(writeBank); - s.integer(writeAddress); + s.integer(writeX); + s.integer(writeY); }