summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/watchdog.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/watchdog.c')
-rw-r--r--trunk/src/emu/watchdog.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/trunk/src/emu/watchdog.c b/trunk/src/emu/watchdog.c
new file mode 100644
index 00000000000..c39b15c4640
--- /dev/null
+++ b/trunk/src/emu/watchdog.c
@@ -0,0 +1,150 @@
+/***************************************************************************
+
+ 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);
+ }
+}