From ecbad583d39d85960453f34ebd7d00adcd4e809b Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 22 May 2021 15:19:34 +0300 Subject: [PATCH] Custom emulation update WIP. --- blitter.cpp | 110 ++++++++++++++++++++++++++++++++++------------------ cia.cpp | 104 ++++++++++++++++++++++--------------------------- custom.cpp | 57 ++++++++++++++------------- 3 files changed, 150 insertions(+), 121 deletions(-) diff --git a/blitter.cpp b/blitter.cpp index 0c06f677..7159882b 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -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 ccd4c652..76dafc61 100644 --- 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 } diff --git a/custom.cpp b/custom.cpp index 0d74a64b..2c97c636 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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) -- 2.47.3