]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
BPLCON4 sprite bank/bitplane XOR timing.
authorToni Wilen <twilen@winuae.net>
Sat, 2 May 2020 17:03:29 +0000 (20:03 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 2 May 2020 17:03:29 +0000 (20:03 +0300)
custom.cpp
drawing.cpp
include/drawing.h

index 9906b61826f29593b102a5d15dba716417afc2ea..569573dbba85134eef32f60a577e7815e58e361e 100644 (file)
@@ -873,7 +873,7 @@ static void finish_playfield_line (void)
                || line_decisions[next_lineno].bplcon3 != thisline_decision.bplcon3
 #endif
 #ifdef AGA
-               || line_decisions[next_lineno].bplcon4 != thisline_decision.bplcon4
+               || line_decisions[next_lineno].bplcon4bm != thisline_decision.bplcon4bm
                || line_decisions[next_lineno].fmode != thisline_decision.fmode
 #endif
                )
@@ -1105,29 +1105,40 @@ void notice_new_xcolors(void)
        }
 }
 
-static void record_color_change2 (int hpos, int regno, uae_u32 value)
+static void record_color_change2(int hpos, int regno, uae_u32 value)
 {
        int pos = (hpos * 2) * 4;
 
        // AGA has extra hires pixel delay in color changes
-       if (currprefs.chipset_mask & CSMASK_AGA) {
+       if ((regno < 0x1000 || regno == 0x1000 + 0x10c) && (currprefs.chipset_mask & CSMASK_AGA)) {
                if (currprefs.chipset_hr)
                        pos += 2;
                if (regno == 0x1000 + 0x10c) {
-                       // BPLCON4 change adds another extra hires pixel delay
-                       pos += 2;
+                       // BPLCON4:
+                       // Bitplane XOR change: 2 hires pixel delay
+                       // Sprite bank change: 1 hires pixel delay
                        if (!currprefs.chipset_hr)
                                pos += 2;
                        if (value & 0xff00)
                                thisline_decision.xor_seen = true;
+                       pos += 2;
+                       if ((value & 0x00ff) != (bplcon4 & 0x00ff)) {
+                               // Sprite bank delay
+                               color_change *ccs = &curr_color_changes[next_color_change];
+                               ccs->linepos = pos;
+                               ccs->regno = regno | 1;
+                               ccs->value = value;
+                               next_color_change++;
+                       }
+                       pos += 2;
                }
        }
-
-       curr_color_changes[next_color_change].linepos = pos;
-       curr_color_changes[next_color_change].regno = regno;
-       curr_color_changes[next_color_change].value = value;
+       color_change *cc = &curr_color_changes[next_color_change];
+       cc->linepos = pos;
+       cc->regno = regno;
+       cc->value = value;
        next_color_change++;
-       curr_color_changes[next_color_change].regno = -1;
+       cc[1].regno = -1;
 }
 
 static bool isehb (uae_u16 bplcon0, uae_u16 bplcon2)
@@ -2247,7 +2258,7 @@ STATIC_INLINE void flush_display (int fm)
        toscr_nbits = 0;
 }
 
-static void record_color_change(int hpos, int regno, unsigned long value);
+static void record_color_change(int hpos, int regno, uae_u32 value);
 
 static void hack_shres_delay(int hpos)
 {
@@ -3585,19 +3596,19 @@ static void decide_line (int hpos)
 
 /* Called when a color is about to be changed (write to a color register),
 * but the new color has not been entered into the table yet. */
-static void record_color_change (int hpos, int regno, unsigned long value)
+static void record_color_change (int hpos, int regno, uae_u32 value)
 {
-       if (regno < 0x1000 && nodraw ())
+       if (regno < 0x1000 && nodraw())
                return;
        /* Early positions don't appear on-screen. */
        if (vpos < minfirstline)
                return;
 
-       decide_diw (hpos);
-       decide_line (hpos);
+       decide_diw(hpos);
+       decide_line(hpos);
 
        if (thisline_decision.ctable < 0)
-               remember_ctable ();
+               remember_ctable();
 
        if  ((regno < 0x1000 || regno == 0x1000 + 0x10c) && hpos < HBLANK_OFFSET && !(beamcon0 & 0x80) && prev_lineno >= 0) {
                struct draw_info *pdip = curr_drawinfo + prev_lineno;
@@ -3624,7 +3635,7 @@ static void record_color_change (int hpos, int regno, unsigned long value)
                        curr_color_changes[idx + 1].regno = -1;
                }
        }
-       record_color_change2 (hpos, regno, value);
+       record_color_change2(hpos, regno, value);
 }
 
 static bool isbrdblank (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
@@ -3678,16 +3689,16 @@ static void record_register_change (int hpos, int regno, uae_u16 value)
        if (regno == 0x100) { // BPLCON0
                if (value & 0x800)
                        thisline_decision.ham_seen = 1;
-               thisline_decision.ehb_seen = isehb (value, bplcon2);
-               isbrdblank (hpos, value, bplcon3);
-               issprbrd (hpos, value, bplcon3);
+               thisline_decision.ehb_seen = isehb(value, bplcon2);
+               isbrdblank(hpos, value, bplcon3);
+               issprbrd(hpos, value, bplcon3);
        } else if (regno == 0x104) { // BPLCON2
-               thisline_decision.ehb_seen = isehb (bplcon0, value);
+               thisline_decision.ehb_seen = isehb(bplcon0, value);
        } else if (regno == 0x106) { // BPLCON3
-               isbrdblank (hpos, bplcon0, value);
-               issprbrd (hpos, bplcon0, value);
+               isbrdblank(hpos, bplcon0, value);
+               issprbrd(hpos, bplcon0, value);
        }
-       record_color_change (hpos, regno + 0x1000, value);
+       record_color_change(hpos, regno + 0x1000, value);
 }
 
 typedef int sprbuf_res_t, cclockres_t, hwres_t,        bplres_t;
@@ -4478,7 +4489,8 @@ static void reset_decisions (void)
        thisline_decision.bplcon3 = bplcon3;
 #endif
 #ifdef AGA
-       thisline_decision.bplcon4 = bplcon4;
+       thisline_decision.bplcon4bm = bplcon4;
+       thisline_decision.bplcon4sp = bplcon4;
        thisline_decision.fmode = fmode;
 #endif
        bplcon0d_old = -1;
@@ -6102,9 +6114,9 @@ static void BPLCON4(int hpos, uae_u16 v)
                return;
        if (bplcon4 == v)
                return;
-       decide_line (hpos);
+       decide_line(hpos);
+       record_register_change(hpos, 0x10c, v);
        bplcon4 = v;
-       record_register_change (hpos, 0x10c, v);
 }
 #endif
 
index 53284883bb4c2c8f5ecd132b10c3c963aeef8297..48ad35dcdf58f87efb6e8c453a5656f962412ac3 100644 (file)
@@ -265,7 +265,7 @@ static int bpldualpf2of, bplplanecnt, ecsshres;
 static int bplbypass, bplcolorburst, bplcolorburst_field;
 static bool issprites;
 static int bplres;
-static int plf1pri, plf2pri, bplxor, bpland, bpldelay_sh;
+static int plf1pri, plf2pri, bplxor, bplxorsp, bpland, bpldelay_sh;
 static uae_u32 plf_sprite_mask;
 static int sbasecol[2] = { 16, 16 };
 static int hposblank;
@@ -2826,9 +2826,9 @@ static void pfield_expand_dp_bplcon (void)
                bplehb = 0;
        }
        bpldualpf2of = (dp_for_drawing->bplcon3 >> 10) & 7;
-       sbasecol[0] = ((dp_for_drawing->bplcon4 >> 4) & 15) << 4;
-       sbasecol[1] = ((dp_for_drawing->bplcon4 >> 0) & 15) << 4;
-       bplxor = dp_for_drawing->bplcon4 >> 8;
+       sbasecol[0] = ((dp_for_drawing->bplcon4sp >> 4) & 15) << 4;
+       sbasecol[1] = ((dp_for_drawing->bplcon4sp >> 0) & 15) << 4;
+       bplxor = dp_for_drawing->bplcon4bm >> 8;
        int sh = (colors_for_drawing.extra >> CE_SHRES_DELAY) & 3;
        if (sh != bpldelay_sh) {
                bpldelay_sh = sh;
@@ -2900,8 +2900,12 @@ static void pfield_expand_dp_bplconx (int regno, int v)
                break;
 #endif
 #ifdef AGA
-       case 0x10c: // BPLCON4
-               dp_for_drawing->bplcon4 = v;
+       case 0x10c: // BPLCON4 bitplane xor (and sprite if sprite change is not visible)
+               dp_for_drawing->bplcon4bm = v;
+               dp_for_drawing->bplcon4sp = v;
+               break;
+       case 0x10c+1: // BPLCON4 sprite bank
+               dp_for_drawing->bplcon4sp = v;
                break;
        case 0x1fc: // FMODE
                dp_for_drawing->fmode = v;
@@ -2981,7 +2985,7 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke
 
        for (i = dip_for_drawing->first_color_change; i <= dip_for_drawing->last_color_change; i++) {
                int regno = curr_color_changes[i].regno;
-               unsigned int value = curr_color_changes[i].value;
+               uae_u32 value = curr_color_changes[i].value;
                int nextpos, nextpos_in_range;
 
                if (i == dip_for_drawing->last_color_change)
@@ -3221,7 +3225,8 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
                        uae_u16 b0 = dp_for_drawing->bplcon0;
                        uae_u16 b2 = dp_for_drawing->bplcon2;
                        uae_u16 b3 = dp_for_drawing->bplcon3;
-                       uae_u16 b4 = dp_for_drawing->bplcon4;
+                       uae_u16 b4bm = dp_for_drawing->bplcon4bm;
+                       uae_u16 b4sp = dp_for_drawing->bplcon4sp;
                        uae_u16 fm = dp_for_drawing->fmode;
                        init_ham_decoding ();
                        do_color_changes (dummy_worker, decode_ham, lineno);
@@ -3231,7 +3236,8 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
                                dp_for_drawing->bplcon0 = b0;
                                dp_for_drawing->bplcon2 = b2;
                                dp_for_drawing->bplcon3 = b3;
-                               dp_for_drawing->bplcon4 = b4;
+                               dp_for_drawing->bplcon4bm = b4bm;
+                               dp_for_drawing->bplcon4bm = b4sp;
                                dp_for_drawing->fmode = fm;
                                pfield_expand_dp_bplcon ();
                        }
index 94a79925f84a55705248ea4a80213bd95c8abe37..252b289863fef338467c4568485d97c8e7c43d90 100644 (file)
@@ -211,7 +211,7 @@ STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *s
 struct color_change {
        int linepos;
        int regno;
-       unsigned int value;
+       uae_u32 value;
 };
 
 /* 440 rather than 880, since sprites are always lores.  */
@@ -268,7 +268,7 @@ struct decision {
 
        uae_u16 bplcon0, bplcon2;
 #ifdef AGA
-       uae_u16 bplcon3, bplcon4;
+       uae_u16 bplcon3, bplcon4bm, bplcon4sp;
        uae_u16 fmode;
 #endif
        uae_u8 nr_planes;