From: Atari Ace [mailto:atari_ace@verizon.net]

Subject: [patch] Collapse timer callbacks

Hi mamedev,

The following patch collapses timer callbacks in some cases to avoid
duplicating code.  In the case of crystal.c, it also refactors two DMA
handlers and shuffles the init/reset code around a bit.  I noticed
while doing this that h8_itu_read8 is missing cases 0x96,0x97 which is
almost certainly a bug, but I left it alone.

~aa
This commit is contained in:
Aaron Giles 2008-08-14 06:27:52 +00:00
parent d6b6e913fa
commit 2ec0fea9c2
9 changed files with 252 additions and 515 deletions

View File

@ -336,11 +336,7 @@ static void h8_init(int index, int clock, const void *config, int (*irqcallback)
state_save_register_item_array("H8/3002", index, h8.per_regs);
state_save_register_item("H8/3002", index, h8.h8TSTR);
state_save_register_item("H8/3002", index, h8.h8TCNT0);
state_save_register_item("H8/3002", index, h8.h8TCNT1);
state_save_register_item("H8/3002", index, h8.h8TCNT2);
state_save_register_item("H8/3002", index, h8.h8TCNT3);
state_save_register_item("H8/3002", index, h8.h8TCNT4);
state_save_register_item_array("H8/3002", index, h8.h8TCNT);
state_save_register_postload(Machine, h8_onstateload, NULL);

View File

@ -32,63 +32,22 @@
#define TCR3 (0x82)
#define TCR4 (0x92)
static TIMER_CALLBACK( h8itu_timer_0_cb )
{
timer_adjust_oneshot(h8.timer[0], attotime_never, 0);
h8.h8TCNT0 = 0;
h8.per_regs[TSR0] |= 4;
// interrupt on overflow ?
if(h8.per_regs[TIER0] & 4)
{
h8_3002_InterruptRequest(26);
}
}
static const UINT8 tsr[5] = { TSR0, TSR1, TSR2, TSR3, TSR4 };
static const UINT8 tier[5] = { TIER0, TIER1, TIER2, TIER3, TIER4 };
static const UINT8 tcr[5] = { TCR0, TCR1, TCR2, TCR3, TCR4 };
static const int tscales[4] = { 1, 2, 4, 8 };
static TIMER_CALLBACK( h8itu_timer_1_cb )
static TIMER_CALLBACK( h8itu_timer_cb )
{
timer_adjust_oneshot(h8.timer[1], attotime_never, 0);
h8.h8TCNT1 = 0;
h8.per_regs[TSR1] |= 4;
// interrupt on overflow ?
if(h8.per_regs[TIER1] & 4)
{
h8_3002_InterruptRequest(30);
}
}
static TIMER_CALLBACK( h8itu_timer_2_cb )
{
timer_adjust_oneshot(h8.timer[2], attotime_never, 0);
h8.h8TCNT2 = 0;
h8.per_regs[TSR2] |= 4;
int which = (int)ptr;
timer_adjust_oneshot(h8.timer[which], attotime_never, 0);
h8.h8TCNT[which] = 0;
h8.per_regs[tsr[which]] |= 4;
// interrupt on overflow ?
if(h8.per_regs[TIER2] & 4)
if(h8.per_regs[tier[which]] & 4)
{
h8_3002_InterruptRequest(34);
}
}
static TIMER_CALLBACK( h8itu_timer_3_cb )
{
timer_adjust_oneshot(h8.timer[3], attotime_never, 0);
h8.h8TCNT3 = 0;
h8.per_regs[TSR3] |= 4;
// interrupt on overflow ?
if(h8.per_regs[TIER3] & 4)
{
h8_3002_InterruptRequest(38);
}
}
static TIMER_CALLBACK( h8itu_timer_4_cb )
{
timer_adjust_oneshot(h8.timer[4], attotime_never, 0);
h8.h8TCNT4 = 0;
h8.per_regs[TSR4] |= 4;
// interrupt on overflow ?
if(h8.per_regs[TIER4] & 4)
{
h8_3002_InterruptRequest(42);
h8_3002_InterruptRequest(26 + 4*which);
}
}
@ -97,31 +56,9 @@ static void h8_itu_refresh_timer(int tnum)
int ourTCR = 0;
int ourTVAL = 0;
attotime period;
static const int tscales[4] = { 1, 2, 4, 8 };
switch (tnum)
{
case 0:
ourTCR = h8.per_regs[TCR0];
ourTVAL = h8.h8TCNT0;
break;
case 1:
ourTCR = h8.per_regs[TCR1];
ourTVAL = h8.h8TCNT1;
break;
case 2:
ourTCR = h8.per_regs[TCR2];
ourTVAL = h8.h8TCNT2;
break;
case 3:
ourTCR = h8.per_regs[TCR3];
ourTVAL = h8.h8TCNT3;
break;
case 4:
ourTCR = h8.per_regs[TCR4];
ourTVAL = h8.h8TCNT4;
break;
}
ourTCR = h8.per_regs[tcr[tnum]];
ourTVAL = h8.h8TCNT[tnum];
period = attotime_mul(ATTOTIME_IN_HZ(cpunum_get_clock(h8.cpu_number)), tscales[ourTCR & 3] * (65536 - ourTVAL));
@ -138,26 +75,8 @@ static void h8_itu_sync_timers(int tnum)
int ourTCR = 0;
attotime cycle_time, cur;
UINT16 ratio;
static const int tscales[4] = { 1, 2, 4, 8 };
switch (tnum)
{
case 0:
ourTCR = h8.per_regs[TCR0];
break;
case 1:
ourTCR = h8.per_regs[TCR1];
break;
case 2:
ourTCR = h8.per_regs[TCR2];
break;
case 3:
ourTCR = h8.per_regs[TCR3];
break;
case 4:
ourTCR = h8.per_regs[TCR4];
break;
}
ourTCR = h8.per_regs[tcr[tnum]];
// get the time per unit
cycle_time = attotime_mul(ATTOTIME_IN_HZ(cpunum_get_clock(h8.cpu_number)), tscales[ourTCR & 3]);
@ -165,24 +84,7 @@ static void h8_itu_sync_timers(int tnum)
ratio = attotime_to_double(cur) / attotime_to_double(cycle_time);
switch (tnum)
{
case 0:
h8.h8TCNT0 = ratio;
break;
case 1:
h8.h8TCNT1 = ratio;
break;
case 2:
h8.h8TCNT2 = ratio;
break;
case 3:
h8.h8TCNT3 = ratio;
break;
case 4:
h8.h8TCNT4 = ratio;
break;
}
h8.h8TCNT[tnum] = ratio;
}
UINT8 h8_itu_read8(UINT8 reg)
@ -196,35 +98,35 @@ UINT8 h8_itu_read8(UINT8 reg)
break;
case 0x68:
h8_itu_sync_timers(0);
val = h8.h8TCNT0>>8;
val = h8.h8TCNT[0]>>8;
break;
case 0x69:
h8_itu_sync_timers(0);
val = h8.h8TCNT0&0xff;
val = h8.h8TCNT[0]&0xff;
break;
case 0x72:
h8_itu_sync_timers(1);
val = h8.h8TCNT1>>8;
val = h8.h8TCNT[1]>>8;
break;
case 0x73:
h8_itu_sync_timers(1);
val = h8.h8TCNT1&0xff;
val = h8.h8TCNT[1]&0xff;
break;
case 0x7c:
h8_itu_sync_timers(2);
val = h8.h8TCNT2>>8;
val = h8.h8TCNT[2]>>8;
break;
case 0x7d:
h8_itu_sync_timers(2);
val = h8.h8TCNT2&0xff;
val = h8.h8TCNT[2]&0xff;
break;
case 0x86:
h8_itu_sync_timers(3);
val = h8.h8TCNT3>>8;
val = h8.h8TCNT[3]>>8;
break;
case 0x87:
h8_itu_sync_timers(3);
val = h8.h8TCNT3&0xff;
val = h8.h8TCNT[3]&0xff;
break;
default:
val = h8.per_regs[reg];
@ -264,70 +166,70 @@ void h8_itu_write8(UINT8 reg, UINT8 val)
h8.h8TSTR = val;
break;
case 0x68:
h8.h8TCNT0 = (val<<8) | (h8.h8TCNT0 & 0xff);
h8.h8TCNT[0] = (val<<8) | (h8.h8TCNT[0] & 0xff);
if (h8.h8TSTR & 1)
{
h8_itu_refresh_timer(0);
}
break;
case 0x69:
h8.h8TCNT0 = (val) | (h8.h8TCNT0 & 0xff00);
h8.h8TCNT[0] = (val) | (h8.h8TCNT[0] & 0xff00);
if (h8.h8TSTR & 1)
{
h8_itu_refresh_timer(0);
}
break;
case 0x72:
h8.h8TCNT1 = (val<<8) | (h8.h8TCNT1 & 0xff);
h8.h8TCNT[1] = (val<<8) | (h8.h8TCNT[1] & 0xff);
if (h8.h8TSTR & 2)
{
h8_itu_refresh_timer(1);
}
break;
case 0x73:
h8.h8TCNT1 = (val) | (h8.h8TCNT1 & 0xff00);
h8.h8TCNT[1] = (val) | (h8.h8TCNT[1] & 0xff00);
if (h8.h8TSTR & 2)
{
h8_itu_refresh_timer(1);
}
break;
case 0x7c:
h8.h8TCNT2 = (val<<8) | (h8.h8TCNT2 & 0xff);
h8.h8TCNT[2] = (val<<8) | (h8.h8TCNT[2] & 0xff);
if (h8.h8TSTR & 4)
{
h8_itu_refresh_timer(2);
}
break;
case 0x7d:
h8.h8TCNT2 = (val) | (h8.h8TCNT2 & 0xff00);
h8.h8TCNT[2] = (val) | (h8.h8TCNT[2] & 0xff00);
if (h8.h8TSTR & 4)
{
h8_itu_refresh_timer(2);
}
break;
case 0x86:
h8.h8TCNT3 = (val<<8) | (h8.h8TCNT3 & 0xff);
h8.h8TCNT[3] = (val<<8) | (h8.h8TCNT[3] & 0xff);
if (h8.h8TSTR & 8)
{
h8_itu_refresh_timer(3);
}
break;
case 0x87:
h8.h8TCNT3 = (val) | (h8.h8TCNT3 & 0xff00);
h8.h8TCNT[3] = (val) | (h8.h8TCNT[3] & 0xff00);
if (h8.h8TSTR & 8)
{
h8_itu_refresh_timer(3);
}
break;
case 0x96:
h8.h8TCNT4 = (val<<8) | (h8.h8TCNT4 & 0xff);
h8.h8TCNT[4] = (val<<8) | (h8.h8TCNT[4] & 0xff);
if (h8.h8TSTR & 0x10)
{
h8_itu_refresh_timer(4);
}
break;
case 0x97:
h8.h8TCNT4 = (val) | (h8.h8TCNT4 & 0xff00);
h8.h8TCNT[4] = (val) | (h8.h8TCNT[4] & 0xff00);
if (h8.h8TSTR & 0x10)
{
h8_itu_refresh_timer(4);
@ -513,7 +415,6 @@ void h8_register_write8(UINT32 address, UINT8 val)
static void h8_3007_itu_refresh_timer(int tnum)
{
attotime period;
static const int tscales[4] = { 1, 2, 4, 8 };
int ourTCR = h8.per_regs[0x68+(tnum*8)];
period = attotime_mul(ATTOTIME_IN_HZ(cpunum_get_clock(h8.cpu_number)), tscales[ourTCR & 3]);
@ -526,8 +427,9 @@ static void h8_3007_itu_refresh_timer(int tnum)
timer_adjust_oneshot(h8.timer[tnum], period, 0);
}
INLINE void h8itu_3007_timer_cb(int tnum)
static TIMER_CALLBACK( h8itu_3007_timer_cb )
{
int tnum = (int)ptr;
int base = 0x68 + (tnum*8);
UINT16 count = (h8.per_regs[base + 0x2]<<8) | h8.per_regs[base + 0x3];
count++;
@ -594,20 +496,6 @@ INLINE void h8itu_3007_timer_cb(int tnum)
h8.per_regs[base + 0x3] = count & 0xff;
}
static TIMER_CALLBACK( h8itu_3007_timer_0_cb )
{
h8itu_3007_timer_cb(0);
}
static TIMER_CALLBACK( h8itu_3007_timer_1_cb )
{
h8itu_3007_timer_cb(1);
}
static TIMER_CALLBACK( h8itu_3007_timer_2_cb )
{
h8itu_3007_timer_cb(2);
}
UINT8 h8_3007_itu_read8(UINT8 reg)
{
UINT8 val;
@ -816,20 +704,20 @@ void h8_3007_register1_write8(UINT32 address, UINT8 val)
void h8_3007_itu_init(void)
{
h8.timer[0] = timer_alloc(h8itu_3007_timer_0_cb, NULL);
h8.timer[1] = timer_alloc(h8itu_3007_timer_1_cb, NULL);
h8.timer[2] = timer_alloc(h8itu_3007_timer_2_cb, NULL);
int i;
for (i=0; i<3; i++)
h8.timer[i] = timer_alloc(h8itu_3007_timer_cb, (void*)i);
h8_itu_reset();
}
void h8_itu_init(void)
{
h8.timer[0] = timer_alloc(h8itu_timer_0_cb, NULL);
h8.timer[1] = timer_alloc(h8itu_timer_1_cb, NULL);
h8.timer[2] = timer_alloc(h8itu_timer_2_cb, NULL);
h8.timer[3] = timer_alloc(h8itu_timer_3_cb, NULL);
h8.timer[4] = timer_alloc(h8itu_timer_4_cb, NULL);
int i;
for (i=0; i<5; i++)
h8.timer[i] = timer_alloc(h8itu_timer_cb, (void*)i);
h8_itu_reset();
@ -838,10 +726,9 @@ void h8_itu_init(void)
void h8_itu_reset(void)
{
int i;
// stop all the timers
timer_adjust_oneshot(h8.timer[0], attotime_never, 0);
timer_adjust_oneshot(h8.timer[1], attotime_never, 0);
timer_adjust_oneshot(h8.timer[2], attotime_never, 0);
timer_adjust_oneshot(h8.timer[3], attotime_never, 0);
timer_adjust_oneshot(h8.timer[4], attotime_never, 0);
for (i=0; i<5; i++)
timer_adjust_oneshot(h8.timer[i], attotime_never, 0);
}

View File

@ -28,7 +28,7 @@ struct _h83002_state
UINT8 per_regs[256];
UINT16 h8TCNT0, h8TCNT1, h8TCNT2, h8TCNT3, h8TCNT4;
UINT16 h8TCNT[5];
UINT8 h8TSTR;
emu_timer *timer[5];

View File

@ -86,9 +86,7 @@ typedef struct
emu_timer *dma_timer[4];
emu_timer *refresh_timer;
emu_timer *rtc_timer;
emu_timer *timer0;
emu_timer *timer1;
emu_timer *timer2;
emu_timer *timer[3];
UINT32 refresh_timer_base;
int dma_timer_active[2];
@ -118,6 +116,10 @@ static const int exception_codes[] = { 0x000, 0x020, 0x000, 0x140, 0x140, 0x1E0,
0x7E0, 0x6C0, 0xB00, 0xB80, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4A0, 0x4C0, 0x4E0, 0x500, 0x520, 0x540, 0x700, 0x720, 0x740, 0x760,
0x560, 0x580, 0x5A0 };
static const UINT16 tcnt[] = { TCNT0, TCNT1, TCNT2 };
static const UINT16 tcor[] = { TCOR0, TCOR1, TCOR2 };
static const UINT16 tcr[] = { TCR0, TCR1, TCR2 };
enum
{
ICF = 0x00800000,
@ -3590,9 +3592,9 @@ static void sh4_reset(void)
tsaved[3] = sh4.dma_timer[3];
tsave[0] = sh4.refresh_timer;
tsave[1] = sh4.rtc_timer;
tsave[2] = sh4.timer0;
tsave[3] = sh4.timer1;
tsave[4] = sh4.timer2;
tsave[2] = sh4.timer[0];
tsave[3] = sh4.timer[1];
tsave[4] = sh4.timer[2];
f = sh4.ftcsr_read_callback;
save_irqcallback = sh4.irq_callback;
@ -3614,9 +3616,9 @@ static void sh4_reset(void)
sh4.dma_timer[3] = tsaved[3];
sh4.refresh_timer = tsave[0];
sh4.rtc_timer = tsave[1];
sh4.timer0 = tsave[2];
sh4.timer1 = tsave[3];
sh4.timer2 = tsave[4];
sh4.timer[0] = tsave[2];
sh4.timer[1] = tsave[3];
sh4.timer[2] = tsave[4];
sh4.cpu_number = cpunum;
sh4.m = m;
memset(sh4.m, 0, 16384*4);
@ -3756,28 +3758,12 @@ static UINT32 compute_ticks_timer(emu_timer *timer, int hertz, int divisor)
return (UINT32)ret;
}
static void sh4_timer0_recompute(void)
static void sh4_timer_recompute(int which)
{
double ticks;
ticks = sh4.m[TCNT0];
timer_adjust_oneshot(sh4.timer0, sh4_scale_up_mame_time(attotime_mul(ATTOTIME_IN_HZ(sh4.pm_clock), tcnt_div[sh4.m[TCR0] & 7]), ticks), sh4.cpu_number);
}
static void sh4_timer1_recompute(void)
{
double ticks;
ticks = sh4.m[TCNT1];
timer_adjust_oneshot(sh4.timer1, sh4_scale_up_mame_time(attotime_mul(ATTOTIME_IN_HZ(sh4.pm_clock), tcnt_div[sh4.m[TCR1] & 7]), ticks), sh4.cpu_number);
}
static void sh4_timer2_recompute(void)
{
double ticks;
ticks = sh4.m[TCNT2];
timer_adjust_oneshot(sh4.timer2, sh4_scale_up_mame_time(attotime_mul(ATTOTIME_IN_HZ(sh4.pm_clock), tcnt_div[sh4.m[TCR2] & 7]), ticks), sh4.cpu_number);
ticks = sh4.m[tcnt[which]];
timer_adjust_oneshot(sh4.timer[which], sh4_scale_up_mame_time(attotime_mul(ATTOTIME_IN_HZ(sh4.pm_clock), tcnt_div[sh4.m[tcr[which]] & 7]), ticks), sh4.cpu_number);
}
static TIMER_CALLBACK( sh4_refresh_timer_callback )
@ -3909,42 +3895,19 @@ static TIMER_CALLBACK( sh4_rtc_timer_callback )
cpuintrf_pop_context();
}
static TIMER_CALLBACK( sh4_timer0_callback )
static TIMER_CALLBACK( sh4_timer_callback )
{
static const UINT16 tuni[] = { SH4_INTC_TUNI0, SH4_INTC_TUNI1, SH4_INTC_TUNI2 };
int which = (int)ptr;
int cpunum = param;
int idx = tcr[which];
cpuintrf_push_context(cpunum);
sh4.m[TCNT0] = sh4.m[TCOR0];
sh4_timer0_recompute();
sh4.m[TCR0] = sh4.m[TCR0] | 0x100;
if (sh4.m[TCR0] & 0x20)
sh4_exception_request(SH4_INTC_TUNI0);
cpuintrf_pop_context();
}
static TIMER_CALLBACK( sh4_timer1_callback )
{
int cpunum = param;
cpuintrf_push_context(cpunum);
sh4.m[TCNT1] = sh4.m[TCOR1];
sh4_timer1_recompute();
sh4.m[TCR1] = sh4.m[TCR1] | 0x100;
if (sh4.m[TCR1] & 0x20)
sh4_exception_request(SH4_INTC_TUNI1);
cpuintrf_pop_context();
}
static TIMER_CALLBACK( sh4_timer2_callback )
{
int cpunum = param;
cpuintrf_push_context(cpunum);
sh4.m[TCNT2] = sh4.m[TCOR2];
sh4_timer2_recompute();
sh4.m[TCR2] = sh4.m[TCR2] | 0x100;
if (sh4.m[TCR2] & 0x20)
sh4_exception_request(SH4_INTC_TUNI2);
sh4.m[tcnt[which]] = sh4.m[tcor[which]];
sh4_timer_recompute(which);
sh4.m[idx] = sh4.m[idx] | 0x100;
if (sh4.m[idx] & 0x20)
sh4_exception_request(tuni[which]);
cpuintrf_pop_context();
}
@ -4258,32 +4221,32 @@ WRITE32_HANDLER( sh4_internal_w )
// TMU
case TSTR:
if (old & 1)
sh4.m[TCNT0] = compute_ticks_timer(sh4.timer0, sh4.pm_clock, tcnt_div[sh4.m[TCR0] & 7]);
sh4.m[TCNT0] = compute_ticks_timer(sh4.timer[0], sh4.pm_clock, tcnt_div[sh4.m[TCR0] & 7]);
if ((sh4.m[TSTR] & 1) == 0) {
timer_adjust_oneshot(sh4.timer0, attotime_never, 0);
timer_adjust_oneshot(sh4.timer[0], attotime_never, 0);
} else
sh4_timer0_recompute();
sh4_timer_recompute(0);
if (old & 2)
sh4.m[TCNT1] = compute_ticks_timer(sh4.timer1, sh4.pm_clock, tcnt_div[sh4.m[TCR1] & 7]);
sh4.m[TCNT1] = compute_ticks_timer(sh4.timer[1], sh4.pm_clock, tcnt_div[sh4.m[TCR1] & 7]);
if ((sh4.m[TSTR] & 2) == 0) {
timer_adjust_oneshot(sh4.timer1, attotime_never, 0);
timer_adjust_oneshot(sh4.timer[1], attotime_never, 0);
} else
sh4_timer1_recompute();
sh4_timer_recompute(1);
if (old & 4)
sh4.m[TCNT2] = compute_ticks_timer(sh4.timer2, sh4.pm_clock, tcnt_div[sh4.m[TCR2] & 7]);
sh4.m[TCNT2] = compute_ticks_timer(sh4.timer[2], sh4.pm_clock, tcnt_div[sh4.m[TCR2] & 7]);
if ((sh4.m[TSTR] & 4) == 0) {
timer_adjust_oneshot(sh4.timer2, attotime_never, 0);
timer_adjust_oneshot(sh4.timer[2], attotime_never, 0);
} else
sh4_timer2_recompute();
sh4_timer_recompute(2);
break;
case TCR0:
if (sh4.m[TSTR] & 1)
{
sh4.m[TCNT0] = compute_ticks_timer(sh4.timer0, sh4.pm_clock, tcnt_div[old & 7]);
sh4_timer0_recompute();
sh4.m[TCNT0] = compute_ticks_timer(sh4.timer[0], sh4.pm_clock, tcnt_div[old & 7]);
sh4_timer_recompute(0);
}
if (!(sh4.m[TCR0] & 0x20) || !(sh4.m[TCR0] & 0x100))
sh4_exception_unrequest(SH4_INTC_TUNI0);
@ -4291,8 +4254,8 @@ WRITE32_HANDLER( sh4_internal_w )
case TCR1:
if (sh4.m[TSTR] & 2)
{
sh4.m[TCNT1] = compute_ticks_timer(sh4.timer1, sh4.pm_clock, tcnt_div[old & 7]);
sh4_timer1_recompute();
sh4.m[TCNT1] = compute_ticks_timer(sh4.timer[1], sh4.pm_clock, tcnt_div[old & 7]);
sh4_timer_recompute(1);
}
if (!(sh4.m[TCR1] & 0x20) || !(sh4.m[TCR1] & 0x100))
sh4_exception_unrequest(SH4_INTC_TUNI1);
@ -4300,8 +4263,8 @@ WRITE32_HANDLER( sh4_internal_w )
case TCR2:
if (sh4.m[TSTR] & 4)
{
sh4.m[TCNT2] = compute_ticks_timer(sh4.timer2, sh4.pm_clock, tcnt_div[old & 7]);
sh4_timer2_recompute();
sh4.m[TCNT2] = compute_ticks_timer(sh4.timer[2], sh4.pm_clock, tcnt_div[old & 7]);
sh4_timer_recompute(2);
}
if (!(sh4.m[TCR2] & 0x20) || !(sh4.m[TCR2] & 0x100))
sh4_exception_unrequest(SH4_INTC_TUNI2);
@ -4310,35 +4273,35 @@ WRITE32_HANDLER( sh4_internal_w )
case TCOR0:
if (sh4.m[TSTR] & 1)
{
sh4.m[TCNT0] = compute_ticks_timer(sh4.timer0, sh4.pm_clock, tcnt_div[sh4.m[TCR0] & 7]);
sh4_timer0_recompute();
sh4.m[TCNT0] = compute_ticks_timer(sh4.timer[0], sh4.pm_clock, tcnt_div[sh4.m[TCR0] & 7]);
sh4_timer_recompute(0);
}
break;
case TCNT0:
if (sh4.m[TSTR] & 1)
sh4_timer0_recompute();
sh4_timer_recompute(0);
break;
case TCOR1:
if (sh4.m[TSTR] & 2)
{
sh4.m[TCNT1] = compute_ticks_timer(sh4.timer1, sh4.pm_clock, tcnt_div[sh4.m[TCR1] & 7]);
sh4_timer1_recompute();
sh4.m[TCNT1] = compute_ticks_timer(sh4.timer[1], sh4.pm_clock, tcnt_div[sh4.m[TCR1] & 7]);
sh4_timer_recompute(1);
}
break;
case TCNT1:
if (sh4.m[TSTR] & 2)
sh4_timer1_recompute();
sh4_timer_recompute(1);
break;
case TCOR2:
if (sh4.m[TSTR] & 4)
{
sh4.m[TCNT2] = compute_ticks_timer(sh4.timer2, sh4.pm_clock, tcnt_div[sh4.m[TCR2] & 7]);
sh4_timer2_recompute();
sh4.m[TCNT2] = compute_ticks_timer(sh4.timer[2], sh4.pm_clock, tcnt_div[sh4.m[TCR2] & 7]);
sh4_timer_recompute(2);
}
break;
case TCNT2:
if (sh4.m[TSTR] & 4)
sh4_timer2_recompute();
sh4_timer_recompute(2);
break;
// INTC
@ -4483,19 +4446,19 @@ READ32_HANDLER( sh4_internal_r )
case TCNT0:
if (sh4.m[TSTR] & 1)
return compute_ticks_timer(sh4.timer0, sh4.pm_clock, tcnt_div[sh4.m[TCR0] & 7]);
return compute_ticks_timer(sh4.timer[0], sh4.pm_clock, tcnt_div[sh4.m[TCR0] & 7]);
else
return sh4.m[TCNT0];
break;
case TCNT1:
if (sh4.m[TSTR] & 2)
return compute_ticks_timer(sh4.timer1, sh4.pm_clock, tcnt_div[sh4.m[TCR1] & 7]);
return compute_ticks_timer(sh4.timer[1], sh4.pm_clock, tcnt_div[sh4.m[TCR1] & 7]);
else
return sh4.m[TCNT1];
break;
case TCNT2:
if (sh4.m[TSTR] & 4)
return compute_ticks_timer(sh4.timer2, sh4.pm_clock, tcnt_div[sh4.m[TCR2] & 7]);
return compute_ticks_timer(sh4.timer[2], sh4.pm_clock, tcnt_div[sh4.m[TCR2] & 7]);
else
return sh4.m[TCNT2];
break;
@ -4686,23 +4649,20 @@ static offs_t sh4_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8
static void sh4_init(int index, int clock, const void *config, int (*irqcallback)(int))
{
int i;
const struct sh4_config *conf = config;
sh4.timer0 = timer_alloc(sh4_timer0_callback, NULL);
timer_adjust_oneshot(sh4.timer0, attotime_never, 0);
sh4.timer1 = timer_alloc(sh4_timer1_callback, NULL);
timer_adjust_oneshot(sh4.timer1, attotime_never, 0);
sh4.timer2 = timer_alloc(sh4_timer2_callback, NULL);
timer_adjust_oneshot(sh4.timer2, attotime_never, 0);
for (i=0; i<3; i++)
{
sh4.timer[i] = timer_alloc(sh4_timer_callback, (void*)i);
timer_adjust_oneshot(sh4.timer[i], attotime_never, 0);
}
sh4.dma_timer[0] = timer_alloc(sh4_dmac_callback, NULL);
timer_adjust_oneshot(sh4.dma_timer[0], attotime_never, 0);
sh4.dma_timer[1] = timer_alloc(sh4_dmac_callback, NULL);
timer_adjust_oneshot(sh4.dma_timer[1], attotime_never, 0);
sh4.dma_timer[2] = timer_alloc(sh4_dmac_callback, NULL);
timer_adjust_oneshot(sh4.dma_timer[2], attotime_never, 0);
sh4.dma_timer[3] = timer_alloc(sh4_dmac_callback, NULL);
timer_adjust_oneshot(sh4.dma_timer[3], attotime_never, 0);
for (i=0; i<4; i++)
{
sh4.dma_timer[i] = timer_alloc(sh4_dmac_callback, NULL);
timer_adjust_oneshot(sh4.dma_timer[i], attotime_never, 0);
}
sh4.refresh_timer = timer_alloc(sh4_refresh_timer_callback, NULL);
timer_adjust_oneshot(sh4.refresh_timer, attotime_never, 0);

View File

@ -87,9 +87,7 @@ typedef struct _ptm6840
// Local prototypes ///////////////////////////////////////////////////////
static void ptm6840_timeout(running_machine *machine, int which, int idx);
static TIMER_CALLBACK( ptm6840_t1_timeout );
static TIMER_CALLBACK( ptm6840_t2_timeout );
static TIMER_CALLBACK( ptm6840_t3_timeout );
static TIMER_CALLBACK( ptm6840_timer_cb );
// Local vars /////////////////////////////////////////////////////////////
@ -397,12 +395,11 @@ void ptm6840_config(int which, const ptm6840_interface *intf)
ptm[which].external_clock[i] = 1;
}
ptm[which].timer[0] = timer_alloc(ptm6840_t1_timeout, NULL);
ptm[which].timer[1] = timer_alloc(ptm6840_t2_timeout, NULL);
ptm[which].timer[2] = timer_alloc(ptm6840_t3_timeout, NULL);
for (i = 0; i < 3; i++)
{
ptm[which].timer[i] = timer_alloc(ptm6840_timer_cb, (void*)i);
timer_enable(ptm[which].timer[i], FALSE);
}
state_save_register_item("6840ptm", which, currptr->lsb_buffer);
state_save_register_item("6840ptm", which, currptr->msb_buffer);
@ -672,9 +669,7 @@ static void ptm6840_timeout(running_machine *machine, int which, int idx)
reload_count(machine, which, idx);
}
static TIMER_CALLBACK( ptm6840_t1_timeout ) { ptm6840_timeout(machine, param, 0); }
static TIMER_CALLBACK( ptm6840_t2_timeout ) { ptm6840_timeout(machine, param, 1); }
static TIMER_CALLBACK( ptm6840_t3_timeout ) { ptm6840_timeout(machine, param, 2); }
static TIMER_CALLBACK( ptm6840_timer_cb ) { ptm6840_timeout(machine, param, (int)ptr); }
///////////////////////////////////////////////////////////////////////////
// //

View File

@ -610,6 +610,7 @@ static void *pokey_start(const char *tag, int sndindex, int clock, const void *c
{
struct POKEYregisters *chip;
int sample_rate = clock;
int i;
chip = auto_malloc(sizeof(*chip));
memset(chip, 0, sizeof(*chip));
@ -653,23 +654,11 @@ static void *pokey_start(const char *tag, int sndindex, int clock, const void *c
chip->timer[1] = timer_alloc(pokey_timer_expire, chip);
chip->timer[2] = timer_alloc(pokey_timer_expire, chip);
chip->ptimer[0] = timer_alloc(pokey_pot_trigger, chip);
chip->ptimer[1] = timer_alloc(pokey_pot_trigger, chip);
chip->ptimer[2] = timer_alloc(pokey_pot_trigger, chip);
chip->ptimer[3] = timer_alloc(pokey_pot_trigger, chip);
chip->ptimer[4] = timer_alloc(pokey_pot_trigger, chip);
chip->ptimer[5] = timer_alloc(pokey_pot_trigger, chip);
chip->ptimer[6] = timer_alloc(pokey_pot_trigger, chip);
chip->ptimer[7] = timer_alloc(pokey_pot_trigger, chip);
chip->pot_r[0] = chip->intf.pot_r[0];
chip->pot_r[1] = chip->intf.pot_r[1];
chip->pot_r[2] = chip->intf.pot_r[2];
chip->pot_r[3] = chip->intf.pot_r[3];
chip->pot_r[4] = chip->intf.pot_r[4];
chip->pot_r[5] = chip->intf.pot_r[5];
chip->pot_r[6] = chip->intf.pot_r[6];
chip->pot_r[7] = chip->intf.pot_r[7];
for (i=0; i<8; i++)
{
chip->ptimer[i] = timer_alloc(pokey_pot_trigger, chip);
chip->pot_r[i] = chip->intf.pot_r[i];
}
chip->allpot_r = chip->intf.allpot_r;
chip->serin_r = chip->intf.serin_r;
chip->serout_w = chip->intf.serout_w;

View File

@ -132,10 +132,10 @@ static UINT32 *workram,*textureram,*frameram;
static UINT32 *sysregs,*vidregs;
static UINT32 Bank;
static UINT8 FlipCount,IntHigh;
static UINT32 Timer0ctrl,Timer1ctrl,Timer2ctrl,Timer3ctrl;
static void *Timer0,*Timer1,*Timer2,*Timer3;
static UINT32 Timerctrl[4];
static emu_timer *Timer[4];
static UINT32 FlashCmd,PIO;
static UINT32 DMA0ctrl,DMA1ctrl;
static UINT32 DMActrl[2];
static UINT8 OldPort4;
static UINT32 *ResetPatch;
@ -235,116 +235,70 @@ static WRITE32_HANDLER(Banksw_w)
memory_set_bankptr(1,memory_region(machine, "user2"));
}
static TIMER_CALLBACK( Timer0cb )
static TIMER_CALLBACK( Timercb )
{
if(!(Timer0ctrl&2))
Timer0ctrl&=~1;
IntReq(machine, 0);
int which = (int)ptr;
static const int num[] = { 0, 1, 9, 10 };
if(!(Timerctrl[which]&2))
Timerctrl[which]&=~1;
IntReq(machine, num[which]);
}
INLINE void Timer_w(int which, UINT32 data, UINT32 mem_mask)
{
if(((data^Timerctrl[which])&1) && (data&1)) //Timer activate
{
int PD=(data>>8)&0xff;
int TCV=program_read_dword_32le(0x01801404+which*8);
attotime period = attotime_mul(ATTOTIME_IN_HZ(43000000), (PD + 1) * (TCV + 1));
if(Timerctrl[which]&2)
timer_adjust_periodic(Timer[which],period,0,period);
else
timer_adjust_oneshot(Timer[which],period,0);
}
COMBINE_DATA(&Timerctrl[which]);
}
static WRITE32_HANDLER(Timer0_w)
{
if(((data^Timer0ctrl)&1) && (data&1)) //Timer activate
{
int PD=(data>>8)&0xff;
int TCV=program_read_dword_32le(0x01801404);
attotime period = attotime_mul(ATTOTIME_IN_HZ(43000000), (PD + 1) * (TCV + 1));
if(Timer0ctrl&2)
timer_adjust_periodic(Timer0,period,0,period);
else
timer_adjust_oneshot(Timer0,period,0);
}
COMBINE_DATA(&Timer0ctrl);
Timer_w(0, data, mem_mask);
}
static READ32_HANDLER(Timer0_r)
{
return Timer0ctrl;
}
static TIMER_CALLBACK( Timer1cb )
{
if(!(Timer1ctrl&2))
Timer1ctrl&=~1;
IntReq(machine, 1);
return Timerctrl[0];
}
static WRITE32_HANDLER(Timer1_w)
{
if(((data^Timer1ctrl)&1) && (data&1)) //Timer activate
{
int PD=(data>>8)&0xff;
int TCV=program_read_dword_32le(0x0180140C);
attotime period = attotime_mul(ATTOTIME_IN_HZ(43000000), (PD + 1) * (TCV + 1));
if(Timer1ctrl&2)
timer_adjust_periodic(Timer1,period,0,period);
else
timer_adjust_oneshot(Timer1,period,0);
}
COMBINE_DATA(&Timer1ctrl);
Timer_w(1, data, mem_mask);
}
static READ32_HANDLER(Timer1_r)
{
return Timer1ctrl;
}
static TIMER_CALLBACK( Timer2cb )
{
if(!(Timer2ctrl&2))
Timer2ctrl&=~1;
IntReq(machine, 9);
return Timerctrl[1];
}
static WRITE32_HANDLER(Timer2_w)
{
if(((data^Timer2ctrl)&1) && (data&1)) //Timer activate
{
int PD=(data>>8)&0xff;
int TCV=program_read_dword_32le(0x01801414);
attotime period = attotime_mul(ATTOTIME_IN_HZ(43000000), (PD + 1) * (TCV + 1));
if(Timer2ctrl&2)
timer_adjust_periodic(Timer2,period,0,period);
else
timer_adjust_oneshot(Timer2,period,0);
}
COMBINE_DATA(&Timer2ctrl);
Timer_w(2, data, mem_mask);
}
static READ32_HANDLER(Timer2_r)
{
return Timer2ctrl;
}
static TIMER_CALLBACK( Timer3cb )
{
if(!(Timer3ctrl&2))
Timer3ctrl&=~1;
IntReq(machine, 10);
return Timerctrl[2];
}
static WRITE32_HANDLER(Timer3_w)
{
if(((data^Timer3ctrl)&1) && (data&1)) //Timer activate
{
int PD=(data>>8)&0xff;
int TCV=program_read_dword_32le(0x0180141C);
attotime period = attotime_mul(ATTOTIME_IN_HZ(43000000), (PD + 1) * (TCV + 1));
if(Timer3ctrl&2)
timer_adjust_periodic(Timer3,period,0,period);
else
timer_adjust_oneshot(Timer3,period,0);
}
COMBINE_DATA(&Timer3ctrl);
Timer_w(3, data, mem_mask);
}
static READ32_HANDLER(Timer3_r)
{
return Timer3ctrl;
return Timerctrl[3];
}
static READ32_HANDLER(FlashCmd_r)
@ -397,96 +351,65 @@ static WRITE32_HANDLER(PIO_w)
COMBINE_DATA(&PIO);
}
INLINE void DMA_w(running_machine *machine, int which, UINT32 data, UINT32 mem_mask)
{
if(((data^DMActrl[which])&(1<<10)) && (data&(1<<10))) //DMAOn
{
UINT32 CTR=data;
UINT32 SRC=program_read_dword_32le(0x01800804+which*0x10);
UINT32 DST=program_read_dword_32le(0x01800808+which*0x10);
UINT32 CNT=program_read_dword_32le(0x0180080C+which*0x10);
int i;
if(CTR&0x2) //32 bits
{
for(i=0;i<CNT;++i)
{
UINT32 v=program_read_dword_32le(SRC+i*4);
program_write_dword_32le(DST+i*4,v);
}
}
else if(CTR&0x1) //16 bits
{
for(i=0;i<CNT;++i)
{
UINT16 v=program_read_word_32le(SRC+i*2);
program_write_word_32le(DST+i*2,v);
}
}
else //8 bits
{
for(i=0;i<CNT;++i)
{
UINT8 v=program_read_byte_32le(SRC+i);
program_write_byte_32le(DST+i,v);
}
}
data&=~(1<<10);
program_write_dword_32le(0x0180080C+which*0x10,0);
IntReq(machine, 7+which);
}
COMBINE_DATA(&DMActrl[which]);
}
static READ32_HANDLER(DMA0_r)
{
return DMA0ctrl;
return DMActrl[0];
}
static WRITE32_HANDLER(DMA0_w)
{
if(((data^DMA0ctrl)&(1<<10)) && (data&(1<<10))) //DMAOn
{
UINT32 CTR=data;
UINT32 SRC=program_read_dword_32le(0x01800804);
UINT32 DST=program_read_dword_32le(0x01800808);
UINT32 CNT=program_read_dword_32le(0x0180080C);
int i;
if(CTR&0x2) //32 bits
{
for(i=0;i<CNT;++i)
{
UINT32 v=program_read_dword_32le(SRC+i*4);
program_write_dword_32le(DST+i*4,v);
}
}
else if(CTR&0x1) //16 bits
{
for(i=0;i<CNT;++i)
{
UINT16 v=program_read_word_32le(SRC+i*2);
program_write_word_32le(DST+i*2,v);
}
}
else //8 bits
{
for(i=0;i<CNT;++i)
{
UINT8 v=program_read_byte_32le(SRC+i);
program_write_byte_32le(DST+i,v);
}
}
data&=~(1<<10);
program_write_dword_32le(0x0180080C,0);
IntReq(machine, 7);
}
COMBINE_DATA(&DMA0ctrl);
DMA_w(machine, 0, data, mem_mask);
}
static READ32_HANDLER(DMA1_r)
{
return DMA1ctrl;
return DMActrl[1];
}
static WRITE32_HANDLER(DMA1_w)
{
if(((data^DMA1ctrl)&(1<<10)) && (data&(1<<10))) //DMAOn
{
UINT32 CTR=data;
UINT32 SRC=program_read_dword_32le(0x01800814);
UINT32 DST=program_read_dword_32le(0x01800818);
UINT32 CNT=program_read_dword_32le(0x0180081C);
int i;
if(CTR&0x2) //32 bits
{
for(i=0;i<CNT;++i)
{
UINT32 v=program_read_dword_32le(SRC+i*4);
program_write_dword_32le(DST+i*4,v);
}
}
else if(CTR&0x1) //16 bits
{
for(i=0;i<CNT;++i)
{
UINT16 v=program_read_word_32le(SRC+i*2);
program_write_word_32le(DST+i*2,v);
}
}
else //8 bits
{
for(i=0;i<CNT;++i)
{
UINT8 v=program_read_byte_32le(SRC+i);
program_write_byte_32le(DST+i,v);
}
}
data&=~(1<<10);
program_write_dword_32le(0x0180081C,0);
IntReq(machine, 8);
}
COMBINE_DATA(&DMA1ctrl);
DMA_w(machine, 1, data, mem_mask);
}
@ -572,8 +495,21 @@ loop:
#endif
}
static MACHINE_START(crystal)
{
int i;
cpunum_set_irq_callback(0,icallback);
for (i=0; i<4; i++)
Timer[i] = timer_alloc(Timercb, (void*)i);
PatchReset();
}
static MACHINE_RESET(crystal)
{
int i;
memset(sysregs,0,0x10000);
memset(vidregs,0,0x10000);
FlipCount=0;
@ -584,25 +520,14 @@ static MACHINE_RESET(crystal)
FlashCmd=0xff;
OldPort4=0;
DMA0ctrl=0;
DMA1ctrl=0;
DMActrl[0]=0;
DMActrl[1]=0;
Timer0ctrl=0;
Timer1ctrl=0;
Timer2ctrl=0;
Timer3ctrl=0;
Timer0=timer_alloc(Timer0cb, NULL);
timer_adjust_oneshot(Timer0,attotime_never,0);
Timer1=timer_alloc(Timer1cb, NULL);
timer_adjust_oneshot(Timer1,attotime_never,0);
Timer2=timer_alloc(Timer2cb, NULL);
timer_adjust_oneshot(Timer2,attotime_never,0);
Timer3=timer_alloc(Timer3cb, NULL);
timer_adjust_oneshot(Timer3,attotime_never,0);
for (i=0; i<4; i++)
{
Timerctrl[i]=0;
timer_adjust_oneshot(Timer[i],attotime_never,0);
}
vr0_snd_set_areas(textureram,frameram);
#ifdef IDLE_LOOP_SPEEDUP
@ -809,6 +734,7 @@ static MACHINE_DRIVER_START( crystal )
MDRV_CPU_PROGRAM_MAP(crystal_mem,0)
MDRV_CPU_VBLANK_INT("main", crystal_interrupt)
MDRV_MACHINE_START(crystal)
MDRV_MACHINE_RESET(crystal)
MDRV_NVRAM_HANDLER(generic_0fill)

View File

@ -1406,32 +1406,20 @@ static WRITE8_HANDLER( megadriv_z80_YM2612_write )
static emu_timer *io_timeout[3];
static int io_stage[3];
static TIMER_CALLBACK( io_timeout0_timer_callback )
static TIMER_CALLBACK( io_timeout_timer_callback )
{
io_stage[0] = -1;
io_stage[(int)ptr] = -1;
}
static TIMER_CALLBACK( io_timeout1_timer_callback )
{
io_stage[1] = -1;
}
static TIMER_CALLBACK( io_timeout2_timer_callback )
{
io_stage[2] = -1;
}
static void init_megadri6_io(void)
{
io_timeout[0] = timer_alloc(io_timeout0_timer_callback, NULL);
io_stage[0] = -1;
int i;
io_timeout[1] = timer_alloc(io_timeout1_timer_callback, NULL);
io_stage[1] = -1;
io_timeout[2] = timer_alloc(io_timeout2_timer_callback, NULL);
io_stage[2] = -1;
for (i=0; i<3; i++)
{
io_timeout[i] = timer_alloc(io_timeout_timer_callback, (void*)i);
io_stage[i] = -1;
}
}
/* pointers to our io data read/write functions */

View File

@ -310,8 +310,11 @@ static WRITE32_HANDLER( timers_w )
model2_timerrun[offset] = 1;
}
static void model2_timer_exp(running_machine *machine, int tnum, int bit)
static TIMER_CALLBACK( model2_timer_cb )
{
int tnum = (int)ptr;
int bit = tnum + 2;
timer_adjust_oneshot(model2_timers[tnum], attotime_never, 0);
model2_intreq |= (1<<bit);
@ -324,13 +327,10 @@ static void model2_timer_exp(running_machine *machine, int tnum, int bit)
model2_timerrun[tnum] = 0;
}
static TIMER_CALLBACK( model2_timer_0_cb ) { model2_timer_exp(machine, 0, 2); }
static TIMER_CALLBACK( model2_timer_1_cb ) { model2_timer_exp(machine, 1, 3); }
static TIMER_CALLBACK( model2_timer_2_cb ) { model2_timer_exp(machine, 2, 4); }
static TIMER_CALLBACK( model2_timer_3_cb ) { model2_timer_exp(machine, 3, 5); }
static MACHINE_RESET(model2_common)
{
int i;
model2_intreq = 0;
model2_intena = 0;
model2_coproctl = 0;
@ -347,15 +347,11 @@ static MACHINE_RESET(model2_common)
model2_timerrun[0] = model2_timerrun[1] = model2_timerrun[2] = model2_timerrun[3] = 0;
model2_timers[0] = timer_alloc(model2_timer_0_cb, NULL);
model2_timers[1] = timer_alloc(model2_timer_1_cb, NULL);
model2_timers[2] = timer_alloc(model2_timer_2_cb, NULL);
model2_timers[3] = timer_alloc(model2_timer_3_cb, NULL);
timer_adjust_oneshot(model2_timers[0], attotime_never, 0);
timer_adjust_oneshot(model2_timers[1], attotime_never, 0);
timer_adjust_oneshot(model2_timers[2], attotime_never, 0);
timer_adjust_oneshot(model2_timers[3], attotime_never, 0);
for (i=0; i<4; i++)
{
model2_timers[i] = timer_alloc(model2_timer_cb, (void*)i);
timer_adjust_oneshot(model2_timers[i], attotime_never, 0);
}
}
static MACHINE_RESET(model2o)