brdblank = false;
#endif
if (hpos >= 0 && current_colors.borderblank != brdblank) {
- record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0));
+ record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (current_colors.bordersprite ? 2 : 0));
current_colors.borderblank = brdblank;
remembered_color_entry = -1;
}
return brdblank;
}
+
+static bool issprbrd (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
+{
+ bool brdsprt;
+#ifdef AGA
+ brdsprt = (currprefs.chipset_mask & CSMASK_AGA) && (bplcon0 & 1) && (bplcon3 & 0x02);
+#else
+ brdsprt = false;
+#endif
+ if (hpos >= 0 && current_colors.bordersprite != brdsprt) {
+ record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (current_colors.borderblank ? 1 : 0) | (brdsprt ? 2 : 0));
+ current_colors.bordersprite = brdsprt;
+ remembered_color_entry = -1;
+ if (brdsprt)
+ thisline_decision.bordersprite_seen = true;
+ }
+ return brdsprt;
+}
+
static void record_register_change (int hpos, int regno, uae_u16 value)
{
if (regno == 0x100) { // BPLCON0
thisline_decision.ham_seen = 1;
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);
} else if (regno == 0x106) { // BPLCON3
isbrdblank (hpos, bplcon0, value);
+ issprbrd (hpos, bplcon0, value);
}
record_color_change (hpos, regno + 0x1000, value);
}
thisline_decision.ham_seen = !! (bplcon0 & 0x800);
thisline_decision.ehb_seen = !! isehb (bplcon0, bplcon2);
thisline_decision.ham_at_start = !! (bplcon0 & 0x800);
+ thisline_decision.bordersprite_seen = issprbrd (-1, bplcon0, bplcon3);
/* decided_res shouldn't be touched before it's initialized by decide_line(). */
thisline_decision.diwfirstword = -1;
/* Pixels outside of visible_start and visible_stop are always black */
static int visible_left_start, visible_right_stop;
static int visible_top_start, visible_bottom_stop;
+/* same for hblank */
+static int hblank_left_start, hblank_right_stop;
static int linetoscr_x_adjust_bytes;
static int thisframe_y_adjust;
static int plf1pri, plf2pri, bplxor;
static uae_u32 plf_sprite_mask;
static int sbasecol[2] = { 16, 16 };
-static bool brdsprt, brdblank;
static int hposblank;
static bool specialmonitoron;
gclorealh = -1;
}
+static void set_blanking_limits (void)
+{
+ hblank_left_start = visible_left_start;
+ hblank_right_stop = visible_right_stop;
+
+ if (programmedmode) {
+ if (hblank_left_start < coord_hw_to_window_x (hsyncendpos * 2))
+ hblank_left_start = coord_hw_to_window_x (hsyncendpos * 2);
+ if (hblank_right_stop > coord_hw_to_window_x (hsyncstartpos * 2))
+ hblank_right_stop = coord_hw_to_window_x (hsyncstartpos * 2);
+ }
+}
+
void set_custom_limits (int w, int h, int dx, int dy)
{
int vls = visible_left_start;
if (vls != visible_left_start || vrs != visible_right_stop ||
vts != visible_top_start || vbs != visible_bottom_stop)
notice_screen_contents_lost ();
+ set_blanking_limits ();
}
int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh)
return xcolors[0x0f0];
else if (hposblank == 3)
return xcolors[0x00f];
- else if (brdblank)
+ else if ( colors_for_drawing.borderblank)
return xcolors[0x880];
//return colors_for_drawing.acolors[0];
return xcolors[0xf0f];
res_shift = lores_shift - bplres;
- if (dip_for_drawing->nr_sprites == 0) {
- if (linetoscr_diw_start < native_ddf_left)
- linetoscr_diw_start = native_ddf_left;
- if (linetoscr_diw_end > native_ddf_right)
- linetoscr_diw_end = native_ddf_right;
- }
-
/* Perverse cases happen. */
if (linetoscr_diw_end < linetoscr_diw_start)
linetoscr_diw_end = linetoscr_diw_start;
playfield_start = linetoscr_diw_start;
playfield_end = linetoscr_diw_end;
-
- if (beamcon0 & 0x80) {
- if (playfield_start < coord_hw_to_window_x (hsyncendpos * 2 + DIW_DDF_OFFSET))
- playfield_start = coord_hw_to_window_x (hsyncendpos * 2 + DIW_DDF_OFFSET);
- if (playfield_end > coord_hw_to_window_x (hsyncstartpos * 2 + DIW_DDF_OFFSET))
- playfield_end = coord_hw_to_window_x (hsyncstartpos * 2 + DIW_DDF_OFFSET);
- }
+ if (playfield_start < native_ddf_left)
+ playfield_start = native_ddf_left;
+ if (playfield_end > native_ddf_right)
+ playfield_end = native_ddf_right;
unpainted = visible_left_border < playfield_start ? 0 : visible_left_border - playfield_start;
ham_src_pixel = MAX_PIXELS_PER_LINE + res_shift_from_window (playfield_start - native_ddf_left);
real_playfield_end = playfield_end;
real_playfield_start = playfield_start;
+
#ifdef AGA
- if (brdsprt && dip_for_drawing->nr_sprites) {
+ if (dp_for_drawing->bordersprite_seen && 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;
}
min = coord_hw_to_window_x (min >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift);
max = coord_hw_to_window_x (max >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift);
- if (beamcon0 & 0x80) {
- if (min < coord_hw_to_window_x (hsyncendpos * 2 + DIW_DDF_OFFSET))
- min = coord_hw_to_window_x (hsyncendpos * 2 + DIW_DDF_OFFSET);
- if (min > coord_hw_to_window_x (hsyncstartpos * 2 + DIW_DDF_OFFSET))
- min = coord_hw_to_window_x (hsyncstartpos * 2 + DIW_DDF_OFFSET);
- }
+
if (min < playfield_start)
playfield_start = min;
if (playfield_start < visible_left_border)
for (i = start; i < stop; i++)
b[i] = col;
}
-static void pfield_do_fill_line2 (int start, int stop, bool blank)
+static void pfield_do_fill_line (int start, int stop, bool blank)
{
switch (gfxvidinfo.drawbuffer.pixbytes) {
case 2: fill_line_16 (xlinebuffer, start, stop, blank); break;
case 4: fill_line_32 (xlinebuffer, start, stop, blank); break;
}
}
-static void pfield_do_fill_line (int start, int stop, bool blank)
-{
- xlinecheck(start, stop);
- if (!blank) {
- if (start < visible_left_start) {
- pfield_do_fill_line2 (start, visible_left_start, true);
- start = visible_left_start;
- }
- if (stop > visible_right_stop) {
- pfield_do_fill_line2 (start, visible_right_stop, false);
- blank = true;
- start = visible_right_stop;
- }
- }
- pfield_do_fill_line2 (start, stop, blank);
-}
-
STATIC_INLINE void fill_line2 (int startpos, int len)
{
visible_right_stop = MAX_STOP;
visible_top_start = 0;
visible_bottom_stop = MAX_STOP;
+ set_blanking_limits ();
}
/*
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;
- brdsprt = !brdblank && (currprefs.chipset_mask & CSMASK_AGA) && (dp_for_drawing->bplcon0 & 1) && (dp_for_drawing->bplcon3 & 0x02);
bplxor = dp_for_drawing->bplcon4 >> 8;
#endif
}
if (nextpos > endpos)
nextpos_in_range = endpos;
- if (nextpos_in_range > lastpos) {
- if (lastpos < playfield_start) {
- int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start;
- (*worker_border) (lastpos, t, false);
- lastpos = t;
- }
+ // left hblank (left edge to hblank end)
+ if (nextpos_in_range > lastpos && lastpos < hblank_left_start) {
+ int t = nextpos_in_range <= hblank_left_start ? nextpos_in_range : hblank_left_start;
+ (*worker_border) (lastpos, t, true);
+ lastpos = t;
}
- if (nextpos_in_range > lastpos) {
- if (lastpos >= playfield_start && lastpos < playfield_end) {
- int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
- (*worker_pfield) (lastpos, t, false);
- /* blank start and end that shouldn't be visible */
- if (lastpos < visible_left_start)
- (*worker_border) (lastpos, visible_left_start, true);
- if (t > visible_right_stop)
- (*worker_border) (visible_right_stop, endpos, true);
- lastpos = t;
- }
+
+ // 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, false);
+ 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;
+ (*worker_pfield) (lastpos, t, false);
+ lastpos = t;
}
- if (nextpos_in_range > lastpos) {
- if (lastpos >= playfield_end)
- (*worker_border) (lastpos, nextpos_in_range, false);
+
+ // right border (playfield end to hblank start)
+ if (nextpos_in_range > lastpos && lastpos >= playfield_end) {
+ int t = nextpos_in_range <= hblank_right_stop ? nextpos_in_range : hblank_right_stop;
+ (*worker_border) (lastpos, t, false);
+ lastpos = t;
+ }
+
+ // right hblank (hblank start to right edge, hblank start may be earlier than playfield end)
+ if (nextpos_in_range > hblank_right_stop) {
+ (*worker_border) (hblank_right_stop, nextpos_in_range, true);
lastpos = nextpos_in_range;
}
} else if (regno >= 0) {
if (regno == 0 && (value & COLOR_CHANGE_BRDBLANK)) {
colors_for_drawing.borderblank = (value & 1) != 0;
+ colors_for_drawing.bordersprite = (value & 2) != 0;
} 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 (brdsprt)
+ if (dp_for_drawing->bordersprite_seen)
clear_bitplane_border_aga ();
#endif
for (i = 0; i < dip_for_drawing->nr_sprites; i++) {
}
} else if (border == 1) {
- int dosprites = 0;
+ bool dosprites = false;
adjust_drawing_colors (dp_for_drawing->ctable, 0);
#ifdef AGA /* this makes things complex.. */
- if (brdsprt && dip_for_drawing->nr_sprites > 0) {
- dosprites = 1;
+ if (dp_for_drawing->bordersprite_seen && dip_for_drawing->nr_sprites > 0) {
+ dosprites = true;
pfield_expand_dp_bplcon ();
pfield_init_linetoscr ();
memset (pixdata.apixels + MAX_PIXELS_PER_LINE, colors_for_drawing.borderblank ? 0 : colors_for_drawing.acolors[0], MAX_PIXELS_PER_LINE);
return;
}
-
if (dosprites) {
int i;
} else {
int tmp = hposblank;
- //hposblank = brdblank;
hposblank = colors_for_drawing.borderblank;
fill_line ();
do_flush_line (vb, gfx_ypos);
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
printf ("\tCLEAR_CZNV ();\n");
printf ("\tif (src == 0) {\n");
- if (cpu_level > 0) {
- /* 68020 sets V when dividing by zero and N if dst is negative
- * 68000 clears both
- */
- printf("\t\tSET_VFLG (1);\n");
- printf("\t\tif (dst < 0) SET_NFLG (1);\n");
- }
+ if (cpu_level > 0)
+ printf ("\t\tdivbyzero_special (0, dst);\n");
incpc ("%d", m68k_pc_offset);
printf ("\t\tException (5);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
case i_DIVS:
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
- printf ("\tCLEAR_CZNV ();\n");
printf ("\tif (src == 0) {\n");
- if (cpu_level > 0) {
- /* 68000 Set Z. Clear N, V, C.
- * 68020 Set V, Z. Clear C and N. Keep X.
- * 68060 Clear C, everything else is kept.
- */
- printf("\t\tSET_VFLG (1);\n");
- printf("\t\tSET_ZFLG (1);\n");
- }
+ if (cpu_level > 0)
+ printf ("\t\tdivbyzero_special (1, dst);\n");
incpc ("%d", m68k_pc_offset);
printf ("\t\tException (5);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t} else {\n");
printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
+ printf ("\t\tCLEAR_CZNV ();\n");
fill_prefetch_next ();
if (using_ce) {
start_brace ();