From 81df2f07f4ee17876a5b5769996dd3796527aac0 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 2 Jan 2021 16:52:43 +0200 Subject: [PATCH] Blitter/copper fixes/updates. --- blitter.cpp | 116 ++++++++++++++++++++++++---------------------------- custom.cpp | 50 ++++++++++++++-------- debug.cpp | 68 +++++++++++++++++++++++++----- 3 files changed, 143 insertions(+), 91 deletions(-) diff --git a/blitter.cpp b/blitter.cpp index 3c6cb287..cddcc334 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -4,7 +4,7 @@ * Custom chip emulation * * (c) 1995 Bernd Schmidt, Alessandro Bissacco -* (c) 2002 - 2005 Toni Wilen +* (c) 2002 - 2021 Toni Wilen */ #define SPEEDUP 1 @@ -267,9 +267,16 @@ static void record_dma_blit(uae_u16 reg, uae_u16 v, uae_u32 addr, int hpos) #ifdef DEBUGGER if (debug_dma) { if (reg == 0) { - record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_BLITTER, blitline ? 2 : (blitfill ? 1 : 0)); + record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_BLITTER, 3 + (blitline ? 0x20 : (blitfill ? 0x10 : 0))); } else { - record_dma_read(reg, addr, hpos, vpos, DMARECORD_BLITTER, blitline ? 2 : (blitfill ? 1 : 0)); + int r = 0; + if (reg == 0x70) + r = 2; + if (reg == 0x72) + r = 1; + if (reg == 0x74) + r = 0; + record_dma_read(reg, addr, hpos, vpos, DMARECORD_BLITTER, r + (blitline ? 0x20 : (blitfill ? 0x10 : 0))); } } if (memwatch_enabled) { @@ -417,7 +424,7 @@ static void blitter_interrupt(int hpos, int done) if (!done && (!blitter_cycle_exact || immediate_blits || currprefs.cpu_model >= 68030 || currprefs.cachesize || currprefs.m68k_speed < 0)) return; blt_info.blit_interrupt = 1; - send_interrupt (6, 4 * CYCLE_UNIT); + send_interrupt (6, (4 + 1) * CYCLE_UNIT); if (debug_dma) record_dma_event (DMA_EVENT_BLITIRQ, hpos, vpos); blitter_done_notify(hpos); @@ -426,6 +433,11 @@ static void blitter_interrupt(int hpos, int done) static void blitter_done (int hpos) { ddat1use = 0; + if (blt_info.blit_finald) { + if (debug_dma) + record_dma_event(DMA_EVENT_BLITFINALD, hpos, vpos); + } + blt_info.blit_finald = 0; blitter_interrupt (hpos, 1); blitter_done_notify (hpos); event2_remevent (ev2_blitter); @@ -722,14 +734,6 @@ static void blitter_line (void) static void blitter_line_proc (void) { - if (bltcon0 & 0x800) { - if (blitsign) - bltapt += (uae_s16)blt_info.bltbmod; - else - bltapt += (uae_s16)blt_info.bltamod; - } - blitsign = 0 > (uae_s16)bltapt; - if (!blitsign) { if (bltcon1 & 0x10) { if (bltcon1 & 0x8) @@ -755,12 +759,18 @@ static void blitter_line_proc (void) blitter_line_incy(); } + if (bltcon0 & 0x800) { + if (blitsign) + bltapt += (uae_s16)blt_info.bltbmod; + else + bltapt += (uae_s16)blt_info.bltamod; + } + blitsign = 0 > (uae_s16)bltapt; } static void blitter_nxline (void) { blineb = (blineb << 1) | (blineb >> 15); - blt_info.vblitsize--; } static void actually_do_blit (void) @@ -776,6 +786,7 @@ static void actually_do_blit (void) blitter_line(); blitter_line_proc(); blitter_nxline(); + blt_info.vblitsize--; if (blitlinepixel) { record_dma_blit(0x00, blt_info.bltddat, bltdpt, last_blitter_hpos); blitter_write(); @@ -944,15 +955,18 @@ static int get_current_channel(void) if (blitline) { if (shifter[0]) { + // A or idle if (blitter_hcounter + 1 == blt_info.hblitsize) return 5; if (bltcon0 & 0x800) return 1; return 0; } + // B if (shifter[1] && (bltcon0 & 0x400)) { return 2; } + // C or D if (shifter[2] && (bltcon0 & 0x200)) { if (blitter_hcounter + 1 == blt_info.hblitsize) return 4; @@ -978,8 +992,13 @@ static int get_current_channel(void) return 2; } // D only if A, B and C is not currently active - if (shifter_out) { - if ((bltcon0 & 0x100) && ddat1use) { + if (ddat1use) { + // if stage 3 and C disabled and D enabled: D + if (shifter[2] && !(bltcon0 & 0x200) && (bltcon0 & 0x100)) { + return 4; + } + // if stage 4 and C enabled and D enabled: D + if (shifter[3] && (bltcon0 & 0x200) && (bltcon0 & 0x100)) { return 4; } } @@ -1006,7 +1025,7 @@ static uae_u16 blitter_doblit (void) ddat = blit_func (blitahold, blt_info.bltbhold, blt_info.bltcdat, mt) & 0xFFFF; - if ((bltcon1 & 0x18)) { + if (blitfill) { uae_u16 d = ddat; int ifemode = blitife ? 2 : 0; int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; @@ -1097,6 +1116,7 @@ static void blitter_doddma_new(int hpos) record_dma_blit(0x00, ddat1, bltdpt, hpos); chipmem_agnus_wput2 (bltdpt, ddat1); alloc_cycle_blitter (hpos, &bltdpt, 4); + if (!blitline) { bltdpt += blit_add; if (blitter_hcounter == 0) { @@ -1241,14 +1261,16 @@ bool decide_blitter_maybe_write(int hpos, uaecptr addr, uae_u16 value) for (;;) { int v = canblit(last_blitter_hpos); + // final D idle cycle + // does not need free bus if (blt_info.blit_finald > 1) { blt_info.blit_finald--; } // copper bltsize write needs one cycle (any cycle) delay + // does not need free bus if (blit_waitcyclecounter) { blit_waitcyclecounter = 0; - markidlecycle(last_blitter_hpos); break; } @@ -1258,9 +1280,9 @@ bool decide_blitter_maybe_write(int hpos, uaecptr addr, uae_u16 value) } if (blt_info.blit_finald == 1) { - blt_info.blit_finald = 0; + // final D write blitter_doddma_new(last_blitter_hpos); - blitter_done(hpos); + blitter_done(last_blitter_hpos); break; } @@ -1277,16 +1299,11 @@ bool decide_blitter_maybe_write(int hpos, uaecptr addr, uae_u16 value) written = decide_blitter_idle(last_blitter_hpos, hpos, addr, value); - } else if (c == 1 && blitline) { // line 1 (A, free) - - if (blitsign) - bltapt += (uae_s16)blt_info.bltbmod; - else - bltapt += (uae_s16)blt_info.bltamod; + } else if (c == 1 && blitline) { // line 1/4 (A, free) written = decide_blitter_idle(last_blitter_hpos, hpos, addr, value); - } else if (c == 3 && blitline) { // line 2 (C) + } else if (c == 3 && blitline) { // line 2/4 (C) record_dma_blit(0x70, 0, bltcpt, last_blitter_hpos); blt_info.bltcdat = chipmem_wget_indirect(bltcpt); @@ -1294,47 +1311,20 @@ bool decide_blitter_maybe_write(int hpos, uaecptr addr, uae_u16 value) record_dma_blit_val(blt_info.bltcdat); alloc_cycle_blitter(last_blitter_hpos, &bltcpt, 3); - blitter_line(); - - if (!blitsign) { - if (bltcon1 & 0x10) { - if (bltcon1 & 0x8) - blitter_line_decy(); - else - blitter_line_incy(); - } - } - if (!(bltcon1 & 0x10)) { - if (bltcon1 & 0x4) - blitter_line_decy(); - else - blitter_line_incy(); - } + } else if (c == 5 && blitline) { // line 3/4 (free) - blitsign = 0 > (uae_s16)bltapt; - - blineb = (blineb << 1) | (blineb >> 15); + blitter_line(); - } else if (c == 5 && blitline) { // line 3 (free) + written = decide_blitter_idle(last_blitter_hpos, hpos, addr, value); - if (!blitsign) { - if (!(bltcon1 & 0x10)) { - if (bltcon1 & 0x8) - blitter_line_decx(); - else - blitter_line_incx(); - } - } - if (bltcon1 & 0x10) { - if (bltcon1 & 0x4) - blitter_line_decx(); - else - blitter_line_incx(); - } + } else if (c == 4 && blitline) { // line 4/4 (D) - written = decide_blitter_idle(last_blitter_hpos, hpos, addr, value); + if (ddat1use) + bltdpt = bltcpt; + ddat1use = 1; - } else if (c == 4 && blitline) { // line 4 (D) + blitter_line_proc(); + blitter_nxline(); /* onedot mode and no pixel = bus write access is skipped */ if (blitlinepixel) { @@ -1423,7 +1413,7 @@ void reset_blit (int bltcon) blinea_shift = bltcon0 >> 12; if (bltcon & 2) blitsign = bltcon1 & 0x40; - if (!blt_info.blit_main) + if (!blt_info.blit_main && !blt_info.blit_finald) return; if (bltcon) blit_bltset (bltcon); diff --git a/custom.cpp b/custom.cpp index 46325ddd..00503f70 100644 --- a/custom.cpp +++ b/custom.cpp @@ -5724,7 +5724,7 @@ static void DMACON (int hpos, uae_u16 v) if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && (blt_info.blit_main || blt_info.blit_finald)) set_special (SPCFLAG_BLTNASTY); - if (dmaen (DMA_BLITTER) && (blt_info.blit_pending || blt_info.blit_main || blt_info.blit_finald)) { + if (dmaen (DMA_BLITTER) && blt_info.blit_pending) { blitter_check_start (); } @@ -7364,12 +7364,13 @@ static void update_copper (int until_hpos) cop_state.state = COP_wait_in2; } else { // MOVE + unsigned int reg = cop_state.i1 & 0x1FE; #ifdef DEBUGGER if (debug_dma) { - record_dma_read(0x8c, cop_state.ip - 2, old_hpos, vpos, DMARECORD_COPPER, 0); + record_dma_read(reg, cop_state.ip, old_hpos, vpos, DMARECORD_COPPER, 0); } if (memwatch_enabled) { - debug_getpeekdma_chipram(cop_state.ip - 2, MW_MASK_COPPER, 0x8c, cop_state.last_strobe == 2 ? 0x84 : 0x80); + debug_getpeekdma_chipram(cop_state.ip, MW_MASK_COPPER, 0x8c, cop_state.last_strobe == 2 ? 0x84 : 0x80); } #endif cop_state.i2 = chipmem_wget_indirect(cop_state.ip); @@ -7390,7 +7391,6 @@ static void update_copper (int until_hpos) #ifdef DEBUGGER uaecptr debugip = cop_state.ip; #endif - unsigned int reg = cop_state.i1 & 0x1FE; uae_u16 data = cop_state.i2; cop_state.state = COP_read1; @@ -7398,8 +7398,9 @@ static void update_copper (int until_hpos) if (! copper_enabled_thisline) goto out; // was "dangerous" register -> copper stopped - if (cop_state.ignore_next) + if (cop_state.ignore_next) { reg = 0x1fe; + } if (reg == 0x88) { cop_state.strobe = 1; @@ -7596,10 +7597,31 @@ void blitter_done_notify (int hpos) if (cop_state.state != COP_bltwait) return; + cop_state.state = COP_wait; + int hp = current_hpos(); + hp += 3; + hp &= ~1; int vp_wait = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); int vp = vpos; + if (hpos >= maxhpos) { + hpos -= maxhpos; + vp++; + } + last_copper_hpos = hp; + cop_state.hpos = hp; + cop_state.vpos = vp; + if (dmaen(DMA_COPPER) && vp_wait >= cop_state.vcmp) { + copper_enabled_thisline = 1; + set_special(SPCFLAG_COPPER); + } else { + unset_special(SPCFLAG_COPPER); + } + return; + + vp_wait = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + vp = vpos; - hpos++; + hpos += 1; hpos &= ~1; if (hpos >= maxhpos) { hpos -= maxhpos; @@ -11724,11 +11746,15 @@ static int dma_cycle(uaecptr addr, uae_u16 v, int *mode) } break; } +#if 0 + decide_blitter(hpos); +#else // CPU write must be done at the same time with blitter idle cycles if (decide_blitter_maybe_write(hpos, addr, v)) { // inform caller that write was already done *mode = -2; } +#endif // copper may have been waiting for the blitter sync_copper (hpos); } @@ -11736,7 +11762,7 @@ static int dma_cycle(uaecptr addr, uae_u16 v, int *mode) alloc_cycle (hpos_old, CYCLE_CPU); break; } - if (debug_dma && blt_info.nasty_cnt >= BLIT_NASTY_CPU_STEAL_CYCLE_COUNT) { + if (debug_dma && !blitpri && blt_info.nasty_cnt >= BLIT_NASTY_CPU_STEAL_CYCLE_COUNT) { record_dma_event(DMA_EVENT_CPUBLITTERSTEAL, hpos_old, vpos); } @@ -11748,12 +11774,6 @@ static int dma_cycle(uaecptr addr, uae_u16 v, int *mode) return hpos_old; } -STATIC_INLINE void checknasty (int hpos, int vpos) -{ - if (blt_info.blitter_nasty >= BLIT_NASTY_CPU_STEAL_CYCLE_COUNT && !(dmacon & DMA_BLITPRI)) - record_dma_event (DMA_EVENT_BLITNASTY, hpos, vpos); -} - static void sync_ce020 (void) { unsigned long c; @@ -11789,7 +11809,6 @@ uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode) else reg |= 1; record_dma_read(reg, addr, hpos, vpos, DMARECORD_CPU, mode == -2 || mode == 2 ? 0 : 1); - checknasty (hpos, vpos); } peekdma_data.mask = 0; #endif @@ -11845,7 +11864,6 @@ uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode) else reg |= 1; record_dma_read(reg, addr, hpos, vpos, DMARECORD_CPU, mode == -2 || mode == 2 ? 0 : 1); - checknasty (hpos, vpos); } peekdma_data.mask = 0; #endif @@ -11897,7 +11915,6 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v) else reg |= 1; record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_CPU, 1); - checknasty (hpos, vpos); } peekdma_data.mask = 0; #endif @@ -11935,7 +11952,6 @@ void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v) else reg |= 1; record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_CPU, 1); - checknasty (hpos, vpos); } peekdma_data.mask = 0; #endif diff --git a/debug.cpp b/debug.cpp index 63c879de..2cc43e98 100644 --- a/debug.cpp +++ b/debug.cpp @@ -1899,7 +1899,10 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, uae_u32 bool longsize = false; bool got = false; int r = dr->reg; + int regsize = 3; const TCHAR *sr; + int br = dr->extra & 7; + int chcnt = -1; if (l1) l1[0] = 0; @@ -1922,19 +1925,52 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, uae_u32 else sr = _T("COP "); } else if (dr->type == DMARECORD_BLITTER) { - if (dr->extra == 2) - sr = _T("BLL "); - else - sr = _T("BLT "); + if (dr->extra & 0x20) { + if (br == 0) + sr = _T("BLL-A"); + if (br == 1) + sr = _T("BLL-B"); + if (br == 2) + sr = _T("BLL-C"); + if (br == 3) + sr = _T("BLL-D"); + } else if (dr->extra & 0x10) { + if (br == 0) + sr = _T("BLF-A"); + if (br == 1) + sr = _T("BLF-B"); + if (br == 2) + sr = _T("BLF-C"); + if (br == 3) + sr = _T("BLF-D"); + } else { + if (br == 0) + sr = _T("BLT-A"); + if (br == 1) + sr = _T("BLT-B"); + if (br == 2) + sr = _T("BLT-C"); + if (br == 3) + sr = _T("BLT-D"); + } + regsize = 2; } else if (dr->type == DMARECORD_REFRESH) { - sr = _T("RFS "); + sr = _T("RFS"); + chcnt = br; } else if (dr->type == DMARECORD_AUDIO) { - sr = _T("AUD "); + sr = _T("AUD"); + chcnt = br; } else if (dr->type == DMARECORD_DISK) { - sr = _T("DSK "); + sr = _T("DSK"); + chcnt = br; } else if (dr->type == DMARECORD_SPRITE) { - sr = _T("SPR "); + sr = _T("SPR"); + chcnt = br; + } else if (dr->type == DMARECORD_BITPLANE) { + sr = _T("BPL"); + chcnt = br; } + _stprintf (l1, _T("[%02X %3d]"), hpos, hpos); if (l4) { _tcscpy (l4, _T(" ")); @@ -1954,7 +1990,17 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, uae_u32 if ((r & 0xff) == 1) l2[5] = 'B'; } else { - _stprintf (l2, _T("%4s %03X"), sr, r); + if (chcnt >= 0) { + if (regsize == 3) + _stprintf(l2, _T("%3s%d %03X"), sr, chcnt, r); + else + _stprintf(l2, _T("%4s%d %02X"), sr, chcnt, r); + } else { + if (regsize == 3) + _stprintf(l2, _T("%4s %03X"), sr, r); + else + _stprintf(l2, _T("%5s %02X"), sr, r); + } } if (l3) { uae_u32 v = dr->dat; @@ -1972,8 +2018,8 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, uae_u32 } if (l3) { int cl2 = 0; - if (dr->evt & DMA_EVENT_BLITNASTY) - l3[cl2++] = 'N'; + if (dr->evt & DMA_EVENT_BLITFINALD) + l3[cl2++] = 'D'; if (dr->evt & DMA_EVENT_BLITSTARTFINISH) l3[cl2++] = 'B'; if (dr->evt & DMA_EVENT_CPUBLITTERSTEAL) -- 2.47.3