]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
BPL1DAT updates, programmed mode updates.
authorToni Wilen <twilen@winuae.net>
Sat, 1 Jan 2022 15:03:28 +0000 (17:03 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 1 Jan 2022 15:03:28 +0000 (17:03 +0200)
custom.cpp
drawing.cpp
include/drawing.h

index 970eb380cf4076aaca7543f3e82cb32643c32314..81c8f2f7fe2dc094842f5f5cfe816cc061d5e064 100644 (file)
@@ -183,7 +183,7 @@ static uae_u32 cop1lc, cop2lc, copcon;
 * horizontal defaults
 * 0x00   0 HCB
 * 0x01   1 HC1 (HSTART)
-* 0x09   9 VR1
+* 0x09   9 VR1 (HBLANK start)
 * 0x12  18 SHS (Horizontal sync start)
 * 0x1a  26 VER1 PAL
 * 0x1b  27 VER1 NTSC
@@ -322,12 +322,13 @@ static uae_u16 bplcon3_saved, bplcon4_saved;
 static int varsync_changed;
 uae_u16 vtotal, htotal;
 static int maxvpos_stored, maxhpos_stored;
-uae_u16 hsstop, hsstop_detect, hsstrt;
-static uae_u16 hbstop, hbstrt;
+uae_u16 hsstop, hsstrt;
+uae_u16 hbstop, hbstrt;
+static int hsstop_detect, hsstop_detect2;
 static uae_u16 vsstop, vsstrt;
 static uae_u16 vbstop, vbstrt;
 static uae_u16 hcenter, hcenter_v2, hcenter_v2_end;
-static uae_u16 hbstop_v, hbstrt_v, hbstop_v2, hbstrt_v2, hbstrt_v2o, hbstop_v2o;
+static uae_u16 hbstop_v, hbstrt_v, hbstop_v2, hbstrt_v2;
 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;
@@ -400,13 +401,13 @@ static int diwhigh_written;
 static int ddfstrt, ddfstop, plfstop_prev;
 static int ddfstrt_hpos, ddfstop_hpos;
 static int line_cyclebased, diw_change;
-static bool bpl_shifter;
+static int bpl_shifter;
 
 #define SET_LINE_CYCLEBASED line_cyclebased = 1;
 
 /* The display and data fetch windows */
 
-enum diw_states
+enum class diw_states
 {
        DIW_waiting_start, DIW_waiting_stop
 };
@@ -424,7 +425,7 @@ static int diwfirstword, diwlastword;
 static int last_diwlastword;
 static int hb_last_diwlastword;
 static int last_hdiw;
-static enum diw_states diwstate, hdiwstate;
+static diw_states diwstate, hdiwstate;
 static int diwstate_vpos;
 static int bpl_hstart;
 static bool exthblank, exthblank_state;
@@ -538,6 +539,7 @@ static int bprun_cycle;
 static int bprun_pipeline_flush_delay;
 static bool plane0, plane0p, plane0p_enabled, plane0p_forced, plane0_first_done;
 static int last_bpl1dat_hpos;
+static bool last_bpl1dat_hpos_early;
 static bool harddis_v, harddis_h;
 static uae_u16 dmal_alloc_mask;
 
@@ -580,7 +582,7 @@ static int delay_lastcycle[2], delay_hsynccycle;
 static int hack_delay_shift;
 static bool bplcon1_written;
 static bool bplcon0_planes_changed;
-static bool sprites_enabled_this_line, sprites_enabled_prev_line;
+static bool sprites_enabled_this_line;
 static int shifter_mask, toscr_delay_shifter[2];
 static int out_subpix[2];
 static bool speedup_first;
@@ -1109,7 +1111,7 @@ static void hdiw_restart(int diw_last, int diw_current)
 
 static void decide_diw_check_start(int start_diw_hpos, int end_diw_hpos, int extrahpos)
 {
-       if (hdiwstate == DIW_waiting_start) {
+       if (hdiwstate == diw_states::DIW_waiting_start) {
                if (diw_hstrt > start_diw_hpos && diw_hstrt < end_diw_hpos) {
                        int first = diwfirstword + extrahpos;
                        if (last_diwlastword >= 0) {
@@ -1132,13 +1134,13 @@ static void decide_diw_check_start(int start_diw_hpos, int end_diw_hpos, int ext
                                        record_dma_event(DMA_EVENT_HDIWS, diw_to_hpos(first), vpos);
                                }
                        }
-                       hdiwstate = DIW_waiting_stop;
+                       hdiwstate = diw_states::DIW_waiting_stop;
                }
        }
 }
 static void decide_diw_check_stop(int start_diw_hpos, int end_diw_hpos, int extrahpos)
 {
-       if (hdiwstate == DIW_waiting_stop) {
+       if (hdiwstate == diw_states::DIW_waiting_stop) {
                if (diw_hstop > start_diw_hpos && diw_hstop <= end_diw_hpos) {
                        int last = diwlastword + extrahpos;
                        if (last > thisline_decision.diwlastword) {
@@ -1150,7 +1152,7 @@ static void decide_diw_check_stop(int start_diw_hpos, int end_diw_hpos, int extr
                                        record_dma_event(DMA_EVENT_HDIWE, diw_to_hpos(last), vpos);
                                }
                        }
-                       hdiwstate = DIW_waiting_start;
+                       hdiwstate = diw_states::DIW_waiting_start;
                }
        }
 }
@@ -2959,10 +2961,10 @@ static void beginning_of_plane_block_early(int hpos)
        bprun_pipeline_flush_delay = maxhpos;
        flush_display(fetchmode);
        reset_bpl_vars();
-       bpl_shifter = true;
+       bpl_shifter = 1;
        int left = hpos + hpos_hsync_extra;
        thisline_decision.plfleft = left * 2;
-       if (hdiwstate == DIW_waiting_stop && thisline_decision.diwfirstword < 0) {
+       if (hdiwstate == diw_states::DIW_waiting_stop && thisline_decision.diwfirstword < 0) {
                // 1.5 lores pixels
                int v = hpos_to_diw(hpos);
                v += 6;
@@ -2975,11 +2977,11 @@ static void beginning_of_plane_block_early(int hpos)
 
 static void start_noborder(int hpos)
 {
-       bpl_shifter = true;
+       bpl_shifter = 1;
        reset_bpl_vars();
        if (thisline_decision.plfleft < 0) {
                thisline_decision.plfleft = hpos * 2;
-               if (hdiwstate == DIW_waiting_stop && thisline_decision.diwfirstword < 0) {
+               if (hdiwstate == diw_states::DIW_waiting_stop && thisline_decision.diwfirstword < 0) {
                        thisline_decision.diwfirstword = min_diwlastword;
                }
        }
@@ -3003,12 +3005,17 @@ static void beginning_of_plane_block(int hpos)
                }
 #endif
        todisplay_fetched = 3;
-       sprites_enabled_this_line = true;
        plane0_first_done = true;
-       last_bpl1dat_hpos = hpos;
+       if (hpos > last_bpl1dat_hpos) {
+               last_bpl1dat_hpos = hpos;
+       }
+       // HBLANK start to HSYNC start?
+       if (!exthblank && ecs_denise && hpos >= 12 && hpos < hsyncstartpos_start_cycles) {
+               last_bpl1dat_hpos_early = true;
+       }
 
        // do not mistake end of bitplane as start of low value hblank programmed mode
-       if (!bpl_shifter && hpos > REFRESH_FIRST_HPOS) {
+       if (bpl_shifter <= 0 && hpos > REFRESH_FIRST_HPOS) {
                start_noborder(hpos + hpos_hsync_extra);
        }
 
@@ -3567,7 +3574,7 @@ STATIC_INLINE void one_fetch_cycle_0(int hpos, int fm)
                uae_u16 d = cycle_line_pipe[offset];
                if ((d & CYCLE_PIPE_BITPLANE) && (d & 7) == 1) {
                        decide_diw(hpos);
-                       if (hdiwstate == DIW_waiting_stop || plane0p_forced) {
+                       if (hdiwstate == diw_states::DIW_waiting_stop || plane0p_forced) {
                                plane0p = true;
                        }
                }
@@ -3790,13 +3797,13 @@ static void decide_vline(void)
 
        /* Take care of the vertical DIW.  */
        if (vpos == plffirstline && !forceoff) {
-               diwstate = DIW_waiting_stop;
+               diwstate = diw_states::DIW_waiting_stop;
                diwstate_vpos = vpos;
                SET_LINE_CYCLEBASED;
        }
        // VB start line forces vertical display window off (if HARDDIS=0)
        if (vpos == plflastline || forceoff) {
-               diwstate = DIW_waiting_start;
+               diwstate = diw_states::DIW_waiting_start;
                diwstate_vpos = vpos;
                SET_LINE_CYCLEBASED;
        }
@@ -4356,6 +4363,7 @@ static void calcsprite(void)
                 * (undocumented feature)
                 */
        }
+       sprite_minx = 0;
 }
 
 static void decide_sprites(int hpos, bool usepointx, bool quick)
@@ -4367,9 +4375,6 @@ static void decide_sprites(int hpos, bool usepointx, bool quick)
        int gotdata = 0;
        int extrahpos = hsyncstartpos_start_cycles * 2; // hpos 0 to this value is visible in right border
 
-       if (!sprites_enabled_this_line && !brdspractive() && !quick)
-               return;
-
        point = (hpos + hpos_hsync_extra) * 2 - DDF_OFFSET;
        if (point <= last_sprite_point) {
                return;
@@ -4433,6 +4438,7 @@ static void decide_sprites(int hpos, bool usepointx, bool quick)
                        }
                        // (not really mutually exclusive of SSCAN2-bit but not worth the trouble)
                }
+               sprites_enabled_this_line = true;
        }
 
        for (int i = 0; i < count; i++) {
@@ -4585,7 +4591,7 @@ static void finish_decisions(int hpos)
        /* Large DIWSTOP values can cause the stop position never to be
        * reached, so the state machine always stays in the same state and
        * there's a more-or-less full-screen DIW. */
-       if (hdiwstate == DIW_waiting_stop && thisline_decision.diwfirstword >= 0) {
+       if (hdiwstate == diw_states::DIW_waiting_stop && thisline_decision.diwfirstword >= 0) {
                thisline_decision.diwlastword = max_diwlastword;
        }
 
@@ -4693,7 +4699,7 @@ static void reset_decisions_scanline_start(void)
                                record_color_change2(0, 0, COLOR_CHANGE_BLANK | 1);
                        }
                }
-               if (vb_end_next_line) {
+               if (vb_end_next_line2) {
                        record_color_change2(0, 0, COLOR_CHANGE_BLANK | 0);
                }
        }
@@ -4709,7 +4715,7 @@ static void reset_decisions_hsync_start(void)
        thisline_decision.diwfirstword = -1;
        thisline_decision.diwlastword = -1;
        // hdiw already open?
-       if (hdiwstate == DIW_waiting_stop) {
+       if (hdiwstate == diw_states::DIW_waiting_stop) {
                thisline_decision.diwfirstword = min_diwlastword;
                if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) {
                        MARK_LINE_CHANGED;
@@ -4768,7 +4774,7 @@ static void reset_decisions_hsync_start(void)
        }
        // if programmed vblank
        if ((beamcon0 & BEAMCON0_VARVBEN) && ecs_agnus) {
-               if (!(thisline_decision.vb & 15)) {
+               if (!thisline_decision.vb) {
                        thisline_decision.vb |= VB_PRGVB;
                }
        }
@@ -4776,7 +4782,7 @@ static void reset_decisions_hsync_start(void)
        // 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 |= VB_XBLANK;
+                       thisline_decision.vb |= VB_XBORDER;
                }
        }
 
@@ -4787,7 +4793,7 @@ static void reset_decisions_hsync_start(void)
 
        int left = thisline_decision.plfleft;
 
-       bpl_shifter = false;
+       bpl_shifter = 0;
        thisline_decision.plfleft = -1;
        thisline_decision.plflinelen = -1;
        thisline_decision.plfright = -1;
@@ -4831,7 +4837,6 @@ static void reset_decisions_hsync_start(void)
                if (bprun != 0 || todisplay_fetched || plane0 || plane0p || toshift) {
                        normalstart = false;
                        SET_LINE_CYCLEBASED;
-                       bpl_shifter = true;
                        if (toscr_hend == 2) {
                                for (int i = 0; i < MAX_PLANES; i++) {
                                        todisplay[i] = todisplay_saved[i];
@@ -4853,6 +4858,7 @@ static void reset_decisions_hsync_start(void)
                        bprun_pipeline_flush_delay = maxhpos;
                        plane0p_enabled = true;
                        plane0p_forced = true;
+                       bpl_shifter = -1;
                }
        }
 
@@ -4885,6 +4891,12 @@ static void reset_decisions_hsync_start(void)
                start_noborder(hpos);
        }
 
+       if (last_bpl1dat_hpos_early && !bpl_shifter) {
+               // BPLxDAT access already happened between refresh slot and hsync (this hpos):
+               // Close border
+               start_noborder(hpos);
+       }
+
        if (normalstart) {
                plane0 = false;
                plane0p = false;
@@ -4909,6 +4921,7 @@ static void reset_decisions_hsync_start(void)
 
        toscr_hend = 0;
        last_bpl1dat_hpos = -1;
+       last_bpl1dat_hpos_early = false;
        last_hblank_start = -1;
 }
 
@@ -5058,15 +5071,11 @@ static void updateextblk(void)
        hsyncendpos_hw = 24;
 
        hbstrt_v = (hbstrt & 0xff) << CCK_SHRES_SHIFT;
-       if (aga_mode) {
-               hbstrt_v |= (hbstrt >> 8) & 7;
-       }
        hbstop_v = (hbstop & 0xff) << CCK_SHRES_SHIFT;
-       if (aga_mode) {
-               hbstop_v |= (hbstop >> 8) & 7;
-       }
        if (aga_mode) {
                // AGA horizontal blanking is simple
+               hbstrt_v |= (hbstrt >> 8) & 7;
+               hbstop_v |= (hbstop >> 8) & 7;
                // hblank has 1 lores pixel offset
                hbstrt_v2 = hbstrt_v - 4;
                if (hbstrt_v >= (1 << CCK_SHRES_SHIFT) && hbstrt_v2 < (1 << CCK_SHRES_SHIFT)) {
@@ -5113,19 +5122,20 @@ static void updateextblk(void)
 
        if (new_beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN)) {
 
-               hsyncstartpos = hsstrt;
+               hsyncstartpos = hsstrt + 2;
+               if (hsyncstartpos >= maxhpos) {
+                       hsyncstartpos -= maxhpos;
+               }
                hsyncendpos = hsstop;
 
-               hsstop_detect = hsstrt + 17;
-               if (hsstop_detect >= maxhpos) {
-                       hsstop_detect -= maxhpos;
+               hsstop_detect2 = hsstrt + 21;
+               if (hsstop_detect2 >= maxhpos) {
+                       hsstop_detect2 -= maxhpos;
                }
-               hsyncendpos2 = hsstop_detect;
-
-               hsync_end_left_border = hsstop_detect;
+               hsyncendpos2 = hsstop_detect2;
 
                hsyncstartpos_start = hsyncstartpos;
-               if (hsyncstartpos < hsyncendpos) {
+               if (hsyncstartpos < maxhpos / 2) {
                        hsyncstartpos = maxhpos_short + hsyncstartpos_start;
                        hsynctotal = hsyncstartpos;
                } else {
@@ -5142,18 +5152,13 @@ static void updateextblk(void)
                        hsyncendpos2 = 2;
                }
 
-               if (0 && hsyncstartpos - hsyncendpos < maxhpos) {
-                       hsyncstartpos = maxhpos;
-               }
-
        } else {
 
                hsyncstartpos_start = hsyncstartpos_start_hw;
                hsyncstartpos = hsyncstartpos_hw;
                hsyncendpos2 = hsyncendpos = hsyncendpos_hw;
-               hsynctotal = 234;
-
-               hsync_end_left_border = 35 + 9;
+               hsynctotal = 227 + 7;
+               hsstop_detect2 = 35 + 9;
 
        }
 
@@ -5171,8 +5176,6 @@ static void updateextblk(void)
        if (hbstop_v2 >= (maxhpos << CCK_SHRES_SHIFT) + (1 << CCK_SHRES_SHIFT)) {
                hbstop_v2 = 0xffff;
        }
-       hbstrt_v2o = hbstrt_v2 >> (CCK_SHRES_SHIFT - 1);
-       hbstop_v2o = hbstop_v2 >> (CCK_SHRES_SHIFT - 1);
        // hsync start offset adjustment
        if (hbstrt_v2 <= (hsyncstartpos_start << CCK_SHRES_SHIFT)) {
                hbstrt_v2 += maxhpos << CCK_SHRES_SHIFT;
@@ -5353,80 +5356,52 @@ void compute_framesync(void)
        vidinfo->drawbuffer.inyoffset = -1;
        updateextblk();
 
-       if (programmedmode == 1) {
-               int res = GET_RES_AGNUS (bplcon0);
-               int vres = islace ? 1 : 0;
-               int res2, vres2;
-               int eres = 0;
-                       
-               res2 = currprefs.gfx_resolution;
-               if (doublescan > 0) {
-                       res2++;
-                       eres++;
-               }
-               if (res2 > RES_MAX) {
-                       res2 = RES_MAX;
-                       eres--;
-               }
-               
-               vres2 = currprefs.gfx_vresolution;
-               if (doublescan > 0 && !islace)
-                       vres2--;
-
-               if (vres2 < 0)
-                       vres2 = 0;
-               if (vres2 > VRES_QUAD)
-                       vres2 = VRES_QUAD;
+       hsync_end_left_border = hsstop_detect;
 
-               int start = hsyncstartpos >> CCK_SHRES_SHIFT;
-               int stop = hsyncendpos >> CCK_SHRES_SHIFT;
-               int w;
+       int res = GET_RES_AGNUS(bplcon0);
+       int eres = 0;
 
-               int minhsync = 23;
+       int res2 = currprefs.gfx_resolution;
 
-               if (start > maxhpos) {
-                       int hssize = stop - (start - maxhpos);
-                       if (hssize < minhsync) {
-                               hssize = minhsync;
-                       }
-                       w = maxhpos - hssize;
-               } else {
-                       int hssize = stop - start;
-                       if (hssize < minhsync) {
-                               hssize = minhsync;
-                       }
-                       w = maxhpos - hssize;
-               }
-
-               vidinfo->drawbuffer.inwidth = (w * 2) << res2;
+       if (doublescan > 0) {
+               res2++;
+               eres++;
+       }
+       if (res2 > RES_MAX) {
+               res2 = RES_MAX;
+               eres--;
+       }
 
-               vidinfo->drawbuffer.inxoffset = ((stop + 7) * 2) << eres;
-               
-               vidinfo->drawbuffer.extrawidth = 0;
-               vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth;
+       hsync_end_left_border <<= eres;
 
-               vidinfo->drawbuffer.inheight = ((firstblankedline < maxvpos ? firstblankedline : maxvpos) - minfirstline + 1) << vres2;
-               vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.inheight;
+       int vres2 = currprefs.gfx_vresolution;
+       if (doublescan > 0 && !islace) {
+               vres2--;
+       }
 
-       } else {
+       if (vres2 < 0) {
+               vres2 = 0;
+       }
+       if (vres2 > VRES_QUAD) {
+               vres2 = VRES_QUAD;
+       }
 
-               vidinfo->drawbuffer.inwidth = maxhpos_display << currprefs.gfx_resolution;
-               vidinfo->drawbuffer.extrawidth = -2;
-               if (currprefs.gfx_extrawidth > 0) {
-                       vidinfo->drawbuffer.extrawidth = currprefs.gfx_extrawidth;
-               }
-               vidinfo->drawbuffer.extraheight = -2;
-               if (currprefs.gfx_extraheight > 0) {
-                       vidinfo->drawbuffer.extraheight = currprefs.gfx_extraheight;
-               }
-               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;
-               vidinfo->drawbuffer.inheight = (maxvpos_display + maxvpos_display_vsync - minfirstline) << currprefs.gfx_vresolution;
-               vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.inheight;
-               vidinfo->drawbuffer.inxoffset = 0;
+       vidinfo->drawbuffer.inwidth = maxhpos_display << res2;
+       vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth;
+       vidinfo->drawbuffer.extrawidth = -2;
+       if (currprefs.gfx_extrawidth > 0) {
+               vidinfo->drawbuffer.extrawidth = currprefs.gfx_extrawidth << res2;
        }
+       vidinfo->drawbuffer.extraheight = -2;
+       if (currprefs.gfx_extraheight > 0) {
+               vidinfo->drawbuffer.extraheight = currprefs.gfx_extraheight << vres2;
+       }
+       if (vidinfo->drawbuffer.extrawidth == -2 && ((new_beamcon0 & (BEAMCON0_VARVBEN | BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) || currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME)) {
+               vidinfo->drawbuffer.extrawidth = -1;
+       }
+       vidinfo->drawbuffer.inheight = (maxvpos_display + maxvpos_display_vsync - minfirstline) << vres2;
+       vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.inheight;
+       vidinfo->drawbuffer.inxoffset = 0;
 
        if (vidinfo->drawbuffer.inwidth < 16)
                vidinfo->drawbuffer.inwidth = 16;
@@ -5576,7 +5551,6 @@ static void init_hz(bool checkvposw)
                }
        }
 
-       maxhpos_display = AMIGA_WIDTH_MAX;
        maxvpos_nom = maxvpos;
        maxvpos_display = maxvpos;
        maxvpos_display_vsync = 1;
@@ -5584,27 +5558,75 @@ static void init_hz(bool checkvposw)
        if (currprefs.cs_dipagnus) {
                maxvpos_display_vsync++;
        }
-       // A1000/OCS Denise has topmost line "almost" blanked
-       if (!ecs_denise) {
-               minfirstline--;
-       }
+
        vblank_firstline_hw = minfirstline;
 
-       if (currprefs.gfx_extrawidth > 0) {
-               maxhpos_display += currprefs.gfx_extrawidth;
-       } else if (currprefs.gfx_overscanmode < OVERSCANMODE_BROADCAST) {
-               // one pixel row missing from right border if OCS
-               if (!ecs_denise) {
-                       maxhpos_display--;
+       // calculate max possible display width in lores pixels
+       if (beamcon0 & BEAMCON0_VARBEAMEN) {
+               // assume VGA-like monitor if VARBEAMEN
+               if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
+                       maxhpos_display = maxhpos - 2;
+                       hsstop_detect = 18;
+               } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
+                       maxhpos_display = maxhpos - 10;
+                       hsstop_detect = 22;
+               } else {
+                       int hb = 0;
+                       if (exthblank) {
+                               if (hbstrt > maxhpos / 2 && hbstop < maxhpos / 2) {
+                                       hb = (maxhpos - hbstrt) + hbstop;
+                               } else if (hbstop < maxhpos / 2 && hbstrt < hbstop) {
+                                       hb = hbstop - hbstrt;
+                               }
+                               maxhpos_display = maxhpos - (hb - 2);
+                               int hsadj = 10;
+                               int hsz = 0;
+                               if (hsstrt > maxhpos / 2 && hsstop > hsstrt) {
+                                       hsz = hsstop - hsstrt;
+                               } else if (hsstrt > maxhpos / 2 && hsstop < maxhpos / 2) {
+                                       hsz = (maxhpos - hsstrt) - hsstop;
+                               } else if (hsstop < maxhpos / 2 && hsstrt < hsstop) {
+                                       hsz = hsstop - hsstrt;
+                               }
+                               if (hsz >= 12) {
+                                       hsadj = 15;
+                               }
+                               hsstop_detect = (hbstop - (hsstrt - hsadj));
+                       } else {
+                               maxhpos_display = maxhpos - 15;
+                               hsstop_detect = 15;
+                       }
+               }
+               maxhpos_display *= 2;
+               if (currprefs.gfx_extrawidth > 0) {
+                       maxhpos_display += currprefs.gfx_extrawidth;
+               }
+
+       } else {
+
+               maxhpos_display = AMIGA_WIDTH_MAX;
+               hsstop_detect = hsstop_detect2;
+
+               if (currprefs.gfx_extrawidth > 0) {
+                       maxhpos_display += currprefs.gfx_extrawidth;
+               } else if (currprefs.gfx_overscanmode < OVERSCANMODE_BROADCAST) {
+                       // one pixel row missing from right border if OCS
+                       if (!ecs_denise) {
+                               maxhpos_display--;
+                       }
+               } else if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
+                       maxhpos_display += EXTRAWIDTH_EXTREME;
+                       maxvpos_display_vsync += 2;
+                       minfirstline--;
+               } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
+                       maxhpos_display += EXTRAWIDTH_BROADCAST;
+                       maxvpos_display_vsync++;
+                       minfirstline--;
                }
-       } else if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
-               maxhpos_display += EXTRAWIDTH_EXTREME;
-               maxvpos_display_vsync += 2;
-               minfirstline--;
-       } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
-               maxhpos_display += EXTRAWIDTH_BROADCAST;
-               maxvpos_display_vsync++;
-               minfirstline--;
+       }
+
+       if (hsstop_detect < 0) {
+               hsstop_detect = 0;
        }
 
        vblank_extraline = !currprefs.cs_dipagnus && !ecs_denise ? 1 : 0;
@@ -5850,7 +5872,7 @@ static void calcdiw(void)
                diwlastword = min_diwlastword;
        }
 
-       if (vstrt == vpos && vstop != vpos && diwstate == DIW_waiting_start) {
+       if (vstrt == vpos && vstop != vpos && diwstate == diw_states::DIW_waiting_start) {
                // This may start BPL DMA immediately.
                SET_LINE_CYCLEBASED;
        }
@@ -7086,17 +7108,23 @@ static void BPL2MOD(int hpos, uae_u16 v)
 /* Needed in special OCS/ECS "7-plane" mode,
  * also handles CPU generated bitplane data
  */
-static void BPLxDAT_next(int hpos, int num, uae_u16 data)
+static void BPLxDAT_next(uae_u32 vv)
 {
-       // only BPL1DAT access can do anything visible
-       if (num == 0 && hpos >= hsyncstartpos_start_cycles) {
+       int num = vv >> 16;
+       uae_u16 data = vv;
+
+       int hpos = current_hpos();
+
+       // only BPL1DAT access can do anything visible immediately
+       if (num == 0) {
                decide_line(hpos);
                decide_fetch_safe(hpos);
+               flush_display(fetchmode);
        }
-       flush_display(fetchmode);
+
        fetched[num] = data;
        if ((fmode & 3) == 3) {
-               fetched_aga[num] = ((uae_u64)last_custom_value << 48) | ((uae_u64)data << 32) | (data << 16) | data;
+               fetched_aga[num] = ((uae_u64)last_custom_value << 48) | ((uae_u64)data << 32) | ((uae_u64)data << 16) | data;
        } else if ((fmode & 3) == 2) {
                fetched_aga[num] = (last_custom_value << 16) | data;
        } else if ((fmode & 3) == 1) {
@@ -7104,23 +7132,22 @@ static void BPLxDAT_next(int hpos, int num, uae_u16 data)
        } else {
                fetched_aga[num] = data;
        }
-}
 
-static void BPLxDAT(int hpos, int num, uae_u16 v)
-{
-       uae_u32 vv = (num << 16) | v;
-       BPLxDAT_next(hpos, num, v);
-
-       if (num == 0 && hpos >= hsyncstartpos_start_cycles) {
-               if (thisline_decision.plfleft < 0) {
-                       reset_bpl_vars();
+       if (num == 0) {
+               if (ecs_denise || (!ecs_denise && hpos >= 0x2e)) {
+                       beginning_of_plane_block(hpos);
+                       bprun_pipeline_flush_delay = maxhpos;
+                       SET_LINE_CYCLEBASED;
                }
-               beginning_of_plane_block(hpos);
-               bprun_pipeline_flush_delay = maxhpos;
-               SET_LINE_CYCLEBASED;
        }
 }
 
+static void BPLxDAT(int hpos, int num, uae_u16 data)
+{
+       uae_u32 vv = (num << 16) | data;
+       event2_newevent_xx(-1, 1 * CYCLE_UNIT, vv, BPLxDAT_next);
+}
+
 static void DIWSTRT(int hpos, uae_u16 v)
 {
        if (diwstrt == v && !diwhigh_written) {
@@ -8051,7 +8078,7 @@ static void decide_line(int endhpos)
                }
 
                bool dma = dmaen(DMA_BITPLANE) != 0;
-               bool diw = diwstate == DIW_waiting_stop;
+               bool diw = diwstate == diw_states::DIW_waiting_stop;
                // DIW latching takes one cycle
                if (hpos == 0 && vpos == diwstate_vpos) {
                        diw = !diw;
@@ -9218,7 +9245,7 @@ static void init_sprites(void)
 static void init_hardware_frame(void)
 {
        if (!harddis_v) {
-               diwstate = DIW_waiting_start;
+               diwstate = diw_states::DIW_waiting_start;
        }
 }
 
@@ -10312,7 +10339,7 @@ static void hautoscale_check(void)
                                firstword_bplcon1 = bplcon1;
                        }
                }
-               if (diwstate == DIW_waiting_stop) {
+               if (diwstate == diw_states::DIW_waiting_stop) {
                        int f = 8 << fetchmode;
                        if (plfstrt + f < ddffirstword_total + f) {
                                ddffirstword_total = plfstrt + f;
@@ -10366,7 +10393,7 @@ static void hsync_handlerh(bool onvsync)
        hpos_hsync_extra = 0;
        estimate_last_fetch_cycle(hpos);
 
-       if (vb_end_line && !ecs_denise) {
+       if (vb_end_next_line && !ecs_denise) {
                record_color_change2(hpos, 0, COLOR_CHANGE_BLANK | 1);
        }
 
@@ -11230,7 +11257,7 @@ static void hsync_handler_post(bool onvsync)
        }
 
        if (!custom_disabled) {
-               if (!currprefs.blitter_cycle_exact && blt_info.blit_main && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) {
+               if (!currprefs.blitter_cycle_exact && blt_info.blit_main && dmaen (DMA_BITPLANE) && diwstate == diw_states::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)],
                                cycle_diagram_free_cycles[fetchmode][GET_RES_AGNUS (bplcon0)][GET_PLANES_LIMIT (bplcon0)]);
@@ -11404,7 +11431,7 @@ static void hsync_handler_post(bool onvsync)
                if (vb_start_line) {
                        record_dma_event(DMA_EVENT_VB, REFRESH_FIRST_HPOS, vpos);
                }
-               if (diwstate == DIW_waiting_stop) {
+               if (diwstate == diw_states::DIW_waiting_stop) {
                        record_dma_event(DMA_EVENT_VDIW, REFRESH_FIRST_HPOS, vpos);
                }
                if (lof_store) {
@@ -11804,7 +11831,7 @@ void custom_reset(bool hardreset, bool keyboardreset)
 
                diwhigh = 0;
                diwhigh_written = 0;
-               hdiwstate = DIW_waiting_start; // this does not reset at vblank
+               hdiwstate = diw_states::DIW_waiting_start; // this does not reset at vblank
 
                refptr = 0xffff;
                FMODE(0, 0);
@@ -11850,7 +11877,7 @@ void custom_reset(bool hardreset, bool keyboardreset)
        cop_state.movedelay = 0;
        cop_state.strobe = 0;
        cop_state.ignore_next = 0;
-       diwstate = DIW_waiting_start;
+       diwstate = diw_states::DIW_waiting_start;
        check_harddis();
 
        dmal = 0;
@@ -11977,7 +12004,7 @@ void dumpcustom(void)
        console_out_f(_T("BPLCON 0: %04x 1: %04x 2: %04x 3: %04x 4: %04x LOF=%d/%d HDIW=%d VDIW=%d\n"),
                bplcon0, bplcon1, bplcon2, bplcon3, bplcon4,
                lof_display, lof_store,
-               hdiwstate == DIW_waiting_start ? 0 : 1, diwstate == DIW_waiting_start ? 0 : 1);
+               hdiwstate == diw_states::DIW_waiting_start ? 0 : 1, diwstate == diw_states::DIW_waiting_start ? 0 : 1);
        if (timeframes) {
                console_out_f(_T("Average frame time: %.2f ms [frames: %d time: %d]\n"),
                        (double)frametime / timeframes, timeframes, frametime);
@@ -12744,8 +12771,8 @@ uae_u8 *restore_custom(uae_u8 *src)
        hcenter = RW;                   /* 1E2 HCENTER */
        diwhigh = RW;                   /* 1E4 DIWHIGH */
        diwhigh_written = (diwhigh & 0x8000) ? 1 : 0;
-       hdiwstate = (diwhigh & 0x4000) ? DIW_waiting_stop : DIW_waiting_start;
-       diwstate = (diwhigh & 0x0080) ? DIW_waiting_start : DIW_waiting_stop;
+       hdiwstate = (diwhigh & 0x4000) ? diw_states::DIW_waiting_stop : diw_states::DIW_waiting_start;
+       diwstate = (diwhigh & 0x0080) ? diw_states::DIW_waiting_start : diw_states::DIW_waiting_stop;
        diwhigh &= 0x3f3f;
        RW;                                             /* 1E6 ? */
        RW;                                             /* 1E8 ? */
@@ -12955,7 +12982,7 @@ uae_u8 *save_custom(int *len, uae_u8 *dstptr, int full)
        SW(hsstrt);                     /* 1DE HSSTRT */
        SW(vsstrt);                     /* 1E0 VSSTRT */
        SW(hcenter);            /* 1E2 HCENTER */
-       SW(diwhigh | (diwhigh_written ? 0x8000 : 0) | (hdiwstate == DIW_waiting_stop ? 0x4000 : 0) | (diwstate == DIW_waiting_start ? 0x0080 : 0)); /* 1E4 DIWHIGH */
+       SW(diwhigh | (diwhigh_written ? 0x8000 : 0) | (hdiwstate == diw_states::DIW_waiting_stop ? 0x4000 : 0) | (diwstate == diw_states::DIW_waiting_start ? 0x0080 : 0)); /* 1E4 DIWHIGH */
        SW(0);                          /* 1E6 */
        SW(0);                          /* 1E8 */
        SW(0);                          /* 1EA */
index fdac729c9bb4266370b5eae7c629b216860498e9..857831836a5a2bc1b6cb299e68492edb59b8f247 100644 (file)
@@ -573,6 +573,7 @@ int get_vertical_visible_height(bool useoldsize)
        if (programmedmode <= 1) {
                h = maxvpos_display + maxvpos_display_vsync - minfirstline;
                if (useoldsize) {
+                       // 288/576 or 243/486
                        if (h == 288 || h == 243) {
                                h--;
                        }
@@ -1071,10 +1072,15 @@ static xcolnr getbgc(int blank)
        if (!(vb_state & VB_NOVB) && extblken && aga_mode) {
                return fullblack;
        }
+       bool brdblank = ce_is_borderblank(colors_for_drawing.extra);
+       if (vb_state & VB_XBORDER) {
+               if (brdblank)
+                       return fullblack;
+               return colors_for_drawing.acolors[0];
+       }
        if (hposblank) {
                return fullblack;
        }
-       bool brdblank = ce_is_borderblank(colors_for_drawing.extra);
 #if 0
        if (brdblank && blank == 4) {
                return colors_for_drawing.acolors[0];
@@ -1175,7 +1181,19 @@ static void pfield_init_linetoscr (int lineno, bool border)
                        if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) {
                                playfield_end = linetoscr_diw_end;
                        }
-                       int left = coord_hw_to_window_x_lores(dp_for_drawing->plfleft - DDF_OFFSET);
+                       int plfleft = dp_for_drawing->plfleft - DDF_OFFSET;
+                       int left = coord_hw_to_window_x_lores(plfleft);
+                       if (aga_mode) {
+                               // If AGA: "bordersprite" starts 0.5 lores pixels earlier
+                               if (currprefs.chipset_hr) {
+                                       left -= lores_shift > 0 ? 1 : 0;
+                               } else {
+                                       left -= 1 << lores_shift;
+                               }
+                       } else if (ecs_denise) {
+                               // If ECS Denise: "bordersprite" starts 1 lores pixel earlier
+                               left -= 1 << lores_shift;
+                       }
                        if (left < visible_left_border)
                                left = visible_left_border;
                        if (left < playfield_start && left >= linetoscr_diw_start) {
@@ -3719,6 +3737,7 @@ static void center_image (void)
 
        int w = vidinfo->drawbuffer.inwidth;
        int ew = vidinfo->drawbuffer.extrawidth;
+       int maxdiw = max_diwlastword;
        if (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN && currprefs.gfx_xcenter && !currprefs.gf[0].gfx_filter_autoscale && max_diwstop > 0) {
 
                if (max_diwstop - min_diwstart < w && currprefs.gfx_xcenter == 2)
@@ -3726,7 +3745,7 @@ static void center_image (void)
                        visible_left_border = (max_diwstop - min_diwstart - w) / 2 + min_diwstart;
                else
                        visible_left_border = max_diwstop - w - (max_diwstop - min_diwstart - w) / 2;
-               visible_left_border &= ~((xshift (1, lores_shift)) - 1);
+               visible_left_border &= ~((xshift(1, lores_shift)) - 1);
 
                if (!center_reset && !vertical_changed) {
                        /* Would the old value be good enough? If so, leave it as it is if we want to be clever. */
@@ -3743,18 +3762,15 @@ static void center_image (void)
                        hs++;
                }
                visible_left_border = hs << currprefs.gfx_resolution;
-               if (visible_left_border + w < max_diwlastword) {
-                       visible_left_border += (max_diwlastword - (visible_left_border + w) - 1) / 2;
-               }
-               if (ew > 0) {
-                       visible_left_border -= (ew / 2) << currprefs.gfx_resolution;
+               if (visible_left_border + w > maxdiw) {
+                       visible_left_border += (maxdiw - (visible_left_border + w) - 1) / 2;
                }
                if (visible_left_border < (hs << currprefs.gfx_resolution)) {
                        visible_left_border = hs << currprefs.gfx_resolution;
                }
        } else if (ew < -1) {
                // normal
-               visible_left_border = max_diwlastword - w;
+               visible_left_border = maxdiw - w;
        } else {
                if (vidinfo->drawbuffer.inxoffset < 0) {
                        visible_left_border = 0;
@@ -3774,9 +3790,9 @@ static void center_image (void)
        linetoscr_x_adjust_pixels = visible_left_border;
        linetoscr_x_adjust_pixbytes = linetoscr_x_adjust_pixels * vidinfo->drawbuffer.pixbytes;
 
-       visible_right_border = visible_left_border + w + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution);
-       if (visible_right_border > max_diwlastword + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution))
-               visible_right_border = max_diwlastword + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution);
+       visible_right_border = maxdiw + w + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution);
+       if (visible_right_border > maxdiw + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution))
+               visible_right_border = maxdiw + ((ew > 0 ? ew : 0) << currprefs.gfx_resolution);
 
        int max_drawn_amiga_line_tmp = max_drawn_amiga_line;
        if (max_drawn_amiga_line_tmp > vidinfo->drawbuffer.inheight)
@@ -3795,7 +3811,7 @@ static void center_image (void)
 
                        /* Would the old value be good enough? If so, leave it as it is if we want to be clever. */
                        if (!center_reset && !horizontal_changed) {
-                               if (currprefs.gfx_ycenter == 2 && thisframe_y_adjust != prev_y_adjust && abs(thisframe_y_adjust - prev_y_adjust) < 16) {
+                               if (currprefs.gfx_ycenter == 2 && thisframe_y_adjust != prev_y_adjust && abs(thisframe_y_adjust - prev_y_adjust) < 100) {
                                        if (prev_y_adjust <= thisframe_first_drawn_line && prev_y_adjust + max_drawn_amiga_line_tmp > thisframe_last_drawn_line)
                                                thisframe_y_adjust = prev_y_adjust;
                                }
index a0abfe35880a0f17deb1419174b5a35533af1202..93a7e5db976150791534a6582065b68f24375eda 100644 (file)
@@ -142,9 +142,10 @@ STATIC_INLINE bool ce_is_borderntrans(uae_u8 data)
        return (data & (1 << CE_BORDERNTRANS)) != 0;
 }
 
-#define VB_XBLANK 0x04
-#define VB_PRGVB 0x02
-#define VB_NOVB 0x01
+#define VB_XBORDER 0x08 // forced border color or bblank
+#define VB_XBLANK 0x04 // forced bblank
+#define VB_PRGVB 0x02 // programmed vblank
+#define VB_NOVB 0x01 // normal
 
 struct color_entry {
        uae_u16 color_regs_ecs[32];