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)

This commit is contained in:
Scott Stone 2011-10-07 16:06:28 +00:00
parent ae1fb4a685
commit e681d4a62c
6 changed files with 90 additions and 16 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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));
}

View File

@ -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)

View File

@ -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 );

View File

@ -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<cpu_device *>(device)->cycles_to_attotime(10000), FUNC(cavesh3_interrupt_off));
}