static bool shifter_skip_b_old, shifter_skip_y_old;
static uae_u16 bltcon0_old, bltcon1_old;
static bool shifter[4], shifter_out, shifter_first;
+static bool blitline_c, blitfill_c;
static int blitter_delayed_debug;
#ifdef BLITTER_SLOWDOWNDEBUG
static int blit_cyclecounter, blit_waitcyclecounter;
static int blit_maxcyclecounter, blit_slowdown, blit_totalcyclecounter;
static int blit_misscyclecounter;
+static int blit_copperstarted;
#ifdef CPUEMU_13
static int blitter_cyclecounter;
static int blt_delayed_irq;
static uae_u16 ddat1;
static int ddat1use, ddat2use;
+static int blit_dof;
static int last_blitter_hpos;
#ifdef DEBUGGER
if (debug_dma && blitter_cycle_exact) {
if (reg == 0) {
- record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_BLITTER, 3 + (blitline ? 0x20 : (blitfill ? 0x10 : 0)));
+ record_dma_write(reg, v, addr, hpos, vpos, DMARECORD_BLITTER, 3 + (blitline_c ? 0x20 : (blitfill_c ? 0x10 : 0)));
} else {
int r = 0;
if (reg == 0x70)
r = 1;
if (reg == 0x74)
r = 0;
- record_dma_read(reg, addr, hpos, vpos, DMARECORD_BLITTER, r + (blitline ? 0x20 : (blitfill ? 0x10 : 0)));
+ record_dma_read(reg, addr, hpos, vpos, DMARECORD_BLITTER, r + (blitline_c ? 0x20 : (blitfill_c ? 0x10 : 0)));
}
}
if (memwatch_enabled) {
if (reg == 0) {
uae_u32 mask = MW_MASK_BLITTER_D_N;
- if (blitfill)
+ if (blitfill_c)
mask = MW_MASK_BLITTER_D_F;
- if (blitline)
+ if (blitline_c)
mask = MW_MASK_BLITTER_D_L;
debug_putpeekdma_chipram(addr, v, mask, reg, 0x054);
} else if (reg == 0x70) {
// (or cycle where last D write would have been if
// ONEDOT was active)
-static bool blitter_interrupt(int done)
+static void blitter_interrupt(void)
{
- blt_info.blit_main = 0;
if (blt_info.blit_interrupt) {
- return false;
- }
- if (!done && (!blitter_cycle_exact || immediate_blits || currprefs.cpu_model >= 68030 || currprefs.cachesize || currprefs.m68k_speed < 0)) {
- return false;
+ return;
}
blt_info.blit_interrupt = 1;
send_interrupt(6, (4 + 1) * CYCLE_UNIT);
if (debug_dma) {
record_dma_event(DMA_EVENT_BLITIRQ, current_hpos(), vpos);
}
- blitter_done_notify(blitline);
- return true;
}
-static void blitter_done(void)
+static void blitter_end(void)
{
+ blt_info.blit_main = 0;
blt_info.blit_finald = 0;
- if (!blitter_interrupt(1)) {
- blitter_done_notify(blitline);
- }
+ blt_info.blit_queued = 0;
event2_remevent(ev2_blitter);
unset_special(SPCFLAG_BLTNASTY);
if (log_blitter & 1) {
blt_info.blitter_dangerous_bpl = 0;
}
+static void blitter_done_all(void)
+{
+ blt_info.blit_main = 0;
+ blt_info.blit_finald = 0;
+ blitter_interrupt();
+ blitter_done_notify(blitline);
+ if (!blt_info.blit_queued && !blt_info.blit_finald) {
+ blitter_end();
+ }
+}
+
static void blitter_done_except_d(void)
{
- blitter_interrupt(1);
+ blt_info.blit_main = 0;
+ blitter_interrupt();
+ blitter_done_notify(blitline);
}
+
STATIC_INLINE void chipmem_agnus_wput2 (uaecptr addr, uae_u32 w)
{
if (!(log_blitter & 4)) {
- debug_putpeekdma_chipram(addr, w, MW_MASK_BLITTER_D_N, 0x000, 0x054);
- chipmem_wput_indirect (addr, w);
+ if (!blit_dof) {
+ debug_putpeekdma_chipram(addr, w, MW_MASK_BLITTER_D_N, 0x000, 0x054);
+ chipmem_wput_indirect(addr, w);
+ }
last_custom_value1 = w;
}
}
static void blitter_doit (void)
{
if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) {
- blitter_done();
+ blitter_done_all();
return;
}
actually_do_blit();
- blitter_done();
+ blitter_done_all();
}
static int makebliteventtime(int delay)
if ((bltcon1 & 1) && !blitline_started) {
write_log(_T("BLITTER: linedraw enabled when blitter is active! %08x\n"), M68K_GETPC);
blit_warned--;
+ //activate_debugger();
} else if (!(bltcon1 & 1) && blitline_started) {
write_log(_T("BLITTER: linedraw disabled when blitter is active! %08x\n"), M68K_GETPC);
blit_warned--;
+ //activate_debugger();
}
if ((bltcon1 & 0x18) && !(bltcon1_old & 0x18)) {
write_log(_T("BLITTER: fill enabled when blitter is active! %08x\n"), M68K_GETPC);
blit_warned--;
+ //activate_debugger();
} else if (!(bltcon1 & 0x18) && (bltcon1_old & 0x18)) {
write_log(_T("BLITTER: fill disabled when blitter is active! %08x\n"), M68K_GETPC);
blit_warned--;
+ //activate_debugger();
}
}
}
blit_dmacount = ((bltcon0 & 0x800) ? 1 : 0) + ((bltcon0 & 0x400) ? 1 : 0) +
((bltcon0 & 0x200) ? 1 : 0) + ((bltcon0 & 0x100) ? 1 : 0);
+ if (blt_info.blit_main || blt_info.blit_pending) {
+ blitfill_c = blitfill;
+ blitline_c = blitline;
+ }
+
+ blit_dof = 0;
if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
+ blit_dof = 1;
debugtest(DEBUGTEST_BLITTER, _T("ECS BLTCON1 DOFF-bit set\n"));
if (log_blitter & 16)
activate_debugger();
#define BLITTER_PIPELINE_LINE 0x0020
#define BLITTER_PIPELINE_PROCESS 0x0200
#define BLITTER_PIPELINE_FINISHED 0x0400
-#define BLITTER_PIPELINE_LASTDTODO 0x0800
#define BLITTER_PIPELINE_LASTD 0x1000
#define BLITTER_PIPELINE_FIRST 0x2000
#define BLITTER_PIPELINE_LAST 0x4000
}
}
blitter_hcounter++;
- if (blitter_hcounter == blt_info.hblitsize) {
+ if (blitter_hcounter >= blt_info.hblitsize) {
blitter_hcounter = 0;
blitter_vcounter++;
- if (blitter_vcounter == blt_info.vblitsize) {
+ if (blitter_vcounter >= blt_info.vblitsize) {
shifter_out = false;
blit_cyclecounter = CYCLECOUNT_FINISHED;
if (!blitline) {
if (!blitline) {
bltdpt += blit_add;
- if (addmod) {
- bltdpt += blit_modaddd;
- }
+ }
+ if (addmod) {
+ bltdpt += blit_modaddd;
}
}
while (hpos < until_hpos) {
- bool cycle_allocated = false;
// dma transfers and processing
for (;;) {
- if (blt_info.blit_queued > 0) {
+ if (!cycle_line_slot[hpos] && blt_info.blit_queued > 0) {
blt_info.blit_queued--;
+ if (!blt_info.blit_queued && !blt_info.blit_finald) {
+ blitter_end();
+ }
}
uae_u16 dat = blitter_pipe[hpos];
if (dat) {
// last D write?
if (dat & BLITTER_PIPELINE_LASTD) {
+ line = false;
if (debug_dma) {
record_dma_event(DMA_EVENT_BLITFINALD, hpos, vpos);
}
if (cycle_line_slot[hpos]) {
write_log("Blitter cycle allocated by %d!?\n", cycle_line_slot[hpos]);
}
+ if (!blt_info.blit_main && !blt_info.blit_finald && !blt_info.blit_queued) {
+ blitter_end();
+ }
//activate_debugger();
}
if (blt_info.blit_finald || blt_info.blit_main) {
- blt_info.blit_queued++;
+ blt_info.blit_queued = BLITTER_MAX_PIPELINED_CYCLES;
// copper bltsize write needs one cycle (any cycle) delay
// does not need free bus
int offset = get_rga_pipeline(hpos, RGA_PIPELINE_OFFSET_BLITTER);
cycle_line_pipe[offset] = CYCLE_PIPE_BLITTER;
blitter_pipe[offset] = cycle_line_pipe[offset] | 4 | BLITTER_PIPELINE_ADDMOD | BLITTER_PIPELINE_LASTD;
- blitter_done();
+ if (currprefs.chipset_mask & CSMASK_AGA) {
+ blitter_done_all();
+ }
+ blt_info.blit_finald = 0;
+ if (!blt_info.blit_queued) {
+ blitter_end();
+ }
break;
}
}
// has final D write?
if (blt_info.blit_finald) {
- v |= BLITTER_PIPELINE_LASTDTODO;
- blitter_done_except_d();
+ if (!(currprefs.chipset_mask & CSMASK_AGA)) {
+ blitter_done_except_d();
+ }
} else {
- blitter_done();
+ blitter_done_all();
}
}
} else {
actually_do_blit();
}
- blitter_done();
+ blitter_done_all();
dmacon = odmacon;
}
blitter_hcounter = 0;
blitter_vcounter = 0;
blit_cyclecounter = -CYCLECOUNT_START;
+ blit_copperstarted = copper;
if (copper) {
- blit_waitcyclecounter = 2;
+ blit_waitcyclecounter = 0;
} else {
blit_waitcyclecounter = 0;
}
if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) {
if (dmaen(DMA_BLITTER)) {
- blitter_done();
+ blitter_done_all();
}
return;
}
tod_hack_enabled = TOD_HACK_TIME;
#endif
- kblostsynccnt = 0;
- serbits = 0;
- resetwarning_phase = resetwarning_timer = 0;
- heartbeat_cnt = 0;
- ciab_tod_event_state = 0;
-
- if (!savestate_state) {
- oldovl = true;
- kbstate = 0;
- ciaatlatch = ciabtlatch = 0;
- ciaapra = 0; ciaadra = 0;
- ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
- ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
- ciaacra = ciaacrb = ciabcra = ciabcrb = 0;
- ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
- ciaaalarm = ciabalarm = 0;
- ciabpra = 0x8C; ciabdra = 0;
- div10 = 0;
- ciaasdr_cnt = 0; ciaasdr = 0; ciaasdr_load = 0;
- ciabsdr_cnt = 0; ciabsdr = 0; ciabsdr_buf = 0; ciabsdr_load = 0;
- ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
- CIA_calctimers ();
- DISK_select_set (ciabprb);
- }
- map_overlay (0);
- check_led ();
+kblostsynccnt = 0;
+serbits = 0;
+resetwarning_phase = resetwarning_timer = 0;
+heartbeat_cnt = 0;
+ciab_tod_event_state = 0;
+
+if (!savestate_state) {
+ oldovl = true;
+ kbstate = 0;
+ ciaatlatch = ciabtlatch = 0;
+ ciaapra = 0; ciaadra = 0;
+ ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
+ ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
+ ciaacra = ciaacrb = ciabcra = ciabcrb = 0;
+ ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
+ ciaaalarm = ciabalarm = 0;
+ ciabpra = 0x8C; ciabdra = 0;
+ div10 = 0;
+ ciaasdr_cnt = 0; ciaasdr = 0; ciaasdr_load = 0;
+ ciabsdr_cnt = 0; ciabsdr = 0; ciabsdr_buf = 0; ciabsdr_load = 0;
+ ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
+ CIA_calctimers();
+ DISK_select_set(ciabprb);
+}
+map_overlay(0);
+check_led();
#ifdef SERIAL_PORT
- if (currprefs.use_serial && !savestate_state)
- serial_dtr_off (); /* Drop DTR at reset */
+if (currprefs.use_serial && !savestate_state)
+serial_dtr_off(); /* Drop DTR at reset */
#endif
- if (savestate_state) {
- if (currprefs.cs_ciaoverlay) {
- oldovl = true;
- }
- bfe001_change ();
- if (!currprefs.cs_ciaoverlay) {
- map_overlay (oldovl ? 0 : 1);
- }
+if (savestate_state) {
+ if (currprefs.cs_ciaoverlay) {
+ oldovl = true;
+ }
+ bfe001_change();
+ if (!currprefs.cs_ciaoverlay) {
+ map_overlay(oldovl ? 0 : 1);
}
}
+}
-void dumpcia (void)
+void dumpcia(void)
{
- console_out_f (_T("A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"),
+ console_out_f(_T("A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"),
ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb);
- console_out_f (_T("TOD %06x (%06x) ALARM %06x %c%c CYC=%08X\n"),
- ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', get_cycles ());
- console_out_f (_T("B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"),
+ console_out_f(_T("TOD %06x (%06x) ALARM %06x %c%c CYC=%08X\n"),
+ ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', get_cycles());
+ console_out_f(_T("B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n"),
ciabcra, ciabcrb, ciabicr, ciabimask, ciabta, ciabla, ciabtb, ciablb);
- console_out_f (_T("TOD %06x (%06x) ALARM %06x %c%c CLK=%d\n"),
+ console_out_f(_T("TOD %06x (%06x) ALARM %06x %c%c CLK=%d\n"),
ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 / CYCLE_UNIT);
}
ABFLAG_IO | ABFLAG_CIA, S_READ, S_WRITE, NULL, 0x3f01, 0xbfc000
};
-static void cia_wait_pre (int cianummask)
+static void cia_wait_pre(int cianummask)
{
if (currprefs.cachesize || currprefs.cpu_thread)
return;
}
#ifndef CUSTOM_SIMPLE
- int div = (get_cycles () - eventtab[ev_cia].oldcycles) % DIV10;
- int cycles;
-
- if (div >= DIV10 * ECLOCK_DATA_CYCLE / 10) {
- cycles = DIV10 - div;
- cycles += DIV10 * ECLOCK_DATA_CYCLE / 10;
- } else if (div) {
- cycles = DIV10 + DIV10 * ECLOCK_DATA_CYCLE / 10 - div;
- } else {
- cycles = DIV10 * ECLOCK_DATA_CYCLE / 10 - div;
- }
-
+ int div = get_cycles() % DIV10;
+ int cycles = DIV10 - div;
if (cycles) {
if (currprefs.cpu_memory_cycle_exact)
- x_do_cycles_pre (cycles);
+ x_do_cycles_pre(cycles);
else
- do_cycles (cycles);
+ do_cycles(cycles);
}
#endif
}
sprite_vblank_endline = minfirstline - 1;
+ if (firstblankedline < minfirstline) {
+ firstblankedline = maxvpos + 1;
+ }
+
if (beamcon0 & 0x80) {
// programmable scanrates (ECS Agnus)
if (vtotal >= MAXVPOS) {
vtotal = MAXVPOS - 1;
}
maxvpos = vtotal + 1;
- firstblankedline = maxvpos + 1;
if (htotal >= MAXHPOS) {
htotal = MAXHPOS - 1;
}
vblank_hz_lof = clk / ((maxvpos + 1) * maxhpos);
vblank_hz_lace = clk / ((maxvpos + 0.5) * maxhpos);
- if (firstblankedline < minfirstline) {
- firstblankedline = maxvpos + 1;
- }
-
maxvpos_nom = maxvpos;
maxvpos_display = maxvpos;
equ_vblank_endline = -1;
static bool blit_busy(void)
{
- if (!blt_info.blit_main && !blt_info.blit_finald)
+ if (!blt_info.blit_main && !blt_info.blit_finald) {
return false;
+ }
// AGA apparently fixes both bugs.
if (currprefs.cs_agnusbltbusybug) {
// Blitter busy bug: A1000 Agnus only sets busy-bit when blitter gets first DMA slot.
- if (!blt_info.got_cycle)
+ if (!blt_info.got_cycle) {
return false;
- if (blt_info.blit_pending)
+ }
+ if (blt_info.blit_pending) {
return true;
+ }
// Blitter is considered finished even if last D has not yet been written
- if (!blt_info.blit_main && blt_info.blit_finald < 2)
+ if (!blt_info.blit_main) {
return false;
+ }
} else if (!aga_mode) {
- if (blt_info.blit_pending)
+ if (blt_info.blit_pending) {
return true;
+ }
// Blitter is considered finished even if last D has not yet been written
- if (!blt_info.blit_main && blt_info.blit_finald < 2)
- return false;
-#if 0
- // Blitter busy bug: Blitter nasty off, CPU attempting to steal cycle, Copper started blitter,
- // Copper WAITing for blitter finished: busy is not set until CPU gets the cycle.
- // NOT CORRECT YET
- if (!(dmacon & DMA_BLITPRI) && blt_info.wait_nasty && blt_info.nasty_cnt >= BLIT_NASTY_CPU_STEAL_CYCLE_COUNT)
+ if (!blt_info.blit_main) {
return false;
-#endif
+ }
}
return true;
}
}
}
-
static void BPLxDAT(int hpos, int num, uae_u16 v)
{
uae_u32 vv = (num << 16) | v;
- if (num == 0) {
- event2_newevent2(1, vv, BPLxDAT_next);
- } else {
- BPLxDAT_next(vv);
- }
+ BPLxDAT_next(vv);
if (num == 0 && hpos >= (hsyncstartpos_start >> CCK_SHRES_SHIFT)) {
if (thisline_decision.plfleft < 0) {
}
beginning_of_plane_block(hpos, fetchmode);
bprun_pipeline_flush_delay = -1;
+ SET_LINE_CYCLEBASED;
}
}
}
maybe_blit(hpos, 0);
blt_info.vblitsize = v & 0x7FFF;
+ if (!blt_info.vblitsize) {
+ blt_info.vblitsize = 0x8000;
+ }
}
static void BLTSIZH(int hpos, uae_u16 v)
blt_info.hblitsize = 0x0800;
}
do_blitter(hpos, copper_access, copper_access ? cop_state.ip : M68K_GETPC);
+ dcheck_is_blit_dangerous();
}
static void spr_arm(int num, int state)
}
if ((cop_state.ir[1] & 0x8000) == 0) {
- decide_blitter(hpos + 1);
+ decide_blitter(hpos);
if (blit_busy()) {
if (blitwait) {
/* We need to wait for the blitter. */
if (cop_state.state != COP_bltwait) {
return;
}
+ // blitter_done_notify() might be called too early, wait a bit if blitter is still busy.
+ if (blit_busy()) {
+ event2_newevent_xx(-1, 1 * CYCLE_UNIT, 0, blitter_done_notify_wakeup);
+ return;
+ }
+
cop_state.state = COP_wait1;
compute_spcflag_copper();
#ifdef DEBUGGER
if (cop_state.state != COP_bltwait) {
return;
}
- int wait = 1;
- event2_newevent_xx(-1, wait * CYCLE_UNIT, 0, blitter_done_notify_wakeup);
+ event2_newevent_xx(-1, 1 * CYCLE_UNIT, 0, blitter_done_notify_wakeup);
}
void do_copper(void)