#include "specialmonitors.h"
#endif
-
+#define VPOSW_DISABLED 0
#define VPOSW_DEBUG 0
#define FRAMEWAIT_MIN_MS 2
uae_u16 v;
};
static uae_u32 displayresetcnt;
+static int displayreset_delayed;
uae_u8 agnus_hpos;
int agnus_hpos_prev, agnus_hpos_next, agnus_vpos_next;
static int agnus_pos_change;
static struct pipeline_reg preg;
static struct pipeline_func pfunc[MAX_PIPELINE_REG];
static uae_u16 prev_strobe;
-static bool vb_fast, vb_fast_prev;
+static bool vb_fast;
static uae_u32 custom_state_flags;
static int not_safe_mode;
static bool dmal_next;
int display_reset;
static bool initial_frame;
static int custom_fastmode_exit;
+static evt_t last_vsync_evt, last_hsync_evt;
#if 0
static int custom_fastmode_bplextendmask;
#endif
static int last_hdiw;
static diw_states vdiwstate, hdiwstate;
static int hdiwbplstart;
-static int bpl_hstart;
static bool exthblank;
static int hsyncdebug;
static int display_vsync_counter, display_hsync_counter;
static evt_t display_last_hsync, display_last_vsync;
-static int fetch_cycle;
-
static bool ddf_limit, ddfstrt_match, hwi_old;
static int ddf_stopping, ddf_enable_on;
static int bprun;
uae_u16 strobe = 0x1fe;
if (slot == 0) {
bool equ = ecs_agnus ? agnus_p_ve : agnus_ve;
- bool vb = (beamcon0 & BEAMCON0_VARVBEN) ? agnus_pvb && !agnus_pvb_start_line : (agnus_vb == 1 || agnus_vb_end_line);
+ bool vb = (beamcon0 & BEAMCON0_VARVBEN) ? (agnus_pvb || agnus_pvb_end_line) && !agnus_pvb_start_line : (agnus_vb == 1 || agnus_vb_end_line);
/*
A1000 Agnus:
Line 0: STRHOR
return stored_chipset_refresh != get_chipset_refresh(&currprefs);
}
-static void resetfulllinestate(void)
+void resetfulllinestate(void)
{
- displayresetcnt++;
+ displayreset_delayed |= 4 | 2 | 1;
}
void compute_framesync(void)
static void VPOSW(uae_u16 v)
{
+#if VPOSW_DISABLED
+ return;
+#endif
+
int newvpos = vpos;
#if 0
static void VHPOSW(uae_u32 v)
{
+#if VPOSW_DISABLED
+ return;
+#endif
+
int newvpos = vpos;
#if VPOSW_DEBUG
serial_rbf_change((newreq & 0x0800) ? 1 : 0);
}
-static void event_doint_delay_do_ext(uae_u32 v)
+void event_doint_delay_do_ext_old(uae_u32 v)
{
uae_u16 old = intreq2;
setclr(&intreq, (1 << v) | 0x8000);
doint();
}
+void event_doint_delay_do_ext(uae_u32 v)
+{
+ uae_u16 old = intreq2;
+ setclr(&intreq, v | 0x8000);
+ setclr(&intreq2, v | 0x8000);
+
+ doint();
+}
+
static void event_send_interrupt_do_ext(uae_u32 v)
{
- event2_newevent_xx(-1, 1 * CYCLE_UNIT, v, event_doint_delay_do_ext);
+ event2_newevent_xx(-1, 1 * CYCLE_UNIT, 1 << v, event_doint_delay_do_ext);
}
// external delayed interrupt
if (delay < CYCLE_UNIT) {
delay *= CYCLE_UNIT;
}
- event2_newevent_xx(-1, delay + CYCLE_UNIT, num, event_doint_delay_do_ext);
+ event2_newevent_xx(-1, delay + CYCLE_UNIT, 1 << num, event_doint_delay_do_ext);
} else {
- event_doint_delay_do_ext(num);
+ event_doint_delay_do_ext(1 << num);
}
}
}
}
+static void check_exthblank(void)
+{
+ resetfulllinestate();
+}
+
static void varsync(int reg, bool resync, int oldval)
{
struct amigadisplay *ad = &adisplays[0];
static void BPLCON0_delayed(uae_u32 va)
{
+ if ((bplcon0 & 1) != (va & 1) && (bplcon3 & 1)) {
+ bplcon0 = va;
+ check_exthblank();
+ }
+
bplcon0 = va;
check_harddis();
}
static void BPLCON3(uae_u16 v)
{
+ if ((bplcon0 & 1) && (bplcon3 & 1) != (v & 1)) {
+ bplcon3 = v;
+ check_exthblank();
+ }
bplcon3_saved = v;
bplcon3 = v;
if (aga_mode) {
// return if register is in Agnus or Denise (or both)
static int get_reg_chip(int reg)
{
+#if VPOSW_DISABLED
+ if (reg == 0x2a || reg == 0x2c) {
+ return 0;
+ }
+#endif
if (reg == 0x100 || reg == 0x1fc) {
return 1 | 2;
} else if (reg >= 0x102 && reg < 0x108) {
} else if (reg >= 0x110 && reg < 0x110 + 8 * 2) {
return 2;
} else if (reg == 0x02c) {
- return 1 | 2;
+ if (currprefs.cpu_memory_cycle_exact) {
+ return 1 | 2;
+ }
+ return 1;
} else if (reg == 0x1c4 || reg == 0x1c6) {
return 1 | 2;
} else if (reg == 0x098 || reg == 0x10e) {
static void bprun_start(int hpos)
{
- bpl_hstart = hpos;
- fetch_cycle = 0;
if (bplcon0_planes > 0 && ddffirstword_total > hpos) {
ddffirstword_total = hpos + 4 + 8;
}
if (!vsync_display_rendered) {
vsyncmintimepre = read_processor_time();
+ if (!has_draw_denise()) {
+ start_draw_denise();
+ }
+
if (!custom_disabled) {
draw_denise_vsync_queue(display_redraw);
display_redraw = false;
{
if (nosignal_status < 0) {
nosignal_status = 0;
+ resetfulllinestate();
}
if (nosignal_cnt) {
nosignal_cnt--;
if (nosignal_cnt == 0) {
nosignal_status = -1;
+ resetfulllinestate();
}
}
if (nosignal_trigger) {
struct amigadisplay *ad = &adisplays[0];
nosignal_trigger = false;
+ resetfulllinestate();
if (!ad->specialmonitoron) {
if (currprefs.gfx_monitorblankdelay > 0) {
nosignal_status = 1;
}
} else {
nosignal_status = 2;
- nosignal_cnt = (int)(vblank_hz / 2);
+ nosignal_cnt = 2;
}
}
}
}
+static void vsync_start_check(void)
+{
+ if (displayreset_delayed) {
+ if (displayreset_delayed & 1) {
+ displayresetcnt++;
+ }
+ displayreset_delayed >>= 1;
+ }
+}
+
static bool vsync_line;
// executed at start of scanline
static void hsync_handler(bool vs)
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
maxvpos_display_vsync_next = false;
+ vsync_start_check();
} else {
display_hsync_counter++;
if (display_hsync_counter > maxvpos) {
inputdevice_read_msg(true);
vsync_display_render();
vsync_display_rendered = false;
+ vsync_start_check();
}
}
f = event_send_interrupt_do_ext;
break;
case 2:
- f = event_doint_delay_do_ext;
+ f = event_doint_delay_do_ext_old;
break;
case 3:
f = event_audxdat_func;
case 10:
f = bitplane_dma_change;
break;
+ case 11:
+ f = event_doint_delay_do_ext;
+ break;
case 0:
write_log("ignored event type %d (%08x) restored\n", type, data);
break;
uae_u8 type = 0;
if (f == event_send_interrupt_do_ext) {
type = 1;
- } else if (f == event_doint_delay_do_ext) {
+ } else if (f == event_doint_delay_do_ext_old) {
type = 2;
} else if (f == event_audxdat_func) {
type = 3;
type = 9;
} else if (f == bitplane_dma_change) {
type = 10;
+ } else if (f == event_doint_delay_do_ext) {
+ type = 11;
} else {
write_log("unknown event2 handler %p\n", e->handler);
e->active = false;
if (lof_store && vpos == vsstop) {
agnus_pvsync = false;
}
+ if (vpos == vbstrt) {
+ agnus_pvb = true;
+ agnus_pvb_start_line = true;
+ update_agnus_vb();
+ update_lof_detect();
+ } else if (agnus_pvb_start_line) {
+ agnus_pvb_start_line = false;
+ update_agnus_vb();
+ }
+ if (vpos == vbstop) {
+ agnus_pvb = false;
+ agnus_pvb_end_line = true;
+ update_agnus_vb();
+ } else if (agnus_pvb_end_line) {
+ agnus_pvb_end_line = false;
+ update_agnus_vb();
+ }
}
+
+ if (programmed_register_accessed_h) {
+ if (hcenter < maxhpos) {
+ if (lof_store && vpos == vsstrt) {
+ agnus_pvsync = true;
+ lof_pdetect = 1;
+ }
+ if (lof_store && vpos == vsstop) {
+ agnus_pvsync = false;
+ }
+ }
+ }
+
+
check_vidsyncs();
}
{
int type = 0;
- if (vb_fast) {
+ if (vb_fast || nosignal_status) {
type = LINETYPE_BLANK;
} else if (vdiwstate == diw_states::DIW_waiting_start || GET_PLANES(bplcon0) == 0 || !dmaen(DMA_BITPLANE)) {
type = LINETYPE_BORDER;
if (l->hbstrt_offset < 0 || l->hbstop_offset < 0) {
return false;
}
- l->color0 = ((bplcon0 & 1) && (bplcon3 & 0x20)) ? 0 : (aga_mode ? agnus_colors.color_regs_aga[0] : agnus_colors.color_regs_ecs[0]);
+ bool brdblank = (bplcon0 & 1) && (bplcon3 & 0x20);
+ l->color0 = aga_mode ? agnus_colors.color_regs_aga[0] : agnus_colors.color_regs_ecs[0];
+ l->brdblank = brdblank;
int dvp = calculate_linetype(ldv);
draw_denise_border_line_fast_queue(dvp, nextline_how, l);
return true;
l->cnt = displayresetcnt - 1;
}
+#define MAX_STORED_BPL_DATA 204
+
static void storelinestate(void)
{
int lvpos = linear_vpos + 1;
l->ddfstop = ddfstop;
l->diwstrt = diwstrt;
l->diwstop = diwstop;
- l->color0 = ((bplcon0 & 1) && (bplcon3 & 0x20)) ? 0 : (aga_mode ? agnus_colors.color_regs_aga[0] : agnus_colors.color_regs_ecs[0]);
+ bool brdblank = (bplcon0 & 1) && (bplcon3 & 0x20);
+ l->color0 = aga_mode ? agnus_colors.color_regs_aga[0] : agnus_colors.color_regs_ecs[0];
+ l->brdblank = brdblank;
l->bplcon3 = bplcon3;
l->bplcon4 = bplcon4;
l->diwhigh = diwhigh;
l->fmode = fmode;
+
if (l->type == LINETYPE_BPL) {
int stop = !harddis_h && ddfstop > 0xd8 ? 0xd8 : ddfstop;
int len = ((stop - ddfstrt) + fetchunit - 1) / fetchunit + 1;
int type = getlinetype();
if (type && type == l->type && displayresetcnt == l->cnt) {
- if (type == LINETYPE_BLANK && vb_fast) {
+ if (type == LINETYPE_BLANK) {
if (1) {
ret = true;
}
- } else if (type == LINETYPE_BORDER && !vb_fast && !l->blankedline) {
+ } else if (type == LINETYPE_BORDER) {
if (1) {
- uae_u32 c = ((bplcon0 & 1) && (bplcon3 & 0x20)) ? 0 : (aga_mode ? agnus_colors.color_regs_aga[0] : agnus_colors.color_regs_ecs[0]);
- if (!always && c == l->color0) {
+ bool brdblank = (bplcon0 & 1) && (bplcon3 & 0x20);
+ uae_u32 c = aga_mode ? agnus_colors.color_regs_aga[0] : agnus_colors.color_regs_ecs[0];
+ if (!always && c == l->color0 && brdblank == l->brdblank) {
ret = true;
} else if (always || currprefs.cs_optimizations == DISPLAY_OPTIMIZATIONS_FULL) {
storelinestate();
ret = draw_border_fast(l, linear_display_vpos + 1);
}
}
- } else if (type == LINETYPE_BPL && !vb_fast && !l->blankedline) {
+ } else if (type == LINETYPE_BPL && !l->blankedline) {
if (1) {
int r = checkprevfieldlinestateequalbpl(l);
if ((r && always) || (r && currprefs.cs_optimizations == DISPLAY_OPTIMIZATIONS_FULL)) {
int cslen = 10;
draw_denise_line_queue(dvp, nextline_how, rga_denise_cycle_line, rga_denise_cycle_start, rga_denise_cycle, rga_denise_cycle_count,
display_hstart_cyclewait_skip, display_hstart_cyclewait_skip2,
- wclks, cs, cslen, lof_store, lol, display_hstart_fastmode - display_hstart_cyclewait, l);
+ wclks, cs, cslen, lof_store, lol, display_hstart_fastmode - display_hstart_cyclewait, nosignal_status != 0, l);
}
static void dmal_fast(void)
dmal_shifter = 0;
}
+static void update_fast_vb(void)
+{
+ if (new_beamcon0 & BEAMCON0_VARVBEN) {
+ vb_fast = get_strobe_reg(0) != 0x3c;
+ } else {
+ vb_fast = get_strobe_reg(0) != 0x3c;
+ }
+}
+
static void sync_equalline_handler(void);
static void start_sync_equalline_handler(void)
{
}
+static void vsync_nosync(void)
+{
+ nosignal_trigger = true;
+ linear_vpos = 0;
+ vsync_handler_post();
+ devices_vsync_pre();
+ inputdevice_read_msg(true);
+ vsync_display_render();
+ vsync_display_rendered = false;
+ virtual_vsync_check();
+}
+
static void custom_trigger_start_nosync(void)
{
linear_display_vpos = linear_vpos;
linear_vpos++;
if (linear_vpos >= maxvpos + lof_store) {
- nosignal_trigger = true;
- linear_vpos = 0;
- vsync_handler_post();
- devices_vsync_pre();
- inputdevice_read_msg(true);
- vsync_display_render();
- vsync_display_rendered = false;
- virtual_vsync_check();
+ vsync_nosync();
}
}
virtual_vsync_check();
+ last_vsync_evt = get_cycles() + (maxvpos * maxhpos * 3) * CYCLE_UNIT;
}
bool vposzero = false;
int custom_fastmode_prev = custom_fastmode;
+ update_fast_vb();
+
if (custom_disabled && !eventtab[ev_sync].active && !currprefs.cpu_memory_cycle_exact && currprefs.cs_optimizations < DISPLAY_OPTIMIZATIONS_NONE) {
custom_fastmode = 0;
start_sync_imm_handler();
}
}
#endif
- if (new_beamcon0 & BEAMCON0_VARVBEN) {
- vb_fast = get_strobe_reg(0) != 0x3c || vpos == vbstrt;
- } else {
- vb_fast = get_strobe_reg(0) != 0x3c;
- }
int canline = can_fast_custom();
if (canline) {
calculate_linetype(linear_display_vpos + 1);
int calib_len;
bool lol, lof;
int hdelay;
+ bool blanked;
uae_u16 strobe;
int strobe_pos;
int erase;
static void denise_handle_quick_strobe(uae_u16 strobe, int offset, int vpos);
static void draw_denise_vsync(int);
static void denise_update_reg(uae_u16 reg, uae_u16 v, int linecnt);
-static void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol, int hdelay, struct linestate *ls);
+static void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol, int hdelay, bool blanked, struct linestate *ls);
static void quick_denise_rga(int linecnt, int startpos, int endpos)
{
if (q->type == 0) {
- draw_denise_line(q->gfx_ypos, q->how, q->linecnt, q->startpos, q->total, q->skip, q->skip2, q->dtotal, q->calib_start, q->calib_len, q->lol, q->hdelay, q->ls);
+ draw_denise_line(q->gfx_ypos, q->how, q->linecnt, q->startpos, q->total, q->skip, q->skip2, q->dtotal, q->calib_start, q->calib_len, q->lol, q->hdelay, q->blanked, q->ls);
next = true;
} else if (q->type == 1) {
draw_denise_bitplane_line_fast(q->gfx_ypos, q->how, q->ls);
} else if (q->type == 4) {
denise_handle_quick_strobe(q->strobe, q->strobe_pos, q->vpos);
next = true;
+ nolock = true;
} else if (q->type == 5) {
draw_denise_vsync(q->erase);
} else if (q->type == 6) {
static int thisframe_y_adjust;
static int thisframe_y_adjust_real, min_ypos_for_screen;
static int max_ypos_thisframe1;
-int thisframe_first_drawn_line, thisframe_last_drawn_line;
+static int thisframe_first_drawn_line, thisframe_last_drawn_line;
/* A frame counter that forces a redraw after at least one skipped frame in
interlace mode. */
if (isnativevidbuf(0) && !max) {
int x = visible_left_border;
int y = minfirstline << currprefs.gfx_vresolution;
+
+ x -= 1 << currprefs.gfx_resolution;
#if 0
int dbl1, dbl2;
dbl2 = dbl1 = currprefs.gfx_vresolution;
if (doublescan == 1 && vshift > 0) {
vshift--;
}
- denise_vblank_extra_top = ((visible_top_start - 1) >> vshift) - 1;
- denise_vblank_extra_bottom = ((visible_bottom_stop + 1) >> vshift) + 1;
- denise_hblank_extra_left = visible_left_start - (1 << currprefs.gfx_resolution);
- denise_hblank_extra_right = visible_right_stop + (1 << currprefs.gfx_resolution);
+ int ydiff = minfirstline - minfirstline_linear;
+ denise_vblank_extra_top = (visible_top_start - ydiff) >> vshift;
+ denise_vblank_extra_bottom = (visible_bottom_stop - ydiff) >> vshift;
+ denise_hblank_extra_left = visible_left_start;
+ denise_hblank_extra_right = visible_right_stop;
//write_log("%d %d %d %d\n", denise_vblank_extra_top, denise_vblank_extra_bottom, visible_top_start, visible_bottom_stop);
}
struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
struct vidbuffer *vb = vidinfo->inbuffer;
+ if (dx > 0 && w > 0) {
+ dx -= 1 << currprefs.gfx_resolution;
+ }
+
if (fd->gfx_filter_left_border == 0) {
w = 0;
dx = 0;
}
#endif
- int hwadd = 0;
- int vwadd = 0;
+ int wwadd = 0;
+ int hhadd = 0, hhadd2 = 0;
if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) {
- int wadd = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 8;
+ int addw = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 8;
+ int addh = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 5;
if (currprefs.gfx_overscanmode == 0) {
- wadd -= 6;
+ addw -= 6;
}
- hwadd = wadd << hresolution;
- vwadd = ((wadd - (vsync_startline + 1)) << currprefs.gfx_vresolution);
+ wwadd = addw << hresolution;
+ hhadd = addh << currprefs.gfx_vresolution;
+ hhadd2 = hhadd + (1 << currprefs.gfx_vresolution);
}
int vshift = currprefs.gfx_vresolution;
visible_left_start = 0;
visible_right_stop = MAX_STOP;
} else {
- if (dx < hwadd) {
- w -= 2 * (hwadd - dx);
- dx = hwadd;
+ if (dx < wwadd) {
+ w -= 2 * (wwadd - dx);
+ dx = wwadd;
}
visible_left_start = visible_left_border + dx;
visible_right_stop = visible_left_start + w;
visible_top_start -= 1 << currprefs.gfx_resolution;
visible_bottom_stop += 1 << currprefs.gfx_resolution;
}
- if (visible_top_start < vwadd + startypos) {
- visible_top_start = vwadd + startypos;
+ if (visible_top_start < hhadd + startypos) {
+ visible_top_start = hhadd + startypos;
}
- if ((current_linear_vpos << currprefs.gfx_vresolution) - vwadd < visible_bottom_stop) {
- visible_bottom_stop = (current_linear_vpos << currprefs.gfx_vresolution) - vwadd;
+ if ((current_linear_vpos << currprefs.gfx_vresolution) - hhadd2 < visible_bottom_stop) {
+ visible_bottom_stop = (current_linear_vpos << currprefs.gfx_vresolution) - hhadd2;
}
}
minfirstline);
#endif
center_reset = 1;
+ resetfulllinestate();
return 1;
}
if (visible_left_border < 0) {
visible_left_border = 0;
}
- visible_left_border &= ~((xshift (1, 0)) - 1);
+ if (currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) {
+ if (ecs_denise) {
+ visible_left_border += 1 << currprefs.gfx_resolution;
+ } else {
+ visible_left_border += 2 << currprefs.gfx_resolution;
+ }
+ } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
+ if (ecs_denise) {
+ visible_left_border += 3 << currprefs.gfx_resolution;
+ } else {
+ visible_left_border += 4 << currprefs.gfx_resolution;
+ }
+ }
+ visible_left_border &= ~((1 << currprefs.gfx_resolution) - 1);
//write_log (_T("%d %d %d %d\n"), max_diwlastword, vidinfo->inbuffer->width, currprefs.gfx_resolution, visible_left_border);
{
denise_brdstrt_unalign = false;
denise_brdstop_unalign = false;
- if (aga_mode && hresolution == RES_SUPERHIRES && borderblank) {
+ if (aga_mode && currprefs.gfx_resolution == RES_SUPERHIRES && borderblank) {
denise_brdstrt = denise_hstop - 1;
denise_brdstop = denise_hstrt - 1;
denise_brdstrt_lores = denise_brdstrt >> 2;
denise_max_odd_even = denise_odd_even;
}
-static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol, int hdelay, struct linestate *ls)
+static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol, int hdelay, bool blanked, struct linestate *ls)
{
bool fullline = false; // currprefs.chipset_hr;
uae_u32 *bufdt = buf_d;
uae_u8 *bufg = gbuf;
- if (denise_pixtotal_max == -0x7fffffff || blankedline) {
+ if (denise_pixtotal_max == -0x7fffffff || blankedline || blanked) {
// don't draw vertical blanking if not ultra extreme overscan
+ internal_pixel_cnt = -1;
while (denise_cck < denise_total) {
while (denise_cck < denise_total) {
do_denise_cck(denise_linecnt, denise_startpos, denise_cck);
lts_changed = false;
}
- if (buf1t && denise_pixtotal_max > 0) {
- memset(buf1t, DEBUG_TVOVERSCAN_V_GRAYSCALE, ((2 * denise_pixtotal_max) << hresolution) * sizeof(uae_u32));
- if (buf2t && buf1t != buf2t) {
- memset(buf2t, DEBUG_TVOVERSCAN_V_GRAYSCALE, ((2 * denise_pixtotal_max) << hresolution) * sizeof(uae_u32));
+ if (xlinebuffer) {
+ struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
+ struct vidbuffer *vb = vidinfo->inbuffer;
+ int w = vb->inwidth;
+ memset(xlinebuffer, DEBUG_TVOVERSCAN_V_GRAYSCALE, w * sizeof(uae_u32));
+ if (xlinebuffer2 && xlinebuffer != xlinebuffer2) {
+ memset(xlinebuffer2, DEBUG_TVOVERSCAN_V_GRAYSCALE, w * sizeof(uae_u32));
}
- if (gbuf) {
- memset(bufg, 0, (2 * denise_pixtotal_max) << hresolution);
+ if (xlinebuffer_genlock) {
+ memset(xlinebuffer_genlock, 0, w);
}
}
}
}
}
- int right = denise_strlong_seen ? denise_hblank_extra_right + (1 << currprefs.gfx_resolution) : denise_hblank_extra_right;
+ int right = denise_strlong_seen ? denise_hblank_extra_right - (1 << currprefs.gfx_resolution) : denise_hblank_extra_right;
if (!programmedmode && (denise_hblank_extra_left > visible_left_border || visible_right_border > right) && currprefs.gfx_overscanmode < OVERSCANMODE_EXTREME) {
int ww1 = denise_hblank_extra_left > visible_left_border ? (denise_hblank_extra_left - visible_left_border) << 0 : 0;
int ww2 = visible_right_border > right ? (visible_right_border - right) << 0 : 0;
ls->internal_pixel_start_cnt = internal_pixel_start_cnt;
ls->blankedline = blankedline;
ls->strlong_seen = denise_strlong_seen;
+ ls->vb = denise_vblank_active;
ls->lol = lol;
}
uae_u8 gpix = 0xff;
if (!denise_blank_active) {
// borderblank ends 1 shres pixel early
- dpix_val = cnt == denise_brdstop ? denise_colors.acolors[0] : bordercolor;
+ dpix_val = cnt == denise_brdstop && denise_hdiw && bpl1dat_trigger && !denise_vblank_active ? denise_colors.acolors[0] : bordercolor;
gpix = 0;
if (denise_hdiw && bpl1dat_trigger) {
pix = loaded_pixs[ipix];
uae_u8 pix = 0;
uae_u8 gpix = 0xff;
if (!denise_blank_active) {
- gpix = 0;
// borderblank ends 1 shres pixel early
dpix_val = cnt == denise_brdstop ? denise_colors.acolors[0] : bordercolor;
-
+ gpix = 0;
if (denise_hdiw && bpl1dat_trigger) {
pix = getbpl6();
static void tvadjust(int *hbstrt_offset, int *hbstop_offset, struct linestate *ls)
{
if (!programmedmode && currprefs.gfx_overscanmode < OVERSCANMODE_EXTREME) {
- int right = denise_strlong_seen ? denise_hblank_extra_right + (1 << currprefs.gfx_resolution) : denise_hblank_extra_right;
+ int right = denise_strlong_seen ? denise_hblank_extra_right - (1 << currprefs.gfx_resolution) : denise_hblank_extra_right;
int ww1 = denise_hblank_extra_left > visible_left_border ? (denise_hblank_extra_left - visible_left_border) << 0 : 0;
int ww2 = visible_right_border > right ? (visible_right_border - right) << 0 : 0;
// negative checks are needed to handle always-on HDIW
int hstop_offset_adjusted = ls->hstop_offset;
if (ls->bpl1dat_trigger_offset >= 0) {
- int bpl_end = ls->bpl1dat_trigger_offset + (1 << RES_MAX) + ls->bpllen * 32;
+ int bpl_end = ls->bpl1dat_trigger_offset + (1 << RES_MAX) + ((ls->bpllen * 32) >> denise_res);
if (hstop_offset_adjusted < 0 || hstop_offset_adjusted > bpl_end) {
hstop_offset_adjusted = bpl_end;
}
{
if (MULTITHREADED_DENISE) {
- if (!waitqueue()) {
+ if (!waitqueue_nolock()) {
return;
}
}
}
-void draw_denise_line_queue(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int endpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lof, bool lol, int hdelay, struct linestate *ls)
+void draw_denise_line_queue(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int endpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lof, bool lol, int hdelay, bool blanked, struct linestate *ls)
{
if (MULTITHREADED_DENISE) {
q->ls = ls;
q->vpos = vpos;
q->hdelay = hdelay;
+ q->blanked = blanked;
q->linear_vpos = linear_vpos;
addtowritequeue();
} else {
updatelinedata();
- draw_denise_line(gfx_ypos, how, linecnt, startpos, total, skip, skip2, dtotal, calib_start, calib_len, lol, hdelay, ls);
+ draw_denise_line(gfx_ypos, how, linecnt, startpos, total, skip, skip2, dtotal, calib_start, calib_len, lol, hdelay, blanked, ls);
update_overlapped_cycles(endpos);
}
event2_newevent_xx(-1, t, data, func);
}
+void event_doint_delay_do_ext(uae_u32 v);
+
void event2_newevent_xx(int no, evt_t t, uae_u32 data, evfunc2 func)
{
evt_t et;
if (eventtab2[no].evtime == et && eventtab2[no].handler == func && eventtab2[no].data == data)
break;
no++;
- if (no == ev2_max)
+ if (no == ev2_max) {
no = ev2_misc;
+ }
if (no == next) {
- write_log (_T("out of event2's!\n"));
+ // we may have multiple interrupts queued, merge if possible
+ for (int i = 0; i < ev2_max; i++) {
+ auto ev2 = &eventtab2[i];
+ if (ev2->active && ev2->handler == func && ev2->evtime == et && func == event_doint_delay_do_ext) {
+ ev2->data |= data;
+ return;
+ }
+ }
+ write_log(_T("out of event2's!\n"));
// execute most recent event immediately
evt_t mintime = EVT_MAX;
int minevent = -1;
event2_newevent_xx(-1, t * CYCLE_UNIT, data, func);
}
+void event2_newevent_x_add_not_exists(evt_t t, uae_u32 data, evfunc2 func)
+{
+ if (event2_newevent_x_exists(func)) {
+ return;
+ }
+ if (t <= 0) {
+ func(data);
+ return;
+ }
+ event2_newevent_xx(-1, t * CYCLE_UNIT, data, func);
+}
+
void event_init(void)
{
}
extern uae_u16 clxdat;
void custom_end_drawing(void);
+void resetfulllinestate(void);
extern int current_linear_vpos, current_linear_hpos;
extern uae_u8 agnus_hpos;
extern int detected_screen_resolution;
extern int hsync_end_left_border, hdisplay_left_border, denisehtotal;
extern int vsync_startline;
-
extern bool exthblanken;
#define AMIGA_WIDTH_MAX (754 / 2)
#define CCK_SHRES_SHIFT 3
-#define MAX_STORED_BPL_DATA 204
-#define MAX_STORED_BPL_DATA_BYTES (MAX_STORED_BPL_DATA * sizeof(uae_u64))
-
/* color values in two formats: 12 (OCS/ECS) or 24 (AGA) bit Amiga RGB (color_regs),
* and the native color value; both for each Amiga hardware color register.
*
/* Finally, stuff that shouldn't really be shared. */
-extern int thisframe_first_drawn_line, thisframe_last_drawn_line;
-
#define IHF_SCROLLLOCK 0
#define IHF_QUIT_PROGRAM 1
#define IHF_PICASSO 2
uae_u16 bplcon0, bplcon1, bplcon2, bplcon3, bplcon4;
uae_u16 fmode;
uae_u32 color0;
+ bool brdblank;
uae_u8 *linecolorstate;
int bpllen;
int colors;
int internal_pixel_start_cnt;
bool lol;
bool blankedline;
+ bool vb;
bool strlong_seen;
int fetchmode_size, fetchstart_mask;
uae_u16 strobe;
};
extern struct color_entry denise_colors;
-void draw_denise_line_queue(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int endpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lof, bool lol, int hdelay, struct linestate *ls);
+void draw_denise_line_queue(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int endpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lof, bool lol, int hdelay, bool blanked, struct linestate *ls);
void draw_denise_bitplane_line_fast(int gfx_ypos, enum nln_how how, struct linestate *ls);
void draw_denise_bitplane_line_fast_queue(int gfx_ypos, enum nln_how how, struct linestate *ls);
void draw_denise_border_line_fast(int gfx_ypos, enum nln_how how, struct linestate *ls);
enum {
ev2_blitter, ev2_misc,
- ev2_max = 8
+ ev2_max = 16
};
extern int pissoff_value;
extern void event2_newevent_xx(int no, evt_t t, uae_u32 data, evfunc2 func);
extern void event2_newevent_x_replace(evt_t t, uae_u32 data, evfunc2 func);
extern void event2_newevent_x_replace_exists(evt_t t, uae_u32 data, evfunc2 func);
+extern void event2_newevent_x_add_not_exists(evt_t t, uae_u32 data, evfunc2 func);
extern void event2_newevent_x_remove(evfunc2 func);
extern void event2_newevent_xx_ce(evt_t t, uae_u32 data, evfunc2 func);
bool event2_newevent_x_exists(evfunc2 func);
cy = *cyp;
v = currprefs.gfx_xcenter_pos;
if (v >= 0) {
- if (v < 0) {
- v = 0;
- }
cx = (v >> (RES_MAX - currprefs.gfx_resolution)) - cx;
}
} else {
bool isp = ispal(NULL);
if (currprefs.ntscmode) {
- dstratio = dstratio * 1.21f;
- if (keep_aspect == 2 && isp)
+ if (keep_aspect == 2 && !isp)
dstratio = dstratio * 0.93f;
- else if (keep_aspect == 1 && !isp)
+ else if (keep_aspect == 1 && isp)
dstratio = dstratio * 0.98f;
} else {
if (keep_aspect == 2 && isp)
} else if (led == LED_LINES) {
pos = 3;
ptr = drive_text + pos * LED_STRING_WIDTH;
- _stprintf(ptr, _T("%d%c"), gui_data.lines, gui_data.lace ? 'i' : 'p');
+ if (gui_data.fps_color < 2) {
+ _stprintf(ptr, _T("%3d%c"), gui_data.lines, gui_data.lace ? 'i' : 'p');
+ } else {
+ _tcscpy(ptr, _T("----"));
+ }
on = 1;
} else if (led == LED_FPS) {
float fps = gui_data.fps / 10.0f;