From c2f8bd2841fe499dabf670a0f5bffbc799f93123 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 19 Nov 2022 19:41:49 +0200 Subject: [PATCH] Copper waiting, CPU COPJMPx write and blitter active bug accurate implementation --- blitter.cpp | 27 +++++++++++++++------------ custom.cpp | 21 ++++++++++++--------- include/custom.h | 2 +- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/blitter.cpp b/blitter.cpp index c1311120..da5b6f92 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -1333,9 +1333,9 @@ static void blitter_doddma_new(int hpos, bool addmod) uaecptr *hpt = NULL; check_channel_mods(hpos, 4, &bltdpt); - uaecptr orptr = alloc_cycle_blitter_conflict_or(); - record_dma_blit(0x00, ddat1, bltdpt | orptr, hpos); - blit_chipmem_agnus_wput(bltdpt | orptr, ddat1, MW_MASK_BLITTER_D_N); + bltdpt |= alloc_cycle_blitter_conflict_or(hpos); + record_dma_blit(0x00, ddat1, bltdpt, hpos); + blit_chipmem_agnus_wput(bltdpt, ddat1, MW_MASK_BLITTER_D_N); bool skipadd = alloc_cycle_blitter(hpos, &bltdpt, 4, addmod ? blit_modaddd : 0); if (!blitline && !skipadd) { @@ -1353,16 +1353,17 @@ static void blitter_dodma_new(int ch, int hpos, bool addmod) bool skipadd = false; int mod; - uaecptr orptr = alloc_cycle_blitter_conflict_or(); + uaecptr orptr = alloc_cycle_blitter_conflict_or(hpos); switch (ch) { case 1: // A { + bltapt |= orptr; check_channel_mods(hpos, 1, &bltapt); reg = 0x74; - record_dma_blit(reg, 0, bltapt | orptr, hpos); - blt_info.bltadat = dat = chipmem_wget_indirect(bltapt | orptr); + record_dma_blit(reg, 0, bltapt, hpos); + blt_info.bltadat = dat = chipmem_wget_indirect(bltapt); record_dma_blit_val(dat); regs.chipset_latch_rw = blt_info.bltadat; addr = &bltapt; @@ -1373,10 +1374,11 @@ static void blitter_dodma_new(int ch, int hpos, bool addmod) case 2: // B { int bshift = bltcon1 >> 12; + bltbpt |= orptr; check_channel_mods(hpos, 2, &bltbpt); reg = 0x72; - record_dma_blit(reg, 0, bltbpt | orptr, hpos); - blt_info.bltbdat = dat = chipmem_wget_indirect(bltbpt | orptr); + record_dma_blit(reg, 0, bltbpt, hpos); + blt_info.bltbdat = dat = chipmem_wget_indirect(bltbpt); record_dma_blit_val(dat); regs.chipset_latch_rw = blt_info.bltbdat; addr = &bltbpt; @@ -1393,9 +1395,10 @@ static void blitter_dodma_new(int ch, int hpos, bool addmod) case 3: // C { reg = 0x70; + bltcpt |= orptr; check_channel_mods(hpos, 3, &bltcpt); - record_dma_blit(reg, 0, bltcpt | orptr, hpos); - blt_info.bltcdat = dat = chipmem_wget_indirect(bltcpt | orptr); + record_dma_blit(reg, 0, bltcpt, hpos); + blt_info.bltcdat = dat = chipmem_wget_indirect(bltcpt); record_dma_blit_val(dat); regs.chipset_latch_rw = blt_info.bltcdat; addr = &bltcpt; @@ -1569,7 +1572,7 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va blitter_line_proc_cpt_y(); blitlineloop = 0; } - uaecptr orptr = alloc_cycle_blitter_conflict_or(); + uaecptr orptr = alloc_cycle_blitter_conflict_or(hpos); record_dma_blit(0x70, 0, bltcpt | orptr, hpos); check_channel_mods(hpos, 3, &bltcpt); blt_info.bltcdat = chipmem_wget_indirect(bltcpt | orptr); @@ -1606,7 +1609,7 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va /* onedot mode and no pixel = bus write access is skipped */ if (blitlinepixel && c == 4) { - uaecptr orptr = alloc_cycle_blitter_conflict_or(); + uaecptr orptr = alloc_cycle_blitter_conflict_or(hpos); record_dma_blit(0x00, blt_info.bltddat, bltdpt | orptr, hpos); check_channel_mods(hpos, 4, &bltdpt); blit_chipmem_agnus_wput(bltdpt | orptr, blt_info.bltddat, MW_MASK_BLITTER_D_L); diff --git a/custom.cpp b/custom.cpp index 7c2ba215..a3fa4f73 100644 --- a/custom.cpp +++ b/custom.cpp @@ -151,6 +151,7 @@ static int toscr_hend; static int nosignal_cnt, nosignal_status; static bool nosignal_trigger; int display_reset; +static evt_t line_start_cycles; #define LOF_TOGGLES_NEEDED 3 //#define NLACE_CNT_NEEDED 50 @@ -775,10 +776,10 @@ void alloc_cycle_ext(int hpos, int type) alloc_cycle(hpos, type); } -uaecptr alloc_cycle_blitter_conflict_or(void) +uaecptr alloc_cycle_blitter_conflict_or(int hpos) { uaecptr orptr = 0; - if (get_cycles() == copper_bad_cycle) { + if (copper_bad_cycle && line_start_cycles + hpos * CYCLE_UNIT == copper_bad_cycle) { orptr = copper_bad_cycle_pc_old; } return orptr; @@ -787,11 +788,12 @@ uaecptr alloc_cycle_blitter_conflict_or(void) bool alloc_cycle_blitter(int hpos, uaecptr *ptr, int chnum, int add) { bool skipadd = false; - if (get_cycles() == copper_bad_cycle) { - write_log("Copper PT=%08x %08x. Blitter CH=%d PT=%08x bug!\n", copper_bad_cycle_pc_old, copper_bad_cycle_pc_new, chnum, *ptr); + if (copper_bad_cycle && line_start_cycles + hpos * CYCLE_UNIT == copper_bad_cycle) { + write_log("Copper PT=%08x/%08x. Blitter CH=%d PT=%08x. Conflict bug!\n", copper_bad_cycle_pc_old, copper_bad_cycle_pc_new, chnum, *ptr); cop_state.ip += add; - *ptr = copper_bad_cycle_pc_new; + *ptr = copper_bad_cycle_pc_old; skipadd = true; + copper_bad_cycle = 0; //activate_debugger(); } alloc_cycle(hpos, CYCLE_BLITTER); @@ -7527,12 +7529,12 @@ static void COPJMP(int num, int vblank) if (blt_info.blit_main) { static int warned = 100; if (warned > 0) { - write_log(_T("possible buggy copper cycle conflict with blitter PC=%08x\n"), M68K_GETPC); + write_log(_T("Potential buggy copper cycle conflict with blitter PC=%08x, COP=%08x\n"), M68K_GETPC, cop_state.ip); warned--; } } int hp = current_hpos(); - if (0 && (hp & 1) && currprefs.cpu_model == 68000 && currprefs.cpu_cycle_exact) { + if ((hp & 1) && currprefs.cpu_model == 68000 && currprefs.cpu_cycle_exact && currprefs.blitter_cycle_exact && currprefs.m68k_speed == 0 && !(currprefs.cs_hacks & 16)) { // CPU unaligned COPJMP while waiting cop_state.state = COP_strobe_delay1x; copper_bad_cycle_start = get_cycles(); @@ -11833,12 +11835,13 @@ static void hsync_handlerh(bool onvsync) static void set_hpos(void) { + line_start_cycles = get_cycles(); maxhposeven_prev = maxhposeven; maxhpos = maxhpos_short + lol; maxhposm1 = maxhpos - 1; maxhposeven = (maxhpos & 1) == 0; - eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME; - eventtab[ev_hsync].oldcycles = get_cycles(); + eventtab[ev_hsync].evtime = line_start_cycles + HSYNCTIME; + eventtab[ev_hsync].oldcycles = line_start_cycles; #ifdef DEBUGGER if (debug_dma) { record_dma_hsync(maxhpos); diff --git a/include/custom.h b/include/custom.h index 0302ff27..9a7c9b63 100644 --- a/include/custom.h +++ b/include/custom.h @@ -252,7 +252,7 @@ struct customhack { }; extern void alloc_cycle_ext(int, int); extern bool alloc_cycle_blitter(int hpos, uaecptr *ptr, int, int); -extern uaecptr alloc_cycle_blitter_conflict_or(void); +extern uaecptr alloc_cycle_blitter_conflict_or(int); extern bool ispal(int *lines); extern bool isvga(void); extern int current_maxvpos(void); -- 2.47.3