BPLCON4 sprite bank/bitplane XOR timing.

This commit is contained in:
Dimitris Panokostas 2020-05-02 23:48:13 +02:00
parent 84590cefdd
commit fdb06a4bbd
3 changed files with 49 additions and 31 deletions

View file

@ -809,7 +809,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
)
@ -1013,29 +1013,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)
@ -2043,7 +2054,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)
{
@ -3322,19 +3333,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;
@ -3361,7 +3372,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)
@ -4170,7 +4181,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;
@ -5650,9 +5662,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

View file

@ -275,7 +275,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;
@ -2731,9 +2731,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;
@ -2805,8 +2805,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;
@ -2886,7 +2890,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)
@ -3120,7 +3124,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);
@ -3130,7 +3135,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 ();
}

View 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;