diff options
author | Aaron Giles <aaron@aarongiles.com> | 2021-06-06 15:35:40 -0700 |
---|---|---|
committer | Aaron Giles <aaron@aarongiles.com> | 2021-06-06 15:35:40 -0700 |
commit | 5127bd81c44a5300ea1b6864ee00b7183699974c (patch) | |
tree | c429eb7774d6ef097b4a1ae30b19ef7446cc3070 | |
parent | e38c112c9b943bc1d50ab4ae62cccefc982ed6fa (diff) |
Dynamically allocate input lines. Add range checks for input lines. Fix a few incorrect cases.
-rw-r--r-- | src/devices/cpu/i386/i386.cpp | 11 | ||||
-rw-r--r-- | src/devices/cpu/m6502/m6502.cpp | 2 | ||||
-rw-r--r-- | src/devices/cpu/m6502/m6502.h | 2 | ||||
-rw-r--r-- | src/devices/cpu/saturn/saturn.h | 2 | ||||
-rw-r--r-- | src/emu/diexec.cpp | 32 | ||||
-rw-r--r-- | src/emu/diexec.h | 55 |
6 files changed, 56 insertions, 48 deletions
diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp index e8fdf6a12ea..c9e13e1b252 100644 --- a/src/devices/cpu/i386/i386.cpp +++ b/src/devices/cpu/i386/i386.cpp @@ -2681,15 +2681,12 @@ void i386_device::execute_set_input(int irqline, int state) } else { - if (irqline >= 0 && irqline <= MAX_INPUT_LINES) + if ( state != CLEAR_LINE && m_halted ) { - if ( state != CLEAR_LINE && m_halted ) - { - m_halted = 0; - } - - m_irq_state = state; + m_halted = 0; } + + m_irq_state = state; } } diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp index dce6244c457..4bbcd3358f7 100644 --- a/src/devices/cpu/m6502/m6502.cpp +++ b/src/devices/cpu/m6502/m6502.cpp @@ -144,7 +144,7 @@ uint32_t m6502_device::execute_max_cycles() const noexcept uint32_t m6502_device::execute_input_lines() const noexcept { - return NMI_LINE+1; + return 16; } bool m6502_device::execute_input_edge_triggered(int inputnum) const noexcept diff --git a/src/devices/cpu/m6502/m6502.h b/src/devices/cpu/m6502/m6502.h index 077de2920ac..53f9fb548ec 100644 --- a/src/devices/cpu/m6502/m6502.h +++ b/src/devices/cpu/m6502/m6502.h @@ -17,7 +17,7 @@ public: IRQ_LINE = INPUT_LINE_IRQ0, APU_IRQ_LINE = INPUT_LINE_IRQ1, NMI_LINE = INPUT_LINE_NMI, - V_LINE = INPUT_LINE_IRQ0 + 16 + V_LINE = INPUT_LINE_IRQ0 + 15 }; m6502_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); diff --git a/src/devices/cpu/saturn/saturn.h b/src/devices/cpu/saturn/saturn.h index 5111de6d7ed..25d683f1d21 100644 --- a/src/devices/cpu/saturn/saturn.h +++ b/src/devices/cpu/saturn/saturn.h @@ -86,7 +86,7 @@ protected: // device_execute_interface overrides virtual uint32_t execute_min_cycles() const noexcept override { return 2; } virtual uint32_t execute_max_cycles() const noexcept override { return 21; } - virtual uint32_t execute_input_lines() const noexcept override { return 1; } + virtual uint32_t execute_input_lines() const noexcept override { return 3; } virtual void execute_run() override; virtual void execute_set_input(int inputnum, int state) override; diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp index 3a411e2a4aa..aefd1ed8c41 100644 --- a/src/emu/diexec.cpp +++ b/src/emu/diexec.cpp @@ -407,6 +407,9 @@ void device_execute_interface::interface_pre_start() m_profiler = profile_type(index + PROFILER_DEVICE_FIRST); m_inttrigger = index + TRIGGER_INT; + // size the input array + m_input.resize(INPUT_LINES_INTERNAL + execute_input_lines()); + // allocate timers if we need them if (m_periodic_interrupt_period != attotime::zero) m_periodic_interrupt_timer.init(*this, FUNC(device_execute_interface::periodic_interrupt)); @@ -438,14 +441,14 @@ void device_execute_interface::interface_post_start() device().save_item(NAME(m_localtime.m_base)); // it's more efficient and causes less clutter to save these this way - device().save_item(STRUCT_MEMBER(m_input, m_stored_vector)); - device().save_item(STRUCT_MEMBER(m_input, m_enqueued_vector)); - device().save_item(STRUCT_MEMBER(m_input, m_live_vector)); - device().save_item(STRUCT_MEMBER(m_input, m_enqueued_state)); - device().save_item(STRUCT_MEMBER(m_input, m_live_state)); - for (int index = 0; index < std::size(m_input); index++) + for (int index = 0; index < m_input.size(); index++) + { device().save_item(NAME(m_input[index].m_last_event_time), index); + device().save_item(NAME(m_input[index].m_stored_vector), index); + device().save_item(NAME(m_input[index].m_live_vector), index); + device().save_item(NAME(m_input[index].m_live_state), index); + } } @@ -475,11 +478,11 @@ void device_execute_interface::interface_pre_reset() void device_execute_interface::interface_post_reset() { // reset the interrupt vectors - for (int linenum = 0; linenum < std::size(m_input); linenum++) + for (int linenum = 0; linenum < m_input.size(); linenum++) { auto &input = m_input[linenum]; input.m_last_event_time = attotime::zero; - input.m_stored_vector = input.m_live_vector = default_irq_vector(linenum); + input.m_stored_vector = input.m_live_vector = default_irq_vector(linenum - INPUT_LINES_INTERNAL); } // reconfingure VBLANK interrupts @@ -540,7 +543,7 @@ IRQ_CALLBACK_MEMBER( device_execute_interface::standard_irq_callback_member ) int device_execute_interface::standard_irq_callback(int irqline) { - auto &input = m_input[irqline]; + auto &input = input_from_line(irqline); // get the default vector and acknowledge the interrupt if needed int vector = input.m_live_vector; @@ -627,13 +630,7 @@ void device_execute_interface::periodic_interrupt(timer_instance const &timer) void device_execute_interface::enqueue_input_line_change(int line, int state, int vector) { - auto &input = m_input[line]; - - // don't bother enqueuing redundant states - if (state == input.m_enqueued_state && vector == input.m_enqueued_vector) - return; - input.m_enqueued_state = state; - input.m_enqueued_vector = vector; + auto &input = input_from_line(line); // the event should land now, but never enqueue events earlier than the last // one we enqueued or else we'll get in a bad state @@ -653,8 +650,7 @@ void device_execute_interface::enqueue_input_line_change(int line, int state, in void device_execute_interface::process_input_event(timer_instance const &timer) { int linenum = timer.param(0); - assert(linenum < MAX_INPUT_LINES); - auto &input = m_input[linenum]; + auto &input = input_from_line(linenum); int state = timer.param(1); assert(state == ASSERT_LINE || state == HOLD_LINE || state == CLEAR_LINE); diff --git a/src/emu/diexec.h b/src/emu/diexec.h index 9f69d513ec2..d5b0ed27dfc 100644 --- a/src/emu/diexec.h +++ b/src/emu/diexec.h @@ -16,6 +16,9 @@ #include "debug/debugcpu.h" +#define VERIFY_INPUT_LINE_IN_RANGE (1) + + //************************************************************************** // CONSTANTS //************************************************************************** @@ -50,7 +53,6 @@ enum line_state enum { // input lines - MAX_INPUT_LINES = 64+3, INPUT_LINE_IRQ0 = 0, INPUT_LINE_IRQ1 = 1, INPUT_LINE_IRQ2 = 2, @@ -61,11 +63,12 @@ enum INPUT_LINE_IRQ7 = 7, INPUT_LINE_IRQ8 = 8, INPUT_LINE_IRQ9 = 9, - INPUT_LINE_NMI = MAX_INPUT_LINES - 3, // special input lines that are implemented in the core - INPUT_LINE_RESET = MAX_INPUT_LINES - 2, - INPUT_LINE_HALT = MAX_INPUT_LINES - 1 + INPUT_LINES_INTERNAL = 3, + INPUT_LINE_NMI = -1, + INPUT_LINE_RESET = -2, + INPUT_LINE_HALT = -3, }; @@ -104,6 +107,15 @@ class device_execute_interface : public device_interface using execute_delegate = delegate<void ()>; + // internal information about the state of inputs + struct device_input + { + attotime m_last_event_time; // time of last enqueued event + s32 m_stored_vector; // most recently written vector + s32 m_live_vector; // most recently processed vector + u8 m_live_state; // most recently processed state + }; + public: // construction/destruction device_execute_interface(const machine_config &mconfig, device_t &device); @@ -169,10 +181,10 @@ public: void abort_timeslice() noexcept; // input and interrupt management - void set_input_line(int linenum, int state) { enqueue_input_line_change(linenum, state, m_input[linenum].m_stored_vector); } - void set_input_line_vector(int linenum, int vector) { m_input[linenum].m_stored_vector = vector; } + void set_input_line(int linenum, int state) { enqueue_input_line_change(linenum, state, input_from_line(linenum).m_stored_vector); } + void set_input_line_vector(int linenum, int vector) { input_from_line(linenum).m_stored_vector = vector; } void set_input_line_and_vector(int linenum, int state, int vector) { enqueue_input_line_change(linenum, state, vector); } - int input_state(int linenum) const { return m_input[linenum].m_live_state; } + int input_state(int linenum) const { return input_from_line(linenum).m_live_state; } void pulse_input_line(int irqline, const attotime &duration); // suspend/resume @@ -251,7 +263,7 @@ protected: bool update_suspend(); // for use by devcpu for now... - int current_input_state(unsigned i) const { return m_input[i].m_live_state; } + int current_input_state(unsigned linenum) const { return input_from_line(linenum).m_live_state; } void set_icountptr(int &icount) { assert(!m_icountptr); m_icountptr = &icount; } IRQ_CALLBACK_MEMBER(standard_irq_callback_member); int standard_irq_callback(int irqline); @@ -267,18 +279,21 @@ private: void periodic_interrupt(timer_instance const &timer); void process_input_event(timer_instance const &timer); - void enqueue_input_line_change(int line, int state, int vector); - - // internal information about the state of inputs - struct device_input + device_input &input_from_line(int linenum) { - attotime m_last_event_time; // time of last enqueued event - s32 m_stored_vector; // most recently written vector - s32 m_enqueued_vector; // most recently enqueued vector - s32 m_live_vector; // most recently processed vector - u8 m_enqueued_state; // most recently enqueued state - u8 m_live_state; // most recently processed state - }; + int index = linenum + INPUT_LINES_INTERNAL; + if (VERIFY_INPUT_LINE_IN_RANGE && (index < 0 || index >= m_input.size())) + throw emu_fatalerror("%s: input_from_line(%d) failure", device().tag(), linenum); + return m_input[index]; + } + device_input const &input_from_line(int linenum) const + { + int index = linenum + INPUT_LINES_INTERNAL; + if (VERIFY_INPUT_LINE_IN_RANGE && (index < 0 || index >= m_input.size())) + throw emu_fatalerror("%s: input_from_line(%d) failure", device().tag(), linenum); + return m_input[index]; + } + void enqueue_input_line_change(int line, int state, int vector); // core execution state: keep all these members close to the top // so they live within the first 128 bytes of the object; this helps @@ -336,7 +351,7 @@ private: // input states and IRQ callbacks device_irq_acknowledge_delegate m_driver_irq; // driver-specific IRQ callback - device_input m_input[MAX_INPUT_LINES]; // data about inputs + std::vector<device_input> m_input; // data about inputs }; // iterator |