From fb56bf4b786c1152b2cf64852f83742debf1ce00 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 16 Jan 2025 20:56:18 +0200 Subject: [PATCH 01/10] Fix wait for blitter option. --- blitter.cpp | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/blitter.cpp b/blitter.cpp index 8a0b1600..eed14e99 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -1694,6 +1694,22 @@ void process_blitter(struct rgabuf *rga) } } +static bool is_done(void) +{ + if (blt_info.blit_main) { + return false; + } + if (!blitter_cycle_exact) { + return true; + } + if (!shifter_d_armed && blt_info.blit_count_done && !shifter[0] && !shifter[1] && !shifter[2] && !shifter[3] && + !shifter_d[0] && !shifter_d[1] && !shifter_d[2] && !shifter_d[3] && + !shifter_d_aga[0] && !shifter_d_aga[1] && !shifter_d_aga[2]) { + return true; + } + return false; +} + void generate_blitter(void) { if (!blitter_cycle_exact) { @@ -1933,7 +1949,7 @@ void reset_blit(int bltcon) static bool waitingblits(void) { - static int warned = 10; + static int warned = 50; // crazy large blit size? don't wait.. (Vital / Mystic) if (blt_info.vblitsize * blt_info.hblitsize * 2 > 2 * 1024 * 1024) { @@ -1947,9 +1963,9 @@ static bool waitingblits(void) bool waited = false; int waiting = 0; int vpos_prev = vpos; - while ((blt_info.blit_main) && dmaen(DMA_BLITTER)) { + while (!is_done() && dmaen(DMA_BLITTER)) { waited = true; - x_do_cycles (8 * CYCLE_UNIT); + x_do_cycles (4 * CYCLE_UNIT); if (vpos_prev != vpos) { vpos_prev = vpos; waiting++; @@ -1957,15 +1973,12 @@ static bool waitingblits(void) break; } } - if (blitter_cycle_exact && blit_cyclecounter > 0 && !shifter[0] && !shifter[1] && !shifter[2] && !shifter[3]) { - break; - } } if (warned && waited) { warned--; write_log(_T("waiting_blits detected PC=%08x\n"), M68K_GETPC); } - if (!blt_info.blit_main) { + if (is_done()) { return true; } return false; @@ -2145,20 +2158,7 @@ void maybe_blit(int hack) { static int warned = 10; - if (blitter_cycle_exact) { -#if 0 - if (1) { - if (blt_info.blit_main || shifter_d_armed || shifter[0] || shifter[1] || shifter[2] || shifter[3] || - shifter_d[0] || shifter_d[1] || shifter_d[2] || shifter_d[3]) { - write_log("blitter register change while active!\n"); - activate_debugger(); - } - } -#endif - return; - } - - if (!blt_info.blit_main) { + if (is_done()) { return; } From 37c4aa74c9fe77c0cd9a52eda00713940b478834 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 16 Jan 2025 20:57:56 +0200 Subject: [PATCH 02/10] Reimplement interlace scandoubler --- custom.cpp | 14 ++++++++------ drawing.cpp | 8 ++++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/custom.cpp b/custom.cpp index 8b99e24a..88dba25d 100644 --- a/custom.cpp +++ b/custom.cpp @@ -119,8 +119,8 @@ static uae_u32 custom_state_flags; static int not_safe_mode; static bool dmal_next; -#define MAX_SCANDOUBLED_LINES 1000 -static uae_u32 scandoubled_bpl_ptr[MAX_SCANDOUBLED_LINES][8][2]; +#define MAX_SCANDOUBLED_LINES 1200 +static uae_u32 scandoubled_bpl_ptr[MAX_SCANDOUBLED_LINES][2][MAX_PLANES]; static evt_t blitter_dma_change_cycle, copper_dma_change_cycle, sprite_dma_change_cycle_on, sprite_dma_change_cycle_off; @@ -9637,7 +9637,7 @@ static void decide_bpl(int hpos) ddf_enable_on = 1; if (currprefs.gfx_scandoubler && vpos < MAX_SCANDOUBLED_LINES) { for (int i = 0; i < MAX_PLANES; i++) { - scandoubled_bpl_ptr[vpos][i][lof_store] = bplpt[i]; + scandoubled_bpl_ptr[vpos][lof_store][i] = bplpt[i]; } } } @@ -9795,7 +9795,7 @@ static void decide_bpl(int hpos) ddfstrt_match = true; if (currprefs.gfx_scandoubler && vpos < MAX_SCANDOUBLED_LINES) { for (int i = 0; i < MAX_PLANES; i++) { - scandoubled_bpl_ptr[vpos][i][lof_store] = bplpt[i]; + scandoubled_bpl_ptr[vpos][lof_store][i] = bplpt[i]; } } } else { @@ -10237,8 +10237,8 @@ static void do_scandouble(void) if (rd->rga >= 0x110 && rd->rga < 0x120) { int plane = (rd->rga - 0x110) / 2; if (vp < MAX_SCANDOUBLED_LINES) { - uaecptr l1 = scandoubled_bpl_ptr[vp][plane][l]; - uaecptr l2 = scandoubled_bpl_ptr[vp][plane][l ^ 1]; + uaecptr l1 = scandoubled_bpl_ptr[vp][l][plane]; + uaecptr l2 = scandoubled_bpl_ptr[vp][l ^ 1][plane]; rga.pv = rd->pt - l1 + l2; if (fetchmode_fmode_bpl == 3) { rd->v64 = fetch64(&rga); @@ -10485,7 +10485,9 @@ static void decide_hsync(void) do_scandouble(); denise_restore_registers(); lof_display ^= 1; + scandoubled_line = 1; draw_line(linear_hpos); + scandoubled_line = 0; lof_display ^= 1; } else { draw_line(linear_hpos); diff --git a/drawing.cpp b/drawing.cpp index 6c0fc6ce..1d530009 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -42,6 +42,8 @@ #define AUTOSCALE_SPRITES 1 #define LOL_SHIFT_COLORS 0 +int scandoubled_line; + struct amigadisplay adisplays[MAX_AMIGADISPLAYS]; typedef enum @@ -4579,8 +4581,10 @@ static void matchsprites_aga(int cnt) } static uae_u16 s_bplcon0, s_bplcon1, s_bplcon2, s_bplcon3, s_bplcon4, s_fmode; +static int denise_hcounter_s; void denise_store_registers(void) { + denise_hcounter_s = denise_hcounter; s_bplcon0 = bplcon0_denise; s_bplcon1 = bplcon1_denise; s_bplcon2 = bplcon2_denise; @@ -4590,6 +4594,7 @@ void denise_store_registers(void) } void denise_restore_registers(void) { + denise_hcounter = denise_hcounter_s; expand_bplcon0(s_bplcon0); expand_bplcon1(s_bplcon1); expand_bplcon2(s_bplcon2); @@ -4798,7 +4803,7 @@ static void get_line(int gfx_ypos, enum nln_how how) } // clear lines if mode height is now smaller than previously - if (gfx_ypos >= 0 && gfx_ypos < prevline) { + if (gfx_ypos >= 0 && gfx_ypos < prevline && !scandoubled_line) { struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; struct vidbuffer *vb = &vidinfo->drawbuffer; if (prevline > vb->inheight) { @@ -4927,7 +4932,6 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start get_line(gfx_ypos, how); hbstrt_ptr1 = NULL; - if (denise_pixtotal_max == -0x7fffffff || ((linear_vpos >= denise_vblank_extra_vbstop || linear_vpos < denise_vblank_extra_vbstrt) && currprefs.gfx_overscanmode < OVERSCANMODE_ULTRA)) { // don't draw vertical blanking if not ultra extreme overscan From 17eea9ac401aa42d874605fbc1e1c7a32c0477fd Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 16 Jan 2025 20:59:15 +0200 Subject: [PATCH 03/10] Long line and long field always matches if not programmed mode. --- custom.cpp | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/custom.cpp b/custom.cpp index 88dba25d..c7d4057e 100644 --- a/custom.cpp +++ b/custom.cpp @@ -503,9 +503,11 @@ static bool agnus_equdis; int maxhpos = MAXHPOS_PAL; +static int maxhpos_long; int maxhpos_short = MAXHPOS_PAL; int maxvpos = MAXVPOS_PAL; int maxvpos_nom = MAXVPOS_PAL; // nominal value (same as maxvpos but "faked" maxvpos in fake 60hz modes) +static int maxvpos_long; int maxvpos_display = MAXVPOS_PAL; // value used for display size int maxhpos_display = AMIGA_WIDTH_MAX; int maxvsize_display = AMIGA_HEIGHT_MAX; @@ -1987,6 +1989,7 @@ static void init_beamcon0(void) if (maxvpos_nom >= MAXVPOS) { maxvpos_nom = MAXVPOS; } + maxvpos_long = (beamcon0 & BEAMCON0_VARBEAMEN) ? -1 : maxvpos + 1; if (maxvpos_display >= MAXVPOS) { maxvpos_display = MAXVPOS; } @@ -2259,6 +2262,7 @@ STATIC_INLINE int GETHPOS(void) static void setmaxhpos(void) { maxhpos = maxhpos_short + lol; + maxhpos_long = linetoggle ? maxhpos_short + 1 : -1; maxhposm0 = maxhpos; maxhposm1 = maxhpos - 1; maxhposeven = (maxhposm1 & 1) == 0; @@ -2288,7 +2292,7 @@ static void incpos(uae_u16 *hpp, uae_u16 *vpp) } } hp++; - if (hp == maxhpos) { + if (hp == maxhpos || hp == maxhpos_long) { hp = 0; } if (agnus_pos_change >= 1) { @@ -5015,15 +5019,6 @@ static void vsync_handler_post(void) uae_lua_run_handler("on_uae_vsync"); #endif -#if 0 - if (bplcon0 & 4) { - lof_store = lof_store ? 0 : 1; - } - if ((bplcon0 & 2) && currprefs.genlock) { - genlockvtoggle = lof_store ? 1 : 0; - } -#endif - check_no_signal(); #ifdef DEBUGGER @@ -5308,16 +5303,6 @@ static void lightpen_trigger_func(uae_u32 v) lightpen_triggered = 1; } -static bool is_custom_vsync (void) -{ - int vp = vpos; - if (vp == maxvpos + lof_store) { - // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely - return true; - } - return false; -} - static bool do_render_slice(int mode, int slicecnt, int lastline) { //draw_lines(lastline, slicecnt); @@ -6817,6 +6802,7 @@ void custom_reset(bool hardreset, bool keyboardreset) sprite_width = GET_SPRITEWIDTH(fmode); setup_fmodes(bplcon0); + setmaxhpos(); #ifdef ACTION_REPLAY /* Doing this here ensures we can use the 'reset' command from within AR */ @@ -10580,7 +10566,8 @@ static void custom_trigger_start(void) } bool vposzero = false; - if (vpos == maxvpos + lof_store) { + // LOF=1 is always matched, even when LOF=0 but only in PAL/NTSC modes + if ((vpos == maxvpos + lof_store) || (vpos == maxvpos_long)) { vpos = 0; check_vsyncs(); @@ -10754,7 +10741,7 @@ static bool cck_clock; static void get_cck_clock(void) { int h = agnus_hpos + 1; - if (h == maxhpos) { + if (h == maxhpos || h == maxhpos_long) { h = 0; } if (agnus_pos_change == 1 && agnus_hpos_next >= 0) { @@ -10784,7 +10771,7 @@ static void inc_cck(void) currcycle_cck++; // must check end of line first - if (agnus_hpos == maxhpos) { + if (agnus_hpos == maxhpos || agnus_hpos == maxhpos_long) { agnus_hpos = 0; if (issyncstopped(bplcon0) && !syncs_stopped) { if (!lol) { @@ -10804,7 +10791,7 @@ static void inc_cck(void) rga_denise_cycle_count++; } if (beamcon0_dual) { - if (hhpos == maxhpos) { + if (hhpos == maxhpos || hhpos == maxhpos_long) { hhpos = 0; } } else { From c9cc0f816412b872b9146024a2939efec3ca64e2 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 16 Jan 2025 21:01:18 +0200 Subject: [PATCH 04/10] Some Voodoo updates --- pcem/vid_voodoo_banshee.cpp | 10 +++++++++- pcem/vid_voodoo_fb.cpp | 9 +++++++++ pcem/vid_voodoo_regs.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pcem/vid_voodoo_banshee.cpp b/pcem/vid_voodoo_banshee.cpp index cda8bee4..60411f9d 100644 --- a/pcem/vid_voodoo_banshee.cpp +++ b/pcem/vid_voodoo_banshee.cpp @@ -147,6 +147,7 @@ enum cmdHoleCnt0 = 0x48 }; +#define VGAINIT0_RAMDAC_8BIT (1 << 2) #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) #define VIDPROCCFG_VIDPROC_ENABLE (1 << 0) @@ -376,7 +377,7 @@ static void banshee_render_16bpp_tiled(svga_t *svga) else addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); - for (x = 0; x <= svga->hdisp; x += 64) + for (x = 0; x < svga->hdisp; x += 64) { if (svga->hwcursor_on || svga->overlay_on) svga->changedvram[addr >> 12] = 2; @@ -630,6 +631,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) break; case Init_vgaInit0: banshee->vgaInit0 = val; + svga_set_ramdac_type(svga, (val & VGAINIT0_RAMDAC_8BIT ? RAMDAC_8BIT : RAMDAC_6BIT)); break; case Init_vgaInit1: banshee->vgaInit1 = val; @@ -1044,6 +1046,10 @@ static uint32_t banshee_cmd_read(banshee_t *banshee, uint32_t addr) // pclog("Read cmdfifo_depth %08x\n", ret); break; + case cmdBaseSize0: + ret = voodoo->cmdfifo_size; + break; + case 0x108: break; @@ -1753,6 +1759,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) for (xx = 0; xx < 8; xx++) { + if (((x_off + xx + svga->x_add) >= 0) && ((x_off + xx + svga->x_add) <= 2047)) { if (!(plane0[x >> 3] & (1 << 7))) ((uint32_t *)buffer32->line[displine])[x_off + xx] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; else if (plane1[x >> 3] & (1 << 7)) @@ -1760,6 +1767,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) plane0[x >> 3] <<= 1; plane1[x >> 3] <<= 1; + } } } diff --git a/pcem/vid_voodoo_fb.cpp b/pcem/vid_voodoo_fb.cpp index be07311a..d6251f59 100644 --- a/pcem/vid_voodoo_fb.cpp +++ b/pcem/vid_voodoo_fb.cpp @@ -325,6 +325,15 @@ void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) addr >>= 1; break; + case LFB_FORMAT_XRGB8888: + colour_data[0].b = val & 0xff; + colour_data[0].g = (val >> 8) & 0xff; + colour_data[0].r = (val >> 16) & 0xff; + alpha_data[0] = 0xff; + write_mask = LFB_WRITE_COLOUR; + addr >>= 1; + break; + case LFB_FORMAT_DEPTH: depth_data[0] = val; depth_data[1] = val >> 16; diff --git a/pcem/vid_voodoo_regs.h b/pcem/vid_voodoo_regs.h index e99241f6..eb8435d7 100644 --- a/pcem/vid_voodoo_regs.h +++ b/pcem/vid_voodoo_regs.h @@ -342,6 +342,7 @@ enum LFB_FORMAT_RGB565 = 0, LFB_FORMAT_RGB555 = 1, LFB_FORMAT_ARGB1555 = 2, + LFB_FORMAT_XRGB8888 = 4, LFB_FORMAT_ARGB8888 = 5, LFB_FORMAT_DEPTH = 15, LFB_FORMAT_MASK = 15 From 057955013cc9182d24ed833a377e3258ac72935c Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 16 Jan 2025 21:04:56 +0200 Subject: [PATCH 05/10] 6000b5 --- od-win32/win32.h | 4 ++-- od-win32/win32gui.cpp | 3 +-- od-win32/winuaechangelog.txt | 12 ++++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/od-win32/win32.h b/od-win32/win32.h index ff6cee93..6d101c5b 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -20,12 +20,12 @@ #define LANG_DLL_FULL_VERSION_MATCH 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("4") +#define WINUAEBETA _T("5") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2025, 1, 11) +#define WINUAEDATE MAKEBD(2025, 1, 16) //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index db9892fb..7a5ccb2a 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -21539,7 +21539,6 @@ static void enable_for_avioutputdlg (HWND hDlg) #endif ew (hDlg, IDC_SCREENSHOT, full_property_sheet ? FALSE : TRUE); - ew (hDlg, IDC_SAMPLERIPPER_ACTIVATED, full_property_sheet ? FALSE : TRUE); ew (hDlg, IDC_AVIOUTPUT_FILE, TRUE); @@ -21798,7 +21797,7 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP break; #endif case IDC_SAMPLERIPPER_ACTIVATED: - if (ischecked(hDlg, IDC_AVIOUTPUT_ACTIVATED) != (sampleripper_enabled != 0)) { + if (ischecked(hDlg, IDC_SAMPLERIPPER_ACTIVATED) != (sampleripper_enabled != 0)) { sampleripper_enabled = !sampleripper_enabled; audio_sampleripper (-1); } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 5f03b3d4..db23f8e9 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,16 @@ +Beta 5: + +- Autoscale filter fixed again. +- BPLCON4 was cleared when on the fly switching from OCS/ECS to AGA, causing wrong sprite colors. +- Wait for blitter option works again. +- "Remove interlace artifacts" option works again (with last line flicker, this will be fixed later). It now uses different logic which might work better when interlace mode is "non-standard". +- Prometheus FireStorm PCI IO space size is 2M, only lowest 1M was mapped and it also was not correctly mapped. +- Do not log Prometheus FireStorm status long read as config space accesses. +- Merged some minor Voodoo emulation updates from 86box. +- Added previously missing hardware feature: PAL/NTSC long line count always causes end of field, even if current LOF=0. (Only important when doing VPOSW tricks badly :)) NTSC long line horizontal is also always matched, even if LOL=0. +- Added address and length to sample ripper file names. +- Query PC drive/network drive/removable drive status only after confirming drive type first. (For example if "Add PC drives at startup" or "CDFS automount" is only ticked, don't query status of possible network drives that might respond slowly) Beta 4: From bf1c2928733497acc2262bb01a5c6904709d1fb0 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 18 Jan 2025 21:30:36 +0200 Subject: [PATCH 06/10] Clipboard limit --- od-win32/clipboard_win32.cpp | 45 +++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/od-win32/clipboard_win32.cpp b/od-win32/clipboard_win32.cpp index dd426105..fc1eacad 100644 --- a/od-win32/clipboard_win32.cpp +++ b/od-win32/clipboard_win32.cpp @@ -37,6 +37,9 @@ static void *clipboard_delayed_data; static int clipboard_delayed_size; static bool clip_disabled; +#define CLIP_SIZE_LIMIT 10000000 +#define CLIP_SIZE_LIMIT_INIT 30000 + static void debugwrite (TrapContext *ctx, const TCHAR *name, uaecptr p, int size) { FILE *f; @@ -248,7 +251,7 @@ static void from_iff_text(uae_u8 *addr, uae_u32 len) xfree(txt); } -static void to_iff_ilbm(TrapContext *ctx, HBITMAP hbmp) +static void to_iff_ilbm(TrapContext *ctx, HBITMAP hbmp, bool initial) { BITMAP bmp; int bmpw, w, h, bpp, iffbpp, tsize, size, x, y, i; @@ -264,6 +267,7 @@ static void to_iff_ilbm(TrapContext *ctx, HBITMAP hbmp) if (!GetObject (hbmp, sizeof bmp, &bmp)) return; + w = bmp.bmWidth; h = bmp.bmHeight; bpp = bmp.bmBitsPixel; @@ -272,6 +276,14 @@ static void to_iff_ilbm(TrapContext *ctx, HBITMAP hbmp) return; bmpw = (w * bpp / 8 + 3) & ~3; size = bmpw * h; + + if (size > (initial ? CLIP_SIZE_LIMIT_INIT : CLIP_SIZE_LIMIT)) { + if (clipboard_log) { + write_log(_T("clipboard: initial size too large, ignored.\n")); + } + return; + } + bmp.bmBits = xmalloc (uae_u8, size); if (!GetBitmapBits (hbmp, size, bmp.bmBits)) { xfree (bmp.bmBits); @@ -736,7 +748,7 @@ void clipboard_disable (bool disabled) clip_disabled = disabled; } -static void clipboard_read(TrapContext *ctx, HWND hwnd, bool keyboardinject) +static void clipboard_read(TrapContext *ctx, HWND hwnd, bool keyboardinject, bool initial) { HGLOBAL hglb; UINT f; @@ -770,13 +782,20 @@ static void clipboard_read(TrapContext *ctx, HWND hwnd, bool keyboardinject) if (hglb != NULL) { TCHAR *lptstr = (TCHAR*)GlobalLock (hglb); if (lptstr != NULL) { - if (clipboard_log) { - write_log (_T("clipboard: CF_UNICODETEXT '%s'\n"), lptstr); - } - if (keyboardinject) { - to_keyboard(lptstr); + size_t len = _tcslen(lptstr); + if (len > (initial ? CLIP_SIZE_LIMIT_INIT : CLIP_SIZE_LIMIT)) { + if (clipboard_log) { + write_log(_T("clipboard: initial size too large, ignored.\n")); + } } else { - to_iff_text(ctx, lptstr); + if (clipboard_log) { + write_log (_T("clipboard: CF_UNICODETEXT '%s'\n"), lptstr); + } + if (keyboardinject) { + to_keyboard(lptstr); + } else { + to_iff_text(ctx, lptstr); + } } GlobalUnlock (hglb); } @@ -787,7 +806,7 @@ static void clipboard_read(TrapContext *ctx, HWND hwnd, bool keyboardinject) if (clipboard_log) { write_log (_T("clipboard: CF_BITMAP\n")); } - to_iff_ilbm(ctx, hbmp); + to_iff_ilbm(ctx, hbmp, initial); } } CloseClipboard (); @@ -820,7 +839,7 @@ void clipboard_changed (HWND hwnd) clipboard_change = 1; return; } - clipboard_read(NULL, hwnd, false); + clipboard_read(NULL, hwnd, false, false); } static int clipboard_put_bmp_real (HBITMAP hbmp) @@ -896,7 +915,7 @@ void amiga_clipboard_init(TrapContext *ctx) signaling = 0; write_log (_T("clipboard initialized\n")); initialized = 1; - clipboard_read(ctx, chwnd, false); + clipboard_read(ctx, chwnd, false, true); } void amiga_clipboard_task_start(TrapContext *ctx, uaecptr data) @@ -963,7 +982,7 @@ void clipboard_active(HWND hwnd, int active) if (!initialized || !hwnd) return; if (clipactive && clipboard_change) { - clipboard_read(NULL, hwnd, false); + clipboard_read(NULL, hwnd, false, false); } if (!clipactive && clipboard_delayed_data) { if (clipboard_delayed_size < 0) { @@ -1041,7 +1060,7 @@ void clipboard_init (HWND hwnd) void target_paste_to_keyboard(void) { - clipboard_read(NULL, chwnd, true); + clipboard_read(NULL, chwnd, true, false); } // force 2 second delay before accepting new data From 7682cbb6b0e80479679a4c4f2a273c84a523e6ed Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 18 Jan 2025 21:30:51 +0200 Subject: [PATCH 07/10] Fix A2024 15Hz mode. --- specialmonitors.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specialmonitors.cpp b/specialmonitors.cpp index 79824e51..512f2817 100755 --- a/specialmonitors.cpp +++ b/specialmonitors.cpp @@ -2092,7 +2092,7 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) panel_width_draw = px == 2 ? 352 : 336; pxcnt = 3; hires = false; - srcxoffset = 85 - spm_left_border * 2;; + srcxoffset = 85 - spm_left_border * 2; if (px > 2) return false; total_width = 336 + 336 + 352; @@ -2101,7 +2101,7 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) panel_width_draw = 512; pxcnt = 2; hires = true; - srcxoffset = 101 - spm_left_border * 2; + srcxoffset = 100 - spm_left_border * 2; if (px > 1) return false; total_width = 512 + 512; From 141525f45b4e3d57102ae358194e32de3fdb5c71 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 18 Jan 2025 21:32:02 +0200 Subject: [PATCH 08/10] Scandoubler update --- custom.cpp | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/custom.cpp b/custom.cpp index c7d4057e..e01cb957 100644 --- a/custom.cpp +++ b/custom.cpp @@ -121,6 +121,7 @@ static bool dmal_next; #define MAX_SCANDOUBLED_LINES 1200 static uae_u32 scandoubled_bpl_ptr[MAX_SCANDOUBLED_LINES][2][MAX_PLANES]; +static bool scandoubled_bpl_ena[MAX_SCANDOUBLED_LINES]; static evt_t blitter_dma_change_cycle, copper_dma_change_cycle, sprite_dma_change_cycle_on, sprite_dma_change_cycle_off; @@ -9621,9 +9622,9 @@ static void decide_bpl(int hpos) // DDFSTRT if (hpos == ddfstrt) { ddf_enable_on = 1; - if (currprefs.gfx_scandoubler && vpos < MAX_SCANDOUBLED_LINES) { + if (currprefs.gfx_scandoubler && linear_vpos < MAX_SCANDOUBLED_LINES) { for (int i = 0; i < MAX_PLANES; i++) { - scandoubled_bpl_ptr[vpos][lof_store][i] = bplpt[i]; + scandoubled_bpl_ptr[linear_vpos][lof_store][i] = bplpt[i]; } } } @@ -9779,9 +9780,9 @@ static void decide_bpl(int hpos) // DDFSTRT if (hpos == ddfstrt) { ddfstrt_match = true; - if (currprefs.gfx_scandoubler && vpos < MAX_SCANDOUBLED_LINES) { + if (currprefs.gfx_scandoubler && linear_vpos < MAX_SCANDOUBLED_LINES) { for (int i = 0; i < MAX_PLANES; i++) { - scandoubled_bpl_ptr[vpos][lof_store][i] = bplpt[i]; + scandoubled_bpl_ptr[linear_vpos][lof_store][i] = bplpt[i]; } } } else { @@ -9856,6 +9857,9 @@ static void check_bpl_vdiw(void) } #endif } + if (linear_vpos < MAX_SCANDOUBLED_LINES) { + scandoubled_bpl_ena[linear_vpos] = vdiwstate != diw_states::DIW_waiting_start; + } } static void generate_sprites(int num, int slot) @@ -10214,25 +10218,26 @@ static void check_vsyncs(void) static void do_scandouble(void) { + if (linear_vpos >= MAX_SCANDOUBLED_LINES) { + return; + } int l = lof_store; - int vp = vpos; + int vp = linear_vpos; struct rgabuf rga = { 0 }; for (int i = 0; i < rga_denise_cycle_count; i++) { int idx = (i + rga_denise_cycle_start) & (DENISE_RGA_SLOT_TOTAL - 1); struct denise_rga *rd = &rga_denise[idx]; if (rd->rga >= 0x110 && rd->rga < 0x120) { int plane = (rd->rga - 0x110) / 2; - if (vp < MAX_SCANDOUBLED_LINES) { - uaecptr l1 = scandoubled_bpl_ptr[vp][l][plane]; - uaecptr l2 = scandoubled_bpl_ptr[vp][l ^ 1][plane]; - rga.pv = rd->pt - l1 + l2; - if (fetchmode_fmode_bpl == 3) { - rd->v64 = fetch64(&rga); - } else if (fetchmode_fmode_bpl > 0) { - rd->v = fetch32_bpl(&rga); - } else { - rd->v = fetch16(&rga); - } + uaecptr l1 = scandoubled_bpl_ptr[vp][l][plane]; + uaecptr l2 = scandoubled_bpl_ptr[vp][l ^ 1][plane]; + rga.pv = rd->pt - l1 + l2; + if (fetchmode_fmode_bpl == 3) { + rd->v64 = fetch64(&rga); + } else if (fetchmode_fmode_bpl > 0) { + rd->v = fetch32_bpl(&rga); + } else { + rd->v = fetch16(&rga); } } } @@ -10465,7 +10470,7 @@ static void decide_hsync(void) if (!custom_disabled) { if (custom_fastmode >= 0) { - if (doflickerfix_active()) { + if (doflickerfix_active() && scandoubled_bpl_ena[linear_vpos]) { denise_store_registers(); draw_line(linear_hpos); do_scandouble(); From 93864b3607230108639f950174d5317786524d15 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 18 Jan 2025 21:32:42 +0200 Subject: [PATCH 09/10] Skip most of chipset emulation in RTG modes. --- custom.cpp | 253 ++++++++++++++++++++--------------------------------- events.cpp | 2 +- 2 files changed, 98 insertions(+), 157 deletions(-) diff --git a/custom.cpp b/custom.cpp index e01cb957..796a0060 100644 --- a/custom.cpp +++ b/custom.cpp @@ -2251,13 +2251,21 @@ static void checksyncstopped(uae_u16 con0) } } -STATIC_INLINE int GETVPOS(void) +static int GETVPOS(void) { return islightpentriggered() ? vpos_lpen : vpos; } -STATIC_INLINE int GETHPOS(void) +static int GETHPOS(void) { - return islightpentriggered() ? hpos_lpen : agnus_hpos; + if (islightpentriggered()) { + return hpos_lpen; + } + if (!eventtab[ev_sync].active) { + return agnus_hpos; + } + evt_t c = get_cycles(); + int hp = (c - eventtab[ev_sync].oldcycles) / CYCLE_UNIT; + return hp; } static void setmaxhpos(void) @@ -3051,22 +3059,6 @@ static void DMACON(int hpos, uae_u16 v) if (changed & (DMA_MASTER | DMA_AUD3 | DMA_AUD2 | DMA_AUD1 | DMA_AUD0)) { audio_state_machine(); } - -#if 0 - if (changed & (DMA_MASTER | DMA_BITPLANE)) { - // if ECS, DDFSTRT has already passed but DMA was off and DMA gets turned on: BPRUN actvates 1 cycle earlier - bool bpl = (dmacon & DMA_BITPLANE) && (dmacon & DMA_MASTER); - //event2_newevent_xx(-1, CYCLE_UNIT, dmacon, bitplane_dma_change); - dmacon_bpl = bpl; - if (ecs_agnus && bpl && !dmacon_bpl && ddf_enable_on > 0) { - dmacon_bpl = true; - } else { - dmacon_bpl = true; - event2_newevent_xx(-1, CYCLE_UNIT, dmacon, bitplane_dma_change); - } - SET_LINE_CYCLEBASED(hpos); - } -#endif } static int irq_forced; @@ -4145,6 +4137,7 @@ bool blitter_cant_access(void) return false; } +// return if register is in Agnus or Denise (or both) static int get_reg_chip(int reg) { if (reg == 0x100 || reg == 0x1fc) { @@ -5100,131 +5093,6 @@ static void copper_check(int n) } } -#if 0 -static void reset_scandoubler_sync(int hpos) -{ - last_decide_line_hpos = hpos; - last_decide_sprite_hpos = hpos; - last_fetch_hpos = hpos; - last_copper_hpos = hpos; - last_diw_hpos = hpos; - last_sprite_hpos = hpos; - sprites_enabled_this_line = false; - plfstrt_sprite = 0x100; - bprun = 0; - bprun_cycle = 0; - ddf_stopping = 0; - int hnew = hpos - (REFRESH_FIRST_HPOS - HARDWIRED_DMA_TRIGGER_HPOS + 2); - hdiw_denisecounter = ((hnew + 0) & 0xff) << CCK_SHRES_SHIFT; - last_sprite_hpos = last_sprite_point = (((hnew + 0) & 0xff) << 1) + 1; -} -#endif - - -/* - -0 0 - -1 1 -- -2 2 - -3 3 -- -4 4 - -5 5 -- - -0 x -+ -1 0 -- -2 1 - -3 2 -- -4 3 - -5 4 -- - -*/ - -#if 0 -static void hsync_scandoubler(int hpos) -{ - uae_u16 odmacon = dmacon; - int ocop = copper_enabled_thisline; - uaecptr bpltmp[MAX_PLANES], bpltmpx[MAX_PLANES]; - int lof = lof_display; - - if (vb_start_line > 2) { - return; - } - - scandoubled_line = 1; - line_disabled |= 8; - last_hdiw = 0 - 1; - - for (int i = 0; i < MAX_PLANES; i++) { - bpltmp[i] = bplpt[i]; - bpltmpx[i] = bplptx[i]; - uaecptr pb1 = prevbpl[lof][vpos][i]; - uaecptr pb2 = prevbpl[1 - lof][vpos][i]; - if (pb1 && pb2) { - int diff = pb1 - pb2; - if (lof) { - if (bplcon0 & 4) { - bplpt[i] = pb1 - diff; - } - } else { - if (bplcon0 & 4) { - bplpt[i] = pb1; - } else { - bplpt[i] = bplpt[i] - diff; - } - } - } - } - - uae_u8 cycle_line_slot_tmp[MAX_CHIPSETSLOTS]; - uae_u16 cycle_line_pipe_tmp[MAX_CHIPSETSLOTS]; - - memcpy(cycle_line_slot_tmp, cycle_line_slot, sizeof(uae_u8) * MAX_CHIPSETSLOTS); - memcpy(cycle_line_pipe_tmp, cycle_line_pipe, sizeof(uae_u16) * MAX_CHIPSETSLOTS); - - reset_decisions_scanline_start(); - reset_scandoubler_sync(hpos); - reset_decisions_hsync_start(); - - // Bitplane and sprites only - dmacon = odmacon & (DMA_MASTER | DMA_BITPLANE | DMA_SPRITE); - copper_enabled_thisline = 0; - - // copy color changes - struct draw_info *dip1 = curr_drawinfo + next_lineno - 1; - for (int idx1 = dip1->first_color_change; idx1 < dip1->last_color_change; idx1++) { - struct color_change *cs2 = &curr_color_changes[idx1]; - struct color_change *cs1 = &curr_color_changes[next_color_change]; - memcpy(cs1, cs2, sizeof(struct color_change)); - next_color_change++; - } - curr_color_changes[next_color_change].regno = -1; - - hpos_hsync_extra = 0; - finish_partial_decision(maxhpos); - hpos_hsync_extra = maxhpos; - finish_decisions(hpos); - hsync_record_line_state(next_lineno, nln_normal, thisline_changed); - - scandoubled_line = 0; - line_disabled &= ~8; - - dmacon = odmacon; - copper_enabled_thisline = ocop; - - memcpy(cycle_line_slot, cycle_line_slot_tmp, sizeof(uae_u8) * MAX_CHIPSETSLOTS); - memcpy(cycle_line_pipe, cycle_line_pipe_tmp, sizeof(uae_u16) * MAX_CHIPSETSLOTS); - - for (int i = 0; i < MAX_PLANES; i++) { - bplpt[i] = bpltmp[i]; - bplptx[i] = bpltmpx[i]; - } - - reset_decisions_scanline_start(); - reset_scandoubler_sync(hpos); -} -#endif - static void dmal_emu_disk(struct rgabuf *rga, int slot, bool w) { uae_u16 dat = 0; @@ -5256,7 +5124,7 @@ static void dmal_emu_disk(struct rgabuf *rga, int slot, bool w) } else { // read from disk if (disk_fifostatus() >= 0) { - uaecptr pt = *rga->p; + uaecptr pt = rga->pv; dat = DSKDATR(slot); #ifdef DEBUGGER if (debug_dma) { @@ -10531,6 +10399,14 @@ static int can_fast_custom(void) return 0; } +static void start_sync_handler(void) +{ + eventtab[ev_sync].active = 1; + eventtab[ev_sync].oldcycles = get_cycles(); + eventtab[ev_sync].evtime = get_cycles() + (maxhpos + lol) * CYCLE_UNIT; + events_schedule(); +} + static void custom_trigger_start(void) { vpos_prev = vpos; @@ -10637,6 +10513,12 @@ static void custom_trigger_start(void) eventtab[ev_sync].active = true; events_schedule(); } + + if (custom_disabled && !eventtab[ev_sync].active) { + start_sync_handler(); + write_log("Chipset emulation inactive\n"); + } + // if (1 && !can_fast_custom() && custom_fastmode) { // custom_fastmode = 0; // } @@ -10679,6 +10561,7 @@ static void set_fakehsync_handler(void) event2_newevent_xx(-1, CYCLE_UNIT * maxhpos, 0, fakehsync_handler); } +#if 0 static void sync_evhandler(void) { eventtab[ev_sync].active = false; @@ -10739,7 +10622,7 @@ static void sync_evhandler(void) return; } } - +#endif static bool cck_clock; @@ -11447,28 +11330,29 @@ static void generate_dmal(void) static void generate_dma_requests(void) { - generate_bpl(cck_clock); - - if (bplcon0 & 0x0080) { - generate_uhres(); - } - - if (copper_enabled_thisline) { - generate_copper(); + if (!custom_disabled) { + generate_bpl(cck_clock); + if (bplcon0 & 0x0080) { + generate_uhres(); + } + if (copper_enabled_thisline) { + generate_copper(); + } } if (blt_info.blit_queued || blitter_delayed_update) { extern void generate_blitter(void); generate_blitter(); } - } static void do_cck(bool docycles) { get_cck_clock(); - bitplane_rga_ptmod(); + if (!custom_disabled) { + bitplane_rga_ptmod(); + } handle_rga_out(); @@ -11511,6 +11395,63 @@ static void do_cck(bool docycles) } +// horizontal sync callback when in RTG mode + fast cpu +static void sync_evhandler(void) +{ + if (!custom_disabled) { + eventtab[ev_sync].active = 0; + write_log("Chipset emulation active\n"); + return; + } + + custom_trigger_start(); + + if (vpos == 0) { // TODO: programmed VB + INTREQ_INT(5, 0); + } + + process_dmal(0); + uae_u32 dmal_d = dmal; + + // "immediate" audio DMA + if (dmaen(DMA_AUD0 | DMA_AUD1 | DMA_AUD2 | DMA_AUD3) && ((dmal_d >> (3 * 2)) & 255)) { + for (int nr = 0; nr < 4; nr++) { + uae_u32 dmalbits = (dmal_d >> ((3 + nr) * 2)) & 3; + if (dmalbits) { + struct rgabuf r = { 0 }; + uaecptr *pt = audio_getpt(nr); + r.pv = *pt; + dmal_emu_audio(&r, nr); + *pt += 2; + if (dmalbits & 1) { + *pt = audio_getloadpt(nr); + } + } + } + } + + // "immediate" disk DMA + if (dmaen(DMA_DISK) && (((dmal_d >> 0) & 63))) { + for (int nr = 0; nr < 3; nr++) { + uae_u32 dmalbits = (dmal_d >> (0 + nr * 2)) & 3; + if (dmalbits) { + int w = (dmalbits & 3) == 3; + struct rgabuf r = { 0 }; + uaecptr *pt = disk_getpt(); + r.pv = *pt; + dmal_emu_disk(&r, nr, w); + *pt += 2; + } + } + } + + dmal = 0; + dmal_shifter = 0; + + start_sync_handler(); +} + + int do_cycles_cck(int cycles) { int c = 0; diff --git a/events.cpp b/events.cpp index 54e98096..813244c0 100644 --- a/events.cpp +++ b/events.cpp @@ -326,7 +326,7 @@ void do_cycles_slow(int cycles_to_add) while (cycles_to_add >= CYCLE_UNIT) { - if (custom_fastmode <= 0) { + if (!eventtab[ev_sync].active) { int cyc = cycles_to_add; cyc = do_cycles_cck(cyc); cycles_to_add -= cyc; From f57b4f070ae5344c6636d4bb66b0273532241dbc Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 18 Jan 2025 21:39:05 +0200 Subject: [PATCH 10/10] 6000b6 --- od-win32/win32.h | 4 ++-- od-win32/winuaechangelog.txt | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/od-win32/win32.h b/od-win32/win32.h index 6d101c5b..69f09a60 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -20,12 +20,12 @@ #define LANG_DLL_FULL_VERSION_MATCH 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("5") +#define WINUAEBETA _T("6") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2025, 1, 16) +#define WINUAEDATE MAKEBD(2025, 1, 18) //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index db23f8e9..1d015a6a 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,12 @@ + +Beta 6: + +- Almost all chipset emulation code is skipped when RTG mode is active and chipset screen is not visible (not connected to any other virtual monitor). This should restore RTG mode performance back to pre-v6 WinUAE versions. Pre-v6 versions also used similar optimization. +- "Remove interlace artifacts" now uses virtual lines internally, works even when VPOSW is modified mid screen. Last line flicker fixed. +- Limit initial Windows to Amiga clipboard copy to max 30k (initial = when Amiga is booted and Windows clipboard is not empty) if clipboard sharing is enabled. This prevent slow startup if clipboard sharing is enabled and configuration is not fast and Windows clipboard has some random large image. +- Fixed A2024 15Hz mode vertical line. + Beta 5: - Autoscale filter fixed again. @@ -6,9 +14,9 @@ Beta 5: - Wait for blitter option works again. - "Remove interlace artifacts" option works again (with last line flicker, this will be fixed later). It now uses different logic which might work better when interlace mode is "non-standard". - Prometheus FireStorm PCI IO space size is 2M, only lowest 1M was mapped and it also was not correctly mapped. -- Do not log Prometheus FireStorm status long read as config space accesses. +- Do not log Prometheus FireStorm status long reads as config space accesses. - Merged some minor Voodoo emulation updates from 86box. -- Added previously missing hardware feature: PAL/NTSC long line count always causes end of field, even if current LOF=0. (Only important when doing VPOSW tricks badly :)) NTSC long line horizontal is also always matched, even if LOL=0. +- Added previously missing hardware feature: PAL/NTSC long line count always causes end of field, even if current LOF=0. (Only important when doing VPOSW tricks badly) NTSC long line horizontal is also always matched, even if LOL=0. - Added address and length to sample ripper file names. - Query PC drive/network drive/removable drive status only after confirming drive type first. (For example if "Add PC drives at startup" or "CDFS automount" is only ticked, don't query status of possible network drives that might respond slowly)