} else {
if (using_prefetch) {
if (flags & GF_NOREFILL) {
- sprintf (buffer, "regs.irc", r);
+ strcpy (buffer, "regs.irc");
} else {
sprintf (buffer, "%s (%d)", prefetch_word, r + 2);
count_read++;
insn_n_cycles += 4;
if (using_prefetch) {
if (flags & GF_NOREFILL) {
- sprintf (buffer, "(uae_u8)regs.irc", r);
+ strcpy (buffer, "(uae_u8)regs.irc");
} else {
sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r + 2);
insn_n_cycles += 4;
do_cycles = "do_cycles_ce020_internal";
nextw = "next_iword_cache040";
nextl = "next_ilong_cache040";
- } else if (using_prefetch_020) {
+ } else if (using_prefetch_020 == 1) {
disp020 = "x_get_disp_ea_020";
prefetch_word = "get_word_020_prefetch";
prefetch_long = "get_long_020_prefetch";
dstb = "x_put_byte";
nextw = "next_iword_020_prefetch";
nextl = "next_ilong_020_prefetch";
+ } else if (using_prefetch_020 == 2) {
+ disp020 = "x_get_disp_ea_020";
+ prefetch_word = "get_word_030_prefetch";
+ prefetch_long = "get_long_030_prefetch";
+ srcli = "x_get_ilong";
+ srcwi = "x_get_iword";
+ srcbi = "x_get_ibyte";
+ srcl = "x_get_long";
+ dstl = "x_put_long";
+ srcw = "x_get_word";
+ dstw = "x_put_word";
+ srcb = "x_get_byte";
+ dstb = "x_put_byte";
+ nextw = "next_iword_030_prefetch";
+ nextl = "next_ilong_030_prefetch";
}
#if 0
} else if (using_ce020) {
}
} else if (id == 20) { // 68020 prefetch
cpu_level = 2;
- using_prefetch_020 = 2;
+ using_prefetch_020 = 1;
read_counts ();
for (rp = 0; rp < nr_cpuop_funcs; rp++)
opcode_next_clev[rp] = cpu_level;
} else if (id == 21) { // 68020 cycle-exact
cpu_level = 2;
using_ce020 = 1;
- using_prefetch_020 = 2;
+ using_prefetch_020 = 1;
// timing tables are from 030 which has 2
// clock memory accesses, 68020 has 3 clock
// memory accesses
#ifdef CPUEMU_22
+extern uae_u32 get_word_030_prefetch(int);
+
+STATIC_INLINE void put_long_030(uaecptr addr, uae_u32 v)
+{
+ write_dcache030(addr, v, 2);
+}
+STATIC_INLINE void put_word_030(uaecptr addr, uae_u32 v)
+{
+ write_dcache030(addr, v, 1);
+}
+STATIC_INLINE void put_byte_030(uaecptr addr, uae_u32 v)
+{
+ write_dcache030(addr, v, 0);
+}
+STATIC_INLINE uae_u32 get_long_030(uaecptr addr)
+{
+ return read_dcache030(addr, 2);
+}
+STATIC_INLINE uae_u32 get_word_030(uaecptr addr)
+{
+ return read_dcache030(addr, 1);
+}
+STATIC_INLINE uae_u32 get_byte_030(uaecptr addr)
+{
+ return read_dcache030(addr, 0);
+}
+
+STATIC_INLINE uae_u32 get_long_030_prefetch(int o)
+{
+ uae_u32 v;
+ v = get_word_030_prefetch(o) << 16;
+ v |= get_word_030_prefetch(o + 2);
+ return v;
+}
+
+STATIC_INLINE uae_u32 next_iword_030_prefetch(void)
+{
+ uae_u32 r = get_word_030_prefetch(0);
+ m68k_incpci(2);
+ return r;
+}
+STATIC_INLINE uae_u32 next_ilong_030_prefetch(void)
+{
+ uae_u32 r = get_long_030_prefetch(0);
+ m68k_incpci(4);
+ return r;
+}
+
+STATIC_INLINE void m68k_do_bsr_030(uaecptr oldpc, uae_s32 offset)
+{
+ m68k_areg(regs, 7) -= 4;
+ put_long_030(m68k_areg(regs, 7), oldpc);
+ m68k_incpci(offset);
+}
+STATIC_INLINE void m68k_do_rts_030(void)
+{
+ m68k_setpc(get_long_030(m68k_areg(regs, 7)));
+ m68k_areg(regs, 7) += 4;
+}
+
+#endif
+
+#ifdef CPUEMU_23
+
extern uae_u32 get_word_ce030_prefetch(int);
STATIC_INLINE void put_long_ce030 (uaecptr addr, uae_u32 v)
x_do_cycles_post = do_cycles_post;
} else if (currprefs.cpu_model == 68030 && !currprefs.cachesize) {
x_prefetch = get_word_prefetch;
- x_get_ilong = get_long_020_prefetch;
- x_get_iword = get_word_020_prefetch;
+ x_get_ilong = get_long_030_prefetch;
+ x_get_iword = get_word_030_prefetch;
x_get_ibyte = NULL;
- x_next_iword = next_iword_020_prefetch;
- x_next_ilong = next_ilong_020_prefetch;
+ x_next_iword = next_iword_030_prefetch;
+ x_next_ilong = next_ilong_030_prefetch;
x_put_long = put_long;
x_put_word = put_word;
x_put_byte = put_byte;
if (pc & 2) {
v = regs.prefetch020[0] & 0xffff;
+#if MORE_ACCURATE_68020_PIPELINE
+ pipeline_020(regs.prefetch020[1], pc);
+#endif
regs.prefetch020[0] = regs.prefetch020[1];
- fill_icache030 (pc + 2 + 4);
- regs.prefetch020[1] = regs.cacheholdingdata020;
+ // branch instruction detected in pipeline: stop fetches until branch executed.
+ if (!MORE_ACCURATE_68020_PIPELINE || regs.pipeline_stop >= 0) {
+ fill_icache030 (pc + 2 + 4);
+ regs.prefetch020[1] = regs.cacheholdingdata020;
+ }
} else {
v = regs.prefetch020[0] >> 16;
+#if MORE_ACCURATE_68020_PIPELINE
+ pipeline_020(regs.prefetch020[1] >> 16, pc);
+#endif
}
do_cycles_ce020_internal (2);
return v;
}
+uae_u32 get_word_030_prefetch(int o)
+{
+ uae_u32 pc = m68k_getpc() + o;
+ uae_u32 v;
+
+ if (pc & 2) {
+ v = regs.prefetch020[0] & 0xffff;
+#if MORE_ACCURATE_68020_PIPELINE
+ pipeline_020(regs.prefetch020[1], pc);
+#endif
+ regs.prefetch020[0] = regs.prefetch020[1];
+ // branch instruction detected in pipeline: stop fetches until branch executed.
+ if (!MORE_ACCURATE_68020_PIPELINE || regs.pipeline_stop >= 0) {
+ fill_icache030(pc + 2 + 4);
+ regs.prefetch020[1] = regs.cacheholdingdata020;
+ }
+ } else {
+ v = regs.prefetch020[0] >> 16;
+#if MORE_ACCURATE_68020_PIPELINE
+ pipeline_020(regs.prefetch020[1] >> 16, pc);
+#endif
+ }
+ return v;
+}
+
uae_u32 get_word_icache030(uaecptr addr)
{
fill_icache030(addr);
void fill_prefetch_030 (void)
{
uaecptr pc = m68k_getpc ();
+ uaecptr pc2 = pc;
pc &= ~3;
regs.pipeline_pos = 0;
regs.pipeline_stop = 0;
do_cycles_ce020_internal(2);
regs.prefetch020[1] = regs.cacheholdingdata020;
- regs.irc = get_word_ce030_prefetch (0);
+#if MORE_ACCURATE_68020_PIPELINE
+ if (pc2 & 2) {
+ pipeline_020(regs.prefetch020[0], pc);
+ pipeline_020(regs.prefetch020[1] >> 16, pc);
+ } else {
+ pipeline_020(regs.prefetch020[0] >> 16, pc);
+ pipeline_020(regs.prefetch020[0], pc);
+ }
+#endif
+
+ if (currprefs.cpu_cycle_exact)
+ regs.irc = get_word_ce030_prefetch (0);
+ else
+ regs.irc = get_word_030_prefetch(0);
}
void fill_prefetch_020 (void)