]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
STOP cycle-accuracy fix, stop state/wakeup added to DMA debugger.
authorToni Wilen <twilen@winuae.net>
Mon, 6 Jun 2022 15:44:50 +0000 (18:44 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 6 Jun 2022 15:44:50 +0000 (18:44 +0300)
debug.cpp
gencpu.cpp
include/debug.h
include/newcpu.h
newcpu.cpp

index a87a79155ffe3fd8a2d7c0847a68710e4a1d05cd..ab61b718650b77669c7fbc7638684393612a0ff2 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -2221,6 +2221,10 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, evt_t cy
                }
                if (dr->evt & DMA_EVENT_CPUIRQ)
                        l3[cl2++] = 'I';
+               if (dr->evt & DMA_EVENT_CPUSTOP)
+                       l3[cl2++] = '|';
+               if (dr->evt & DMA_EVENT_CPUSTOPIPL)
+                       l3[cl2++] = '+';
                if (dr->evt & DMA_EVENT_INTREQ)
                        l3[cl2++] = 'i';
                if (dr->evt & DMA_EVENT_SPECIAL)
@@ -6246,7 +6250,7 @@ static bool debug_line (TCHAR *input)
                                                        lastframes = history[temp].fp;
                                                        lastvpos = history[temp].vpos;
                                                        lasthpos = history[temp].hpos;
-                                                       console_out_f(_T("%2d "), regs.intmask ? regs.intmask : (regs.s ? -1 : 0));
+                                                       console_out_f(_T("%2d %03d/%03d "), regs.intmask ? regs.intmask : (regs.s ? -1 : 0), lasthpos, lastvpos);
                                                        m68k_disasm (regs.pc, NULL, 0xffffffff, 1);
                                                }
                                                if (addr && regs.pc == addr)
@@ -6544,6 +6548,9 @@ static void debug_1 (void)
 
 static void addhistory (void)
 {
+       if (regs.stopped)
+               return;
+
        uae_u32 pc = currprefs.cpu_model >= 68020 && currprefs.cpu_compatible ? regs.instruction_pc : m68k_getpc();
        history[lasthist].regs = regs;
        history[lasthist].regs.pc = pc;
index 78e9fde8a26779feae24b57ba9b1782b4a11e345..3d4c04fb0a7d77ed079bd834f3e01a663ac37723 100644 (file)
@@ -6656,6 +6656,7 @@ static void gen_opcode (unsigned int opcode)
                trace_t0_68040_only();
                break;
        case i_STOP:
+       {
                if (using_prefetch) {
                        out("uae_u16 sr = regs.irc;\n");
                        m68k_pc_offset += 2;
@@ -6675,11 +6676,21 @@ 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();
-               out("m68k_setstopped();\n");
-               if ((cpu_level == 0 || cpu_level == 1) && (using_ce || using_prefetch)) {
-                       out("%s(4);\n", do_cycles);
+               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();
                // STOP does not prefetch anything
@@ -6687,6 +6698,7 @@ static void gen_opcode (unsigned int opcode)
                next_cpu_level = cpu_level - 1;
                next_level_000();
                break;
+       }
        case i_LPSTOP: /* 68060 */
                out("uae_u16 sw = %s;\n", gen_nextiword(0));
                out("if (sw != 0x01c0) {\n");
index 0669af0b811f4edef7f2c6c87b724fbba4a28d72..1acbda9c58d6a38e32dbee9e64a10917bcb7e8d2 100644 (file)
@@ -264,6 +264,9 @@ extern struct dma_rec *last_dma_rec;
 #define DMA_EVENT_HSE          0x04000000
 #define DMA_EVENT_CIAA_IRQ     0x08000000
 #define DMA_EVENT_CIAB_IRQ     0x10000000
+#define DMA_EVENT_CPUSTOP      0x20000000
+#define DMA_EVENT_CPUSTOPIPL 0x40000000
+
 
 #define DMARECORD_REFRESH 1
 #define DMARECORD_CPU 2
index 63746225847ebb629e2aa2b569a95813ff5ace9c..6a6c59a03696801489d51f578bc2bca5b476025f 100644 (file)
@@ -661,6 +661,7 @@ extern void REGPARAM3 x_put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val
 extern void m68k_setstopped(void);
 extern void m68k_resumestopped(void);
 extern void m68k_cancel_idle(void);
+extern void do_cycles_stop(int);
 
 extern uae_u32 REGPARAM3 get_disp_ea_020 (uae_u32 base, int idx) REGPARAM;
 extern uae_u32 REGPARAM3 get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
@@ -690,6 +691,7 @@ extern void IRQ_forced(int, int);
 extern void prepare_interrupt (uae_u32);
 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 90d14a7f38e69be6808c50c1b47f7af2b3cf4dc4..291ea2261c4a5f9c046edc42218a01797c54838f 100644 (file)
@@ -60,7 +60,7 @@
 bool check_prefs_changed_comp (bool checkonly) { return false; }
 #endif
 /* For faster JIT cycles handling */
-uae_s32 pissoff = 0;
+int pissoff = 0;
 
 /* Opcode of faulting instruction */
 static uae_u32 last_op_for_exception_3;
@@ -4355,6 +4355,20 @@ 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
@@ -4389,6 +4403,14 @@ static void check_debugger(void)
        }
 }
 
+static void debug_cpu_stop(void)
+{
+       record_dma_event(DMA_EVENT_CPUSTOP, current_hpos(), vpos);
+       if (time_for_interrupt()) {
+               record_dma_event(DMA_EVENT_CPUSTOPIPL, current_hpos(), vpos);
+       }
+}
+
 static int do_specialties (int cycles)
 {
        bool stopped_debug = false;
@@ -4493,7 +4515,6 @@ static int do_specialties (int cycles)
                Exception (3);
        }
 
-       bool first = true;
        while (regs.spcflags & SPCFLAG_STOP) {
 
                if (regs.s == 0 && currprefs.cpu_model <= 68010) {
@@ -4527,9 +4548,13 @@ static int do_specialties (int cycles)
                if (m68k_interrupt_delay) {
                        unset_special(SPCFLAG_INT);
                        if (time_for_interrupt()) {
-                               if (!first) {
-                                       // extra loop because even after higher ipl detection,
-                                       // stop needs to do one more loop before it exits.
+                               // 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);
@@ -4556,12 +4581,20 @@ static int do_specialties (int cycles)
                        }
                }
 
-               first = false;
                ipl_fetch();
-               x_do_cycles(4 * cpucycleunit);
 
-               if (regs.spcflags & SPCFLAG_COPPER)
+               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();
@@ -7637,6 +7670,18 @@ bool cpureset (void)
        return false;
 }
 
+void do_cycles_stop(int 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)
 {