summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/diexec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/diexec.cpp')
-rw-r--r--src/emu/diexec.cpp37
1 files changed, 21 insertions, 16 deletions
diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp
index 49dee5f650e..715f0c38459 100644
--- a/src/emu/diexec.cpp
+++ b/src/emu/diexec.cpp
@@ -68,9 +68,8 @@ device_execute_interface::device_execute_interface(const machine_config &mconfig
, m_divshift(0)
, m_cycles_per_second(0)
, m_attoseconds_per_cycle(0)
+ , m_spin_end_timer(nullptr)
{
- memset(&m_localtime, 0, sizeof(m_localtime));
-
// configure the fast accessor
assert(!device.interfaces().m_execute);
device.interfaces().m_execute = this;
@@ -164,7 +163,7 @@ void device_execute_interface::spin_until_time(const attotime &duration)
suspend_until_trigger(TRIGGER_SUSPENDTIME + timetrig, true);
// then set a timer for it
- m_scheduler->timer_set(duration, timer_expired_delegate(FUNC(device_execute_interface::timed_trigger_callback),this), TRIGGER_SUSPENDTIME + timetrig, this);
+ m_spin_end_timer->adjust(duration, TRIGGER_SUSPENDTIME + timetrig);
timetrig = (timetrig + 1) % 256;
}
@@ -384,9 +383,16 @@ void device_execute_interface::interface_pre_start()
m_profiler = profile_type(index + PROFILER_DEVICE_FIRST);
m_inttrigger = index + TRIGGER_INT;
- // allocate timers if we need them
+ // allocate a timed-interrupt timer if we need it
if (m_timed_interrupt_period != attotime::zero)
m_timedint_timer = m_scheduler->timer_alloc(timer_expired_delegate(FUNC(device_execute_interface::trigger_periodic_interrupt), this));
+
+ // allocate a timer for triggering the end of spin-until conditions
+ m_spin_end_timer = m_scheduler->timer_alloc(timer_expired_delegate(FUNC(device_execute_interface::timed_trigger_callback), this));
+
+ // allocate input-pulse timers if we have input lines
+ for (u32 i = 0; i < MAX_INPUT_LINES; i++)
+ m_pulse_end_timers[i] = m_scheduler->timer_alloc(timer_expired_delegate(FUNC(device_execute_interface::irq_pulse_clear), this));
}
@@ -475,7 +481,7 @@ void device_execute_interface::interface_post_reset()
// information for this device
//-------------------------------------------------
-void device_execute_interface::interface_clock_changed()
+void device_execute_interface::interface_clock_changed(bool sync_on_new_clock_domain)
{
// a clock of zero disables the device
if (device().clock() == 0)
@@ -492,6 +498,10 @@ void device_execute_interface::interface_clock_changed()
m_cycles_per_second = clocks_to_cycles(device().clock());
m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second);
+ // resynchronize the localtime to the clock domain when asked to
+ if (sync_on_new_clock_domain)
+ m_localtime = attotime::from_ticks(m_localtime.as_ticks(device().clock())+1, device().clock());
+
// update the device's divisor
s64 attos = m_attoseconds_per_cycle;
m_divshift = 0;
@@ -508,17 +518,12 @@ void device_execute_interface::interface_clock_changed()
//-------------------------------------------------
-// standard_irq_callback_member - IRQ acknowledge
+// standard_irq_callback - IRQ acknowledge
// callback; handles HOLD_LINE case and signals
// to the debugger
//-------------------------------------------------
-IRQ_CALLBACK_MEMBER( device_execute_interface::standard_irq_callback_member )
-{
- return device.execute().standard_irq_callback(irqline);
-}
-
-int device_execute_interface::standard_irq_callback(int irqline)
+int device_execute_interface::standard_irq_callback(int irqline, offs_t pc)
{
// get the default vector and acknowledge the interrupt if needed
int vector = m_input[irqline].default_irq_callback();
@@ -531,7 +536,7 @@ int device_execute_interface::standard_irq_callback(int irqline)
// notify the debugger
if (device().machine().debug_flags & DEBUG_FLAG_ENABLED)
- device().debug()->interrupt_hook(irqline);
+ device().debug()->interrupt_hook(irqline, pc);
return vector;
}
@@ -615,7 +620,7 @@ void device_execute_interface::pulse_input_line(int irqline, const attotime &dur
set_input_line(irqline, ASSERT_LINE);
attotime target_time = local_time() + duration;
- m_scheduler->timer_set(target_time - m_scheduler->time(), timer_expired_delegate(FUNC(device_execute_interface::irq_pulse_clear), this), irqline);
+ m_pulse_end_timers[irqline]->adjust(target_time - m_scheduler->time(), irqline);
}
}
@@ -682,7 +687,7 @@ if (TEMPLOG) printf("setline(%s,%d,%d,%d)\n", m_execute->device().tag(), m_linen
if (event_index >= std::size(m_queue))
{
m_qindex--;
- empty_event_queue(nullptr,0);
+ empty_event_queue(0);
event_index = m_qindex++;
m_execute->device().logerror("Exceeded pending input line event queue on device '%s'!\n", m_execute->device().tag());
}
@@ -696,7 +701,7 @@ if (TEMPLOG) printf("setline(%s,%d,%d,%d)\n", m_execute->device().tag(), m_linen
// if this is the first one, set the timer
if (event_index == 0)
- m_execute->scheduler().synchronize(timer_expired_delegate(FUNC(device_execute_interface::device_input::empty_event_queue),this), 0, this);
+ m_execute->scheduler().synchronize(timer_expired_delegate(FUNC(device_execute_interface::device_input::empty_event_queue),this));
}
}