static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 };
static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), 0 };
static const TCHAR *filterapiopts[] = { _T("hardware"), _T("software"), 0 };
+static const TCHAR *overscanmodes[] = { _T("tv_narrow"), _T("tv_standard"), _T("tv_wide"), _T("overscan"), _T("broadcast"), _T("extreme"), NULL };
static const TCHAR *dongles[] =
{
_T("none"),
cfgfile_dwrite(f, _T("gfx_vertical_extra"), _T("%d"), p->gfx_extraheight);
cfgfile_dwrite(f, _T("gfx_frame_slices"), _T("%d"), p->gfx_display_sections);
cfgfile_dwrite_bool(f, _T("gfx_vrr_monitor"), p->gfx_variable_sync != 0);
+ cfgfile_dwrite_str(f, _T("gfx_overscanmode"), overscanmodes[p->gfx_overscanmode]);
+
#ifdef GFXFILTER
for (int j = 0; j < 2; j++) {
|| cfgfile_strval(option, value, _T("gfx_api"), &p->gfx_api, filterapi, 0)
|| cfgfile_strval(option, value, _T("gfx_api_options"), &p->gfx_api_options, filterapiopts, 0)
|| cfgfile_strval(option, value, _T("gfx_atari_palette_fix"), &p->gfx_threebitcolors, threebitcolors, 0)
+ || cfgfile_strval(option, value, _T("gfx_overscanmode"), &p->gfx_overscanmode, overscanmodes, 0)
|| cfgfile_strval(option, value, _T("magic_mousecursor"), &p->input_magic_mouse_cursor, magiccursors, 0)
|| cfgfile_strval (option, value, _T("absolute_mouse"), &p->input_tablet, abspointers, 0))
return 1;
p->gfx_display_sections = 4;
p->gfx_variable_sync = 0;
p->gfx_windowed_resize = true;
+ p->gfx_overscanmode = 3;
p->immediate_blits = 0;
p->waiting_blits = 0;
#define SPRBORDER 0
+#define EXTRAWIDTH_BROADCAST 7
+#define EXTRAHEIGHT_BROADCAST 2
+#define EXTRAWIDTH_EXTREME 32
+#define EXTRAHEIGHT_EXTREME 24
+
extern uae_u16 serper;
STATIC_INLINE bool nocustom (void)
static int plffirstline, plflastline;
int plffirstline_total, plflastline_total;
+int vblank_firstline_hw, vblank_lastline_hw;
static int autoscale_bordercolors;
static int plfstrt, plfstop;
static int sprite_minx;
static void decide_vline(void)
{
+ bool forceoff = (vb_start_line == 1 && !harddis_v);
+
/* Take care of the vertical DIW. */
- if (vpos == plffirstline) {
- // Following line after VB start has bitplane DMA start inhibited (if HARDDIS=0)
- if (vb_start_line != 2 || harddis_v) {
- diwstate = DIW_waiting_stop;
- diwstate_vpos = vpos;
- SET_LINE_CYCLEBASED;
- }
+ if (vpos == plffirstline && !forceoff) {
+ diwstate = DIW_waiting_stop;
+ diwstate_vpos = vpos;
+ SET_LINE_CYCLEBASED;
}
// VB start line forces vertical display window off (if HARDDIS=0)
- if (vpos == plflastline || (vb_start_line == 1 && !harddis_v)) {
+ if (vpos == plflastline || forceoff) {
diwstate = DIW_waiting_start;
diwstate_vpos = vpos;
SET_LINE_CYCLEBASED;
bpldmawasactive = false;
bpl1mod_hpos = -1;
bpl2mod_hpos = -1;
- //plane0 = false;
+ plane0 = false;
delay_cycles_right_offset = 0;
toscr_right_edge_offset = 0;
vidinfo->drawbuffer.inyoffset = -1;
updateextblk();
- if (beamcon0 & 0x80) {
+ if (new_beamcon0 & 0x80) {
int res = GET_RES_AGNUS (bplcon0);
int vres = islace ? 1 : 0;
int res2, vres2;
} else {
vidinfo->drawbuffer.inwidth = maxhpos_display << currprefs.gfx_resolution;
- vidinfo->drawbuffer.extrawidth = currprefs.gfx_extrawidth ? currprefs.gfx_extrawidth : -1;
- vidinfo->drawbuffer.extraheight = currprefs.gfx_extraheight ? currprefs.gfx_extraheight : -1;
+ vidinfo->drawbuffer.extrawidth = -2;
+ if (currprefs.gfx_extrawidth > 0) {
+ vidinfo->drawbuffer.extrawidth = currprefs.gfx_extrawidth;
+ }
+ vidinfo->drawbuffer.extraheight = -2;
+ if (currprefs.gfx_extraheight > 0) {
+ vidinfo->drawbuffer.extraheight = currprefs.gfx_extraheight;
+ }
+ if (vidinfo->drawbuffer.extrawidth == -2 && ((new_beamcon0 & (0x1000 | 0x0200 | 0x0010)) || currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME)) {
+ vidinfo->drawbuffer.extrawidth = -1;
+ }
vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth;
vidinfo->drawbuffer.inheight = (maxvpos_display - minfirstline + maxvpos_display_vsync) << currprefs.gfx_vresolution;
vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.inheight;
if (beamcon0 != new_beamcon0) {
vpos_count_diff = vpos_count = 0;
}
+ if ((beamcon0 & (0x1000 | 0x0200 | 0x0010)) != (new_beamcon0 & (0x1000 | 0x0200 | 0x0010))) {
+ hzc = 1;
+ }
+
beamcon0 = new_beamcon0;
isntsc = (beamcon0 & 0x20) ? 0 : 1;
islace = (interlace_seen) ? 1 : 0;
}
if (currprefs.gfx_extrawidth > 0) {
maxhpos_display += currprefs.gfx_extrawidth;
+ } else if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
+ maxhpos_display += EXTRAWIDTH_EXTREME;
+ } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
+ maxhpos_display += EXTRAWIDTH_BROADCAST;
}
+
// A1000/OCS Denise has topmost line "almost" blanked
if (!ecs_denise) {
minfirstline--;
}
vblank_extraline = !currprefs.cs_dipagnus && !ecs_denise ? 1 : 0;
+
+ vblank_lastline_hw = maxvpos + maxvpos_display_vsync + vblank_extraline;
+ vblank_firstline_hw = minfirstline;
+
+ int maxvpos_display_vsync_hw = maxvpos_display_vsync;
+ int minfirstline_hw = minfirstline;
+ if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
+ minfirstline_hw -= EXTRAHEIGHT_EXTREME / 2;
+ maxvpos_display_vsync_hw += EXTRAHEIGHT_EXTREME / 2;
+ } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
+ minfirstline_hw -= EXTRAHEIGHT_BROADCAST / 2;
+ maxvpos_display_vsync_hw += EXTRAHEIGHT_BROADCAST / 2;
+ }
+ if (beamcon0 & 0x0080) {
+ minfirstline_hw = 0;
+ }
+
if (vpos_count > 0) {
// we come here if vpos_count != maxvpos and beamcon0 didn't change
// (someone poked VPOSW)
maxvpos_display_vsync = 4;
}
- if (currprefs.gfx_extraheight > 0) {
+ int eh = currprefs.gfx_extraheight;
+ if (eh <= 0) {
+ if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
+ eh = EXTRAHEIGHT_EXTREME;
+ } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
+ eh = EXTRAHEIGHT_BROADCAST;
+ }
+ }
+ if (eh > 0) {
if (beamcon0 & (0x0200 | 0x0010)) {
- maxvpos_display_vsync += currprefs.gfx_extraheight / 2;
- minfirstline -= currprefs.gfx_extraheight / 2;
- if (maxvpos_display_vsync >= vsstop) {
- maxvpos_display_vsync = vsstop - 1;
- }
- if (minfirstline <= vsstop) {
- minfirstline = vsstop + 1;
- }
+ maxvpos_display_vsync += eh / 2;
+ minfirstline -= eh / 2;
} else {
maxvpos_display_vsync = 3;
- minfirstline -= currprefs.gfx_extraheight / 2;
+ minfirstline -= eh / 2;
if (minfirstline < 8) {
minfirstline = 8;
}
if (minfirstline < 1) {
minfirstline = 1;
}
- if (!(beamcon0 & 0x80) && minfirstline < 8 && !currprefs.gfx_extraheight) {
+ if (!(beamcon0 & 0x80) && minfirstline < 8 && !eh) {
minfirstline = 8;
}
firstblankedline = maxvpos + 1;
}
+ if (minfirstline < minfirstline_hw) {
+ minfirstline = minfirstline_hw;
+ }
+ if (maxvpos_display_vsync > maxvpos_display_vsync_hw) {
+ maxvpos_display_vsync = maxvpos_display_vsync_hw;
+ }
+
+ if (beamcon0 & (0x0200 | 0x0010)) {
+ if (maxvpos_display_vsync >= vsstop) {
+ maxvpos_display_vsync = vsstop - 1;
+ }
+ if (minfirstline <= vsstop) {
+ minfirstline = vsstop + 1;
+ }
+ }
+
if (beamcon0 & 0x80) {
// programmable scanrates (ECS Agnus)
if (vtotal >= MAXVPOS) {
dumpsync();
}
}
- if ((beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000)) != (new_beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000))) {
- varsync_changed = 2;
- }
beamcon0_saved = v;
record_register_change(hpos, 0x1dc, new_beamcon0);
check_harddis();
}
#endif
updateextblk();
- if (!(beamcon0 & (0x80 | 0x1000 | 0x0200 | 0x0100 | 0x4000)))
- return;
- varsync_changed = 2;
}
#ifdef PICASSO96
if (!aga_mode) {
v &= ~(0x0008 | 0x0010 | 0x1000 | 0x0800);
}
- v &= ~(0x08000 | 0x4000 | 0x0080 | 0x0040);
+ v &= ~(0x8000 | 0x4000 | 0x0080 | 0x0040);
if (diwhigh_written && diwhigh == v) {
return;
}
// autoscale if copper changes COLOR00 on top or bottom of screen
if (vpos >= minfirstline) {
int vpos2 = autoscale_bordercolors ? minfirstline : vpos;
- if (first_planes_vpos == 0)
+ if (first_planes_vpos == 0) {
first_planes_vpos = vpos2 - 2;
- if (plffirstline_total == current_maxvpos ())
+ }
+ if (plffirstline_total == current_maxvpos()) {
plffirstline_total = vpos2 - 2;
- if (vpos2 > last_planes_vpos || vpos2 > plflastline_total)
+ }
+ if (vpos2 > last_planes_vpos || vpos2 > plflastline_total) {
plflastline_total = last_planes_vpos = vpos2 + 3;
+ }
autoscale_bordercolors = 0;
} else {
autoscale_bordercolors++;
}
}
+// line=0
static void init_hardware_frame(void)
{
- first_bpl_vpos = -1;
if (!harddis_v) {
diwstate = DIW_waiting_start;
}
-
- if (first_bplcon0 != first_bplcon0_old) {
- vertical_changed = horizontal_changed = true;
- }
- first_bplcon0_old = first_bplcon0;
-
- if (first_planes_vpos != first_planes_vpos_old ||
- last_planes_vpos != last_planes_vpos_old) {
- vertical_changed = true;
- }
- first_planes_vpos_old = first_planes_vpos;
- last_planes_vpos_old = last_planes_vpos;
-
- if (diwfirstword_total != diwfirstword_total_old ||
- diwlastword_total != diwlastword_total_old ||
- ddffirstword_total != ddffirstword_total_old ||
- ddflastword_total != ddflastword_total_old) {
- horizontal_changed = true;
- }
- diwfirstword_total_old = diwfirstword_total;
- diwlastword_total_old = diwlastword_total;
- ddffirstword_total_old = ddffirstword_total;
- ddflastword_total_old = ddflastword_total;
-
- first_planes_vpos = 0;
- last_planes_vpos = 0;
- diwfirstword_total = max_diwlastword;
- diwlastword_total = 0;
- ddffirstword_total = max_diwlastword;
- ddflastword_total = 0;
- plflastline_total = 0;
- plffirstline_total = current_maxvpos();
- first_bplcon0 = 0;
- autoscale_bordercolors = 0;
}
+// vsync start
void init_hardware_for_drawing_frame(void)
{
/* Avoid this code in the first frame after a customreset. */
devices_vsync_post();
+ if ((beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000)) != (new_beamcon0 & (0x10 | 0x20 | 0x80 | 0x100 | 0x200 | 0x1000 | 0x4000))) {
+ if (!varsync_changed) {
+ varsync_changed = 2;
+ }
+ }
vsync_check_vsyncmode();
lof_changed = 0;
return true;
}
+static void reset_autoscale(void)
+{
+ first_bpl_vpos = -1;
+ if (first_bplcon0 != first_bplcon0_old) {
+ vertical_changed = horizontal_changed = true;
+ }
+ first_bplcon0_old = first_bplcon0;
+
+ if (first_planes_vpos != first_planes_vpos_old ||
+ last_planes_vpos != last_planes_vpos_old) {
+ vertical_changed = true;
+ }
+ first_planes_vpos_old = first_planes_vpos;
+ last_planes_vpos_old = last_planes_vpos;
+
+ if (diwfirstword_total != diwfirstword_total_old ||
+ diwlastword_total != diwlastword_total_old ||
+ ddffirstword_total != ddffirstword_total_old ||
+ ddflastword_total != ddflastword_total_old) {
+ horizontal_changed = true;
+ }
+ diwfirstword_total_old = diwfirstword_total;
+ diwlastword_total_old = diwlastword_total;
+ ddffirstword_total_old = ddffirstword_total;
+ ddflastword_total_old = ddflastword_total;
+
+ first_planes_vpos = 0;
+ last_planes_vpos = 0;
+ diwfirstword_total = max_diwlastword;
+ diwlastword_total = 0;
+ ddffirstword_total = max_diwlastword;
+ ddflastword_total = 0;
+ plflastline_total = 0;
+ plffirstline_total = current_maxvpos();
+ first_bplcon0 = 0;
+ autoscale_bordercolors = 0;
+}
+
+static void hautoscale_check(void)
+{
+ // border detection/autoscale
+ if (GET_PLANES(bplcon0) > 0 && dmaen(DMA_BITPLANE)) {
+ if (first_bplcon0 == 0) {
+ first_bplcon0 = bplcon0;
+ }
+ if (vpos > last_planes_vpos) {
+ last_planes_vpos = vpos;
+ }
+ if (vpos >= minfirstline && first_planes_vpos == 0) {
+ first_planes_vpos = vpos > minfirstline ? vpos - 1 : vpos;
+ } else if (vpos >= current_maxvpos() - 1) {
+ last_planes_vpos = current_maxvpos();
+ }
+ }
+ if (diw_change == 0) {
+ if (vpos >= first_planes_vpos && vpos <= last_planes_vpos) {
+ int diwlastword_lores = diwlastword;
+ int diwfirstword_lores = diwfirstword;
+ if (diwlastword_lores > diwlastword_total) {
+ diwlastword_total = diwlastword_lores;
+ if (diwlastword_total > coord_diw_shres_to_window_x(hsyncstartpos)) {
+ diwlastword_total = coord_diw_shres_to_window_x(hsyncstartpos);
+ }
+ }
+ if (diwfirstword_lores < diwfirstword_total) {
+ diwfirstword_total = diwfirstword_lores;
+ if (diwfirstword_total < coord_diw_shres_to_window_x(hsyncendpos)) {
+ diwfirstword_total = coord_diw_shres_to_window_x(hsyncendpos);
+ }
+ firstword_bplcon1 = bplcon1;
+ }
+ }
+ if (diwstate == DIW_waiting_stop) {
+ int f = 8 << fetchmode;
+ if (plfstrt + f < ddffirstword_total + f) {
+ ddffirstword_total = plfstrt + f;
+ }
+ if (plfstop + 2 * f > ddflastword_total + 2 * f) {
+ ddflastword_total = plfstop + 2 * f;
+ }
+ }
+ if ((plffirstline < plffirstline_total || (plffirstline_total == minfirstline && vpos > minfirstline)) && plffirstline < maxvpos / 2) {
+ firstword_bplcon1 = bplcon1;
+ if (plffirstline < minfirstline) {
+ plffirstline_total = minfirstline;
+ } else {
+ plffirstline_total = plffirstline;
+ }
+ }
+ if (plflastline > plflastline_total && plflastline > plffirstline_total && plflastline > maxvpos / 2) {
+ plflastline_total = plflastline;
+ }
+ }
+ if (diw_change > 0) {
+ diw_change--;
+ }
+}
+
static void hsync_handlerh(bool onvsync)
{
int hpos = current_hpos();
notice_resolution_seen(GET_RES_AGNUS(bplcon0), interlace_seen != 0);
+ hautoscale_check();
+
int lineno = vposh;
if (lineno >= MAXVPOS) {
lineno %= MAXVPOS;
#endif
} else if (currprefs.cs_ciaatod == 0 && ciavsyncs) {
// CIA-A TOD counter increases when vsync pulse ends
- if (beamcon0 & 0x200) {
+ if (beamcon0 & 0x0200) {
if (vpos == vsstop && vs_state == true) {
CIAA_tod_inc(lof_store ? hsstop : hsstop + hcenter);
}
lof_lastline = lof_store != 0;
}
- decide_vline();
-
vb_end_next_line = false;
if (vb_start_line) {
vb_start_line++;
vb_end_line = false;
vb_end_next_line = true;
}
+
if (ecs_agnus) {
if (vsstrt_m == vpos) {
vsstrt_m = -1;
}
}
+ decide_vline();
+
int hp = REFRESH_FIRST_HPOS;
for (int i = 0; i < 4; i++) {
alloc_cycle(hp, i == 0 ? CYCLE_STROBE : CYCLE_REFRESH); /* strobe */
compute_spcflag_copper();
- // border detection/autoscale
- if (GET_PLANES (bplcon0) > 0 && dmaen(DMA_BITPLANE)) {
- if (first_bplcon0 == 0) {
- first_bplcon0 = bplcon0;
- }
- if (vpos > last_planes_vpos) {
- last_planes_vpos = vpos;
- }
- if (vpos >= minfirstline && first_planes_vpos == 0) {
- first_planes_vpos = vpos > minfirstline ? vpos - 1 : vpos;
- } else if (vpos >= current_maxvpos() - 1) {
- last_planes_vpos = current_maxvpos();
- }
- }
- if (diw_change == 0) {
- if (vpos >= first_planes_vpos && vpos <= last_planes_vpos) {
- int diwlastword_lores = diwlastword;
- int diwfirstword_lores = diwfirstword;
- if (diwlastword_lores > diwlastword_total) {
- diwlastword_total = diwlastword_lores;
- if (diwlastword_total > coord_diw_shres_to_window_x(hsyncstartpos)) {
- diwlastword_total = coord_diw_shres_to_window_x(hsyncstartpos);
- }
- }
- if (diwfirstword_lores < diwfirstword_total) {
- diwfirstword_total = diwfirstword_lores;
- if (diwfirstword_total < coord_diw_shres_to_window_x(hsyncendpos)) {
- diwfirstword_total = coord_diw_shres_to_window_x(hsyncendpos);
- }
- firstword_bplcon1 = bplcon1;
- }
- }
- if (diwstate == DIW_waiting_stop) {
- int f = 8 << fetchmode;
- if (plfstrt + f < ddffirstword_total + f) {
- ddffirstword_total = plfstrt + f;
- }
- if (plfstop + 2 * f > ddflastword_total + 2 * f) {
- ddflastword_total = plfstop + 2 * f;
- }
- }
- if ((plffirstline < plffirstline_total || (plffirstline_total == minfirstline && vpos > minfirstline)) && plffirstline < maxvpos / 2) {
- firstword_bplcon1 = bplcon1;
- if (plffirstline < minfirstline) {
- plffirstline_total = minfirstline;
- } else {
- plffirstline_total = plffirstline;
- }
- }
- if (plflastline > plflastline_total && plflastline > plffirstline_total && plflastline > maxvpos / 2) {
- plflastline_total = plflastline;
- }
- }
- if (diw_change > 0) {
- diw_change--;
- }
+
#if 0
/* fastest possible + last line and no vflip wait: render the frame as early as possible */
if (vpos == maxvpos_display_vsync) {
vsync_display_render();
vsync_display_rendered = false;
+ reset_autoscale();
}
vsync_line = vs;
hsync_handler_post(vs);
case 0x1C2:
if (hsstop != value) {
hsstop = value & (MAXHPOS_ROWS - 1);
- //record_register_change(hpos, 0x1c2, hsstop);
varsync();
}
break;
hbstrt = value & 0x7ff;
varsync();
updateextblk();
- //record_register_change(hpos, 0x1c4, hbstrt);
+ if (exthblank) {
+ record_color_change2(hpos, 0xffff, 0);
+ }
}
break;
case 0x1C6:
hbstop = value & 0x7ff;
varsync();
updateextblk();
- //record_register_change(hpos, 0x1c6, hbstop);
+ if (exthblank) {
+ record_color_change2(hpos, 0xffff, 0);
+ }
}
break;
case 0x1C8:
case 0x1DE:
if (hsstrt != value) {
hsstrt = value & (MAXHPOS_ROWS - 1);
- //record_register_change(hpos, 0x1de, hsstrt);
varsync();
}
break;
peekdma_data.mask = 0;
#endif
+ x_do_cycles_pre(CYCLE_UNIT);
+
switch (mode) {
case -1:
v = get_long(addr);
}
#endif
- x_do_cycles_pre(CYCLE_UNIT);
-
-
regs.chipset_latch_rw = regs.chipset_latch_read = v;
SETIFCHIP;
/* 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 */
+/* same for blank */
+static int vblank_top_start, vblank_bottom_stop;
static int hblank_left_start, hblank_right_stop;
static bool exthblank;
{
hblank_left_start = visible_left_start;
hblank_right_stop = visible_right_stop;
+ vblank_top_start = visible_top_start;
+ vblank_bottom_stop = visible_bottom_stop;
+
if (hblank_left_start < visible_left_border) {
hblank_left_start = visible_left_border;
}
if (hblank_right_stop > visible_right_border) {
hblank_right_stop = visible_right_border;
}
+ if (vblank_top_start < visible_top_start) {
+ vblank_top_start = visible_top_start;
+ }
+ if (vblank_bottom_stop > visible_bottom_stop) {
+ vblank_bottom_stop = visible_bottom_stop;
+ }
- int hbstrt = 0;
- int hbstop = 0;
- int offset = -1;
-
- if (!dp_for_drawing || !ce_is_extblankset(colors_for_drawing.extra) || !ce_is_extblankmode(colors_for_drawing.extra)) {
+ if (!dp_for_drawing || !ce_is_extblankset(colors_for_drawing.extra) || !ce_is_extblankmode(colors_for_drawing.extra) || (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN && !(new_beamcon0 & 0x80))) {
// hardwired blanking
- // has 1.5 hires pixel offset
- offset = 3;
- hbstrt = hsyncstartpos_hw;
- hbstop = hsyncendpos_hw;
- exthblank = false;
- }
- if (offset >= 0) {
- if (hblank_left_start < coord_hw_to_window_x_shres(hbstop - offset)) {
- hblank_left_start = coord_hw_to_window_x_shres(hbstop - offset);
+ int hbstrt = (235 << CCK_SHRES_SHIFT) - 3;
+ int hbstop = (47 << CCK_SHRES_SHIFT) - 7;
+
+ if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) {
+ int mult = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 4;
+ hbstrt -= mult << CCK_SHRES_SHIFT;
+ hbstop += mult << CCK_SHRES_SHIFT;
+ if (currprefs.gfx_overscanmode == 0) {
+ hbstrt += 2 << CCK_SHRES_SHIFT;
+ hbstop -= 2 << CCK_SHRES_SHIFT;
+ }
+ }
+ if (!dp_for_drawing || !ce_is_extblankset(colors_for_drawing.extra) || !ce_is_extblankmode(colors_for_drawing.extra)) {
+ exthblank = false;
+ } else if (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) {
+ if ((new_beamcon0 & 0x0110) && !(new_beamcon0 & 0x80)) {
+ extern uae_u16 hsstrt;
+ hbstrt += (hsstrt - 13) << CCK_SHRES_SHIFT;
+ hbstop += (hsstrt - 13) << CCK_SHRES_SHIFT;
+ }
+ }
+ if (currprefs.chipset_hr) {
+ hbstrt &= ~(3 >> currprefs.gfx_resolution);
+ hbstop &= ~(3 >> currprefs.gfx_resolution);
+ } else {
+ hbstrt &= ~3;
+ hbstop &= ~3;
}
- if (hblank_right_stop > coord_hw_to_window_x_shres(hbstrt - offset)) {
- hblank_right_stop = coord_hw_to_window_x_shres(hbstrt - offset);
+ if (hblank_left_start < coord_hw_to_window_x_shres(hbstop)) {
+ hblank_left_start = coord_hw_to_window_x_shres(hbstop);
+ }
+ if (hblank_right_stop > coord_hw_to_window_x_shres(hbstrt)) {
+ hblank_right_stop = coord_hw_to_window_x_shres(hbstrt);
+ }
+ }
+ if (!(new_beamcon0 & 0x1000) || (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN && !(new_beamcon0 & 0x80))) {
+ int vbstrt = vblank_firstline_hw;
+ int vbstop = vblank_lastline_hw;
+
+ if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) {
+ int mult = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 5;
+ vbstrt += mult;
+ vbstop -= mult;
+ }
+
+ vbstrt <<= currprefs.gfx_vresolution;
+ vbstop <<= currprefs.gfx_vresolution;
+ if (vblank_top_start < vbstrt) {
+ vblank_top_start = vbstrt;
+ }
+ if (vblank_bottom_stop > vbstop) {
+ vblank_bottom_stop = vbstop;
}
}
}
ddflastword_total = coord_hw_to_window_x_lores(ddflastword_total * 2 + DIW_DDF_OFFSET);
if (doublescan <= 0 && !programmedmode) {
- int min = coord_diw_lores_to_window_x (92);
- int max = coord_diw_lores_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)
int endpos = visible_right_border;
int w = endpos - lastpos;
- if (lineno < visible_top_start || lineno >= visible_bottom_stop) {
+ if (lineno < visible_top_start || lineno < vblank_top_start || lineno >= visible_bottom_stop || lineno >= vblank_bottom_stop) {
int b = hposblank;
hposblank = 3;
fill_line2(lastpos, w);
}
// vblank + extblanken: blanked
- if (!(vb_state & 1) && ce_is_extblankset(colors_for_drawing.extra)) {
+ if (!(vb_state & 1) && ce_is_extblankset(colors_for_drawing.extra) || vp < vblank_top_start || vp >= vblank_bottom_stop) {
if (nextpos_in_range > lastpos && lastpos < playfield_end) {
int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end;
}
}
#if 1
- if (vp < visible_top_start || vp >= visible_bottom_stop) {
+ if (vp < visible_top_start || vp >= visible_bottom_stop || vp < vblank_top_start || vp >= vblank_bottom_stop) {
// outside of visible area
// Just overwrite with black. Above code needs to run because of custom registers,
// not worth the trouble for separate code path just for max 10 lines or so
- (*worker_border)(visible_left_border, visible_left_border + vidinfo->drawbuffer.inwidth, 1);
+ (*worker_border)(visible_left_border, visible_right_border - visible_left_border, 1);
}
#endif
if (hsync_shift_hack > 0) {
int shift = (hsync_shift_hack << lores_shift) * vidinfo->drawbuffer.pixbytes;
if (shift) {
int firstpos = visible_left_border * vidinfo->drawbuffer.pixbytes;
- int lastpos = (visible_left_border + vidinfo->drawbuffer.inwidth) * vidinfo->drawbuffer.pixbytes;
+ int lastpos = (visible_right_border - visible_left_border) * vidinfo->drawbuffer.pixbytes;
memmove(xlinebuffer + firstpos, xlinebuffer + firstpos + shift, lastpos - firstpos - shift);
memset(xlinebuffer + lastpos - shift, 0, shift);
}
int w = vidinfo->drawbuffer.inwidth;
int ew = vidinfo->drawbuffer.extrawidth;
- if (currprefs.gfx_xcenter && !currprefs.gf[0].gfx_filter_autoscale && max_diwstop > 0) {
+ if (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN && currprefs.gfx_xcenter && !currprefs.gf[0].gfx_filter_autoscale && max_diwstop > 0) {
if (max_diwstop - min_diwstart < w && currprefs.gfx_xcenter == 2)
/* Try to center. */
}
}
#endif
- } else if (vidinfo->drawbuffer.extrawidth) {
+ } else if (vidinfo->drawbuffer.extrawidth > 0 || ew == -1 || currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
+ // wide mode
visible_left_border = (hsync_end_left_border * 2) << currprefs.gfx_resolution;
if (visible_left_border + w < max_diwlastword) {
visible_left_border += (max_diwlastword - (visible_left_border + w)) / 2;
if (visible_left_border < ((hsync_end_left_border * 2) << currprefs.gfx_resolution)) {
visible_left_border = (hsync_end_left_border * 2) << currprefs.gfx_resolution;
}
+ } else if (ew < -1) {
+ // normal
+ visible_left_border = max_diwlastword - w;
} else {
if (vidinfo->drawbuffer.inxoffset < 0) {
visible_left_border = 0;
extern float hblank_hz;
extern int vblank_skip, doublescan;
extern bool programmedmode;
+extern int vblank_firstline_hw, vblank_lastline_hw;
#define DMA_AUD0 0x0001
#define DMA_AUD1 0x0002
#define CYCLE_MASK 0x0f
extern unsigned long frametime, timeframes;
-extern uae_u16 htotal, vtotal, beamcon0;
+extern uae_u16 htotal, vtotal, beamcon0, new_beamcon0;
// 100 words give you 1600 horizontal pixels. Should be more than enough for superhires.
// must be divisible by 8
#define MONITOREMU_OPALVISION 11
#define MONITOREMU_COLORBURST 12
+#define OVERSCANMODE_OVERSCAN 3
+#define OVERSCANMODE_BROADCAST 4
+#define OVERSCANMODE_EXTREME 5
+
#define MAX_FILTERSHADERS 4
#define MAX_CHIPSET_REFRESH 10
int gfx_display_sections;
int gfx_variable_sync;
bool gfx_windowed_resize;
+ int gfx_overscanmode;
struct gfx_filterdata gf[2];
#define IDC_AUTORESOLUTIONVGA 1181
#define IDC_RATE2ENABLE 1182
#define IDC_GRAYSCALE 1183
+#define IDC_OVERSCANMODE 1184
#define IDC_FRAMERATE 1185
#define IDC_XSIZE 1187
#define IDC_YSIZE 1188
CONTROL "VGA mode resolution autoswitch [] Automatically selects between hires and superhires in programmed display modes, keeping correct aspect ratio.",IDC_AUTORESOLUTIONVGA,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,155,158,124,10
CONTROL "Monochrome video out",IDC_GRAYSCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,171,139,10
- RTEXT "Resolution:",IDC_STATIC,24,196,110,8,SS_CENTERIMAGE
- COMBOBOX IDC_LORES,142,195,127,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+ RTEXT "Resolution:",IDC_STATIC,6,196,44,8,SS_CENTERIMAGE
+ COMBOBOX IDC_LORES,57,195,77,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
RTEXT "Resolution autoswitch:",IDC_STATIC,92,216,110,8,SS_CENTERIMAGE
- COMBOBOX IDC_AUTORESOLUTIONSELECT,210,215,59,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_AUTORESOLUTIONSELECT,214,215,63,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
RTEXT "Refresh:",IDC_REFRESHTEXT,11,235,57,8
CONTROL "Slider1",IDC_FRAMERATE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,71,230,99,20
- COMBOBOX IDC_RATE2BOX,210,235,60,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_RATE2BOX,213,235,64,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
RTEXT "FPS adj.:",IDC_REFRESH2TEXT,9,256,61,8
CONTROL "",IDC_FRAMERATE2,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,71,251,99,20
- EDITTEXT IDC_RATE2TEXT,210,255,46,12,ES_AUTOHSCROLL
- CONTROL "",IDC_RATE2ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,261,256,8,10
+ EDITTEXT IDC_RATE2TEXT,212,255,46,12,ES_AUTOHSCROLL
+ CONTROL "",IDC_RATE2ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,265,256,8,10
COMBOBOX IDC_DA_MODE,15,280,71,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_DA_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,96,276,96,20
EDITTEXT IDC_DA_TEXT,205,280,56,12,ES_AUTOHSCROLL | ES_READONLY
CONTROL "VRR monitor. Do not tick!",IDC_DISPLAY_VARSYNC,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,58,71,112,10
COMBOBOX IDC_SCREENMODE_NATIVE3,246,102,31,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
CONTROL "Window resize",IDC_DISPLAY_RESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,161,55,92,10
+ COMBOBOX IDC_OVERSCANMODE,197,194,80,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+ RTEXT "Overscan:",IDC_STATIC,145,196,43,8,SS_CENTERIMAGE
END
IDD_MEMORY DIALOGEX 0, 0, 396, 316
c |= _tcsicmp(currprefs.genlock_video_file, changed_prefs.genlock_video_file) ? (2 | 8) : 0;
c |= currprefs.gfx_lores_mode != changed_prefs.gfx_lores_mode ? (2 | 8) : 0;
+ c |= currprefs.gfx_overscanmode != changed_prefs.gfx_overscanmode ? (2 | 8) : 0;
c |= currprefs.gfx_scandoubler != changed_prefs.gfx_scandoubler ? (2 | 8) : 0;
c |= currprefs.gfx_threebitcolors != changed_prefs.gfx_threebitcolors ? (256) : 0;
c |= currprefs.gfx_grayscale != changed_prefs.gfx_grayscale ? (512) : 0;
_tcscpy(currprefs.genlock_video_file, changed_prefs.genlock_video_file);
currprefs.gfx_lores_mode = changed_prefs.gfx_lores_mode;
+ currprefs.gfx_overscanmode = changed_prefs.gfx_overscanmode;
currprefs.gfx_scandoubler = changed_prefs.gfx_scandoubler;
currprefs.gfx_threebitcolors = changed_prefs.gfx_threebitcolors;
currprefs.gfx_grayscale = changed_prefs.gfx_grayscale;
#ifndef PICASSO96
rtg = FALSE;
#endif
- ew (hDlg, IDC_SCREENMODE_RTG, rtg);
- ew (hDlg, IDC_SCREENMODE_RTG2, rtg);
- ew (hDlg, IDC_XCENTER, TRUE);
- ew (hDlg, IDC_YCENTER, TRUE);
- ew (hDlg, IDC_FRAMERATE, !workprefs.cpu_memory_cycle_exact);
- ew (hDlg, IDC_LORES, !workprefs.gfx_autoresolution);
+ ew(hDlg, IDC_SCREENMODE_RTG, rtg);
+ ew(hDlg, IDC_SCREENMODE_RTG2, rtg);
+ ew(hDlg, IDC_XCENTER, TRUE);
+ ew(hDlg, IDC_YCENTER, TRUE);
+ ew(hDlg, IDC_FRAMERATE, !workprefs.cpu_memory_cycle_exact);
+ ew(hDlg, IDC_LORES, !workprefs.gfx_autoresolution);
+ ew(hDlg, IDC_OVERSCANMODE, TRUE);
ew(hDlg, IDC_AUTORESOLUTIONVGA, workprefs.gfx_resolution >= RES_HIRES && workprefs.gfx_vresolution >= VRES_DOUBLE);
if (workprefs.gfx_resolution < RES_HIRES || workprefs.gfx_vresolution < VRES_DOUBLE) {
SendDlgItemMessage(hDlg, IDC_LORES, CB_ADDSTRING, 0, (LPARAM)buffer);
SendDlgItemMessage (hDlg, IDC_LORES, CB_SETCURSEL, workprefs.gfx_resolution, 0);
- SendDlgItemMessage(hDlg, IDC_AUTORESOLUTIONSELECT, CB_RESETCONTENT, 0, 0);
-
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("TV (narrow)"));
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("TV (standard"));
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("TV (wide)"));
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Overscan"));
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Overscan+"));
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Extreme"));
+ SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_SETCURSEL, workprefs.gfx_overscanmode, 0);
+ SendDlgItemMessage(hDlg, IDC_AUTORESOLUTIONSELECT, CB_RESETCONTENT, 0, 0);
WIN32GUI_LoadUIString(IDS_DISABLED, buffer, sizeof buffer / sizeof (TCHAR));
SendDlgItemMessage(hDlg, IDC_AUTORESOLUTIONSELECT, CB_ADDSTRING, 0, (LPARAM)buffer);
WIN32GUI_LoadUIString(IDS_ALWAYS_ON, buffer, sizeof buffer / sizeof (TCHAR));
init_resolution_combo (hDlg);
init_display_mode (hDlg);
return;
- } else if (LOWORD (wParam) == IDC_LORES) {
- posn = SendDlgItemMessage (hDlg, IDC_LORES, CB_GETCURSEL, 0, 0);
+ } else if (LOWORD(wParam) == IDC_LORES) {
+ posn = SendDlgItemMessage(hDlg, IDC_LORES, CB_GETCURSEL, 0, 0);
if (posn != CB_ERR)
workprefs.gfx_resolution = posn;
+ } else if (LOWORD(wParam) == IDC_OVERSCANMODE) {
+ posn = SendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_GETCURSEL, 0, 0);
+ if (posn != CB_ERR)
+ workprefs.gfx_overscanmode = posn;
} else if ((LOWORD (wParam) == IDC_RESOLUTION || LOWORD(wParam) == IDC_RESOLUTIONDEPTH) && dmode >= 0) {
workprefs.gfx_monitor[0].gfx_size_fs.width = md->DisplayModes[dmode].res.width;
workprefs.gfx_monitor[0].gfx_size_fs.height = md->DisplayModes[dmode].res.height;