32x, improve poll detection
authorkub <derkub@gmail.com>
Mon, 28 Jun 2021 20:58:04 +0000 (22:58 +0200)
committerkub <derkub@gmail.com>
Mon, 28 Jun 2021 20:58:04 +0000 (22:58 +0200)
cpu/sh2/compiler.c
cpu/sh2/mame/sh2.c
cpu/sh2/mame/sh2pico.c
cpu/sh2/sh2.h
pico/32x/memory.c
pico/pico_int.h

index 66400c7..bb2206c 100644 (file)
@@ -4417,6 +4417,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
           EMITH_HINT_COND(DCOND_EQ);
           emith_subf_r_r_imm(tmp, tmp2, 1);
           emith_set_t_cond(sr, DCOND_EQ);
+          emith_or_r_imm(sr, SH2_NO_POLLING);
           goto end_op;
         }
         goto default_;
index fa49153..17b96a3 100644 (file)
@@ -800,6 +800,7 @@ INLINE void DT(sh2_state *sh2, UINT32 n)
                sh2->sr |= T;\r
        else\r
                sh2->sr &= ~T;\r
+       sh2->no_polling = SH2_NO_POLLING;\r
 #if BUSY_LOOP_HACKS\r
        {\r
                UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM );\r
index f4ae85c..65f4757 100644 (file)
@@ -24,9 +24,10 @@ typedef u8  UINT8;
 static __inline unsigned int name(SH2 *sh2, unsigned int a) \
 { \
        unsigned int ret; \
-       sh2->sr |= sh2->icount << 12; \
+       sh2->sr |= (sh2->icount << 12) | (sh2->no_polling); \
        ret = cname(a, sh2); \
        sh2->icount = (signed int)sh2->sr >> 12; \
+       sh2->no_polling = (sh2->sr & SH2_NO_POLLING); \
        sh2->sr &= 0x3f3; \
        return ret; \
 }
@@ -34,9 +35,10 @@ static __inline unsigned int name(SH2 *sh2, unsigned int a) \
 #define MAKE_WRITEFUNC(name, cname) \
 static __inline void name(SH2 *sh2, unsigned int a, unsigned int d) \
 { \
-       sh2->sr |= sh2->icount << 12; \
+       sh2->sr |= (sh2->icount << 12) | (sh2->no_polling); \
        cname(a, d, sh2); \
        sh2->icount = (signed int)sh2->sr >> 12; \
+       sh2->no_polling = (sh2->sr & SH2_NO_POLLING); \
        sh2->sr &= 0x3f3; \
 }
 
index 614e7de..bb8debe 100644 (file)
@@ -56,6 +56,9 @@ typedef struct SH2_
        uint32_t        poll_addr;\r
        int             poll_cycles;\r
        int             poll_cnt;\r
+// NB MUST be a bit unused in SH2 SR, see also cpu/sh2/compiler.c!\r
+#define SH2_NO_POLLING (1 << 10)       // poll detection control\r
+       int             no_polling;\r
 \r
        // DRC branch cache. size must be 2^n and <=128\r
        int rts_cache_idx;\r
index ac26ba4..d49cd2a 100644 (file)
@@ -119,8 +119,9 @@ void NOINLINE p32x_sh2_poll_detect(u32 a, SH2 *sh2, u32 flags, int maxcnt)
   // reading 2 consecutive 16bit values is probably a 32bit access. detect this
   // by checking address (max 2 bytes away) and cycles (max 2 cycles later).
   // no polling if more than 20 cycles have passed since last detect call.
-  if (a - sh2->poll_addr <= 2 && CYCLES_GE(10, cycles_diff)) {
-    if (CYCLES_GT(cycles_diff, 2) && ++sh2->poll_cnt >= maxcnt) {
+  if (a - sh2->poll_addr <= 2 && CYCLES_GE(20, cycles_diff)) {
+    if (!sh2_not_polling(sh2) && CYCLES_GT(cycles_diff, 2) &&
+                ++sh2->poll_cnt >= maxcnt) {
       if (!(sh2->state & flags))
         elprintf_sh2(sh2, EL_32X, "state: %02x->%02x",
           sh2->state, sh2->state | flags);
@@ -144,6 +145,7 @@ void NOINLINE p32x_sh2_poll_detect(u32 a, SH2 *sh2, u32 flags, int maxcnt)
     sh2->poll_addr = a;
   }
   sh2->poll_cycles = cycles_done;
+  sh2_set_polling(sh2);
 }
 
 void NOINLINE p32x_sh2_poll_event(SH2 *sh2, u32 flags, u32 m68k_cycles)
index 18e3341..83e8141 100644 (file)
@@ -224,6 +224,8 @@ extern SH2 sh2s[2];
 # define sh2_cycles_left(sh2) (sh2)->icount\r
 # define sh2_burn_cycles(sh2, n) (sh2)->icount -= n\r
 # define sh2_pc(sh2) (sh2)->ppc\r
+# define sh2_not_polling(sh2) (sh2)->no_polling\r
+# define sh2_set_polling(sh2) (sh2)->no_polling = 0\r
 #else\r
 # define sh2_end_run(sh2, after_) do { \\r
   int left_ = ((signed int)(sh2)->sr >> 12) - (after_); \\r
@@ -235,6 +237,8 @@ extern SH2 sh2s[2];
 # define sh2_cycles_left(sh2) ((signed int)(sh2)->sr >> 12)\r
 # define sh2_burn_cycles(sh2, n) (sh2)->sr -= ((n) << 12)\r
 # define sh2_pc(sh2) (sh2)->pc\r
+# define sh2_not_polling(sh2) ((sh2)->sr & SH2_NO_POLLING)\r
+# define sh2_set_polling(sh2) ((sh2)->sr &= ~SH2_NO_POLLING)\r
 #endif\r
 \r
 #define sh2_cycles_done(sh2) (unsigned)((int)(sh2)->cycles_timeslice - sh2_cycles_left(sh2))\r