From f2a9a0194625f657165ad64021e51a9daeb0f1fe Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 23 Oct 2022 20:42:41 +0300 Subject: [PATCH] IPL wait state fix --- cia.cpp | 2 +- custom.cpp | 17 +++++++++++------ gencpu.cpp | 6 +++--- include/newcpu.h | 1 - newcpu.cpp | 17 +++++++---------- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/cia.cpp b/cia.cpp index 33edcda1..71935a40 100644 --- 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); diff --git a/custom.cpp b/custom.cpp index ad844330..2e1c0a2f 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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; } } diff --git a/gencpu.cpp b/gencpu.cpp index 6ba883fd..141cfd98 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -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(); diff --git a/include/newcpu.h b/include/newcpu.h index 51823a21..28da2183 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -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); diff --git a/newcpu.cpp b/newcpu.cpp index 6cdd1a35..038008c4 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -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) { -- 2.47.3