Exemplo n.º 1
0
void timer_adjust_periodic(emu_timer *which, attotime start_delay, INT32 param, attotime period)
{
	attotime time = get_current_time();

	/* if this is the callback timer, mark it modified */
	if (which == callback_timer)
		callback_timer_modified = TRUE;

	/* compute the time of the next firing and insert into the list */
	which->param = param;
	which->enabled = TRUE;

	/* clamp negative times to 0 */
	if (start_delay.seconds < 0)
		start_delay = attotime_zero;

	/* set the start and expire times */
	which->start = time;
	which->expire = attotime_add(time, start_delay);
	which->period = period;

	/* remove and re-insert the timer in its new order */
	timer_list_remove(which);
	timer_list_insert(which);

	/* if this was inserted as the head, abort the current timeslice and resync */
	LOG(("timer_adjust_oneshot %s.%s:%d to expire @ %s\n", which->file, which->func, which->line, attotime_string(which->expire, 9)));
	if (which == timer_head && cpu_getexecutingcpu() >= 0)
		activecpu_abort_timeslice();
}
Exemplo n.º 2
0
void timer_set_global_time(attotime newbase)
{
	emu_timer *timer;

	/* set the new global offset */
	global_basetime = newbase;

	LOG(("timer_set_global_time: new=%s head->expire=%s\n", attotime_string(newbase, 9), attotime_string(timer_head->expire, 9)));

	/* now process any timers that are overdue */
	while (attotime_compare(timer_head->expire, global_basetime) <= 0)
	{
		int was_enabled = timer_head->enabled;

		/* if this is a one-shot timer, disable it now */
		timer = timer_head;
		if (attotime_compare(timer->period, attotime_zero) == 0 || attotime_compare(timer->period, attotime_never) == 0)
			timer->enabled = FALSE;

		/* set the global state of which callback we're in */
		callback_timer_modified = FALSE;
		callback_timer = timer;
		callback_timer_expire_time = timer->expire;

		/* call the callback */
		if (was_enabled && timer->callback != NULL)
		{
			LOG(("Timer %s:%d[%s] fired (expire=%s)\n", timer->file, timer->line, timer->func, attotime_string(timer->expire, 9)));
			profiler_mark(PROFILER_TIMER_CALLBACK);
			(*timer->callback)(Machine, timer->ptr, timer->param);
			profiler_mark(PROFILER_END);
		}

		/* clear the callback timer global */
		callback_timer = NULL;

		/* reset or remove the timer, but only if it wasn't modified during the callback */
		if (!callback_timer_modified)
		{
			/* if the timer is temporary, remove it now */
			if (timer->temporary)
				timer_remove(timer);

			/* otherwise, reschedule it */
			else
			{
				timer->start = timer->expire;
				timer->expire = attotime_add(timer->expire, timer->period);

				timer_list_remove(timer);
				timer_list_insert(timer);
			}
		}
	}
}
Exemplo n.º 3
0
void timer_add_scheduling_quantum(running_machine *machine, attoseconds_t quantum, attotime duration)
{
	timer_private *global = machine->timer_data;
	attotime curtime = timer_get_time(machine);
	attotime expire = attotime_add(curtime, duration);
	int curr, blank = -1;

	/* a 0 request (minimum) needs to be non-zero to occupy a slot */
	if (quantum == 0)
		quantum = 1;

	/* find an equal-duration slot or an empty slot */
	for (curr = 1; curr < ARRAY_LENGTH(global->quantum_list); curr++)
	{
		quantum_slot *slot = &global->quantum_list[curr];

		/* look for a matching quantum and extend it */
		if (slot->requested == quantum)
		{
			slot->expire = attotime_max(slot->expire, expire);
			return;
		}

		/* remember any empty slots in case of no match */
		if (slot->requested == 0)
		{
			if (blank == -1)
				blank = curr;
		}

		/* otherwise, expire any expired slots */
		else if (attotime_compare(curtime, slot->expire) >= 0)
			slot->requested = 0;
	}

	/* fatal error if no slots left */
	assert_always(blank != -1, "Out of scheduling quantum slots!");

	/* fill in the item */
	global->quantum_list[blank].requested = quantum;
	global->quantum_list[blank].actual = MAX(global->quantum_list[blank].requested, global->quantum_minimum);
	global->quantum_list[blank].expire = expire;

	/* update the minimum */
	if (quantum < global->quantum_current->requested)
	{
		global->quantum_current = &global->quantum_list[blank];
		global->exec.curquantum = global->quantum_current->actual;
	}
}
Exemplo n.º 4
0
/* Called via stream_update(stream).
 * This can be triggered by the core (based on emulated time) or via speaker_level_w().
 */
static STREAM_UPDATE( speaker_sound_update )
{
	speaker_state *sp = (speaker_state *) param;
	stream_sample_t *buffer = outputs[0];
	int volume = sp->levels[sp->level];
	double filtered_volume;
	attotime sampled_time = attotime_zero;

	if (samples > 0)
	{
		/* Prepare to update time state */
		sampled_time = attotime_make(0, sp->channel_sample_period);
		if (samples > 1)
			sampled_time = attotime_mul(sampled_time, samples);

		/* Note: since the stream is in the process of being updated,
         * stream_get_time() will return the time before the update! (MAME 0.130)
         * Avoid using it here in order to avoid a subtle dependence on the stream implementation.
         */
	}

	if (samples-- > 0)
	{
		/* Note that first interm. sample may be composed... */
		filtered_volume = update_interm_samples_get_filtered_volume(sp, volume);

		/* Composite volume is now quantized to the stream resolution */
		*buffer++ = (stream_sample_t)filtered_volume;

		/* Any additional samples will be homogeneous, however may need filtering across samples: */
		while (samples-- > 0)
		{
			filtered_volume = update_interm_samples_get_filtered_volume(sp, volume);
			*buffer++ = (stream_sample_t)filtered_volume;
		}

		/* Update the time state */
		sp->channel_last_sample_time = attotime_add(sp->channel_last_sample_time, sampled_time);
		sp->channel_next_sample_time = attotime_add_attoseconds(sp->channel_last_sample_time, sp->channel_sample_period);
		sp->next_interm_sample_time = attotime_add_attoseconds(sp->channel_last_sample_time, sp->interm_sample_period);
		sp->last_update_time = sp->channel_last_sample_time;
	}

} /* speaker_sound_update */
Exemplo n.º 5
0
INLINE void count_states(int states)
{
	attotime state_time = attotime_make(0, attotime_to_attoseconds(MICRO_STATE_CLOCK_PERIOD) * states);

	if (!micro.timer)
	{
		timer_adjust_oneshot(micro.timer, attotime_never, 0);
		micro.timer_active = 1;
		micro.endtime = state_time;
	}
	else if (attotime_compare(timer_timeelapsed(micro.timer), micro.endtime) > 0)
	{
		timer_adjust_oneshot(micro.timer, attotime_never, 0);
		micro.timer_active = 1;
		micro.endtime = state_time;
	}
	else
		micro.endtime = attotime_add(micro.endtime, state_time);
}
Exemplo n.º 6
0
void timer_execute_timers(running_machine *machine)
{
	timer_private *global = machine->timer_data;
	emu_timer *timer;

	/* if the current quantum has expired, find a new one */
	if (attotime_compare(global->exec.basetime, global->quantum_current->expire) >= 0)
	{
		int curr;

		global->quantum_current->requested = 0;
		global->quantum_current = &global->quantum_list[0];
		for (curr = 1; curr < ARRAY_LENGTH(global->quantum_list); curr++)
			if (global->quantum_list[curr].requested != 0 && global->quantum_list[curr].requested < global->quantum_current->requested)
				global->quantum_current = &global->quantum_list[curr];
		global->exec.curquantum = global->quantum_current->actual;
	}

	LOG(("timer_set_global_time: new=%s head->expire=%s\n", attotime_string(global->exec.basetime, 9), attotime_string(global->activelist->expire, 9)));

	/* now process any timers that are overdue */
	while (attotime_compare(global->activelist->expire, global->exec.basetime) <= 0)
	{
		int was_enabled = global->activelist->enabled;

		/* if this is a one-shot timer, disable it now */
		timer = global->activelist;
		if (attotime_compare(timer->period, attotime_zero) == 0 || attotime_compare(timer->period, attotime_never) == 0)
			timer->enabled = FALSE;

		/* set the global state of which callback we're in */
		global->callback_timer_modified = FALSE;
		global->callback_timer = timer;
		global->callback_timer_expire_time = timer->expire;

		/* call the callback */
		if (was_enabled && timer->callback != NULL)
		{
			LOG(("Timer %s:%d[%s] fired (expire=%s)\n", timer->file, timer->line, timer->func, attotime_string(timer->expire, 9)));
			profiler_mark_start(PROFILER_TIMER_CALLBACK);
			(*timer->callback)(machine, timer->ptr, timer->param);
			profiler_mark_end();
		}

		/* clear the callback timer global */
		global->callback_timer = NULL;

		/* reset or remove the timer, but only if it wasn't modified during the callback */
		if (!global->callback_timer_modified)
		{
			/* if the timer is temporary, remove it now */
			if (timer->temporary)
				timer_remove(timer);

			/* otherwise, reschedule it */
			else
			{
				timer->start = timer->expire;
				timer->expire = attotime_add(timer->expire, timer->period);

				timer_list_remove(timer);
				timer_list_insert(timer);
			}
		}
	}
}