]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
DMA/memory only cycle-exact mode.
authorToni Wilen <twilen@winuae.net>
Wed, 14 Oct 2015 17:11:05 +0000 (20:11 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 14 Oct 2015 17:11:05 +0000 (20:11 +0300)
blitter.cpp
cfgfile.cpp
cia.cpp
cpummu.cpp
custom.cpp
include/cpu_prefetch.h
include/memory.h
include/options.h
main.cpp
newcpu.cpp

index 9fa0577a7a35b5e2fa273525b0e478d0be0c387a..12b604d3f6dd04cc77486bcad9fd76da14dc35f0 100644 (file)
@@ -1599,7 +1599,7 @@ static void do_blitter2 (int hpos, int copper)
        blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1)); 
        event2_newevent (ev2_blitter, blit_cyclecounter, 0);
 
-       if (dmaen (DMA_BLITTER) && (currprefs.cpu_model >= 68020 || !currprefs.cpu_cycle_exact)) {
+       if (dmaen (DMA_BLITTER) && (currprefs.cpu_model >= 68020 || !currprefs.cpu_memory_cycle_exact)) {
                if (currprefs.waiting_blits) {
                        // wait immediately if all cycles in use and blitter nastry
                        if (blit_dmacount == blit_diag[0] && (regs.spcflags & SPCFLAG_BLTNASTY)) {
@@ -1646,7 +1646,7 @@ void maybe_blit (int hpos, int hack)
        if (savestate_state)
                return;
 
-       if (dmaen (DMA_BLITTER) && (currprefs.cpu_model >= 68020 || !currprefs.cpu_cycle_exact)) {
+       if (dmaen (DMA_BLITTER) && (currprefs.cpu_model >= 68020 || !currprefs.cpu_memory_cycle_exact)) {
                bool doit = false;
                if (currprefs.waiting_blits == 3) { // always
                        doit = true;
index 47a2c34b6b0090d2bfd9762fe688a06c4acb06c3..b027acee3d667c30acbf6b131e49db940734dfeb 100644 (file)
@@ -332,12 +332,11 @@ static TCHAR *cfgfile_option_find_it(const TCHAR *s, const TCHAR *option, bool c
                *tmpp++ = 0;
                if (checkequals) {
                        tmpp2 = _tcschr(p, '=');
-                       if (!tmpp2)
-                               return NULL;
-                       *tmpp2++ = 0;
+                       if (tmpp2)
+                               *tmpp2++ = 0;
                }
                if (!strcasecmp(p, option)) {
-                       if (checkequals)
+                       if (checkequals && tmpp2)
                                return tmpp2;
                        return p;
                }
@@ -962,6 +961,12 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
                                _tcscat(tmp, extras);
                                _tcscat(tmp3, extras);
                        }
+                       if (ci->unit_special_flags) {
+                               TCHAR tmpx[32];
+                               _stprintf(tmpx, _T(",flags=0x%x"), ci->unit_special_flags);
+                               _tcscat(tmp, tmpx);
+                               _tcscat(tmp3, tmpx);
+                       }
                        if (ci->type == UAEDEV_HDF)
                                cfgfile_write_str (f, _T("hardfile2"), tmp);
 #if 0
@@ -1853,6 +1858,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        }
 
        cfgfile_write_bool (f, _T("cpu_cycle_exact"), p->cpu_cycle_exact);
+       // must be after cpu_cycle_exact
+       cfgfile_write_bool (f, _T("cpu_memory_cycle_exact"), p->cpu_memory_cycle_exact);
        cfgfile_write_bool (f, _T("blitter_cycle_exact"), p->blitter_cycle_exact);
        cfgfile_write_bool (f, _T("cycle_exact"), p->cpu_cycle_exact && p->blitter_cycle_exact ? 1 : 0);
        cfgfile_dwrite_bool (f, _T("fpu_no_unimplemented"), p->fpu_no_unimplemented);
@@ -3847,6 +3854,11 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA
                                else if (cfgfile_option_find(tmpp2, _T("HD")))
                                        uci.controller_media_type = 0;
 
+                               TCHAR *pflags;
+                               if ((pflags = cfgfile_option_get(tmpp2, _T("flags")))) {
+                                       getintval(&pflags, &uci.unit_special_flags, 0);
+                               }
+
                                if (cfgfile_option_find(tmpp2, _T("SCSI2")))
                                        uci.unit_feature_level = HD_LEVEL_SCSI_2;
                                else if (cfgfile_option_find(tmpp2, _T("SCSI1")))
@@ -4188,17 +4200,27 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
        bool tmpbool, dummybool;
        TCHAR tmpbuf[CONFIG_BLEN];
 
-       if (cfgfile_yesno (option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)
-               || cfgfile_yesno (option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) {
-                       if (p->cpu_model >= 68020 && p->cachesize > 0)
-                               p->cpu_cycle_exact = p->blitter_cycle_exact = 0;
-                       /* we don't want cycle-exact in 68020/40+JIT modes */
-                       return 1;
+       if (cfgfile_yesno (option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)) {
+               /* we don't want cycle-exact in 68020/40+JIT modes */
+               if (p->cpu_model >= 68020 && p->cachesize > 0)
+                       p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0;
+               p->cpu_memory_cycle_exact = p->cpu_cycle_exact;
+               return 1;
+       }
+       if (cfgfile_yesno (option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) {
+               if (p->cpu_model >= 68020 && p->cachesize > 0)
+                       p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0;
+               return 1;
+       }
+       if (cfgfile_yesno (option, value, _T("cpu_memory_cycle_exact"), &p->cpu_memory_cycle_exact)) {
+               if (!p->cpu_memory_cycle_exact)
+                       p->cpu_cycle_exact = false;
+               return 1;
        }
        if (cfgfile_yesno (option, value, _T("cycle_exact"), &tmpbool)) {
-               p->cpu_cycle_exact = p->blitter_cycle_exact = tmpbool;
+               p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = tmpbool;
                if (p->cpu_model >= 68020 && p->cachesize > 0)
-                       p->cpu_cycle_exact = p->blitter_cycle_exact = false;
+                       p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false;
                // if old version and CE and fastest possible: set to approximate
                if (p->cpu_cycle_exact && p->config_version < ((2 << 16) | (8 << 8) | (2 << 0)) && p->m68k_speed < 0)
                        p->m68k_speed = 0;
@@ -6168,6 +6190,7 @@ void default_prefs (struct uae_prefs *p, int type)
        p->cpu_compatible = 1;
        p->address_space_24 = 1;
        p->cpu_cycle_exact = 0;
+       p->cpu_memory_cycle_exact = 0;
        p->blitter_cycle_exact = 0;
        p->chipset_mask = CSMASK_ECS_AGNUS;
        p->genlock = 0;
@@ -6319,6 +6342,7 @@ static void buildin_default_prefs (struct uae_prefs *p)
        p->cpu_compatible = 1;
        p->address_space_24 = 1;
        p->cpu_cycle_exact = 0;
+       p->cpu_memory_cycle_exact = 0;
        p->blitter_cycle_exact = 0;
        p->chipset_mask = CSMASK_ECS_AGNUS;
        p->immediate_blits = 0;
@@ -6394,6 +6418,7 @@ static void set_68020_compa (struct uae_prefs *p, int compa, int cd32)
                p->m68k_speed = 0;
                if (p->cpu_model == 68020 && p->cachesize == 0) {
                        p->cpu_cycle_exact = 1;
+                       p->cpu_memory_cycle_exact = 1;
                        p->cpu_clock_multiplier = 4 << 8;
                }
        break;
@@ -6426,7 +6451,7 @@ static void set_68000_compa (struct uae_prefs *p, int compa)
        switch (compa)
        {
        case 0:
-               p->cpu_cycle_exact = p->blitter_cycle_exact = 1;
+               p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 1;
                break;
        case 1:
                break;
@@ -6991,7 +7016,7 @@ int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int r
                v = bip_super (p, config, compa, romcheck);
                break;
        }
-       if ((p->cpu_model >= 68020 || !p->cpu_cycle_exact) && !p->immediate_blits)
+       if ((p->cpu_model >= 68020 || !p->cpu_cycle_exact || !p->cpu_memory_cycle_exact) && !p->immediate_blits)
                p->waiting_blits = 1;
        if (p->sound_filter_type == FILTER_SOUND_TYPE_A500 && (p->chipset_mask & CSMASK_AGA))
                p->sound_filter_type = FILTER_SOUND_TYPE_A1200;
diff --git a/cia.cpp b/cia.cpp
index 454868cc77116c23d8aef531bd9dcb00b32b821a..8443d5cf735982499d571ca4e017f8f91dd8fe02 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -745,7 +745,7 @@ static int ciab_tod_event_state;
 static void CIAB_tod_inc (bool irq)
 {
        ciab_tod_event_state = 3; // done
-       if (!ciaatodon)
+       if (!ciabtodon)
                return;
        ciabtod++;
        ciabtod &= 0xFFFFFF;
@@ -1795,7 +1795,7 @@ static void cia_wait_post (int cianummask, uae_u32 value)
                do_cycles (8 * CYCLE_UNIT /2);
        } else {
                int c = 6 * CYCLE_UNIT / 2;
-               if (currprefs.cpu_cycle_exact)
+               if (currprefs.cpu_memory_cycle_exact)
                        x_do_cycles_post (c, value);
                else
                        do_cycles (c);
@@ -1846,7 +1846,7 @@ static uae_u32 REGPARAM2 cia_bget (uaecptr addr)
        uae_u8 v = 0xff;
 
        if (isgarynocia(addr))
-               return dummy_get(addr, 1, false);
+               return dummy_get(addr, 1, false, 0);
 
        if (!isgaylenocia (addr))
                return v;
@@ -1898,7 +1898,7 @@ static uae_u32 REGPARAM2 cia_wget (uaecptr addr)
        uae_u16 v = 0xffff;
 
        if (isgarynocia(addr))
-               return dummy_get(addr, 2, false);
+               return dummy_get(addr, 2, false, 0);
 
        if (!isgaylenocia (addr))
                return v;
@@ -2178,7 +2178,7 @@ void rtc_hardreset (void)
 static uae_u32 REGPARAM2 clock_lget (uaecptr addr)
 {
        if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0)
-               return dummy_get(addr, 4, false);
+               return dummy_get(addr, 4, false, 0);
 
        return (clock_wget (addr) << 16) | clock_wget (addr + 2);
 }
@@ -2186,7 +2186,7 @@ static uae_u32 REGPARAM2 clock_lget (uaecptr addr)
 static uae_u32 REGPARAM2 clock_wget (uaecptr addr)
 {
        if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0)
-               return dummy_get(addr, 2, false);
+               return dummy_get(addr, 2, false, 0);
 
        return (clock_bget (addr) << 8) | clock_bget (addr + 1);
 }
@@ -2197,7 +2197,7 @@ static uae_u32 REGPARAM2 clock_bget (uaecptr addr)
        uae_u8 v = 0;
 
        if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0)
-               return dummy_get(addr, 1, false);
+               return dummy_get(addr, 1, false, 0);
 
 #ifdef CDTV
        if (currprefs.cs_cdtvram && (addr & 0xffff) >= 0x8000)
@@ -2206,9 +2206,7 @@ static uae_u32 REGPARAM2 clock_bget (uaecptr addr)
 
        addr &= 0x3f;
        if ((addr & 3) == 2 || (addr & 3) == 0 || currprefs.cs_rtc == 0) {
-               if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible)
-                       v = regs.irc >> 8;
-               return v;
+               return dummy_get_safe(addr, 1, false, v);
        }
        time_t t = time (0);
        t += currprefs.cs_rtc_adjust;
index 233d0c7530019fbfa05e53d9571206db63901728..114fa99589aeb22313310447b321fdc713d9c603 100644 (file)
@@ -1246,7 +1246,7 @@ void REGPARAM2 mmu_set_funcs(void)
 {
        if (currprefs.mmu_model != 68040 && currprefs.mmu_model != 68060)
                return;
-       if (currprefs.cpu_cycle_exact || currprefs.cpu_compatible) {
+       if (currprefs.cpu_memory_cycle_exact || currprefs.cpu_compatible) {
                x_phys_get_iword = get_word_icache040;
                x_phys_get_ilong = get_long_icache040;
                x_phys_get_byte = get_byte_cache_040;
index 4bf58c67e52c63a01abc6f573cdcb3f6ed3b491f..72960a3614ec2024b8df1a43542bbf6ee4519538 100644 (file)
@@ -446,7 +446,7 @@ STATIC_INLINE int ecsshres(void)
 
 STATIC_INLINE int nodraw (void)
 {
-       return !currprefs.cpu_cycle_exact && framecnt != 0;
+       return !currprefs.cpu_memory_cycle_exact && framecnt != 0;
 }
 
 static int doflickerfix (void)
@@ -7251,7 +7251,7 @@ static bool framewait (void)
        int clockadjust = 0;
        int vstb = vsynctimebase;
 
-       if (currprefs.m68k_speed < 0 && !currprefs.cpu_cycle_exact) {
+       if (currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) {
 
 #if 0
                static uae_u32 prevtick;
@@ -7904,7 +7904,7 @@ static void hsync_handler_post (bool onvsync)
 {
        last_copper_hpos = 0;
 #ifdef CPUEMU_13
-       if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
+       if (currprefs.cpu_memory_cycle_exact || currprefs.blitter_cycle_exact) {
                memset (cycle_line, 0, sizeof cycle_line);
        }
 #endif
@@ -7996,7 +7996,7 @@ static void hsync_handler_post (bool onvsync)
        }
 
 #ifdef CPUEMU_13
-       if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
+       if (currprefs.cpu_memory_cycle_exact || currprefs.blitter_cycle_exact) {
                int hp = maxhpos - 1, i;
                for (i = 0; i < 4; i++) {
                        alloc_cycle (hp, i == 0 ? CYCLE_STROBE : CYCLE_REFRESH); /* strobe */
@@ -8037,7 +8037,7 @@ static void hsync_handler_post (bool onvsync)
                port_get_custom (1, out);
        }
 #endif
-       if (!currprefs.cpu_thread && currprefs.m68k_speed < 0 && !currprefs.cpu_cycle_exact) {
+       if (!currprefs.cpu_thread && currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) {
                static int sleeps_remaining;
                if (is_last_line ()) {
                        sleeps_remaining = (165 - currprefs.cpu_idle) / 6;
@@ -8757,7 +8757,7 @@ static uae_u32 REGPARAM2 custom_wget (uaecptr addr)
        uae_u32 v;
 
        if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0)
-               return dummy_get(addr, 2, false);
+               return dummy_get(addr, 2, false, 0);
        if (addr & 1) {
                /* think about move.w $dff005,d0.. (68020+ only) */
                addr &= ~1;
@@ -8772,7 +8772,7 @@ static uae_u32 REGPARAM2 custom_bget (uaecptr addr)
 {
        uae_u32 v;
        if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0)
-               return dummy_get(addr, 1, false);
+               return dummy_get(addr, 1, false, 0);
        v = custom_wget2 (addr & ~1, true);
        v >>= (addr & 1 ? 0 : 8);
        return v;
@@ -8781,7 +8781,7 @@ static uae_u32 REGPARAM2 custom_bget (uaecptr addr)
 static uae_u32 REGPARAM2 custom_lget (uaecptr addr)
 {
        if ((addr & 0xffff) < 0x8000 && currprefs.cs_fatgaryrev >= 0)
-               return dummy_get(addr, 4, false);
+               return dummy_get(addr, 4, false, 0);
        return ((uae_u32)custom_wget (addr) << 16) | custom_wget (addr + 2);
 }
 static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int noget)
@@ -9755,9 +9755,9 @@ static int dma_cycle (void)
        blitter_nasty = 1;
        if (cpu_tracer  < 0)
                return current_hpos ();
-       if (!currprefs.cpu_cycle_exact)
+       if (!currprefs.cpu_memory_cycle_exact)
                return current_hpos ();
-       while (currprefs.cpu_cycle_exact) {
+       while (currprefs.cpu_memory_cycle_exact) {
                int bpldma;
                int blitpri = dmacon & DMA_BLITPRI;
                hpos_old = current_hpos ();
index acf9e5b11610f47143d6fd59d2050141f1a96016..96604d13a4e56517c1a32b752c3444db50b1f3b2 100644 (file)
@@ -333,104 +333,11 @@ STATIC_INLINE void ipl_fetch (void)
        regs.ipl = regs.ipl_pin;
 }
 
-STATIC_INLINE uae_u32 mem_access_delay_word_read (uaecptr addr)
-{
-       uae_u32 v;
-       switch (ce_banktype[addr >> 16])
-       {
-       case CE_MEMBANK_CHIP16:
-       case CE_MEMBANK_CHIP32:
-               v = wait_cpu_cycle_read (addr, 1);
-               break;
-       case CE_MEMBANK_FAST16:
-       case CE_MEMBANK_FAST32:
-               v = get_word (addr);
-               x_do_cycles_post (4 * cpucycleunit, v);
-               break;
-       default:
-               v = get_word (addr);
-               break;
-       }
-       regs.db = v;
-       return v;
-}
-STATIC_INLINE uae_u32 mem_access_delay_wordi_read (uaecptr addr)
-{
-       uae_u32 v;
-       switch (ce_banktype[addr >> 16])
-       {
-       case CE_MEMBANK_CHIP16:
-       case CE_MEMBANK_CHIP32:
-               v = wait_cpu_cycle_read (addr, 1);
-               break;
-       case CE_MEMBANK_FAST16:
-       case CE_MEMBANK_FAST32:
-               v = get_wordi (addr);
-               x_do_cycles_post (4 * cpucycleunit, v);
-               break;
-       default:
-               v = get_wordi (addr);
-               break;
-       }
-       regs.db = v;
-       return v;
-}
-
-STATIC_INLINE uae_u32 mem_access_delay_byte_read (uaecptr addr)
-{
-       uae_u32  v;
-       switch (ce_banktype[addr >> 16])
-       {
-       case CE_MEMBANK_CHIP16:
-       case CE_MEMBANK_CHIP32:
-               v = wait_cpu_cycle_read (addr, 0);
-               break;
-       case CE_MEMBANK_FAST16:
-       case CE_MEMBANK_FAST32:
-               v = get_byte (addr);
-               x_do_cycles_post (4 * cpucycleunit, v);
-               break;
-       default:
-               v = get_byte (addr);
-               break;
-       }
-       regs.db = (v << 8) | v;
-       return v;
-}
-STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
-{
-       regs.db = (v << 8)  | v;
-       switch (ce_banktype[addr >> 16])
-       {
-       case CE_MEMBANK_CHIP16:
-       case CE_MEMBANK_CHIP32:
-               wait_cpu_cycle_write (addr, 0, v);
-               return;
-       case CE_MEMBANK_FAST16:
-       case CE_MEMBANK_FAST32:
-               put_byte (addr, v);
-               x_do_cycles_post (4 * cpucycleunit, v);
-               return;
-       }
-       put_byte (addr, v);
-}
-STATIC_INLINE void mem_access_delay_word_write (uaecptr addr, uae_u32 v)
-{
-       regs.db = v;
-       switch (ce_banktype[addr >> 16])
-       {
-       case CE_MEMBANK_CHIP16:
-       case CE_MEMBANK_CHIP32:
-               wait_cpu_cycle_write (addr, 1, v);
-               return;
-       case CE_MEMBANK_FAST16:
-       case CE_MEMBANK_FAST32:
-               put_word (addr, v);
-               x_do_cycles_post (4 * cpucycleunit, v);
-               return;
-       }
-       put_word (addr, v);
-}
+uae_u32 mem_access_delay_word_read (uaecptr addr);
+uae_u32 mem_access_delay_wordi_read (uaecptr addr);
+uae_u32 mem_access_delay_byte_read (uaecptr addr);
+void mem_access_delay_byte_write (uaecptr addr, uae_u32 v);
+void mem_access_delay_word_write (uaecptr addr, uae_u32 v);
 
 STATIC_INLINE uae_u32 get_long_ce000 (uaecptr addr)
 {
index 338383294fdf9f8accbb8946117c9624b0b626f5..65160037d6bff8157b42ab514588bd18048902a5 100644 (file)
@@ -283,7 +283,8 @@ extern uae_u32 last_custom_value1;
 /* Default memory access functions */
 
 extern void dummy_put (uaecptr addr, int size, uae_u32 val);
-extern uae_u32 dummy_get (uaecptr addr, int size, bool inst);
+extern uae_u32 dummy_get (uaecptr addr, int size, bool inst, uae_u32 defvalue);
+extern uae_u32 dummy_get_safe(uaecptr addr, int size, bool inst, uae_u32 defvalue);
 
 extern int REGPARAM3 default_check(uaecptr addr, uae_u32 size) REGPARAM;
 extern uae_u8 *REGPARAM3 default_xlate(uaecptr addr) REGPARAM;
index 20da48b7161429df0de3ff81d619674fad258cad..386b1b510638b8f98603fe74edc1b82d6cde53a5 100644 (file)
@@ -170,6 +170,7 @@ struct uaedev_config_info {
        int controller_unit;
        int controller_media_type; // 1 = CF IDE, 0 = normal
        int unit_feature_level;
+       int unit_special_flags;
        bool physical_geometry; // if false: use defaults
        int pcyls, pheads, psecs;
        int flags;
@@ -454,6 +455,7 @@ struct uae_prefs {
        int cpu_clock_multiplier;
        int cpu_frequency;
        bool blitter_cycle_exact;
+       bool cpu_memory_cycle_exact;
        int floppy_speed;
        int floppy_write_length;
        int floppy_random_bits_min;
index c68e4d3f0e6622bce1ba9d9e766c2d982b6f4e02..598298c581215ef45991f0d8ddde9faf5c4c7fc5 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -246,7 +246,7 @@ void fixup_cpu (struct uae_prefs *p)
                break;
        }
 
-       if (p->cpu_thread && (p->cpu_compatible || p->ppc_mode || p->cpu_cycle_exact || p->cpu_model < 68020)) {
+       if (p->cpu_thread && (p->cpu_compatible || p->ppc_mode || p->cpu_cycle_exact || p->cpu_memory_cycle_exact || p->cpu_model < 68020)) {
                p->cpu_thread = false;
                error_log(_T("Threaded CPU mode is not compatible with PPC emulation, More compatible or Cycle Exact modes. CPU type must be 68020 or higher."));
        }
@@ -270,6 +270,9 @@ void fixup_cpu (struct uae_prefs *p)
                error_log (_T("JIT requires 68020 or better CPU."));
        }
 
+       if (!p->cpu_memory_cycle_exact && p->cpu_cycle_exact)
+               p->cpu_memory_cycle_exact = true;
+
        if (p->cpu_model >= 68040 && p->cachesize && p->cpu_compatible)
                p->cpu_compatible = false;
 
@@ -278,7 +281,7 @@ void fixup_cpu (struct uae_prefs *p)
                p->mmu_model = 0;
        }
 
-       if (p->cachesize && p->cpu_cycle_exact) {
+       if (p->cachesize && (p->cpu_cycle_exact || p->cpu_memory_cycle_exact)) {
                error_log (_T("JIT and cycle-exact can't be enabled simultaneously."));
                p->cachesize = 0;
        }
@@ -302,10 +305,10 @@ void fixup_cpu (struct uae_prefs *p)
                error_log (_T("Immediate blitter and waiting blits can't be enabled simultaneously.\n"));
                p->waiting_blits = 0;
        }
-       if (p->cpu_cycle_exact)
+       if (p->cpu_cycle_exact || p->cpu_memory_cycle_exact)
                p->cpu_compatible = true;
 
-       if (p->cpu_cycle_exact && p->produce_sound == 0) {
+       if ((p->cpu_cycle_exact || p->cpu_memory_cycle_exact) && p->produce_sound == 0) {
                p->produce_sound = 1;
                error_log(_T("Cycle-exact mode requires at least Disabled but emulated sound setting."));
        }
index 56d1419295a3d5bdf7ed284d13339ab74bfb6870..e24d4fbba7b96fde3400bb40b7d092971aa872ca 100644 (file)
@@ -819,7 +819,25 @@ static void set_x_funcs (void)
                        x_do_cycles = do_cycles_ce;
                        x_do_cycles_pre = do_cycles_ce;
                        x_do_cycles_post = do_cycles_ce_post;
+               } else if (currprefs.cpu_memory_cycle_exact) {
+                       // cpu_memory_cycle_exact + cpu_compatible
+                       x_prefetch = get_word_prefetch;
+                       x_get_ilong = NULL;
+                       x_get_iword = get_iiword;
+                       x_get_ibyte = get_iibyte;
+                       x_next_iword = NULL;
+                       x_next_ilong = NULL;
+                       x_put_long = put_long_ce000;
+                       x_put_word = put_word_ce000;
+                       x_put_byte = put_byte_ce000;
+                       x_get_long = get_long_ce000;
+                       x_get_word = get_word_ce000;
+                       x_get_byte = get_byte_ce000;
+                       x_do_cycles = do_cycles;
+                       x_do_cycles_pre = do_cycles;
+                       x_do_cycles_post = do_cycles_post;
                } else if (currprefs.cpu_compatible) {
+                       // cpu_compatible only
                        x_prefetch = get_word_prefetch;
                        x_get_ilong = NULL;
                        x_get_iword = get_iiword;
@@ -854,7 +872,73 @@ static void set_x_funcs (void)
                }
        } else if (!currprefs.cpu_cycle_exact) {
                // 68020+ no ce
-               if (currprefs.cpu_compatible) {
+               if (currprefs.cpu_memory_cycle_exact) {
+                       // cpu_memory_cycle_exact + cpu_compatible
+                       if (currprefs.cpu_model == 68020 && !currprefs.cachesize) {
+                               x_prefetch = get_word_020_prefetch;
+                               x_get_ilong = get_long_020_prefetch;
+                               x_get_iword = get_word_020_prefetch;
+                               x_get_ibyte = NULL;
+                               x_next_iword = next_iword_020_prefetch;
+                               x_next_ilong = next_ilong_020_prefetch;
+                               x_put_long = put_long_ce020;
+                               x_put_word = put_word_ce020;
+                               x_put_byte = put_byte_ce020;
+                               x_get_long = get_long_ce020;
+                               x_get_word = get_word_ce020;
+                               x_get_byte = get_byte_ce020;
+                               x_do_cycles = do_cycles;
+                               x_do_cycles_pre = do_cycles;
+                               x_do_cycles_post = do_cycles_post;
+                       } else if (currprefs.cpu_model == 68030 && !currprefs.cachesize) {
+                               x_prefetch = get_word_030_prefetch;
+                               x_get_ilong = get_long_030_prefetch;
+                               x_get_iword = get_word_030_prefetch;
+                               x_get_ibyte = NULL;
+                               x_next_iword = next_iword_030_prefetch;
+                               x_next_ilong = next_ilong_030_prefetch;
+                               x_put_long = put_long_ce030;
+                               x_put_word = put_word_ce030;
+                               x_put_byte = put_byte_ce030;
+                               x_get_long = get_long_ce030;
+                               x_get_word = get_word_ce030;
+                               x_get_byte = get_byte_ce030;
+                               x_do_cycles = do_cycles;
+                               x_do_cycles_pre = do_cycles;
+                               x_do_cycles_post = do_cycles_post;
+                       } else if (currprefs.cpu_model < 68040) {
+                               // JIT or 68030+ does not have real prefetch only emulation
+                               x_prefetch = NULL;
+                               set_x_ifetches();
+                               x_put_long = put_long;
+                               x_put_word = put_word;
+                               x_put_byte = put_byte;
+                               x_get_long = get_long;
+                               x_get_word = get_word;
+                               x_get_byte = get_byte;
+                               x_do_cycles = do_cycles;
+                               x_do_cycles_pre = do_cycles;
+                               x_do_cycles_post = do_cycles_post;
+                       } else {
+                               // 68040+ (same as below)
+                               x_prefetch = NULL;
+                               x_get_ilong = get_ilong_cache_040;
+                               x_get_iword = get_iword_cache_040;
+                               x_get_ibyte = NULL;
+                               x_next_iword = next_iword_cache040;
+                               x_next_ilong = next_ilong_cache040;
+                               x_put_long = put_long_cache_040;
+                               x_put_word = put_word_cache_040;
+                               x_put_byte = put_byte_cache_040;
+                               x_get_long = get_long_cache_040;
+                               x_get_word = get_word_cache_040;
+                               x_get_byte = get_byte_cache_040;
+                               x_do_cycles = do_cycles;
+                               x_do_cycles_pre = do_cycles;
+                               x_do_cycles_post = do_cycles_post;
+                       }
+               } else if (currprefs.cpu_compatible) {
+                       // cpu_compatible only
                        if (currprefs.cpu_model == 68020 && !currprefs.cachesize) {
                                x_prefetch = get_word_prefetch;
                                x_get_ilong = get_long_020_prefetch;
@@ -1049,7 +1133,7 @@ static void set_x_funcs (void)
 
 bool can_cpu_tracer (void)
 {
-       return (currprefs.cpu_model == 68000 || currprefs.cpu_model == 68020) && currprefs.cpu_cycle_exact;
+       return (currprefs.cpu_model == 68000 || currprefs.cpu_model == 68020) && currprefs.cpu_memory_cycle_exact;
 }
 
 bool is_cpu_tracer (void)
@@ -1079,7 +1163,7 @@ bool set_cpu_tracer (bool state)
 
 void flush_cpu_caches(bool force)
 {
-       bool doflush = currprefs.cpu_compatible || currprefs.cpu_cycle_exact;
+       bool doflush = currprefs.cpu_compatible || currprefs.cpu_memory_cycle_exact;
 
        if (currprefs.cpu_model == 68020) {
                if (regs.cacr & 0x08) { // clear instr cache
@@ -1301,7 +1385,7 @@ static void build_cpufunctbl (void)
        }
        write_log (_T("Building CPU, %d opcodes (%d %d %d)\n"),
                opcnt, lvl,
-               currprefs.cpu_cycle_exact ? -1 : currprefs.cpu_compatible ? 1 : 0, currprefs.address_space_24);
+               currprefs.cpu_cycle_exact ? -2 : currprefs.cpu_memory_cycle_exact ? -1 : currprefs.cpu_compatible ? 1 : 0, currprefs.address_space_24);
 #ifdef JIT
        write_log(_T("JIT: &countdown =  %p\n"), &countdown);
        write_log(_T("JIT: &build_comp = %p\n"), &build_comp);
@@ -1330,6 +1414,8 @@ static void build_cpufunctbl (void)
                        write_log(_T(" prefetch and cycle-exact"));
                else
                        write_log(_T(" ~cycle-exact"));
+       } else if (currprefs.cpu_memory_cycle_exact) {
+                       write_log(_T(" ~memory-cycle-exact"));
        } else if (currprefs.cpu_compatible) {
                if (currprefs.cpu_model <= 68020) {
                        write_log(_T(" prefetch"));
@@ -1422,6 +1508,7 @@ static void prefs_changed_cpu (void)
        currprefs.mmu_model = changed_prefs.mmu_model;
        currprefs.cpu_compatible = changed_prefs.cpu_compatible;
        currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact;
+       currprefs.cpu_memory_cycle_exact = changed_prefs.cpu_memory_cycle_exact;
        currprefs.int_no_unimplemented = changed_prefs.int_no_unimplemented;
        currprefs.fpu_no_unimplemented = changed_prefs.fpu_no_unimplemented;
        currprefs.blitter_cycle_exact = changed_prefs.blitter_cycle_exact;
@@ -1441,7 +1528,8 @@ static int check_prefs_changed_cpu2(void)
                || currprefs.int_no_unimplemented != changed_prefs.int_no_unimplemented
                || currprefs.fpu_no_unimplemented != changed_prefs.fpu_no_unimplemented
                || currprefs.cpu_compatible != changed_prefs.cpu_compatible
-               || currprefs.cpu_cycle_exact != changed_prefs.cpu_cycle_exact) {
+               || currprefs.cpu_cycle_exact != changed_prefs.cpu_cycle_exact
+               || currprefs.cpu_memory_cycle_exact != changed_prefs.cpu_memory_cycle_exact) {
                        cpu_prefs_changed_flag |= 1;
        }
        if (changed
@@ -5358,9 +5446,9 @@ static const TCHAR *movemregs[] =
        _T("FP5"),
        _T("FP6"),
        _T("FP7"),
-       _T("FPCR"),
+       _T("FPIAR"),
        _T("FPSR"),
-       _T("FPIAR")
+       _T("FPCR")
 };
 
 static void addmovemreg (TCHAR *out, int *prevreg, int *lastreg, int *first, int reg, int fpmode)
@@ -6009,6 +6097,7 @@ uae_u8 *restore_cpu (uae_u8 *src)
        currprefs.address_space_24 = changed_prefs.address_space_24;
        currprefs.cpu_compatible = changed_prefs.cpu_compatible;
        currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact;
+       currprefs.cpu_memory_cycle_exact = changed_prefs.cpu_memory_cycle_exact;
        currprefs.blitter_cycle_exact = changed_prefs.blitter_cycle_exact;
        currprefs.cpu_frequency = changed_prefs.cpu_frequency = 0;
        currprefs.cpu_clock_multiplier = changed_prefs.cpu_clock_multiplier = 0;
@@ -6301,6 +6390,9 @@ uae_u8 *restore_cpu_extra (uae_u8 *src)
        uae_u32 flags = restore_u32 ();
 
        currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact = (flags & 1) ? true : false;
+       currprefs.cpu_memory_cycle_exact = changed_prefs.cpu_memory_cycle_exact = currprefs.cpu_cycle_exact;
+       if ((flags & 32) && !(flags & 1))
+               currprefs.cpu_memory_cycle_exact = changed_prefs.cpu_memory_cycle_exact = true;
        currprefs.blitter_cycle_exact = changed_prefs.blitter_cycle_exact = currprefs.cpu_cycle_exact;
        currprefs.cpu_compatible = changed_prefs.cpu_compatible = (flags & 2) ? true : false;
        currprefs.cpu_frequency = changed_prefs.cpu_frequency = restore_u32 ();
@@ -6335,6 +6427,7 @@ uae_u8 *save_cpu_extra (int *len, uae_u8 *dstptr)
        flags |= currprefs.m68k_speed < 0 ? 4 : 0;
        flags |= currprefs.cachesize > 0 ? 8 : 0;
        flags |= currprefs.m68k_speed > 0 ? 16 : 0;
+       flags |= currprefs.cpu_memory_cycle_exact ? 32 : 0;
        if (currprefs.m68k_speed > 0)
                flags |= (currprefs.m68k_speed / CYCLE_UNIT) << 24;
        save_u32 (flags);
@@ -6584,7 +6677,7 @@ void cpureset (void)
        m68k_reset_delay = currprefs.reset_delay;
        set_special(SPCFLAG_CHECK);
        send_internalevent(INTERNALEVENT_CPURESET);
-       if ((currprefs.cpu_compatible || currprefs.cpu_cycle_exact) && currprefs.cpu_model <= 68020) {
+       if ((currprefs.cpu_compatible || currprefs.cpu_memory_cycle_exact) && currprefs.cpu_model <= 68020) {
                custom_reset (false, false);
                return;
        }
@@ -6640,6 +6733,107 @@ void m68k_resumestopped (void)
        unset_special (SPCFLAG_STOP);
 }
 
+
+uae_u32 mem_access_delay_word_read (uaecptr addr)
+{
+       uae_u32 v;
+       switch (ce_banktype[addr >> 16])
+       {
+       case CE_MEMBANK_CHIP16:
+       case CE_MEMBANK_CHIP32:
+               v = wait_cpu_cycle_read (addr, 1);
+               break;
+       case CE_MEMBANK_FAST16:
+       case CE_MEMBANK_FAST32:
+               v = get_word (addr);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               break;
+       default:
+               v = get_word (addr);
+               break;
+       }
+       regs.db = v;
+       return v;
+}
+uae_u32 mem_access_delay_wordi_read (uaecptr addr)
+{
+       uae_u32 v;
+       switch (ce_banktype[addr >> 16])
+       {
+       case CE_MEMBANK_CHIP16:
+       case CE_MEMBANK_CHIP32:
+               v = wait_cpu_cycle_read (addr, 1);
+               break;
+       case CE_MEMBANK_FAST16:
+       case CE_MEMBANK_FAST32:
+               v = get_wordi (addr);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               break;
+       default:
+               v = get_wordi (addr);
+               break;
+       }
+       regs.db = v;
+       return v;
+}
+
+uae_u32 mem_access_delay_byte_read (uaecptr addr)
+{
+       uae_u32  v;
+       switch (ce_banktype[addr >> 16])
+       {
+       case CE_MEMBANK_CHIP16:
+       case CE_MEMBANK_CHIP32:
+               v = wait_cpu_cycle_read (addr, 0);
+               break;
+       case CE_MEMBANK_FAST16:
+       case CE_MEMBANK_FAST32:
+               v = get_byte (addr);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               break;
+       default:
+               v = get_byte (addr);
+               break;
+       }
+       regs.db = (v << 8) | v;
+       return v;
+}
+void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
+{
+       regs.db = (v << 8)  | v;
+       switch (ce_banktype[addr >> 16])
+       {
+       case CE_MEMBANK_CHIP16:
+       case CE_MEMBANK_CHIP32:
+               wait_cpu_cycle_write (addr, 0, v);
+               return;
+       case CE_MEMBANK_FAST16:
+       case CE_MEMBANK_FAST32:
+               put_byte (addr, v);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               return;
+       }
+       put_byte (addr, v);
+}
+void mem_access_delay_word_write (uaecptr addr, uae_u32 v)
+{
+       regs.db = v;
+       switch (ce_banktype[addr >> 16])
+       {
+       case CE_MEMBANK_CHIP16:
+       case CE_MEMBANK_CHIP32:
+               wait_cpu_cycle_write (addr, 1, v);
+               return;
+       case CE_MEMBANK_FAST16:
+       case CE_MEMBANK_FAST32:
+               put_word (addr, v);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               return;
+       }
+       put_word (addr, v);
+}
+
+
 // this one is really simple and easy
 static void fill_icache020 (uae_u32 addr, uae_u32 (*fetch)(uaecptr))
 {
@@ -6818,7 +7012,7 @@ uae_u32 get_word_020_prefetch (int o)
 #endif
                regs.prefetch020[0] = regs.prefetch020[1];
                if (!MORE_ACCURATE_68020_PIPELINE || regs.pipeline_stop >= 0) {
-                       fill_icache020 (pc + 2 + 4, get_longi);
+                       fill_icache020 (pc + 2 + 4, currprefs.cpu_memory_cycle_exact ? mem_access_delay_longi_read_ce020 : get_longi);
                        regs.prefetch020[1] = regs.cacheholdingdata020;
                }
                regs.db = regs.prefetch020[0] >> 16;
@@ -7114,6 +7308,8 @@ static void fill_icache030 (uae_u32 addr)
                // add as available "free" internal CPU time.
                cycs = get_cycles () - cycs;
                regs.ce020memcycles += cycs;
+       } else if (currprefs.cpu_memory_cycle_exact) {
+               data = mem_access_delay_longi_read_ce020 (addr);
        } else {
                data = get_longi (addr);
        }
@@ -7210,7 +7406,7 @@ static void write_dcache030x(uaecptr addr, uae_u32 val, int size)
 void write_dcache030(uaecptr addr, uae_u32 v, int size)
 {
        write_dcache030x(addr, v, size);
-       if (currprefs.cpu_cycle_exact) {
+       if (currprefs.cpu_memory_cycle_exact) {
                if (size == 2)
                        mem_access_delay_long_write_ce020(addr, v);
                else if (size == 1)
@@ -7236,7 +7432,7 @@ uae_u32 read_dcache030 (uaecptr addr, int size)
        uae_u32 v1, v2;
 
        if (!(regs.cacr & 0x100) || !cancache030 (addr)) { // data cache disabled?
-               if (currprefs.cpu_cycle_exact) {
+               if (currprefs.cpu_memory_cycle_exact) {
                        if (size == 2)
                                return mem_access_delay_long_read_ce020 (addr);
                        else if (size == 1)
@@ -7255,7 +7451,7 @@ uae_u32 read_dcache030 (uaecptr addr, int size)
        c1 = getcache030 (dcaches030, addr, &tag1, &lws1);
        addr &= ~3;
        if (!c1->valid[lws1] || c1->tag != tag1) {
-               v1 = currprefs.cpu_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
+               v1 = currprefs.cpu_memory_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
                update_cache030 (c1, v1, tag1, lws1);
        } else {
                v1 = c1->data[lws1];
@@ -7293,7 +7489,7 @@ uae_u32 read_dcache030 (uaecptr addr, int size)
        addr += 4;
        c2 = getcache030 (dcaches030, addr, &tag2, &lws2);
        if (!c2->valid[lws2] || c2->tag != tag2) {
-               v2 = currprefs.cpu_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
+               v2 = currprefs.cpu_memory_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
                update_cache030 (c2, v2, tag2, lws2);
        } else {
                v2 = c2->data[lws2];
@@ -7401,7 +7597,7 @@ uae_u32 fill_icache040(uae_u32 addr)
                if (regs.prefetch020addr == addr2)
                        return regs.prefetch020[lws];
                regs.prefetch020addr = addr2;
-               if (currprefs.cpu_cycle_exact) {
+               if (currprefs.cpu_memory_cycle_exact) {
                        regs.prefetch020[0] = mem_access_delay_longi_read_ce020(addr2 +  0);
                        regs.prefetch020[1] = mem_access_delay_longi_read_ce020(addr2 +  4);
                        regs.prefetch020[2] = mem_access_delay_longi_read_ce020(addr2 +  8);
@@ -7441,7 +7637,7 @@ uae_u32 fill_icache040(uae_u32 addr)
        }
        c->tag[line] = tag;
        c->valid[line] = true;
-       if (currprefs.cpu_cycle_exact) {
+       if (currprefs.cpu_memory_cycle_exact) {
                c->data[line][0] = mem_access_delay_longi_read_ce020(addr +  0);
                c->data[line][1] = mem_access_delay_longi_read_ce020(addr +  4);
                c->data[line][2] = mem_access_delay_longi_read_ce020(addr +  8);
@@ -7596,7 +7792,7 @@ uae_u32 get_iword_cache_040(int o)
 
 STATIC_INLINE bool nocache040(uaecptr addr)
 {
-       if (!currprefs.cpu_cycle_exact)
+       if (!currprefs.cpu_memory_cycle_exact)
                return false;
        if (!(regs.cacr & 0x80000000))
                return true;
@@ -7618,7 +7814,7 @@ void put_long_cache_040(uaecptr addr, uae_u32 v)
        if ((addr & 2) == 0) {
                if (is_dcache040(addr))
                        write_dcache040(addr, v);
-               else if (currprefs.cpu_cycle_exact)
+               else if (currprefs.cpu_memory_cycle_exact)
                        mem_access_delay_long_write_ce020(addr, v);
                else
                        put_long(addr, v);
@@ -7629,7 +7825,7 @@ void put_long_cache_040(uaecptr addr, uae_u32 v)
                        vp &= 0xffff0000;
                        vp |= v >> 16;
                        write_dcache040(addr, vp);
-               } else if (currprefs.cpu_cycle_exact) {
+               } else if (currprefs.cpu_memory_cycle_exact) {
                        mem_access_delay_word_write_ce020(addr + 0, v >> 16);
                } else {
                        put_word(addr + 0, v >> 16);
@@ -7639,7 +7835,7 @@ void put_long_cache_040(uaecptr addr, uae_u32 v)
                        vp &= 0x0000ffff;
                        vp |= v << 16;
                        write_dcache040(addr + 4, vp);
-               } else if (currprefs.cpu_cycle_exact) {
+               } else if (currprefs.cpu_memory_cycle_exact) {
                        mem_access_delay_word_write_ce020(addr + 2, v);
                } else {
                        put_word(addr + 2, v);
@@ -7666,7 +7862,7 @@ void put_word_cache_040(uaecptr addr, uae_u32 v)
                        vp |= v << 16;
                }
                write_dcache040(addr, vp);
-       } else if (currprefs.cpu_cycle_exact) {
+       } else if (currprefs.cpu_memory_cycle_exact) {
                mem_access_delay_word_write_ce020(addr, v);
        } else {
                put_word(addr, v);
@@ -7688,7 +7884,7 @@ void put_byte_cache_040(uaecptr addr, uae_u32 v)
                vp &= ~mask;
                vp |= (v << (3 - (addr & 3))) & mask;
                write_dcache040(addr, vp);
-       } else if (currprefs.cpu_cycle_exact) {
+       } else if (currprefs.cpu_memory_cycle_exact) {
                mem_access_delay_byte_write_ce020(addr, v);
        } else {
                put_byte(addr, v);
@@ -7751,7 +7947,7 @@ uae_u32 next_ilong_cache040(void)
 
 void flush_dcache (uaecptr addr, int size)
 {
-       if (!currprefs.cpu_cycle_exact && !currprefs.cpu_compatible)
+       if (!currprefs.cpu_memory_cycle_exact && !currprefs.cpu_compatible)
                return;
        if (currprefs.cpu_model >= 68030) {
                for (int i = 0; i < CACHELINES030; i++) {
@@ -7802,7 +7998,7 @@ void fill_prefetch_020 (void)
        uaecptr pc = m68k_getpc ();
        uaecptr pc2 = pc;
        pc &= ~3;
-       uae_u32 (*fetch)(uaecptr) = currprefs.cpu_cycle_exact ? mem_access_delay_longi_read_ce020 : get_longi;
+       uae_u32 (*fetch)(uaecptr) = currprefs.cpu_memory_cycle_exact ? mem_access_delay_longi_read_ce020 : get_longi;
        regs.pipeline_pos = 0;
        regs.pipeline_stop = 0;
        regs.pipeline_r8[0] = regs.pipeline_r8[1] = -1;
@@ -7841,7 +8037,7 @@ void fill_prefetch (void)
        if (!currprefs.cpu_compatible)
                return;
        if (currprefs.cpu_model >= 68040) {
-               if (currprefs.cpu_compatible || currprefs.cpu_cycle_exact) {
+               if (currprefs.cpu_compatible || currprefs.cpu_memory_cycle_exact) {
                        fill_icache040(m68k_getpc() + 16);
                        fill_icache040(m68k_getpc());
                }