summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2011-06-05 16:01:42 +0000
committer Aaron Giles <aaron@aarongiles.com>2011-06-05 16:01:42 +0000
commitbdca1b980a6473153867771361be5c860d1426ee (patch)
tree2c8c2d29099e5ceaf04722bd9e5078722369ebdf
parentc0fbaa4def380efec0adb5051481c3726dede21a (diff)
Fix inverted check on anonymous timers prior to saving state. Also
fix bug where we fail to ignore the permanent non-expiring anonymous timer. Added code to log timers, and we now log them at each save attempt as well as at restore time. Should fix most recent save state releated regressions. [Aaron Giles]
-rw-r--r--src/emu/attotime.c6
-rw-r--r--src/emu/machine.c2
-rw-r--r--src/emu/schedule.c62
-rw-r--r--src/emu/schedule.h7
4 files changed, 69 insertions, 8 deletions
diff --git a/src/emu/attotime.c b/src/emu/attotime.c
index 433bef061bf..12b9c537dd2 100644
--- a/src/emu/attotime.c
+++ b/src/emu/attotime.c
@@ -148,9 +148,13 @@ const char *attotime::as_string(int precision) const
static char buffers[8][30];
static int nextbuf;
char *buffer = &buffers[nextbuf++ % 8][0];
+
+ // special case: never
+ if (*this == never)
+ sprintf(buffer, "%-*s", precision, "(never)");
// case 1: we want no precision; seconds only
- if (precision == 0)
+ else if (precision == 0)
sprintf(buffer, "%d", seconds);
// case 2: we want 9 or fewer digits of precision
diff --git a/src/emu/machine.c b/src/emu/machine.c
index 8c2835e918a..fdd0b1d22ba 100644
--- a/src/emu/machine.c
+++ b/src/emu/machine.c
@@ -789,7 +789,7 @@ void running_machine::handle_saveload()
// if there are anonymous timers, we can't save just yet, and we can't load yet either
// because the timers might overwrite data we have loaded
- if (m_scheduler.can_save())
+ if (!m_scheduler.can_save())
{
// if more than a second has passed, we're probably screwed
if ((this->time() - m_saveload_schedule_time) > attotime::from_seconds(1))
diff --git a/src/emu/schedule.c b/src/emu/schedule.c
index 9d1b8c57050..f2aa22d95da 100644
--- a/src/emu/schedule.c
+++ b/src/emu/schedule.c
@@ -257,8 +257,8 @@ attotime emu_timer::remaining() const
//-------------------------------------------------
-// timer_register_save - register ourself with
-// the save state system
+// register_save - register ourself with the save
+// state system
//-------------------------------------------------
void emu_timer::register_save()
@@ -312,6 +312,21 @@ void emu_timer::schedule_next_period()
}
+//-------------------------------------------------
+// dump - dump internal state to a single output
+// line in the error log
+//-------------------------------------------------
+
+void emu_timer::dump() const
+{
+ logerror("%p: en=%d temp=%d exp=%15s start=%15s per=%15s param=%d ptr=%p", this, m_enabled, m_temporary, m_expire.as_string(), m_start.as_string(), m_period.as_string(), m_param, m_ptr);
+ if (m_device == NULL)
+ logerror(" cb=%s\n", m_callback.name());
+ else
+ logerror(" dev=%s id=%d\n", m_device->tag(), m_id);
+}
+
+
//**************************************************************************
// DEVICE SCHEDULER
@@ -341,6 +356,7 @@ device_scheduler::device_scheduler(running_machine &machine) :
// register global states
machine.save().save_item(NAME(m_basetime));
+ machine.save().register_presave(save_prepost_delegate(FUNC(device_scheduler::presave), this));
machine.save().register_postload(save_prepost_delegate(FUNC(device_scheduler::postload), this));
}
@@ -382,8 +398,12 @@ bool device_scheduler::can_save() const
{
// if any live temporary timers exit, fail
for (emu_timer *timer = m_timer_list; timer != NULL; timer = timer->next())
- if (timer->m_temporary)
+ if (timer->m_temporary && timer->expire() != attotime::never)
+ {
+ logerror("Failed save state attempt due to anonymous timers:\n");
+ dump_timers();
return false;
+ }
// otherwise, we're good
return true;
@@ -633,6 +653,18 @@ void device_scheduler::timed_trigger(void *ptr, INT32 param)
//-------------------------------------------------
+// presave - before creating a save state
+//-------------------------------------------------
+
+void device_scheduler::presave()
+{
+ // report the timer state after a log
+ logerror("Prior to saving state:\n");
+ dump_timers();
+}
+
+
+//-------------------------------------------------
// postload - after loading a save state
//-------------------------------------------------
@@ -644,8 +676,8 @@ void device_scheduler::postload()
{
emu_timer &timer = *m_timer_list;
- // temporary timers go away entirely
- if (timer.m_temporary)
+ // temporary timers go away entirely (except our special never-expiring one)
+ if (timer.m_temporary && timer.expire() != attotime::never)
m_timer_allocator.reclaim(timer.release());
// permanent ones get added to our private list
@@ -657,6 +689,10 @@ void device_scheduler::postload()
emu_timer *timer;
while ((timer = private_list.detach_head()) != NULL)
timer_list_insert(*timer);
+
+ // report the timer state after a log
+ logerror("After resetting/reordering timers:\n");
+ dump_timers();
}
@@ -936,3 +972,19 @@ void device_scheduler::add_scheduling_quantum(attotime quantum, attotime duratio
m_quantum_list.insert_after(quant, insert_after);
}
}
+
+
+//-------------------------------------------------
+// dump_timers - dump the current timer state
+//-------------------------------------------------
+
+void device_scheduler::dump_timers() const
+{
+ logerror("=============================================\n");
+ logerror("Timer Dump: Time = %15s\n", time().as_string());
+ for (emu_timer *timer = first_timer(); timer != NULL; timer = timer->next())
+ timer->dump();
+ logerror("=============================================\n");
+}
+
+
diff --git a/src/emu/schedule.h b/src/emu/schedule.h
index aebdc6c1e85..c322cd5cae7 100644
--- a/src/emu/schedule.h
+++ b/src/emu/schedule.h
@@ -117,11 +117,12 @@ public:
attotime remaining() const;
attotime start() const { return m_start; }
attotime expire() const { return m_expire; }
-
+
private:
// internal helpers
void register_save();
void schedule_next_period();
+ void dump() const;
// internal state
running_machine * m_machine; // reference to the owning machine
@@ -181,12 +182,16 @@ public:
emu_timer *timer_alloc(device_t &device, device_timer_id id = 0, void *ptr = NULL);
void timer_set(attotime duration, device_t &device, device_timer_id id = 0, int param = 0, void *ptr = NULL);
+ // debugging
+ void dump_timers() const;
+
// for emergencies only!
void eat_all_cycles();
private:
// callbacks
void timed_trigger(void *ptr, INT32 param);
+ void presave();
void postload();
// scheduling helpers