mame/src/emu/watchdog.c

151 lines
4.1 KiB
C

/***************************************************************************
watchdog.c
Watchdog handling
Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
#include "emu.h"
#include "emuopts.h"
/***************************************************************************
GLOBAL VARIABLES
***************************************************************************/
static UINT8 watchdog_enabled;
static INT32 watchdog_counter;
static emu_timer *watchdog_timer;
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
static void watchdog_internal_reset(running_machine &machine);
static TIMER_CALLBACK( watchdog_callback );
/*-------------------------------------------------
watchdog_init - one time initialization
-------------------------------------------------*/
void watchdog_init(running_machine &machine)
{
/* allocate a timer for the watchdog */
watchdog_timer = machine.scheduler().timer_alloc(FUNC(watchdog_callback));
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(watchdog_internal_reset), &machine));
/* save some stuff in the default tag */
machine.save().save_item(NAME(watchdog_enabled));
machine.save().save_item(NAME(watchdog_counter));
}
/*-------------------------------------------------
watchdog_internal_reset - reset the watchdog
system
-------------------------------------------------*/
static void watchdog_internal_reset(running_machine &machine)
{
/* set up the watchdog timer; only start off enabled if explicitly configured */
watchdog_enabled = (machine.config().m_watchdog_vblank_count != 0 || machine.config().m_watchdog_time != attotime::zero);
watchdog_reset(machine);
watchdog_enabled = TRUE;
}
/*-------------------------------------------------
watchdog_callback - watchdog timer callback
-------------------------------------------------*/
static TIMER_CALLBACK( watchdog_callback )
{
logerror("Reset caused by the watchdog!!!\n");
int verbose = machine.options().verbose();
#ifdef MAME_DEBUG
verbose = 1;
#endif
if (verbose)
popmessage("Reset caused by the watchdog!!!\n");
machine.schedule_soft_reset();
}
/*-------------------------------------------------
on_vblank - updates VBLANK based watchdog
timers
-------------------------------------------------*/
static void on_vblank(running_machine &machine, screen_device &screen, bool vblank_state)
{
/* VBLANK starting */
if (vblank_state && watchdog_enabled)
{
/* check the watchdog */
if (screen.machine().config().m_watchdog_vblank_count != 0)
{
watchdog_counter = watchdog_counter - 1;
if (watchdog_counter == 0)
watchdog_callback(screen.machine(), NULL, 0);
}
}
}
/*-------------------------------------------------
watchdog_reset - reset the watchdog timer
-------------------------------------------------*/
void watchdog_reset(running_machine &machine)
{
/* if we're not enabled, skip it */
if (!watchdog_enabled)
watchdog_timer->adjust(attotime::never);
/* VBLANK-based watchdog? */
else if (machine.config().m_watchdog_vblank_count != 0)
{
watchdog_counter = machine.config().m_watchdog_vblank_count;
/* register a VBLANK callback for the primary screen */
if (machine.primary_screen != NULL)
machine.primary_screen->register_vblank_callback(vblank_state_delegate(FUNC(on_vblank), &machine));
}
/* timer-based watchdog? */
else if (machine.config().m_watchdog_time != attotime::zero)
watchdog_timer->adjust(machine.config().m_watchdog_time);
/* default to an obscene amount of time (3 seconds) */
else
watchdog_timer->adjust(attotime::from_seconds(3));
}
/*-------------------------------------------------
watchdog_enable - reset the watchdog timer
-------------------------------------------------*/
void watchdog_enable(running_machine &machine, int enable)
{
/* when re-enabled, we reset our state */
if (watchdog_enabled != enable)
{
watchdog_enabled = enable;
watchdog_reset(machine);
}
}