]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Yet another STOP emulation rewrite. Not yet fully cputester validated.
authorToni Wilen <twilen@winuae.net>
Mon, 11 Jul 2022 08:40:18 +0000 (11:40 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 11 Jul 2022 08:40:18 +0000 (11:40 +0300)
cia.cpp
cputest.cpp
cputest/main.c
debug.cpp
gencpu.cpp
include/cpu_prefetch.h
include/custom.h
include/debug.h
include/newcpu.h
newcpu.cpp

diff --git a/cia.cpp b/cia.cpp
index d7236dda3163b907c33b813a75e073279fb1c12f..d7efa40e3d3ffe56a580cb44dfb2ecf2466fe720 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -2747,7 +2747,7 @@ static void REGPARAM2 clock_bput(uaecptr addr, uae_u32 value)
 //     write_log(_T("W: %x (%x): %x, PC=%08x\n"), addr, (addr & 0xff) >> 2, value & 0xff, M68K_GETPC);
 
        if (currprefs.cputester && (addr & 65535) == 0) {
-               event2_newevent_xx(-1, CYCLE_UNIT * (62 / 2), 0, cputester_event);
+               event2_newevent_xx(-1, CYCLE_UNIT * (64 / 2 - 1), 0, cputester_event);
        }
 
        if ((addr & 0xffff) >= 0x8000 && currprefs.cs_fatgaryrev >= 0) {
index 18c9442fbfd4b2adbfad258229427f9fb12096a3..7e01e081ad43e04f1eba8eab091002b03bca66e1 100644 (file)
@@ -126,7 +126,7 @@ static int max_storage_buffer;
 static bool out_of_test_space;
 static uaecptr out_of_test_space_addr;
 static int forced_immediate_mode;
-static int test_exception;
+static int test_exception, test_exception_orig;
 static int test_exception_extra;
 static int exception_stack_frame_size;
 static uae_u8 exception_extra_frame[100];
@@ -522,7 +522,7 @@ void put_byte_test(uaecptr addr, uae_u32 v)
                return;
        if (feature_interrupts >= 2 && addr == IPL_TRIGGER_ADDR) {
                add_memory_cycles(1);
-               interrupt_cycle_cnt = INTERRUPT_CYCLES - 2;
+               interrupt_cycle_cnt = INTERRUPT_CYCLES;
                return;
        }
        check_bus_error(addr, 1, regs.s ? 5 : 1);
@@ -830,7 +830,7 @@ bool is_cycle_ce(uaecptr addr)
 void ipl_fetch(void)
 {
        if (regs.ipl_pin) {
-               regs.ipl = regs.ipl_pin;
+               regs.ipl[0] = regs.ipl_pin;
        }
 }
 
@@ -839,6 +839,11 @@ int intlev(void)
        return interrupt_level;
 }
 
+void do_cycles_stop(int c)
+{
+       do_cycles_test(c);
+}
+
 uae_u32(*x_get_long)(uaecptr);
 uae_u32(*x_get_word)(uaecptr);
 uae_u32(*x_get_byte)(uaecptr);
@@ -905,6 +910,10 @@ static void activate_trace(void)
 
 static void do_trace(void)
 {
+       if (cpu_stopped) {
+               m68k_incpci(4);
+               cpu_stopped = 0;
+       }
        regs.trace_pc = regs.pc;
        if (regs.t0 && !regs.t1 && currprefs.cpu_model >= 68020) {
                // this is obsolete
@@ -1020,13 +1029,7 @@ void cpu_halt(int halt)
 
 void m68k_setstopped(void)
 {
-       /* A traced STOP instruction drops through immediately without
-       actually stopping.  */
-       if (SPCFLAG_DOTRACE == 0) {
-               cpu_stopped = 1;
-       } else {
-               cpu_stopped = 0;
-       }
+       cpu_stopped = 1;
 }
 
 void check_t0_trace(void)
@@ -1475,13 +1478,15 @@ uae_u16 exception3_word_read(uaecptr addr)
 
 void REGPARAM2 Exception(int n)
 {
+       if (cpu_stopped) {
+               m68k_incpci(4);
+               cpu_stopped = 0;
+       }
+
        test_exception = n;
        test_exception_addr = m68k_getpci();
        test_exception_opcode = -1;
        doexcstack();
-       if (n >= 24 && n < 24 + 8) {
-               cpu_stopped = 0;
-       }
 }
 void REGPARAM2 Exception_cpu_oldpc(int n, uaecptr oldpc)
 {
@@ -2085,25 +2090,25 @@ static uae_u8 *store_fpureg(uae_u8 *dst, uae_u8 mode, floatx80 *s, floatx80 d, i
        }
        uae_u8 fs[10], fd[10];
        fs[0] = s->high >> 8;
-       fs[1] = s->high;
-       fs[2] = s->low >> 56;
-       fs[3] = s->low >> 48;
-       fs[4] = s->low >> 40;
-       fs[5] = s->low >> 32;
-       fs[6] = s->low >> 24;
-       fs[7] = s->low >> 16;
-       fs[8] = s->low >> 8;
-       fs[9] = s->low >> 0;
+       fs[1] = (uae_u8)s->high;
+       fs[2] = (uae_u8)(s->low >> 56);
+       fs[3] = (uae_u8)(s->low >> 48);
+       fs[4] = (uae_u8)(s->low >> 40);
+       fs[5] = (uae_u8)(s->low >> 32);
+       fs[6] = (uae_u8)(s->low >> 24);
+       fs[7] = (uae_u8)(s->low >> 16);
+       fs[8] = (uae_u8)(s->low >> 8);
+       fs[9] = (uae_u8)(s->low >> 0);
        fd[0] = d.high >> 8;
-       fd[1] = d.high;
-       fd[2] = d.low >> 56;
-       fd[3] = d.low >> 48;
-       fd[4] = d.low >> 40;
-       fd[5] = d.low >> 32;
-       fd[6] = d.low >> 24;
-       fd[7] = d.low >> 16;
-       fd[8] = d.low >> 8;
-       fd[9] = d.low >> 0;
+       fd[1] = (uae_u8)d.high;
+       fd[2] = (uae_u8)(d.low >> 56);
+       fd[3] = (uae_u8)(d.low >> 48);
+       fd[4] = (uae_u8)(d.low >> 40);
+       fd[5] = (uae_u8)(d.low >> 32);
+       fd[6] = (uae_u8)(d.low >> 24);
+       fd[7] = (uae_u8)(d.low >> 16);
+       fd[8] = (uae_u8)(d.low >> 8);
+       fd[9] = (uae_u8)(d.low >> 0);
        *dst++ = mode | CT_SIZE_FPU;
        if (fs[4] != fd[4] || fs[5] != fd[5]) {
                *dst++ = 0xff;
@@ -2460,7 +2465,7 @@ static int putfpuimm(uaecptr addr, int opcodesize, int *isconstant)
                fpu_imm_cnt++;
                put_long_test(addr + 0, v.high);
                put_long_test(addr + 4, v.low >> 32);
-               put_long_test(addr + 8, v.low);
+               put_long_test(addr + 8, (uae_u32)v.low);
                addr += 12;
                break;
        }
@@ -2492,7 +2497,7 @@ static int putfpuimm(uaecptr addr, int opcodesize, int *isconstant)
                fpu_imm_cnt++;
                float64 v2 = floatx80_to_float64(v, &fpustatus);
                put_long_test(addr + 0, v2 >> 32);
-               put_long_test(addr + 4, v2);
+               put_long_test(addr + 4, (uae_u32)v2);
                addr += 8;
                break;
        }
@@ -3051,7 +3056,11 @@ static int create_ea_random(uae_u16 *opcodep, uaecptr pc, int mode, int reg, str
                                        put_word_test(pc, imm16_cnt);
                                        if (dp->mnemo == i_STOP && feature_interrupts > 0) {
                                                // STOP hack to keep STOP test size smaller.
-                                               imm16_cnt += 0x0100;
+                                               if (feature_interrupts > 1) {
+                                                       imm16_cnt += 0x0100;
+                                               } else {
+                                                       imm16_cnt += 0x0001;
+                                               }
                                        } else {
                                                imm16_cnt += 0x0001;
                                        }
@@ -3907,6 +3916,14 @@ static bool check_interrupts(void)
        return false;
 }
 
+static int get_ipl(void)
+{
+       if (cpu_cycles + 4 > regs.ipl_time) {
+               return regs.ipl[0];
+       }
+       return regs.ipl[1];
+}
+
 static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool fpumode)
 {
        uae_u16 opc = regs.ir;
@@ -3950,13 +3967,16 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
        cpu_cycles = 0;
        regs.loop_mode = 0;
        regs.ipl_pin = 0;
-       regs.ipl = 0;
+       regs.ipl[0] = regs.ipl[1] = 0;
+       regs.ipl_time = 0;
        interrupt_level = 0;
        interrupt_cycle_cnt = 0;
+       test_exception_orig = 0;
 
        int cnt = 2;
        uaecptr first_pc = regs.pc;
        uae_u32 loop_mode_reg = 0;
+       int stop_count = 0;
 
        if (feature_loop_mode_68010) {
                // 68010 loop mode
@@ -3990,7 +4010,7 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                        abort();
                }
 
-               if (SPCFLAG_TRACE && !cpu_stopped) {
+               if (SPCFLAG_TRACE) {
                        do_trace();
                }
 
@@ -4012,24 +4032,14 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                }
 
                if (cpu_stopped) {
-                       if (feature_interrupts && !interrupt_cycle_cnt) {
-                               test_exception = -1;
+                       stop_count++;
+                       if (stop_count > 256) {
                                break;
                        }
-                       ipl_fetch();
-                       do_cycles_test(4);
-                       if (!SPCFLAG_DOTRACE && regs.s == 0 && currprefs.cpu_model <= 68010) {
-                               // 68000/68010 undocumented special case:
-                               // if STOP clears S-bit and T was not set:
-                               // cause privilege violation exception, PC pointing to following instruction.
-                               // If T was set before STOP: STOP works as documented.
-                               cpu_stopped = 0;
-                               Exception(8);
-                       }
-               } else {
-                       (*cpufunctbl[opc])(opc);
                }
 
+               (*cpufunctbl[opc])(opc);
+
                if (fpumode) {
                        // skip result has too large or small exponent
                        for (int i = 0; i < 8; i++) {
@@ -4060,6 +4070,7 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                if (out_of_test_space) {
                        break;
                }
+
                // CPU stopped or was reset: skip
                if (cpu_stopped && feature_interrupts < 2) {
                        break;
@@ -4086,17 +4097,18 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                        break;
                }
 
-               if (!test_exception && regs.ipl > regs.intmask) {
-                       Exception(24 + regs.ipl);
+               if (get_ipl() > regs.intmask) {
+                       Exception(24 + get_ipl());
                        break;
                }
 
-               if ((regs.pc == endpc || regs.pc == targetpc) && !cpu_stopped) {
+               if ((regs.pc == endpc || regs.pc == targetpc) && !cpu_stopped && feature_interrupts < 2) {
                        // Trace is only added as an exception if there was no other exceptions
                        // Trace stacked with other exception is handled later
                        if (SPCFLAG_DOTRACE && !test_exception && trace_store_pc == 0xffffffffff) {
                                Exception(9);
                        }
+
                        break;
                }
 
@@ -4117,11 +4129,6 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                                        trace_store_sr = regs.sr;
                                        SPCFLAG_DOTRACE = 0;
                                }
-                               // STOP can only end with exception, fake prefetch here.
-                               if (dp->mnemo == i_STOP) {
-                                       regs.ir = get_iword_test(regs.pc + 0);
-                                       regs.irc = get_iword_test(regs.pc + 2);
-                               }
                        }
                        if (currprefs.cpu_model >= 68020) {
                                regs.ir = get_iword_test(regs.pc + 0);
@@ -4148,12 +4155,20 @@ static void execute_ins(uaecptr endpc, uaecptr targetpc, struct instr *dp, bool
                opc = regs.ir;
        }
 
+       test_exception_orig = test_exception;
+
+       // if still stopped: skip test
+       if (cpu_stopped) {
+               test_exception = -1;
+       }
+
        if (feature_interrupts >= 2) {
-               // IPL test must cause some exception
-               if (!test_exception || test_exception == 8) {
+               // Skip test if end exception
+               if (regs.pc == endpc || regs.pc == targetpc) {
                        test_exception = -1;
                }
-               if (cpu_stopped) {
+               // Skip test if no exception
+               if (!test_exception) {
                        test_exception = -1;
                }
                // Interrupt start must be before test instruction,
@@ -4198,7 +4213,7 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
        // Separate, non-stacked Trace
        if (test_exception_extra & 0x80) {
                *p++ = trace_store_sr >> 8;
-               *p++ = trace_store_sr;
+               *p++ = (uae_u8)trace_store_sr;
                p = store_rel(p, 0, opcode_memory_start, trace_store_pc, 1);
        }
        uae_u8 *sf = NULL;
@@ -4221,7 +4236,7 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
                                *p++ = sf[7];
                                if (st & 0x20) {
                                        *p++ = regs.opcode >> 8;
-                                       *p++ = regs.opcode;
+                                       *p++ = (uae_u8)regs.opcode;
                                }
                                // access address
                                p = store_rel(p, 0, opcode_memory_start, gl(sf + 2), 1);
@@ -4281,7 +4296,7 @@ static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
                                *p++ = sf[25];
                                // optional data input (some hardware does real memory fetch when CPU does the dummy fetch, some don't)
                                *p++ = read_buffer_prev >> 8;
-                               *p++ = read_buffer_prev;
+                               *p++ = (uae_u8)read_buffer_prev;
                                break;
                        case 0x0a: // 68020/030 address error.
                        case 0x0b: // Don't save anything extra, too many undefined fields and bits..
@@ -4653,6 +4668,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                int branch_target_swap_mode_old = 0;
                int doopcodeswap = 1;
 
+               if (feature_interrupts >= 2) {
+                       doopcodeswap = 0;
+               }
+
                if (verbose) {
                        if (target_ea[0] != 0xffffffff)
                                wprintf(_T(" Target EA SRC=%08x\n"), target_ea[0]);
@@ -5593,7 +5612,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        if (regs.sr & 0x2000)
                                                                prev_s_cnt++;
 
-                                                       if (subtest_count == 433)
+                                                       if (subtest_count == 19)
                                                                printf("");
 
                                                        // execute test instruction(s)
@@ -5627,7 +5646,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                        }
 
                                                        // exception check disabled
-                                                       if (!exceptionenabletable[test_exception]) {
+                                                       if (test_exception < 0 || !exceptionenabletable[test_exception]) {
                                                                skipped = 1;
                                                        }
 
@@ -5921,8 +5940,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, const TCHAR *ovrfi
                                                }
                                        }
                                        if (verbose) {
-                                               wprintf(_T(" OK=%d OB=%d S=%d/%d T=%d STP=%d I=%d/%d %08x"), ok, exception_array[0],
-                                                       prev_s_cnt, s_cnt, t_cnt, cnt_stopped, interrupt_delay_cnt, interrupt_cycle_cnt, test_exception_addr);
+                                               wprintf(_T(" OK=%d OB=%d S=%d/%d T=%d STP=%d I=%d/%d EX=%d %08x %08x"), ok, exception_array[0],
+                                                       prev_s_cnt, s_cnt, t_cnt, cnt_stopped, interrupt_delay_cnt, interrupt_cycle_cnt,
+                                                       test_exception_orig,
+                                                       test_exception_addr, regs.pc);
                                                if (!ccr_done)
                                                        wprintf(_T(" X"));
                                                for (int i = 2; i < 128; i++) {
index b608c30fdb24d13ee69c7c19e7d525401ab0f796..5e14e98b4ba1675646b817736ff6274de8953152 100644 (file)
@@ -128,6 +128,7 @@ static int errors;
 static int totalerrors;
 static int testcnt;
 static short testcntsub, testcntsubmax;
+static int invalidcycles;
 static int fpu_approx, fpu_approxcnt;
 static short dooutput = 1;
 static short quit;
@@ -1696,7 +1697,6 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, short excnu
        uae_u8 *sp = (uae_u8*)regs->excframe;
        uae_u32 v;
        uae_u8 excdatalen = *p++;
-       int size;
        int excrwp = 0;
        int alts = 0;
 
@@ -2172,6 +2172,13 @@ static int check_cycles(int exc, short extratrace, short extrag2w1, struct regis
 {
        int gotcycles = 0;
 
+       if ((test_regs.cycles >> 16) == 0xffff) {
+               // cycle counter got exception (interrupt) during exception handling
+               // -> cycle counter was invalidated. Ignore cycle count.
+               invalidcycles++;
+               return 1;
+       }
+
        if (cyclecounter_addr != 0xffffffff) {
                gotcycles = (test_regs.cycles & 0xffff) - (test_regs.cycles >> 16);
                if (gotcycles == 0) {
@@ -2257,7 +2264,7 @@ static int check_cycles(int exc, short extratrace, short extrag2w1, struct regis
 
        if (0 || abs(gotcycles - expectedcycles) > cycles_range) {
                addinfo();
-               sprintf(outbp, "Got %d cycles (%d + %d) but expected %d (%d + %d) cycles\n",
+               sprintf(outbp, "Got %d cycles (%d + %d) but expected %d (%d + %d)\n",
                        gotcycles, gotcycles - exceptioncycles, exceptioncycles,
                        expectedcycles, expectedcycles - exceptioncycles, exceptioncycles);
                outbp += strlen(outbp);
@@ -2944,6 +2951,10 @@ static void out_endinfo(void)
                        outbp += strlen(outbp);
                }
        }
+       if (invalidcycles) {
+               sprintf(outbp, " INVCYC=%d", invalidcycles);
+               outbp += strlen(outbp);
+       }
        strcat(outbp, "\n");
        outbp += strlen(outbp);
        if (fpu_approxcnt) {
@@ -3018,6 +3029,10 @@ static void process_test(uae_u8 *p)
 
        short doopcodeswap = 1;
 
+       if (interrupttest >= 1) {
+               doopcodeswap = 0;
+       }
+
        for (;;) {
 
                cur_regs.endpc = endpc;
@@ -3403,7 +3418,7 @@ static int test_mnemo(const char *opcode)
        int size;
        uae_u8 data[4] = { 0 };
        uae_u32 v;
-       char fname[256], tfname[256];
+       char tfname[256];
        int filecnt = 1;
        uae_u32 starttimeid;
        int lvl;
index 09a66aa685596a98683fb06ec9e1350d6950c83c..b32dbf81a229497e759a20d10a4b18685741ab6d 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -179,6 +179,7 @@ static const TCHAR help[] = {
        _T("  a <address>           Assembler.\n")
        _T("  d <address> [<lines>] Disassembly starting at <address>.\n")
        _T("  t [instructions]      Step one or more instructions.\n")
+       _T("  tx                    Break when any exception.\n")
        _T("  z                     Step through one instruction - useful for JSR, DBRA etc.\n")
        _T("  f                     Step forward until PC in RAM (\"boot block finder\").\n")
        _T("  f <address>           Add/remove breakpoint.\n")
@@ -1401,7 +1402,7 @@ static void set_dbg_color(int index, int extra, uae_u8 r, uae_u8 g, uae_u8 b, in
        if (extra >= 0) {
                debug_colors[index].l[extra] = lc((r << 16) | (g << 8) | (b << 0));
        } else {
-               for (int i = 0; i < DMARECORD_SUBITEMS; i++) {
+               for (int i = 0; i < DMARECORD_MAX; i++) {
                        debug_colors[index].l[i] = lc((r << 16) | (g << 8) | (b << 0));
                }
        }
@@ -1417,7 +1418,7 @@ static void set_debug_colors(void)
        set_dbg_color(DMARECORD_CPU,                    0, 0xa2, 0x53, 0x42, 2, _T("CPU")); // code
        set_dbg_color(DMARECORD_COPPER,                 0, 0xee, 0xee, 0x00, 3, _T("Copper"));
        set_dbg_color(DMARECORD_AUDIO,                  0, 0xff, 0x00, 0x00, 4, _T("Audio"));
-       set_dbg_color(DMARECORD_BLITTER,                0, 0x00, 0x88, 0x88, 2, _T("Blitter")); // blit A
+       set_dbg_color(DMARECORD_BLITTER,                0, 0x00, 0x88, 0x88, 2, _T("Blitter"));
        set_dbg_color(DMARECORD_BITPLANE,               0, 0x00, 0x00, 0xff, 8, _T("Bitplane"));
        set_dbg_color(DMARECORD_SPRITE,                 0, 0xff, 0x00, 0xff, 8, _T("Sprite"));
        set_dbg_color(DMARECORD_DISK,                   0, 0xff, 0xff, 0xff, 3, _T("Disk"));
@@ -1432,11 +1433,8 @@ static void set_debug_colors(void)
        set_dbg_color(DMARECORD_CPU,                    1, 0xad, 0x98, 0xd6, 0, NULL); // data
        set_dbg_color(DMARECORD_COPPER,                 1, 0xaa, 0xaa, 0x22, 0, NULL); // wait
        set_dbg_color(DMARECORD_COPPER,                 2, 0x66, 0x66, 0x44, 0, NULL); // special
-       set_dbg_color(DMARECORD_BLITTER,                1, 0x00, 0x88, 0x88, 0, NULL); // blit B
-       set_dbg_color(DMARECORD_BLITTER,                2, 0x00, 0x88, 0x88, 0, NULL); // blit C
-       set_dbg_color(DMARECORD_BLITTER,                3, 0x00, 0xaa, 0x88, 0, NULL); // blit D (write)
-       set_dbg_color(DMARECORD_BLITTER,                4, 0x00, 0x88, 0xff, 0, NULL); // fill A-D
-       set_dbg_color(DMARECORD_BLITTER,                6, 0x00, 0xff, 0x00, 0, NULL); // line A-D
+       set_dbg_color(DMARECORD_BLITTER,                1, 0x00, 0x88, 0xff, 0, NULL); // fill
+       set_dbg_color(DMARECORD_BLITTER,                2, 0x00, 0xff, 0x00, 0, NULL); // line
 }
 
 static int cycles_toggle;
@@ -1477,20 +1475,10 @@ static void debug_draw_cycles (uae_u8 *buf, int bpp, int line, int width, int he
                uae_u32 c = debug_colors[0].l[0];
                xx = x * xplus + dx;
                dr = &dma_record[t][y * NR_DMA_REC_HPOS + x];
-
                if (dr->reg != 0xffff && debug_colors[dr->type].enabled) {
-                       // General DMA slots
-                       c = debug_colors[dr->type].l[dr->extra & 7];
-
-                       // Special cases
+                       c = debug_colors[dr->type].l[dr->extra];
                        if (dr->cf_reg != 0xffff && ((cycles_toggle ^ line) & 1)) {
                                c = debug_colors[DMARECORD_CONFLICT].l[0];
-                       } else if (dr->extra > 0xF) {
-                               // High bits of "extra" contain additional blitter state.
-                               if (dr->extra & 0x10)
-                                       c = debug_colors[dr->type].l[4]; // blit fill, channels A-D
-                               else if (dr->extra & 0x20)
-                                       c = debug_colors[dr->type].l[6]; // blit line, channels A-D
                        }
                }
                if (dr->intlev > intlev)
@@ -2103,9 +2091,7 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, evt_t cy
 
        sr = _T("    ");
        if (dr->type == DMARECORD_COPPER) {
-               if (br == 2)
-                       sr = _T("COPS");
-               else if (br == 1)
+               if (dr->extra == 3)
                        sr = _T("COPW");
                else
                        sr = _T("COP ");
@@ -6153,6 +6139,11 @@ static bool debug_line (TCHAR *input)
                                        trace_param[1] = debugmem_get_sourceline(M68K_GETPC, NULL, 0);
                                        return true;
                                }
+                       } else if (*inptr == 'x') {
+                               trace_mode = TRACE_SKIP_INS;
+                               trace_param[0] = 0xffffffff;
+                               exception_debugging = 1;
+                               return true;
                        } else {
                                if (more_params(&inptr))
                                        trace_param[0] = readint(&inptr);
@@ -6561,22 +6552,26 @@ static void debug_1 (void)
        }
 }
 
-static void addhistory (void)
+static void addhistory(void)
 {
-       if (regs.stopped)
-               return;
-
        uae_u32 pc = currprefs.cpu_model >= 68020 && currprefs.cpu_compatible ? regs.instruction_pc : m68k_getpc();
+       int prevhist = lasthist == 0 ? MAX_HIST - 1 : lasthist - 1;
+       if (history[prevhist].regs.pc == pc) {
+               return;
+       }
        history[lasthist].regs = regs;
        history[lasthist].regs.pc = pc;
        history[lasthist].vpos = vpos;
        history[lasthist].hpos = current_hpos();
        history[lasthist].fp = timeframes;
 
-       if (++lasthist == MAX_HIST)
+       if (++lasthist == MAX_HIST) {
                lasthist = 0;
+       }
        if (lasthist == firsthist) {
-               if (++firsthist == MAX_HIST) firsthist = 0;
+               if (++firsthist == MAX_HIST) {
+                       firsthist = 0;
+               }
        }
 }
 
@@ -6585,6 +6580,19 @@ static void debug_continue(void)
        set_special (SPCFLAG_BRK);
 }
 
+void debug_exception(int nr)
+{
+       if (debug_illegal) {
+               if (nr <= 63 && (debug_illegal_mask & ((uae_u64)1 << nr))) {
+                       write_log(_T("Exception %d breakpoint\n"), nr);
+                       activate_debugger();
+               }
+       }
+       if (trace_param[0] == 0xffffffff && trace_mode == TRACE_SKIP_INS) {
+               activate_debugger();
+       }
+}
+
 void debug (void)
 {
        int i;
@@ -6726,7 +6734,7 @@ void debug (void)
                                                }
                                        }
                                } else if (trace_mode == TRACE_SKIP_INS) {
-                                       if (trace_param[0] != 0)
+                                       if (trace_param[0] != 0 && trace_param[0] != 0xffffffff)
                                                trace_param[0]--;
                                        if (trace_param[0] == 0) {
                                                bp = -1;
@@ -6783,9 +6791,16 @@ void debug (void)
 
        if (trace_cycles && last_frame >= 0) {
                if (last_frame + 2 >= timeframes || trace_cycles > 1) {
+                       evt_t c = last_cycles2 - last_cycles1;
+                       uae_u32 cc;
+                       if (c >= 0x7fffffff) {
+                               cc = 0x7fffffff;
+                       } else {
+                               cc = (uae_u32)c;
+                       }
                        console_out_f(_T("Cycles: %d Chip, %d CPU. (V=%d H=%d -> V=%d H=%d)\n"),
-                               (last_cycles2 - last_cycles1) / CYCLE_UNIT,
-                               (last_cycles2 - last_cycles1) / cpucycleunit,
+                               cc / CYCLE_UNIT,
+                               cc / cpucycleunit,
                                last_vpos1, last_hpos1,
                                last_vpos2, last_hpos2);
                }
index 3d4c04fb0a7d77ed079bd834f3e01a663ac37723..6e5fef5896ce661f931d26dafc6c53a0e58933b7 100644 (file)
@@ -6657,16 +6657,19 @@ static void gen_opcode (unsigned int opcode)
                break;
        case i_STOP:
        {
+               const char *reg = cpu_level <= 1 ? "irc" : "ir";
+               out("if (!regs.stopped) {\n");
                if (using_prefetch) {
-                       out("uae_u16 sr = regs.irc;\n");
-                       m68k_pc_offset += 2;
+                       out("uae_u16 src = regs.%s;\n", reg);
                } else {
                        genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-                       out("uae_u16 sr = src;\n");
                }
+               out("regs.%s = src;\n", reg);
+               out("}\n");
+               out("uae_u16 sr = regs.%s;\n", reg);
                // STOP undocumented features:
                // if new SR S-bit is not set:
-               // 68000/68010: Update SR, increase PC and then cause privilege violation exception (handled in newcpu)
+               // 68000/68010: Update SR, increase PC and then cause privilege violation exception
                // 68000/68010: Traced STOP runs 4 cycles faster.
                // 68020 68030 68040: STOP works normally
                // 68060: Immediate privilege violation exception
@@ -6676,25 +6679,14 @@ static void gen_opcode (unsigned int opcode)
                        write_return_cycles(0);
                        out("}\n");
                }
-               bool accstop = (cpu_level == 0 || cpu_level == 1) && (using_ce || using_prefetch);
-               if (accstop) {
-                       // if interrupt is pending before SR change: STOP finishes in 4 cycles
-                       out("bool irq = stop_interrupt_pending();\n");
-               }
                out("regs.sr = sr;\n");
                check_ipl_always();
-               makefromsr();
-               if (accstop) {
-                       out("do_cycles_stop(4);\n");
-                       out("if (!irq) {\n");
-                       out("m68k_setstopped();\n");
-                       out("}\n");
-               } else {
-                       out("m68k_setstopped();\n");
-               }
-               sync_m68k_pc();
+               out("MakeFromSR();\n");
+               out("do_cycles_stop(4);\n");
+               out("m68k_setstopped();\n");
                // STOP does not prefetch anything
                did_prefetch = -1;
+               m68k_pc_offset = 0;
                next_cpu_level = cpu_level - 1;
                next_level_000();
                break;
index 6885e1646b2035ae34905d1c899028d0d6795985..4d7a6737747cd293eda766fc3857992b42ab9e8c 100644 (file)
@@ -386,7 +386,9 @@ STATIC_INLINE void do_cycles_ce000 (int clocks)
 
 STATIC_INLINE void ipl_fetch (void)
 {
-       regs.ipl = regs.ipl_pin;
+       regs.ipl[1] = regs.ipl[0];
+       regs.ipl[0] = regs.ipl_pin;
+       regs.ipl_time = get_cycles();
 }
 
 uae_u32 mem_access_delay_word_read (uaecptr addr);
index aae817e8ffc4cc4fd4e0fa213d999d3feb6ff8c0..2ef6a75fa2e877bff14dae04e60af9f866ede9d4 100644 (file)
@@ -81,7 +81,6 @@ STATIC_INLINE int dmaen(unsigned int dmamask)
        return (dmamask & dmacon) && (dmacon & 0x200);
 }
 
-#define SPCFLAG_STOP 2
 #define SPCFLAG_COPPER 4
 #define SPCFLAG_INT 8
 #define SPCFLAG_BRK 16
index 1acbda9c58d6a38e32dbee9e64a10917bcb7e8d2..b881d4bfd616c7986e1861074dfba116b2ac9c7c 100644 (file)
@@ -73,6 +73,7 @@ extern int memwatch_access_validator;
 extern bool debug_sprintf(uaecptr, uae_u32, int);
 extern bool debug_get_prefetch(int idx, uae_u16 *opword);
 extern void debug_hsync(void);
+extern void debug_exception(int);
 
 extern void debug_init_trainer(const TCHAR*);
 extern void debug_trainer_match(void);
index 6a6c59a03696801489d51f578bc2bca5b476025f..8262118500c7ec25eec53cc5afdc68b553d7eaa4 100644 (file)
@@ -201,7 +201,8 @@ struct regstruct
        int halted;
        int exception;
        int intmask;
-       int ipl, ipl_pin;
+       int ipl[2], ipl_pin;
+       evt_t ipl_time;
 
        uae_u32 vbr, sfc, dfc;
 
@@ -689,9 +690,8 @@ extern void REGPARAM3 ExceptionL (int, uaecptr) REGPARAM;
 extern void NMI (void);
 extern void IRQ_forced(int, int);
 extern void prepare_interrupt (uae_u32);
-extern void doint (void);
+extern void doint(void);
 extern void intlev_load(void);
-extern bool stop_interrupt_pending(void);
 extern void dump_counts (void);
 extern int m68k_move2c (int, uae_u32 *);
 extern int m68k_movec2 (int, uae_u32 *);
index 291ea2261c4a5f9c046edc42218a01797c54838f..8b8428767b9e4654e82d4231ca06b2da68a2ae4b 100644 (file)
@@ -104,6 +104,7 @@ static int cachedsets04060, cachedsets04060mask, cachedtag04060mask;
 
 static int cpu_prefs_changed_flag;
 
+int cpuipldelay;
 int cpucycleunit;
 int cpu_tracer;
 
@@ -2030,6 +2031,12 @@ static void build_cpufunctbl (void)
        }
        write_log(_T("\n"));
 
+       if (m68k_interrupt_delay) {
+               cpuipldelay = 4 * cpucycleunit;
+       } else {
+               cpuipldelay = 0;
+       }
+
        set_cpu_caches (true);
        target_cpu_speed();
 }
@@ -2290,7 +2297,6 @@ static void m68k_set_stop(void)
        if (regs.stopped)
                return;
        regs.stopped = 1;
-       set_special(SPCFLAG_STOP);
        if (cpu_last_stop_vpos >= 0) {
                cpu_last_stop_vpos = vpos;
        }
@@ -2299,7 +2305,6 @@ static void m68k_set_stop(void)
 static void m68k_unset_stop(void)
 {
        regs.stopped = 0;
-       unset_special(SPCFLAG_STOP);
        if (cpu_last_stop_vpos >= 0) {
                cpu_stopped_lines += vpos - cpu_last_stop_vpos;
                cpu_last_stop_vpos = vpos;
@@ -3327,12 +3332,10 @@ static void ExceptionX (int nr, uaecptr address, uaecptr oldpc)
        if (oldpc != 0xffffffff) {
                regs.instruction_pc = oldpc;
        }
-       if (debug_illegal && !in_rom(pc)) {
-               if (nr <= 63 && (debug_illegal_mask & ((uae_u64)1 << nr))) {
-                       write_log(_T("Exception %d breakpoint\n"), nr);
-                       activate_debugger();
-               }
-       }
+#ifdef DEBUGGER
+       debug_exception(nr);
+#endif
+       m68k_resumestopped();
 
 #ifdef CPUEMU_13
        if (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68010)
@@ -3396,6 +3399,14 @@ static void bus_error(void)
        } ENDTRY
 }
 
+static int get_ipl(void)
+{
+       if (get_cycles() - cpuipldelay > regs.ipl_time) {
+               return regs.ipl[0];
+       }
+       return regs.ipl[1];
+}
+
 static void do_interrupt (int nr)
 {
        if (debug_dma)
@@ -3408,7 +3419,6 @@ static void do_interrupt (int nr)
                        inprec_playdebug_cpu (2);
        }
 
-       m68k_unset_stop();
        assert (nr < 8 && nr >= 0);
 
        for (;;) {
@@ -3416,7 +3426,7 @@ static void do_interrupt (int nr)
                if (!currprefs.cpu_compatible || currprefs.cpu_model == 68060)
                        break;
                if (m68k_interrupt_delay)
-                       nr = regs.ipl;
+                       nr = get_ipl();
                else
                        nr = intlev();
                if (nr <= 0 || regs.intmask >= nr)
@@ -3471,7 +3481,7 @@ static void m68k_reset2(bool hardreset)
 
        regs.spcflags = 0;
        m68k_reset_delay = 0;
-       regs.ipl = regs.ipl_pin = 0;
+       regs.ipl[0] = regs.ipl[1] = regs.ipl_pin = 0;
        for (int i = 0; i < IRQ_SOURCE_MAX; i++) {
                uae_interrupts2[i] = 0;
                uae_interrupts6[i] = 0;
@@ -4345,9 +4355,10 @@ static bool uae_ppc_poll_check_halt(void)
 
 
 // handle interrupt delay (few cycles)
-STATIC_INLINE bool time_for_interrupt (void)
+static bool time_for_interrupt(void)
 {
-       return regs.ipl > regs.intmask || regs.ipl == 7;
+       int ipl = get_ipl();
+       return ipl > regs.intmask || ipl == 7;
 }
 
 void intlev_load(void)
@@ -4355,20 +4366,6 @@ void intlev_load(void)
        doint();
 }
 
-bool stop_interrupt_pending(void)
-{
-       if (m68k_interrupt_delay) {
-               int il = intlev();
-               regs.ipl_pin = il;
-               if (regs.ipl_pin > regs.intmask || regs.ipl_pin == 7) {
-                       if (regs.spcflags & SPCFLAG_INT) {
-                               return true;
-                       }
-               }
-       }
-       return false;
-}
-
 void doint(void)
 {
 #ifdef WITH_PPC
@@ -4413,7 +4410,7 @@ static void debug_cpu_stop(void)
 
 static int do_specialties (int cycles)
 {
-       bool stopped_debug = false;
+       uaecptr pc = m68k_getpc();
 
        if (regs.spcflags & SPCFLAG_MODE_CHANGE)
                return 1;
@@ -4447,15 +4444,15 @@ static int do_specialties (int cycles)
 #ifdef ACTION_REPLAY
 #ifdef ACTION_REPLAY_HRTMON
        if ((regs.spcflags & SPCFLAG_ACTION_REPLAY) && hrtmon_flag != ACTION_REPLAY_INACTIVE) {
-               int isinhrt = (m68k_getpc () >= hrtmem_start && m68k_getpc () < hrtmem_start + hrtmem_size);
+               int isinhrt = pc >= hrtmem_start && pc < hrtmem_start + hrtmem_size;
                /* exit from HRTMon? */
                if (hrtmon_flag == ACTION_REPLAY_ACTIVE && !isinhrt)
-                       hrtmon_hide ();
+                       hrtmon_hide();
                /* HRTMon breakpoint? (not via IRQ7) */
                if (hrtmon_flag == ACTION_REPLAY_IDLE && isinhrt)
-                       hrtmon_breakenter ();
+                       hrtmon_breakenter();
                if (hrtmon_flag == ACTION_REPLAY_ACTIVATE)
-                       hrtmon_enter ();
+                       hrtmon_enter();
        }
 #endif
        if ((regs.spcflags & SPCFLAG_ACTION_REPLAY) && action_replay_flag != ACTION_REPLAY_INACTIVE) {
@@ -4463,14 +4460,14 @@ static int do_specialties (int cycles)
                /*      write_log (_T("PC:%p\n"), m68k_getpc ());*/
 
                if (action_replay_flag == ACTION_REPLAY_ACTIVATE || action_replay_flag == ACTION_REPLAY_DORESET)
-                       action_replay_enter ();
-               if ((action_replay_flag == ACTION_REPLAY_HIDE || action_replay_flag == ACTION_REPLAY_ACTIVE) && !is_ar_pc_in_rom ()) {
-                       action_replay_hide ();
+                       action_replay_enter();
+               if ((action_replay_flag == ACTION_REPLAY_HIDE || action_replay_flag == ACTION_REPLAY_ACTIVE) && !is_ar_pc_in_rom()) {
+                       action_replay_hide();
                        unset_special (SPCFLAG_ACTION_REPLAY);
                }
                if (action_replay_flag == ACTION_REPLAY_WAIT_PC) {
                        /*write_log (_T("Waiting for PC: %p, current PC= %p\n"), wait_for_pc, m68k_getpc ());*/
-                       if (m68k_getpc () == wait_for_pc) {
+                       if (pc == wait_for_pc) {
                                action_replay_flag = ACTION_REPLAY_ACTIVATE; /* Activate after next instruction. */
                        }
                }
@@ -4478,14 +4475,14 @@ static int do_specialties (int cycles)
 #endif
 
        if (regs.spcflags & SPCFLAG_COPPER)
-               do_copper ();
+               do_copper();
 
 #ifdef JIT
-       unset_special (SPCFLAG_END_COMPILE);   /* has done its job */
+       unset_special(SPCFLAG_END_COMPILE);   /* has done its job */
 #endif
 
        while ((regs.spcflags & SPCFLAG_BLTNASTY) && dmaen (DMA_BLITTER) && cycles > 0 && ((currprefs.waiting_blits && currprefs.cpu_model >= 68020) || !currprefs.blitter_cycle_exact)) {
-               int c = blitnasty ();
+               int c = blitnasty();
                if (c < 0) {
                        break;
                } else if (c > 0) {
@@ -4495,9 +4492,9 @@ static int do_specialties (int cycles)
                } else {
                        c = 4;
                }
-               x_do_cycles (c * CYCLE_UNIT);
+               x_do_cycles(c * CYCLE_UNIT);
                if (regs.spcflags & SPCFLAG_COPPER)
-                       do_copper ();
+                       do_copper();
 #ifdef WITH_PPC
                if (ppc_state)  {
                        if (uae_ppc_poll_check_halt())
@@ -4508,116 +4505,15 @@ static int do_specialties (int cycles)
        }
 
        if (regs.spcflags & SPCFLAG_DOTRACE)
-               Exception (9);
+               Exception(9);
 
        if (regs.spcflags & SPCFLAG_TRAP) {
                unset_special (SPCFLAG_TRAP);
-               Exception (3);
-       }
-
-       while (regs.spcflags & SPCFLAG_STOP) {
-
-               if (regs.s == 0 && currprefs.cpu_model <= 68010) {
-                       // 68000/68010 undocumented special case:
-                       // if STOP clears S-bit and T was not set:
-                       // cause privilege violation exception, PC pointing to following instruction.
-                       // If T was set before STOP: STOP works as documented.
-                       m68k_unset_stop();
-                       Exception(8);
-                       break;
-               }
-
-       isstopped:
-               check_uae_int_request();
-               {
-                       if (bsd_int_requested)
-                               bsdsock_fake_int_handler ();
-               }
-
-               if (cpu_tracer > 0) {
-                       cputrace.stopped = regs.stopped;
-                       cputrace.intmask = regs.intmask;
-                       cputrace.sr = regs.sr;
-                       cputrace.state = 1;
-                       cputrace.pc = m68k_getpc ();
-                       cputrace.memoryoffset = 0;
-                       cputrace.cyclecounter = cputrace.cyclecounter_pre = cputrace.cyclecounter_post = 0;
-                       cputrace.readcounter = cputrace.writecounter = 0;
-               }
-
-               if (m68k_interrupt_delay) {
-                       unset_special(SPCFLAG_INT);
-                       if (time_for_interrupt()) {
-                               // extra STOP "round"
-                               if (debug_dma) {
-                                       debug_cpu_stop();
-                                       x_do_cycles(2 * cpucycleunit);
-                                       debug_cpu_stop();
-                                       x_do_cycles(2 * cpucycleunit);
-                               } else {
-                                       x_do_cycles(4 * cpucycleunit);
-                               }
-                               do_interrupt(regs.ipl);
-                               break;
-                       }
-               } else {
-                       if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)) {
-                               int intr = intlev ();
-                               unset_special (SPCFLAG_INT | SPCFLAG_DOINT);
-#ifdef WITH_PPC
-                               bool m68kint = true;
-                               if (ppc_state) {
-                                       m68kint = ppc_interrupt(intr);
-                               }
-                               if (m68kint) {
-#endif
-                                       if (intr > 0 && intr > regs.intmask) {
-                                               do_interrupt(intr);
-                                               break;
-                                       }
-#ifdef WITH_PPC
-                               }
-#endif
-                       }
-               }
-
-               ipl_fetch();
-
-               if (debug_dma) {
-                       debug_cpu_stop();
-                       x_do_cycles(2 * cpucycleunit);
-                       debug_cpu_stop();
-                       x_do_cycles(2 * cpucycleunit);
-               } else {
-                       x_do_cycles(4 * cpucycleunit);
-               }
-
-               if (regs.spcflags & SPCFLAG_COPPER) {
-                       do_copper();
-               }
-
-               if (regs.spcflags & SPCFLAG_MODE_CHANGE) {
-                       m68k_resumestopped();
-                       fill_prefetch();
-                       return 1;
-               }
-
-               if (regs.spcflags & SPCFLAG_BRK) {
-                       stopped_debug = false;
-                       goto dodebug;
-               }
-
-#ifdef WITH_PPC
-               if (ppc_state) {
-                       uae_ppc_execute_check();
-                       uae_ppc_poll_check_halt();
-               }
-#endif
-
+               Exception(3);
        }
 
        if (regs.spcflags & SPCFLAG_TRACE)
-               do_trace ();
+               do_trace();
 
        if (regs.spcflags & SPCFLAG_UAEINT) {
                check_uae_int_request();
@@ -4625,44 +4521,29 @@ static int do_specialties (int cycles)
        }
 
        if (m68k_interrupt_delay) {
-               if (time_for_interrupt ()) {
+               if (time_for_interrupt()) {
                        unset_special(SPCFLAG_INT);
-                       do_interrupt (regs.ipl);
+                       do_interrupt(get_ipl());
                }
        } else {
                if (regs.spcflags & SPCFLAG_INT) {
-                       int intr = intlev ();
+                       int intr = intlev();
                        unset_special (SPCFLAG_INT | SPCFLAG_DOINT);
                        if (intr > 0 && (intr > regs.intmask || intr == 7))
-                               do_interrupt (intr);
+                               do_interrupt(intr);
                }
        }
 
        if (regs.spcflags & SPCFLAG_DOINT) {
-               unset_special (SPCFLAG_DOINT);
-               set_special (SPCFLAG_INT);
+               unset_special(SPCFLAG_DOINT);
+               set_special(SPCFLAG_INT);
        }
 
-       if ((regs.spcflags & SPCFLAG_BRK) || stopped_debug) {
-dodebug:
+       if (regs.spcflags & SPCFLAG_BRK) {
                unset_special(SPCFLAG_BRK);
 #ifdef DEBUGGER
-               if (stopped_debug && !regs.stopped) {
-                       if (debugging) {
-                               debugger_active = 1;
-                               stopped_debug = false;
-                       }
-               }
                if (debugging) {
-                       if (!stopped_debug)
-                               debug();
-                       if (regs.stopped) {
-                               stopped_debug = true;
-                               if (debugging) {
-                                       debugger_active = 0;
-                               }
-                               goto isstopped;
-                       }
+                       debug();
                }
 #endif
        }
@@ -4670,6 +4551,12 @@ dodebug:
        return 0;
 }
 
+
+uaecptr m68kpc(void)
+{
+       return m68k_getpc();
+}
+
 //static uae_u32 pcs[1000];
 
 #if DEBUG_CD32CDTVIO
@@ -4806,7 +4693,7 @@ static void m68k_run_1 (void)
                                        if (do_specialties (cpu_cycles))
                                                exit = true;
                                }
-                               regs.ipl = regs.ipl_pin;
+                               regs.ipl[0] = regs.ipl_pin;
                                if (!currprefs.cpu_compatible || (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68010))
                                        exit = true;
                        }
@@ -4816,7 +4703,7 @@ static void m68k_run_1 (void)
                                if (do_specialties(cpu_cycles))
                                        exit = true;
                        }
-                       regs.ipl = regs.ipl_pin;
+                       regs.ipl[0] = regs.ipl[1] = regs.ipl_pin;
                } ENDTRY
        }
 }
@@ -4867,8 +4754,6 @@ static void m68k_run_1_ce (void)
                                        } else {
                                                write_log (_T("CPU TRACE: STOPPED\n"));
                                        }
-                                       if (r->stopped)
-                                               set_special (SPCFLAG_STOP);
                                        set_cpu_tracer (false);
                                        goto cont;
                                }
@@ -5031,10 +4916,7 @@ static int do_specialties_thread(void)
                        do_interrupt(ilvl);
                }
 
-               if (!(regs.spcflags & SPCFLAG_STOP))
-                       break;
-
-               uae_sem_wait(&cpu_wakeup_sema);
+               break;
        }
 
        return 0;
@@ -5741,7 +5623,7 @@ insretry:
                                } else {
 
                                        regs.instruction_cnt++;
-                                       regs.ipl = regs.ipl_pin;
+                                       regs.ipl[0] = regs.ipl_pin;
                                        if (regs.spcflags || time_for_interrupt ()) {
                                                if (do_specialties(0)) {
                                                        STOPTRY;
@@ -5915,8 +5797,6 @@ static void m68k_run_2ce (void)
                                                else if (cputrace.state == 1)
                                                        (*cpufunctbl[cputrace.opcode])(cputrace.opcode);
                                        }
-                                       if (regs.stopped)
-                                               set_special (SPCFLAG_STOP);
                                        set_cpu_tracer (false);
                                        goto cont;
                                }
@@ -5999,7 +5879,7 @@ static void m68k_run_2ce (void)
                                regs.instruction_cnt++;
 
                cont:
-                               regs.ipl = regs.ipl_pin;
+                               regs.ipl[0] = regs.ipl_pin;
                                if (r->spcflags || time_for_interrupt ()) {
                                        if (do_specialties (0))
                                                exit = true;
@@ -6009,7 +5889,7 @@ static void m68k_run_2ce (void)
                        }
                } CATCH(prb) {
                        bus_error();
-                       regs.ipl = regs.ipl_pin;
+                       regs.ipl[0] = regs.ipl_pin;
                        if (r->spcflags || time_for_interrupt()) {
                                if (do_specialties(0))
                                        exit = true;
@@ -6060,8 +5940,6 @@ static void m68k_run_2p (void)
                                                else if (cputrace.state == 1)
                                                        (*cpufunctbl[cputrace.opcode])(cputrace.opcode);
                                        }
-                                       if (regs.stopped)
-                                               set_special (SPCFLAG_STOP);
                                        set_cpu_tracer (false);
                                        goto cont;
                                }
@@ -6950,8 +6828,6 @@ void restore_cpu_finish (void)
        fill_prefetch_quick ();
        set_cycles (start_cycles);
        events_schedule ();
-       if (regs.stopped)
-               set_special (SPCFLAG_STOP);
        //activate_debugger ();
 }
 
@@ -7672,32 +7548,31 @@ bool cpureset (void)
 
 void do_cycles_stop(int c)
 {
-       if (debug_dma) {
-               while (c >= 2) {
-                       debug_cpu_stop();
-                       do_cycles_ce000_internal(2);
-                       c -= 2;
-               }
+       if (!currprefs.cpu_compatible) {
+               do_cycles(c);
        } else {
-               do_cycles_ce000_internal(c);
+               if (debug_dma) {
+                       while (c >= 2) {
+                               debug_cpu_stop();
+                               do_cycles_ce000_internal(2);
+                               c -= 2;
+                       }
+               } else {
+                       do_cycles_ce000_internal(c);
+               }
        }
 }
 
 void m68k_setstopped (void)
 {
-       /* A traced STOP instruction drops through immediately without
-       actually stopping.  */
-       if ((regs.spcflags & SPCFLAG_DOTRACE) == 0) {
-               m68k_set_stop();
-       } else {
-               m68k_resumestopped();
-       }
+       m68k_set_stop();
 }
 
 void m68k_resumestopped(void)
 {
        if (!regs.stopped)
                return;
+       m68k_incpci(4);
        m68k_unset_stop();
 }