From 98cd53c482533248887707837307493a8087fc23 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 30 Apr 2026 18:53:40 +0300 Subject: [PATCH] Implemented missing A1200/A4000 mainboard non-nasty blitter busy bug workaround. --- blitter.cpp | 28 ++++++++++++++++------------ custom.cpp | 18 +++++++++++++----- include/blitter.h | 6 ++++-- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/blitter.cpp b/blitter.cpp index 9b5b40aa..19480c5b 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -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); diff --git a/custom.cpp b/custom.cpp index d2060ad9..416f697e 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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 diff --git a/include/blitter.h b/include/blitter.h index ea61d367..9b208fed 100644 --- a/include/blitter.h +++ b/include/blitter.h @@ -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; -- 2.47.3