From 9f759e8b7edd7665648257338fef3eefbc1704f1 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Fri, 10 Feb 2023 21:25:24 +0200 Subject: [PATCH] Statefile accurate blitter and event support. --- blitter.cpp | 148 ++++++++++++++++++---------- cia.cpp | 10 +- custom.cpp | 228 ++++++++++++++++++++++++++++++++++---------- devices.cpp | 2 + disk.cpp | 25 ++--- events.cpp | 20 +++- include/events.h | 10 +- include/savestate.h | 7 +- newcpu.cpp | 19 ++-- savestate.cpp | 15 ++- 10 files changed, 350 insertions(+), 134 deletions(-) diff --git a/blitter.cpp b/blitter.cpp index 3a4e65a0..758ed102 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -113,11 +113,10 @@ static int blitter_vcounter; static evt_t blit_firstline_cycles; static evt_t blit_first_cycle; static int blit_last_cycle, blit_dmacount, blit_cyclecount; -static int blit_linecycles, blit_extracycles; static int blit_faulty; static int blt_delayed_irq; -static uae_u16 ddat1; -static int ddat1use, ddat2use; +static uae_u16 ddat; +static int ddatuse; static int blit_dof; static int last_blitter_hpos; @@ -1164,7 +1163,7 @@ static int get_current_channel(void) return 0; } // D only if A, B and C is not currently active - if (ddat1use) { + if (ddatuse) { // idle fill cycle: 3 = D, 4 = idle if (blitfill_idle) { // if stage 4: idle @@ -1269,7 +1268,7 @@ static int blitter_next_cycle(void) dodat = true; if (!blitline) { if (bltcon0 & BLTCHD) { - ddat1use = true; + ddatuse = true; } } blitter_hcounter++; @@ -1281,7 +1280,7 @@ static int blitter_next_cycle(void) blit_cyclecounter = CYCLECOUNT_FINISHED; if (!blitline) { // do we need final D write? - if (ddat1use && (bltcon0 & BLTCHD)) { + if (ddatuse && (bltcon0 & BLTCHD)) { if (blt_info.blit_finald) { write_log(_T("blit finald already set!?\n")); } @@ -1338,8 +1337,8 @@ static void blitter_doddma_new(int hpos, bool addmod) // alloc_cycle_blitter() can change modulo, old modulo is used during this cycle. int mod = blit_modaddd; if (!skip) { - record_dma_blit(0x00, ddat1, bltdpt, hpos); - blit_chipmem_agnus_wput(bltdpt, ddat1, MW_MASK_BLITTER_D_N); + record_dma_blit(0x00, ddat, bltdpt, hpos); + blit_chipmem_agnus_wput(bltdpt, ddat, MW_MASK_BLITTER_D_N); } bool skipadd = alloc_cycle_blitter(hpos, &bltdpt, 4, addmod ? mod : 0); @@ -1661,8 +1660,8 @@ static bool decide_blitter_maybe_write2(int until_hpos, uaecptr addr, uae_u32 va } if ((dat & BLITTER_PIPELINE_BLIT) && !blitline) { - ddat1 = blitter_doblit(dat); - blt_info.bltddat = ddat1; + ddat = blitter_doblit(dat); + blt_info.bltddat = ddat; } if (dat & BLITTER_PIPELINE_PROCESS) { @@ -1846,7 +1845,7 @@ static void blitter_force_finish(bool state) write_log(_T("forcing blitter finish\n")); if (blitter_cycle_exact && !immediate_blits) { int rounds = 10000; - while (blt_info.blit_main || blt_info.blit_finald && rounds > 0) { + while ((blt_info.blit_main || blt_info.blit_finald) && rounds > 0) { memset(cycle_line_slot, 0, sizeof(cycle_line_slot)); decide_blitter(-1); rounds--; @@ -1917,12 +1916,9 @@ static void blitter_start_init (void) blitline_started = bltcon1 & BLTLINE; blitlineloop = 1; - blit_bltset (1 | 2); - shifter_skip_b_old = shifter_skip_b; - shifter_skip_y_old = shifter_skip_y; + blit_bltset(1 | 2); blit_modset(); - ddat1use = 0; - ddat2use = 0; + ddatuse = 0; blt_info.blit_interrupt = 0; blt_info.bltaold = 0; @@ -2236,44 +2232,42 @@ uae_u8 *restore_blitter (uae_u8 *src) { uae_u32 flags = restore_u32(); - blt_statefile_type = 0; - blt_delayed_irq = 0; - blt_info.blit_pending = 0; - blt_info.blit_finald = 0; - blt_info.blit_main = 0; - if (flags & 4) { - if (!(flags & 1)) { - blt_info.blit_pending = 1; + if (!(flags & 8)) { + blt_statefile_type = 0; + blt_delayed_irq = 0; + blt_info.blit_pending = 0; + blt_info.blit_finald = 0; + blt_info.blit_main = 0; + if (flags & 4) { + if (!(flags & 1)) { + blt_info.blit_pending = 1; + } + } + if (flags & 2) { + write_log (_T("blitter was force-finished when this statefile was saved\n")); + write_log (_T("contact the author if restored program freezes\n")); + // there is a problem. if system ks vblank is active, we must not activate + // "old" blit's intreq until vblank is handled or ks 1.x thinks it was blitter + // interrupt.. + blt_delayed_irq = -1; } - } - if (flags & 2) { - write_log (_T("blitter was force-finished when this statefile was saved\n")); - write_log (_T("contact the author if restored program freezes\n")); - // there is a problem. if system ks vblank is active, we must not activate - // "old" blit's intreq until vblank is handled or ks 1.x thinks it was blitter - // interrupt.. - blt_delayed_irq = -1; } return src; } -uae_u8 *save_blitter (size_t *len, uae_u8 *dstptr) +uae_u8 *save_blitter (size_t *len, uae_u8 *dstptr, bool newstate) { uae_u8 *dstbak,*dst; - int forced; - forced = 0; - if (blt_info.blit_main || blt_info.blit_finald) { - write_log (_T("blitter is active, forcing immediate finish\n")); - /* blitter is active just now but we don't have blitter state support yet */ - blitter_force_finish(true); - forced = 2; - } if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = xmalloc (uae_u8, 16); - save_u32 (((blt_info.blit_main || blt_info.blit_finald) ? 0 : 1) | forced | 4); + dstbak = dst = xmalloc(uae_u8, 16); + if (blt_info.blit_main || blt_info.blit_finald) { + save_u32(8); + } else { + save_u32(1 | 4); + } *len = dst - dstbak; return dstbak; @@ -2321,9 +2315,9 @@ uae_u8 *restore_blitter_new(uae_u8 *src) restore_u8(); restore_u8(); - ddat1use = restore_u8(); + ddatuse = restore_u8(); restore_u8(); - ddat1 = restore_u16(); + ddat = restore_u16(); restore_u16(); blitline = restore_u8(); @@ -2334,7 +2328,9 @@ uae_u8 *restore_blitter_new(uae_u8 *src) blitonedot = restore_u8(); blitlinepixel = restore_u8(); restore_u8(); - blitlinepixel = restore_u8(); + tmp = restore_u8(); + blitlinepixel = (tmp & 1) != 0; + blitlineloop = (tmp & 2) != 0; blt_info.blit_interrupt = restore_u8(); blt_delayed_irq = restore_u8(); blt_info.blitzero = restore_u8(); @@ -2361,6 +2357,8 @@ uae_u8 *restore_blitter_new(uae_u8 *src) shifter[1] = (tmp & 2) != 0; shifter[2] = (tmp & 4) != 0; shifter[3] = (tmp & 8) != 0; + shifter_skip_b_old = (tmp & 16) != 0; + shifter_skip_y_old = (tmp & 32) != 0; blt_info.blit_finald = restore_u8(); blit_ovf = restore_u8(); } @@ -2382,15 +2380,45 @@ uae_u8 *restore_blitter_new(uae_u8 *src) blt_info.blit_pending = 1; } else if (state == 2) { blt_info.blit_main = 1; + blt_info.blit_queued = BLITTER_MAX_PIPELINED_CYCLES; } if (blt_info.blit_finald) { + blt_info.blit_queued = BLITTER_MAX_PIPELINED_CYCLES; blt_info.blit_main = 0; } if (blt_statefile_type == 2) { blit_bltset(0); } } + shifter_skip_b_old = shifter_skip_b; + shifter_skip_y_old = shifter_skip_y; + } + + blit_first_cycle |= ((uae_u64)restore_u32()) << 32; + blit_firstline_cycles |= ((uae_u64)restore_u32()) << 32; + + blt_info.bltaold = restore_u16(); + blt_info.bltbold = restore_u16(); + + blt_info.nasty_cnt = restore_u8(); + blt_info.wait_nasty = restore_u8(); + + shifter_first = (uae_s8)restore_u8(); + blt_info.finishhpos = restore_u8(); + + blit_cyclecounter = restore_u32(); + + for (int i = 0; i < 4; i++) { + blitter_pipe[i] = restore_u16(); + if (blitter_pipe[i]) { + blt_info.blit_queued = BLITTER_MAX_PIPELINED_CYCLES; + } + cycle_line_pipe[i] = restore_u16(); + cycle_line_slot[i] = restore_u8(); } + + //activate_debugger(); + return src; } @@ -2408,6 +2436,8 @@ uae_u8 *save_blitter_new(size_t *len, uae_u8 *dstptr) state = 0; } else if (blt_info.blit_pending) { state = 1; + } else if (blt_info.blit_finald) { + state = 3; } else { state = 2; } @@ -2446,9 +2476,9 @@ uae_u8 *save_blitter_new(size_t *len, uae_u8 *dstptr) save_u8(bltcon0 >> 12); save_u8(16 - (bltcon0 >> 12)); - save_u8(ddat1use); + save_u8(ddatuse); save_u8(0); //(ddat2use); - save_u16(ddat1); + save_u16(ddat); save_u16(0); //(ddat2); save_u8(blitline); @@ -2459,7 +2489,7 @@ uae_u8 *save_blitter_new(size_t *len, uae_u8 *dstptr) save_u8(blitonedot); save_u8(blitlinepixel); save_u8((bltcon1 & BLTSING) != 0); - save_u8(blitlinepixel); + save_u8((blitlinepixel ? 1 : 0) | (blitlineloop ? 2 : 0)); save_u8(blt_info.blit_interrupt); save_u8(blt_delayed_irq); save_u8(blt_info.blitzero); @@ -2475,13 +2505,31 @@ uae_u8 *save_blitter_new(size_t *len, uae_u8 *dstptr) save_u16(0x1234); save_u8(blt_info.blitter_nasty); - save_u8((shifter[0] ? 1 : 0) | (shifter[1] ? 2 : 0) | (shifter[2] ? 4 : 0) | (shifter[3] ? 8 : 0)); + save_u8((shifter[0] ? 1 : 0) | (shifter[1] ? 2 : 0) | (shifter[2] ? 4 : 0) | (shifter[3] ? 8 : 0) | + (shifter_skip_b_old ? 16 : 0) | (shifter_skip_y_old ? 32 : 0)); save_u8(blt_info.blit_finald); save_u8(blit_ovf); save_u32(blit_first_cycle >> 32); save_u32(blit_firstline_cycles >> 32); + save_u16(blt_info.bltaold); + save_u16(blt_info.bltbold); + + save_u8(blt_info.nasty_cnt); + save_u8(blt_info.wait_nasty); + + save_u8(shifter_first); + save_u8(blt_info.finishhpos); + + save_u32(blit_cyclecounter); + + for (int i = 0; i < 4; i++) { + save_u16(blitter_pipe[i]); + save_u16(cycle_line_pipe[i]); + save_u8(cycle_line_slot[i]); + } + *len = dst - dstbak; return dstbak; } diff --git a/cia.cpp b/cia.cpp index b4bddb68..dc344a4c 100644 --- a/cia.cpp +++ b/cia.cpp @@ -749,7 +749,7 @@ static int get_cia_sync_cycles(int *syncdelay) return add; } -static void CIA_synced_interrupt(uae_u32 v) +void event_CIA_synced_interrupt(uae_u32 v) { CIA_update(); CIA_calctimers(); @@ -771,7 +771,7 @@ static void CIA_sync_interrupt(int num, uae_u8 icr) int syncdelay = 0; int delay = get_cia_sync_cycles(&syncdelay); delay += syncdelay; - event2_newevent_xx(-1, DIV10 + delay, num, CIA_synced_interrupt); + event2_newevent_xx(-1, DIV10 + delay, num, event_CIA_synced_interrupt); } else { c->icr1 |= icr; CIA_check_ICR(); @@ -1054,7 +1054,7 @@ static void CIA_tod_inc(bool irq, int num) cia_checkalarm(true, irq, num); } -static void CIA_tod_inc_event(uae_u32 num) +void event_CIA_tod_inc_event(uae_u32 num) { struct CIA *c = &cia[num]; if (c->tod_event_state != 2) { @@ -1092,7 +1092,7 @@ static void CIA_tod_check(int num) } // Not yet, add event to guarantee exact TOD inc position c->tod_event_state = 2; // event active - event2_newevent_xx(-1, -hpos * CYCLE_UNIT, num, CIA_tod_inc_event); + event2_newevent_xx(-1, -hpos * CYCLE_UNIT, num, event_CIA_tod_inc_event); } static void CIA_tod_handler(int hoffset, int num, bool delayedevent) @@ -1113,7 +1113,7 @@ static void CIA_tod_handler(int hoffset, int num, bool delayedevent) if (checkalarm((c->tod + 1) & 0xffffff, c->alarm, true)) { // causes interrupt on this line, add event c->tod_event_state = 2; // event active - event2_newevent_xx(-1, c->tod_offset * CYCLE_UNIT, num, CIA_tod_inc_event); + event2_newevent_xx(-1, c->tod_offset * CYCLE_UNIT, num, event_CIA_tod_inc_event); } } diff --git a/custom.cpp b/custom.cpp index 3a162419..2e93ba1a 100644 --- a/custom.cpp +++ b/custom.cpp @@ -7852,7 +7852,7 @@ static void intreq_checks(uae_u16 oldreq, uae_u16 newreq) } } -static void doint_delay_do_ext(uae_u32 v) +static void event_doint_delay_do_ext(uae_u32 v) { uae_u16 old = intreq2; setclr(&intreq, (1 << v) | 0x8000); @@ -7862,13 +7862,13 @@ static void doint_delay_do_ext(uae_u32 v) doint(); } -static void send_interrupt_do_ext(uae_u32 v) +static void event_send_interrupt_do_ext(uae_u32 v) { //uae_u16 old = intreq; //setclr(&intreq, (1 << v) | 0x8000); //intreq_checks(old); - event2_newevent_xx(-1, 1 * CYCLE_UNIT, v, doint_delay_do_ext); + event2_newevent_xx(-1, 1 * CYCLE_UNIT, v, event_doint_delay_do_ext); } // external delayed interrupt @@ -7878,13 +7878,13 @@ void INTREQ_INT(int num, int delay) if (delay < CYCLE_UNIT) { delay *= CYCLE_UNIT; } - event2_newevent_xx(-1, delay + CYCLE_UNIT, num, doint_delay_do_ext); + event2_newevent_xx(-1, delay + CYCLE_UNIT, num, event_doint_delay_do_ext); } else { - doint_delay_do_ext(num); + event_doint_delay_do_ext(num); } } -static void doint_delay_do_intreq(uae_u32 v) +static void event_doint_delay_do_intreq(uae_u32 v) { uae_u16 old = intreq2; setclr(&intreq2, v); @@ -7898,13 +7898,13 @@ static void doint_delay_intreq(uae_u16 v) if (m68k_interrupt_delay) { // INTREQ or INTENA write: IPL line changes 0.5 CCKs later. // 68000 needs one more CPU clock (0.5 CCK) before it detects it. - event2_newevent_xx(-1, 1 * CYCLE_UNIT, v, doint_delay_do_intreq); + event2_newevent_xx(-1, 1 * CYCLE_UNIT, v, event_doint_delay_do_intreq); } else { - doint_delay_do_intreq(v); + event_doint_delay_do_intreq(v); } } -static void doint_delay_do_intena(uae_u32 v) +static void event_doint_delay_do_intena(uae_u32 v) { setclr(&intena2, v); @@ -7916,10 +7916,10 @@ static void doint_delay_intena(uae_u16 v) if (m68k_interrupt_delay) { // INTREQ or INTENA write: IPL line changes 0.5 CCKs later. // 68000 needs one more CPU clock (0.5 CCK) before it detects it. - event2_newevent_xx(-1, 1 * CYCLE_UNIT, v, doint_delay_do_intena); + event2_newevent_xx(-1, 1 * CYCLE_UNIT, v, event_doint_delay_do_intena); } else { - doint_delay_do_intena(v); + event_doint_delay_do_intena(v); } } @@ -13294,15 +13294,8 @@ static void audio_evhandler2(void) void init_eventtab (void) { - int i; - - nextevent = EVT_MAX; - for (i = 0; i < ev_max; i++) { - eventtab[i].active = 0; - eventtab[i].oldcycles = get_cycles(); - } - for (i = 0; i < ev2_max; i++) { - eventtab2[i].active = 0; + if (!savestate_state) { + clear_events(); } eventtab[ev_cia].handler = CIA_handler; @@ -13316,7 +13309,6 @@ void init_eventtab (void) eventtab[ev_audio].handler = audio_evhandler2; eventtab2[ev2_blitter].handler = blitter_handler; - eventtab2[ev2_disk].handler = DISK_handler; events_schedule (); } @@ -13526,9 +13518,6 @@ void custom_reset(bool hardreset, bool keyboardreset) toscr_delay_sh[0] = 0; toscr_delay_sh[1] = 0; - memset(&cop_state, 0, sizeof(cop_state)); - cop_state.state = COP_stop; - vdiwstate = diw_states::DIW_waiting_start; vdiw_change(0); check_harddis(); @@ -13544,6 +13533,8 @@ void custom_reset(bool hardreset, bool keyboardreset) audio_reset(); if (!isrestore()) { + memset(&cop_state, 0, sizeof(cop_state)); + cop_state.state = COP_stop; /* must be called after audio_reset */ adkcon = 0; serial_uartbreak(0); @@ -14308,12 +14299,12 @@ static void REGPARAM2 custom_lput (uaecptr addr, uae_u32 value) void custom_prepare_savestate(void) { - int i; - - for (i = 0; i < ev2_max; i++) { - if (eventtab2[i].active) { - eventtab2[i].active = 0; - eventtab2[i].handler(eventtab2[i].data); + if (!currprefs.cpu_cycle_exact) { + for (int i = 0; i < ev2_max; i++) { + if (eventtab2[i].active) { + eventtab2[i].active = 0; + eventtab2[i].handler(eventtab2[i].data); + } } } } @@ -14326,6 +14317,12 @@ void restore_custom_finish(void) } } +void restore_custom_start(void) +{ + memset(&cop_state, 0, sizeof(cop_state)); + cop_state.state = COP_stop; +} + #define RB restore_u8() #define SRB (uae_s8)restore_u8() #define RBB restore_u8() != 0 @@ -14342,7 +14339,7 @@ uae_u8 *restore_custom(uae_u8 *src) changed_prefs.chipset_mask = currprefs.chipset_mask = RL & CSMASK_MASK; update_mirrors(); - RW; /* 000 BLTDDAT */ + blt_info.bltddat = RW; /* 000 BLTDDAT */ RW; /* 002 DMACONR */ RW; /* 004 VPOSR */ RW; /* 006 VHPOSR */ @@ -14813,8 +14810,8 @@ uae_u8 *restore_custom_extra(uae_u8 *src) currprefs.cs_ciaatod = changed_prefs.cs_ciaatod = RB; currprefs.cs_ciaoverlay = changed_prefs.cs_ciaoverlay = RBB; - currprefs.cs_agnusbltbusybug = changed_prefs.cs_agnusbltbusybug = RBB; - currprefs.cs_denisenoehb = changed_prefs.cs_denisenoehb = RBB; + tmp = RBB; + tmp = RBB; currprefs.cs_agnusrev = changed_prefs.cs_agnusrev = SRB; currprefs.cs_deniserev = changed_prefs.cs_deniserev = SRB; @@ -14829,7 +14826,7 @@ uae_u8 *restore_custom_extra(uae_u8 *src) RB; currprefs.cs_df0idhw = changed_prefs.cs_df0idhw = RBB; - currprefs.cs_dipagnus = changed_prefs.cs_dipagnus = RBB; + tmp = RBB; currprefs.cs_ide = changed_prefs.cs_ide = RB; currprefs.cs_mbdmac = changed_prefs.cs_mbdmac = RB; currprefs.cs_ksmirror_a8 = changed_prefs.cs_ksmirror_a8 = RBB; @@ -14847,6 +14844,10 @@ uae_u8 *restore_custom_extra(uae_u8 *src) currprefs.cs_memorypatternfill = changed_prefs.cs_memorypatternfill = RBB; + currprefs.cs_agnusmodel = changed_prefs.cs_agnusmodel = RBB; + currprefs.cs_agnussize = changed_prefs.cs_agnussize = RBB; + currprefs.cs_denisemodel = changed_prefs.cs_denisemodel = RBB; + return src; } @@ -14874,8 +14875,8 @@ uae_u8 *save_custom_extra(size_t *len, uae_u8 *dstptr) SB(currprefs.cs_ciaatod); SB(currprefs.cs_ciaoverlay ? 1 : 0); - SB(currprefs.cs_agnusbltbusybug ? 1 : 0); - SB(currprefs.cs_denisenoehb ? 1 : 0); + SB(agnusa1000 ? 1 : 0); + SB(denisea1000_noehb ? 1 : 0); SB(currprefs.cs_agnusrev); SB(currprefs.cs_deniserev); @@ -14890,7 +14891,7 @@ uae_u8 *save_custom_extra(size_t *len, uae_u8 *dstptr) SB(0); SB(currprefs.cs_df0idhw ? 1 : 0); - SB(currprefs.cs_dipagnus ? 1 : 0); + SB(agnusa1000 ? 1 : 0); SB(currprefs.cs_ide); SB(currprefs.cs_mbdmac); SB(currprefs.cs_ksmirror_a8 ? 1 : 0); @@ -14903,14 +14904,74 @@ uae_u8 *save_custom_extra(size_t *len, uae_u8 *dstptr) SB(currprefs.cs_color_burst ? 1 : 0); SB(currprefs.cs_toshibagary ? 1 : 0); SB(currprefs.cs_romisslow ? 1 : 0); + SB(currprefs.cs_ciatype[0]); SB(currprefs.cs_ciatype[1]); + SB(currprefs.cs_memorypatternfill); + SB(currprefs.cs_agnusmodel); + SB(currprefs.cs_agnussize); + SB(currprefs.cs_denisemodel); + *len = dst - dstbak; return dstbak; } +uae_u8 *save_custom_slots(size_t *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak, *dst; + + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = xmalloc(uae_u8, 1000); + + uae_u32 v = 1; + // copper final MOVE pending? + if (cop_state.state == COP_read1) { + v |= 2; + } else if (cop_state.state == COP_read2) { + v |= 4; + } + save_u32(v); + save_u32(cop_state.ip); + save_u16(cop_state.ir[0]); + save_u16(cop_state.ir[1]); + + for (int i = 0; i < 4; i++) { + save_u16(cycle_line_pipe[i]); + save_u16(cycle_line_slot[i]); + } + + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_custom_slots(uae_u8 *src) +{ + uae_u32 v = restore_u32(); + if (!(v & 1)) + return src; + + cop_state.ip = restore_u32(); + cop_state.ir[0] = restore_u16(); + cop_state.ir[1] = restore_u16(); + cop_state.state = COP_stop; + if (v & 2) { + cop_state.state = COP_read1; + } else if (v & 4) { + cop_state.state = COP_read2; + } + + for (int i = 0; i < 4; i++) { + cycle_line_pipe[i] = restore_u16(); + cycle_line_slot[i] = (uae_u8)restore_u16(); + } + + return src; +} + uae_u8 *restore_custom_event_delay(uae_u8 *src) { if (restore_u32() != 1) @@ -14920,19 +14981,57 @@ uae_u8 *restore_custom_event_delay(uae_u8 *src) uae_u8 type = restore_u8(); evt_t e = restore_u64(); uae_u32 data = restore_u32(); - if (type == 1) - event2_newevent_xx(-1, e, data, send_interrupt_do_ext); + evfunc2 f = NULL; + switch(type) + { + case 1: + f = event_send_interrupt_do_ext; + break; + case 2: + f = event_doint_delay_do_ext; + break; + case 3: + f = event_audxdat_func; + break; + case 4: + f = event_setdsr; + break; + case 5: + f = event_CIA_synced_interrupt; + break; + case 6: + f = event_doint_delay_do_intreq; + break; + case 7: + f = event_doint_delay_do_intena; + break; + case 8: + f = event_CIA_tod_inc_event; + break; + case 9: + f = event_DISK_handler; + break; + case 0: + write_log("ignored event type %d (%08x) restored\n", type, data); + break; + default: + write_log("unknown event type %d (%08x) restored\n", type, data); + break; + } + if (f) { + event2_newevent_xx(-1, e, data, f); + } } return src; } uae_u8 *save_custom_event_delay(size_t *len, uae_u8 *dstptr) { uae_u8 *dstbak, *dst; - int cnt = 0; + int cnt = 0, cnt2 = 0; for (int i = ev2_misc; i < ev2_max; i++) { struct ev2 *e = &eventtab2[i]; - if (e->active && e->handler == send_interrupt_do_ext) { + if (e->active) { cnt++; } } @@ -14948,13 +15047,41 @@ uae_u8 *save_custom_event_delay(size_t *len, uae_u8 *dstptr) save_u8(cnt); for (int i = ev2_misc; i < ev2_max; i++) { struct ev2 *e = &eventtab2[i]; - if (e->active && e->handler == send_interrupt_do_ext) { - save_u8(1); + if (e->active) { + evfunc2 f = e->handler; + uae_u8 type = 0; + if (f == event_send_interrupt_do_ext) { + type = 1; + } else if (f == event_doint_delay_do_ext) { + type = 2; + } else if (f == event_audxdat_func) { + type = 3; + } else if (f == event_setdsr) { + type = 4; + } else if (f == event_CIA_synced_interrupt) { + type = 5; + } else if (f == event_doint_delay_do_intreq) { + type = 6; + } else if (f == event_doint_delay_do_intena) { + type = 7; + } else if (f == event_CIA_tod_inc_event) { + type = 8; + } else if (f == event_DISK_handler) { + type = 9; + } else { + write_log("unknown event2 handler %p\n", e->handler); + e->active = false; + f(e->data); + } + if (type) { + cnt2++; + } + save_u8(type); save_u64(e->evtime - get_cycles()); save_u32(e->data); - } } + write_log("%d pending events saved\n", cnt2); *len = dst - dstbak; return dstbak; @@ -14972,7 +15099,6 @@ uae_u8 *save_cycles(size_t *len, uae_u8 *dstptr) save_u32(CYCLE_UNIT); save_u64(get_cycles()); save_u32(extra_cycle); - write_log(_T("SAVECYCLES %08llX\n"), get_cycles()); *len = dst - dstbak; return dstbak; } @@ -14986,7 +15112,8 @@ uae_u8 *restore_cycles(uae_u8 *src) extra_cycle = restore_u32(); if (extra_cycle >= 2 * CYCLE_UNIT) extra_cycle = 0; - write_log(_T("RESTORECYCLES %08llX\n"), start_cycles); + set_cycles(start_cycles); + clear_events(); return src; } @@ -15035,7 +15162,9 @@ void check_prefs_changed_custom(void) currprefs.cs_deniserev = changed_prefs.cs_deniserev; currprefs.cs_mbdmac = changed_prefs.cs_mbdmac; currprefs.cs_df0idhw = changed_prefs.cs_df0idhw; - currprefs.cs_denisenoehb = changed_prefs.cs_denisenoehb; + currprefs.cs_denisemodel = changed_prefs.cs_denisemodel; + currprefs.cs_agnusmodel = changed_prefs.cs_agnusmodel; + currprefs.cs_agnussize = changed_prefs.cs_agnussize; currprefs.cs_z3autoconfig = changed_prefs.cs_z3autoconfig; currprefs.cs_bytecustomwritebug = changed_prefs.cs_bytecustomwritebug; currprefs.cs_color_burst = changed_prefs.cs_color_burst; @@ -15049,7 +15178,6 @@ void check_prefs_changed_custom(void) currprefs.cs_memorypatternfill = changed_prefs.cs_memorypatternfill; if (currprefs.chipset_mask != changed_prefs.chipset_mask || - currprefs.cs_dipagnus != changed_prefs.cs_dipagnus || currprefs.picasso96_nocustom != changed_prefs.picasso96_nocustom || currprefs.ntscmode != changed_prefs.ntscmode || currprefs.cs_hvcsync != changed_prefs.cs_hvcsync @@ -15074,7 +15202,9 @@ void check_prefs_changed_custom(void) nosignal_status = 0; } currprefs.chipset_mask = changed_prefs.chipset_mask; - currprefs.cs_dipagnus = changed_prefs.cs_dipagnus; + currprefs.cs_agnusmodel = changed_prefs.cs_agnusmodel; + currprefs.cs_agnussize = changed_prefs.cs_agnussize; + currprefs.cs_denisemodel = changed_prefs.cs_denisemodel; currprefs.cs_hvcsync = changed_prefs.cs_hvcsync; init_custom(); } diff --git a/devices.cpp b/devices.cpp index a7390955..f71495e6 100644 --- a/devices.cpp +++ b/devices.cpp @@ -382,9 +382,11 @@ void virtualdevice_init (void) void devices_restore_start(void) { + restore_audio_start(); restore_cia_start(); restore_blkdev_start(); restore_blitter_start(); + restore_custom_start(); changed_prefs.bogomem.size = 0; changed_prefs.chipmem.size = 0; for (int i = 0; i < MAX_RAM_BOARDS; i++) { diff --git a/disk.cpp b/disk.cpp index b051ee3c..9b3a5732 100644 --- a/disk.cpp +++ b/disk.cpp @@ -3845,28 +3845,29 @@ static void do_disk_index (void) } } -void DISK_handler (uae_u32 data) +void event_DISK_handler(uae_u32 data) { int flag = data & 255; int disk_sync_cycle = data >> 8; - int hpos = current_hpos (); + int hpos = current_hpos(); - event2_remevent (ev2_disk); - DISK_update (disk_sync_cycle); + DISK_update(disk_sync_cycle); if (!dskdmaen) { if (flag & (DISK_REVOLUTION << 0)) - fetchnextrevolution (&floppy[0]); + fetchnextrevolution(&floppy[0]); if (flag & (DISK_REVOLUTION << 1)) - fetchnextrevolution (&floppy[1]); + fetchnextrevolution(&floppy[1]); if (flag & (DISK_REVOLUTION << 2)) - fetchnextrevolution (&floppy[2]); + fetchnextrevolution(&floppy[2]); if (flag & (DISK_REVOLUTION << 3)) - fetchnextrevolution (&floppy[3]); + fetchnextrevolution(&floppy[3]); } - if (flag & DISK_WORDSYNC) + if (flag & DISK_WORDSYNC) { INTREQ_INT(12, 0); - if (flag & DISK_INDEXSYNC) - do_disk_index (); + } + if (flag & DISK_INDEXSYNC) { + do_disk_index(); + } } static void loaddskbytr(int bits, int speed) @@ -4083,7 +4084,7 @@ static void disk_doupdate_predict (int startcycle) } } if (finaleventflag && (finaleventcycle >> 8) < maxhpos) { - event2_newevent (ev2_disk, (finaleventcycle - startcycle) >> 8, ((finaleventcycle >> 8) << 8) | finaleventflag); + event2_newevent_x_replace((finaleventcycle - startcycle) >> 8, ((finaleventcycle >> 8) << 8) | finaleventflag, event_DISK_handler); } } diff --git a/events.cpp b/events.cpp index d8f2d855..c5184993 100644 --- a/events.cpp +++ b/events.cpp @@ -430,14 +430,18 @@ void event2_newevent_x_replace_exists(evt_t t, uae_u32 data, evfunc2 func) } } - -void event2_newevent_x_replace(evt_t t, uae_u32 data, evfunc2 func) +void event2_newevent_x_remove(evfunc2 func) { for (int i = 0; i < ev2_max; i++) { if (eventtab2[i].active && eventtab2[i].handler == func) { eventtab2[i].active = false; } } +} + +void event2_newevent_x_replace(evt_t t, uae_u32 data, evfunc2 func) +{ + event2_newevent_x_remove(func); if (t <= 0) { func(data); return; @@ -505,3 +509,15 @@ void modify_eventcounter(int diff) events_schedule(); } + +void clear_events(void) +{ + nextevent = EVT_MAX; + for (int i = 0; i < ev_max; i++) { + eventtab[i].active = 0; + eventtab[i].oldcycles = get_cycles(); + } + for (int i = 0; i < ev2_max; i++) { + eventtab2[i].active = 0; + } +} diff --git a/include/events.h b/include/events.h index 9ea1e010..d0f81522 100644 --- a/include/events.h +++ b/include/events.h @@ -37,6 +37,7 @@ extern void events_schedule(void); extern void do_cycles_slow(int cycles_to_add); extern void events_reset_syncline(void); extern void modify_eventcounter(int diff); +extern void clear_events(void); extern bool is_cycle_ce(uaecptr); @@ -68,7 +69,7 @@ enum { }; enum { - ev2_blitter, ev2_disk, ev2_misc, + ev2_blitter, ev2_misc, ev2_max = 12 }; @@ -135,6 +136,7 @@ extern void MISC_handler(void); extern void event2_newevent_xx(int no, evt_t t, uae_u32 data, evfunc2 func); extern void event2_newevent_x_replace(evt_t t, uae_u32 data, evfunc2 func); extern void event2_newevent_x_replace_exists(evt_t t, uae_u32 data, evfunc2 func); +extern void event2_newevent_x_remove(evfunc2 func); STATIC_INLINE void event2_newevent_x(int no, evt_t t, uae_u32 data, evfunc2 func) { @@ -159,4 +161,10 @@ STATIC_INLINE void event2_remevent(int no) eventtab2[no].active = 0; } +void event_audxdat_func(uae_u32); +void event_setdsr(uae_u32); +void event_CIA_synced_interrupt(uae_u32); +void event_CIA_tod_inc_event(uae_u32); +void event_DISK_handler(uae_u32 data); + #endif /* UAE_EVENTS_H */ diff --git a/include/savestate.h b/include/savestate.h index 70b8dff0..4cb47069 100644 --- a/include/savestate.h +++ b/include/savestate.h @@ -101,6 +101,7 @@ extern uae_u8 *save_custom(size_t *, uae_u8 *, int); extern uae_u8 *restore_custom_extra(uae_u8 *); extern uae_u8 *save_custom_extra(size_t *, uae_u8 *); extern void restore_custom_finish(void); +extern void restore_custom_start(void); extern uae_u8 *restore_custom_sprite(int num, uae_u8 *src); extern uae_u8 *save_custom_sprite(int num, size_t *len, uae_u8 *); @@ -111,8 +112,11 @@ extern uae_u8 *save_custom_agacolors(size_t *len, uae_u8 *); extern uae_u8 *restore_custom_event_delay (uae_u8 *src); extern uae_u8 *save_custom_event_delay(size_t *len, uae_u8 *dstptr); +extern uae_u8 *restore_custom_slots(uae_u8 *src); +extern uae_u8 *save_custom_slots(size_t *len, uae_u8 *dstptr); + extern uae_u8 *restore_blitter (uae_u8 *src); -extern uae_u8 *save_blitter (size_t *len, uae_u8 *); +extern uae_u8 *save_blitter (size_t *len, uae_u8 *, bool); extern uae_u8 *restore_blitter_new (uae_u8 *src); extern uae_u8 *save_blitter_new (size_t *len, uae_u8 *); extern void restore_blitter_finish (void); @@ -120,6 +124,7 @@ extern void restore_blitter_finish (void); extern uae_u8 *restore_audio(int, uae_u8 *); extern uae_u8 *save_audio(int, size_t *, uae_u8 *); extern void restore_audio_finish(void); +extern void restore_audio_start(void); extern uae_u8 *restore_cia(int, uae_u8 *); extern uae_u8 *save_cia(int, size_t *, uae_u8 *); diff --git a/newcpu.cpp b/newcpu.cpp index 5384df13..6ed0cc44 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -683,11 +683,11 @@ static void cputracefunc_x_do_cycles(int cycles) while (cycles >= CYCLE_UNIT) { cputrace.cyclecounter += CYCLE_UNIT; cycles -= CYCLE_UNIT; - x2_do_cycles (CYCLE_UNIT); + x2_do_cycles(CYCLE_UNIT); } if (cycles > 0) { cputrace.cyclecounter += cycles; - x2_do_cycles (cycles); + x2_do_cycles(cycles); } } @@ -699,10 +699,10 @@ static void cputracefunc2_x_do_cycles(int cycles) } cycles -= cputrace.cyclecounter; cputrace.cyclecounter = 0; - check_trace (); + check_trace(); x_do_cycles = x2_do_cycles; if (cycles > 0) - x_do_cycles (cycles); + x_do_cycles(cycles); } static void cputracefunc_x_do_cycles_pre(int cycles) @@ -712,10 +712,10 @@ static void cputracefunc_x_do_cycles_pre(int cycles) while (cycles >= CYCLE_UNIT) { cycles -= CYCLE_UNIT; cputrace.cyclecounter_pre += CYCLE_UNIT; - x2_do_cycles (CYCLE_UNIT); + x2_do_cycles_pre(CYCLE_UNIT); } if (cycles > 0) { - x2_do_cycles (cycles); + x2_do_cycles_pre(cycles); cputrace.cyclecounter_pre += cycles; } cputrace.cyclecounter_pre = 0; @@ -742,12 +742,13 @@ static void cputracefunc2_x_do_cycles_pre (int cycles) x_do_cycles (cycles); } -static void cputracefunc_x_do_cycles_post (int cycles, uae_u32 v) +static void cputracefunc_x_do_cycles_post(int cycles, uae_u32 v) { if (cputrace.memoryoffset < 1) { #if CPUTRACE_DEBUG write_log (_T("cputracefunc_x_do_cycles_post memoryoffset=%d!\n"), cputrace.memoryoffset); #endif + x2_do_cycles_post(cycles, v); return; } struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset - 1]; @@ -757,11 +758,11 @@ static void cputracefunc_x_do_cycles_post (int cycles, uae_u32 v) while (cycles >= CYCLE_UNIT) { cycles -= CYCLE_UNIT; cputrace.cyclecounter_post -= CYCLE_UNIT; - x2_do_cycles (CYCLE_UNIT); + x2_do_cycles_post(CYCLE_UNIT, v); } if (cycles > 0) { cputrace.cyclecounter_post -= cycles; - x2_do_cycles (cycles); + x2_do_cycles_post(cycles, v); } cputrace.cyclecounter_post = 0; } diff --git a/savestate.cpp b/savestate.cpp index 42bf531f..6597c005 100644 --- a/savestate.cpp +++ b/savestate.cpp @@ -620,6 +620,7 @@ void restore_state (const TCHAR *filename) restore_header (chunk); xfree (chunk); devices_restore_start(); + clear_events(); z2num = z3num = 0; for (;;) { name[0] = 0; @@ -708,6 +709,8 @@ void restore_state (const TCHAR *filename) end = restore_custom_extra (chunk); else if (!_tcscmp (name, _T("CHPD"))) end = restore_custom_event_delay (chunk); + else if (!_tcscmp (name, _T("CHSL"))) + end = restore_custom_slots (chunk); else if (!_tcscmp (name, _T("AUD0"))) end = restore_audio (0, chunk); else if (!_tcscmp (name, _T("AUD1"))) @@ -1023,11 +1026,13 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c dst = save_blitter_new (&len, 0); save_chunk (f, dst, len, _T("BLTX"), 0); xfree (dst); - if (new_blitter == false) { - dst = save_blitter (&len, 0); - save_chunk (f, dst, len, _T("BLIT"), 0); - xfree (dst); - } + dst = save_blitter (&len, 0, new_blitter); + save_chunk (f, dst, len, _T("BLIT"), 0); + xfree (dst); + + dst = save_custom_slots(&len, 0); + save_chunk(f, dst, len, _T("CHSL"), 0); + xfree(dst); dst = save_input (&len, 0); save_chunk (f, dst, len, _T("CINP"), 0); -- 2.47.3