]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Statefile accurate blitter and event support.
authorToni Wilen <twilen@winuae.net>
Fri, 10 Feb 2023 19:25:24 +0000 (21:25 +0200)
committerToni Wilen <twilen@winuae.net>
Fri, 10 Feb 2023 19:25:24 +0000 (21:25 +0200)
blitter.cpp
cia.cpp
custom.cpp
devices.cpp
disk.cpp
events.cpp
include/events.h
include/savestate.h
newcpu.cpp
savestate.cpp

index 3a4e65a065f879a77b08e9b422f27e76d2dc99ec..758ed10235302d2b8af23fa79d8d2f9514a632b2 100644 (file)
@@ -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 b4bddb68354f9beae5d5eaab695fa30748bd216c..dc344a4cb4b8aee52aad3739450a538c2cc4be7b 100644 (file)
--- 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);
        }
 }
 
index 3a162419443a5c505ad883fa15ead8ce72a38d83..2e93ba1ac2458725b6a140517496b917fea16210 100644 (file)
@@ -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();
        }
index a7390955746854548203e818b1cd0b0098fb5d4f..f71495e682a18786add6f80cf93ac422ae97ad88 100644 (file)
@@ -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++) {
index b051ee3c5c4e009c416a9c55337eff168cd187fd..9b3a5732760a8cfeba4a18fd06968b834bdee07f 100644 (file)
--- 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);
        }
 }
 
index d8f2d8556ddbb76a12988334f8370cab630ecdd9..c518499362858480082554a108c5e6b2d503b5c8 100644 (file)
@@ -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;
+       }
+}
index 9ea1e010b133964e60277ea9991e890618f0c9d0..d0f81522dac2f22ecc114b4e32676f069841a65e 100644 (file)
@@ -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 */
index 70b8dff06f1f03af2ece61d6a06bcd22d9c63bb2..4cb4706998e6d04cdf62b9242a54951939b24e78 100644 (file)
@@ -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 *);
index 5384df135d42debe79afe8c0f6c856060818b0df..6ed0cc44a0ac8839c55d8d4c71a54c6b667eab1f 100644 (file)
@@ -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;
 }
index 42bf531f24b54296510913e471d7bd3006e73d4d..6597c0050693ea98946d1419a0d7def431992c69 100644 (file)
@@ -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);