From e681d4a62cabe75a78dee4243109355336605135 Mon Sep 17 00:00:00 2001 From: Scott Stone Date: Fri, 7 Oct 2011 16:06:28 +0000 Subject: [PATCH] Made the interrupt priority registers reusable on the SH3, hooked up TMU priority register on the sh3 side so that the Timers actually attempt to cause exceptions. From Haze (nw) --- src/emu/cpu/sh4/sh3comn.c | 30 +++++++++++++++++++++++- src/emu/cpu/sh4/sh3comn.h | 3 +++ src/emu/cpu/sh4/sh4.c | 4 ++++ src/emu/cpu/sh4/sh4comn.c | 47 +++++++++++++++++++++++++++++--------- src/emu/cpu/sh4/sh4comn.h | 5 ++++ src/mame/drivers/cavesh3.c | 17 ++++++++++---- 6 files changed, 90 insertions(+), 16 deletions(-) diff --git a/src/emu/cpu/sh4/sh3comn.c b/src/emu/cpu/sh4/sh3comn.c index af74162cfd6..c9b9d9a90e3 100644 --- a/src/emu/cpu/sh4/sh3comn.c +++ b/src/emu/cpu/sh4/sh3comn.c @@ -15,6 +15,25 @@ WRITE32_HANDLER( sh3_internal_high_w ) switch (offset) { + + case SH3_ICR0_IPRA_ADDR: + if (mem_mask & 0xffff0000) + { + logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_ICR0_IPRA_ADDR - ICR0)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + } + + if (mem_mask & 0x0000ffff) + { + logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_ICR0_IPRA_ADDR - IPRA)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + sh4_handler_ipra_w(sh4,data&0xffff,mem_mask&0xffff); + } + + break; + + case SH3_IPRB_ADDR: + logerror("'%s' (%08x): INTC internal write to %08x = %08x & %08x (SH3_IPRB_ADDR)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); + break; + case SH3_TOCR_TSTR_ADDR: logerror("'%s' (%08x): TMU internal write to %08x = %08x & %08x (SH3_TOCR_TSTR_ADDR)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+SH3_UPPER_REGBASE,data,mem_mask); if (mem_mask&0xff000000) @@ -60,6 +79,15 @@ READ32_HANDLER( sh3_internal_high_r ) switch (offset) { + + case SH3_ICR0_IPRA_ADDR: + logerror("'%s' (%08x): INTC internal read from %08x mask %08x (SH3_ICR0_IPRA_ADDR - %08x)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, sh4->m_sh3internal_upper[offset]); + return (sh4->m_sh3internal_upper[offset] & 0xffff0000) | (sh4->SH4_IPRA & 0xffff); + + case SH3_IPRB_ADDR: + logerror("'%s' (%08x): INTC internal read from %08x mask %08x (SH3_IPRB_ADDR - %08x)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+SH3_UPPER_REGBASE,mem_mask, sh4->m_sh3internal_upper[offset]); + return sh4->m_sh3internal_upper[offset]; + case SH3_TOCR_TSTR_ADDR: if (mem_mask&0xff00000) @@ -119,7 +147,7 @@ READ32_HANDLER( sh3_internal_r ) { case INTEVT2: { - logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (INTEVT2)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+0x4000000,mem_mask); + // logerror("'%s' (%08x): unmapped internal read from %08x mask %08x (INTEVT2)\n",sh4->device->tag(), sh4->pc & AM,(offset *4)+0x4000000,mem_mask); return sh4->m_sh3internal_lower[offset]; } break; diff --git a/src/emu/cpu/sh4/sh3comn.h b/src/emu/cpu/sh4/sh3comn.h index 51f5b616b48..3c97fde5637 100644 --- a/src/emu/cpu/sh4/sh3comn.h +++ b/src/emu/cpu/sh4/sh3comn.h @@ -24,6 +24,9 @@ #define SH3_UPPER_REGBASE (0xffffd000) #define SH3_UPPER_REGEND (0xffffffff) +#define SH3_ICR0_IPRA_ADDR ((0xfffffee0 - SH3_UPPER_REGBASE)/4) +#define SH3_IPRB_ADDR ((0xfffffee4 - SH3_UPPER_REGBASE)/4) + #define SH3_TOCR_TSTR_ADDR ((0xfffffe90 - SH3_UPPER_REGBASE)/4) #define SH3_TCOR0_ADDR ((0xfffffe94 - SH3_UPPER_REGBASE)/4) #define SH3_TCNT0_ADDR ((0xfffffe98 - SH3_UPPER_REGBASE)/4) diff --git a/src/emu/cpu/sh4/sh4.c b/src/emu/cpu/sh4/sh4.c index 210c2dbd5e9..4dc2ac67646 100644 --- a/src/emu/cpu/sh4/sh4.c +++ b/src/emu/cpu/sh4/sh4.c @@ -3546,6 +3546,10 @@ static CPU_INIT( sh4 ) device->save_item(NAME(sh4->SH4_TOCR)); device->save_item(NAME(sh4->SH4_TCPR2)); + device->save_item(NAME(sh4->SH4_IPRA)); + + + } diff --git a/src/emu/cpu/sh4/sh4comn.c b/src/emu/cpu/sh4/sh4comn.c index 2b483f8d289..e1c276c1946 100644 --- a/src/emu/cpu/sh4/sh4comn.c +++ b/src/emu/cpu/sh4/sh4comn.c @@ -234,18 +234,25 @@ void sh4_exception_recompute(sh4_state *sh4) // checks if there is any interrupt for (a=0;a <= SH4_INTC_ROVI;a++) { if (sh4->exception_requesting[a]) - if ((((int)sh4->exception_priority[a] >> 8) & 255) > z) + { + int pri = (((int)sh4->exception_priority[a] >> 8) & 255); + //logerror("pri is %02x z is %02x\n",pri,z); + if (pri > z) { + //logerror("will test\n"); sh4->test_irq = 1; // will check for exception at end of instructions break; } + } } } void sh4_exception_request(sh4_state *sh4, int exception) // start requesting an exception { + //logerror("sh4_exception_request a\n"); if (!sh4->exception_requesting[exception]) { + //logerror("sh4_exception_request b\n"); sh4->exception_requesting[exception] = 1; sh4->pending_irq++; sh4_exception_recompute(sh4); @@ -817,7 +824,28 @@ int s; } } +void sh4_handler_ipra_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask) +{ + COMBINE_DATA(&sh4->SH4_IPRA); + /* 15 - 12 TMU0 */ + /* 11 - 8 TMU1 */ + /* 7 - 4 TMU2 */ + /* 3 - 0 RTC */ + sh4->exception_priority[SH4_INTC_ATI] = INTPRI(sh4->SH4_IPRA & 0x000f, SH4_INTC_ATI); + sh4->exception_priority[SH4_INTC_PRI] = INTPRI(sh4->SH4_IPRA & 0x000f, SH4_INTC_PRI); + sh4->exception_priority[SH4_INTC_CUI] = INTPRI(sh4->SH4_IPRA & 0x000f, SH4_INTC_CUI); + sh4->exception_priority[SH4_INTC_TUNI2] = INTPRI((sh4->SH4_IPRA & 0x00f0) >> 4, SH4_INTC_TUNI2); + sh4->exception_priority[SH4_INTC_TICPI2] = INTPRI((sh4->SH4_IPRA & 0x00f0) >> 4, SH4_INTC_TICPI2); + + sh4->exception_priority[SH4_INTC_TUNI1] = INTPRI((sh4->SH4_IPRA & 0x0f00) >> 8, SH4_INTC_TUNI1); + + sh4->exception_priority[SH4_INTC_TUNI0] = INTPRI((sh4->SH4_IPRA & 0xf000) >> 12, SH4_INTC_TUNI0); + + logerror("setting priorities TMU0 %01x TMU1 %01x TMU2 %01x RTC %01x\n", (sh4->SH4_IPRA & 0xf000)>>12, (sh4->SH4_IPRA & 0x0f00)>>8, (sh4->SH4_IPRA & 0x00f0)>>4, (sh4->SH4_IPRA & 0x000f)>>0); + + sh4_exception_recompute(sh4); +} WRITE32_HANDLER( sh4_internal_w ) { @@ -948,16 +976,7 @@ WRITE32_HANDLER( sh4_internal_w ) case ICR: sh4->m[ICR] = (sh4->m[ICR] & 0x7fff) | (old & 0x8000); break; - case IPRA: - sh4->exception_priority[SH4_INTC_ATI] = INTPRI(sh4->m[IPRA] & 0x000f, SH4_INTC_ATI); - sh4->exception_priority[SH4_INTC_PRI] = INTPRI(sh4->m[IPRA] & 0x000f, SH4_INTC_PRI); - sh4->exception_priority[SH4_INTC_CUI] = INTPRI(sh4->m[IPRA] & 0x000f, SH4_INTC_CUI); - sh4->exception_priority[SH4_INTC_TUNI2] = INTPRI((sh4->m[IPRA] & 0x00f0) >> 4, SH4_INTC_TUNI2); - sh4->exception_priority[SH4_INTC_TICPI2] = INTPRI((sh4->m[IPRA] & 0x00f0) >> 4, SH4_INTC_TICPI2); - sh4->exception_priority[SH4_INTC_TUNI1] = INTPRI((sh4->m[IPRA] & 0x0f00) >> 8, SH4_INTC_TUNI1); - sh4->exception_priority[SH4_INTC_TUNI0] = INTPRI((sh4->m[IPRA] & 0xf000) >> 12, SH4_INTC_TUNI0); - sh4_exception_recompute(sh4); - break; + case IPRA: sh4_handler_ipra_w(sh4, data, mem_mask); break; case IPRB: sh4->exception_priority[SH4_INTC_SCI1ERI] = INTPRI((sh4->m[IPRB] & 0x00f0) >> 4, SH4_INTC_SCI1ERI); sh4->exception_priority[SH4_INTC_SCI1RXI] = INTPRI((sh4->m[IPRB] & 0x00f0) >> 4, SH4_INTC_SCI1RXI); @@ -1105,6 +1124,12 @@ READ32_HANDLER( sh4_internal_r ) return sh4->m[RTCNT]; break; +/********************************************************************************************************************* + INTC (Interrupt Controller) +*********************************************************************************************************************/ + + case IPRA: + return sh4->SH4_IPRA; /********************************************************************************************************************* TMU (Timer Unit) diff --git a/src/emu/cpu/sh4/sh4comn.h b/src/emu/cpu/sh4/sh4comn.h index 047d76e41b7..37bfdbaac20 100644 --- a/src/emu/cpu/sh4/sh4comn.h +++ b/src/emu/cpu/sh4/sh4comn.h @@ -96,6 +96,10 @@ typedef struct UINT32 SH4_TOCR; UINT32 SH4_TCPR2; + // INTC regs + UINT32 SH4_IPRA; + + // sh3 internal UINT32 m_sh3internal_upper[0x3000/4]; UINT32 m_sh3internal_lower[0x1000]; @@ -289,6 +293,7 @@ void sh4_swap_fp_couples(sh4_state *sh4); #endif void sh4_common_init(device_t *device); UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address); +void sh4_handler_ipra_w(sh4_state *sh4, UINT32 data, UINT32 mem_mask); READ64_HANDLER( sh4_tlb_r ); WRITE64_HANDLER( sh4_tlb_w ); diff --git a/src/mame/drivers/cavesh3.c b/src/mame/drivers/cavesh3.c index 5bd4912999f..73ba7f85e47 100644 --- a/src/mame/drivers/cavesh3.c +++ b/src/mame/drivers/cavesh3.c @@ -128,15 +128,24 @@ static const struct sh4_config sh4cpu_config = { 1, 0, 1, 0, 0, 0, 1, 1, static IRQ_CALLBACK(cavesh3_int_callback) { - printf("irqline %02x\n",irqline); - cputag_set_input_line(device->machine(), "maincpu", 2, CLEAR_LINE); - return 0x640; // hack vector until SH3 core works better + if (irqline == 4) + { + logerror("irqline %02x\n",irqline); + cputag_set_input_line(device->machine(), "maincpu", 4, CLEAR_LINE); + return 0x420; + } + else + { + logerror("irqline %02x\n",irqline); + cputag_set_input_line(device->machine(), "maincpu", 2, CLEAR_LINE); + return 0x640; // hack vector until SH3 core works better + } } static INTERRUPT_GEN(cavesh3_interrupt) { - device_set_input_line(device, 2, ASSERT_LINE); +// device_set_input_line(device, 2, ASSERT_LINE); // device->machine().scheduler().timer_set(downcast(device)->cycles_to_attotime(10000), FUNC(cavesh3_interrupt_off)); }