From b1cdcc5a666c0cab7807b259a221b5ac66069453 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 16 Feb 2025 18:42:32 +0200 Subject: [PATCH] Fast mode chipset emulation updates --- custom.cpp | 18 ++++++++----- drawing.cpp | 68 ++++++++++++++++++++++++++++++++++++++--------- include/drawing.h | 6 ++--- 3 files changed, 71 insertions(+), 21 deletions(-) diff --git a/custom.cpp b/custom.cpp index 21dbf040..b2aee33e 100644 --- a/custom.cpp +++ b/custom.cpp @@ -128,7 +128,7 @@ static struct rgabuf rga_pipe[RGA_SLOT_TOTAL + 1]; struct denise_rga rga_denise[DENISE_RGA_SLOT_TOTAL]; static struct linestate *current_line_state; static struct linestate lines[MAX_SCANDOUBLED_LINES][2]; -static int rga_denise_cycle, rga_denise_cycle_start, rga_denise_cycle_start_prev, rga_denise_cycle_count; +static int rga_denise_cycle, rga_denise_cycle_start, rga_denise_cycle_count; static int rga_denise_cycle_line = 1; static struct pipeline_reg preg; static struct pipeline_func pfunc[MAX_PIPELINE_REG]; @@ -2263,7 +2263,7 @@ static int GETHPOS(void) if (islightpentriggered()) { return hpos_lpen; } - if (!eventtab[ev_sync].active) { + if (!eventtab[ev_sync].active || syncs_stopped) { return agnus_hpos; } evt_t c = get_cycles(); @@ -10177,7 +10177,6 @@ static int wclks_prev; static void next_denise_rga(void) { - rga_denise_cycle_start_prev = rga_denise_cycle_start; rga_denise_cycle_start = rga_denise_cycle; rga_denise_cycle_count = 0; rga_denise[(rga_denise_cycle - 1) & DENISE_RGA_SLOT_MASK].line++; @@ -10206,6 +10205,7 @@ static void decide_line_end(void) static int getlinetype(void) { int type; + if (agnus_vb_active) { type = LINETYPE_BLANK; } else if (vdiwstate == diw_states::DIW_waiting_start || GET_PLANES(bplcon0) == 0 || !dmaen(DMA_BITPLANE)) { @@ -10431,7 +10431,7 @@ static void draw_line(void) int cslen = 10; draw_denise_line(dvp, nextline_how, rga_denise_cycle_line, rga_denise_cycle_start, rga_denise_cycle_count, display_hstart_cyclewait_skip, display_hstart_cyclewait_skip2, - wclks, cs, cslen); + wclks, cs, cslen, lol); } static void dmal_fast(void) @@ -10607,10 +10607,12 @@ static void quick_denise_rga(void) for (int i = 0; i < rga_denise_cycle_count; i++) { int off = i + rga_denise_cycle_start; struct denise_rga *rd = &rga_denise[off & DENISE_RGA_SLOT_MASK]; - if (rd->line == rga_denise_cycle_line && rd->rga != 0x1fe) { + if (rd->line == rga_denise_cycle_line && rd->rga != 0x1fe && (rd->rga < 0x38 || rd->rga >= 0x40)) { denise_update_reg(rd->rga, rd->v); } } + uae_u16 strobe = get_strobe_reg(0); + denise_handle_quick_strobe(strobe, display_hstart_fastmode); } static void do_draw_line(void) @@ -10683,6 +10685,7 @@ static int can_fast_custom(void) } compute_spcflag_copper(); if (copper_enabled_thisline) { + #if 0 // if copper is waiting, wake up is inside blank/border and // it is followed by only writes to color registers: @@ -11958,7 +11961,7 @@ static void fast_strobe(void) if (prev_strobe == 0x3c && str != 0x3c) { INTREQ_INT(5, 0); } - denise_handle_quick_strobe(str); + denise_handle_quick_strobe(str, display_hstart_fastmode); prev_strobe = str; } @@ -12015,6 +12018,9 @@ static void sync_equalline_handler(void) custom_trigger_start(); + int dvp = calculate_linetype(linear_display_vpos); + denise_set_line(dvp); + if (eventtab[ev_sync].active) { check_extra(); do_imm_dmal(); diff --git a/drawing.cpp b/drawing.cpp index 6a16ba2b..c67fa65d 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -316,6 +316,7 @@ static uae_u8 pixx0, pixx1, pixx2, pixx3; static uae_u32 debug_buf[256 * 2 * 4], debug_bufx[256 * 2 * 4]; static uae_u32 *hbstrt_ptr1, *hbstrt_ptr2; static uae_u32 *hbstop_ptr1, *hbstop_ptr2; +static bool no_denise_lol; void set_inhibit_frame(int monid, int bit) { @@ -2037,6 +2038,7 @@ void reset_drawing(void) if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) { denise_vblank_extra = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 5; } + no_denise_lol = !currprefs.cpu_memory_cycle_exact && !currprefs.chipset_hr; } static void gen_direct_drawing_table(void) @@ -2987,6 +2989,10 @@ static void expand_clxcon2(uae_u16 v) static void set_strlong(void) { + if (no_denise_lol) { + denise_strlong = false; + return; + } denise_strlong = true; if (!strlong_emulation) { write_log("STRLONG strobe emulation activated.\n"); @@ -3473,6 +3479,9 @@ static void expand_drga(struct denise_rga *rd) } if ((rd->flags & DENISE_RGA_FLAG_LOL)) { agnus_lol = (rd->flags & DENISE_RGA_FLAG_LOL_ON) != 0; + if (no_denise_lol) { + agnus_lol = false; + } if (!agnus_lol && !denise_lol_shift_prev) { int add = 1 << hresolution; buf1 += add; @@ -4206,11 +4215,15 @@ static void do_hstop_ecs(int cnt) #endif } -void denise_handle_quick_strobe(uae_u16 strobe) +// fix strobe position after fast mode +void denise_handle_quick_strobe(uae_u16 strobe, int offset) { struct denise_rga rd = { 0 }; rd.rga = strobe; handle_strobes(&rd); + // 3 = refresh offset, 2 = pipeline delay + denise_hcounter_new = (offset - 3 - 2) * 2 + 2; + denise_hcounter = denise_hcounter_new; } void denise_handle_quick_disable_hblank(void) { @@ -4777,11 +4790,20 @@ static void lts_null(void) } } +static int prevline; + +// set highest line, used in fast mode emulation +void denise_set_line(int gfx_ypos) +{ + if (gfx_ypos < prevline) { + prevline = gfx_ypos; + } +} + static void get_line(int gfx_ypos, enum nln_how how) { struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; struct vidbuffer *vb = &vidinfo->drawbuffer; - static int prevline; xlinebuffer = NULL; xlinebuffer2 = NULL; @@ -4896,7 +4918,7 @@ static void denise_draw_update(void) denise_max_odd_even = denise_odd_even; } -void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len) +void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol) { bool fullline = false; // currprefs.chipset_hr; @@ -4919,6 +4941,9 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start get_line(gfx_ypos, how); hbstrt_ptr1 = NULL; + hbstrt_ptr2 = NULL; + hbstop_ptr1 = NULL; + hbstop_ptr2 = NULL; if (denise_pixtotal_max == -0x7fffffff || ((linear_vpos >= denise_vblank_extra_vbstop || linear_vpos < denise_vblank_extra_vbstrt) && currprefs.gfx_overscanmode < OVERSCANMODE_ULTRA)) { @@ -5001,7 +5026,7 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start #endif // blank last pixel row if normal overscan mode, it might have NTSC artifacts - if (denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) { + if (denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN && !ecs_denise) { int add = 1 << hresolution; uae_u32 *p1 = hbstrt_ptr1 - denise_lol_shift_prev; uae_u32 *p2 = hbstrt_ptr2 - denise_lol_shift_prev; @@ -5010,8 +5035,17 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start *p2++ = 0x000000; } } - + if (no_denise_lol && denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && !lol) { + int add = 1 << hresolution; + uae_u32 *p1 = hbstrt_ptr1 - denise_lol_shift_prev * 2; + uae_u32 *p2 = hbstrt_ptr2 - denise_lol_shift_prev * 2; + for (int i = 0; i < add * 2; i++) { + *p1++ = 0x000000; + *p2++ = 0x000000; + } + } if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) { + int add = 1 << hresolution; int w = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 8; if (currprefs.gfx_overscanmode == 0) { w -= 4; @@ -5019,34 +5053,44 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start w <<= hresolution; for (int i = 0; i < 4; i++) { uae_u32 *ptr, *ptr2; + int lolshift = 0; switch (i) { case 0: ptr = hbstrt_ptr1; ptr2 = buf1t; + lolshift = lol ? -add : 0; break; case 1: ptr = hbstrt_ptr2; ptr2 = buf2t; + lolshift = lol ? -add : 0; break; case 2: ptr = hbstop_ptr1; ptr2 = buf1t; + lolshift = lol ? add : 0; break; case 3: ptr = hbstop_ptr2; ptr2 = buf2t; + lolshift = lol ? add : 0; break; - } if (ptr) { - uae_u32 *p1 = ptr - denise_lol_shift_prev; - memset(p1, 0, w * sizeof(uae_u32)); - memset(p1 - w, 0, w * sizeof(uae_u32)); + uae_u32 *p1 = ptr - lolshift; + if (i >= 2) { + memset(p1, 0, w * sizeof(uae_u32)); + } else { + memset(p1 - w, 0, w * sizeof(uae_u32)); + } if (bufg) { uae_u16 *gp1 = (p1 - ptr2) + bufg; - memset(gp1, 0xff, w * sizeof(uae_u16)); - memset(gp1 - w, 0xff, w * sizeof(uae_u16)); + if (i >= 2) { + memset(gp1, 0xff, w * sizeof(uae_u16)); + } else { + memset(gp1 - w, 0xff, w * sizeof(uae_u16)); + } } } } @@ -5585,7 +5629,7 @@ static void lts_unaligned_ecs(int cnt, int cnt_next, int h) // bitplane and sprite merge & output if (!dpixcnt && buf1 && denise_pixtotal >= 0 && denise_pixtotal < denise_pixtotal_max) { - uae_u32 t = dtbuf[h ^ lol][ipix]; + uae_u32 t = dtbuf[h ^ lol][ipix]; #ifdef DEBUGGER if (decode_specials_debug) { diff --git a/include/drawing.h b/include/drawing.h index e5e79659..ecfecc32 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -165,7 +165,7 @@ void clear_inhibit_frame(int monid, int bit); void toggle_inhibit_frame(int monid, int bit); extern struct color_entry denise_colors; -void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len); +void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol); bool draw_denise_line_fast(uae_u8 *bplpt[8], int bplstart, int bpllen, int gfx_ypos, enum nln_how how, int total, int dstart, int dtotal, bool vblank, struct denise_fastsprite *dfs); bool start_draw_denise(void); void end_draw_denise(void); @@ -174,8 +174,8 @@ void denise_reset(bool); bool denise_update_reg_queued(uae_u16 reg, uae_u16 v, uae_u32 cycle); void denise_store_registers(void); void denise_restore_registers(void); - +void denise_set_line(int gfx_ypos); void denise_handle_quick_disable_hblank(void); -void denise_handle_quick_strobe(uae_u16 strobe); +void denise_handle_quick_strobe(uae_u16 strobe, int offset); #endif /* UAE_DRAWING_H */ -- 2.47.3