]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
BEAMCON0 defines, blanking updates.
authorToni Wilen <twilen@winuae.net>
Sat, 18 Dec 2021 18:58:14 +0000 (20:58 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 18 Dec 2021 18:58:14 +0000 (20:58 +0200)
custom.cpp
drawing.cpp
include/custom.h
include/drawing.h

index f1f42fcd62bf369c9ec48ac6375ef9bf062c42bc..33db773b27e36f9e84f7651372ef0ff5d7a3e1f2 100644 (file)
 
 extern uae_u16 serper;
 
-STATIC_INLINE bool nocustom (void)
-{
-       struct amigadisplay *ad = &adisplays[0];
-       if (ad->picasso_on && currprefs.picasso96_nocustom)
-               return true;
-       return false;
-}
-
 static void uae_abort (const TCHAR *format,...)
 {
        static int nomore;
@@ -339,7 +331,7 @@ static uae_u16 hbstop_v, hbstrt_v, hbstop_v2, hbstrt_v2, hbstrt_v2o, hbstop_v2o;
 static int vsstrt_m, vsstop_m, vbstrt_m, vbstop_m;
 static bool vb_state, vb_end_line;
 static bool vs_state, vs_state_on, vs_state_hw;
-static bool vb_end_next_line;
+static bool vb_end_next_line, vb_end_next_line2;
 static int vb_start_line;
 static bool ocs_blanked;
 static uae_u16 sprhstrt, sprhstop, bplhstrt, bplhstop, hhpos, hhpos_hpos;
@@ -350,6 +342,8 @@ static int diw_hstrt, diw_hstop;
 static int diw_hcounter;
 static uae_u16 refptr;
 static uae_u32 refptr_val;
+static int line_disabled;
+static bool custom_disabled;
 
 #define HSYNCTIME (maxhpos * CYCLE_UNIT)
 
@@ -611,6 +605,18 @@ static int REGPARAM3 custom_wput_1(int, uaecptr, uae_u32, int) REGPARAM;
 * helper functions
 */
 
+static void check_nocustom(void)
+{
+       struct amigadisplay* ad = &adisplays[0];
+       if (ad->picasso_on && currprefs.picasso96_nocustom) {
+               custom_disabled = true;
+               line_disabled |= 2;
+       } else {
+               custom_disabled = false;
+               line_disabled &= ~2;
+       }
+}
+
 STATIC_INLINE int ecsshres(void)
 {
        return bplcon0_res == RES_SUPERHIRES && ecs_denise && !aga_mode;
@@ -896,7 +902,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
 {
        color_change *cc;
 
-       if (scandoubled_line || line_hidden() || nocustom()) {
+       if (line_disabled) {
                return;
        }
 
@@ -930,7 +936,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
                }
        }
 
-       // HCENTER blanking
+       // HCENTER blanking (ECS Denise only)
        if (hcenter_v2 && vs_state_on && vpos < maxvpos_display_vsync && lof_display) {
                int chpos = pos;
                if (hcenter_v2_end == 0xffff && hcenter_v2 < chpos && hcenter_v2 >= last_recorded_diw_hpos) {
@@ -942,7 +948,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
                        cc[1].regno = -1;
                        last_recorded_diw_hpos = cc->linepos;
                        hcenter_v2_end = hcenter_v2;
-                       hcenter_v2_end += ((beamcon0 & 0x20) ? 8 : 9) << CCK_SHRES_SHIFT;
+                       hcenter_v2_end += ((beamcon0 & BEAMCON0_PAL) ? 8 : 9) << CCK_SHRES_SHIFT;
                        if (hcenter_v2_end >= maxhpos << CCK_SHRES_SHIFT) {
                                hcenter_v2_end -= maxhpos << CCK_SHRES_SHIFT;
                        }
@@ -1005,7 +1011,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
                                        record_dma_event(DMA_EVENT_HBE, diw_to_hpos(cc->linepos), vpos);
                                }
                        }
-               } else  if (hbstrt_v2 > hbstop_v2) {
+               } else  if (hbstrt_v2 >= hbstop_v2) { // equal: blank enable wins
                        if (hbstop_v2 < chpos && hbstop_v2 >= last_recorded_diw_hpos) {
                                if (next_color_change == last_color_change && exthblank_state) {
                                        cc = &curr_color_changes[next_color_change];
@@ -1068,7 +1074,7 @@ static void sync_color_changes(int hpos)
 // erase (color0 or bblank) area between previous end and new start
 static void hdiw_restart(int diw_last, int diw_current)
 {
-       if (diw_last >= diw_current || line_hidden() || nocustom()) {
+       if (diw_last >= diw_current || line_hidden() || custom_disabled) {
                return;
        }
        // update state
@@ -1791,7 +1797,7 @@ int get_bitplane_dma_rel(int hpos, int off)
 static int islinetoggle(void)
 {
        int linetoggle = 0;
-       if (!(new_beamcon0 & 0x0800) && !(new_beamcon0 & 0x0020) && ecs_agnus) {
+       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
@@ -3383,12 +3389,23 @@ static void do_long_fetch(int hpos, int nwords, int fm)
 #endif
        }
 
+       plane0 = toscr_nr_planes > 0;
+
+       int cnt = nwords;
+       while (exthblank) {
+               cnt -= fetchstart;
+               hpos += fetchstart;
+               hbstrt_bordercheck(hpos, false);
+               if (cnt <= 0) {
+                       break;
+               }
+       }
+
        out_nbits += nwords * 16;
        out_offs += out_nbits >> 5;
        out_nbits &= 31;
        quick_add_delay_cycles((nwords * 16) << toscr_res_pixels_shift);
 
-       plane0 = toscr_nr_planes > 0;
 }
 
 #endif
@@ -3853,7 +3870,7 @@ static bool isbrdblank(int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
        brdntrans = ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x10);
        // ECSENA=0: hardwired horizontal, strobe vertical
        // ECSENA=1: EXTBLKEN=0: hardwired blanking, strobe vertical
-       // ECSENA=1: EXTBLKEN=1: blanking equals HSYNC, no vertical, AGA: programmed horizontal, strobe vertical
+       // ECSENA=1: EXTBLKEN=1: blanking equals HSYNC if VARCSYEN=1, blanking equals HBSTRT-HBSTOP if VARCSYEN=0, no vertical, AGA: programmed horizontal, strobe vertical
        extblank = (bplcon0 & 1) && (bplcon3 & 1);
 #else
        brdblank = false;
@@ -4559,7 +4576,8 @@ static void finish_decisions(int hpos)
                thisline_decision.bplres = output_res(RES_LORES);
        }
 
-       sync_color_changes(hpos + 1);
+       // Add DDF_OFFSET to detect blanking changes past hpos max
+       sync_color_changes(hpos + DDF_OFFSET / 2 + 1);
 
        /* Large DIWSTOP values can cause the stop position never to be
        * reached, so the state machine always stays in the same state and
@@ -4735,29 +4753,40 @@ static void reset_decisions_hsync_start(void)
        thisline_decision.bplcon4bm = bplcon4;
        thisline_decision.bplcon4sp = bplcon4;
        thisline_decision.fmode = fmode;
+
        // 0 = vb, 1 = vb off, 3 = vb off, previous line was bitplane + vb on
        //bool t = thisline_decision.plfleft >= 0 && (thisline_decision.vb & 1) == 0 && !vb_state && !vb_end_line;
        if (!aga_mode && ecs_denise && exthblank) {
                // ECS Denise + EXTHBLANK: VBLANK blanking is always disabled
-               thisline_decision.vb = 1;
+               thisline_decision.vb = VB_NOVB;
        } else {
-               thisline_decision.vb = vb_start_line > 1 + vblank_extraline ? 0 : 1;
+               // 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 & 0x1000) && ecs_agnus) {
-               if (!thisline_decision.vb) {
-                       thisline_decision.vb |= 2;
+       if ((beamcon0 & BEAMCON0_VARVBEN) && ecs_agnus) {
+               if (!(thisline_decision.vb & 15)) {
+                       thisline_decision.vb |= VB_PRGVB;
                }
        }
+
        // doublescan last line garbage workaround
        if (doflickerfix_active()) {
                if (vpos < maxvpos_display_vsync || (!lof_display && vpos >= maxvpos - 1) || (lof_display && vpos >= maxvpos - 1)) {
-                       thisline_decision.vb |= 4;
+                       thisline_decision.vb |= VB_XBLANK;
                }
        }
 
        if (!ecs_denise && vb_end_line) {
-               thisline_decision.vb = 1;
+               thisline_decision.vb = VB_NOVB;
        }
 #endif
 
@@ -4797,7 +4826,7 @@ static void reset_decisions_hsync_start(void)
        if (1 && fetchmode >= 2 && !doflickerfix_active()) {
                // handle bitplane data wrap around
                bool toshift = false;
-               if ((exthblank || (beamcon0 & 0x0110)) && (thisline_decision.bplres == 0 || currprefs.chipset_hr)) {
+               if ((exthblank || (beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN))) && (thisline_decision.bplres == 0 || currprefs.chipset_hr)) {
                        for (int i = 0; i < thisline_decision.nr_planes; i++) {
                                if (todisplay2_aga_saved[i]) {
                                        toshift = true;
@@ -4873,7 +4902,7 @@ static void reset_decisions_hsync_start(void)
 #endif
        }
 
-       if (debug_dma && (new_beamcon0 & (0x000 | 0x0010))) {
+       if (debug_dma && (new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN))) {
                record_dma_event(DMA_EVENT_HSS, hpos, vpos);
                record_dma_event(DMA_EVENT_HSE, hsstop, vpos);
        }
@@ -5003,7 +5032,7 @@ static void checklacecount(bool lace)
 static void set_hcenter(void)
 {
        if (!aga_mode && ecs_denise && (bplcon0 & 1) && (bplcon3 & 1)) {
-               if (beamcon0 & 0x0210) {
+               if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) {
                        hcenter_v2 = (hcenter & 0xff) << CCK_SHRES_SHIFT;
                } else {
                        hcenter_v2 = 132 << CCK_SHRES_SHIFT;
@@ -5037,6 +5066,7 @@ static void updateextblk(void)
                hbstop_v |= (hbstop >> 8) & 7;
        }
        if (aga_mode) {
+               // AGA horizontal blanking is simple
                // hblank has 1 lores pixel offset
                hbstrt_v2 = hbstrt_v - 4;
                if (hbstrt_v >= (1 << CCK_SHRES_SHIFT) && hbstrt_v2 < (1 << CCK_SHRES_SHIFT)) {
@@ -5048,17 +5078,40 @@ static void updateextblk(void)
                }
                exthblank = (bplcon0 & 1) && (bplcon3 & 1);
        } else {
-               if (new_beamcon0 & 0x0010) { // VARCSYEN
-                       // ECS HBLANK uses CSYNC input and matches HSSYNC period.
+               // ECS Denise CSYNC horizontal blanking is complex
+               if (new_beamcon0 & BEAMCON0_VARCSYEN) {
+                       // ECS Denise HBLANK uses CSYNC input and matches programmed HSYNC period.
                        hbstrt_v2 = (hsstrt & 0xff) << CCK_SHRES_SHIFT;
                        hbstop_v2 = (hsstop & 0xff) << CCK_SHRES_SHIFT;
-                       exthblank = (bplcon0 & 1) && (bplcon3 & 1);
+               } else if (new_beamcon0 & BEAMCON0_BLANKEN) {
+                       // HBSTRT/HBSTOP blanking
+                       hbstrt_v2 = hbstrt_v;
+                       hbstop_v2 = hbstop_v;
                } else {
-                       exthblank = false;
+                       // ECS Denise HBLANK uses CSYNC input and matches hardwired HSYNC period.
+                       hbstrt_v2 = 18 << CCK_SHRES_SHIFT;
+                       hbstop_v2 = 35 << CCK_SHRES_SHIFT;
+               }
+               if (new_beamcon0 & BEAMCON0_CSYTRUE) {
+                       uae_u16 tmp = hbstrt_v2;
+                       hbstrt_v2 = hbstop_v2;
+                       hbstop_v2 = tmp;
+               }
+               hbstrt_v = hbstrt_v2;
+               hbstop_v = hbstop_v2;
+               // hblank has 1 lores pixel offset
+               hbstrt_v2 -= 4;
+               hbstop_v2 -= 4;
+               if (hbstrt_v >= (1 << CCK_SHRES_SHIFT) && hbstrt_v2 < (1 << CCK_SHRES_SHIFT)) {
+                       hbstrt_v2 += maxhpos << CCK_SHRES_SHIFT;
                }
+               if (hbstop_v >= (1 << CCK_SHRES_SHIFT) && hbstop_v2 < (1 << CCK_SHRES_SHIFT)) {
+                       hbstop_v2 += maxhpos << CCK_SHRES_SHIFT;
+               }
+               exthblank = (bplcon0 & 1) && (bplcon3 & 1);
        }
 
-       if (new_beamcon0 & 0x0110) { // VARHSYEN | VARCSYEN
+       if (new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN)) {
 
                hsyncstartpos = hsstrt;
                hsstop_detect = hsstrt + 17;
@@ -5121,9 +5174,15 @@ static void updateextblk(void)
        // hsync start offset adjustment
        if (hbstrt_v2 <= (hsyncstartpos_start << CCK_SHRES_SHIFT)) {
                hbstrt_v2 += maxhpos << CCK_SHRES_SHIFT;
+               if (hbstrt_v2 > (maxhpos + hsyncstartpos_start_cycles) << CCK_SHRES_SHIFT) {
+                       hbstrt_v2 = 1 << CCK_SHRES_SHIFT;
+               }
        }
        if (hbstop_v2 <= (hsyncstartpos_start << CCK_SHRES_SHIFT)) {
                hbstop_v2 += maxhpos << CCK_SHRES_SHIFT;
+               if (hbstop_v2 > (maxhpos + hsyncstartpos_start_cycles) << CCK_SHRES_SHIFT) {
+                       hbstop_v2 = 1 << CCK_SHRES_SHIFT;
+               }
        }
 
        int strt = hbstrt_v2;
@@ -5171,7 +5230,7 @@ struct chipset_refresh *get_chipset_refresh(struct uae_prefs *p)
 {
        struct amigadisplay *ad = &adisplays[0];
        int islace = interlace_seen ? 1 : 0;
-       int isntsc = (beamcon0 & 0x20) ? 0 : 1;
+       int isntsc = (beamcon0 & BEAMCON0_PAL) ? 0 : 1;
        int custom = programmedmode == 1 ? 1 : 0;
 
        if (!ecs_agnus) {
@@ -5211,7 +5270,7 @@ void compute_framesync(void)
        struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
        struct amigadisplay *ad = &adisplays[0];
        int islace = interlace_seen ? 1 : 0;
-       int isntsc = (beamcon0 & 0x20) ? 0 : 1;
+       int isntsc = (beamcon0 & BEAMCON0_PAL) ? 0 : 1;
        bool found = false;
 
        if (islace) {
@@ -5314,8 +5373,14 @@ void compute_framesync(void)
                int start = hsyncstartpos >> CCK_SHRES_SHIFT;
                int stop = hsyncstartpos_start_cycles;
 
-               vidinfo->drawbuffer.inwidth = ((maxhpos - (maxhpos - start + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2;
-               vidinfo->drawbuffer.inxoffset = stop * 2;
+               int w;
+               if (maxhpos > start) {
+                       w = maxhpos - start;
+               } else {
+                       w = maxhpos - (start - maxhpos);
+               }
+               vidinfo->drawbuffer.inwidth = (((w + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2;
+               vidinfo->drawbuffer.inxoffset = stop * 4;
                
                vidinfo->drawbuffer.extrawidth = 0;
                vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth;
@@ -5334,7 +5399,7 @@ void compute_framesync(void)
                if (currprefs.gfx_extraheight > 0) {
                        vidinfo->drawbuffer.extraheight = currprefs.gfx_extraheight;
                }
-               if (vidinfo->drawbuffer.extrawidth == -2 && ((new_beamcon0 & (0x1000 | 0x0200 | 0x0010)) || currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME)) {
+               if (vidinfo->drawbuffer.extrawidth == -2 && ((new_beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) || currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME)) {
                        vidinfo->drawbuffer.extrawidth = -1;
                }
                vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth;
@@ -5377,6 +5442,8 @@ void compute_framesync(void)
                line_decisions[i].plfleft = -2;
        }
 
+       check_nocustom();
+
        compute_vsynctime();
 
        hblank_hz = (currprefs.ntscmode ? CHIPSET_CLOCK_NTSC : CHIPSET_CLOCK_PAL) / (maxhpos + (islinetoggle() ? 0.5 : 0));
@@ -5419,18 +5486,18 @@ static void init_hz(bool checkvposw)
 
        doublescan = 0;
        programmedmode = 0;
-       if ((beamcon0 & (0x80 | 0x20)) != (new_beamcon0 & (0x80 | 0x20))) {
+       if ((beamcon0 & (BEAMCON0_VARBEAMEN | BEAMCON0_PAL)) != (new_beamcon0 & (BEAMCON0_VARBEAMEN | BEAMCON0_PAL))) {
                hzc = 1;
        }
        if (beamcon0 != new_beamcon0) {
                vpos_count_diff = vpos_count = 0;
        }
-       if ((beamcon0 & (0x1000 | 0x0200 | 0x0010)) != (new_beamcon0 & (0x1000 | 0x0200 | 0x0010))) {
+       if ((beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) != (new_beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) {
                hzc = 1;
        }
 
        beamcon0 = new_beamcon0;
-       isntsc = (beamcon0 & 0x20) ? 0 : 1;
+       isntsc = (beamcon0 & BEAMCON0_PAL) ? 0 : 1;
        islace = (interlace_seen) ? 1 : 0;
        if (!ecs_agnus) {
                isntsc = currprefs.ntscmode ? 1 : 0;
@@ -5461,7 +5528,7 @@ static void init_hz(bool checkvposw)
        }
 
        dmal_htotal_mask = 0xffff;
-       if (beamcon0 & 0x0080) {
+       if (beamcon0 & BEAMCON0_VARBEAMEN) {
                // programmable scanrates (ECS Agnus)
                if (vtotal >= MAXVPOS) {
                        vtotal = MAXVPOS - 1;
@@ -5482,7 +5549,7 @@ static void init_hz(bool checkvposw)
 
        // after vsync, it seems earlier possible visible line is vsync+3.
        int vsync_startline = 3;
-       if ((beamcon0 & 0x1000) && (beamcon0 & (0x0200 | 0x0010))) {
+       if ((beamcon0 & BEAMCON0_VARVBEN) && (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) {
                vsync_startline += vsstrt;
                if (vsync_startline >= maxvpos / 2) {
                        vsync_startline = 3;
@@ -5528,7 +5595,7 @@ static void init_hz(bool checkvposw)
        } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
                minfirstline_hw -= EXTRAHEIGHT_BROADCAST_TOP;
        }
-       if (beamcon0 & 0x0080) {
+       if (beamcon0 & BEAMCON0_VARBEAMEN) {
                minfirstline_hw = 0;
        }
 
@@ -5541,7 +5608,7 @@ static void init_hz(bool checkvposw)
                vblank_hz = (isntsc ? 15734.0 : 15625.0) / vpos_count;
                vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = (float)vblank_hz;
                maxvpos_nom = vpos_count - (lof_store ? 1 : 0);
-               if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & 0x80)) {
+               if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & BEAMCON0_VARBEAMEN)) {
                        maxvpos_display = maxvpos_nom;
                } else if (maxvpos_nom < 256) {
                        maxvpos_display = 255;
@@ -5555,7 +5622,7 @@ static void init_hz(bool checkvposw)
                vpos_count_diff = maxvpos;
        }
 
-       if ((beamcon0 & 0x1000) && (beamcon0 & (0x0200 | 0x0010))) { // VARVBEN + VARVSYEN|VARCSYEN
+       if ((beamcon0 & BEAMCON0_VARVBEN) && (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) {
                minfirstline = vsync_startline;
                if (minfirstline > maxvpos / 2) {
                        minfirstline = vsync_startline;
@@ -5565,9 +5632,9 @@ static void init_hz(bool checkvposw)
                if (vsstrt > 0 && vsstrt < maxvpos / 2) {
                        maxvpos_display_vsync += vsstrt;
                }
-       } else if (beamcon0 & (0x0200 | 0x0010)) { // VARVSYEN | VARCSYEN
+       } else if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) {
                firstblankedline = maxvpos + 1;
-       } else if (beamcon0 & 0x1000) { // VARVBEN
+       } else if (beamcon0 & BEAMCON0_VARVBEN) {
                firstblankedline = vbstrt;
                if (vsstrt > 0 && vsstrt < maxvpos / 2) {
                        maxvpos_display_vsync += vsstrt;
@@ -5575,14 +5642,13 @@ static void init_hz(bool checkvposw)
        } else {
                firstblankedline = maxvpos + 1;
        }
-
-       if (beamcon0 & (0x1000 | 0x0200 | 0x0010)) {
+       if (beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) {
                programmedmode = 2;
        }
 
        int eh = currprefs.gfx_extraheight;
        if (eh > 0) {
-               if (beamcon0 & (0x0200 | 0x0010)) {
+               if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) {
                        maxvpos_display_vsync += eh / 2;
                        minfirstline -= eh / 2;
                } else {
@@ -5611,7 +5677,7 @@ static void init_hz(bool checkvposw)
                minfirstline = minfirstline_hw;
        }
 
-       if (beamcon0 & (0x0200 | 0x0010)) {
+       if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) {
                if (maxvpos_display_vsync >= vsstrt) {
                        maxvpos_display_vsync = vsstrt;
                }
@@ -5623,7 +5689,7 @@ static void init_hz(bool checkvposw)
                }
        }
 
-       if (beamcon0 & 0x80) {
+       if (beamcon0 & BEAMCON0_VARBEAMEN) {
                vblank_hz_nom = vblank_hz = clk / (maxvpos * maxhpos);
                vblank_hz_shf = vblank_hz;
                vblank_hz_lof = clk / ((maxvpos + 1) * maxhpos);
@@ -5787,6 +5853,7 @@ static void calcdiw(void)
 /* display mode changed (lores, doubling etc..), recalculate everything */
 void init_custom(void)
 {
+       check_nocustom();
        update_mirrors();
        create_cycle_diagram_table();
        reset_drawing();
@@ -5902,7 +5969,7 @@ STATIC_INLINE uae_u16 ADKCONR(void)
 
 STATIC_INLINE int islightpentriggered(void)
 {
-       if (beamcon0 & 0x2000) // LPENDIS
+       if (beamcon0 & BEAMCON0_LPENDIS)
                return 0;
        return lightpen_triggered != 0;
 }
@@ -5937,8 +6004,17 @@ static bool hsyncdelay(void)
 
 #define CPU_ACCURATE (currprefs.cpu_model < 68020 || (currprefs.cpu_model == 68020 && currprefs.cpu_memory_cycle_exact))
 
+static void check_line_enabled(void)
+{
+       line_disabled &= ~3;
+       line_disabled |= line_hidden() ? 1 : 0;
+       line_disabled |= custom_disabled ? 2 : 0;
+}
+
 static void vb_check(void)
 {
+       check_line_enabled();
+
        // A1000 Agnus VBSTRT=first line, OCS and later: VBSTRT=last line
        if (currprefs.cs_dipagnus) {
                if (vpos == 0) {
@@ -6118,7 +6194,7 @@ static uae_u16 HHPOSR(void)
        if (islightpentriggered()) {
                v = hhpos_lpen;
        } else {
-               uae_u16 max = (new_beamcon0 & 0x40) ? htotal : maxhpos - 1;
+               uae_u16 max = (new_beamcon0 & BEAMCON0_DUAL) ? htotal : maxhpos - 1;
                v = hhpos + current_hpos() - hhpos_hpos;
                if (hhpos <= max || v >= 0x100) {
                        if (max) {
@@ -6313,7 +6389,7 @@ static void COPJMP(int num, int vblank)
        cop_state.strobe = num;
        cop_state.last_strobe = num;
 
-       if (nocustom()) {
+       if (custom_disabled) {
                immediate_copper(num);
                return;
        }
@@ -6575,9 +6651,9 @@ static void ADKCON(int hpos, uae_u16 v)
 static void check_harddis(void)
 {
        // VARBEAMEN, HARDDIS, SHRES, UHRES
-       harddis_h = ecs_agnus && ((new_beamcon0 & 0x0080) || (new_beamcon0 & 0x4000) || (bplcon0 & 0x0040) || (bplcon0 & 0x0080));
+       harddis_h = ecs_agnus && ((new_beamcon0 & BEAMCON0_VARBEAMEN) || (new_beamcon0 & BEAMCON0_HARDDIS) || (bplcon0 & 0x0040) || (bplcon0 & 0x0080));
        // VARBEAMEN, VARVBEN, HARDDIS
-       harddis_v = ecs_agnus && ((new_beamcon0 & 0x0080) || (new_beamcon0 & 0x1000) || (new_beamcon0 & 0x4000));
+       harddis_v = ecs_agnus && ((new_beamcon0 & BEAMCON0_VARBEAMEN) || (new_beamcon0 & BEAMCON0_VARVBEN) || (new_beamcon0 & BEAMCON0_HARDDIS));
 }
 
 static void BEAMCON0(int hpos, uae_u16 v)
@@ -6587,7 +6663,7 @@ static void BEAMCON0(int hpos, uae_u16 v)
                        new_beamcon0 = v;
                        write_log(_T("BEAMCON0 = %04X, PC=%08X\n"), v, M68K_GETPC);
                        // not LPENDIS, LOLDIS, PAL, BLANKEN, SYNC INVERT
-                       if (v & ~(0x2000 | 0x0800 | 0x0020 | 0x0008 | 0x0004 | 0x0002 | 0x0001)) {
+                       if (v & ~(BEAMCON0_LPENDIS | BEAMCON0_LOLDIS | BEAMCON0_PAL | BEAMCON0_BLANKEN | BEAMCON0_CSYTRUE | BEAMCON0_VSYTRUE | BEAMCON0_HSYTRUE)) {
                                dumpsync();
                        }
                }
@@ -6616,19 +6692,19 @@ static void varsync(int reg, bool resync)
                return;
        }
        // TOTAL
-       if ((reg == 0x1c0 || reg == 0x1c8) && (beamcon0 & 0x0080)) {
+       if ((reg == 0x1c0 || reg == 0x1c8) && (beamcon0 & BEAMCON0_VARBEAMEN)) {
                varsync_changed = 1;
        }
        // VB
-       if ((reg == 0x1cc || reg == 0x1ce) && (beamcon0 & 0x1000)) {
+       if ((reg == 0x1cc || reg == 0x1ce) && (beamcon0 & BEAMCON0_VARVBEN)) {
                varsync_changed = 1;
        }
        // VS
-       if ((reg == 0x1e0 || reg == 0x1ca) && (beamcon0 & (0x0200 | 0x0010))) {
+       if ((reg == 0x1e0 || reg == 0x1ca) && (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN))) {
                varsync_changed = 1;
        }
        // HS
-       if ((reg == 0x1de || reg == 0x1c2) && (beamcon0 & (0x0100 | 0x0010))) {
+       if ((reg == 0x1de || reg == 0x1c2) && (beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN))) {
                varsync_changed = 1;
        }
 }
@@ -6644,7 +6720,7 @@ void set_picasso_hack_rate(int hz)
        if (!currprefs.cs_ciaatod)
                changed_prefs.cs_ciaatod = currprefs.cs_ciaatod = currprefs.ntscmode ? 2 : 1;
        if (p96refresh_active > 0) {
-               new_beamcon0 |= 0x80;
+               new_beamcon0 |= BEAMCON0_VARBEAMEN;
        }
        varsync_changed = 1;
 }
@@ -8551,7 +8627,7 @@ static int coppercomp(int hpos, bool blitwait)
 
 static void update_copper(int until_hpos)
 {
-       if (1 && (nocustom() || !copper_enabled_thisline)) {
+       if (1 && (custom_disabled || !copper_enabled_thisline)) {
                last_copper_hpos = until_hpos;
                return;
        }
@@ -8780,7 +8856,7 @@ next:
 
 static void compute_spcflag_copper(void)
 {
-       if (!dmaen(DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait || cop_state.state == COP_bltwait2 || nocustom())
+       if (!dmaen(DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_waitforever || cop_state.state == COP_bltwait || cop_state.state == COP_bltwait2 || custom_disabled)
                return;
        if (cop_state.state == COP_wait1) {
                int vp = vpos & (((cop_state.ir[1] >> 8) & 0x7F) | 0x80);
@@ -9705,6 +9781,8 @@ static void vsync_handler_post(void)
        //write_log (_T("%d %d %d\n"), vsynctimebase, read_processor_time () - vsyncmintime, read_processor_time () - prevtime);
        prevtime = read_processor_time();
 
+       check_nocustom();
+
 #if CUSTOM_DEBUG > 1
        if ((intreq & 0x0020) && (intena & 0x0020))
                write_log(_T("vblank interrupt not cleared\n"));
@@ -9797,7 +9875,8 @@ static void vsync_handler_post(void)
 
        devices_vsync_post();
 
-       if ((beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000)) != (new_beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000))) {
+       if ((beamcon0 & (BEAMCON0_VARCSYEN | BEAMCON0_PAL | BEAMCON0_VARBEAMEN | BEAMCON0_VARHSYEN | BEAMCON0_VARVSYEN | BEAMCON0_VARVBEN | BEAMCON0_HARDDIS)) !=
+               (new_beamcon0 & (BEAMCON0_VARCSYEN | BEAMCON0_PAL | BEAMCON0_VARBEAMEN | BEAMCON0_VARHSYEN | BEAMCON0_VARVSYEN | BEAMCON0_VARVBEN | BEAMCON0_HARDDIS))) {
                if (!varsync_changed) {
                        varsync_changed = 2;
                }
@@ -9883,6 +9962,7 @@ static void hsync_scandoubler(int hpos)
        int lof = lof_display;
        next_lineno++;
        scandoubled_line = 1;
+       line_disabled |= 8;
        last_hdiw = 0 - 1;
 
        for (int i = 0; i < MAX_PLANES; i++) {
@@ -9930,6 +10010,7 @@ static void hsync_scandoubler(int hpos)
        finish_decisions(hpos);
        hsync_record_line_state(next_lineno, nln_normal, thisline_changed);
        scandoubled_line = 0;
+       line_disabled &= ~8;
 
        dmacon = odmacon;
        copper_enabled_thisline = ocop;
@@ -10252,7 +10333,7 @@ static void hsync_handlerh(bool onvsync)
 {
        int hpos = current_hpos();
 
-       if (!nocustom()) {
+       if (!custom_disabled) {
 
                if (doflickerfix_active()) {
                        finish_decisions(hpos);
@@ -10299,7 +10380,7 @@ static void set_hpos(void)
 // this finishes current line
 static void hsync_handler_pre(bool onvsync)
 {
-       if (!nocustom()) {
+       if (!custom_disabled) {
 
                // make sure decisions are done to end of scanline
                finish_partial_decision(maxhpos);
@@ -10356,6 +10437,7 @@ static void hsync_handler_pre(bool onvsync)
                vpos = 0;
                vsync_counter++;
        }
+       check_line_enabled();
 
        hpos_hsync_extra = maxhpos;
 
@@ -11084,7 +11166,7 @@ static void hsync_handler_post(bool onvsync)
                CIAB_tod_handler(18);
        } else if (ciahsyncs) {
                CIA_hsync_posthandler(true, ciahsyncs);
-               if (beamcon0 & 0x0100) {
+               if (beamcon0 & BEAMCON0_VARHSYEN) {
                        if (hsstop < (maxhpos & ~1) && hsstrt < maxhpos) {
                                CIAB_tod_handler(hsstrt);
                        }
@@ -11127,7 +11209,7 @@ static void hsync_handler_post(bool onvsync)
 #endif
        } else if (currprefs.cs_ciaatod == 0 && ciavsyncs) {
                // CIA-A TOD counter increases when vsync pulse ends
-               if (beamcon0 & 0x0200) {
+               if (beamcon0 & BEAMCON0_VARVSYEN) {
                        if (vpos == vsstop && vs_state == true) {
                                CIAA_tod_inc(lof_store ? hsstop : hsstop + hcenter);
                        }
@@ -11138,7 +11220,7 @@ static void hsync_handler_post(bool onvsync)
                }
        }
 
-       if (!nocustom ()) {
+       if (!custom_disabled) {
                if (!currprefs.blitter_cycle_exact && blt_info.blit_main && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) {
                        blitter_slowdown(thisline_decision.plfleft, thisline_decision.plfright - (16 << fetchmode),
                                cycle_diagram_total_cycles[fetchmode][GET_RES_AGNUS (bplcon0)][GET_PLANES_LIMIT (bplcon0)],
@@ -11162,7 +11244,13 @@ static void hsync_handler_post(bool onvsync)
                lof_lastline = lof_store != 0;
        }
 
-       vb_end_next_line = false;
+       if (vb_end_next_line2) {
+               vb_end_next_line2 = false;
+       }
+       if (vb_end_next_line) {
+               vb_end_next_line2 = true;
+               vb_end_next_line = false;
+       }
        if (vb_start_line) {
                vb_start_line++;
        }
@@ -11196,7 +11284,7 @@ static void hsync_handler_post(bool onvsync)
                        vs_state = false;
                }
 
-               if (new_beamcon0 & 0x1000) {
+               if (new_beamcon0 & BEAMCON0_VARVBEN) {
                        if (vbstrt == vpos) {
                                vbstrt_m = vpos;
                                vb_start_line = 1;
@@ -11226,7 +11314,7 @@ static void hsync_handler_post(bool onvsync)
                        hhbpl = 0;
                }
                uae_u16 add = maxhpos - 1;
-               uae_u16 max = (new_beamcon0 & 0x040) ? htotal : add;
+               uae_u16 max = (new_beamcon0 & BEAMCON0_DUAL) ? htotal : add;
                uae_u16 hhpos_old = hhpos;
                hhpos += add;
                if (hhpos_old <= max || hhpos >= 0x100) {
@@ -11242,7 +11330,7 @@ static void hsync_handler_post(bool onvsync)
                hhpos &= 0xff;
        }
 
-       if (beamcon0 & 0x20) {
+       if (beamcon0 & BEAMCON0_PAL) {
                if (vpos == 2 && !lof_store) {
                        vs_state_hw = true;
                }
@@ -11261,13 +11349,13 @@ static void hsync_handler_post(bool onvsync)
                }
        }
 
-       if (new_beamcon0 & (0x0200 | 0x0010)) {
+       if (new_beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) {
                vs_state_on = vs_state;
        } else {
                vs_state_on = vs_state_hw;
        }
 
-       if (!(new_beamcon0 & 0x1000)) {
+       if (!(new_beamcon0 & BEAMCON0_VARVBEN)) {
                vb_check();
        }
 
@@ -11520,6 +11608,7 @@ static void hsync_handler(void)
 
        }
        if (vpos == maxvpos_display_vsync) {
+               inputdevice_read_msg(true);
                vsync_display_render();
                vsync_display_rendered = false;
                lof_display = lof_store;
@@ -11713,7 +11802,7 @@ void custom_reset(bool hardreset, bool keyboardreset)
                CLXCON(0);
                CLXCON2(0);
                setup_fmodes(0);
-               beamcon0 = new_beamcon0 = beamcon0_saved = currprefs.ntscmode ? 0x00 : 0x20;
+               beamcon0 = new_beamcon0 = beamcon0_saved = currprefs.ntscmode ? 0x00 : BEAMCON0_PAL;
                blt_info.blit_main = 0;
                blt_info.blit_finald = 0;
                blt_info.blit_pending = 0;
@@ -13233,13 +13322,13 @@ void check_prefs_changed_custom(void)
                        currprefs.picasso96_nocustom = changed_prefs.picasso96_nocustom;
                        if (currprefs.ntscmode != changed_prefs.ntscmode) {
                                currprefs.ntscmode = changed_prefs.ntscmode;
-                               new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
+                               new_beamcon0 = currprefs.ntscmode ? 0x00 : BEAMCON0_PAL;
                        }
                        if ((changed_prefs.chipset_mask & CSMASK_ECS_AGNUS) && !(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
                                new_beamcon0 = beamcon0_saved;
                        } else if (!(changed_prefs.chipset_mask & CSMASK_ECS_AGNUS) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
                                beamcon0_saved = beamcon0;
-                               beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
+                               beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : BEAMCON0_PAL;
                                diwhigh = 0;
                                diwhigh_written = 0;
                                bplcon0 &= ~(0x10 | 0x01);
index 430bae8c0256b95afc45e4aac80fc64536b45be5..102da53670eba925dd617ee31272a8d4033cff9c 100644 (file)
@@ -284,6 +284,9 @@ static uae_u8 ecs_genlock_features_mask;
 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;
 
@@ -471,6 +474,26 @@ static void reset_custom_limits(void)
        center_reset = 1;
 }
 
+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;
+       }
+}
+
+static void extblankcheck(void)
+{
+       if (exthblanken && ((dp_for_drawing->bplcon3 & 1) && (dp_for_drawing->bplcon0 & 1))) {
+               exthblank = true;
+       }
+       if (exthblanken && (!(dp_for_drawing->bplcon3 & 1) || !(dp_for_drawing->bplcon0 & 1))) {
+               exthblank = false;
+       }
+}
+
 static void reset_hblanking_limits(void)
 {
        hblank_left_start = visible_left_start;
@@ -533,7 +556,7 @@ static void set_vblanking_limits(void)
 
        bool hardwired = true;
        if (ecs_agnus) {
-               hardwired = (new_beamcon0 & 0x1000) == 0;
+               hardwired = (new_beamcon0 & BEAMCON0_VARVBEN) == 0;
        }
        if (hardwired) {
                int vbstrt, vbstop;
@@ -567,7 +590,7 @@ int get_vertical_visible_height(bool useoldsize)
        }
        bool hardwired = true;
        if (ecs_agnus) {
-               hardwired = (new_beamcon0 & 0x1000) == 0;
+               hardwired = (new_beamcon0 & BEAMCON0_VARVBEN) == 0;
        }
        if (hardwired) {
                get_vblanking_limits(&vbstrt, &vbstop, true);
@@ -596,6 +619,7 @@ static void set_hblanking_limits(void)
                        hbstop -= 2 << CCK_SHRES_SHIFT;
                }
        }
+
        if (hardwired) {
                doblank = true;
        } else if (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) {
@@ -607,7 +631,7 @@ static void set_hblanking_limits(void)
        if (doblank && programmedmode != 1) {
                // reposition to sync
                // use hardwired hblank emulation as overscan blanking.
-               if ((new_beamcon0 & 0x0110) && !hardwired) {
+               if ((new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN)) && !hardwired) {
                        extern uae_u16 hsstrt;
                        hbstrt += (hsstrt - 17) << CCK_SHRES_SHIFT;
                        hbstop += (hsstrt - 17) << CCK_SHRES_SHIFT;
@@ -682,7 +706,7 @@ void check_custom_limits(void)
                visible_top_start = top;
        if (bottom > top && bottom < visible_bottom_stop)
                visible_bottom_stop = bottom;
-       }
+}
 
 void set_custom_limits (int w, int h, int dx, int dy, bool blank)
 {
@@ -1018,7 +1042,6 @@ static int may_require_hard_way;
 static int linetoscr_diw_start, linetoscr_diw_end;
 static int native_ddf_left, native_ddf_right;
 static int hamleftborderhidden;
-static uae_u8 vb_state;
 
 static int pixels_offset;
 static int src_pixel;
@@ -1051,21 +1074,23 @@ static xcolnr getbgc(int blank)
        }
        bool extblken = ce_is_extblankset(colors_for_drawing.extra);
        // extblken=1: hblank and vblank = black
-       if (!(vb_state & 1) && extblken && aga_mode) {
+       if (!(vb_state & VB_NOVB) && extblken && aga_mode) {
+               return fullblack;
+       }
+       if (hposblank) {
                return fullblack;
        }
        bool brdblank = ce_is_borderblank(colors_for_drawing.extra);
 #if 0
-       // if this line next line after VB end and bitplane DMA was active in previous (hidden) line: borderblank is ignored.
-       if (vb_state == 3) {
-               brdblank = false;
+       if (brdblank && blank == 4) {
+               return colors_for_drawing.acolors[0];
        }
 #endif
        // borderblank = black (overrides extblken)
        if (brdblank && blank >= 0) {
                return fullblack;
        }
-       if (hposblank || blank > 0) {
+       if (blank > 0) {
                return fullblack;
        }
        return colors_for_drawing.acolors[0];
@@ -1452,7 +1477,7 @@ static void fill_line_border(int lineno)
        int endpos = visible_left_border + vidinfo->drawbuffer.inwidth;
        int w = endpos - lastpos;
 
-       if (lineno < visible_top_start || lineno < vblank_top_start || lineno >= visible_bottom_stop || lineno >= vblank_bottom_stop || vb_state >= 4) {
+       if (lineno < visible_top_start || lineno < vblank_top_start || lineno >= visible_bottom_stop || lineno >= vblank_bottom_stop || full_blank) {
                int b = hposblank;
                hposblank = 3;
                fill_line2(lastpos, w);
@@ -3135,16 +3160,6 @@ static bool isham(uae_u16 bplcon0)
        return 0;
 }
 
-static void extblankcheck(void)
-{
-       if (exthblanken && ((dp_for_drawing->bplcon3 & 1) && (dp_for_drawing->bplcon0 & 1))) {
-               exthblank = true;
-       }
-       if (exthblanken && (!(dp_for_drawing->bplcon3 & 1) || !(dp_for_drawing->bplcon0 & 1))) {
-               exthblank = false;
-       }
-}
-
 static void pfield_expand_dp_bplconx (int regno, int v, int hp, int vp)
 {
        regno -= RECORDED_REGISTER_CHANGE_OFFSET;
@@ -3231,6 +3246,7 @@ static void adjust_drawing_colors (int ctable, int need_full, bool blankcheck)
        if (colors_for_drawing.extra != oe) {
                reset_hblanking_limits();
                set_hblanking_limits();
+               expand_vb_state();
        }
 }
 
@@ -3296,96 +3312,99 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker
                }
 
                if (vp >= 0) {
-                       // left hblank (left edge to hblank end)
-                       if (nextpos_in_range > lastpos && lastpos < hblank_left_start) {
-                               int t = nextpos_in_range <= hblank_left_start ? nextpos_in_range : hblank_left_start;
-                               (*worker_border)(lastpos, t, 1);
-                               lastpos = t;
-                       }
 
-                       // vblank + programmed vblank / hardwired vblank
-                       if (vb_state == 2 || vb_state >= 4 || vbarea) {
+                       if (full_blank || vbarea) {
+                               // vblank + programmed vblank / hardwired vblank
 
-                               if (vbarea || vb_state >= 4) {
+                               if (vbarea || vb_state >= VB_XBLANK) {
                                        hposblank = 3;
                                }
-                               if (nextpos_in_range > lastpos && lastpos < playfield_end) {
-                                       int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
+                               if (nextpos_in_range > lastpos) {
+                                       int t = nextpos_in_range;
                                        (*worker_border)(lastpos, t, 1);
                                        lastpos = t;
                                }
 
-                               // normal
-                       } else if (playfield_start_pre >= playfield_start || !ce_is_borderblank(colors_for_drawing.extra)) {
+                       } else {
+                               // non-vblank scanline
 
-                               // 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, 0);
+                               // left hblank (left edge to hblank end)
+                               if (nextpos_in_range > lastpos && lastpos < hblank_left_start) {
+                                       int t = nextpos_in_range <= hblank_left_start ? nextpos_in_range : hblank_left_start;
+                                       (*worker_border)(lastpos, t, 1);
                                        lastpos = t;
                                }
 
-                               // playfield
-                               if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end) {
-                                       int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
-                                       if ((plf2pri >= 5 || plf1pri >= 5) && !aga_mode) {
-                                               weird_bitplane_fix(lastpos, t);
+                               if (playfield_start_pre >= playfield_start || !ce_is_borderblank(colors_for_drawing.extra)) {
+
+                                       // 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);
+                                               lastpos = t;
                                        }
-                                       if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) {
-                                               playfield_hard_way(worker_pfield, lastpos, t);
-                                       } else {
-                                               (*worker_pfield)(lastpos, t, 0);
+
+                                       // playfield
+                                       if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end) {
+                                               int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
+                                               if ((plf2pri >= 5 || plf1pri >= 5) && !aga_mode) {
+                                                       weird_bitplane_fix(lastpos, t);
+                                               }
+                                               if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) {
+                                                       playfield_hard_way(worker_pfield, lastpos, t);
+                                               } else {
+                                                       (*worker_pfield)(lastpos, t, 0);
+                                               }
+                                               lastpos = t;
                                        }
-                                       lastpos = t;
-                               }
 
-                       } else {
-                               // special AGA borderblank 1 shres pixel delay
+                               } else {
+                                       // special AGA borderblank 1 shres pixel delay
 
-                               // 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, 0);
-                                       lastpos = t;
-                               }
-                               // AGA "buggy" borderblank, real background color visible, single shres pixel wide.
-                               if (nextpos_in_range > lastpos && lastpos < playfield_start) {
-                                       int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start;
-                                       (*worker_border)(lastpos, t, -1);
-                                       lastpos = t;
-                               }
+                                       // 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);
+                                               lastpos = t;
+                                       }
+                                       // AGA "buggy" borderblank, real background color visible, single shres pixel wide.
+                                       if (nextpos_in_range > lastpos && lastpos < playfield_start) {
+                                               int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start;
+                                               (*worker_border)(lastpos, t, -1);
+                                               lastpos = t;
+                                       }
 
-                               // playfield with last shres pixel not drawn.
-                               if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end_pre) {
-                                       int t = nextpos_in_range <= playfield_end_pre ? nextpos_in_range : playfield_end_pre;
-                                       if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) {
-                                               playfield_hard_way(worker_pfield, lastpos, t);
-                                       } else {
-                                               (*worker_pfield)(lastpos, t, 0);
+                                       // playfield with last shres pixel not drawn.
+                                       if (nextpos_in_range > lastpos && lastpos >= playfield_start && lastpos < playfield_end_pre) {
+                                               int t = nextpos_in_range <= playfield_end_pre ? nextpos_in_range : playfield_end_pre;
+                                               if (may_require_hard_way && (may_require_hard_way < 0 || (bplxor && may_require_hard_way && worker_pfield != pfield_do_linetoscr_bordersprite_aga))) {
+                                                       playfield_hard_way(worker_pfield, lastpos, t);
+                                               } else {
+                                                       (*worker_pfield)(lastpos, t, 0);
+                                               }
+                                               lastpos = t;
+                                       }
+
+                                       // last shres pixel of playfield blanked
+                                       if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre && lastpos < playfield_end) {
+                                               int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
+                                               (*worker_border)(lastpos, t, 0);
+                                               lastpos = t;
                                        }
-                                       lastpos = t;
                                }
 
-                               // last shres pixel of playfield blanked
-                               if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre && lastpos < playfield_end) {
-                                       int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
+                               // right border (playfield end to hblank start)
+                               if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre) {
+                                       int t = nextpos_in_range <= hblank_right_stop ? nextpos_in_range : hblank_right_stop;
                                        (*worker_border)(lastpos, t, 0);
                                        lastpos = t;
                                }
 
-                       }
-
-                       // right border (playfield end to hblank start)
-                       if (nextpos_in_range > lastpos && lastpos >= playfield_end_pre) {
-                               int t = nextpos_in_range <= hblank_right_stop ? nextpos_in_range : hblank_right_stop;
-                               (*worker_border)(lastpos, t, 0);
-                               lastpos = t;
-                       }
-
-                       // right hblank (hblank start to right edge, hblank start may be earlier than playfield end)
-                       if (nextpos_in_range > hblank_right_stop) {
-                               (*worker_border) (hblank_right_stop, nextpos_in_range, 1);
-                               lastpos = nextpos_in_range;
+                               // right hblank (hblank start to right edge, hblank start may be earlier than playfield end)
+                               if (nextpos_in_range > hblank_right_stop) {
+                                       (*worker_border) (hblank_right_stop, nextpos_in_range, 1);
+                                       lastpos = nextpos_in_range;
+                               }
                        }
                }
 
@@ -3515,7 +3534,10 @@ static void pfield_draw_line(struct vidbuffer *vb, int lineno, int gfx_ypos, int
        }
 
        have_color_changes = is_color_changes(dip_for_drawing);
-       vb_state = dp_for_drawing->vb;
+       if (vb_state != dp_for_drawing->vb) {
+               vb_state = dp_for_drawing->vb;
+               expand_vb_state();
+       }
        sprite_smaller_than_64_inuse = false;
 
        dh = dh_line;
@@ -4259,6 +4281,8 @@ static void draw_frame2(struct vidbuffer *vbin, struct vidbuffer *vbout)
        set_vblanking_limits();
        reset_hblanking_limits();
        set_hblanking_limits();
+       extblankcheck();
+       expand_vb_state();
 
        bool firstline = true;
        int lastline = thisframe_y_adjust_real - (1 << linedbl);
@@ -4292,8 +4316,10 @@ static void draw_frame2(struct vidbuffer *vbin, struct vidbuffer *vbout)
                        largest = whereline;
 #endif
 
-               reset_hblanking_limits();
-               set_hblanking_limits();
+               if (ecs_denise) {
+                       reset_hblanking_limits();
+                       set_hblanking_limits();
+               }
 
                hposblank = 0;
                pfield_draw_line(vbout, line, whereline, wherenext);
index f6d49a245bd2831bd11280f72d52126052632a13..166c5885f97c4c65a00e05232a26d4def5b8bb9d 100644 (file)
 #include "uae/types.h"
 #include "machdep/rpt.h"
 
+#define BEAMCON0_HARDDIS       0x4000
+#define BEAMCON0_LPENDIS       0x2000
+#define BEAMCON0_VARVBEN       0x1000
+#define BEAMCON0_LOLDIS                0x0800
+#define BEAMCON0_CSCBEN                0x0400
+#define BEAMCON0_VARVSYEN      0x0200
+#define BEAMCON0_VARHSYEN      0x0100
+#define BEAMCON0_VARBEAMEN     0x0080
+#define BEAMCON0_DUAL          0x0040
+#define BEAMCON0_PAL           0x0020
+#define BEAMCON0_VARCSYEN      0x0010
+#define BEAMCON0_BLANKEN       0x0008
+#define BEAMCON0_CSYTRUE       0x0004
+#define BEAMCON0_VSYTRUE       0x0002
+#define BEAMCON0_HSYTRUE       0x0001
+
 extern bool aga_mode, ecs_agnus, ecs_denise, direct_rgb;
 
 /* These are the masks that are ORed together in the chipset_mask option.
index 2c0d0ef8795c4de2292bb8521448c020ebfbde75..e137dc21e7956684dfed7e6894a69114aa8aa194 100644 (file)
@@ -142,6 +142,11 @@ 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
+
 struct color_entry {
        uae_u16 color_regs_ecs[32];
 #ifndef AGA