toscr_nbits = 0;
}
+static void record_color_change(int hpos, int regno, unsigned long value);
+
+static void hack_shres_delay(int hpos)
+{
+ if (!(currprefs.chipset_mask & CSMASK_AGA) && !toscr_delay_sh[0] && !toscr_delay_sh[1])
+ return;
+ int o0 = toscr_delay_sh[0];
+ int o1 = toscr_delay_sh[1];
+ int shdelay1 = (bplcon1 >> 8) & 3;
+ int shdelay2 = (bplcon1 >> 12) & 3;
+ toscr_delay_sh[0] = (shdelay1 & 3) >> toscr_res;
+ toscr_delay_sh[1] = (shdelay2 & 3) >> toscr_res;
+ if (hpos >= 0 && toscr_delay_sh[0] != o0 || toscr_delay_sh[1] != o1) {
+ record_color_change(hpos, 0, COLOR_CHANGE_SHRES_DELAY | toscr_delay_sh[0]);
+ current_colors.extra &= ~(1 << CE_SHRES_DELAY);
+ current_colors.extra &= ~(1 << (CE_SHRES_DELAY + 1));
+ current_colors.extra |= toscr_delay_sh[0] << CE_SHRES_DELAY;
+ remembered_color_entry = -1;
+ }
+}
+
static void update_denise_shifter_planes (int hpos)
{
int np = GET_PLANES (bplcon0d);
toscr_nr_planes2 = toscr_nr_planes;
}
toscr_nr_planes_shifter = toscr_nr_planes2;
+ hack_shres_delay(hpos);
}
STATIC_INLINE void fetch_start (int hpos)
brdblank = false;
brdntrans = false;
#endif
- if (hpos >= 0 && (current_colors.borderblank != brdblank || current_colors.borderntrans != brdntrans)) {
- record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (current_colors.bordersprite ? 2 : 0) | (brdntrans ? 4 : 0));
- current_colors.borderblank = brdblank;
- current_colors.borderntrans = brdntrans;
+ if (hpos >= 0 && (ce_is_borderblank(current_colors.extra) != brdblank || ce_is_borderntrans(current_colors.extra) != brdntrans)) {
+ record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (ce_is_bordersprite(current_colors.extra) ? 2 : 0) | (brdntrans ? 4 : 0));
+ current_colors.extra &= ~(1 << CE_BORDERBLANK);
+ current_colors.extra &= ~(1 << CE_BORDERNTRANS);
+ current_colors.extra |= brdblank ? (1 << CE_BORDERBLANK) : 0;
+ current_colors.extra |= brdntrans ? (1 << CE_BORDERNTRANS) : 0;
remembered_color_entry = -1;
}
return brdblank;
}
-
static bool issprbrd (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
{
bool brdsprt;
#else
brdsprt = false;
#endif
- if (hpos >= 0 && current_colors.bordersprite != brdsprt) {
- record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (current_colors.borderblank ? 1 : 0) | (current_colors.borderntrans ? 4 : 0) | (brdsprt ? 2 : 0));
- current_colors.bordersprite = brdsprt;
+ if (hpos >= 0 && ce_is_bordersprite(current_colors.extra) != brdsprt) {
+ record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (ce_is_borderblank(current_colors.extra) ? 1 : 0) | (ce_is_borderntrans(current_colors.extra) ? 4 : 0) | (brdsprt ? 2 : 0));
+ current_colors.extra &= ~(1 << CE_BORDERSPRITE);
+ current_colors.extra |= brdsprt ? (1 << CE_BORDERSPRITE) : 0;
remembered_color_entry = -1;
- if (brdsprt && !current_colors.borderblank)
+ if (brdsprt && !ce_is_borderblank(current_colors.extra))
thisline_decision.bordersprite_seen = true;
}
- return brdsprt && !current_colors.borderblank;
+ return brdsprt && !ce_is_borderblank(current_colors.extra);
}
static void record_register_change (int hpos, int regno, uae_u16 value)
BPLCON0_Denise (hpos, v, true);
}
-static void hack_bplcon2(void)
-{
- // AGA subpixel scrolling in lores/hires modes
- int shdelay1 = (bplcon1 >> 8) & 3;
- int shdelay2 = (bplcon1 >> 12) & 3;
- toscr_delay_sh[0] = (shdelay1 & 3) >> toscr_res;
- toscr_delay_sh[1] = (shdelay2 & 3) >> toscr_res;
- bplcon2 &= ~0xc000;
- bplcon2 |= toscr_delay_sh[0] << 14;
-}
-
static void BPLCON1 (int hpos, uae_u16 v)
{
if (!(currprefs.chipset_mask & CSMASK_AGA))
decide_fetch_safe (hpos);
bplcon1_written = true;
bplcon1 = v;
-
- if (currprefs.chipset_mask & CSMASK_AGA) {
- int o0 = toscr_delay_sh[0];
- int o1 = toscr_delay_sh[1];
- hack_bplcon2();
- if (toscr_delay_sh[0] != o0 || toscr_delay_sh[1] != o1) {
- // HACK: Use BPLCON2 unused bits to store sh shift
- record_register_change(hpos, 0x104, bplcon2);
- }
- }
+ hack_shres_delay(hpos);
}
static void BPLCON2(int hpos, uae_u16 v)
return;
decide_line (hpos);
bplcon2 = v;
- if (currprefs.chipset_mask & CSMASK_AGA)
- hack_bplcon2();
record_register_change (hpos, 0x104, bplcon2);
}
sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS;
memset (spixels, 0, 2 * MAX_SPR_PIXELS * sizeof *spixels);
memset (&spixstate, 0, sizeof spixstate);
+ toscr_delay_sh[0] = 0;
+ toscr_delay_sh[1] = 0;
cop_state.state = COP_stop;
cop_state.movedelay = 0;
i = RW; /* 1FA ? */
if (i & 0x8000)
currprefs.ntscmode = changed_prefs.ntscmode = i & 1;
- fmode = RW; /* 1FC FMODE */
+ fmode = fmode_saved = RW; /* 1FC FMODE */
last_custom_value1 = RW;/* 1FE ? */
- current_colors.borderblank = isbrdblank (-1, bplcon0, bplcon3);
+ current_colors.extra = 0;
+ if (isbrdblank (-1, bplcon0, bplcon3))
+ current_colors.extra |= 1 << CE_BORDERBLANK;
+ if (issprbrd(-1, bplcon0, bplcon3))
+ current_colors.extra |= 1 << CE_BORDERSPRITE;
+ if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x10))
+ current_colors.extra |= 1 << CE_BORDERNTRANS;
+
DISK_restore_custom (dskpt, dsklen, dskbytr);
return src;
static bool issprites;
static int bplres;
static int plf1pri, plf2pri, bplxor, bpldelay_sh;
-static bool enabled_sh;
static uae_u32 plf_sprite_mask;
static int sbasecol[2] = { 16, 16 };
static int hposblank;
//return colors_for_drawing.acolors[0];
return xcolors[0xf0f];
#endif
- return (blank || hposblank || colors_for_drawing.borderblank) ? 0 : colors_for_drawing.acolors[0];
+ return (blank || hposblank || ce_is_borderblank(colors_for_drawing.extra)) ? 0 : colors_for_drawing.acolors[0];
}
// before first bitplane pixel appears.
// This means "bordersprite" condition is possible under OCS/ECS too. Argh!
if (dip_for_drawing->nr_sprites) {
- if (!colors_for_drawing.borderblank) {
+ if (!ce_is_borderblank(colors_for_drawing.extra)) {
/* bordersprite off or not supported: sprites are visible until diw_end */
if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) {
playfield_end = linetoscr_diw_end;
#ifdef AGA
may_require_hard_way = false;
- if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank && dip_for_drawing->nr_sprites) {
+ if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra) && dip_for_drawing->nr_sprites) {
int min = visible_right_border, max = visible_left_border, i;
for (i = 0; i < dip_for_drawing->nr_sprites; i++) {
int x;
int first_x = sprite_first_x;
int last_x = sprite_last_x;
if (first_x < last_x) {
- if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank) {
+ if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra)) {
if (first_x > visible_left_border)
first_x = visible_left_border;
if (last_x < visible_right_border)
static bool get_genlock_very_rare_and_complex_case(uae_u8 v)
{
// border color without BRDNTRAN bit set = transparent
- if (v == 0 && !colors_for_drawing.borderntrans)
+ if (v == 0 && !ce_is_borderntrans(colors_for_drawing.extra))
return false;
if (ecs_genlock_features_colorkey) {
// color key match?
{
int add = get_shdelay_add();
int add2 = add * gfxvidinfo.drawbuffer.pixbytes;
+ if (add) {
+ // Clear skipped pixel(s).
+ pfield_do_linetoscr_shdelay_sprite(spix, dpix, dpix + add);
+ }
xlinebuffer += add2;
int out = pfield_do_linetoscr_shdelay_normal(spix, dpix, dpix_end);
xlinebuffer -= add2;
}
static int pfield_do_linetoscr_sprite_shdelay(int spix, int dpix, int dpix_end)
{
+ int out = spix;
+ if (dpix < real_playfield_start && dpix_end > real_playfield_start) {
+ // Crosses real_playfield_start.
+ // Render only from dpix to real_playfield_start.
+ int len = real_playfield_start - dpix;
+ out = pfield_do_linetoscr_spriteonly(out, dpix, dpix + len);
+ dpix = real_playfield_start;
+ } else if (dpix_end <= real_playfield_start) {
+ // Does not cross real_playfield_start, nothing special needed.
+ out = pfield_do_linetoscr_spriteonly(out, dpix, dpix_end);
+ return out;
+ }
+ // Render bitplane with subpixel scroll, from real_playfield_start to end.
int add = get_shdelay_add();
int add2 = add * gfxvidinfo.drawbuffer.pixbytes;
+ if (add) {
+ pfield_do_linetoscr_shdelay_sprite(out, dpix, dpix + add);
+ }
sprite_shdelay = add;
spritepixels += add;
xlinebuffer += add2;
- int out = pfield_do_linetoscr_shdelay_sprite(spix, dpix, dpix_end);
+ out = pfield_do_linetoscr_shdelay_sprite(out, dpix, dpix_end);
xlinebuffer -= add2;
spritepixels -= add;
sprite_shdelay = 0;
static void pfield_set_linetoscr (void)
{
xlinecheck(start, stop);
- enabled_sh = false;
spritepixels = spritepixels_buffer;
pfield_do_linetoscr_spriteonly = pfield_do_nothing;
#ifdef AGA
pfield_do_linetoscr_shdelay_sprite = pfield_do_linetoscr_sprite;
pfield_do_linetoscr_normal = pfield_do_linetoscr_normal_shdelay;
pfield_do_linetoscr_sprite = pfield_do_linetoscr_sprite_shdelay;
- enabled_sh = true;
}
}
#endif
pfield_do_fill_line (start, stop, blank);
return;
}
- src_pixel = pfield_do_linetoscr_spriteonly(src_pixel, start, stop);
+ pfield_do_linetoscr_spriteonly(src_pixel, start, stop);
}
static void dummy_worker (int start, int stop, bool blank)
sbasecol[0] = ((dp_for_drawing->bplcon4 >> 4) & 15) << 4;
sbasecol[1] = ((dp_for_drawing->bplcon4 >> 0) & 15) << 4;
bplxor = dp_for_drawing->bplcon4 >> 8;
- int obpldelay_sh = bpldelay_sh;
- bpldelay_sh = dp_for_drawing->bplcon2 >> 14;
- if ((bpldelay_sh && !obpldelay_sh) || (!bpldelay_sh && obpldelay_sh))
+ int sh = (colors_for_drawing.extra >> CE_SHRES_DELAY) & 3;
+ if (sh != bpldelay_sh) {
+ bpldelay_sh = sh;
pfield_mode_changed = true;
+ }
#endif
- ecs_genlock_features_active = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && ((dp_for_drawing->bplcon2 & 0x0c00) || colors_for_drawing.borderntrans) ? 1 : 0;
+ ecs_genlock_features_active = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && ((dp_for_drawing->bplcon2 & 0x0c00) || ce_is_borderntrans(colors_for_drawing.extra)) ? 1 : 0;
if (ecs_genlock_features_active) {
ecs_genlock_features_colorkey = false;
ecs_genlock_features_mask = 0;
} else {
memcpy (colors_for_drawing.acolors, curr_color_tables[ctable].acolors,
sizeof colors_for_drawing.acolors);
- colors_for_drawing.borderblank = curr_color_tables[ctable].borderblank;
- colors_for_drawing.bordersprite = curr_color_tables[ctable].bordersprite;
+ colors_for_drawing.extra = curr_color_tables[ctable].extra;
color_match_type = color_match_acolors;
}
drawing_color_matches = ctable;
pfield_expand_dp_bplconx (regno, value);
} else if (regno >= 0) {
if (regno == 0 && (value & COLOR_CHANGE_BRDBLANK)) {
- colors_for_drawing.borderblank = (value & 1) != 0;
- colors_for_drawing.bordersprite = (value & 3) == 2;
- colors_for_drawing.borderntrans = (value & 5) == 4;
+ colors_for_drawing.extra &= ~(1 << CE_BORDERBLANK);
+ colors_for_drawing.extra &= ~(1 << CE_BORDERNTRANS);
+ colors_for_drawing.extra &= ~(1 << CE_BORDERSPRITE);
+ colors_for_drawing.extra |= (value & 1) != 0 ? (1 << CE_BORDERBLANK) : 0;
+ colors_for_drawing.extra |= (value & 3) == 2 ? (1 << CE_BORDERSPRITE) : 0;
+ colors_for_drawing.extra |= (value & 5) == 4 ? (1 << CE_BORDERNTRANS) : 0;
+ } else if (regno == 0 && (value & COLOR_CHANGE_SHRES_DELAY)) {
+ colors_for_drawing.extra &= ~(1 << CE_SHRES_DELAY);
+ colors_for_drawing.extra &= ~(1 << (CE_SHRES_DELAY + 1));
+ colors_for_drawing.extra |= (value & 3) << CE_SHRES_DELAY;
+ pfield_expand_dp_bplcon();
} else {
color_reg_set (&colors_for_drawing, regno, value);
colors_for_drawing.acolors[regno] = getxcolor (value);
if (dip_for_drawing->nr_sprites) {
int i;
#ifdef AGA
- if (colors_for_drawing.bordersprite && dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank)
+ if (ce_is_bordersprite(colors_for_drawing.extra) && dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra))
clear_bitplane_border_aga ();
#endif
}
#ifdef AGA
- if (dip_for_drawing->nr_sprites && colors_for_drawing.bordersprite && !colors_for_drawing.borderblank && dp_for_drawing->bordersprite_seen)
+ if (dip_for_drawing->nr_sprites && ce_is_bordersprite(colors_for_drawing.extra) && !ce_is_borderblank(colors_for_drawing.extra) && dp_for_drawing->bordersprite_seen)
do_color_changes (pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr_spr, lineno);
else
#endif
adjust_drawing_colors (dp_for_drawing->ctable, 0);
#ifdef AGA /* this makes things complex.. */
- if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank && dip_for_drawing->nr_sprites) {
+ if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra) && dip_for_drawing->nr_sprites) {
dosprites = true;
pfield_expand_dp_bplcon ();
pfield_init_linetoscr (true);