summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/diexec.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/diexec.h')
-rw-r--r--src/emu/diexec.h117
1 files changed, 54 insertions, 63 deletions
diff --git a/src/emu/diexec.h b/src/emu/diexec.h
index 663cc6ddb1c..1e8303287e8 100644
--- a/src/emu/diexec.h
+++ b/src/emu/diexec.h
@@ -7,6 +7,7 @@
Device execution interfaces.
***************************************************************************/
+
#ifndef MAME_EMU_DIEXEC_H
#define MAME_EMU_DIEXEC_H
@@ -108,81 +109,67 @@ public:
u32 max_cycles() const { return execute_max_cycles(); }
attotime cycles_to_attotime(u64 cycles) const { return device().clocks_to_attotime(cycles_to_clocks(cycles)); }
u64 attotime_to_cycles(const attotime &duration) const { return clocks_to_cycles(device().attotime_to_clocks(duration)); }
- u32 input_lines() const { return execute_input_lines(); }
u32 default_irq_vector(int linenum) const { return execute_default_irq_vector(linenum); }
bool input_edge_triggered(int linenum) const { return execute_input_edge_triggered(linenum); }
// inline configuration helpers
void set_disable() { m_disabled = true; }
- template <typename Object> void set_vblank_int(Object &&cb, const char *tag)
- {
- m_vblank_interrupt = std::forward<Object>(cb);
- m_vblank_interrupt_screen = tag;
- }
- void set_vblank_int(device_interrupt_delegate callback, const char *tag)
+
+ template <typename... T> void set_vblank_int(const char *tag, T &&... args)
{
- m_vblank_interrupt = callback;
+ m_vblank_interrupt.set(std::forward<T>(args)...);
m_vblank_interrupt_screen = tag;
}
- template <class FunctionClass> void set_vblank_int(const char *tag, const char *devname, void (FunctionClass::*callback)(device_t &), const char *name)
- {
- set_vblank_int(device_interrupt_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)), tag);
- }
- template <class FunctionClass> void set_vblank_int(const char *tag, void (FunctionClass::*callback)(device_t &), const char *name)
+ void remove_vblank_int()
{
- set_vblank_int(device_interrupt_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)), tag);
+ m_vblank_interrupt = device_interrupt_delegate(*this);
+ m_vblank_interrupt_screen = nullptr;
}
- template <typename Object> void set_periodic_int(Object &&cb, const attotime &rate)
+ template <typename F> void set_periodic_int(F &&cb, const char *name, const attotime &rate)
{
- m_timed_interrupt = std::forward<Object>(cb);
+ m_timed_interrupt.set(std::forward<F>(cb), name);
m_timed_interrupt_period = rate;
}
- void set_periodic_int(device_interrupt_delegate callback, const attotime &rate)
+ template <typename T, typename F> void set_periodic_int(T &&target, F &&cb, const char *name, const attotime &rate)
{
- m_timed_interrupt = callback;
+ m_timed_interrupt.set(std::forward<T>(target), std::forward<F>(cb), name);
m_timed_interrupt_period = rate;
}
- template <class FunctionClass> void set_periodic_int(const char *devname, void (FunctionClass::*callback)(device_t &), const char *name, const attotime &rate)
- {
- set_periodic_int(device_interrupt_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)), rate);
- }
- template <class FunctionClass> void set_periodic_int(void (FunctionClass::*callback)(device_t &), const char *name, const attotime &rate)
+ void remove_periodic_int()
{
- set_periodic_int(device_interrupt_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)), rate);
+ m_timed_interrupt = device_interrupt_delegate(*this);
+ m_timed_interrupt_period = attotime();
}
- template <typename Object> void set_irq_acknowledge_callback(Object &&cb) { m_driver_irq = std::forward<Object>(cb); }
- void set_irq_acknowledge_callback(device_irq_acknowledge_delegate callback) { m_driver_irq = callback; }
- template <class FunctionClass> void set_irq_acknowledge_callback(const char *devname, int (FunctionClass::*callback)(device_t &, int), const char *name)
+ template <typename... T> void set_irq_acknowledge_callback(T &&... args)
{
- set_irq_acknowledge_callback(device_irq_acknowledge_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
+ m_driver_irq.set(std::forward<T>(args)...);
}
- template <class FunctionClass> void set_irq_acknowledge_callback(int (FunctionClass::*callback)(device_t &, int), const char *name)
+ void remove_irq_acknowledge_callback()
{
- set_irq_acknowledge_callback(device_irq_acknowledge_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
+ m_driver_irq = device_irq_acknowledge_delegate(*this);
}
// execution management
- device_scheduler &scheduler() const { assert(m_scheduler != nullptr); return *m_scheduler; }
- bool executing() const { return scheduler().currently_executing() == this; }
- s32 cycles_remaining() const { return executing() ? *m_icountptr : 0; } // cycles remaining in this timeslice
- void eat_cycles(int cycles) { if (executing()) *m_icountptr = (cycles > *m_icountptr) ? 0 : (*m_icountptr - cycles); }
- void adjust_icount(int delta) { if (executing()) *m_icountptr += delta; }
- void abort_timeslice();
+ device_scheduler &scheduler() const noexcept { assert(m_scheduler != nullptr); return *m_scheduler; }
+ bool executing() const noexcept { return scheduler().currently_executing() == this; }
+ s32 cycles_remaining() const noexcept { return executing() ? *m_icountptr : 0; } // cycles remaining in this timeslice
+ void eat_cycles(int cycles) noexcept { if (executing()) *m_icountptr = (cycles > *m_icountptr) ? 0 : (*m_icountptr - cycles); }
+ void adjust_icount(int delta) noexcept { if (executing()) *m_icountptr += delta; }
+ void abort_timeslice() noexcept;
// input and interrupt management
- void set_input_line(int linenum, int state) { m_input[linenum].set_state_synced(state); }
- void set_input_line_vector(int linenum, int vector) { m_input[linenum].set_vector(vector); }
- void set_input_line_and_vector(int linenum, int state, int vector) { m_input[linenum].set_state_synced(state, vector); }
- int input_state(int linenum) const { return m_input[linenum].m_curstate; }
+ void set_input_line(int linenum, int state) { assert(device().started()); m_input[linenum].set_state_synced(state); }
+ void set_input_line_vector(int linenum, int vector) { assert(device().started()); m_input[linenum].set_vector(vector); }
+ void set_input_line_and_vector(int linenum, int state, int vector) { assert(device().started()); m_input[linenum].set_state_synced(state, vector); }
+ int input_line_state(int linenum) const { assert(device().started()); return m_input[linenum].m_curstate; }
void pulse_input_line(int irqline, const attotime &duration);
- void pulse_input_line_and_vector(int irqline, int vector, const attotime &duration);
// suspend/resume
void suspend(u32 reason, bool eatcycles);
void resume(u32 reason);
- bool suspended(u32 reason = SUSPEND_ANY_REASON) const { return (m_nextsuspend & reason) != 0; }
+ bool suspended(u32 reason = SUSPEND_ANY_REASON) const noexcept { return (m_nextsuspend & reason) != 0; }
void yield() { suspend(SUSPEND_REASON_TIMESLICE, false); }
void spin() { suspend(SUSPEND_REASON_TIMESLICE, true); }
void spin_until_trigger(int trigid) { suspend_until_trigger(trigid, true); }
@@ -195,31 +182,28 @@ public:
void signal_interrupt_trigger() { trigger(m_inttrigger); }
// time and cycle accounting
- attotime local_time() const;
- u64 total_cycles() const;
+ attotime local_time() const noexcept;
+ u64 total_cycles() const noexcept;
// required operation overrides
void run() { execute_run(); }
- // deliberately ambiguous functions; if you have the execute interface
- // just use it
+ // deliberately ambiguous functions; if you have the execute interface just use it
device_execute_interface &execute() { return *this; }
protected:
// clock and cycle information getters
- virtual u64 execute_clocks_to_cycles(u64 clocks) const;
- virtual u64 execute_cycles_to_clocks(u64 cycles) const;
- virtual u32 execute_min_cycles() const;
- virtual u32 execute_max_cycles() const;
+ virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept;
+ virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept;
+ virtual u32 execute_min_cycles() const noexcept;
+ virtual u32 execute_max_cycles() const noexcept;
// input line information getters
- virtual u32 execute_input_lines() const;
- virtual u32 execute_default_irq_vector(int linenum) const;
- virtual bool execute_input_edge_triggered(int linenum) const;
+ virtual u32 execute_default_irq_vector(int linenum) const noexcept;
+ virtual bool execute_input_edge_triggered(int linenum) const noexcept;
// optional operation overrides
virtual void execute_run() = 0;
- virtual void execute_burn(s32 cycles);
virtual void execute_set_input(int linenum, int state);
// interface-level overrides
@@ -228,13 +212,11 @@ protected:
virtual void interface_post_start() override;
virtual void interface_pre_reset() override;
virtual void interface_post_reset() override;
- virtual void interface_clock_changed() override;
+ virtual void interface_clock_changed(bool sync_on_new_clock_domain) override;
// for use by devcpu for now...
- int current_input_state(unsigned i) const { return m_input[i].m_curstate; }
void set_icountptr(int &icount) { assert(!m_icountptr); m_icountptr = &icount; }
- IRQ_CALLBACK_MEMBER(standard_irq_callback_member);
- int standard_irq_callback(int irqline);
+ int standard_irq_callback(int irqline, offs_t pc);
// debugger hooks
bool debugger_enabled() const { return bool(device().machine().debug_flags & DEBUG_FLAG_ENABLED); }
@@ -255,16 +237,22 @@ protected:
device().debug()->privilege_hook();
}
+ void debugger_wait_hook()
+ {
+ if (device().machine().debug_flags & DEBUG_FLAG_CALL_HOOK)
+ device().debug()->wait_hook();
+ }
+
private:
// internal information about the state of inputs
class device_input
{
- static const int USE_STORED_VECTOR = 0xff000000;
+ static constexpr int USE_STORED_VECTOR = 0xff000000;
public:
device_input();
- void start(device_execute_interface *execute, int linenum);
+ void start(device_execute_interface &execute, int linenum);
void reset();
void set_state_synced(int state, int vector = USE_STORED_VECTOR);
@@ -316,7 +304,9 @@ private:
// cycle counting and executing
profile_type m_profiler; // profiler tag
+protected: // TODO: decide whether to bring up the wait-state methods
int * m_icountptr; // pointer to the icount
+private:
int m_cycles_running; // number of cycles we are executing
int m_cycles_stolen; // number of cycles we artificially stole
@@ -329,15 +319,16 @@ private:
s32 m_inttrigger; // interrupt trigger index
// clock and timing information
-protected: // FIXME: MIPS3 accesses m_totalcycles directly from execute_burn - devise a better solution
u64 m_totalcycles; // total device cycles executed
-private:
attotime m_localtime; // local time, relative to the timer system's global time
s32 m_divisor; // 32-bit attoseconds_per_cycle divisor
u8 m_divshift; // right shift amount to fit the divisor into 32 bits
u32 m_cycles_per_second; // cycles per second, adjusted for multipliers
attoseconds_t m_attoseconds_per_cycle; // attoseconds per adjusted clock cycle
+ emu_timer * m_spin_end_timer; // timer for triggering the end of spin_until_time
+ emu_timer * m_pulse_end_timers[MAX_INPUT_LINES]; // timer for ending input-line pulses
+
// callbacks
TIMER_CALLBACK_MEMBER(timed_trigger_callback) { trigger(param); }
@@ -354,6 +345,6 @@ public:
};
// iterator
-typedef device_interface_iterator<device_execute_interface> execute_interface_iterator;
+typedef device_interface_enumerator<device_execute_interface> execute_interface_enumerator;
#endif // MAME_EMU_DIEXEC_H