* Custom chip emulation
*
* (c) 1995 Bernd Schmidt, Alessandro Bissacco
-* (c) 2002 - 2005 Toni Wilen
+* (c) 2002 - 2021 Toni Wilen
*/
#define SPEEDUP 1
#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) {
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);
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);
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)
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)
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();
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;
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;
}
}
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];
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) {
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;
}
}
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;
}
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);
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) {
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);
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 ();
}
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);
#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;
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;
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;
}
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);
}
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);
}
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;
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
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
else
reg |= 1;
record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_CPU, 1);
- checknasty (hpos, vpos);
}
peekdma_data.mask = 0;
#endif
else
reg |= 1;
record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_CPU, 1);
- checknasty (hpos, vpos);
}
peekdma_data.mask = 0;
#endif
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;
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(" "));
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;
}
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)