]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
68030 prefetch/ce pipeline emulation added (68020 was added earlier).
authorToni Wilen <twilen@winuae.net>
Sun, 2 Aug 2015 17:52:52 +0000 (20:52 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 2 Aug 2015 17:52:52 +0000 (20:52 +0300)
gencpu.cpp
include/cpu_prefetch.h
newcpu.cpp

index 29da629620c123b2a2ce123f62b65c3bbabf2074..67773c4ffecaa09883fb498d271f6e6a2a99bf44 100644 (file)
@@ -542,7 +542,7 @@ static const char *gen_nextiword (int flags)
        } 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++;
@@ -579,7 +579,7 @@ static const char *gen_nextibyte (int flags)
                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;
@@ -2819,7 +2819,7 @@ static void resetvars (void)
                        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";
@@ -2834,6 +2834,21 @@ static void resetvars (void)
                        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) {
@@ -5788,14 +5803,14 @@ static void generate_cpu (int id, int mode)
                }
        } 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
index 035daca0ffe0113cd476781957d34bca4aaafbda..c479346d99cea3f05021d63c8d94022a2ad3bdfe 100644 (file)
@@ -153,6 +153,70 @@ STATIC_INLINE void m68k_do_rts_ce020 (void)
 
 #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)
index 513e6a23c72ef1bb4a55a06b2148b3f3d1a70b80..79bae77900c4bebb76e10e12a537c72d741159f7 100644 (file)
@@ -871,11 +871,11 @@ static void set_x_funcs (void)
                                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;
@@ -7282,16 +7282,50 @@ uae_u32 get_word_ce030_prefetch (int o)
 
        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);
@@ -7688,6 +7722,7 @@ void flush_dcache (uaecptr addr, int size)
 void fill_prefetch_030 (void)
 {
        uaecptr pc = m68k_getpc ();
+       uaecptr pc2 = pc;
        pc &= ~3;
        regs.pipeline_pos = 0;
        regs.pipeline_stop = 0;
@@ -7702,7 +7737,20 @@ void fill_prefetch_030 (void)
                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)