From bd07808352da7c6d0d7f67b086319c2e681cd273 Mon Sep 17 00:00:00 2001 From: kub Date: Mon, 28 Jun 2021 22:58:04 +0200 Subject: [PATCH] 32x, improve poll detection --- cpu/sh2/compiler.c | 1 + cpu/sh2/mame/sh2.c | 1 + cpu/sh2/mame/sh2pico.c | 6 ++++-- cpu/sh2/sh2.h | 3 +++ pico/32x/memory.c | 6 ++++-- pico/pico_int.h | 4 ++++ 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 66400c77..bb2206c1 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -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_; diff --git a/cpu/sh2/mame/sh2.c b/cpu/sh2/mame/sh2.c index fa49153a..17b96a31 100644 --- a/cpu/sh2/mame/sh2.c +++ b/cpu/sh2/mame/sh2.c @@ -800,6 +800,7 @@ INLINE void DT(sh2_state *sh2, UINT32 n) sh2->sr |= T; else sh2->sr &= ~T; + sh2->no_polling = SH2_NO_POLLING; #if BUSY_LOOP_HACKS { UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM ); diff --git a/cpu/sh2/mame/sh2pico.c b/cpu/sh2/mame/sh2pico.c index f4ae85cb..65f4757e 100644 --- a/cpu/sh2/mame/sh2pico.c +++ b/cpu/sh2/mame/sh2pico.c @@ -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; \ } diff --git a/cpu/sh2/sh2.h b/cpu/sh2/sh2.h index 614e7de1..bb8debe0 100644 --- a/cpu/sh2/sh2.h +++ b/cpu/sh2/sh2.h @@ -56,6 +56,9 @@ typedef struct SH2_ uint32_t poll_addr; int poll_cycles; int poll_cnt; +// NB MUST be a bit unused in SH2 SR, see also cpu/sh2/compiler.c! +#define SH2_NO_POLLING (1 << 10) // poll detection control + int no_polling; // DRC branch cache. size must be 2^n and <=128 int rts_cache_idx; diff --git a/pico/32x/memory.c b/pico/32x/memory.c index ac26ba4b..d49cd2a5 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -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) diff --git a/pico/pico_int.h b/pico/pico_int.h index 18e33418..83e81418 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -224,6 +224,8 @@ extern SH2 sh2s[2]; # define sh2_cycles_left(sh2) (sh2)->icount # define sh2_burn_cycles(sh2, n) (sh2)->icount -= n # define sh2_pc(sh2) (sh2)->ppc +# define sh2_not_polling(sh2) (sh2)->no_polling +# define sh2_set_polling(sh2) (sh2)->no_polling = 0 #else # define sh2_end_run(sh2, after_) do { \ int left_ = ((signed int)(sh2)->sr >> 12) - (after_); \ @@ -235,6 +237,8 @@ extern SH2 sh2s[2]; # define sh2_cycles_left(sh2) ((signed int)(sh2)->sr >> 12) # define sh2_burn_cycles(sh2, n) (sh2)->sr -= ((n) << 12) # define sh2_pc(sh2) (sh2)->pc +# define sh2_not_polling(sh2) ((sh2)->sr & SH2_NO_POLLING) +# define sh2_set_polling(sh2) ((sh2)->sr &= ~SH2_NO_POLLING) #endif #define sh2_cycles_done(sh2) (unsigned)((int)(sh2)->cycles_timeslice - sh2_cycles_left(sh2)) -- 2.39.5