summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/netlist.lua1
-rw-r--r--src/devices/machine/netlist.cpp214
-rw-r--r--src/devices/machine/netlist.h27
-rw-r--r--src/lib/netlist/nl_factory.h43
-rw-r--r--src/lib/netlist/nl_interface.h129
-rwxr-xr-xsrc/lib/netlist/nl_setup.cpp1
6 files changed, 252 insertions, 163 deletions
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua
index 49d8371a1c4..b260e8e3dec 100644
--- a/scripts/src/netlist.lua
+++ b/scripts/src/netlist.lua
@@ -44,6 +44,7 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/nl_dice_compat.h",
MAME_DIR .. "src/lib/netlist/nl_factory.cpp",
MAME_DIR .. "src/lib/netlist/nl_factory.h",
+ MAME_DIR .. "src/lib/netlist/nl_interface.h",
MAME_DIR .. "src/lib/netlist/nl_parser.cpp",
MAME_DIR .. "src/lib/netlist/nl_parser.h",
MAME_DIR .. "src/lib/netlist/nl_setup.cpp",
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index 26c1b16cf00..fdcd6db0753 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -15,6 +15,7 @@
#include "netlist/nl_setup.h"
#include "netlist/nl_factory.h"
#include "netlist/nl_parser.h"
+#include "netlist/nl_interface.h"
#include "netlist/devices/net_lib.h"
#include "netlist/devices/nlid_system.h"
@@ -187,114 +188,6 @@ private:
namespace {
-// ----------------------------------------------------------------------------------------
-// analog_callback
-// ----------------------------------------------------------------------------------------
-
-class NETLIB_NAME(analog_callback) : public netlist::device_t
-{
-public:
- NETLIB_NAME(analog_callback)(netlist::netlist_state_t &anetlist, const pstring &name)
- : device_t(anetlist, name)
- , m_in(*this, "IN")
- , m_cpu_device(nullptr)
- , m_last(*this, "m_last", 0)
- {
- auto *nl = dynamic_cast<netlist_mame_device::netlist_mame_t *>(&state());
- if (nl != nullptr)
- m_cpu_device = downcast<netlist_mame_cpu_device *>(&nl->parent());
- }
-
- void reset() override
- {
- m_last = 0.0;
- }
-
- void register_callback(netlist_mame_analog_output_device::output_delegate &&callback)
- {
- m_callback.reset(new netlist_mame_analog_output_device::output_delegate(std::move(callback)));
- }
-
- NETLIB_UPDATEI()
- {
- netlist::nl_fptype cur = m_in();
-
- // FIXME: make this a parameter
- // avoid calls due to noise
- if (plib::abs(cur - m_last) > 1e-6)
- {
- m_cpu_device->update_icount(exec().time());
- (*m_callback)(cur, m_cpu_device->local_time());
- m_cpu_device->check_mame_abort_slice();
- m_last = cur;
- }
- }
-
-private:
- netlist::analog_input_t m_in;
- std::unique_ptr<netlist_mame_analog_output_device::output_delegate> m_callback; // TODO: change to std::optional for C++17
- netlist_mame_cpu_device *m_cpu_device;
- netlist::state_var<netlist::nl_fptype> m_last;
-};
-
-// ----------------------------------------------------------------------------------------
-// logic_callback
-//
-// This device must be connected to a logic net. It has no power terminals
-// and conversion with proxies will not work.
-//
-// Background: This is inserted later into the driver and should not modify
-// the resulting analog representation of the netlist.
-//
-// ----------------------------------------------------------------------------------------
-
-class NETLIB_NAME(logic_callback) : public netlist::device_t
-{
-public:
- NETLIB_NAME(logic_callback)(netlist::netlist_state_t &anetlist, const pstring &name)
- : device_t(anetlist, name)
- , m_in(*this, "IN")
- , m_cpu_device(nullptr)
- , m_last(*this, "m_last", 0)
-// , m_supply(*this)
- {
- auto *nl = dynamic_cast<netlist_mame_device::netlist_mame_t *>(&state());
- if (nl != nullptr)
- m_cpu_device = downcast<netlist_mame_cpu_device *>(&nl->parent());
- }
-
- void reset() override
- {
- m_last = 0;
- }
-
- void register_callback(netlist_mame_logic_output_device::output_delegate &&callback)
- {
- m_callback.reset(new netlist_mame_logic_output_device::output_delegate(std::move(callback)));
- }
-
- NETLIB_UPDATEI()
- {
- netlist::netlist_sig_t cur = m_in();
-
- // FIXME: make this a parameter
- // avoid calls due to noise
- if (cur != m_last)
- {
- m_cpu_device->update_icount(exec().time());
- (*m_callback)(cur, m_cpu_device->local_time());
- m_cpu_device->check_mame_abort_slice();
- m_last = cur;
- }
- }
-
-private:
- netlist::logic_input_t m_in;
- std::unique_ptr<netlist_mame_logic_output_device::output_delegate> m_callback; // TODO: change to std::optional for C++17
- netlist_mame_cpu_device *m_cpu_device;
- netlist::state_var<netlist::netlist_sig_t> m_last;
- //netlist::devices::NETLIB_NAME(power_pins) m_supply;
-};
// ----------------------------------------------------------------------------------------
@@ -799,19 +692,38 @@ netlist_mame_analog_output_device::netlist_mame_analog_output_device(const machi
{
}
-void netlist_mame_analog_output_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
-{
- const pstring pin(m_in);
- pstring dname = pstring("OUT_") + pin;
+
+void netlist_mame_analog_output_device::custom_netlist_additions(netlist::nlparse_t &parser)
+{
/* ignore if no running machine -> called within device_validity_check context */
if (owner()->has_running_machine())
m_delegate.resolve();
- auto dev = nlstate.make_pool_object<NETLIB_NAME(analog_callback)>(nlstate, dname);
- dev->register_callback(std::move(m_delegate));
- nlstate.register_device(dname, std::move(dev));
- nlstate.parser().register_link(dname + ".IN", pin);
+ const pstring pin(m_in);
+ pstring dname = pstring("OUT_") + pin;
+
+ parser.register_dev(dname, dname);
+ parser.register_link(dname + ".IN", pin);
+}
+
+void netlist_mame_analog_output_device::pre_parse_action(netlist::nlparse_t &parser)
+{
+ const pstring pin(m_in);
+ pstring dname = pstring("OUT_") + pin;
+
+ const auto lambda = [this](auto &in, netlist::nl_fptype val)
+ {
+ this->cpu()->update_icount(in.exec().time());
+ this->m_delegate(val, this->cpu()->local_time());
+ this->cpu()->check_mame_abort_slice();
+ };
+
+ using lb_t = decltype(lambda);
+ using cb_t = netlist::interface::NETLIB_NAME(analog_callback)<lb_t>;
+
+ parser.factory().add<cb_t, netlist::nl_fptype, lb_t>(dname,
+ netlist::factory::properties("-", PSOURCELOC()), 1e-6, std::forward<lb_t>(lambda));
}
void netlist_mame_analog_output_device::device_start()
@@ -832,21 +744,39 @@ netlist_mame_logic_output_device::netlist_mame_logic_output_device(const machine
{
}
-void netlist_mame_logic_output_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
+void netlist_mame_logic_output_device::custom_netlist_additions(netlist::nlparse_t &parser)
{
- pstring pin(m_in);
- pstring dname = "OUT_" + pin;
-
/* ignore if no running machine -> called within device_validity_check context */
if (owner()->has_running_machine())
m_delegate.resolve();
- auto dev = nlstate.make_pool_object<NETLIB_NAME(logic_callback)>(nlstate, dname);
- dev->register_callback(std::move(m_delegate));
- nlstate.register_device(dname, std::move(dev));
- nlstate.parser().register_link(dname + ".IN", pin);
+ const pstring pin(m_in);
+ pstring dname = pstring("OUT_") + pin;
+
+ parser.register_dev(dname, dname);
+ parser.register_link(dname + ".IN", pin);
}
+void netlist_mame_logic_output_device::pre_parse_action(netlist::nlparse_t &parser)
+{
+ const pstring pin(m_in);
+ pstring dname = pstring("OUT_") + pin;
+
+ const auto lambda = [this](auto &in, netlist::netlist_sig_t val)
+ {
+ this->cpu()->update_icount(in.exec().time());
+ this->m_delegate(val, this->cpu()->local_time());
+ this->cpu()->check_mame_abort_slice();
+ };
+
+ using lb_t = decltype(lambda);
+ using cb_t = netlist::interface::NETLIB_NAME(logic_callback)<lb_t>;
+
+ parser.factory().add<cb_t, lb_t>(dname,
+ netlist::factory::properties("-", PSOURCELOC()), std::forward<lb_t>(lambda));
+}
+
+
void netlist_mame_logic_output_device::device_start()
{
LOGDEVCALLS("start\n");
@@ -1015,17 +945,17 @@ void netlist_mame_stream_input_device::device_start()
LOGDEVCALLS("start\n");
}
-void netlist_mame_stream_input_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
+void netlist_mame_stream_input_device::custom_netlist_additions(netlist::nlparse_t &parser)
{
- if (!nlstate.parser().device_exists("STREAM_INPUT"))
- nlstate.parser().register_dev("NETDEV_SOUND_IN", "STREAM_INPUT");
+ if (!parser.device_exists("STREAM_INPUT"))
+ parser.register_dev("NETDEV_SOUND_IN", "STREAM_INPUT");
pstring sparam = plib::pfmt("STREAM_INPUT.CHAN{1}")(m_channel);
- nlstate.parser().register_param(sparam, pstring(m_param_name));
+ parser.register_param(sparam, pstring(m_param_name));
sparam = plib::pfmt("STREAM_INPUT.MULT{1}")(m_channel);
- nlstate.parser().register_param_val(sparam, m_mult);
+ parser.register_param_val(sparam, m_mult);
sparam = plib::pfmt("STREAM_INPUT.OFFSET{1}")(m_channel);
- nlstate.parser().register_param_val(sparam, m_offset);
+ parser.register_param_val(sparam, m_offset);
}
// ----------------------------------------------------------------------------------------
@@ -1051,18 +981,18 @@ void netlist_mame_stream_output_device::device_start()
LOGDEVCALLS("start\n");
}
-void netlist_mame_stream_output_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
+void netlist_mame_stream_output_device::custom_netlist_additions(netlist::nlparse_t &parser)
{
//NETLIB_NAME(sound_out) *snd_out;
pstring sname = plib::pfmt("STREAM_OUT_{1}")(m_channel);
//snd_out = dynamic_cast<NETLIB_NAME(sound_out) *>(setup.register_dev("nld_sound_out", sname));
- nlstate.parser().register_dev("NETDEV_SOUND_OUT", sname);
+ parser.register_dev("NETDEV_SOUND_OUT", sname);
- nlstate.parser().register_param_val(sname + ".CHAN" , m_channel);
- nlstate.parser().register_param_val(sname + ".MULT", m_mult);
- nlstate.parser().register_param_val(sname + ".OFFSET", m_offset);
- nlstate.parser().register_link(sname + ".IN", pstring(m_out_name));
+ parser.register_param_val(sname + ".CHAN" , m_channel);
+ parser.register_param_val(sname + ".MULT", m_mult);
+ parser.register_param_val(sname + ".OFFSET", m_offset);
+ parser.register_link(sname + ".IN", pstring(m_out_name));
}
@@ -1127,20 +1057,20 @@ void netlist_mame_device::common_dev_start(netlist::netlist_state_t *lnetlist) c
}
}
- /* add default data provider for roms - if not in validity check*/
- //if (has_running_machine())
- lsetup.parser().register_source<netlist_data_memregions_t>(*this);
+ // add default data provider for roms - if not in validity check
+ lsetup.parser().register_source<netlist_data_memregions_t>(*this);
+ // Read the netlist
m_setup_func(lsetup.parser());
- /* let sub-devices tweak the netlist */
+ // let sub-devices tweak the netlist
for (device_t &d : subdevices())
{
netlist_mame_sub_interface *sdev = dynamic_cast<netlist_mame_sub_interface *>(&d);
if( sdev != nullptr )
{
LOGDEVCALLS("Found subdevice %s/%s\n", d.name(), d.shortname());
- sdev->custom_netlist_additions(*lnetlist);
+ sdev->custom_netlist_additions(lsetup.parser());
}
}
}
@@ -1402,8 +1332,6 @@ void netlist_mame_cpu_device::device_start()
void netlist_mame_cpu_device::nl_register_devices(netlist::nlparse_t &parser) const
{
- parser.factory().add<nld_analog_callback>( "NETDEV_CALLBACK",
- netlist::factory::properties("-", PSOURCELOC()));
}
uint64_t netlist_mame_cpu_device::execute_clocks_to_cycles(uint64_t clocks) const noexcept
diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h
index dfd67a88afe..062a61edffa 100644
--- a/src/devices/machine/netlist.h
+++ b/src/devices/machine/netlist.h
@@ -263,10 +263,11 @@ class netlist_mame_sub_interface
{
public:
// construction/destruction
- netlist_mame_sub_interface(device_t &aowner)
+ netlist_mame_sub_interface(device_t &owner)
: m_offset(0.0), m_mult(1.0)
- , m_owner(dynamic_cast<netlist_mame_device *>(&aowner))
- , m_sound(dynamic_cast<netlist_mame_sound_device *>(&aowner))
+ , m_owner(dynamic_cast<netlist_mame_device *>(&owner))
+ , m_sound(dynamic_cast<netlist_mame_sound_device *>(&owner))
+ , m_cpu(dynamic_cast<netlist_mame_cpu_device *>(&owner))
{
}
@@ -274,7 +275,7 @@ public:
{
}
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) { }
+ virtual void custom_netlist_additions(netlist::nlparse_t &parser) { }
virtual void pre_parse_action(netlist::nlparse_t &parser) { }
virtual void validity_helper(validity_checker &valid,
netlist::netlist_state_t &nlstate) const { }
@@ -292,13 +293,16 @@ public:
void set_mult_offset(const double mult, const double offset);
netlist_mame_sound_device *sound() { return m_sound;}
+ netlist_mame_cpu_device *cpu() { return m_cpu;}
+
protected:
double m_offset;
double m_mult;
private:
- netlist_mame_device *const m_owner;
+ netlist_mame_device *const m_owner;
netlist_mame_sound_device *const m_sound;
+ netlist_mame_cpu_device *const m_cpu;
};
// ----------------------------------------------------------------------------------------
@@ -357,7 +361,8 @@ public:
// construction/destruction
netlist_mame_analog_output_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
- template <typename... T> void set_params(const char *in_name, T &&... args)
+ template <typename... T>
+ void set_params(const char *in_name, T &&... args)
{
m_in = in_name;
m_delegate.set(std::forward<T>(args)...);
@@ -367,7 +372,8 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void pre_parse_action(netlist::nlparse_t &parser) override;
+ virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
private:
const char *m_in;
@@ -395,7 +401,8 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void pre_parse_action(netlist::nlparse_t &parser) override;
+ virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
private:
const char *m_in;
@@ -531,7 +538,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
private:
uint32_t m_channel;
const char *m_param_name;
@@ -557,7 +564,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
private:
uint32_t m_channel;
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index 15b15470180..de5265bee69 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -14,6 +14,8 @@
#include "plib/putil.h"
#include <vector>
+#include <tuple>
+#include <utility>
#define NETLIB_DEVICE_IMPL_ALIAS(p_alias, chip, p_name, p_def_param) \
NETLIB_DEVICE_IMPL_BASE(devices, p_alias, chip, p_name, p_def_param) \
@@ -112,25 +114,47 @@ namespace factory {
properties m_properties; ///< source file and other information and settings
};
- template <class C>
+ template <class C, typename... Args>
class device_element_t : public element_t
{
public:
- device_element_t(const pstring &name, properties &&props)
- : element_t(name, std::move(props)) { }
+ device_element_t(const pstring &name, properties &&props, Args&&... args)
+ : element_t(name, std::move(props))
+ , m_args(std::forward<Args>(args)...)
+ { }
+
+
+ template <std::size_t... Is>
+ dev_uptr make_device(nlmempool &pool,
+ netlist_state_t &anetlist,
+ const pstring &name, std::tuple<Args...>& args, std::index_sequence<Is...>)
+ {
+ return pool.make_unique<C>(anetlist, name, std::forward<Args>(std::get<Is>(args))...);
+ }
+
+ dev_uptr make_device(nlmempool &pool,
+ netlist_state_t &anetlist,
+ const pstring &name, std::tuple<Args...>& args)
+ {
+ return make_device(pool, anetlist, name, args, std::index_sequence_for<Args...>{});
+ }
dev_uptr make_device(nlmempool &pool,
netlist_state_t &anetlist,
const pstring &name) override
{
- return pool.make_unique<C>(anetlist, name);
+ return make_device(pool, anetlist, name, m_args);
+ //return pool.make_unique<C>(anetlist, name);
}
- static uptr create(const pstring &name, properties &&props)
+ static uptr create(const pstring &name, properties &&props, Args&&... args)
{
- return plib::make_unique<device_element_t<C>>(name, std::move(props));
+ return plib::make_unique<device_element_t<C, Args...>>(name,
+ std::move(props), std::forward<Args>(args)...);
}
+ private:
+ std::tuple<Args...> m_args;
};
class list_t : public std::vector<element_t::uptr>
@@ -141,10 +165,11 @@ namespace factory {
PCOPYASSIGNMOVE(list_t, delete)
- template<class device_class>
- void add(const pstring &name, properties &&props)
+ template<class device_class, typename... Args>
+ void add(const pstring &name, properties &&props, Args&&... args)
{
- add(device_element_t<device_class>::create(name, std::move(props)));
+ add(device_element_t<device_class, Args...>::create(name, std::move(props),
+ std::forward<Args>(args)...));
}
void add(element_t::uptr &&factory) noexcept(false);
diff --git a/src/lib/netlist/nl_interface.h b/src/lib/netlist/nl_interface.h
new file mode 100644
index 00000000000..55c8185aa5b
--- /dev/null
+++ b/src/lib/netlist/nl_interface.h
@@ -0,0 +1,129 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+
+///
+/// \file nl_interface.h
+///
+/// This header contains objects for interfacing with the netlist core.
+///
+
+#ifndef NLINTERFACE_H_
+#define NLINTERFACE_H_
+
+#include "nl_base.h"
+
+#include <initializer_list>
+#include <memory>
+#include <stack>
+#include <unordered_map>
+#include <vector>
+
+namespace netlist
+{
+
+ namespace interface
+ {
+ /// \brief analog_callback device
+ ///
+ /// This device is used to call back into the application which
+ /// is controlling the execution of the netlist.
+ ///
+ /// The device will call the provided lambda with a reference to
+ /// itself and the current value of the net it is connected to.
+ ///
+ /// The following code is an example on how to add the device to
+ /// the netlist factory.
+ ///
+ /// const pstring pin(m_in);
+ /// pstring dname = pstring("OUT_") + pin;
+ ///
+ /// const auto lambda = [this](auto &in, netlist::nl_fptype val)
+ /// {
+ /// this->cpu()->update_icount(in.exec().time());
+ /// this->m_delegate(val, this->cpu()->local_time());
+ /// this->cpu()->check_mame_abort_slice();
+ /// };
+ ///
+ /// using lb_t = decltype(lambda);
+ /// using cb_t = netlist::interface::NETLIB_NAME(analog_callback)<lb_t>;
+ ///
+ /// parser.factory().add<cb_t, netlist::nl_fptype, lb_t>(dname,
+ /// netlist::factory::properties("-", PSOURCELOC()), 1e-6, std::forward<lb_t>(lambda));
+ ///
+
+ template <typename FUNC>
+ class NETLIB_NAME(analog_callback) : public device_t
+ {
+ public:
+ NETLIB_NAME(analog_callback)(netlist_state_t &anetlist,
+ const pstring &name, nl_fptype threshold, FUNC &&func)
+ : device_t(anetlist, name)
+ , m_in(*this, "IN")
+ , m_threshold(threshold)
+ , m_last(*this, "m_last", 0)
+ , m_func(func)
+ {
+ }
+
+ NETLIB_RESETI()
+ {
+ m_last = 0.0;
+ }
+
+ NETLIB_UPDATEI()
+ {
+ const nl_fptype cur = m_in();
+ if (plib::abs(cur - m_last) > m_threshold)
+ {
+ m_last = cur;
+ m_func(*this, cur);
+ }
+ }
+
+ private:
+ analog_input_t m_in;
+ nl_fptype m_threshold;
+ state_var<nl_fptype> m_last;
+ FUNC m_func;
+ };
+
+
+ /// \brief logic_callback device
+ ///
+ /// This device must be connected to a logic net. It has no power terminals
+ /// and conversion with proxies will not work.
+ ///
+ /// Background: This device may be inserted later into the driver and should
+ /// not modify the resulting analog representation of the netlist.
+ ///
+ /// If you get error messages on missing power terminals you have to use the
+ /// analog callback device instead.
+
+ template <typename FUNC>
+ class NETLIB_NAME(logic_callback) : public device_t
+ {
+ public:
+ NETLIB_NAME(logic_callback)(netlist_state_t &anetlist, const pstring &name, FUNC &&func)
+ : device_t(anetlist, name)
+ , m_in(*this, "IN")
+ , m_func(func)
+ {
+ }
+
+ NETLIB_UPDATEI()
+ {
+ const netlist_sig_t cur = m_in();
+ m_func(*this, cur);
+ }
+
+ private:
+ logic_input_t m_in;
+ FUNC m_func;
+ };
+
+ } // namespace interface
+
+} // namespace netlist
+
+
+#endif // NLINTERFACE_H_
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index 9b0bc5f4340..8e535a45a83 100755
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -81,7 +81,6 @@ namespace netlist
include(f->name());
namespace_pop();
}
- //f->macro_actions(*this, name);
pstring key = build_fqn(name);
if (device_exists(key))