]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Custom emulation update WIP.
authorToni Wilen <twilen@winuae.net>
Sat, 22 May 2021 12:19:34 +0000 (15:19 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 22 May 2021 12:19:34 +0000 (15:19 +0300)
blitter.cpp
cia.cpp
custom.cpp

index 0c06f6779cd34077bee971423a81c831a762882f..7159882b919a6ba43643d9944c0e14befc83191e 100644 (file)
@@ -59,6 +59,7 @@ static bool shifter_skip_b, shifter_skip_y;
 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
@@ -73,6 +74,7 @@ uae_u32 blit_masktable[BLITTER_MAX_WORDS];
 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;
@@ -88,6 +90,7 @@ static int blit_faulty;
 static int blt_delayed_irq;
 static uae_u16 ddat1;
 static int ddat1use, ddat2use;
+static int blit_dof;
 
 static int last_blitter_hpos;
 
@@ -270,7 +273,7 @@ static void record_dma_blit(uae_u16 reg, uae_u16 v, uae_u32 addr, int 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)
@@ -279,15 +282,15 @@ static void record_dma_blit(uae_u16 reg, uae_u16 v, uae_u32 addr, int hpos)
                                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) {
@@ -408,30 +411,23 @@ static void check_channel_mods (int hpos, int ch)
 // (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) {
@@ -441,16 +437,32 @@ static void blitter_done(void)
        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;
        }
 }
@@ -796,11 +808,11 @@ static void actually_do_blit (void)
 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)
@@ -870,16 +882,20 @@ static void blit_bltset(int con)
                        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();
                        }
                }
        }
@@ -942,7 +958,14 @@ static void blit_bltset(int con)
        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();
@@ -959,7 +982,6 @@ static void blit_bltset(int con)
 #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
@@ -1117,10 +1139,10 @@ static int blitter_next_cycle(void)
                        }
                }
                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) {
@@ -1179,9 +1201,9 @@ static void blitter_doddma_new(int hpos, bool addmod)
 
        if (!blitline) {
                bltdpt += blit_add;
-               if (addmod) {
-                       bltdpt += blit_modaddd;
-               }
+       }
+       if (addmod) {
+               bltdpt += blit_modaddd;
        }
 }
 
@@ -1316,12 +1338,14 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va
 
 
        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) {
@@ -1344,12 +1368,16 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va
 
                        // 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();
                        }
 
@@ -1442,7 +1470,7 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va
 
                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
@@ -1480,7 +1508,13 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va
                                        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;
                                }
 
@@ -1542,10 +1576,11 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va
                                                }
                                                // 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();
                                                }
                                        }
 
@@ -1615,7 +1650,7 @@ static void blitter_force_finish(bool state)
        } else {
                actually_do_blit();
        }
-       blitter_done();
+       blitter_done_all();
        dmacon = odmacon;
 }
 
@@ -1788,8 +1823,9 @@ void do_blitter(int hpos, int copper, uaecptr pc)
                        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;
                        }
@@ -1803,7 +1839,7 @@ void do_blitter(int hpos, int copper, uaecptr pc)
 
        if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) {
                if (dmaen(DMA_BLITTER)) {
-                       blitter_done();
+                       blitter_done_all();
                }
                return;
        }
diff --git a/cia.cpp b/cia.cpp
index ccd4c65267a57e69c885d80b1fae812b846de714..76dafc6131e1cbc1699530d65b502bebdd8a4227 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -1891,56 +1891,56 @@ void CIA_reset (void)
                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);
 }
 
@@ -1955,7 +1955,7 @@ addrbank cia_bank = {
        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;
@@ -1969,23 +1969,13 @@ static void cia_wait_pre (int cianummask)
        }
 
 #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
 }
index 0d74a64b70d0b08a6561683312a34d6aa7894b6a..2c97c6369229c66b419efef885aac1478cffbf6e 100644 (file)
@@ -4679,13 +4679,16 @@ static void init_hz(bool checkvposw)
 
        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;
                }
@@ -4695,10 +4698,6 @@ static void init_hz(bool checkvposw)
                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;
@@ -4907,31 +4906,30 @@ static uae_u16 DENISEID(int *missing)
 
 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;
 }
@@ -5970,15 +5968,10 @@ static void BPLxDAT_next(uae_u32 v)
        }
 }
 
-
 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) {
@@ -5986,6 +5979,7 @@ static void BPLxDAT(int hpos, int num, uae_u16 v)
                }
                beginning_of_plane_block(hpos, fetchmode);
                bprun_pipeline_flush_delay = -1;
+               SET_LINE_CYCLEBASED;
        }
 }
 
@@ -6267,6 +6261,9 @@ static void BLTSIZV(int hpos, uae_u16 v)
        }
        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)
@@ -6283,6 +6280,7 @@ 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)
@@ -7426,7 +7424,7 @@ static int coppercomp(int hpos, bool blitwait)
        }
 
        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.  */
@@ -7685,6 +7683,12 @@ static void blitter_done_notify_wakeup(uae_u32 temp)
        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
@@ -7705,8 +7709,7 @@ void blitter_done_notify(int blitline)
        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)