diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index a4e3a9032cc..45753bf8bde 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -2914,3 +2914,14 @@ if (MACHINES["SCNXX562"]~=null) then MAME_DIR .. "src/devices/machine/scnxx562.h", } end + +--------------------------------------------------- +-- +--@src/devices/machine/input_merger.h,MACHINES["INPUT_MERGER"] = true +--------------------------------------------------- +if (MACHINES["INPUT_MERGER"]~=null) then + files { + MAME_DIR .. "src/devices/machine/input_merger.cpp", + MAME_DIR .. "src/devices/machine/input_merger.h", + } +end diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 8d0f32042d4..27a224055b2 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -572,6 +572,7 @@ MACHINES["PCI9050"] = true MACHINES["GENPC"] = true MACHINES["GEN_LATCH"] = true MACHINES["WATCHDOG"] = true +MACHINES["INPUT_MERGER"] = true -------------------------------------------------- -- specify available bus cores diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 44b95bf5615..2377ea4adfd 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -586,6 +586,7 @@ MACHINES["APPLE_FDC"] = true MACHINES["SONY_DRIVE"] = true MACHINES["SCNXX562"] = true MACHINES["FGA002"] = true +MACHINES["INPUT_MERGER"] = true -------------------------------------------------- -- specify available bus cores diff --git a/src/devices/machine/input_merger.cpp b/src/devices/machine/input_merger.cpp new file mode 100644 index 00000000000..398d68ecc59 --- /dev/null +++ b/src/devices/machine/input_merger.cpp @@ -0,0 +1,122 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + Input Merger + + Used to connect multiple lines to a single device input while + keeping it pulled high or low + +***************************************************************************/ + +#include "input_merger.h" + +#include +#include + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type INPUT_MERGER_ACTIVE_HIGH = &device_creator; +const device_type INPUT_MERGER_ACTIVE_LOW = &device_creator; + + +//************************************************************************** +// INPUT ADAPTER +//************************************************************************** + +//------------------------------------------------- +// input_merger_device - constructor +//------------------------------------------------- + +input_merger_device::input_merger_device(machine_config const &mconfig, device_type type, + char const *name, char const *tag, device_t *owner, UINT32 clock, char const *shortname, char const *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + m_output_handler(*this) +{ +} + +//------------------------------------------------- +// input_merger_device - destructor +//------------------------------------------------- + +input_merger_device::~input_merger_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void input_merger_device::device_start() +{ + m_output_handler.resolve_safe(); +} + + +//************************************************************************** +// INPUT ADAPTER ACTIVE HIGH +//************************************************************************** + +//------------------------------------------------- +// input_merger_active_high_device - constructor +//------------------------------------------------- + +input_merger_active_high_device::input_merger_active_high_device(machine_config const &mconfig, char const *tag, device_t *owner, UINT32 clock) + : input_merger_device(mconfig, INPUT_MERGER_ACTIVE_HIGH, "Input Merger (Active High)", tag, owner, clock, "input_merger_hi", __FILE__) +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void input_merger_active_high_device::device_reset() +{ + std::fill(std::begin(m_state), std::end(m_state), false); +} + +//------------------------------------------------- +// update_state - verify current input line state +//------------------------------------------------- + +void input_merger_active_high_device::update_state() +{ + bool state = std::any_of(std::begin(m_state), std::end(m_state), [&](bool state) { return state == true; }); + m_output_handler(state ? ASSERT_LINE : CLEAR_LINE); +} + + +//************************************************************************** +// INPUT ADAPTER ACTIVE LOW +//************************************************************************** + +//------------------------------------------------- +// input_merger_active_low_device - constructor +//------------------------------------------------- + +input_merger_active_low_device::input_merger_active_low_device(machine_config const &mconfig, char const *tag, device_t *owner, UINT32 clock) + : input_merger_device(mconfig, INPUT_MERGER_ACTIVE_LOW, "Input Merger (Active Low)", tag, owner, clock, "input_merger_lo", __FILE__) +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void input_merger_active_low_device::device_reset() +{ + std::fill(std::begin(m_state), std::end(m_state), true); +} + +//------------------------------------------------- +// update_state - verify current input line state +//------------------------------------------------- + +void input_merger_active_low_device::update_state() +{ + bool state = std::any_of(std::begin(m_state), std::end(m_state), [&](bool state) { return state == false; }); + m_output_handler(state ? ASSERT_LINE : CLEAR_LINE); +} diff --git a/src/devices/machine/input_merger.h b/src/devices/machine/input_merger.h new file mode 100644 index 00000000000..9530e8de978 --- /dev/null +++ b/src/devices/machine/input_merger.h @@ -0,0 +1,107 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + Input Merger + + Used to connect multiple lines to a single device input while + keeping it pulled high or low + +***************************************************************************/ + +#pragma once + +#ifndef __INPUT_MERGER_H__ +#define __INPUT_MERGER_H__ + +#include "emu.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_INPUT_MERGER_ACTIVE_HIGH(_tag) \ + MCFG_DEVICE_ADD(_tag, INPUT_MERGER_ACTIVE_HIGH, 0) + +#define MCFG_INPUT_MERGER_ACTIVE_LOW(_tag) \ + MCFG_DEVICE_ADD(_tag, INPUT_MERGER_ACTIVE_LOW, 0) + +#define MCFG_INPUT_MERGER_OUTPUT_HANDLER(_devcb) \ + devcb = &input_merger_device::set_output_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> input_merger_device + +class input_merger_device : public device_t +{ +public: + // callback + template static devcb_base &set_output_handler(device_t &device, _Object object) + { return downcast(device).m_output_handler.set_callback(object); } + + // input lines + DECLARE_WRITE_LINE_MEMBER( in0_w ) { m_state[0] = state; update_state(); }; + DECLARE_WRITE_LINE_MEMBER( in1_w ) { m_state[1] = state; update_state(); }; + DECLARE_WRITE_LINE_MEMBER( in2_w ) { m_state[2] = state; update_state(); }; + DECLARE_WRITE_LINE_MEMBER( in3_w ) { m_state[3] = state; update_state(); }; + DECLARE_WRITE_LINE_MEMBER( in4_w ) { m_state[4] = state; update_state(); }; + DECLARE_WRITE_LINE_MEMBER( in5_w ) { m_state[5] = state; update_state(); }; + DECLARE_WRITE_LINE_MEMBER( in6_w ) { m_state[6] = state; update_state(); }; + DECLARE_WRITE_LINE_MEMBER( in7_w ) { m_state[7] = state; update_state(); }; + +protected: + // constructor/destructor + input_merger_device(machine_config const &mconfig, device_type type, char const *name, char const *tag, device_t *owner, UINT32 clock, char const *shortname, char const *source); + virtual ~input_merger_device() override; + + // device-level overrides + virtual void device_start() override; + + virtual void update_state() = 0; + + devcb_write_line m_output_handler; + bool m_state[8]; +}; + +// ======================> input_merger_active_high_device + +class input_merger_active_high_device : public input_merger_device +{ +public: + input_merger_active_high_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + // device-level overrides + virtual void device_reset() override; + + // input_merger device overrides + virtual void update_state() override; +}; + +// ======================> input_merger_active_low_device + +class input_merger_active_low_device : public input_merger_device +{ +public: + input_merger_active_low_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + // device-level overrides + virtual void device_reset() override; + + // input_merger device overrides + virtual void update_state() override; +}; + + +// device type definition +extern const device_type INPUT_MERGER_ACTIVE_HIGH; +extern const device_type INPUT_MERGER_ACTIVE_LOW; + + +#endif /* __INPUT_MERGER_H__ */