]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Handle bitplane DMA wraparound allocation correctly in NTSC (long/short line toggle).
authorToni Wilen <twilen@winuae.net>
Thu, 2 May 2024 17:19:54 +0000 (20:19 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 2 May 2024 17:19:54 +0000 (20:19 +0300)
custom.cpp

index ce5e00803920f0cd57122e8741c94f3dc72cd969..fe426b2b5ab53b24ecb2df850105d267532fade4 100644 (file)
@@ -902,6 +902,17 @@ static int expand_sprres(uae_u16 con0, uae_u16 con3)
        return res;
 }
 
+static int islinetoggle(void)
+{
+       int linetoggle = 0;
+       if (!(new_beamcon0 & BEAMCON0_LOLDIS) && !(new_beamcon0 & BEAMCON0_PAL) && ecs_agnus) {
+               linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line
+       } else if (!ecs_agnus && currprefs.ntscmode) {
+               linetoggle = 1; // hardwired NTSC Agnus
+       }
+       return linetoggle;
+}
+
 STATIC_INLINE uae_u8 *pfield_xlateptr(uaecptr plpt, int bytecount)
 {
        if (!chipmem_check_indirect(plpt, bytecount)) {
@@ -2047,6 +2058,7 @@ static void estimate_last_fetch_cycle(int hpos)
 #else
                estimated_cycles = estimated_cycles_buf0;
 #endif
+               uae_s8 *ecycs = estimated_cycles;
                // bitplane DMA end can wrap around, even in non-overrun cases
                int start_pos = (hpos + RGA_PIPELINE_ADJUST) % maxhpos;
                int start_pos2 = start_pos;
@@ -2064,13 +2076,16 @@ static void estimate_last_fetch_cycle(int hpos)
 #endif
 
                        if (!off2 && start_pos + fetchstart <= end_pos) {
-                               memcpy(estimated_cycles + start_pos, curr_diagram, fetchstart);
+                               memcpy(ecycs + start_pos, curr_diagram, fetchstart);
                                start_pos += fetchstart;
                        } else {
-                               estimated_cycles[start_pos] = curr_diagram[off2];
+                               ecycs[start_pos] = curr_diagram[off2];
                                start_pos++;
                                if (start_pos >= maxhpos) {
                                        start_pos = 0;
+                                       if (islinetoggle()) {
+                                               ecycs = maxhposeven ? estimated_cycles_buf0 : estimated_cycles_buf1;
+                                       }
                                }
                                if (start_pos == REFRESH_FIRST_HPOS) {
                                        // bpl sequencer repeated this cycle
@@ -2086,10 +2101,10 @@ static void estimate_last_fetch_cycle(int hpos)
                        // zero rest of buffer
                        if (end_pos != start_pos2) {
                                if (end_pos > start_pos2) {
-                                       memset(estimated_cycles + end_pos, 0, maxhpos - end_pos);
-                                       memset(estimated_cycles, 0, start_pos2);
+                                       memset(ecycs + end_pos, 0, maxhpos - end_pos);
+                                       memset(ecycs, 0, start_pos2);
                                } else {
-                                       memset(estimated_cycles + end_pos, 0, start_pos2 - end_pos);
+                                       memset(ecycs + end_pos, 0, start_pos2 - end_pos);
                                }
                        }
                        estimated_bplcon0 = bplcon0;
@@ -2323,17 +2338,6 @@ int get_bitplane_dma_rel(int hpos, int off)
        return 0;
 }
 
-static int islinetoggle(void)
-{
-       int linetoggle = 0;
-       if (!(new_beamcon0 & BEAMCON0_LOLDIS) && !(new_beamcon0 & BEAMCON0_PAL) && ecs_agnus) {
-               linetoggle = 1; // NTSC and !LOLDIS -> LOL toggles every line
-       } else if (!ecs_agnus && currprefs.ntscmode) {
-               linetoggle = 1; // hardwired NTSC Agnus
-       }
-       return linetoggle;
-}
-
 static void compute_shifter_mask(void)
 {
        int shifter_size = 16 << (fetchmode + LORES_TO_SHRES_SHIFT - toscr_res);
@@ -13234,10 +13238,12 @@ static void hsync_handler_pre(bool onvsync)
        hpos_hsync_extra = maxhpos;
 
        lol_prev = lol;
-       if (islinetoggle())
+       if (islinetoggle()) {
                lol = lol ? 0 : 1;
-       else
+       } else {
                lol = 0;
+       }
+       memset(cycle_line_slot, 0, maxhposm1 + 1);
 
        // to record decisions correctly between end of scanline and start of hsync
        if (!eventtab[ev_hsynch].active) {
@@ -13962,8 +13968,6 @@ static void delayed_framestart(uae_u32 v)
 // this prepares for new line
 static void hsync_handler_post(bool onvsync)
 {
-       memset(cycle_line_slot, 0, maxhposm1 + 1);
-
        // genlock active:
        // vertical: interlaced = toggles every other field, non-interlaced = both fields (normal)
        // horizontal: PAL = every line, NTSC = every other line