summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/sh4/sh4comn.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2011-10-07 12:57:06 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2011-10-07 12:57:06 +0000
commit56e64fe500334c14aaaa5b417663dbd77023a41c (patch)
treeb1319de1aeea1cd96f2afdaae2b4331aa74c252c /src/emu/cpu/sh4/sh4comn.c
parentbc30cc554d6c06c637544cadce4d63d1d2a34d47 (diff)
Reusing the SH4 timer code for the SH3 after a bit of refactoring by Haze (no whatsnew)
Diffstat (limited to 'src/emu/cpu/sh4/sh4comn.c')
-rw-r--r--src/emu/cpu/sh4/sh4comn.c292
1 files changed, 30 insertions, 262 deletions
diff --git a/src/emu/cpu/sh4/sh4comn.c b/src/emu/cpu/sh4/sh4comn.c
index 0546bed1196..2b483f8d289 100644
--- a/src/emu/cpu/sh4/sh4comn.c
+++ b/src/emu/cpu/sh4/sh4comn.c
@@ -12,8 +12,9 @@
#include "sh4regs.h"
#include "sh4comn.h"
#include "sh3comn.h"
+#include "sh4tmu.h"
+
-static const int tcnt_div[8] = { 4, 16, 64, 256, 1024, 1, 1, 1 };
static const int rtcnt_div[8] = { 0, 4, 16, 64, 256, 1024, 2048, 4096 };
static const int daysmonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const int dmasize[8] = { 8, 1, 2, 4, 32, 0, 0, 0 };
@@ -337,7 +338,7 @@ void sh4_exception(sh4_state *sh4, const char *message, int exception) // handle
//printf("exception %04x\n", exception);
//sh4->m_sh3internal_lower[INTEVT2] = sh3_intevt2_exception_codes[exception];
sh4->m_sh3internal_lower[INTEVT2] = callbackval;
- sh4->m_sh3internal_upper[SH3_EXPEVT] = exception_codes[exception];
+ sh4->m_sh3internal_upper[SH3_EXPEVT_ADDR] = exception_codes[exception];
LOG(("SH-3 '%s' interrupt exception #%d after [%s]\n", sh4->device->tag(), exception, message));
@@ -366,6 +367,7 @@ void sh4_exception(sh4_state *sh4, const char *message, int exception) // handle
if(sh4->sleep_mode == 1) { sh4->sleep_mode = 2; }
}
+
static UINT32 compute_ticks_refresh_timer(emu_timer *timer, int hertz, int base, int divisor)
{
// elapsed:total = x : ticks
@@ -391,51 +393,6 @@ UINT32 ticks;
sh4->refresh_timer_base = sh4->m[RTCNT];
}
-/*-------------------------------------------------
- sh4_scale_up_mame_time - multiply a attotime by
- a (constant+1) where 0 <= constant < 2^32
--------------------------------------------------*/
-
-INLINE attotime sh4_scale_up_mame_time(attotime _time1, UINT32 factor1)
-{
- return _time1 * factor1 + _time1;
-}
-
-static UINT32 compute_ticks_timer(emu_timer *timer, int hertz, int divisor)
-{
- double ret;
-
- ret=((timer->remaining().as_double() * (double)hertz) / (double)divisor) - 1;
- return (UINT32)ret;
-}
-
-static void sh4_timer_recompute(sh4_state *sh4, int which)
-{
- double ticks;
-
- 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;
-
- 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 )
{
@@ -574,66 +531,6 @@ static TIMER_CALLBACK( sh4_rtc_timer_callback )
}
}
-static TIMER_CALLBACK( sh4_timer_callback )
-{
- sh4_state *sh4 = (sh4_state *)ptr;
- int which = param;
-
- 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_timer_recompute(sh4, 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 )
{
@@ -920,6 +817,8 @@ int s;
}
}
+
+
WRITE32_HANDLER( sh4_internal_w )
{
sh4_state *sh4 = get_safe_token(&space->device());
@@ -932,7 +831,6 @@ 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);
@@ -1032,113 +930,18 @@ WRITE32_HANDLER( sh4_internal_w )
/*********************************************************************************************************************
TMU (Timer Unit)
*********************************************************************************************************************/
- case TSTR:
- 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 (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 (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:
- old2 = sh4->SH4_TCR0;
- COMBINE_DATA(&sh4->SH4_TCR0);
- if (sh4->SH4_TSTR & 1)
- {
- sh4->SH4_TCNT0 = compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[old2 & 7]);
- sh4_timer_recompute(sh4, 0);
- }
- if (!(sh4->SH4_TCR0 & 0x20) || !(sh4->SH4_TCR0 & 0x100))
- sh4_exception_unrequest(sh4, SH4_INTC_TUNI0);
- break;
- case TCR1:
- old2 = sh4->SH4_TCR1;
- COMBINE_DATA(&sh4->SH4_TCR1);
- if (sh4->SH4_TSTR & 2)
- {
- sh4->SH4_TCNT1 = compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[old2 & 7]);
- sh4_timer_recompute(sh4, 1);
- }
- if (!(sh4->SH4_TCR1 & 0x20) || !(sh4->SH4_TCR1 & 0x100))
- sh4_exception_unrequest(sh4, SH4_INTC_TUNI1);
- break;
- case TCR2:
- old2 = sh4->SH4_TCR2;
- COMBINE_DATA(&sh4->SH4_TCR2);
- if (sh4->SH4_TSTR & 4)
- {
- sh4->SH4_TCNT2 = compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[old2 & 7]);
- sh4_timer_recompute(sh4, 2);
- }
- if (!(sh4->SH4_TCR2 & 0x20) || !(sh4->SH4_TCR2 & 0x100))
- sh4_exception_unrequest(sh4, SH4_INTC_TUNI2);
- break;
-
- case TCOR0:
- COMBINE_DATA(&sh4->SH4_TCOR0);
- if (sh4->SH4_TSTR & 1)
- {
- 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:
- COMBINE_DATA(&sh4->SH4_TCNT0);
- if (sh4->SH4_TSTR & 1)
- sh4_timer_recompute(sh4, 0);
- break;
- case TCOR1:
- COMBINE_DATA(&sh4->SH4_TCOR1);
- if (sh4->SH4_TSTR & 2)
- {
- 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:
- COMBINE_DATA(&sh4->SH4_TCNT1);
- if (sh4->SH4_TSTR & 2)
- sh4_timer_recompute(sh4, 1);
- break;
- case TCOR2:
- COMBINE_DATA(&sh4->SH4_TCOR2);
- if (sh4->SH4_TSTR & 4)
- {
- 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:
- COMBINE_DATA(&sh4->SH4_TCNT2);
- if (sh4->SH4_TSTR & 4)
- sh4_timer_recompute(sh4, 2);
- break;
-
- case TOCR: // not supported
- COMBINE_DATA(&sh4->SH4_TOCR);
- break;
-
- case TCPR2: // not supported
- COMBINE_DATA(&sh4->SH4_TCPR2);
- break;
+ case SH4_TSTR_ADDR: sh4_handle_tstr_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCR0_ADDR: sh4_handle_tcr0_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCR1_ADDR: sh4_handle_tcr1_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCR2_ADDR: sh4_handle_tcr2_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCOR0_ADDR: sh4_handle_tcor0_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCNT0_ADDR: sh4_handle_tcnt0_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCOR1_ADDR: sh4_handle_tcor1_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCNT1_ADDR: sh4_handle_tcnt1_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCOR2_ADDR: sh4_handle_tcor2_addr_w(sh4,data,mem_mask); break;
+ case SH4_TCNT2_ADDR: sh4_handle_tcnt2_addr_w(sh4,data,mem_mask); break;
+ case SH4_TOCR_ADDR: sh4_handle_tocr_addr_w(sh4,data,mem_mask); break; // not supported
+ case SH4_TCPR2_ADDR: sh4_handle_tcpr2_addr_w(sh4,data,mem_mask); break; // not supported
/*********************************************************************************************************************
INTC (Interrupt Controller)
*********************************************************************************************************************/
@@ -1306,53 +1109,18 @@ READ32_HANDLER( sh4_internal_r )
/*********************************************************************************************************************
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->SH4_TSTR & 1)
- return compute_ticks_timer(sh4->timer[0], sh4->pm_clock, tcnt_div[sh4->SH4_TCR0 & 7]);
- else
- return sh4->SH4_TCNT0;
- break;
- case TCNT1:
- if (sh4->SH4_TSTR & 2)
- return compute_ticks_timer(sh4->timer[1], sh4->pm_clock, tcnt_div[sh4->SH4_TCR1 & 7]);
- else
- return sh4->SH4_TCNT1;
- break;
- case TCNT2:
- if (sh4->SH4_TSTR & 4)
- return compute_ticks_timer(sh4->timer[2], sh4->pm_clock, tcnt_div[sh4->SH4_TCR2 & 7]);
- else
- return sh4->SH4_TCNT2;
- break;
-
- 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;
-
+ case SH4_TSTR_ADDR: return sh4_handle_tstr_addr_r(sh4, mem_mask);
+ case SH4_TCR0_ADDR: return sh4_handle_tcr0_addr_r(sh4, mem_mask);
+ case SH4_TCR1_ADDR: return sh4_handle_tcr1_addr_r(sh4, mem_mask);
+ case SH4_TCR2_ADDR: return sh4_handle_tcr2_addr_r(sh4, mem_mask);
+ case SH4_TCNT0_ADDR: return sh4_handle_tcnt0_addr_r(sh4, mem_mask);
+ case SH4_TCNT1_ADDR: return sh4_handle_tcnt1_addr_r(sh4, mem_mask);
+ case SH4_TCNT2_ADDR: return sh4_handle_tcnt2_addr_r(sh4, mem_mask);
+ case SH4_TCOR0_ADDR: return sh4_handle_tcor0_addr_r(sh4, mem_mask);
+ case SH4_TCOR1_ADDR: return sh4_handle_tcor1_addr_r(sh4, mem_mask);
+ case SH4_TCOR2_ADDR: return sh4_handle_tcor2_addr_r(sh4, mem_mask);
+ case SH4_TOCR_ADDR: return sh4_handle_tocr_addr_r(sh4, mem_mask); // not supported
+ case SH4_TCPR2_ADDR: return sh4_handle_tcpr2_addr_r(sh4, mem_mask); // not supported
/*********************************************************************************************************************
I/O Ports
*********************************************************************************************************************/