From 35821b373c99f37696ec02aad83415d0467e1bd9 Mon Sep 17 00:00:00 2001 From: kub Date: Fri, 25 Nov 2022 19:26:37 +0000 Subject: [PATCH] Revert 4ec1247 as it cause more troubles than it solves --- cpu/sh2/compiler.c | 2 ++ cpu/sh2/sh2.h | 1 - pico/32x/32x.c | 19 ++++------------- pico/32x/memory.c | 2 +- pico/32x/pwm.c | 6 +++--- pico/32x/sh2soc.c | 51 +++++++++++++++++++++------------------------- 6 files changed, 33 insertions(+), 48 deletions(-) diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 0766a6e7..360fcd03 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -3836,6 +3836,8 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) u = FETCH32(opd->imm); else u = (s16)FETCH_OP(opd->imm); + // tweak for Blackthorne: avoid stack overwriting + if (GET_Rn() == SHR_SP && u == 0x0603f800) u = 0x0603f900; gconst_new(GET_Rn(), u); } else diff --git a/cpu/sh2/sh2.h b/cpu/sh2/sh2.h index db729bba..bb8debe0 100644 --- a/cpu/sh2/sh2.h +++ b/cpu/sh2/sh2.h @@ -52,7 +52,6 @@ typedef struct SH2_ #define SH2_STATE_RPOLL (1 << 4) // polling address in SDRAM #define SH2_TIMER_RUN (1 << 6) // SOC WDT timer is running #define SH2_IN_DRC (1 << 7) // DRC in use -#define SH2_PWM_IRQ (1 << 8) // entering IRQ unsigned int state; uint32_t poll_addr; int poll_cycles; diff --git a/pico/32x/32x.c b/pico/32x/32x.c index 6b54ea48..f7654360 100644 --- a/pico/32x/32x.c +++ b/pico/32x/32x.c @@ -19,11 +19,6 @@ static int REGPARM(2) sh2_irq_cb(SH2 *sh2, int level) if (sh2->pending_irl > sh2->pending_int_irq) { elprintf_sh2(sh2, EL_32X, "ack/irl %d @ %08x", level, sh2_pc(sh2)); - // tweak for Blackthorne, part 1: master SH2 overwrites stack of slave SH2 being - // in pwm interrupt. On real hardware, nothing happens since slave fetches the - // values it has written from its cache, but picodrive doesn't emulate caching. - if ((1<pending_irl/2) == P32XI_PWM && sh2->is_slave) - sh2->state |= SH2_PWM_IRQ; return 64 + sh2->pending_irl / 2; } else { elprintf_sh2(sh2, EL_32X, "ack/int %d/%d @ %08x", @@ -60,13 +55,15 @@ void p32x_update_irls(SH2 *active_sh2, unsigned int m68k_cycles) mrun = sh2_irl_irq(&msh2, mlvl, msh2.state & SH2_STATE_RUN); if (mrun) { p32x_sh2_poll_event(&msh2, SH2_IDLE_STATES & ~SH2_STATE_SLEEP, m68k_cycles); - p32x_sync_other_sh2(&msh2, m68k_cycles); + if (msh2.state & SH2_STATE_RUN) + sh2_end_run(&msh2, 0); } srun = sh2_irl_irq(&ssh2, slvl, ssh2.state & SH2_STATE_RUN); if (srun) { p32x_sh2_poll_event(&ssh2, SH2_IDLE_STATES & ~SH2_STATE_SLEEP, m68k_cycles); - p32x_sync_other_sh2(&ssh2, m68k_cycles); + if (ssh2.state & SH2_STATE_RUN) + sh2_end_run(&ssh2, 0); } elprintf(EL_32X, "update_irls: m %d/%d, s %d/%d", mlvl, mrun, slvl, srun); @@ -389,18 +386,10 @@ static void p32x_run_events(unsigned int until) static void run_sh2(SH2 *sh2, unsigned int m68k_cycles) { unsigned int cycles, done; - unsigned int cpwm = 1400, m68k_cpwm = C_SH2_TO_M68K(sh2, cpwm); pevt_log_sh2_o(sh2, EVT_RUN_START); sh2->state |= SH2_STATE_RUN; cycles = C_M68K_TO_SH2(sh2, m68k_cycles); - // tweak for Blackthorne, part 2: try to ensure that the PWM irq completes before - // switching to the other SH2. This irq can run up to about 1400 cycles. - // NB, may delay hint/vint interrupts on the same SH2, might cause sync problems. - if (unlikely(sh2->state & SH2_PWM_IRQ) && cycles < cpwm && - CYCLES_GT(p32x_event_times[P32X_EVENT_PWM], sh2->m68krcycles_done+m68k_cpwm)) - cycles = 1400; - sh2->state &= ~SH2_PWM_IRQ; elprintf_sh2(sh2, EL_32X, "+run %u %d @%08x", sh2->m68krcycles_done, cycles, sh2->pc); diff --git a/pico/32x/memory.c b/pico/32x/memory.c index c1c35e23..7a61e89e 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -816,7 +816,7 @@ static void p32x_sh2reg_write8(u32 a, u32 d, SH2 *sh2) Pico32x.sh2_regs[0] &= ~0x80; Pico32x.sh2_regs[0] |= d & 0x80; - if ((old ^ d) & 1) + if ((d ^ old) & 1) p32x_pwm_schedule_sh2(sh2); if ((old ^ d) & 2) p32x_update_cmd_irq(sh2, 0); diff --git a/pico/32x/pwm.c b/pico/32x/pwm.c index 1b10103a..ed8d761e 100644 --- a/pico/32x/pwm.c +++ b/pico/32x/pwm.c @@ -41,13 +41,13 @@ void p32x_pwm_ctl_changed(void) pwm.irq_reload = pwm.irq_timer; pwm.irq_state = pwm_irq_opt ? PWM_IRQ_STOPPED: PWM_IRQ_LOCKED; - if (Pico32x.pwm_irq_cnt <= 0) + if (Pico32x.pwm_irq_cnt == 0) Pico32x.pwm_irq_cnt = pwm.irq_reload; } static void do_pwm_irq(SH2 *sh2, unsigned int m68k_cycles) { - p32x_trigger_irq(NULL, m68k_cycles, P32XI_PWM); + p32x_trigger_irq(sh2, m68k_cycles, P32XI_PWM); if (Pico32x.regs[0x30 / 2] & P32XP_RTP) { p32x_event_schedule(m68k_cycles, P32X_EVENT_PWM, pwm.cycles / 3 + 1); @@ -110,7 +110,7 @@ static void consume_fifo_do(SH2 *sh2, unsigned int m68k_cycles, mem->pwm[pwm.ptr * 2 + 1] = pwm.current[1]; pwm.ptr = (pwm.ptr + 1) & (PWM_BUFF_LEN - 1); - if (--Pico32x.pwm_irq_cnt <= 0) { + if (--Pico32x.pwm_irq_cnt == 0) { Pico32x.pwm_irq_cnt = pwm.irq_reload; do_pwm_irq(sh2, m68k_cycles); } else if (Pico32x.pwm_p[1] == 0 && pwm.irq_state >= PWM_IRQ_LOW) { diff --git a/pico/32x/sh2soc.c b/pico/32x/sh2soc.c index f6524724..f8bb4e79 100644 --- a/pico/32x/sh2soc.c +++ b/pico/32x/sh2soc.c @@ -270,7 +270,6 @@ u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2) u8 *r = (void *)sh2->peri_regs; u32 d; - DRC_SAVE_SR(sh2); a &= 0x1ff; d = PREG8(r, a); @@ -278,9 +277,10 @@ u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2) a | ~0x1ff, d, sh2_pc(sh2)); if ((a & 0x1c0) == 0x140) { // abused as comm area + DRC_SAVE_SR(sh2); p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3); + DRC_RESTORE_SR(sh2); } - DRC_RESTORE_SR(sh2); return d; } @@ -289,7 +289,6 @@ u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2) u16 *r = (void *)sh2->peri_regs; u32 d; - DRC_SAVE_SR(sh2); a &= 0x1fe; d = r[MEM_BE2(a / 2)]; @@ -297,9 +296,10 @@ u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2) a | ~0x1ff, d, sh2_pc(sh2)); if ((a & 0x1c0) == 0x140) { // abused as comm area + DRC_SAVE_SR(sh2); p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3); + DRC_RESTORE_SR(sh2); } - DRC_RESTORE_SR(sh2); return d; } @@ -307,7 +307,6 @@ u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2) { u32 d; - DRC_SAVE_SR(sh2); a &= 0x1fc; d = sh2->peri_regs[a / 4]; @@ -318,9 +317,10 @@ u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2) sh2->poll_cnt = 0; else if ((a & 0x1c0) == 0x140) { // abused as comm area + DRC_SAVE_SR(sh2); p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3); + DRC_RESTORE_SR(sh2); } - DRC_RESTORE_SR(sh2); return d; } @@ -364,18 +364,18 @@ void REGPARM(3) sh2_peripheral_write8(u32 a, u32 d, SH2 *sh2) u8 *r = (void *)sh2->peri_regs; u8 old; - DRC_SAVE_SR(sh2); elprintf_sh2(sh2, EL_32XP, "peri w8 [%08x] %02x @%06x", a, d, sh2_pc(sh2)); a &= 0x1ff; old = PREG8(r, a); - PREG8(r, a) = d; switch (a) { case 0x002: // SCR - serial control - if (!(old & 0x20) && (d & 0x20)) // TE being set + if (!(PREG8(r, a) & 0x20) && (d & 0x20)) { // TE being set + PREG8(r, a) = d; sci_trigger(sh2, r); + } break; case 0x003: // TDR - transmit data break; @@ -383,31 +383,27 @@ void REGPARM(3) sh2_peripheral_write8(u32 a, u32 d, SH2 *sh2) d = (old & (d | 0x06)) | (d & 1); PREG8(r, a) = d; sci_trigger(sh2, r); - break; + return; case 0x005: // RDR - receive data break; case 0x010: // TIER if (d & 0x8e) elprintf(EL_32XP|EL_ANOMALY, "TIER: %02x", d); d = (d & 0x8e) | 1; - PREG8(r, a) = d; break; case 0x017: // TOCR d |= 0xe0; - PREG8(r, a) = d; break; - default: - if ((a & 0x1c0) == 0x140) - p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone()); } - DRC_RESTORE_SR(sh2); + PREG8(r, a) = d; + + if ((a & 0x1c0) == 0x140) + p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone()); } void REGPARM(3) sh2_peripheral_write16(u32 a, u32 d, SH2 *sh2) { u16 *r = (void *)sh2->peri_regs; - - DRC_SAVE_SR(sh2); elprintf_sh2(sh2, EL_32XP, "peri w16 [%08x] %04x @%06x", a, d, sh2_pc(sh2)); @@ -421,12 +417,12 @@ void REGPARM(3) sh2_peripheral_write16(u32 a, u32 d, SH2 *sh2) } if ((d & 0xff00) == 0x5a00) // WTCNT PREG8(r, 0x81) = d; - } else { - r[MEM_BE2(a / 2)] = d; - if ((a & 0x1c0) == 0x140) - p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone()); + return; } - DRC_RESTORE_SR(sh2); + + r[MEM_BE2(a / 2)] = d; + if ((a & 0x1c0) == 0x140) + p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone()); } void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2) @@ -435,7 +431,6 @@ void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2) u32 old; struct dmac *dmac; - DRC_SAVE_SR(sh2); elprintf_sh2(sh2, EL_32XP, "peri w32 [%08x] %08x @%06x", a, d, sh2_pc(sh2)); @@ -485,17 +480,17 @@ void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2) if (!(dmac->dmaor & DMA_DME)) return; + DRC_SAVE_SR(sh2); if ((dmac->chan[0].chcr & (DMA_TE|DMA_DE)) == DMA_DE) dmac_trigger(sh2, &dmac->chan[0]); if ((dmac->chan[1].chcr & (DMA_TE|DMA_DE)) == DMA_DE) dmac_trigger(sh2, &dmac->chan[1]); + DRC_RESTORE_SR(sh2); break; - default: - if ((a & 0x1c0) == 0x140) - p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone()); } - DRC_RESTORE_SR(sh2); + if ((a & 0x1c0) == 0x140) + p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone()); } /* 32X specific */ -- 2.39.2