]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Fast mode chipset emulation updates
authorToni Wilen <twilen@winuae.net>
Sun, 16 Feb 2025 16:42:32 +0000 (18:42 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 16 Feb 2025 16:42:32 +0000 (18:42 +0200)
custom.cpp
drawing.cpp
include/drawing.h

index 21dbf04080422dc754d3c6e54c11e8e5b101b9a5..b2aee33ed572a76b540ee40baad313a523337684 100644 (file)
@@ -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();
index 6a16ba2bc913ad9649d111cc98f5e21eaa9509a1..c67fa65d90b4c049862d24c9f69e7a10a1353c19 100644 (file)
@@ -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) {
index e5e7965924de8af5364c46ff98faa536b0329481..ecfecc321c732f651b410a955865e6346854715d 100644 (file)
@@ -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 */