summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/sh4/sh4comn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/sh4/sh4comn.c')
-rw-r--r--src/emu/cpu/sh4/sh4comn.c229
1 files changed, 175 insertions, 54 deletions
diff --git a/src/emu/cpu/sh4/sh4comn.c b/src/emu/cpu/sh4/sh4comn.c
index ecf20a2a719..0546bed1196 100644
--- a/src/emu/cpu/sh4/sh4comn.c
+++ b/src/emu/cpu/sh4/sh4comn.c
@@ -140,9 +140,8 @@ static const int exception_codes[] =
/* SH3 INTEVT2 uses a different table */
-static const UINT16 tcnt[] = { TCNT0, TCNT1, TCNT2 };
-static const UINT16 tcor[] = { TCOR0, TCOR1, TCOR2 };
-static const UINT16 tcr[] = { TCR0, TCR1, TCR2 };
+
+
void sh4_change_register_bank(sh4_state *sh4, int to)
{
@@ -414,12 +413,28 @@ static void sh4_timer_recompute(sh4_state *sh4, int which)
{
double ticks;
- if (sh4->cpu_type != CPU_TYPE_SH4)
- fatalerror("sh4_timer_recompute uses sh4->m[] with SH3\n");
+ UINT32 tcnt = 0;
+ UINT32 tcr = 0;
+ switch (which)
+ {
+ case 0:
+ tcr = sh4->SH4_TCR0;
+ tcnt = sh4->SH4_TCNT0;
+ break;
+ case 1:
+ tcr = sh4->SH4_TCR1;
+ tcnt = sh4->SH4_TCNT1;
+ break;
- ticks = sh4->m[tcnt[which]];
- sh4->timer[which]->adjust(sh4_scale_up_mame_time(attotime::from_hz(sh4->pm_clock) * tcnt_div[sh4->m[tcr[which]] & 7], ticks), which);
+ case 2:
+ tcr = sh4->SH4_TCR2;
+ tcnt = sh4->SH4_TCNT2;
+ break;
+ }
+
+ ticks = tcnt;
+ sh4->timer[which]->adjust(sh4_scale_up_mame_time(attotime::from_hz(sh4->pm_clock) * tcnt_div[tcr & 7], ticks), which);
}
static TIMER_CALLBACK( sh4_refresh_timer_callback )
@@ -561,19 +576,63 @@ static TIMER_CALLBACK( sh4_rtc_timer_callback )
static TIMER_CALLBACK( sh4_timer_callback )
{
- static const UINT16 tuni[] = { SH4_INTC_TUNI0, SH4_INTC_TUNI1, SH4_INTC_TUNI2 };
sh4_state *sh4 = (sh4_state *)ptr;
int which = param;
- int idx = tcr[which];
- if (sh4->cpu_type != CPU_TYPE_SH4)
- fatalerror("sh4_timer_callback uses sh4->m[] with SH3\n");
+ switch (which)
+ {
+ case 0:
+ sh4->SH4_TCNT0 = sh4->SH4_TCOR0;
+ break;
+
+ case 1:
+ sh4->SH4_TCNT1 = sh4->SH4_TCOR1;
+ break;
+
+ case 2:
+ sh4->SH4_TCNT2 = sh4->SH4_TCOR2;
+ break;
+
+ }
- sh4->m[tcnt[which]] = sh4->m[tcor[which]];
sh4_timer_recompute(sh4, which);
- sh4->m[idx] = sh4->m[idx] | 0x100;
- if (sh4->m[idx] & 0x20)
- sh4_exception_request(sh4, tuni[which]);
+
+ switch (which)
+ {
+ case 0:
+ sh4->SH4_TCR0 |= 0x100;
+ break;
+
+ case 1:
+ sh4->SH4_TCR1 |= 0x100;
+ break;
+
+ case 2:
+ sh4->SH4_TCR2 |= 0x100;
+ break;
+
+ }
+
+ switch (which)
+ {
+ case 0:
+ if (sh4->SH4_TCR0 & 0x20)
+ sh4_exception_request(sh4, SH4_INTC_TUNI0);
+ break;
+
+ case 1:
+ if (sh4->SH4_TCR1 & 0x20)
+ sh4_exception_request(sh4, SH4_INTC_TUNI1);
+ break;
+
+ case 2:
+ if (sh4->SH4_TCR2 & 0x20)
+ sh4_exception_request(sh4, SH4_INTC_TUNI2);
+ break;
+
+ }
+
+
}
static TIMER_CALLBACK( sh4_dmac_callback )
@@ -873,6 +932,7 @@ WRITE32_HANDLER( sh4_internal_w )
UINT32 old = sh4->m[offset];
COMBINE_DATA(sh4->m+offset);
+ UINT32 old2 = 0;
// printf("sh4_internal_w: Write %08x (%x), %08x @ %08x\n", 0xfe000000+((offset & 0x3fc0) << 11)+((offset & 0x3f) << 2), offset, data, mem_mask);
@@ -969,93 +1029,119 @@ WRITE32_HANDLER( sh4_internal_w )
}
break;
- // TMU
+/*********************************************************************************************************************
+ TMU (Timer Unit)
+*********************************************************************************************************************/
case TSTR:
- if (old & 1)
- sh4->m[TCNT0] = compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[sh4->m[TCR0] & 7]);
- if ((sh4->m[TSTR] & 1) == 0) {
+ old2 = sh4->SH4_TSTR;
+ COMBINE_DATA(&sh4->SH4_TSTR);
+
+ if (old2 & 1)
+ sh4->SH4_TCNT0 = compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[sh4->SH4_TCR0 & 7]);
+ if ((sh4->SH4_TSTR & 1) == 0) {
sh4->timer[0]->adjust(attotime::never);
} else
sh4_timer_recompute(sh4, 0);
- if (old & 2)
- sh4->m[TCNT1] = compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[sh4->m[TCR1] & 7]);
- if ((sh4->m[TSTR] & 2) == 0) {
+ if (old2 & 2)
+ sh4->SH4_TCNT1 = compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[sh4->SH4_TCR1 & 7]);
+ if ((sh4->SH4_TSTR & 2) == 0) {
sh4->timer[1]->adjust(attotime::never);
} else
sh4_timer_recompute(sh4, 1);
- if (old & 4)
- sh4->m[TCNT2] = compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[sh4->m[TCR2] & 7]);
- if ((sh4->m[TSTR] & 4) == 0) {
+ if (old2 & 4)
+ sh4->SH4_TCNT2 = compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[sh4->SH4_TCR2 & 7]);
+ if ((sh4->SH4_TSTR & 4) == 0) {
sh4->timer[2]->adjust(attotime::never);
} else
sh4_timer_recompute(sh4, 2);
break;
case TCR0:
- if (sh4->m[TSTR] & 1)
+ old2 = sh4->SH4_TCR0;
+ COMBINE_DATA(&sh4->SH4_TCR0);
+ if (sh4->SH4_TSTR & 1)
{
- sh4->m[TCNT0] = compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[old & 7]);
+ sh4->SH4_TCNT0 = compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[old2 & 7]);
sh4_timer_recompute(sh4, 0);
}
- if (!(sh4->m[TCR0] & 0x20) || !(sh4->m[TCR0] & 0x100))
+ if (!(sh4->SH4_TCR0 & 0x20) || !(sh4->SH4_TCR0 & 0x100))
sh4_exception_unrequest(sh4, SH4_INTC_TUNI0);
break;
case TCR1:
- if (sh4->m[TSTR] & 2)
+ old2 = sh4->SH4_TCR1;
+ COMBINE_DATA(&sh4->SH4_TCR1);
+ if (sh4->SH4_TSTR & 2)
{
- sh4->m[TCNT1] = compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[old & 7]);
+ sh4->SH4_TCNT1 = compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[old2 & 7]);
sh4_timer_recompute(sh4, 1);
}
- if (!(sh4->m[TCR1] & 0x20) || !(sh4->m[TCR1] & 0x100))
+ if (!(sh4->SH4_TCR1 & 0x20) || !(sh4->SH4_TCR1 & 0x100))
sh4_exception_unrequest(sh4, SH4_INTC_TUNI1);
break;
case TCR2:
- if (sh4->m[TSTR] & 4)
+ old2 = sh4->SH4_TCR2;
+ COMBINE_DATA(&sh4->SH4_TCR2);
+ if (sh4->SH4_TSTR & 4)
{
- sh4->m[TCNT2] = compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[old & 7]);
+ sh4->SH4_TCNT2 = compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[old2 & 7]);
sh4_timer_recompute(sh4, 2);
}
- if (!(sh4->m[TCR2] & 0x20) || !(sh4->m[TCR2] & 0x100))
+ if (!(sh4->SH4_TCR2 & 0x20) || !(sh4->SH4_TCR2 & 0x100))
sh4_exception_unrequest(sh4, SH4_INTC_TUNI2);
break;
case TCOR0:
- if (sh4->m[TSTR] & 1)
+ COMBINE_DATA(&sh4->SH4_TCOR0);
+ if (sh4->SH4_TSTR & 1)
{
- sh4->m[TCNT0] = compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[sh4->m[TCR0] & 7]);
+ sh4->SH4_TCNT0 = compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[sh4->SH4_TCR0 & 7]);
sh4_timer_recompute(sh4, 0);
}
break;
case TCNT0:
- if (sh4->m[TSTR] & 1)
+ COMBINE_DATA(&sh4->SH4_TCNT0);
+ if (sh4->SH4_TSTR & 1)
sh4_timer_recompute(sh4, 0);
break;
case TCOR1:
- if (sh4->m[TSTR] & 2)
+ COMBINE_DATA(&sh4->SH4_TCOR1);
+ if (sh4->SH4_TSTR & 2)
{
- sh4->m[TCNT1] = compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[sh4->m[TCR1] & 7]);
+ sh4->SH4_TCNT1 = compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[sh4->SH4_TCR1 & 7]);
sh4_timer_recompute(sh4, 1);
}
break;
case TCNT1:
- if (sh4->m[TSTR] & 2)
+ COMBINE_DATA(&sh4->SH4_TCNT1);
+ if (sh4->SH4_TSTR & 2)
sh4_timer_recompute(sh4, 1);
break;
case TCOR2:
- if (sh4->m[TSTR] & 4)
+ COMBINE_DATA(&sh4->SH4_TCOR2);
+ if (sh4->SH4_TSTR & 4)
{
- sh4->m[TCNT2] = compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[sh4->m[TCR2] & 7]);
+ sh4->SH4_TCNT2 = compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[sh4->SH4_TCR2 & 7]);
sh4_timer_recompute(sh4, 2);
}
break;
case TCNT2:
- if (sh4->m[TSTR] & 4)
+ COMBINE_DATA(&sh4->SH4_TCNT2);
+ if (sh4->SH4_TSTR & 4)
sh4_timer_recompute(sh4, 2);
break;
- // INTC
+ case TOCR: // not supported
+ COMBINE_DATA(&sh4->SH4_TOCR);
+ break;
+
+ case TCPR2: // not supported
+ COMBINE_DATA(&sh4->SH4_TCPR2);
+ break;
+/*********************************************************************************************************************
+ INTC (Interrupt Controller)
+*********************************************************************************************************************/
case ICR:
sh4->m[ICR] = (sh4->m[ICR] & 0x7fff) | (old & 0x8000);
break;
@@ -1216,26 +1302,61 @@ READ32_HANDLER( sh4_internal_r )
return sh4->m[RTCNT];
break;
+
+/*********************************************************************************************************************
+ TMU (Timer Unit)
+*********************************************************************************************************************/
+
+ case TSTR:
+ return sh4->SH4_TSTR;
+
+ case TCR0:
+ return sh4->SH4_TCR0;
+
+ case TCR1:
+ return sh4->SH4_TCR1;
+
+ case TCR2:
+ return sh4->SH4_TCR2;
+
case TCNT0:
- if (sh4->m[TSTR] & 1)
- return compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[sh4->m[TCR0] & 7]);
+ if (sh4->SH4_TSTR & 1)
+ return compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[sh4->SH4_TCR0 & 7]);
else
- return sh4->m[TCNT0];
+ return sh4->SH4_TCNT0;
break;
case TCNT1:
- if (sh4->m[TSTR] & 2)
- return compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[sh4->m[TCR1] & 7]);
+ if (sh4->SH4_TSTR & 2)
+ return compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[sh4->SH4_TCR1 & 7]);
else
- return sh4->m[TCNT1];
+ return sh4->SH4_TCNT1;
break;
case TCNT2:
- if (sh4->m[TSTR] & 4)
- return compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[sh4->m[TCR2] & 7]);
+ if (sh4->SH4_TSTR & 4)
+ return compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[sh4->SH4_TCR2 & 7]);
else
- return sh4->m[TCNT2];
+ return sh4->SH4_TCNT2;
break;
- // I/O ports
+ case TCOR0:
+ return sh4->SH4_TCOR0;
+
+ case TCOR1:
+ return sh4->SH4_TCOR1;
+
+ case TCOR2:
+ return sh4->SH4_TCOR2;
+
+ case TOCR: // not supported
+ return sh4->SH4_TOCR;
+
+ case TCPR2: // not supported
+ return sh4->SH4_TCPR2;
+
+/*********************************************************************************************************************
+ I/O Ports
+*********************************************************************************************************************/
+
case PDTRA:
if (sh4->m[BCR2] & 1)
return (sh4->io->read_dword(SH4_IOPORT_16) & ~sh4->ioport16_direction) | (sh4->m[PDTRA] & sh4->ioport16_direction);