#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
{
static void set_last_access_ipl_prev(void)
{
+ if (ipl_fetched < 0)
+ return;
last_access_offset_ipl_prev = strlen(outbuffer);
}
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);
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);
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++;
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);
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) {
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);
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;
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);
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();
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);