]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
DIWHIGH H0/H1 support. AGA borderblank update. BPLCON1 updates.
authorToni Wilen <twilen@winuae.net>
Mon, 23 Jul 2018 18:55:51 +0000 (21:55 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 23 Jul 2018 18:55:51 +0000 (21:55 +0300)
custom.cpp
drawing.cpp
include/drawing.h

index c5b2e11d4c0fcb139a8b52826f767fd5cb36c217..d7dda90c0105fedb26be3b22533f11aa66c0ec50 100644 (file)
@@ -2126,29 +2126,19 @@ static int flush_plane_data_hr(int fm)
 {
        int i = 0;
 
-       while (out_nbits) {
+       if (out_nbits) {
                int m = 64 - out_nbits;
-               if (m > 16)
-                       m = 16;
                toscr_1_hr(m, fm);
                i += m;
        }
 
-       i += 32;
-       toscr_1_hr(16, fm);
-       toscr_1_hr(16, fm);
-       i += 32;
-       toscr_1_hr(16, fm);
-       toscr_1_hr(16, fm);
+       i += 64;
+       toscr_1_hr(64, fm);
 
        if (fm == 2) {
                /* flush AGA full 64-bit shift register + possible data in todisplay */
-               i += 32;
-               toscr_1_hr(16, fm);
-               toscr_1_hr(16, fm);
-               i += 32;
-               toscr_1_hr(16, fm);
-               toscr_1_hr(16, fm);
+               i += 64;
+               toscr_1_hr(64, fm);
        }
 
        return i >> (1 + toscr_res);
@@ -4980,12 +4970,12 @@ void init_hz_normal (void)
 
 static void calcdiw (void)
 {
-       int hstrt = diwstrt & 0xFF;
-       int hstop = diwstop & 0xFF;
+       int hstrt = (diwstrt & 0xFF) << 2;
+       int hstop = (diwstop & 0xFF) << 2;
        int vstrt = diwstrt >> 8;
        int vstop = diwstop >> 8;
 
-       // vertical in ECS Agnus
+       // ECS Agnus/AGA: DIWHIGH vertical high bits.
        if (diwhigh_written && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
                vstrt |= (diwhigh & 7) << 8;
                vstop |= ((diwhigh >> 8) & 7) << 8;
@@ -4993,19 +4983,24 @@ static void calcdiw (void)
                if ((vstop & 0x80) == 0)
                        vstop |= 0x100;
        }
-       // horizontal in ECS Denise
+       // ECS Denise/AGA: horizontal DIWHIGH high bit.
        if (diwhigh_written && (currprefs.chipset_mask & CSMASK_ECS_DENISE)) {
-               hstrt |= ((diwhigh >> 5) & 1) << 8;
-               hstop |= ((diwhigh >> 13) & 1) << 8;
+               hstrt |= ((diwhigh >> 5) & 1) << (8 + 2);
+               hstop |= ((diwhigh >> 13) & 1) << (8 + 2);
        } else {
-               hstop += 0x100;
+               hstop |= 0x100 << 2;
+       }
+       // AGA only: horizontal DIWHIGH hires/shres bits.
+       if (currprefs.chipset_hr && diwhigh_written && (currprefs.chipset_mask & CSMASK_AGA)) {
+               hstrt |= (diwhigh >> 3) & 3;
+               hstop |= (diwhigh >> 11) & 3;
        }
 
-       diw_hstrt = hstrt;
-       diw_hstop = hstop;
+       diw_hstrt = hstrt >> 2;
+       diw_hstop = hstop >> 2;
 
-       diwfirstword = coord_diw_to_window_x (hstrt);
-       diwlastword = coord_diw_to_window_x (hstop);
+       diwfirstword = coord_diw_shres_to_window_x(hstrt);
+       diwlastword = coord_diw_shres_to_window_x(hstop);
        
        if (diwfirstword >= diwlastword) {
                diwfirstword = min_diwlastword;
@@ -9571,13 +9566,13 @@ static void hsync_handler_post (bool onvsync)
                if (vpos >= first_planes_vpos && vpos <= last_planes_vpos) {
                        if (diwlastword > diwlastword_total) {
                                diwlastword_total = diwlastword;
-                               if (diwlastword_total > coord_diw_to_window_x (hsyncstartpos * 2))
-                                       diwlastword_total = coord_diw_to_window_x (hsyncstartpos * 2);
+                               if (diwlastword_total > coord_diw_lores_to_window_x(hsyncstartpos * 2))
+                                       diwlastword_total = coord_diw_lores_to_window_x(hsyncstartpos * 2);
                        }
                        if (diwfirstword < diwfirstword_total) {
                                diwfirstword_total = diwfirstword;
-                               if (diwfirstword_total < coord_diw_to_window_x (hsyncendpos * 2))
-                                       diwfirstword_total = coord_diw_to_window_x (hsyncendpos * 2);
+                               if (diwfirstword_total < coord_diw_lores_to_window_x(hsyncendpos * 2))
+                                       diwfirstword_total = coord_diw_lores_to_window_x(hsyncendpos * 2);
                                firstword_bplcon1 = bplcon1;
                        }
                }
index a75715ba5d838daa62c1938fc73b795776ecd9bf..fd3c98e6620660ee02335d280c59c8670f1d8cd7 100644 (file)
@@ -69,7 +69,7 @@ typedef enum
 
 extern int sprite_buffer_res;
 static int lores_factor;
-int lores_shift;
+int lores_shift, shres_shift;
 
 static void pfield_set_linetoscr(void);
 
@@ -79,8 +79,10 @@ static void lores_set(int lores)
 {
        int old = lores_shift;
        lores_shift = lores;
-       if (lores_shift != old)
+       if (lores_shift != old) {
+               shres_shift = RES_MAX - lores;
                pfield_set_linetoscr();
+       }
 }
 
 static void lores_reset (void)
@@ -629,8 +631,8 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh)
        ddflastword_total = coord_hw_to_window_x (ddflastword_total * 2 + DIW_DDF_OFFSET);
 
        if (doublescan <= 0 && !programmedmode) {
-               int min = coord_diw_to_window_x (92);
-               int max = coord_diw_to_window_x (460);
+               int min = coord_diw_lores_to_window_x (92);
+               int max = coord_diw_lores_to_window_x (460);
                if (diwfirstword_total < min)
                        diwfirstword_total = min;
                if (diwlastword_total > max)
@@ -841,7 +843,7 @@ STATIC_INLINE int get_shdelay_add(void)
 where do we start drawing the playfield, where do we start drawing the right border.
 All of these are forced into the visible window (VISIBLE_LEFT_BORDER .. VISIBLE_RIGHT_BORDER).
 PLAYFIELD_START and PLAYFIELD_END are in window coordinates.  */
-static int playfield_start_pre;
+static int playfield_start_pre, playfield_end_pre;
 static int playfield_start, playfield_end;
 static int real_playfield_start, real_playfield_end;
 static int sprite_playfield_start;
@@ -1001,10 +1003,12 @@ static void pfield_init_linetoscr (bool border)
        }
 #endif
 
-       // AGA borderblank starts horizontally 1 hires pixel before bitplanes start, leaving 1 hires background color gap
+       // AGA borderblank starts horizontally 1 hires pixel before bitplanes start, leaving 1 hires pixel background color gap
        playfield_start_pre = playfield_start;
-       if (currprefs.chipset_hr && (currprefs.chipset_mask & CSMASK_AGA) && currprefs.gfx_resolution > 0) {
-               playfield_start_pre -= 2;
+       playfield_end_pre = playfield_end;
+       if (currprefs.chipset_hr && (currprefs.chipset_mask & CSMASK_AGA) && bplres > 0) {
+               playfield_start_pre -= bplres;
+               playfield_end_pre -= bplres;
        }
 
        unpainted = visible_left_border < playfield_start ? 0 : visible_left_border - playfield_start;
@@ -2805,42 +2809,65 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke
                        lastpos = t;
                }
 
+               // normal
                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, 0);
                                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) && !(currprefs.chipset_mask & CSMASK_AGA))
+                                       weird_bitplane_fix(lastpos, t);
+                               if (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;
+                       }
+
                } else {
+                       // special AGA borderblank 1 hires 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.
+                       // AGA "buggy" borderblank, real background color visible, single hires 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
-               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) && !(currprefs.chipset_mask & CSMASK_AGA))
-                               weird_bitplane_fix (lastpos, t);
-                       if (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;
+                       // playfield with last hires 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 (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 1 hires 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;
+                       }
+
                }
 
                // right border (playfield end to hblank start)
-               if (nextpos_in_range > lastpos && lastpos >= playfield_end) {
+               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;
@@ -3110,6 +3137,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
                        playfield_start = visible_right_border;
                        playfield_end = visible_right_border;
                        playfield_start_pre = playfield_start;
+                       playfield_end_pre = playfield_end;
                        do_color_changes (pfield_do_fill_line, pfield_do_fill_line, lineno);
 
                }
index 5e35a8e65e8b175b1e56264f525de8e407c6a84f..1dce48aa73253b9bdd7526bc273948e99c71e7aa 100644 (file)
 /* According to the HRM, pixel data spends a couple of cycles somewhere in the chips
 before it appears on-screen. (TW: display emulation now does this automatically)  */
 #define DIW_DDF_OFFSET 1
+#define DIW_DDF_OFFSET_SHRES (DIW_DDF_OFFSET << 2)
 /* this many cycles starting from hpos=0 are visible on right border */
 #define HBLANK_OFFSET 9
 /* We ignore that many lores pixels at the start of the display. These are
 * invisible anyway due to hardware DDF limits. */
 #define DISPLAY_LEFT_SHIFT 0x38
+#define DISPLAY_LEFT_SHIFT_SHRES (DISPLAY_LEFT_SHIFT << 2)
 #endif
 
 #define PIXEL_XPOS(HPOS) (((HPOS)*2 - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift)
@@ -48,7 +50,7 @@ before it appears on-screen. (TW: display emulation now does this automatically)
 #define min_diwlastword (0)
 #define max_diwlastword (PIXEL_XPOS(0x1d4 >> 1))
 
-extern int lores_shift, interlace_seen;
+extern int lores_shift, shres_shift, interlace_seen;
 extern bool aga_mode, direct_rgb;
 extern int visible_left_border, visible_right_border;
 extern int detected_screen_resolution;
@@ -73,11 +75,16 @@ STATIC_INLINE int coord_window_to_hw_x (int x)
        return x + DISPLAY_LEFT_SHIFT;
 }
 
-STATIC_INLINE int coord_diw_to_window_x (int x)
+STATIC_INLINE int coord_diw_lores_to_window_x(int x)
 {
        return (x - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift;
 }
 
+STATIC_INLINE int coord_diw_shres_to_window_x (int x)
+{
+       return (x - DISPLAY_LEFT_SHIFT_SHRES + DIW_DDF_OFFSET_SHRES - (1 << 2)) >> shres_shift;
+}
+
 STATIC_INLINE int coord_window_to_diw_x (int x)
 {
        x = coord_window_to_hw_x (x);