From: Toni Wilen Date: Thu, 1 May 2025 16:38:10 +0000 (+0300) Subject: Chipset updates (fast drawing glitches etc) X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=28c67617f0dd3bb75ad9a5037d0ec979b59e4061;p=francis%2Fwinuae.git Chipset updates (fast drawing glitches etc) --- diff --git a/custom.cpp b/custom.cpp index ebbd3669..3217b907 100644 --- a/custom.cpp +++ b/custom.cpp @@ -57,7 +57,7 @@ #include "specialmonitors.h" #endif - +#define VPOSW_DISABLED 0 #define VPOSW_DEBUG 0 #define FRAMEWAIT_MIN_MS 2 @@ -106,6 +106,7 @@ struct pipeline_reg 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; @@ -121,7 +122,7 @@ static int rga_denise_cycle_line = 1; 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; @@ -416,6 +417,7 @@ static bool syncs_stopped; 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 @@ -695,7 +697,6 @@ static int hb_last_diwlastword; static int last_hdiw; static diw_states vdiwstate, hdiwstate; static int hdiwbplstart; -static int bpl_hstart; static bool exthblank; static int hsyncdebug; @@ -776,8 +777,6 @@ int bogusframe; 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; @@ -1219,7 +1218,7 @@ static uae_u16 get_strobe_reg(int slot) 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 @@ -1509,9 +1508,9 @@ static bool changed_chipset_refresh(void) 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) @@ -2464,6 +2463,10 @@ static uae_u16 VPOSR(void) static void VPOSW(uae_u16 v) { +#if VPOSW_DISABLED + return; +#endif + int newvpos = vpos; #if 0 @@ -2502,6 +2505,10 @@ static void VPOSW(uae_u16 v) static void VHPOSW(uae_u32 v) { +#if VPOSW_DISABLED + return; +#endif + int newvpos = vpos; #if VPOSW_DEBUG @@ -3275,7 +3282,7 @@ static void intreq_checks(uae_u16 oldreq, uae_u16 newreq) 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); @@ -3284,9 +3291,18 @@ static void event_doint_delay_do_ext(uae_u32 v) 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 @@ -3296,9 +3312,9 @@ void INTREQ_INT(int num, int delay) 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); } } @@ -3471,6 +3487,11 @@ static void BEAMCON0(uae_u16 v) } } +static void check_exthblank(void) +{ + resetfulllinestate(); +} + static void varsync(int reg, bool resync, int oldval) { struct amigadisplay *ad = &adisplays[0]; @@ -3571,6 +3592,11 @@ static uae_u16 BPLCON0_Agnus_mask(uae_u16 v) static void BPLCON0_delayed(uae_u32 va) { + if ((bplcon0 & 1) != (va & 1) && (bplcon3 & 1)) { + bplcon0 = va; + check_exthblank(); + } + bplcon0 = va; check_harddis(); @@ -3636,6 +3662,10 @@ static void BPLCON2(uae_u16 v) } 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) { @@ -4267,6 +4297,11 @@ bool blitter_cant_access(void) // 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) { @@ -4285,7 +4320,10 @@ static int get_reg_chip(int reg) } 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) { @@ -4335,8 +4373,6 @@ static void bpl_autoscale(void) static void bprun_start(int hpos) { - bpl_hstart = hpos; - fetch_cycle = 0; if (bplcon0_planes > 0 && ddffirstword_total > hpos) { ddffirstword_total = hpos + 4 + 8; } @@ -5000,6 +5036,10 @@ static void vsync_display_render(void) 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; @@ -5194,16 +5234,19 @@ static void handle_nosignal(void) { 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; @@ -5213,7 +5256,7 @@ static void handle_nosignal(void) } } else { nosignal_status = 2; - nosignal_cnt = (int)(vblank_hz / 2); + nosignal_cnt = 2; } } } @@ -6443,6 +6486,16 @@ static void hsync_handler_post(bool onvsync) } +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) @@ -6486,9 +6539,11 @@ 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) { @@ -6496,6 +6551,7 @@ static void hsync_handler(bool vs) inputdevice_read_msg(true); vsync_display_render(); vsync_display_rendered = false; + vsync_start_check(); } } @@ -8498,7 +8554,7 @@ uae_u8 *restore_custom_event_delay(uae_u8 *src) 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; @@ -8524,6 +8580,9 @@ uae_u8 *restore_custom_event_delay(uae_u8 *src) 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; @@ -8565,7 +8624,7 @@ uae_u8 *save_custom_event_delay(size_t *len, uae_u8 *dstptr) 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; @@ -8583,6 +8642,8 @@ uae_u8 *save_custom_event_delay(size_t *len, uae_u8 *dstptr) 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; @@ -10285,7 +10346,38 @@ static void check_vsyncs_fast(void) 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(); } @@ -10471,7 +10563,7 @@ static int getlinetype(void) { 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; @@ -10563,7 +10655,9 @@ static bool draw_border_fast(struct linestate *l, int ldv) 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; @@ -10654,6 +10748,8 @@ static void resetlinestate(void) l->cnt = displayresetcnt - 1; } +#define MAX_STORED_BPL_DATA 204 + static void storelinestate(void) { int lvpos = linear_vpos + 1; @@ -10677,13 +10773,16 @@ static void storelinestate(void) 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; @@ -10708,21 +10807,22 @@ static bool checkprevfieldlinestateequal(void) 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)) { @@ -10784,7 +10884,7 @@ static void draw_line(void) 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) @@ -11010,6 +11110,15 @@ static void do_imm_dmal(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) { @@ -11030,19 +11139,24 @@ static void start_sync_imm_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(); } } @@ -11088,6 +11202,7 @@ static void custom_trigger_start(void) virtual_vsync_check(); + last_vsync_evt = get_cycles() + (maxvpos * maxhpos * 3) * CYCLE_UNIT; } bool vposzero = false; @@ -11150,6 +11265,8 @@ static void custom_trigger_start(void) 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(); @@ -11195,11 +11312,6 @@ static void custom_trigger_start(void) } } #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); diff --git a/drawing.cpp b/drawing.cpp index 2ef848e0..c90b8252 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -93,6 +93,7 @@ struct denise_rga_queue int calib_len; bool lol, lof; int hdelay; + bool blanked; uae_u16 strobe; int strobe_pos; int erase; @@ -110,7 +111,7 @@ static volatile bool thread_debug_lock; 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) { @@ -155,7 +156,7 @@ static void read_denise_line_queue(void) 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); @@ -166,6 +167,7 @@ static void read_denise_line_queue(void) } 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) { @@ -348,7 +350,7 @@ static int linetoscr_x_adjust_pixbytes, linetoscr_x_adjust_pixels; 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. */ @@ -597,6 +599,8 @@ void get_custom_topedge (int *xp, int *yp, bool max) 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; @@ -736,10 +740,11 @@ void check_custom_limits(void) 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); } @@ -751,6 +756,10 @@ void set_custom_limits (int w, int h, int dx, int dy, bool blank) 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; @@ -766,15 +775,17 @@ void set_custom_limits (int w, int h, int dx, int dy, bool blank) } #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; @@ -789,9 +800,9 @@ void set_custom_limits (int w, int h, int dx, int dy, bool blank) 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; @@ -811,11 +822,11 @@ void set_custom_limits (int w, int h, int dx, int dy, bool blank) 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; } } @@ -1014,6 +1025,7 @@ int get_custom_limits(int *pw, int *ph, int *pdx, int *pdy, int *prealh, int *hr minfirstline); #endif center_reset = 1; + resetfulllinestate(); return 1; } @@ -1362,7 +1374,20 @@ static void center_image (void) 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); @@ -2375,7 +2400,7 @@ static void setup_brdblank(void) { 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; @@ -5387,7 +5412,7 @@ static void denise_draw_update(void) 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; @@ -5430,9 +5455,10 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in 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); @@ -5478,13 +5504,16 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in 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); } } @@ -5559,7 +5588,7 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in } } } - 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; @@ -5663,6 +5692,7 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in 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; } @@ -5935,7 +5965,7 @@ static void lts_unaligned_aga(int cnt, int cnt_next, int h) 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]; @@ -6154,10 +6184,9 @@ static void lts_unaligned_ecs(int cnt, int cnt_next, int h) 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(); @@ -6434,7 +6463,7 @@ static void pfield_doline_8(int planecnt, int wordcount, uae_u8 *datap, struct l 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; @@ -6743,7 +6772,7 @@ void draw_denise_bitplane_line_fast(int gfx_ypos, enum nln_how how, struct lines // 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; } @@ -7109,7 +7138,7 @@ void denise_handle_quick_strobe_queue(uae_u16 strobe, int strobe_pos, int endpos { if (MULTITHREADED_DENISE) { - if (!waitqueue()) { + if (!waitqueue_nolock()) { return; } @@ -7132,7 +7161,7 @@ void denise_handle_quick_strobe_queue(uae_u16 strobe, int strobe_pos, int endpos } } -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) { @@ -7158,6 +7187,7 @@ void draw_denise_line_queue(int gfx_ypos, nln_how how, uae_u32 linecnt, int star q->ls = ls; q->vpos = vpos; q->hdelay = hdelay; + q->blanked = blanked; q->linear_vpos = linear_vpos; addtowritequeue(); @@ -7165,7 +7195,7 @@ void draw_denise_line_queue(int gfx_ypos, nln_how how, uae_u32 linecnt, int star } 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); } diff --git a/events.cpp b/events.cpp index 6ca0159f..013d9fbf 100644 --- a/events.cpp +++ b/events.cpp @@ -386,6 +386,8 @@ void event2_newevent_xx_ce(evt_t t, uae_u32 data, evfunc2 func) 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; @@ -401,10 +403,19 @@ void event2_newevent_xx(int no, evt_t t, uae_u32 data, evfunc2 func) 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; @@ -480,6 +491,18 @@ void event2_newevent_x_replace(evt_t t, uae_u32 data, evfunc2 func) 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) { } diff --git a/include/custom.h b/include/custom.h index d64c4a3a..6f3af70c 100644 --- a/include/custom.h +++ b/include/custom.h @@ -325,6 +325,7 @@ struct rgabuf *write_rga(int slot, int type, uae_u16 v, uae_u32 *p); 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; diff --git a/include/drawing.h b/include/drawing.h index 508b1c9c..b550c3db 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -24,7 +24,6 @@ extern int visible_left_border, visible_right_border; 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) @@ -34,9 +33,6 @@ extern bool exthblanken; #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. * @@ -138,8 +134,6 @@ extern void get_mode_blanking_limits(int *phbstop, int *phbstrt, int *pvbstop, i /* 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 @@ -161,6 +155,7 @@ struct linestate uae_u16 bplcon0, bplcon1, bplcon2, bplcon3, bplcon4; uae_u16 fmode; uae_u32 color0; + bool brdblank; uae_u8 *linecolorstate; int bpllen; int colors; @@ -172,6 +167,7 @@ struct linestate int internal_pixel_start_cnt; bool lol; bool blankedline; + bool vb; bool strlong_seen; int fetchmode_size, fetchstart_mask; uae_u16 strobe; @@ -179,7 +175,7 @@ struct linestate }; 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); diff --git a/include/events.h b/include/events.h index ee3c0494..05312adc 100644 --- a/include/events.h +++ b/include/events.h @@ -75,7 +75,7 @@ enum { enum { ev2_blitter, ev2_misc, - ev2_max = 8 + ev2_max = 16 }; extern int pissoff_value; @@ -151,6 +151,7 @@ extern void MISC_handler(void); 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); diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index c0263f6d..7182fbb6 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -48,9 +48,6 @@ static bool getmanualpos(int monid, int *cxp, int *cyp, int *cwp, int *chp) cy = *cyp; v = currprefs.gfx_xcenter_pos; if (v >= 0) { - if (v < 0) { - v = 0; - } cx = (v >> (RES_MAX - currprefs.gfx_resolution)) - cx; } @@ -137,10 +134,9 @@ static bool get_aspect(int monid, float *dstratiop, float *srcratiop, float *xmu } 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) diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 3ca91d59..1f1b937b 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -24009,7 +24009,11 @@ void gui_led (int led, int on, int brightness) } 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;