summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit5127bd81c44a5300ea1b6864ee00b7183699974c (patch)
treec429eb7774d6ef097b4a1ae30b19ef7446cc3070
parente38c112c9b943bc1d50ab4ae62cccefc982ed6fa (diff)
Dynamically allocate input lines. Add range checks for input lines. Fix a few incorrect cases.
-rw-r--r--src/devices/cpu/i386/i386.cpp11
-rw-r--r--src/devices/cpu/m6502/m6502.cpp2
-rw-r--r--src/devices/cpu/m6502/m6502.h2
-rw-r--r--src/devices/cpu/saturn/saturn.h2
-rw-r--r--src/emu/diexec.cpp32
-rw-r--r--src/emu/diexec.h55
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