Exemplo n.º 1
0
void mame_timer_set_global_time(mame_time newbase)
{
	mame_timer *timer;

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

	LOG(("mame_timer_set_global_time: new=%.9f head->expire=%.9f\n", mame_time_to_double(newbase), mame_time_to_double(timer_head->expire)));

	/* now process any timers that are overdue */
	while (compare_mame_times(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 (compare_mame_times(timer->period, time_zero) == 0 || compare_mame_times(timer->period, time_never) == 0)
			timer->enabled = 0;

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

		/* call the callback */
		if (was_enabled && timer->callback)
		{
			LOG(("Timer %s:%d fired (expire=%.9f)\n", timer->file, timer->line, mame_time_to_double(timer->expire)));
			profiler_mark(PROFILER_TIMER_CALLBACK);
			(*timer->callback)(timer->callback_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 = add_mame_times(timer->expire, timer->period);

				timer_list_remove(timer);
				timer_list_insert(timer);
			}
		}
	}
}
Exemplo n.º 2
0
static UINT8 read_port_and_t0(int port)
{
	UINT8 val = readinputport(port);
	if (compare_mame_times(mame_timer_get_time(), timeout_time) > 0)
		val ^= 0x80;
	return val;
}
Exemplo n.º 3
0
INLINE void timer_list_insert(mame_timer *timer)
{
	mame_time expire = timer->enabled ? timer->expire : time_never;
	mame_timer *t, *lt = NULL;

	/* sanity checks for the debug build */
	#ifdef MAME_DEBUG
	{
		int tnum = 0;

		/* loop over the timer list */
		for (t = timer_head; t; t = t->next, tnum++)
		{
			if (t == timer)
				osd_die("This timer is already inserted in the list!\n");
			if (tnum == MAX_TIMERS-1)
				osd_die("Timer list is full!\n");
		}
	}
	#endif

	/* loop over the timer list */
	for (t = timer_head; t; lt = t, t = t->next)
	{
		/* if the current list entry expires after us, we should be inserted before it */
		if (compare_mame_times(t->expire, expire) > 0)
		{
			/* link the new guy in before the current list entry */
			timer->prev = t->prev;
			timer->next = t;

			if (t->prev)
				t->prev->next = timer;
			else
				timer_head = timer;
			t->prev = timer;
			return;
		}
	}

	/* need to insert after the last one */
	if (lt)
		lt->next = timer;
	else
		timer_head = timer;
	timer->prev = lt;
	timer->next = NULL;
}
Exemplo n.º 4
0
static void update_throttle(mame_time emutime)
{
	static double ticks_per_sleep_msec = 0;
	osd_ticks_t target, curr, cps, diffticks;
	int allowed_to_sleep;
	subseconds_t subsecs_per_cycle;
	int paused = mame_is_paused(Machine);

	// if we're only syncing to the refresh, bail now
	if (video_config.syncrefresh)
		return;

	// if we're paused, emutime will not advance; explicitly resync and set us backwards
	// 1/60th of a second
	if (paused)
		throttle_realtime = throttle_emutime = sub_subseconds_from_mame_time(emutime, MAX_SUBSECONDS / PAUSED_REFRESH_RATE);

	// if time moved backwards (reset), or if it's been more than 1 second in emulated time, resync
	if (compare_mame_times(emutime, throttle_emutime) < 0 || sub_mame_times(emutime, throttle_emutime).seconds > 0)
		goto resync;

	// get the current realtime; if it's been more than 1 second realtime, just resync
	cps = osd_ticks_per_second();
	diffticks = osd_ticks() - throttle_last_ticks;
	throttle_last_ticks += diffticks;
	if (diffticks >= cps)
		goto resync;

	// add the time that has passed to the real time
	subsecs_per_cycle = MAX_SUBSECONDS / cps;
	throttle_realtime = add_subseconds_to_mame_time(throttle_realtime, diffticks * subsecs_per_cycle);

	// update the emulated time
	throttle_emutime = emutime;

	// if we're behind, just sync
	if (compare_mame_times(throttle_emutime, throttle_realtime) <= 0)
		goto resync;

	// determine our target ticks value
	target = throttle_last_ticks + sub_mame_times(throttle_emutime, throttle_realtime).subseconds / subsecs_per_cycle;

	// initialize the ticks per sleep
	if (ticks_per_sleep_msec == 0)
		ticks_per_sleep_msec = (double)(cps / 1000);

	// this counts as idle time
	profiler_mark(PROFILER_IDLE);

	// determine whether or not we are allowed to sleep
	allowed_to_sleep = video_config.sleep && (!effective_autoframeskip() || effective_frameskip() == 0);

	// sync
	for (curr = osd_ticks(); curr - target < 0; curr = osd_ticks())
	{
		// if we have enough time to sleep, do it
		// ...but not if we're autoframeskipping and we're behind
		if (paused || (allowed_to_sleep && (target - curr) > (osd_ticks_t)(ticks_per_sleep_msec * 1.1)))
		{
			osd_ticks_t next;

			// keep track of how long we actually slept
			Sleep(1);
			next = osd_ticks();
			ticks_per_sleep_msec = (ticks_per_sleep_msec * 0.90) + ((double)(next - curr) * 0.10);
		}
	}

	// idle time done
	profiler_mark(PROFILER_END);

	// update realtime
	diffticks = osd_ticks() - throttle_last_ticks;
	throttle_last_ticks += diffticks;
	throttle_realtime = add_subseconds_to_mame_time(throttle_realtime, diffticks * subsecs_per_cycle);
	return;

resync:
	// reset realtime and emutime to the same value
	throttle_realtime = throttle_emutime = emutime;
}