summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-11-04 05:45:54 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-11-04 05:45:54 +0000
commit7d291c792f2f6cd4b557f0fb228ec8373f50674c (patch)
tree67af41115e28fb7ce956b55632ff16f31e60b960
parent807a9b1014365113344aecdfb5b099a9d5f75fbb (diff)
Re-inlined core attotime functions. This makes a significant difference
when running with high interleaves (~2x speed running Dig Dug at perfect interleave).
-rw-r--r--src/emu/attotime.c225
-rw-r--r--src/emu/attotime.h251
-rw-r--r--src/emu/cpuexec.c40
3 files changed, 241 insertions, 275 deletions
diff --git a/src/emu/attotime.c b/src/emu/attotime.c
index b98d1f72657..75b15dba4ff 100644
--- a/src/emu/attotime.c
+++ b/src/emu/attotime.c
@@ -24,181 +24,10 @@ const attotime attotime_never = STATIC_ATTOTIME_IN_SEC(ATTOTIME_MAX_SECONDS);
/***************************************************************************
- CONVERSION HELPERS
-***************************************************************************/
-
-/*-------------------------------------------------
- attotime_to_attoseconds - convert a attotime
- to attoseconds, clamping to maximum positive/
- negative values
--------------------------------------------------*/
-
-attoseconds_t attotime_to_attoseconds(attotime _time)
-{
- /* positive values between 0 and 1 second */
- if (_time.seconds == 0)
- return _time.attoseconds;
-
- /* negative values between -1 and 0 seconds */
- else if (_time.seconds == -1)
- return _time.attoseconds - ATTOSECONDS_PER_SECOND;
-
- /* out-of-range positive values */
- else if (_time.seconds > 0)
- return ATTOSECONDS_PER_SECOND;
-
- /* out-of-range negative values */
- else
- return -ATTOSECONDS_PER_SECOND;
-}
-
-
-/*-------------------------------------------------
- attotime_to_ticks - convert an attotime to
- clock ticks at the given frequency
--------------------------------------------------*/
-
-INT64 attotime_to_ticks(attotime _time, INT32 frequency)
-{
- INT32 fracticks = attotime_mul(attotime_make(0, _time.attoseconds), frequency).seconds;
- return (INT64)_time.seconds * (INT64)frequency + fracticks;
-}
-
-
-/*-------------------------------------------------
- ticks_to_attotime - convert clock ticks at
- the given frequency to an attotime
--------------------------------------------------*/
-
-attotime ticks_to_attotime(INT64 ticks, INT32 frequency)
-{
- attotime result;
- result.seconds = ticks / frequency;
- result.attoseconds = HZ_TO_ATTOSECONDS(frequency) * (ticks - (INT64)result.seconds * (INT64)frequency);
- return result;
-}
-
-
-
-/***************************************************************************
CORE MATH FUNCTIONS
***************************************************************************/
/*-------------------------------------------------
- attotime_add - add two attotimes
--------------------------------------------------*/
-
-attotime attotime_add(attotime _time1, attotime _time2)
-{
- attotime result;
-
- /* if one of the items is attotime_never, return attotime_never */
- if (_time1.seconds >= ATTOTIME_MAX_SECONDS || _time2.seconds >= ATTOTIME_MAX_SECONDS)
- return attotime_never;
-
- /* add the seconds and attoseconds */
- result.attoseconds = _time1.attoseconds + _time2.attoseconds;
- result.seconds = _time1.seconds + _time2.seconds;
-
- /* normalize and return */
- if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
- {
- result.attoseconds -= ATTOSECONDS_PER_SECOND;
- result.seconds++;
- }
-
- /* overflow */
- if (result.seconds >= ATTOTIME_MAX_SECONDS)
- return attotime_never;
- return result;
-}
-
-
-/*-------------------------------------------------
- attotime_add_attoseconds - add attoseconds
- to a attotime
--------------------------------------------------*/
-
-attotime attotime_add_attoseconds(attotime _time1, attoseconds_t _attoseconds)
-{
- attotime result;
-
- /* if one of the items is attotime_never, return attotime_never */
- if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
- return attotime_never;
-
- /* add the seconds and attoseconds */
- result.attoseconds = _time1.attoseconds + _attoseconds;
- result.seconds = _time1.seconds;
-
- /* normalize and return */
- if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
- {
- result.attoseconds -= ATTOSECONDS_PER_SECOND;
- result.seconds++;
- }
-
- /* overflow */
- if (result.seconds >= ATTOTIME_MAX_SECONDS)
- return attotime_never;
- return result;
-}
-
-
-/*-------------------------------------------------
- attotime_sub - subtract two attotimes
--------------------------------------------------*/
-
-attotime attotime_sub(attotime _time1, attotime _time2)
-{
- attotime result;
-
- /* if time1 is attotime_never, return attotime_never */
- if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
- return attotime_never;
-
- /* add the seconds and attoseconds */
- result.attoseconds = _time1.attoseconds - _time2.attoseconds;
- result.seconds = _time1.seconds - _time2.seconds;
-
- /* normalize and return */
- if (result.attoseconds < 0)
- {
- result.attoseconds += ATTOSECONDS_PER_SECOND;
- result.seconds--;
- }
- return result;
-}
-
-
-/*-------------------------------------------------
- attotime_sub_attoseconds - subtract
- attoseconds from a attotime
--------------------------------------------------*/
-
-attotime attotime_sub_attoseconds(attotime _time1, attoseconds_t _attoseconds)
-{
- attotime result;
-
- /* if time1 is attotime_never, return attotime_never */
- if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
- return attotime_never;
-
- /* add the seconds and attoseconds */
- result.attoseconds = _time1.attoseconds - _attoseconds;
- result.seconds = _time1.seconds;
-
- /* normalize and return */
- if (result.attoseconds < 0)
- {
- result.attoseconds += ATTOSECONDS_PER_SECOND;
- result.seconds--;
- }
- return result;
-}
-
-
-/*-------------------------------------------------
attotime_mul - multiply an attotime by
a constant
-------------------------------------------------*/
@@ -282,65 +111,13 @@ attotime attotime_div(attotime _time1, UINT32 factor)
}
-/*-------------------------------------------------
- attotime_compare - compare two attotimes
--------------------------------------------------*/
-
-int attotime_compare(attotime _time1, attotime _time2)
-{
- if (_time1.seconds > _time2.seconds)
- return 1;
- if (_time1.seconds < _time2.seconds)
- return -1;
- if (_time1.attoseconds > _time2.attoseconds)
- return 1;
- if (_time1.attoseconds < _time2.attoseconds)
- return -1;
- return 0;
-}
-
-
-/*-------------------------------------------------
- attotime_min - return the minimum of two
- attotimes
--------------------------------------------------*/
-
-attotime attotime_min(attotime _time1, attotime _time2)
-{
- if (_time1.seconds > _time2.seconds)
- return _time2;
- if (_time1.seconds < _time2.seconds)
- return _time1;
- if (_time1.attoseconds > _time2.attoseconds)
- return _time2;
- return _time1;
-}
-
-
-/*-------------------------------------------------
- attotime_max - return the maximum of two
- attotimes
--------------------------------------------------*/
-
-attotime attotime_max(attotime _time1, attotime _time2)
-{
- if (_time1.seconds > _time2.seconds)
- return _time1;
- if (_time1.seconds < _time2.seconds)
- return _time2;
- if (_time1.attoseconds > _time2.attoseconds)
- return _time1;
- return _time2;
-}
-
-
/***************************************************************************
MISC UTILITIES
***************************************************************************/
/*-------------------------------------------------
- attotime_compare - return a temporary
+ attotime_string - return a temporary
printable string describing an attotime
-------------------------------------------------*/
diff --git a/src/emu/attotime.h b/src/emu/attotime.h
index 2ca17ff6cc6..89ab1d8ab45 100644
--- a/src/emu/attotime.h
+++ b/src/emu/attotime.h
@@ -132,47 +132,14 @@ extern const attotime attotime_never;
FUNCTION PROTOTYPES
***************************************************************************/
-/* ----- conversion helpers ----- */
-
-/* convert an attotime to attoseconds, clamping to maximum positive/negative values */
-attoseconds_t attotime_to_attoseconds(attotime _time);
-
-/* convert an attotime to clock ticks at the given frequency */
-INT64 attotime_to_ticks(attotime _time, INT32 frequency);
-
-/* convert clock ticks at the given frequency to an attotime */
-attotime ticks_to_attotime(INT64 ticks, INT32 frequency);
-
-
/* ----- core math functions ----- */
-/* add two attotimes */
-attotime attotime_add(attotime _time1, attotime _time2);
-
-/* add attoseconds to an attotime */
-attotime attotime_add_attoseconds(attotime _time1, attoseconds_t _attoseconds);
-
-/* subtract two attotimes */
-attotime attotime_sub(attotime _time1, attotime _time2);
-
-/* subtract attoseconds from an attotime */
-attotime attotime_sub_attoseconds(attotime _time1, attoseconds_t _attoseconds);
-
/* multiply an attotime by a constant */
attotime attotime_mul(attotime _time1, UINT32 factor);
/* divide an attotime by a constant */
attotime attotime_div(attotime _time1, UINT32 factor);
-/* compare two attotimes */
-int attotime_compare(attotime _time1, attotime _time2);
-
-/* return the minimum of two attotimes */
-attotime attotime_min(attotime _time1, attotime _time2);
-
-/* return the maximum of two attotimes */
-attotime attotime_max(attotime _time1, attotime _time2);
-
/* ----- misc utilities ----- */
@@ -229,4 +196,222 @@ INLINE attotime double_to_attotime(double _time)
}
+/*-------------------------------------------------
+ attotime_to_attoseconds - convert a attotime
+ to attoseconds, clamping to maximum positive/
+ negative values
+-------------------------------------------------*/
+
+INLINE attoseconds_t attotime_to_attoseconds(attotime _time)
+{
+ /* positive values between 0 and 1 second */
+ if (_time.seconds == 0)
+ return _time.attoseconds;
+
+ /* negative values between -1 and 0 seconds */
+ else if (_time.seconds == -1)
+ return _time.attoseconds - ATTOSECONDS_PER_SECOND;
+
+ /* out-of-range positive values */
+ else if (_time.seconds > 0)
+ return ATTOSECONDS_PER_SECOND;
+
+ /* out-of-range negative values */
+ else
+ return -ATTOSECONDS_PER_SECOND;
+}
+
+
+/*-------------------------------------------------
+ attotime_to_ticks - convert an attotime to
+ clock ticks at the given frequency
+-------------------------------------------------*/
+
+INLINE INT64 attotime_to_ticks(attotime _time, INT32 frequency)
+{
+ INT32 fracticks = attotime_mul(attotime_make(0, _time.attoseconds), frequency).seconds;
+ return (INT64)_time.seconds * (INT64)frequency + fracticks;
+}
+
+
+/*-------------------------------------------------
+ ticks_to_attotime - convert clock ticks at
+ the given frequency to an attotime
+-------------------------------------------------*/
+
+INLINE attotime ticks_to_attotime(INT64 ticks, INT32 frequency)
+{
+ attotime result;
+ result.seconds = ticks / frequency;
+ result.attoseconds = HZ_TO_ATTOSECONDS(frequency) * (ticks - (INT64)result.seconds * (INT64)frequency);
+ return result;
+}
+
+
+/*-------------------------------------------------
+ attotime_add - add two attotimes
+-------------------------------------------------*/
+
+INLINE attotime attotime_add(attotime _time1, attotime _time2)
+{
+ attotime result;
+
+ /* if one of the items is attotime_never, return attotime_never */
+ if (_time1.seconds >= ATTOTIME_MAX_SECONDS || _time2.seconds >= ATTOTIME_MAX_SECONDS)
+ return attotime_never;
+
+ /* add the seconds and attoseconds */
+ result.attoseconds = _time1.attoseconds + _time2.attoseconds;
+ result.seconds = _time1.seconds + _time2.seconds;
+
+ /* normalize and return */
+ if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
+ {
+ result.attoseconds -= ATTOSECONDS_PER_SECOND;
+ result.seconds++;
+ }
+
+ /* overflow */
+ if (result.seconds >= ATTOTIME_MAX_SECONDS)
+ return attotime_never;
+ return result;
+}
+
+
+/*-------------------------------------------------
+ attotime_add_attoseconds - add attoseconds
+ to a attotime
+-------------------------------------------------*/
+
+INLINE attotime attotime_add_attoseconds(attotime _time1, attoseconds_t _attoseconds)
+{
+ attotime result;
+
+ /* if one of the items is attotime_never, return attotime_never */
+ if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
+ return attotime_never;
+
+ /* add the seconds and attoseconds */
+ result.attoseconds = _time1.attoseconds + _attoseconds;
+ result.seconds = _time1.seconds;
+
+ /* normalize and return */
+ if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
+ {
+ result.attoseconds -= ATTOSECONDS_PER_SECOND;
+ result.seconds++;
+ }
+
+ /* overflow */
+ if (result.seconds >= ATTOTIME_MAX_SECONDS)
+ return attotime_never;
+ return result;
+}
+
+
+/*-------------------------------------------------
+ attotime_sub - subtract two attotimes
+-------------------------------------------------*/
+
+INLINE attotime attotime_sub(attotime _time1, attotime _time2)
+{
+ attotime result;
+
+ /* if time1 is attotime_never, return attotime_never */
+ if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
+ return attotime_never;
+
+ /* add the seconds and attoseconds */
+ result.attoseconds = _time1.attoseconds - _time2.attoseconds;
+ result.seconds = _time1.seconds - _time2.seconds;
+
+ /* normalize and return */
+ if (result.attoseconds < 0)
+ {
+ result.attoseconds += ATTOSECONDS_PER_SECOND;
+ result.seconds--;
+ }
+ return result;
+}
+
+
+/*-------------------------------------------------
+ attotime_sub_attoseconds - subtract
+ attoseconds from a attotime
+-------------------------------------------------*/
+
+INLINE attotime attotime_sub_attoseconds(attotime _time1, attoseconds_t _attoseconds)
+{
+ attotime result;
+
+ /* if time1 is attotime_never, return attotime_never */
+ if (_time1.seconds >= ATTOTIME_MAX_SECONDS)
+ return attotime_never;
+
+ /* add the seconds and attoseconds */
+ result.attoseconds = _time1.attoseconds - _attoseconds;
+ result.seconds = _time1.seconds;
+
+ /* normalize and return */
+ if (result.attoseconds < 0)
+ {
+ result.attoseconds += ATTOSECONDS_PER_SECOND;
+ result.seconds--;
+ }
+ return result;
+}
+
+
+/*-------------------------------------------------
+ attotime_compare - compare two attotimes
+-------------------------------------------------*/
+
+INLINE int attotime_compare(attotime _time1, attotime _time2)
+{
+ if (_time1.seconds > _time2.seconds)
+ return 1;
+ if (_time1.seconds < _time2.seconds)
+ return -1;
+ if (_time1.attoseconds > _time2.attoseconds)
+ return 1;
+ if (_time1.attoseconds < _time2.attoseconds)
+ return -1;
+ return 0;
+}
+
+
+/*-------------------------------------------------
+ attotime_min - return the minimum of two
+ attotimes
+-------------------------------------------------*/
+
+INLINE attotime attotime_min(attotime _time1, attotime _time2)
+{
+ if (_time1.seconds > _time2.seconds)
+ return _time2;
+ if (_time1.seconds < _time2.seconds)
+ return _time1;
+ if (_time1.attoseconds > _time2.attoseconds)
+ return _time2;
+ return _time1;
+}
+
+
+/*-------------------------------------------------
+ attotime_max - return the maximum of two
+ attotimes
+-------------------------------------------------*/
+
+INLINE attotime attotime_max(attotime _time1, attotime _time2)
+{
+ if (_time1.seconds > _time2.seconds)
+ return _time1;
+ if (_time1.seconds < _time2.seconds)
+ return _time2;
+ if (_time1.attoseconds > _time2.attoseconds)
+ return _time1;
+ return _time2;
+}
+
+
#endif /* __ATTOTIME_H__ */
diff --git a/src/emu/cpuexec.c b/src/emu/cpuexec.c
index 22a36ae39de..e502d940df9 100644
--- a/src/emu/cpuexec.c
+++ b/src/emu/cpuexec.c
@@ -11,6 +11,7 @@
#include "driver.h"
#include "profiler.h"
+#include "eminline.h"
#include "debugger.h"
@@ -115,6 +116,7 @@ static attotime perfect_interleave;
static void cpuexec_exit(running_machine *machine);
static void cpuexec_reset(running_machine *machine);
static void cpu_inittimers(running_machine *machine);
+static void update_clock_information(running_machine *machine, int cpunum);
static TIMER_CALLBACK( end_interleave_boost );
static TIMER_CALLBACK( trigger_partial_frame_interrupt );
static void compute_perfect_interleave(running_machine *machine);
@@ -135,6 +137,7 @@ void cpuexec_init(running_machine *machine)
int cpunum;
/* loop over all our CPUs */
+ memset(cpu, 0, sizeof(cpu));
for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
{
cpu_type cputype = machine->config->cpu[cpunum].type;
@@ -145,15 +148,13 @@ void cpuexec_init(running_machine *machine)
break;
/* initialize the cpuinfo struct */
- memset(&cpu[cpunum], 0, sizeof(cpu[cpunum]));
cpu[cpunum].suspend = SUSPEND_REASON_RESET;
cpu[cpunum].clock = (UINT64)machine->config->cpu[cpunum].clock * cputype_clock_multiplier(cputype) / cputype_clock_divider(cputype);
cpu[cpunum].clockscale = 1.0;
cpu[cpunum].localtime = attotime_zero;
/* compute the cycle times */
- cycles_per_second[cpunum] = cpu[cpunum].clockscale * cpu[cpunum].clock;
- attoseconds_per_cycle[cpunum] = ATTOSECONDS_PER_SECOND / (cpu[cpunum].clockscale * cpu[cpunum].clock);
+ update_clock_information(machine, cpunum);
/* register some of our variables for later */
state_save_register_item("cpu", cpunum, cpu[cpunum].suspend);
@@ -189,8 +190,9 @@ void cpuexec_init(running_machine *machine)
add_reset_callback(machine, cpuexec_reset);
add_exit_callback(machine, cpuexec_exit);
- /* compute the perfect interleave factor */
- compute_perfect_interleave(machine);
+ /* allocate timers to handle interleave boosts */
+ interleave_boost_timer = timer_alloc(NULL, NULL);
+ interleave_boost_timer_end = timer_alloc(end_interleave_boost, NULL);
}
@@ -267,6 +269,10 @@ void cpuexec_timeslice(running_machine *machine)
/* only process if we're not suspended */
if (!cpu[cpunum].suspend)
{
+ attotime delta = attotime_sub(target, cpu[cpunum].localtime);
+ if (delta.seconds >= 0)
+ {
+
/* compute how long to run */
cycles_running = ATTOTIME_TO_CYCLES(cpunum, attotime_sub(target, cpu[cpunum].localtime));
LOG((" cpu %d: %d cycles\n", cpunum, cycles_running));
@@ -306,6 +312,7 @@ void cpuexec_timeslice(running_machine *machine)
LOG((" (new target)\n"));
}
}
+ }
}
}
@@ -447,7 +454,7 @@ static void update_clock_information(running_machine *machine, int cpunum)
/* recompute cps and spc */
cycles_per_second[cpunum] = (double)cpu[cpunum].clock * cpu[cpunum].clockscale;
attoseconds_per_cycle[cpunum] = ATTOSECONDS_PER_SECOND / ((double)cpu[cpunum].clock * cpu[cpunum].clockscale);
-
+
/* re-compute the perfect interleave factor */
compute_perfect_interleave(machine);
}
@@ -902,16 +909,17 @@ static void compute_perfect_interleave(running_machine *machine)
perfect_interleave = attotime_zero;
perfect_interleave.attoseconds = ATTOSECONDS_PER_SECOND - 1;
for (cpunum = 1; machine->config->cpu[cpunum].type != CPU_DUMMY; cpunum++)
- {
- /* find the 2nd smallest cycle interval */
- if (attoseconds_per_cycle[cpunum] < smallest)
+ if (attoseconds_per_cycle[cpunum] != 0)
{
- perfect_interleave.attoseconds = smallest;
- smallest = attoseconds_per_cycle[cpunum];
+ /* find the 2nd smallest cycle interval */
+ if (attoseconds_per_cycle[cpunum] < smallest)
+ {
+ perfect_interleave.attoseconds = smallest;
+ smallest = attoseconds_per_cycle[cpunum];
+ }
+ else if (attoseconds_per_cycle[cpunum] < perfect_interleave.attoseconds)
+ perfect_interleave.attoseconds = attoseconds_per_cycle[cpunum];
}
- else if (attoseconds_per_cycle[cpunum] < perfect_interleave.attoseconds)
- perfect_interleave.attoseconds = attoseconds_per_cycle[cpunum];
- }
/* adjust the final value */
if (perfect_interleave.attoseconds == ATTOSECONDS_PER_SECOND - 1)
@@ -940,10 +948,6 @@ static void cpu_inittimers(running_machine *machine)
timeslice_timer = timer_alloc(cpu_timeslicecallback, NULL);
timer_adjust_periodic(timeslice_timer, timeslice_period, 0, timeslice_period);
- /* allocate timers to handle interleave boosts */
- interleave_boost_timer = timer_alloc(NULL, NULL);
- interleave_boost_timer_end = timer_alloc(end_interleave_boost, NULL);
-
/* register the interrupt handler callbacks */
for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
{