]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
If interrupt level increased during 68040/060 MMU fault handler execution, interrupt...
authorToni Wilen <twilen@winuae.net>
Thu, 28 Dec 2023 09:59:31 +0000 (11:59 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 28 Dec 2023 09:59:31 +0000 (11:59 +0200)
cpummu.cpp
include/custom.h
include/newcpu.h
newcpu.cpp

index aa1fc95cab841d4cb96b3a9c7ff214c46ba648ba..4123a5a29172e2d0652f12b1521120e3b100e0bb 100644 (file)
@@ -1563,6 +1563,9 @@ void m68k_do_rte_mmu040 (uaecptr a7)
                write_log (_T("MMU restarted MOVEM EA=%08X\n"), mmu040_movem_ea);
 #endif
        }
+       if (currprefs.mmu_model == 68060 || mmu_restart) {
+               set_special(SPCFLAG_MMURESTART);
+       }
 }
 
 void m68k_do_rte_mmu060 (uaecptr a7)
index 16dca1b02a531e03a2513bdd0a422a286dc5a5d8..4ba4b8064aa4caf3b7ab49d70d8731e75ec35b75 100644 (file)
@@ -85,24 +85,6 @@ STATIC_INLINE int dmaen(unsigned int dmamask)
        return (dmamask & dmacon) && (dmacon & 0x200);
 }
 
-#define SPCFLAG_CPUINRESET 2
-#define SPCFLAG_COPPER 4
-#define SPCFLAG_INT 8
-#define SPCFLAG_BRK 16
-#define SPCFLAG_UAEINT 32
-#define SPCFLAG_TRACE 64
-#define SPCFLAG_DOTRACE 128
-#define SPCFLAG_DOINT 256 /* arg, JIT fails without this.. */
-#define SPCFLAG_BLTNASTY 512
-#define SPCFLAG_EXEC 1024
-#define SPCFLAG_ACTION_REPLAY 2048
-#define SPCFLAG_TRAP 4096 /* enforcer-hack */
-#define SPCFLAG_MODE_CHANGE 8192
-#ifdef JIT
-#define SPCFLAG_END_COMPILE 16384
-#endif
-#define SPCFLAG_CHECK 32768
-
 extern uae_u16 adkcon;
 
 extern unsigned int joy0dir, joy1dir;
index d7259166c2a50e62fbf7cc7916cd0af12f0034dc..6eac8ff17621b6c086fca23092e09efc97ad1fb5 100644 (file)
@@ -321,6 +321,25 @@ extern bool m68k_interrupt_delay;
 
 extern void safe_interrupt_set(int, int, bool);
 
+#define SPCFLAG_CPUINRESET 2
+#define SPCFLAG_COPPER 4
+#define SPCFLAG_INT 8
+#define SPCFLAG_BRK 16
+#define SPCFLAG_UAEINT 32
+#define SPCFLAG_TRACE 64
+#define SPCFLAG_DOTRACE 128
+#define SPCFLAG_DOINT 256 /* arg, JIT fails without this.. */
+#define SPCFLAG_BLTNASTY 512
+#define SPCFLAG_EXEC 1024
+#define SPCFLAG_ACTION_REPLAY 2048
+#define SPCFLAG_TRAP 4096 /* enforcer-hack */
+#define SPCFLAG_MODE_CHANGE 8192
+#ifdef JIT
+#define SPCFLAG_END_COMPILE 16384
+#endif
+#define SPCFLAG_CHECK 32768
+#define SPCFLAG_MMURESTART 65536
+
 STATIC_INLINE void set_special_exter(uae_u32 x)
 {
        atomic_or(&regs.spcflags, x);
index 3e74ce3fb2240ef7851e936f46df1b8a58d7cada..f803237ce68207ecf58aa6e1dc102bd92eeff629 100644 (file)
@@ -4614,11 +4614,12 @@ static void debug_cpu_stop(void)
 static int do_specialties (int cycles)
 {
        uaecptr pc = m68k_getpc();
+       uae_atomic spcflags = regs.spcflags;
 
-       if (regs.spcflags & SPCFLAG_MODE_CHANGE)
+       if (spcflags & SPCFLAG_MODE_CHANGE)
                return 1;
        
-       if (regs.spcflags & SPCFLAG_CHECK) {
+       if (spcflags & SPCFLAG_CHECK) {
                if (regs.halted) {
                        if (regs.halted == CPU_HALT_ACCELERATOR_CPU_FALLBACK) {
                                return 1;
@@ -4632,8 +4633,10 @@ static int do_specialties (int cycles)
                        int vsyncstate = -1;
                        while (vsynccnt > 0 && !quit_program) {
                                x_do_cycles(8 * CYCLE_UNIT);
-                               if (regs.spcflags & SPCFLAG_COPPER)
+                               spcflags = regs.spcflags;
+                               if (spcflags & SPCFLAG_COPPER) {
                                        do_copper();
+                               }
                                if (vsync_counter != vsyncstate) {
                                        vsyncstate = vsync_counter;
                                        vsynccnt--;
@@ -4646,7 +4649,7 @@ static int do_specialties (int cycles)
 
 #ifdef ACTION_REPLAY
 #ifdef ACTION_REPLAY_HRTMON
-       if ((regs.spcflags & SPCFLAG_ACTION_REPLAY) && hrtmon_flag != ACTION_REPLAY_INACTIVE) {
+       if ((spcflags & SPCFLAG_ACTION_REPLAY) && hrtmon_flag != ACTION_REPLAY_INACTIVE) {
                int isinhrt = pc >= hrtmem_start && pc < hrtmem_start + hrtmem_size;
                /* exit from HRTMon? */
                if (hrtmon_flag == ACTION_REPLAY_ACTIVE && !isinhrt)
@@ -4658,7 +4661,7 @@ static int do_specialties (int cycles)
                        hrtmon_enter();
        }
 #endif
-       if ((regs.spcflags & SPCFLAG_ACTION_REPLAY) && action_replay_flag != ACTION_REPLAY_INACTIVE) {
+       if ((spcflags & SPCFLAG_ACTION_REPLAY) && action_replay_flag != ACTION_REPLAY_INACTIVE) {
                /*if (action_replay_flag == ACTION_REPLAY_ACTIVE && !is_ar_pc_in_rom ())*/
                /*      write_log (_T("PC:%p\n"), m68k_getpc ());*/
 
@@ -4677,26 +4680,28 @@ static int do_specialties (int cycles)
        }
 #endif
 
-       if (regs.spcflags & SPCFLAG_COPPER)
+       if (spcflags & SPCFLAG_COPPER) {
                do_copper();
+       }
 
 #ifdef JIT
-       if (regs.spcflags & SPCFLAG_END_COMPILE) {
+       if (spcflags & SPCFLAG_END_COMPILE) {
                unset_special(SPCFLAG_END_COMPILE);
        }
 #endif
 
-       while ((regs.spcflags & SPCFLAG_CPUINRESET)) {
+       while (spcflags & SPCFLAG_CPUINRESET) {
                x_do_cycles(4 * CYCLE_UNIT);
-               if (regs.spcflags & SPCFLAG_COPPER) {
+               spcflags = regs.spcflags;
+               if (spcflags & SPCFLAG_COPPER) {
                        do_copper();
                }
-               if (!(regs.spcflags & SPCFLAG_CPUINRESET) || (regs.spcflags & SPCFLAG_BRK) || (regs.spcflags & SPCFLAG_MODE_CHANGE)) {
+               if (!(spcflags & SPCFLAG_CPUINRESET) || (spcflags & SPCFLAG_BRK) || (spcflags & SPCFLAG_MODE_CHANGE)) {
                        break;
                }
        }
 
-       while ((regs.spcflags & SPCFLAG_BLTNASTY) && dmaen (DMA_BLITTER) && cycles > 0 && ((currprefs.waiting_blits && currprefs.cpu_model >= 68020) || !currprefs.blitter_cycle_exact)) {
+       while ((spcflags & SPCFLAG_BLTNASTY) && dmaen (DMA_BLITTER) && cycles > 0 && ((currprefs.waiting_blits && currprefs.cpu_model >= 68020) || !currprefs.blitter_cycle_exact)) {
                int c = blitnasty();
                if (c < 0) {
                        break;
@@ -4708,7 +4713,8 @@ static int do_specialties (int cycles)
                        c = 4;
                }
                x_do_cycles(c * CYCLE_UNIT);
-               if (regs.spcflags & SPCFLAG_COPPER)
+               spcflags = regs.spcflags;
+               if (spcflags & SPCFLAG_COPPER)
                        do_copper();
 #ifdef WITH_PPC
                if (ppc_state)  {
@@ -4719,43 +4725,51 @@ static int do_specialties (int cycles)
 #endif
        }
 
-       if (regs.spcflags & SPCFLAG_DOTRACE)
-               Exception(9);
+       if (spcflags & SPCFLAG_MMURESTART) {
+               // can't have interrupt when 040/060 CPU reruns faulted instruction
+               unset_special(SPCFLAG_MMURESTART);
+       } else {
 
-       if (regs.spcflags & SPCFLAG_TRAP) {
-               unset_special (SPCFLAG_TRAP);
-               Exception(3);
-       }
+               if (spcflags & SPCFLAG_DOTRACE) {
+                       Exception(9);
+               }
 
-       if (regs.spcflags & SPCFLAG_TRACE)
-               do_trace();
+               if (spcflags & SPCFLAG_TRAP) {
+                       unset_special (SPCFLAG_TRAP);
+                       Exception(3);
+               }
 
-       if (regs.spcflags & SPCFLAG_UAEINT) {
-               check_uae_int_request();
-               unset_special(SPCFLAG_UAEINT);
-       }
+               if (spcflags & SPCFLAG_TRACE) {
+                       do_trace();
+               }
 
-       if (m68k_interrupt_delay) {
-               int ipl = time_for_interrupt();
-               if (ipl) {
-                       unset_special(SPCFLAG_INT);
-                       do_interrupt(ipl);
+               if (spcflags & SPCFLAG_UAEINT) {
+                       check_uae_int_request();
+                       unset_special(SPCFLAG_UAEINT);
                }
-       } else {
-               if (regs.spcflags & SPCFLAG_INT) {
-                       int intr = intlev();
-                       unset_special (SPCFLAG_INT | SPCFLAG_DOINT);
-                       if (intr > 0 && (intr > regs.intmask || intr == 7))
-                               do_interrupt(intr);
+
+               if (m68k_interrupt_delay) {
+                       int ipl = time_for_interrupt();
+                       if (ipl) {
+                               unset_special(SPCFLAG_INT);
+                               do_interrupt(ipl);
+                       }
+               } else {
+                       if (spcflags & SPCFLAG_INT) {
+                               int intr = intlev();
+                               unset_special (SPCFLAG_INT | SPCFLAG_DOINT);
+                               if (intr > 0 && (intr > regs.intmask || intr == 7))
+                                       do_interrupt(intr);
+                       }
                }
-       }
 
-       if (regs.spcflags & SPCFLAG_DOINT) {
-               unset_special(SPCFLAG_DOINT);
-               set_special(SPCFLAG_INT);
+               if (spcflags & SPCFLAG_DOINT) {
+                       unset_special(SPCFLAG_DOINT);
+                       set_special(SPCFLAG_INT);
+               }
        }
 
-       if (regs.spcflags & SPCFLAG_BRK) {
+       if (spcflags & SPCFLAG_BRK) {
                unset_special(SPCFLAG_BRK);
 #ifdef DEBUGGER
                if (debugging) {
@@ -5117,7 +5131,9 @@ static bool m68k_cs_initialized;
 
 static int do_specialties_thread(void)
 {
-       if (regs.spcflags & SPCFLAG_MODE_CHANGE)
+       uae_atomic spcflags = regs.spcflags;
+
+       if (spcflags & SPCFLAG_MODE_CHANGE)
                return 1;
 
 #ifdef JIT
@@ -5126,20 +5142,20 @@ static int do_specialties_thread(void)
        }
 #endif
 
-       if (regs.spcflags & SPCFLAG_DOTRACE)
+       if (spcflags & SPCFLAG_DOTRACE)
                Exception(9);
 
-       if (regs.spcflags & SPCFLAG_TRAP) {
+       if (spcflags & SPCFLAG_TRAP) {
                unset_special(SPCFLAG_TRAP);
                Exception(3);
        }
 
-       if (regs.spcflags & SPCFLAG_TRACE)
+       if (spcflags & SPCFLAG_TRACE)
                do_trace();
 
        for (;;) {
 
-               if (regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)) {
+               if (spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)) {
                        return 1;
                }