]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
IPL wait state fix
authorToni Wilen <twilen@winuae.net>
Sun, 23 Oct 2022 17:42:41 +0000 (20:42 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 23 Oct 2022 17:42:41 +0000 (20:42 +0300)
cia.cpp
custom.cpp
gencpu.cpp
include/newcpu.h
newcpu.cpp

diff --git a/cia.cpp b/cia.cpp
index 33edcda1d56b657a8a0312baf0ffe36ea75926a0..71935a40fdb0ad99bbb44ee171cce365f63f3b0e 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -2254,7 +2254,7 @@ static void cia_wait_post(int cianummask, uaecptr addr, uae_u32 value, bool rw)
        } else {
                // Last 6 cycles of E-clock
                // IPL fetch that got delayed by CIA access?
-               if (cia_now_evt == regs.ipl_evt) {
+               if (cia_now_evt == regs.ipl_evt && currprefs.cpu_model <= 68010) {
                        int phase = cia_cycles((e_clock_end - 2) * E_CYCLE_UNIT, 4, value, 1);
                        regs.ipl[0] = regs.ipl_pin;
                        cia_cycles(2 * E_CYCLE_UNIT, phase, value, 1);
index ad8443304c330a10f645fb6b831cb1d8356e9b9f..2e1c0a2f7517f58bd31d1557f4621cd802479027 100644 (file)
@@ -14890,10 +14890,10 @@ extern int cpu_tracer;
 static int dma_cycle(uaecptr addr, uae_u32 value, int *mode, int *ipl)
 {
        int hpos_next, hpos_old;
+       int ws = 0;
 
        blt_info.nasty_cnt = 1;
        blt_info.wait_nasty = 0;
-       *ipl = regs.ipl_pin;
        if (cpu_tracer < 0) {
                return current_hpos_safe();
        }
@@ -14927,7 +14927,10 @@ static int dma_cycle(uaecptr addr, uae_u32 value, int *mode, int *ipl)
                if (blt_info.nasty_cnt > 0) {
                        blt_info.nasty_cnt++;
                }
-               *ipl = regs.ipl_pin;
+               if (!ws) {
+                       *ipl = regs.ipl_pin;
+                       ws = 1;
+               }
                do_cycles(1 * CYCLE_UNIT);
                /* bus was allocated to dma channel, wait for next cycle.. */
        }
@@ -14959,7 +14962,8 @@ void do_copper(void)
 uae_u32 wait_cpu_cycle_read(uaecptr addr, int mode)
 {
        uae_u32 v = 0;
-       int hpos, ipl;
+       int hpos;
+       int ipl = regs.ipl_pin;
        evt_t now = get_cycles();
 
        sync_cycles();
@@ -15017,7 +15021,7 @@ uae_u32 wait_cpu_cycle_read(uaecptr addr, int mode)
 
        // if IPL fetch was pending and CPU had wait states
        // Use ipl_pin value from previous cycle
-       if (now == regs.ipl_evt && regs.ipl_pin_change_evt > now + cpuipldelay2) {
+       if (now == regs.ipl_evt) {
                regs.ipl[0] = ipl;
        }
 
@@ -15026,7 +15030,8 @@ uae_u32 wait_cpu_cycle_read(uaecptr addr, int mode)
 
 void wait_cpu_cycle_write(uaecptr addr, int mode, uae_u32 v)
 {
-       int hpos, ipl;
+       int hpos;
+       int ipl = regs.ipl_pin;
        evt_t now = get_cycles();
 
        sync_cycles();
@@ -15068,7 +15073,7 @@ void wait_cpu_cycle_write(uaecptr addr, int mode, uae_u32 v)
 
        // if IPL fetch was pending and CPU had wait states:
        // Use ipl_pin value from previous cycle
-       if (now == regs.ipl_evt && regs.ipl_pin_change_evt > now + cpuipldelay2) {
+       if (now == regs.ipl_evt) {
                regs.ipl[0] = ipl;
        }
 }
index 6ba883fd739792d7cd560e5a71577335257f0ddc..141cfd98caeca6685cc45334266216b3b4773b49 100644 (file)
@@ -259,7 +259,7 @@ static void set_ipl_pre(void)
 {
        if (using_ce) {
                pre_ipl = 1;
-               out("ipl_fetch_pre();\n");
+               out("ipl_fetch_next_pre();\n");
        } else if (using_prefetch) {
                pre_ipl = 1;
                //out("ipl_fetch_prefetch(%d);\n", get_current_cycles() + 2);
@@ -4956,7 +4956,7 @@ static void shift_ce(amodes dmode, int size)
                        out("{\n");
                        out("int cycles = %d;\n", c);
                        out("cycles += 2 * ccnt;\n");
-                       addcycles000_3(false);
+                       addcycles000_3(true);
                        out("}\n");
                }
                next_level_020_to_010();
@@ -6797,9 +6797,9 @@ static void gen_opcode (unsigned int opcode)
                if (curi->size == sz_byte) {
                        // MOVE TO CCR
                        addcycles000(4);
-                       set_ipl();
                        out("MakeSR();\nregs.sr &= 0xFF00;\nregs.sr |= src & 0xFF;\n");
                        makefromsr();
+                       set_ipl();
                } else {
                        // MOVE TO SR
                        check_trace();
index 51823a21403da9422c08f7b3866c46addcc20870..28da2183d87531d2b026d6a0b88c2a9ecd4d2417 100644 (file)
@@ -703,7 +703,6 @@ extern void checkint(void);
 extern void intlev_load(void);
 extern void ipl_fetch_now_pre(void);
 extern void ipl_fetch_next_pre(void);
-extern void ipl_fetch_pre(void);
 extern void ipl_fetch_now(void);
 extern void ipl_fetch_next(void);
 extern void dump_counts (void);
index 6cdd1a357db298ee5605da08fb31730c2ba6a186..038008c4cb141bf54a13839fcb326a91c80321b1 100644 (file)
@@ -2685,9 +2685,9 @@ static int iack_cycle(int nr)
                // non-autovectored
                // this is basically normal memory access and takes 4 cycles (without wait states).
                vector = x_get_byte(0x00fffff1 | ((nr - 24) << 1));
+               x_do_cycles(4 * cpucycleunit);
        } else {
                // autovectored
-               x_do_cycles(4 * cpucycleunit);
        }
        return vector;
 }
@@ -2793,7 +2793,6 @@ static void Exception_ce000 (int nr)
                x_put_word (m68k_areg (regs, 7) + 4, currpc); // write low address
                if (interrupt) {
                        vector_nr = iack_cycle(nr);
-                       x_do_cycles(4 * cpucycleunit);
                }
                x_put_word (m68k_areg (regs, 7) + 0, regs.sr); // write SR
                x_put_word (m68k_areg (regs, 7) + 2, currpc >> 16); // write high address
@@ -2808,7 +2807,6 @@ static void Exception_ce000 (int nr)
                x_put_word (m68k_areg (regs, 7) + 4, currpc); // write low address
                if (interrupt) {
                        vector_nr = iack_cycle(nr);
-                       x_do_cycles(4 * cpucycleunit);
                }
                x_put_word (m68k_areg (regs, 7) + 0, regs.sr); // write SR
                x_put_word (m68k_areg (regs, 7) + 2, currpc >> 16); // write high address
@@ -4416,15 +4414,15 @@ static int time_for_interrupt(void)
 }
 
 // ipl check mid next memory cycle
-void ipl_fetch_pre(void)
+void ipl_fetch_next_pre(void)
 {
-       ipl_fetch_next();
        regs.ipl_evt_pre = get_cycles();
        regs.ipl_evt_pre_mode = 1;
 }
 
 void ipl_fetch_now_pre(void)
 {
+       regs.ipl[1] = regs.ipl_pin;
        regs.ipl_evt_pre = get_cycles();
        regs.ipl_evt_pre_mode = 0;
 }
@@ -4432,7 +4430,8 @@ void ipl_fetch_now_pre(void)
 // ipl check was early enough, interrupt possible after current instruction
 void ipl_fetch_now(void)
 {
-       regs.ipl_evt = get_cycles();
+       evt_t c = get_cycles();
+       regs.ipl_evt = c;
        regs.ipl[0] = regs.ipl_pin;
        regs.ipl[1] = 0;
 }
@@ -4442,7 +4441,8 @@ void ipl_fetch_now(void)
 // if not early enough: interrupt starts after following instruction.
 void ipl_fetch_next(void)
 {
-       if (get_cycles() - regs.ipl_pin_change_evt >= cpuipldelay4) {
+       evt_t c = get_cycles();
+       if (c - regs.ipl_pin_change_evt >= cpuipldelay4) {
                regs.ipl[0] = regs.ipl_pin;
                regs.ipl[1] = 0;
        } else {
@@ -4636,9 +4636,6 @@ static int do_specialties (int cycles)
                if (ipl) {
                        unset_special(SPCFLAG_INT);
                        do_interrupt(ipl);
-               } else {
-                       regs.ipl[0] = regs.ipl[1];
-                       regs.ipl[1] = 0;
                }
        } else {
                if (regs.spcflags & SPCFLAG_INT) {