static int fast_lines_cnt;
static bool lineoptimizations_draw_always;
static int agnus_trigger_cck;
+static int init_beamcon_delay;
static uae_u32 scandoubled_bpl_ptr[MAX_SCANDOUBLED_LINES + 1][2][MAX_PLANES];
static bool scandoubled_bpl_ena[MAX_SCANDOUBLED_LINES + 1];
*/
static bool agnus_phsync, agnus_phblank;
-static uae_u32 agnus_phblank_start_tmp, agnus_phblank_start, agnus_phblank_end, agnus_hsync_start;
+static uae_u32 agnus_phblank_start_tmp, agnus_phblank_start, agnus_phblank_end, agnus_hsync_start, agnus_vsync_start;
static int hsync_ccks;
static int current_linear_hs_hb_dist;
static uae_u32 agnus_hsstrt_cck, agnus_hsstop_cck;
frame_time_t idletime;
int bogusframe;
static int display_vsync_counter, display_hsync_counter;
-static evt_t display_last_hsync, display_last_vsync;
static bool ddf_limit_in, ddf_limit_out, ddf_limit, ddfstrt_match, hwi_old;
static int ddf_stopping, ddf_enable_on;
hpixels *= 2;
}
int vpixels = vsync_lines - minfirstline;
- int hpixelsd = hpixels * 85 / 100;
- if (hpixelsd < vpixels) {
- doublescan = 1;
- if (programmedmode == 2) {
- programmedmode = 1;
- }
- hpixelsd *= 2;
- }
- if (currprefs.gfx_keep_aspect) {
- bool dbl = line_is_doubled();
- if (dbl) {
- vpixels *= 2;
- }
+ if (vpixels > 0 && minfirstline > 0) {
+ int hpixelsd = hpixels * 85 / 100;
if (hpixelsd < vpixels) {
- doublescan2x = 1;
+ doublescan = 1;
+ if (programmedmode == 2) {
+ programmedmode = 1;
+ }
hpixelsd *= 2;
- if (hpixelsd < vpixels) {
- doublescan2x = 2;
+ }
+ if (currprefs.gfx_keep_aspect) {
+ bool dbl = line_is_doubled();
+ if (dbl) {
+ vpixels *= 2;
}
- } else if (hpixelsd > vpixels * 2) {
- doublescan2x = -1;
- if (hpixelsd > vpixels * 4) {
- doublescan2x = -2;
+ if (hpixelsd < vpixels) {
+ doublescan2x = 1;
+ hpixelsd *= 2;
+ if (hpixelsd < vpixels) {
+ doublescan2x = 2;
+ }
+ } else if (hpixelsd > vpixels * 2) {
+ doublescan2x = -1;
+ if (hpixelsd > vpixels * 4) {
+ doublescan2x = -2;
+ }
}
}
}
);
}
+// do not switch to H/V sync cable mode if required programmed mode registers are uninitialized
+static bool valid_programmed_mode(void)
+{
+ if ((beamcon0 & (BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN)) && programmed_register_accessed_h) {
+ if (hsstrt == 0xffff || hsstop == 0xffff) {
+ return false;
+ }
+ }
+ if ((beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) && programmed_register_accessed_v) {
+ if (vsstrt == 0xffff || vsstop == 0xffff) {
+ return false;
+ }
+ }
+ return true;
+}
+
/* set PAL/NTSC or custom timing variables */
static void init_beamcon0(void)
{
}
beamcon0_pal = !isntsc;
- if (currprefs.cs_hvcsync == HVSYNC_COMBINED || currprefs.cs_hvcsync == HVSYNC_COMBINED_SYNC) {
+ if ((currprefs.cs_hvcsync == HVSYNC_COMBINED || currprefs.cs_hvcsync == HVSYNC_COMBINED_SYNC) && valid_programmed_mode()) {
bemcon0_hsync_mask = BEAMCON0_VARHSYEN | BEAMCON0_VARCSYEN;
bemcon0_vsync_mask = BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN;
- } else if (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC) {
- bemcon0_hsync_mask = BEAMCON0_VARCSYEN;
- bemcon0_vsync_mask = BEAMCON0_VARCSYEN;
- } else {
+ } else if (currprefs.cs_hvcsync == HVSYNC_HVSYNC || currprefs.cs_hvcsync == HVSYNC_HVSYNC_SYNC) {
bemcon0_hsync_mask = BEAMCON0_VARHSYEN;
bemcon0_vsync_mask = BEAMCON0_VARVSYEN;
+ } else {
+ bemcon0_hsync_mask = BEAMCON0_VARCSYEN;
+ bemcon0_vsync_mask = BEAMCON0_VARCSYEN;
}
beamcon0_has_hsync = (beamcon0 & bemcon0_hsync_mask) != 0;
beamcon0_has_vsync = (beamcon0 & bemcon0_vsync_mask) != 0;
display_hstart_cyclewait_start = size;
resetfulllinestate();
updatehwhpostable();
+ init_beamcon_delay = -1;
}
static void init_hz_reset(void)
}
if ((current_linear_hblen != current_linear_hblen_temp || denise_get_hbstate(true)) && currprefs.cs_hvcsync < HVSYNC_SYNCPOS) {
current_linear_hblen = current_linear_hblen_temp;
- init_beamcon0();
framesync = true;
+ init_beamcon0();
display_redraw = true;
}
}
}
- if (framesync) {
- compute_framesync();
- devices_syncchange();
+ // if no sync condition, wait until sync is back before recalculating display
+ if (!nosignal_cnt && !nosignal_trigger) {
+ if (framesync) {
+ compute_framesync();
+ devices_syncchange();
+ init_beamcon_delay = 0;
+ }
+ if (init_beamcon_delay < 0) {
+ init_beamcon_delay = 2;
+ } else if (init_beamcon_delay > 0) {
+ init_beamcon_delay--;
+ if (init_beamcon_delay == 0) {
+ compute_framesync();
+ devices_syncchange();
+ }
+ }
}
if (agnus_afterreset > 0) {
prevlofs[0] = lof_display;
}
-static void check_no_signal(void)
-{
- evt_t c = get_cycles();
- if (issyncstopped(bplcon0)) {
- nosignal_trigger = true;
- }
- // Missing vsync
- if (c > display_last_vsync + (CHIPSET_CLOCK_PAL / 10) * CYCLE_UNIT) {
- nosignal_trigger = true;
- }
- // Missing hsync
- if (c > display_last_hsync + (CHIPSET_CLOCK_PAL / 100) * CYCLE_UNIT) {
- nosignal_trigger = true;
- }
- // Inverted CSYNC
- if ((beamcon0 & BEAMCON0_CSYTRUE) && (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC)) {
- nosignal_trigger = true;
- }
- // BLANKEN set: horizontal blanking is merged with CSYNC
- if ((beamcon0 & BEAMCON0_BLANKEN) && (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC)) {
- nosignal_trigger = true;
- }
- if ((beamcon0 & BEAMCON0_CSCBEN) && (currprefs.cs_hvcsync == HVSYNC_HVSYNC || currprefs.cs_hvcsync == HVSYNC_HVSYNC_SYNC)) {
- nosignal_trigger = true;
- }
- if (beamcon0 & BEAMCON0_VARBEAMEN) {
- if (htotal < 50 || htotal >= 255) {
- nosignal_trigger = true;
- }
- if (vtotal < 100 || vtotal > 1000) {
- nosignal_trigger = true;
- }
- // CSY output is invalid (no vsync part included) if HTOTAL is too small + hardwired CSYNC.
- int csyh = (beamcon0 & 0x20) ? 0x8c : 0x8d;
- if (htotal < csyh && !(beamcon0 & BEAMCON0_VARCSYEN) && (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC)) {
- nosignal_trigger = true;
- }
- }
-}
-
static void handle_nosignal(void)
{
if (nosignal_status < 0) {
struct amigadisplay *ad = &adisplays[0];
nosignal_trigger = false;
resetfulllinestate();
- denise_clearbuffers();
+ if (!nosignal_cnt) {
+ denise_clearbuffers();
+ }
if (!ad->specialmonitoron) {
if (currprefs.gfx_monitorblankdelay > 0) {
nosignal_status = 1;
nosignal_cnt = (int)(currprefs.gfx_monitorblankdelay / (1000.0f / vblank_hz));
if (nosignal_cnt <= 0) {
- nosignal_cnt = 1;
+ nosignal_cnt = 2;
}
} else {
nosignal_status = 2;
}
}
+static void check_no_signal(void)
+{
+ if (!nosignal_trigger) {
+
+ evt_t c = get_cycles();
+ uae_u32 cck = get_cck_cycles();
+
+ if (issyncstopped(bplcon0)) {
+ nosignal_trigger = true;
+ }
+ // Missing vsync
+ if (cck > agnus_vsync_start + 256 * 1000) {
+ nosignal_trigger = true;
+ }
+ // Missing hsync
+ if (cck > agnus_hsync_start + 400) {
+ nosignal_trigger = true;
+ }
+ // Inverted CSYNC
+ if ((beamcon0 & BEAMCON0_CSYTRUE) && (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC)) {
+ nosignal_trigger = true;
+ }
+ // BLANKEN set: horizontal blanking is merged with CSYNC
+ if ((beamcon0 & BEAMCON0_BLANKEN) && (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC)) {
+ nosignal_trigger = true;
+ }
+ if ((beamcon0 & BEAMCON0_CSCBEN) && (currprefs.cs_hvcsync == HVSYNC_HVSYNC || currprefs.cs_hvcsync == HVSYNC_HVSYNC_SYNC)) {
+ nosignal_trigger = true;
+ }
+ if (beamcon0 & BEAMCON0_VARBEAMEN) {
+ // CSY output is invalid (no vsync part included) if HTOTAL is too small + hardwired CSYNC.
+ int csyh = (beamcon0 & 0x20) ? 0x8c : 0x8d;
+ if (htotal < csyh && !(beamcon0 & BEAMCON0_VARCSYEN) && (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC)) {
+ nosignal_trigger = true;
+ }
+ }
+
+ if (nosignal_trigger && !nosignal_cnt) {
+ handle_nosignal();
+ }
+ }
+
+}
+
static void virtual_vsync_check(void)
{
check_display_mode_change();
uae_lua_run_handler("on_uae_vsync");
#endif
- check_no_signal();
-
#ifdef DEBUGGER
if (debug_copper) {
record_copper_reset();
// executed at start of scanline
static void hsync_handler(bool vs)
{
- display_last_hsync = get_cycles();
-
hsync_handler_pre(vs);
if (vs) {
devices_vsync_pre();
inputdevice_read_msg(true);
vsync_display_render();
vsync_display_rendered = false;
- if ((currprefs.cs_hvcsync == HVSYNC_COMBINED || currprefs.cs_hvcsync == HVSYNC_COMBINED_SYNC)) {
+ if ((currprefs.cs_hvcsync == HVSYNC_COMBINED || currprefs.cs_hvcsync == HVSYNC_COMBINED_SYNC) && valid_programmed_mode()) {
if (beamcon0 & (BEAMCON0_VARVSYEN | BEAMCON0_VARCSYEN)) {
lof_display = lof_pdetect;
} else {
lof_display = lof_detect;
}
- } else if (currprefs.cs_hvcsync == HVSYNC_CSYNC || currprefs.cs_hvcsync == HVSYNC_CSYNC_SYNC) {
- if (beamcon0 & BEAMCON0_VARCSYEN) {
+ } else if (currprefs.cs_hvcsync == HVSYNC_HVSYNC || currprefs.cs_hvcsync == HVSYNC_HVSYNC_SYNC) {
+ if (beamcon0 & BEAMCON0_VARVSYEN) {
lof_display = lof_pdetect;
} else {
lof_display = lof_detect;
}
- } else if (currprefs.cs_hvcsync == HVSYNC_HVSYNC || currprefs.cs_hvcsync == HVSYNC_HVSYNC_SYNC) {
- if (beamcon0 & BEAMCON0_VARVSYEN) {
+ } else {
+ if (beamcon0 & BEAMCON0_VARCSYEN) {
lof_display = lof_pdetect;
} else {
lof_display = lof_detect;
display_vsync_counter++;
maxvpos_display_vsync_next = true;
display_hsync_counter = 0;
- display_last_vsync = get_cycles();
vsync_start_check();
} else if (vpos != vsync_startline + 1 && maxvpos_display_vsync_next) {
// protect against weird VPOSW writes causing continuous vblanks
vsync_counter = 0;
display_vsync_counter = 0;
display_hsync_counter = 0;
- display_last_hsync = get_cycles();
- display_last_vsync = get_cycles();
+ agnus_vsync_start = get_cck_cycles();
agnus_hsync_start = get_cck_cycles();
next_lineno = 0;
{
if (vsync_linecnt) {
vsync_lines = vsync_linecnt;
+ agnus_vsync_start = get_cck_cycles();
vsync_linecnt = 0;
linear_vpos_prev[2] = linear_vpos_prev[1];
linear_vpos_prev[1] = linear_vpos_prev[0];
}
}
+ check_no_signal();
+
if (!(new_beamcon0 & BEAMCON0_PAL) && !(new_beamcon0 & BEAMCON0_LOLDIS)) {
lol = lol ? false : true;
linetoggle = true;
struct vidbuf_description* vidinfo = &adisplays[0].gfxvidinfo;
int l = 0;
while (l < vb->inheight) {
- uae_u8* b = get_row(monid, l);
+ uae_u8 *b = get_row(monid, l);
memset(b, 0, vb->inwidth * vb->pixbytes);
l++;
}
ls->lol = lol;
}
- frame_internal_pixel_cnt = internal_pixel_cnt;
-
- // detect horizontal blanking
- if (!denise_vblank_active) {
- int ipc = internal_pixel_cnt + (denise_strlong_seen ? lol * 8 : 0);
- linear_denise_frame_hbstrt = hbstrt_offset + (denise_strlong_seen ? lol * 8 : 0);
- linear_denise_frame_hbstop = hbstop_offset;
- //write_log("%d %d\n", linear_denise_frame_hbstrt, linear_denise_frame_hbstop);
-
- if (linear_denise_frame_hbstrt == linear_denise_frame_hbstrt_tmp && linear_denise_frame_hbstop == linear_denise_frame_hbstop_tmp) {
- denise_hbstrt_relative_cnt++;
- if (denise_hbstrt_relative_cnt > maxvpos_display / 2) {
- int ss = linear_denise_frame_hbstrt_sel;
- int ee = linear_denise_frame_hbstop_sel;
- linear_denise_frame_hbstrt_sel = linear_denise_frame_hbstrt_tmp;
- linear_denise_frame_hbstop_sel = linear_denise_frame_hbstop_tmp;
- if (linear_denise_frame_hbstrt_sel < 0 || linear_denise_frame_hbstop_sel < 0) {
- linear_denise_frame_hbstrt_sel = -1;
- linear_denise_frame_hbstop_sel = -1;
- } else {
- if (linear_denise_frame_hbstrt_sel > linear_denise_frame_hbstop_sel) {
- linear_denise_frame_hbstrt_sel -= ipc;
+ if (internal_pixel_cnt > 0) {
+ frame_internal_pixel_cnt = internal_pixel_cnt;
+ // detect horizontal blanking
+ if (!denise_vblank_active) {
+ int ipc = internal_pixel_cnt + (denise_strlong_seen ? lol * 8 : 0);
+ linear_denise_frame_hbstrt = hbstrt_offset + (denise_strlong_seen ? lol * 8 : 0);
+ linear_denise_frame_hbstop = hbstop_offset;
+ //write_log("%d %d\n", linear_denise_frame_hbstrt, linear_denise_frame_hbstop);
+
+ if (linear_denise_frame_hbstrt == linear_denise_frame_hbstrt_tmp && linear_denise_frame_hbstop == linear_denise_frame_hbstop_tmp) {
+ denise_hbstrt_relative_cnt++;
+ if (denise_hbstrt_relative_cnt > maxvpos_display / 2) {
+ int ss = linear_denise_frame_hbstrt_sel;
+ int ee = linear_denise_frame_hbstop_sel;
+ linear_denise_frame_hbstrt_sel = linear_denise_frame_hbstrt_tmp;
+ linear_denise_frame_hbstop_sel = linear_denise_frame_hbstop_tmp;
+ if (linear_denise_frame_hbstrt_sel < 0 || linear_denise_frame_hbstop_sel < 0) {
+ linear_denise_frame_hbstrt_sel = -1;
+ linear_denise_frame_hbstop_sel = -1;
+ } else {
+ if (linear_denise_frame_hbstrt_sel > linear_denise_frame_hbstop_sel) {
+ linear_denise_frame_hbstrt_sel -= ipc;
+ }
+ }
+ linear_denise_frame_hbstrt_sel += linear_denise_strobe_offset + 2 * 8;
+ linear_denise_frame_hbstop_sel += linear_denise_strobe_offset + 2 * 8;
+ denise_hbstrt_relative_cnt = 0;
+ if (ss != linear_denise_frame_hbstrt_sel || ee != linear_denise_frame_hbstop_sel) {
+ denise_blanking_changed = true;
}
}
- linear_denise_frame_hbstrt_sel += linear_denise_strobe_offset + 2 * 8;
- linear_denise_frame_hbstop_sel += linear_denise_strobe_offset + 2 * 8;
+ } else {
+ linear_denise_frame_hbstrt_tmp = linear_denise_frame_hbstrt;
+ linear_denise_frame_hbstop_tmp = linear_denise_frame_hbstop;
denise_hbstrt_relative_cnt = 0;
- if (ss != linear_denise_frame_hbstrt_sel || ee != linear_denise_frame_hbstop_sel) {
- denise_blanking_changed = true;
- }
}
- } else {
- linear_denise_frame_hbstrt_tmp = linear_denise_frame_hbstrt;
- linear_denise_frame_hbstop_tmp = linear_denise_frame_hbstop;
- denise_hbstrt_relative_cnt = 0;
}
}