]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Implemented missing A1200/A4000 mainboard non-nasty blitter busy bug workaround.
authorToni Wilen <twilen@winuae.net>
Thu, 30 Apr 2026 15:53:40 +0000 (18:53 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 30 Apr 2026 15:53:40 +0000 (18:53 +0300)
blitter.cpp
custom.cpp
include/blitter.h

index 9b5b40aa9240c47568c00f44e9cd2c873317ea7d..19480c5bbf3b1be6da49628946bce08cfc9a369d 100644 (file)
@@ -37,7 +37,7 @@ static uae_u32 blit_tracer[2 * 10000000];
 // 32 = logging (no line)
 
 #if BLITTER_DEBUG
-int log_blitter = 1 | 16;
+int log_blitter = 1 | 2 | 16;
 #else
 int log_blitter = 0;
 #endif
@@ -427,7 +427,8 @@ static void blitter_interrupt(void)
        if (blt_info.blit_interrupt) {
                return;
        }
-       blt_info.blit_interrupt = 1;
+       blt_info.blit_interrupt = true;
+       blt_info.blit_interrupt_trigger = true;
        INTREQ_INT(6, 3);
 }
 
@@ -439,11 +440,8 @@ static void blitter_end(void)
        unset_special(SPCFLAG_BLTNASTY);
 #if BLITTER_DEBUG
        if (log_blitter & 1) {
-
-               if (blt_info.vblitsize > 100) {
-                       blitter_dump();
-               }
-
+               write_log(_T("blitter end:\n"));
+               blitter_dump();
                write_log(_T("cycles %d, missed %d, total %d\n"),
                        blit_totalcyclecounter, blit_misscyclecounter, blit_totalcyclecounter + blit_misscyclecounter);
 
@@ -1736,7 +1734,6 @@ void generate_blitter(void)
                }
        }
 
-
        if (!blt_info.blit_count_done) {
                blt_info.blit_queued = BLITTER_MAX_PIPELINED_CYCLES;
        }
@@ -2006,7 +2003,8 @@ static void blitter_start_init(void)
        blit_bltset(1 | 2);
        blitter_delayed_update = true;
        maybe_load_mods();
-       blt_info.blit_interrupt = 0;
+       blt_info.blit_interrupt = false;
+       blt_info.blit_interrupt_trigger = false;
 
        blt_info.bltaold = 0;
        blt_info.bltbold = 0;
@@ -2032,6 +2030,10 @@ void do_blitter(int copper, uaecptr pc)
                if (blt_info.blit_main) {
                        write_log (_T("blitter was already active! PC=%08x\n"), M68K_GETPC);
                }
+               if (shifter_d_armed || shifter[0] || shifter[1] || shifter[2] || shifter[3] ||
+                       shifter_d1 || shifter_d_aga) {
+                       write_log(_T("blitter was already active! PC=%08x\n"), M68K_GETPC);
+               }
        }
 #endif
 
@@ -2338,7 +2340,7 @@ void restore_blitter_finish(void)
        blitter_cycle_exact = currprefs.blitter_cycle_exact;
        immediate_blits = currprefs.immediate_blits;
        if (blt_statefile_type == 0) {
-               blt_info.blit_interrupt = 1;
+               blt_info.blit_interrupt = true;
                if (blt_info.blit_pending) {
                        write_log (_T("blitter was started but DMA was inactive during save\n"));
                        //do_blitter (0);
@@ -2483,7 +2485,9 @@ uae_u8 *restore_blitter_new(uae_u8 *src)
        tmp = restore_u8();
        blitlinepixel = (tmp & 1) != 0;
        blitlineloop = (tmp & 2) != 0;
-       blt_info.blit_interrupt = restore_u8();
+       tmp = restore_u8();
+       blt_info.blit_interrupt = (tmp & 1) != 0;
+       blt_info.blit_interrupt_trigger = (tmp & 2) != 0;
        blt_delayed_irq = restore_u8();
        blt_info.blitzero = restore_u8();
        blt_info.got_cycle = restore_u8();
@@ -2674,7 +2678,7 @@ uae_u8 *save_blitter_new(size_t *len, uae_u8 *dstptr)
        save_u8(blitlinepixel);
        save_u8((blt_info.bltcon1 & BLTSING) != 0);
        save_u8((blitlinepixel ? 1 : 0) | (blitlineloop ? 2 : 0));
-       save_u8(blt_info.blit_interrupt);
+       save_u8((blt_info.blit_interrupt ? 1 : 0) | (blt_info.blit_interrupt_trigger ? 2 : 0));
        save_u8(blt_delayed_irq);
        save_u8(blt_info.blitzero);
        save_u8(blt_info.got_cycle);
index d2060ad998f4bd23b551ab3f5a063369ce471e23..416f697e0b14b04df5f1885790e92ed2d40d1468 100644 (file)
@@ -6788,7 +6788,8 @@ void custom_reset(bool hardreset, bool keyboardreset)
                beamcon0 = new_beamcon0 = beamcon0_saved = currprefs.ntscmode ? 0x00 : BEAMCON0_PAL;
                blt_info.blit_main = 0;
                blt_info.blit_pending = 0;
-               blt_info.blit_interrupt = 1;
+               blt_info.blit_interrupt = true;
+               blt_info.blit_interrupt_trigger = false;
                blt_info.blit_queued = 0;
                //init_sprites();
 
@@ -12160,6 +12161,7 @@ int do_cycles_cck(int cycles)
 extern int cpu_tracer;
 static void dma_cycle(int *ipl)
 {
+       blt_info.blit_interrupt_trigger = false;
        if (cpu_tracer < 0) {
                return;
        }
@@ -12205,7 +12207,7 @@ uae_u32 wait_cpu_cycle_read(uaecptr addr, int mode)
 
        x_do_cycles_pre(CYCLE_UNIT);
 
-       blt_info.nasty_cnt = 0;
+       blt_info.nasty_cnt = blt_info.blit_interrupt_trigger && aga_mode ? -0x7fffffff : 0;
        dma_cycle(&ipl);
 
 #ifdef DEBUGGER
@@ -12278,7 +12280,7 @@ void wait_cpu_cycle_write(uaecptr addr, int mode, uae_u32 v)
 
        x_do_cycles_pre(CYCLE_UNIT);
 
-       blt_info.nasty_cnt = 0;
+       blt_info.nasty_cnt = blt_info.blit_interrupt_trigger && aga_mode ? -0x7fffffff : 0;
        dma_cycle(&ipl);
 
 #ifdef DEBUGGER
@@ -12329,7 +12331,13 @@ uae_u32 wait_cpu_cycle_read_ce020(uaecptr addr, int mode)
 
        x_do_cycles_pre(CYCLE_UNIT);
 
-       blt_info.nasty_cnt = 1;
+       // Nasty Alice bug, A1200 and A4000 mainboard have a hack that disables Gayle/Gary BLS signal
+       // if Alice INT3 output (blitter finished) is active for next chip bus cycle to allow blitter
+       // to use next free cycle which normally could be stolen by the CPU.
+       // This hack is needed because otherwise CPU could steal many cycles from the blitter after
+       // blitter busy bit has cleared but final D write has not yet completed in FMODE=0 + 7 planes lores
+       // screen mode.
+       blt_info.nasty_cnt = blt_info.blit_interrupt_trigger ? -0x7fffffff : 0;
        dma_cycle(&ipl);
 
 #ifdef DEBUGGER
@@ -12386,7 +12394,7 @@ void wait_cpu_cycle_write_ce020(uaecptr addr, int mode, uae_u32 v)
 
        x_do_cycles_pre(CYCLE_UNIT);
 
-       blt_info.nasty_cnt = 1;
+       blt_info.nasty_cnt = blt_info.blit_interrupt_trigger ? -0x7fffffff : 0;
        dma_cycle(&ipl);
 
 #ifdef DEBUGGER
index ea61d367b3b2419372cde27419dbb250c53cb658..9b208fed7cb322bf680cba171eced53037942cc9 100644 (file)
@@ -24,8 +24,10 @@ struct bltinfo {
     uae_u16 bltsize;
     uae_u16 bltcon0, bltcon1;
     int got_cycle;
-    uae_u32 nasty_cnt, wait_nasty;
-    int blitter_nasty, blit_interrupt;
+    uae_s32 nasty_cnt, wait_nasty;
+    int blitter_nasty;
+    bool blit_interrupt;
+    bool blit_interrupt_trigger;
     int blit_main, blit_pending, blit_count_done;
     int blit_queued;
     evt_t finishcycle_dmacon, finishcycle_copper;