]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Chipset updates (fast drawing glitches etc)
authorToni Wilen <twilen@winuae.net>
Thu, 1 May 2025 16:38:10 +0000 (19:38 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 1 May 2025 16:38:10 +0000 (19:38 +0300)
custom.cpp
drawing.cpp
events.cpp
include/custom.h
include/drawing.h
include/events.h
od-win32/win32_scaler.cpp
od-win32/win32gui.cpp

index ebbd3669c1a9e913e555a6c5b3c3335895951241..3217b9071ea8ac84966cb595050cdaf5ec8be90f 100644 (file)
@@ -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);
index 2ef848e0d6b726bf9cbccf620e50ceba85cb82fb..c90b825228cf2adad34612909e4e7515668f1d24 100644 (file)
@@ -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);
 
        }
index 6ca0159fc43aa0ef396605b4f19052213b69d2e1..013d9fbfe134fbc1b2cafbcffb297a675acc4e30 100644 (file)
@@ -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)
 {
 }
index d64c4a3ab98c403f4083edda70578507fc6da8f4..6f3af70c44af900e60f9b206e889d47497fb9a59 100644 (file)
@@ -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;
index 508b1c9c4e1281164dc0a444a3e82e74852d9ad7..b550c3db307af10eb7ea4717c2c2c0f22bbd1de8 100644 (file)
@@ -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);
index ee3c0494ce1f2ea862dedf16d864d85748164022..05312adcc66041e2a287f6c53040f0d09f2f481b 100644 (file)
@@ -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);
index c0263f6dab01221a09ab9f0c884341df493006ea..7182fbb65784170a972968135bb46a857a3125c5 100644 (file)
@@ -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)
index 3ca91d5954018dab8d432832752ace522b700988..1f1b937bd6bbb82c67d4340797b408a38e8a2134 100644 (file)
@@ -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;