]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Border bug emulation, copper update.
authorToni Wilen <twilen@winuae.net>
Mon, 20 Dec 2021 19:24:58 +0000 (21:24 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 20 Dec 2021 19:24:58 +0000 (21:24 +0200)
custom.cpp
drawing.cpp
include/drawing.h

index 33db773b27e36f9e84f7651372ef0ff5d7a3e1f2..d2f6cb0da28cf80a0190e4609ea0b3bd86b1e3c4 100644 (file)
@@ -292,7 +292,7 @@ int maxvpos_display_vsync; // extra lines from top visible in bottom
 static int vblank_extraline;
 static int maxhposm1;
 static bool maxhposeven, maxhposeven_prev;
-static int hsyncendpos, hsyncstartpos;
+static int hsyncendpos, hsyncstartpos, hsyncendpos2;
 int hsync_end_left_border;
 static int hsyncstartpos_start, hsyncstartpos_start_cycles;
 
@@ -478,7 +478,6 @@ struct copper {
        // following move does not enable COPRS
        int ignore_next;
        int vcmp, hcmp;
-       bool wakecond;
 
        int strobe; /* COPJMP1 / COPJMP2 accessed */
        int last_strobe;
@@ -2974,6 +2973,18 @@ static void beginning_of_plane_block_early(int hpos)
        hbstrt_bordercheck(hpos, false);
 }
 
+static void start_noborder(int hpos)
+{
+       bpl_shifter = true;
+       reset_bpl_vars();
+       if (thisline_decision.plfleft < 0) {
+               thisline_decision.plfleft = hpos * 2;
+               if (hdiwstate == DIW_waiting_stop && thisline_decision.diwfirstword < 0) {
+                       thisline_decision.diwfirstword = min_diwlastword;
+               }
+       }
+}
+
 /* Called when all planes have been fetched, i.e. when a new block
 of data is available to be displayed.  The data in fetched[] is
 moved into todisplay[].  */
@@ -2996,17 +3007,9 @@ static void beginning_of_plane_block(int hpos)
        plane0_first_done = true;
        last_bpl1dat_hpos = hpos;
 
-       if (thisline_decision.plfleft < 0) {
-               int left = hpos + hpos_hsync_extra;
-               // do not mistake end of bitplane as start of low value hblank programmed mode
-               if (hpos > REFRESH_FIRST_HPOS) {
-                       thisline_decision.plfleft = left * 2;
-                       bpl_shifter = true;
-                       reset_bpl_vars();
-                       if (hdiwstate == DIW_waiting_stop && thisline_decision.diwfirstword < 0) {
-                               thisline_decision.diwfirstword = min_diwlastword;
-                       }
-               }
+       // do not mistake end of bitplane as start of low value hblank programmed mode
+       if (!bpl_shifter && hpos > REFRESH_FIRST_HPOS) {
+               start_noborder(hpos + hpos_hsync_extra);
        }
 
        hbstrt_bordercheck(hpos, true);
@@ -4762,14 +4765,6 @@ static void reset_decisions_hsync_start(void)
        } else {
                // Visible vblank end is delayed by 1 line
                thisline_decision.vb = vb_start_line > 1 + vblank_extraline || vb_end_next_line ? 0 : VB_NOVB;
-#if 0
-               // borderblank bug
-               if (vb_end_next_line2) {
-                       if (ecs_agnus && ecs_denise && diwstate == DIW_waiting_stop && vpos != diwstate_vpos && (!exthblank || (exthblank && last_hblank_start < 0))) {
-                               thisline_decision.vb |= VB_BRDBLANKBUG;
-                       }
-               }
-#endif
        }
        // if programmed vblank
        if ((beamcon0 & BEAMCON0_VARVBEN) && ecs_agnus) {
@@ -4858,32 +4853,37 @@ static void reset_decisions_hsync_start(void)
                        bprun_pipeline_flush_delay = maxhpos;
                        plane0p_enabled = true;
                        plane0p_forced = true;
+               }
+       }
 
-                       // HBLANK start before HSYNC (or HBLANK never triggered) and BPL1DAT between HBLANK and HSYNC?
-                       if (exthblank) {
-                               int hblankstart = 0;
-                               if (last_hblank_start >= 0) {
-                                       hblankstart = diw_to_hpos(last_hblank_start + 4);
-                               }
-                               else {
-                                       hblankstart = last_bpl1dat_hpos - 1;
-                               }
-                               int bpl1 = last_bpl1dat_hpos;
-                               if (bpl1 < hblankstart) {
-                                       bpl1 += maxhpos;
-                               }
-                               int hp = hpos;
-                               if (hp < hblankstart || hp < bpl1) {
-                                       hp += maxhpos;
-                               }
-                               int comp = maxhpos / 2 - 1;
-                               if (bpl1 > hblankstart && bpl1 < hp && (bpl1 - hblankstart) < comp && (bpl1 - hp) < comp) {
-                                       // Close border. (HBLANK start opens border, BPL1DAT closes it)
-                                       thisline_decision.plfleft = hpos * 2;
-                               }
+       // HBLANK start before HSYNC (or HBLANK never triggered) and BPL1DAT between HBLANK and HSYNC?
+       if (exthblank) {
+               int hblankstart = -1;
+               if (last_hblank_start >= 0) {
+                       hblankstart = diw_to_hpos(last_hblank_start + 4);
+               } else if (exthblank_state) {
+                       hblankstart = last_bpl1dat_hpos - 1;
+               }
+               if (hblankstart >= 0) {
+                       int bpl1 = last_bpl1dat_hpos;
+                       if (bpl1 < hblankstart) {
+                               bpl1 += maxhpos;
+                       }
+                       int hp = hpos;
+                       if (hp < hblankstart || hp < bpl1) {
+                               hp += maxhpos;
+                       }
+                       int comp = maxhpos / 2 - 1;
+                       if (bpl1 > hblankstart && bpl1 < hp && (bpl1 - hblankstart) < comp && (bpl1 - hp) < comp) {
+                               // Close border. (HBLANK start opens border, BPL1DAT closes it)
+                               start_noborder(hpos);
                        }
                }
        }
+       // vblank end and bitplane was active inside vblank: borderblank bug
+       if (ecs_agnus && ecs_denise && vb_end_next_line2 && last_bpl1dat_hpos >= 0) {
+               start_noborder(hpos);
+       }
 
        if (normalstart) {
                plane0 = false;
@@ -5114,11 +5114,13 @@ static void updateextblk(void)
        if (new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN)) {
 
                hsyncstartpos = hsstrt;
+               hsyncendpos = hsstop;
+
                hsstop_detect = hsstrt + 17;
                if (hsstop_detect >= maxhpos) {
                        hsstop_detect -= maxhpos;
                }
-               hsyncendpos = hsstop_detect;
+               hsyncendpos2 = hsstop_detect;
 
                hsync_end_left_border = hsstop_detect;
 
@@ -5134,10 +5136,10 @@ static void updateextblk(void)
                        hsyncstartpos_start = REFRESH_FIRST_HPOS + 1;
                }
 
-               hsyncendpos -= 1;
+               hsyncendpos2 -= 1;
 
-               if (hsyncendpos < 2) {
-                       hsyncendpos = 2;
+               if (hsyncendpos2 < 2) {
+                       hsyncendpos2 = 2;
                }
 
                if (0 && hsyncstartpos - hsyncendpos < maxhpos) {
@@ -5148,7 +5150,7 @@ static void updateextblk(void)
 
                hsyncstartpos_start = hsyncstartpos_start_hw;
                hsyncstartpos = hsyncstartpos_hw;
-               hsyncendpos = hsyncendpos_hw;
+               hsyncendpos2 = hsyncendpos = hsyncendpos_hw;
                hsynctotal = 234;
 
                hsync_end_left_border = 35 + 9;
@@ -5214,6 +5216,7 @@ static void updateextblk(void)
        hsyncstartpos_start <<= CCK_SHRES_SHIFT;
        hsyncstartpos <<= CCK_SHRES_SHIFT;
        hsyncendpos <<= CCK_SHRES_SHIFT;
+       hsyncendpos2 <<= CCK_SHRES_SHIFT;
        hsynctotal <<= CCK_SHRES_SHIFT;
 
        // ECS Denise has 1 extra lores pixel in right border
@@ -5354,12 +5357,17 @@ void compute_framesync(void)
                int res = GET_RES_AGNUS (bplcon0);
                int vres = islace ? 1 : 0;
                int res2, vres2;
+               int eres = 0;
                        
                res2 = currprefs.gfx_resolution;
-               if (doublescan > 0)
+               if (doublescan > 0) {
                        res2++;
-               if (res2 > RES_MAX)
+                       eres++;
+               }
+               if (res2 > RES_MAX) {
                        res2 = RES_MAX;
+                       eres--;
+               }
                
                vres2 = currprefs.gfx_vresolution;
                if (doublescan > 0 && !islace)
@@ -5371,16 +5379,28 @@ void compute_framesync(void)
                        vres2 = VRES_QUAD;
 
                int start = hsyncstartpos >> CCK_SHRES_SHIFT;
-               int stop = hsyncstartpos_start_cycles;
-
+               int stop = hsyncendpos >> CCK_SHRES_SHIFT;
                int w;
-               if (maxhpos > start) {
-                       w = maxhpos - start;
+
+               int minhsync = 21;
+
+               if (start > maxhpos) {
+                       int hssize = stop - (start - maxhpos);
+                       if (hssize < minhsync) {
+                               hssize = minhsync;
+                       }
+                       w = maxhpos - hssize;
                } else {
-                       w = maxhpos - (start - maxhpos);
+                       int hssize = stop - start;
+                       if (hssize < minhsync) {
+                               hssize = minhsync;
+                       }
+                       w = maxhpos - hssize;
                }
-               vidinfo->drawbuffer.inwidth = (((w + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2;
-               vidinfo->drawbuffer.inxoffset = stop * 4;
+
+               vidinfo->drawbuffer.inwidth = (w * 2) << res2;
+
+               vidinfo->drawbuffer.inxoffset = (stop * 2) << eres;
                
                vidinfo->drawbuffer.extrawidth = 0;
                vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth;
@@ -8584,23 +8604,19 @@ static int coppercomp(int hpos, bool blitwait)
 {
        int hpos_cmp = hpos;
        int vpos_cmp = vpos;
-       int hpos_cmp2 = hpos;
-       int vpos_cmp2 = vpos;
 
        // Copper comparison can match both odd and even cycles
        // Important when crossing scanlines.
-       hpos_cmp2 += 1;
-       if (hpos_cmp2 >= maxhpos) {
-               hpos_cmp2 -= maxhpos;
-               vpos_cmp2++;
+       hpos_cmp += 1;
+       if (hpos_cmp >= maxhpos) {
+               hpos_cmp -= maxhpos;
+               vpos_cmp++;
        }
 
        int vp = vpos_cmp & (((cop_state.ir[1] >> 8) & 0x7F) | 0x80);
        int hp = hpos_cmp & (cop_state.ir[1] & 0xFE);
-       int vp2 = vpos_cmp2 & (((cop_state.ir[1] >> 8) & 0x7F) | 0x80);
-       int hp2 = hpos_cmp2 & (cop_state.ir[1] & 0xFE);
 
-       if (vp < cop_state.vcmp && vp2 < cop_state.vcmp) {
+       if (vp < cop_state.vcmp) {
                return -1;
        }
 
@@ -8619,9 +8635,6 @@ static int coppercomp(int hpos, bool blitwait)
        if (vp == cop_state.vcmp && hp < cop_state.hcmp) {
                return 1;
        }
-       if (vp2 == cop_state.vcmp && hp2 < cop_state.hcmp) {
-               return 1;
-       }
        return 0;
 }
 
@@ -8742,7 +8755,6 @@ static void update_copper(int until_hpos)
                                        goto next;
                                }
                                cop_state.state = COP_wait1;
-                               cop_state.wakecond = false;
                        }
                        break;
 
@@ -8750,24 +8762,21 @@ static void update_copper(int until_hpos)
                        // Need free cycle, cycle not allocated.
                case COP_wait1:
                        {
-                               if (!cop_state.wakecond) {
-                                       int comp = coppercomp(hpos, true);
-                                       if (comp < 0) {
-                                               // If we need to wait for later scanline or blitter: no need to emulate copper cycle-by-cycle
-                                               if (cop_state.ir[0] == 0xFFFF && cop_state.ir[1] == 0xFFFE) {
-                                                       cop_state.state = COP_waitforever;
-                                               }
-                                               copper_enabled_thisline = 0;
-                                               unset_special(SPCFLAG_COPPER);
-                                               goto next;
-                                       }
-
-                                       if (comp) {
-                                               goto next;
+                               int comp = coppercomp(hpos, true);
+                               if (comp < 0) {
+                                       // If we need to wait for later scanline or blitter: no need to emulate copper cycle-by-cycle
+                                       if (cop_state.ir[0] == 0xFFFF && cop_state.ir[1] == 0xFFFE) {
+                                               cop_state.state = COP_waitforever;
                                        }
+                                       copper_enabled_thisline = 0;
+                                       unset_special(SPCFLAG_COPPER);
+                                       goto next;
+                               }
 
-                                       cop_state.wakecond = true;
+                               if (comp) {
+                                       goto next;
                                }
+
                                if (copper_cant_read(hpos, 0)) {
                                        goto next;
                                }
@@ -10297,8 +10306,8 @@ static void hautoscale_check(void)
                        }
                        if (diwfirstword_lores < diwfirstword_total) {
                                diwfirstword_total = diwfirstword_lores;
-                               if (diwfirstword_total < coord_diw_shres_to_window_x(hsyncendpos)) {
-                                       diwfirstword_total = coord_diw_shres_to_window_x(hsyncendpos);
+                               if (diwfirstword_total < coord_diw_shres_to_window_x(hsyncendpos2)) {
+                                       diwfirstword_total = coord_diw_shres_to_window_x(hsyncendpos2);
                                }
                                firstword_bplcon1 = bplcon1;
                        }
index 102da53670eba925dd617ee31272a8d4033cff9c..fdac729c9bb4266370b5eae7c629b216860498e9 100644 (file)
@@ -285,7 +285,6 @@ static bool ecs_genlock_features_colorkey;
 static int hsync_shift_hack;
 static bool sprite_smaller_than_64, sprite_smaller_than_64_inuse;
 static bool full_blank;
-static int borderblank_blank;
 static uae_u8 vb_state;
 
 uae_sem_t gui_sem;
@@ -476,12 +475,7 @@ static void reset_custom_limits(void)
 
 static void expand_vb_state(void)
 {
-       full_blank = (vb_state & 15) == VB_PRGVB || (vb_state & 15) >= VB_XBLANK;
-       if ((vb_state & VB_BRDBLANKBUG) && ce_is_borderblank(colors_for_drawing.extra)) {
-               borderblank_blank = 4;
-       } else {
-               borderblank_blank = 0;
-       }
+       full_blank = vb_state == VB_PRGVB || vb_state >= VB_XBLANK;
 }
 
 static void extblankcheck(void)
@@ -3340,7 +3334,7 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker
                                        // normal left border (hblank end to playfield start)
                                        if (nextpos_in_range > lastpos && lastpos < playfield_start) {
                                                int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start;
-                                               (*worker_border)(lastpos, t, borderblank_blank);
+                                               (*worker_border)(lastpos, t, 0);
                                                lastpos = t;
                                        }
 
@@ -3364,7 +3358,7 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker
                                        // borderblank left border (hblank end to playfield_start_pre)
                                        if (nextpos_in_range > lastpos && lastpos < playfield_start_pre) {
                                                int t = nextpos_in_range <= playfield_start_pre ? nextpos_in_range : playfield_start_pre;
-                                               (*worker_border)(lastpos, t, borderblank_blank);
+                                               (*worker_border)(lastpos, t, 0);
                                                lastpos = t;
                                        }
                                        // AGA "buggy" borderblank, real background color visible, single shres pixel wide.
index e137dc21e7956684dfed7e6894a69114aa8aa194..a0abfe35880a0f17deb1419174b5a35533af1202 100644 (file)
@@ -142,7 +142,6 @@ STATIC_INLINE bool ce_is_borderntrans(uae_u8 data)
        return (data & (1 << CE_BORDERNTRANS)) != 0;
 }
 
-#define VB_BRDBLANKBUG 0x80
 #define VB_XBLANK 0x04
 #define VB_PRGVB 0x02
 #define VB_NOVB 0x01