mirror of
https://github.com/holub/mame
synced 2025-06-02 02:49:44 +03:00
151 lines
4.1 KiB
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);
|
|
}
|
|
}
|