From: Toni Wilen Date: Sun, 17 Apr 2022 15:06:23 +0000 (+0300) Subject: 68000 IPL detection timing fixes. X-Git-Tag: 41000~256 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=f99d1c83601fa011c692b1b1392ad12a6ef8ac70;p=francis%2Fwinuae.git 68000 IPL detection timing fixes. --- diff --git a/gencpu.cpp b/gencpu.cpp index 326180e3..54ca6bb0 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -97,6 +97,8 @@ static int do_always_dynamic_cycles; #define GF_PCM2 0x100000 // internal PC is 2 more than address being prefetched. #define GF_PCP2 0x200000 +// if set, long word fetch does it at the beginning (not second word) +#define GF_NOLIPL 0x400000 typedef enum { @@ -248,6 +250,8 @@ static void set_last_access_ipl(void) static void set_last_access_ipl_prev(void) { + if (ipl_fetched < 0) + return; last_access_offset_ipl_prev = strlen(outbuffer); } @@ -3716,7 +3720,9 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char out("uae_s32 %s = %s(%sa + 2);\n", name, srcwx, name); count_readw++; check_bus_error(name, 0, 0, 1, NULL, 1, 0); - set_last_access_ipl_prev(); + if (!(flags & GF_NOLIPL)) { + set_last_access_ipl_prev(); + } out("%s |= %s(%sa) << 16; \n", name, srcwx, name); count_readw++; check_bus_error(name, -2, 0, 1, NULL, 1, 0); @@ -3724,7 +3730,9 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char out("uae_s32 %s = %s(%sa) << 16;\n", name, srcwx, name); count_readw++; check_bus_error(name, 0, 0, 1, NULL, 1, 0); - set_last_access_ipl_prev(); + if (!(flags & GF_NOLIPL)) { + set_last_access_ipl_prev(); + } out("%s |= %s(%sa + 2); \n", name, srcwx, name); count_readw++; check_bus_error(name, 2, 0, 1, NULL, 1, 0); @@ -4030,7 +4038,9 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz fill_prefetch_next_after(0, NULL); insn_n_cycles += 4; } - set_last_access_ipl_prev(); + if (!(flags & GF_NOLIPL)) { + set_last_access_ipl_prev(); + } out("%s(%sa, %s >> 16);\n", dstwx, to, from); sprintf(tmp, "%s >> 16", from); count_writew++; @@ -4043,7 +4053,9 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz if (flags & GF_SECONDWORDSETFLAGS) { genflags(flag_logical, g_instr->size, "src", "", ""); } - set_last_access_ipl_prev(); + if (!(flags & GF_NOLIPL)) { + set_last_access_ipl_prev(); + } out("%s(%sa + 2, %s);\n", dstwx, to, from); count_writew++; check_bus_error(to, 2, 1, 1, from, 1, pcoffset); @@ -4514,6 +4526,7 @@ static void genmovemel_ce(uae_u16 opcode) int size = table68k[opcode].size == sz_long ? 4 : 2; amodes mode = table68k[opcode].dmode; out("uae_u16 mask = %s;\n", gen_nextiword(mode < Ad16 ? GF_PCM2 : 0)); + ipl_fetched = -1; do_instruction_buserror(); out("uae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); if (mode == Ad8r || mode == PC8r) { @@ -4571,7 +4584,6 @@ static void genmovemel_ce(uae_u16 opcode) out("amask = movem_next[amask];\n"); out("}\n"); } - set_last_access_ipl_prev(); out("%s(srca);\n", srcw); // and final extra word fetch that goes nowhere.. count_readw++; check_bus_error("src", 0, 0, 1, NULL, 1, -1); @@ -6121,7 +6133,7 @@ static void gen_opcode (unsigned int opcode) exception_pc_offset_extra_000 = 2; genamodedual(curi, curi->smode, "srcreg", curi->size, "src", 1, GF_AA, - curi->dmode, "dstreg", curi->size, "dst", 1, GF_AA); + curi->dmode, "dstreg", curi->size, "dst", 1, GF_AA | GF_NOLIPL); genflags (flag_cmp, curi->size, "newv", "src", "dst"); fill_prefetch_next_t(); break; @@ -6184,6 +6196,7 @@ static void gen_opcode (unsigned int opcode) case i_MVPMR: // MOVEP M->R out("uaecptr mempa = m68k_areg(regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword(0)); check_prefetch_buserror(m68k_pc_offset, -2); + ipl_fetched = 1; genamode(curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, cpu_level == 1 ? GF_NOFETCH : 0); if (curi->size == sz_word) { out("uae_u16 val = (%s(mempa) & 0xff) << 8;\n", srcb); @@ -6988,7 +7001,9 @@ static void gen_opcode (unsigned int opcode) write_return_cycles(0); out("}\n"); } - genastore("src", Apdi, "7", sz_long, "old"); + set_last_access_ipl(); + ipl_fetched = 1; + genastore_2("src", Apdi, "7", sz_long, "old", 0, GF_NOLIPL); genastore("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src"); out("m68k_areg(regs, 7) += offs;\n"); fill_prefetch_next_t(); @@ -7952,6 +7967,8 @@ bccl_not68020: genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); genamode(curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); sync_m68k_pc(); + set_last_access_ipl(); + ipl_fetched = 1; addcycles000(4); out("if (dst > src) {\n"); out("setchkundefinedflags(src, dst, %d);\n", curi->size); diff --git a/newcpu.cpp b/newcpu.cpp index ab30081a..d846a4c3 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -4475,7 +4475,7 @@ static int do_specialties (int cycles) } bool first = true; - while ((regs.spcflags & SPCFLAG_STOP) && !(regs.spcflags & SPCFLAG_BRK)) { + while (regs.spcflags & SPCFLAG_STOP) { isstopped: check_uae_int_request(); { @@ -4496,9 +4496,13 @@ static int do_specialties (int cycles) if (m68k_interrupt_delay) { unset_special(SPCFLAG_INT); - ipl_fetch (); - if (time_for_interrupt ()) { - do_interrupt (regs.ipl); + if (first) { + ipl_fetch(); + } + if (time_for_interrupt()) { + x_do_cycles(4 * cpucycleunit); + do_interrupt(regs.ipl); + break; } } else { if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)) { @@ -4511,17 +4515,28 @@ static int do_specialties (int cycles) } if (m68kint) { #endif - if (intr > 0 && intr > regs.intmask) - do_interrupt (intr); + if (intr > 0 && intr > regs.intmask) { + do_interrupt(intr); + break; + } #ifdef WITH_PPC } #endif } } - if (!first) - x_do_cycles(currprefs.cpu_cycle_exact ? 2 * CYCLE_UNIT : 4 * CYCLE_UNIT); + if (!first) { + if (currprefs.cpu_compatible) { + x_do_cycles(2 * cpucycleunit); + ipl_fetch(); + x_do_cycles(2 * cpucycleunit); + } else { + x_do_cycles(4 * cpucycleunit); + ipl_fetch(); + } + } first = false; + if (regs.spcflags & SPCFLAG_COPPER) do_copper(); @@ -4530,6 +4545,11 @@ static int do_specialties (int cycles) return 1; } + if (regs.spcflags & SPCFLAG_BRK) { + stopped_debug = false; + goto dodebug; + } + #ifdef WITH_PPC if (ppc_state) { uae_ppc_execute_check(); @@ -4567,6 +4587,7 @@ static int do_specialties (int cycles) } if ((regs.spcflags & SPCFLAG_BRK) || stopped_debug) { +dodebug: unset_special(SPCFLAG_BRK); #ifdef DEBUGGER if (stopped_debug && !regs.stopped) {