]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Copper waiting, CPU COPJMPx write and blitter active bug accurate implementation
authorToni Wilen <twilen@winuae.net>
Sat, 19 Nov 2022 17:41:49 +0000 (19:41 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 19 Nov 2022 17:41:49 +0000 (19:41 +0200)
blitter.cpp
custom.cpp
include/custom.h

index c1311120b7a4ba9911df84fb410674d80a833c4e..da5b6f92a7a92517a2aa55bab643b78baa0cb0f0 100644 (file)
@@ -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);
index 7c2ba2153143317cf23bd65e9b8fe99145358dac..a3fa4f73deef6f79012d2b47836f155b3dce999c 100644 (file)
@@ -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);
index 0302ff27fc35cdd6c38213f3ca73789dfd29b0f3..9a7c9b63520d0dbdcb2f185a221c86a4f4c6e7ab 100644 (file)
@@ -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);