From c87a487d6de35479210d36dcf53d2c96a478601a Mon Sep 17 00:00:00 2001 From: couriersud Date: Mon, 4 Feb 2019 00:27:23 +0100 Subject: [PATCH] netlist: Refactoring and some functionality enhancements. (nw) - Removed dead code. - nltool now adds a define NLTOOL_VERSION. This can be tested in netlists. It is used in kidniki to ensure I stop committing debug parameters. - Optimized the proposal for no-deactivate hints. - Documented in breakout that hints were manually optimized. - Minor optimizations in the order of 2% enhancement. --- src/devices/machine/netlist.cpp | 6 +- src/devices/machine/netlist.h | 1 - src/lib/netlist/devices/nld_9310.cpp | 31 ++++++----- src/lib/netlist/devices/nld_9316.cpp | 34 ++++-------- src/lib/netlist/devices/nld_system.cpp | 23 ++++++++ src/lib/netlist/devices/nlid_system.h | 15 ++--- src/lib/netlist/devices/nlid_truthtable.h | 4 +- src/lib/netlist/nl_base.cpp | 68 ++++++++--------------- src/lib/netlist/nl_base.h | 59 +++++++++++++++----- src/lib/netlist/nl_setup.cpp | 11 ++-- src/lib/netlist/nl_setup.h | 13 ++++- src/lib/netlist/plib/plists.h | 3 +- src/lib/netlist/plib/poptions.cpp | 6 +- src/lib/netlist/plib/poptions.h | 26 ++++----- src/lib/netlist/plib/pparser.cpp | 14 ++--- src/lib/netlist/plib/pparser.h | 6 +- src/lib/netlist/plib/pstate.cpp | 4 +- src/lib/netlist/plib/pstate.h | 4 +- src/lib/netlist/plib/putil.h | 4 ++ src/lib/netlist/prg/nltool.cpp | 21 ++++--- src/lib/netlist/prg/nlwav.cpp | 10 ++-- src/mame/audio/nl_kidniki.cpp | 9 +++ src/mame/machine/nl_breakout.cpp | 47 ++++++++++++++-- 23 files changed, 250 insertions(+), 169 deletions(-) diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 6795dcb9d6a..fc76132a731 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -301,7 +301,7 @@ public: { int pos = (upto - m_last_buffer_time) / m_sample_time; if (pos > m_bufsize) - state().log().fatal("sound {1}: pos {2} exceeded bufsize {3}\n", name().c_str(), pos, m_bufsize); + throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), pos, m_bufsize); while (m_last_pos < pos ) { m_buffer[m_last_pos++] = (stream_sample_t) m_cur; @@ -1050,10 +1050,8 @@ ATTR_COLD uint64_t netlist_mame_cpu_device::execute_cycles_to_clocks(uint64_t cy ATTR_HOT void netlist_mame_cpu_device::execute_run() { - bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0); - // debugging //m_ppc = m_pc; // copy PC to previous PC - if (check_debugger) + if (debugger_enabled()) { while (m_icount > 0) { diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index d79e9e298c2..06edb4beaa4 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -109,7 +109,6 @@ public: ATTR_HOT inline netlist::setup_t &setup(); ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; } - ATTR_HOT inline const netlist::netlist_time last_time_update() { return m_old; } ATTR_HOT void update_icount(netlist::netlist_time time); ATTR_HOT void check_mame_abort_slice(); diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp index 4348de20417..cbc197a70d8 100644 --- a/src/lib/netlist/devices/nld_9310.cpp +++ b/src/lib/netlist/devices/nld_9310.cpp @@ -158,32 +158,35 @@ namespace netlist NETLIB_UPDATE(9310_sub) { + auto cnt(m_cnt); + if (m_loadq) { - if (m_cnt < MAXCNT - 1) + if (cnt < MAXCNT - 1) { - ++m_cnt; - update_outputs(m_cnt); + ++cnt; + update_outputs(cnt); } - else if (m_cnt == MAXCNT - 1) + else if (cnt == MAXCNT - 1) { - m_cnt = MAXCNT; + cnt = MAXCNT; m_RC.push(m_ent, NLTIME_FROM_NS(20)); m_QA.push(1, NLTIME_FROM_NS(20)); } else // MAXCNT { m_RC.push(0, NLTIME_FROM_NS(20)); - m_cnt = 0; - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); + cnt = 0; + update_outputs_all(cnt, NLTIME_FROM_NS(20)); } } else { - m_cnt = m_ABCD->read_ABCD(); - m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); - update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); + cnt = m_ABCD->read_ABCD(); + m_RC.push(m_ent & (cnt == MAXCNT), NLTIME_FROM_NS(27)); + update_outputs_all(cnt, NLTIME_FROM_NS(22)); } + m_cnt = cnt; } NETLIB_UPDATE(9310) @@ -224,10 +227,10 @@ namespace netlist #if 0 // for (int i=0; i<4; i++) // m_Q[i], (cnt >> i) & 1, delay[i]); - m_QA, (cnt >> 0) & 1, out_delay); - m_QB, (cnt >> 1) & 1, out_delay); - m_QC, (cnt >> 2) & 1, out_delay); - m_QD, (cnt >> 3) & 1, out_delay); + m_QA.push((cnt >> 0) & 1, out_delay); + m_QB.push((cnt >> 1) & 1, out_delay); + m_QC.push((cnt >> 2) & 1, out_delay); + m_QD.push((cnt >> 3) & 1, out_delay); #else if ((cnt & 1) == 1) m_QA.push(1, out_delay); diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index 20858ebc74f..69dd1c1c6ca 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -105,27 +105,15 @@ namespace netlist NETLIB_HANDLER(9316, clk) { + auto cnt(m_cnt); if (m_LOADQ()) { - ++m_cnt &= MAXCNT; - //m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); -#if 0 - if (m_cnt == MAXCNT) - { - m_RC.push(m_ENT(), NLTIME_FROM_NS(27)); - update_outputs_all(MAXCNT, NLTIME_FROM_NS(20)); - } - else if (m_cnt == 0) - { - m_RC.push(0, NLTIME_FROM_NS(27)); - update_outputs_all(0, NLTIME_FROM_NS(20)); - } - else - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); -#else - if (m_cnt > 0 && m_cnt < MAXCNT) - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); - else if (m_cnt == 0) + ++cnt &= MAXCNT; + //m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27)); + + if (cnt > 0 && cnt < MAXCNT) + update_outputs_all(cnt, NLTIME_FROM_NS(20)); + else if (cnt == 0) { m_RC.push(0, NLTIME_FROM_NS(27)); update_outputs_all(0, NLTIME_FROM_NS(20)); @@ -135,14 +123,14 @@ namespace netlist m_RC.push(m_ENT(), NLTIME_FROM_NS(27)); update_outputs_all(MAXCNT, NLTIME_FROM_NS(20)); } -#endif } else { - m_cnt = m_abcd; - m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); - update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); + cnt = m_abcd; + m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27)); + update_outputs_all(cnt, NLTIME_FROM_NS(22)); } + m_cnt = cnt; } NETLIB_UPDATE(9316) diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 24af4527a70..134017d06b0 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -40,15 +40,38 @@ namespace netlist { m_cnt = 0; m_off = netlist_time::from_double(m_offset()); + m_feedback.m_delegate = NETLIB_DELEGATE(extclock, update); + + //m_feedback.m_delegate .set(&NETLIB_NAME(extclock)::update, this); //m_Q.initial(0); } + NETLIB_HANDLER(extclock, clk2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + if (++m_cnt >= m_size) + m_cnt = 0; + } + + NETLIB_HANDLER(extclock, clk2_pow2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + m_cnt = (++m_cnt) & (m_size-1); + } + NETLIB_UPDATE(extclock) { m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off); m_off = netlist_time::zero(); if (++m_cnt >= m_size) m_cnt = 0; + + // continue with optimized clock handlers .... + + if ((m_size & (m_size-1)) == 0) // power of 2? + m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2_pow2, this); + else + m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2, this); } // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 3d878646549..7271084bbc1 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -52,7 +52,7 @@ namespace netlist NETLIB_RESETI() { - m_Q.net().set_time(netlist_time::zero()); + m_Q.net().set_next_scheduled_time(netlist_time::zero()); } NETLIB_UPDATE_PARAMI() @@ -65,7 +65,7 @@ namespace netlist logic_net_t &net = m_Q.net(); // this is only called during setup ... net.toggle_new_Q(); - net.set_time(exec().time() + m_inc); + net.set_next_scheduled_time(exec().time() + m_inc); } public: @@ -73,13 +73,6 @@ namespace netlist param_double_t m_freq; netlist_time m_inc; - - static void mc_update(logic_net_t &net) - { - net.toggle_new_Q(); - net.update_devs(); - } - }; // ----------------------------------------------------------------------------- @@ -158,6 +151,10 @@ namespace netlist NETLIB_UPDATEI(); NETLIB_RESETI(); //NETLIB_UPDATE_PARAMI(); + + NETLIB_HANDLERI(clk2); + NETLIB_HANDLERI(clk2_pow2); + protected: param_double_t m_freq; diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index f0f85e037de..c633a6991a1 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -179,7 +179,7 @@ namespace devices m_I[i].activate(); //nstate |= (m_I[i]() ? (1 << i) : 0); nstate |= (m_I[i]() << i); - mt = std::max(this->m_I[i].net().time(), mt); + mt = std::max(this->m_I[i].net().next_scheduled_time(), mt); } else for (std::size_t i = 0; i < m_NI; i++) @@ -208,7 +208,7 @@ namespace devices { //nstate |= (m_I[i]() ? (1 << i) : 0); nstate |= (m_I[i]() << i); - mt = std::max(this->m_I[i].net().time(), mt); + mt = std::max(this->m_I[i].net().next_scheduled_time(), mt); } else for (std::size_t i = 0; i < m_NI; i++) diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 14807111ff2..4ce980dbba8 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -164,11 +164,9 @@ void detail::queue_t::register_state(plib::state_manager_t &manager, const pstri manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size()); } -void detail::queue_t::on_pre_save() +void detail::queue_t::on_pre_save(plib::state_manager_t &manager) { - state().log().debug("on_pre_save\n"); m_qsize = this->size(); - state().log().debug("qsize {1}\n", m_qsize); for (std::size_t i = 0; i < m_qsize; i++ ) { m_times[i] = this->listptr()[i].m_exec_time.as_raw(); @@ -177,10 +175,9 @@ void detail::queue_t::on_pre_save() } -void detail::queue_t::on_post_load() +void detail::queue_t::on_post_load(plib::state_manager_t &manager) { this->clear(); - state().log().debug("qsize {1}\n", m_qsize); for (std::size_t i = 0; i < m_qsize; i++ ) { detail::net_t *n = state().nets()[m_net_ids[i]].get(); @@ -247,11 +244,11 @@ detail::terminal_type detail::core_terminal_t::type() const // ---------------------------------------------------------------------------------------- netlist_t::netlist_t(const pstring &aname, std::unique_ptr callbacks) - : m_state(plib::make_unique(aname, + : m_time(netlist_time::zero()) + , m_mainclock(nullptr) + , m_state(plib::make_unique(aname, std::move(callbacks), plib::make_unique(*this))) // FIXME, ugly but needed to have netlist_state_t constructed first - , m_time(netlist_time::zero()) - , m_mainclock(nullptr) , m_queue(*m_state) , m_solver(nullptr) { @@ -272,8 +269,7 @@ netlist_t::~netlist_t() netlist_state_t::netlist_state_t(const pstring &aname, std::unique_ptr &&callbacks, std::unique_ptr &&setup) -: m_params(nullptr) -, m_name(aname) +: m_name(aname) , m_state() , m_callbacks(std::move(callbacks)) // Order is important here , m_log(*m_callbacks) @@ -339,7 +335,7 @@ void netlist_t::reset() m_time = netlist_time::zero(); m_queue.clear(); if (m_mainclock != nullptr) - m_mainclock->m_Q.net().set_time(netlist_time::zero()); + m_mainclock->m_Q.net().set_next_scheduled_time(netlist_time::zero()); //if (m_solver != nullptr) // m_solver->reset(); @@ -452,7 +448,7 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT { logic_net_t &mc_net(m_mainclock->m_Q.net()); const netlist_time inc(m_mainclock->m_inc); - netlist_time mc_time(mc_net.time()); + netlist_time mc_time(mc_net.next_scheduled_time()); do { @@ -474,7 +470,7 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT else break; } while (true); //while (e.m_object != nullptr); - mc_net.set_time(mc_time); + mc_net.set_next_scheduled_time(mc_time); } m_stat_mainloop.stop(); } @@ -503,6 +499,9 @@ void netlist_t::print_stats() const total_count += entry->m_stat_total_time.count(); } + log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count, + total_time, total_time / total_count); + nperftime_t overhead; nperftime_t test; overhead.start(); @@ -531,10 +530,16 @@ void netlist_t::print_stats() const / static_cast::type>(m_queue.m_prof_call()); log().verbose("Overhead per pop {1:11}", overhead_per_pop ); log().verbose(""); + + auto trigger = total_count * 200 / 1000000; // 200 ppm for (auto &entry : m_state->m_devices) { - if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count()) - log().verbose("HINT({}, NO_DEACTIVATE)", entry->name()); + // Factor of 3 offers best performace increase + if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count() + && entry->m_stat_inc_active() > trigger) + log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", entry->name(), + static_cast(entry->m_stat_inc_active()) / static_cast(entry->m_stat_total_time.count()), + entry->m_stat_inc_active(), entry->m_stat_total_time.count()); } } } @@ -687,7 +692,7 @@ detail::net_t::net_t(netlist_base_t &nl, const pstring &aname, core_terminal_t * , m_new_Q(*this, "m_new_Q", 0) , m_cur_Q (*this, "m_cur_Q", 0) , m_in_queue(*this, "m_in_queue", QS_DELIVERED) - , m_time(*this, "m_time", netlist_time::zero()) + , m_next_scheduled_time(*this, "m_time", netlist_time::zero()) , m_railterminal(mr) { } @@ -697,35 +702,6 @@ detail::net_t::~net_t() state().run_state_manager().remove_save_items(this); } -void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT -{ - const bool was_empty = m_list_active.empty(); - m_list_active.push_front(&term); - if (was_empty) - { - railterminal().device().do_inc_active(); - if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE) - { - if (m_time > exec().time()) - { - m_in_queue = QS_QUEUED; /* pending */ - exec().queue().push({m_time, this}); - } - else - { - m_in_queue = QS_DELIVERED; - m_cur_Q = m_new_Q; - } - } - } -} - -void detail::net_t::remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT -{ - m_list_active.remove(&term); - if (m_list_active.empty()) - railterminal().device().do_dec_active(); -} void detail::net_t::rebuild_list() { @@ -779,7 +755,7 @@ void detail::net_t::update_devs() NL_NOEXCEPT void detail::net_t::reset() { - m_time = netlist_time::zero(); + m_next_scheduled_time = netlist_time::zero(); m_in_queue = QS_DELIVERED; m_new_Q = 0; diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index ca75046b3e5..35ecc694cfd 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -732,8 +732,8 @@ namespace netlist void update_devs() NL_NOEXCEPT; - const netlist_time time() const noexcept { return m_time; } - void set_time(netlist_time ntime) noexcept { m_time = ntime; } + const netlist_time next_scheduled_time() const noexcept { return m_next_scheduled_time; } + void set_next_scheduled_time(netlist_time ntime) noexcept { m_next_scheduled_time = ntime; } bool isRailNet() const noexcept { return !(m_railterminal == nullptr); } core_terminal_t & railterminal() const noexcept { return *m_railterminal; } @@ -761,7 +761,7 @@ namespace netlist state_var m_cur_Q; state_var m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ - state_var m_time; + state_var m_next_scheduled_time; private: plib::linkedlist_t m_list_active; @@ -803,7 +803,7 @@ namespace netlist if (newQ != m_new_Q) { m_in_queue = QS_DELAYED_DUE_TO_INACTIVE; - m_time = at; + m_next_scheduled_time = at; } m_cur_Q = m_new_Q = newQ; } @@ -1204,8 +1204,8 @@ namespace netlist protected: void register_state(plib::state_manager_t &manager, const pstring &module) override; - void on_pre_save() override; - void on_post_load() override; + void on_pre_save(plib::state_manager_t &manager) override; + void on_post_load(plib::state_manager_t &manager) override; private: std::size_t m_qsize; @@ -1272,8 +1272,6 @@ namespace netlist template void register_net(plib::owned_ptr &&net) { m_nets.push_back(std::move(net)); } - devices::NETLIB_NAME(netlistparams) *m_params; - template inline std::vector get_device_list() { @@ -1387,11 +1385,10 @@ namespace netlist void print_stats() const; private: - std::unique_ptr m_state; - /* mostly rw */ netlist_time m_time; devices::NETLIB_NAME(mainclock) * m_mainclock; + std::unique_ptr m_state; detail::queue_t m_queue; devices::NETLIB_NAME(solver) * m_solver; @@ -1517,15 +1514,50 @@ namespace netlist { if ((num_cons() != 0)) { + auto &lexec(exec()); + auto &q(lexec.queue()); + auto nst(lexec.time() + delay); + if (is_queued()) - exec().queue().remove(this); - m_time = exec().time() + delay; + q.remove(this); m_in_queue = (!m_list_active.empty()) ? QS_QUEUED : QS_DELAYED_DUE_TO_INACTIVE; /* queued ? */ if (m_in_queue == QS_QUEUED) - exec().queue().push(queue_t::entry_t(m_time, this)); + q.push(queue_t::entry_t(nst, this)); + m_next_scheduled_time = nst; } } + inline void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT + { + if (m_list_active.empty()) + { + m_list_active.push_front(&term); + railterminal().device().do_inc_active(); + if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE) + { + if (m_next_scheduled_time > exec().time()) + { + m_in_queue = QS_QUEUED; /* pending */ + exec().queue().push({m_next_scheduled_time, this}); + } + else + { + m_in_queue = QS_DELIVERED; + m_cur_Q = m_new_Q; + } + } + } + else + m_list_active.push_front(&term); + } + + inline void detail::net_t::remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT + { + m_list_active.remove(&term); + if (m_list_active.empty()) + railterminal().device().do_dec_active(); + } + inline const analog_net_t & analog_t::net() const NL_NOEXCEPT { return static_cast(core_terminal_t::net()); @@ -1583,6 +1615,7 @@ namespace netlist return m_device.exec(); } + inline const netlist_t &detail::device_object_t::exec() const NL_NOEXCEPT { return m_device.exec(); diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 291e95add83..cef51f481db 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -27,6 +27,7 @@ namespace netlist { setup_t::setup_t(netlist_t &netlist) : m_netlist(netlist) + , m_netlist_params(nullptr) , m_factory(*this) , m_proxy_cnt(0) , m_frontier_cnt(0) @@ -970,13 +971,13 @@ std::unique_ptr setup_t::get_data_stream(const pstring &name) return std::unique_ptr(nullptr); } -void setup_t::register_define(const pstring &defstr) +void setup_t::add_define(const pstring &defstr) { auto p = defstr.find("="); if (p != pstring::npos) - register_define(plib::left(defstr, p), defstr.substr(p+1)); + add_define(plib::left(defstr, p), defstr.substr(p+1)); else - register_define(defstr, "1"); + add_define(defstr, "1"); } // ---------------------------------------------------------------------------------------- @@ -1024,7 +1025,7 @@ void setup_t::prepare_to_run() log().debug("Searching for solver and parameters ...\n"); auto solver = netlist().get_single_device("solver"); - netlist().m_params = netlist().get_single_device("parameter"); + m_netlist_params = netlist().get_single_device("parameter"); /* create devices */ @@ -1039,7 +1040,7 @@ void setup_t::prepare_to_run() } } - bool use_deactivate = (netlist().m_params->m_use_deactivate() ? true : false); + bool use_deactivate = m_netlist_params->m_use_deactivate() ? true : false; for (auto &d : netlist().devices()) { diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 4becfe1ee0c..25201bee1b5 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -123,6 +123,7 @@ namespace netlist namespace devices { class nld_base_proxy; + class nld_netlistparams; } class core_device_t; @@ -274,8 +275,12 @@ namespace netlist m_sources.push_back(std::move(src)); } - void register_define(pstring def, pstring val) { m_defines.push_back(plib::ppreprocessor::define_t(def, val)); } - void register_define(const pstring &defstr); + void add_define(pstring def, pstring val) + { + m_defines.insert({ def, plib::ppreprocessor::define_t(def, val)}); + } + + void add_define(const pstring &defstr); factory::list_t &factory() { return m_factory; } const factory::list_t &factory() const { return m_factory; } @@ -337,14 +342,16 @@ namespace netlist std::unordered_map m_terminals; netlist_t &m_netlist; + devices::nld_netlistparams *m_netlist_params; std::unordered_map m_params; + std::vector m_links; factory::list_t m_factory; std::unordered_map m_models; std::stack m_namespace_stack; source_t::list_t m_sources; - std::vector m_defines; + plib::ppreprocessor::defines_map_type m_defines; unsigned m_proxy_cnt; unsigned m_frontier_cnt; diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 5574f095484..d440d76de2a 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -152,9 +152,10 @@ public: void remove(const LC *elem) noexcept { auto p = &m_head; - for ( ; *p != elem; p = &((*p)->m_next)) + while(*p != elem) { //nl_assert(*p != nullptr); + p = &((*p)->m_next); } (*p) = elem->m_next; } diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index 43e992f9225..dcb8e3931f3 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -219,7 +219,7 @@ namespace plib { } pstring options::help(pstring description, pstring usage, - unsigned width, unsigned indent) + unsigned width, unsigned indent) const { pstring ret; @@ -293,7 +293,7 @@ namespace plib { return ret; } - option *options::getopt_short(pstring arg) + option *options::getopt_short(pstring arg) const { for (auto & optbase : m_opts) { @@ -303,7 +303,7 @@ namespace plib { } return nullptr; } - option *options::getopt_long(pstring arg) + option *options::getopt_long(pstring arg) const { for (auto & optbase : m_opts) { diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 4a8e6d788d7..925329e80d4 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -27,7 +27,7 @@ public: option_base(options &parent, pstring help); virtual ~option_base(); - pstring help() { return m_help; } + pstring help() const { return m_help; } private: pstring m_help; }; @@ -39,7 +39,7 @@ public: : option_base(parent, help), m_group(group) { } ~option_group(); - pstring group() { return m_group; } + pstring group() const { return m_group; } private: pstring m_group; }; @@ -51,7 +51,7 @@ public: : option_base(parent, help), m_example(group) { } ~option_example(); - pstring example() { return m_example; } + pstring example() const { return m_example; } private: pstring m_example; }; @@ -93,7 +93,7 @@ public: : option(parent, ashort, along, help, true), m_val(defval) {} - pstring operator ()() { return m_val; } + pstring operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override; @@ -128,7 +128,7 @@ public: { } - T operator ()() { return m_val; } + T operator ()() const { return m_val; } pstring as_string() const { return limit()[m_val]; } @@ -157,7 +157,7 @@ public: : option(parent, ashort, along, help, false), m_val(false) {} - bool operator ()() { return m_val; } + bool operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override; @@ -180,7 +180,7 @@ public: , m_max(maxval) {} - T operator ()() { return m_val; } + T operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override @@ -203,7 +203,7 @@ public: : option(parent, ashort, along, help, true) {} - std::vector operator ()() { return m_val; } + const std::vector &operator ()() const { return m_val; } protected: virtual int parse(const pstring &argument) override; @@ -233,9 +233,9 @@ public: int parse(int argc, char *argv[]); pstring help(pstring description, pstring usage, - unsigned width = 72, unsigned indent = 20); + unsigned width = 72, unsigned indent = 20) const; - pstring app() { return m_app; } + pstring app() const { return m_app; } private: static pstring split_paragraphs(pstring text, unsigned width, unsigned indent, @@ -244,7 +244,7 @@ private: void check_consistency(); template - T *getopt_type() + T *getopt_type() const { for (auto & optbase : m_opts ) { @@ -254,8 +254,8 @@ private: return nullptr; } - option *getopt_short(pstring arg); - option *getopt_long(pstring arg); + option *getopt_short(pstring arg) const; + option *getopt_long(pstring arg) const; std::vector m_opts; pstring m_app; diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index 48e29570b4c..d666ad11054 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -268,7 +268,7 @@ void ptokenizer::error(const pstring &errs) // A simple preprocessor // ---------------------------------------------------------------------------------------- -ppreprocessor::ppreprocessor(std::vector *defines) +ppreprocessor::ppreprocessor(defines_map_type *defines) : pistream() , m_ifflag(0) , m_level(0) @@ -292,12 +292,7 @@ ppreprocessor::ppreprocessor(std::vector *defines) m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")}); if (defines != nullptr) - { - for (auto & p : *defines) - { - m_defines.insert({p.m_name, p}); - } - } + m_defines = *defines; } void ppreprocessor::error(const pstring &err) @@ -524,7 +519,10 @@ pstring ppreprocessor::process_line(pstring line) } } else - error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(line)); + { + if (m_ifflag == 0) + error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line))); + } } else { diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h index 1eeb92d797b..3829e8cdcc8 100644 --- a/src/lib/netlist/plib/pparser.h +++ b/src/lib/netlist/plib/pparser.h @@ -163,7 +163,9 @@ public: pstring m_replace; }; - explicit ppreprocessor(std::vector *defines = nullptr); + using defines_map_type = std::unordered_map; + + explicit ppreprocessor(defines_map_type *defines = nullptr); virtual ~ppreprocessor() override {} template @@ -214,7 +216,7 @@ private: pstring process_line(pstring line); pstring process_comments(pstring line); - std::unordered_map m_defines; + defines_map_type m_defines; std::vector m_expr_sep; std::uint_least64_t m_ifflag; // 31 if levels diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp index 3cab5dec127..a5465bfed46 100644 --- a/src/lib/netlist/plib/pstate.cpp +++ b/src/lib/netlist/plib/pstate.cpp @@ -48,13 +48,13 @@ void state_manager_t::remove_save_items(const void *owner) void state_manager_t::pre_save() { for (auto & s : m_custom) - s->m_callback->on_pre_save(); + s->m_callback->on_pre_save(*this); } void state_manager_t::post_load() { for (auto & s : m_custom) - s->m_callback->on_post_load(); + s->m_callback->on_post_load(*this); } template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname) diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index 5b8acc92221..3a908cba2d2 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -56,8 +56,8 @@ public: virtual ~callback_t(); virtual void register_state(state_manager_t &manager, const pstring &module) = 0; - virtual void on_pre_save() = 0; - virtual void on_post_load() = 0; + virtual void on_pre_save(state_manager_t &manager) = 0; + virtual void on_post_load(state_manager_t &manager) = 0; protected: }; diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index 4212677c81c..023a0271ce2 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -14,6 +14,10 @@ #include #include // <<= needed by windows build +#define PSTRINGIFY_HELP(y) # y +#define PSTRINGIFY(x) PSTRINGIFY_HELP(x) + + namespace plib { diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 3c9839a7845..984f8703079 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -17,6 +17,8 @@ #include +#define NLTOOL_VERSION 20190202 + class tool_app_t : public plib::app { public: @@ -36,7 +38,7 @@ public: opt_name(*this, "n", "name", "", "the netlist in file specified by ""-f"" option to run; default is first one"), opt_grp3(*this, "Options for run command", "These options are only used by the run command."), - opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"), + opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)\n\n abc def\n\n xyz"), opt_logs(*this, "l", "log" , "define terminal to log. This option may be specified repeatedly."), opt_inp(*this, "i", "input", "", "input file to process (default is none)"), opt_loadstate(*this,"", "loadstate", "", "load state from file and continue from there"), @@ -99,6 +101,8 @@ private: void listdevices(); + std::vector m_options; + }; static NETLIST_START(dummy) @@ -186,7 +190,7 @@ public: // read the netlist ... for (auto & d : defines) - setup().register_define(d); + setup().add_define(d); for (auto & r : roms) setup().register_source(plib::make_unique_base(setup(), r)); @@ -347,7 +351,7 @@ void tool_app_t::run() nt.read_netlist(opt_file(), opt_name(), opt_logs(), - opt_defines(), opt_rfolders()); + m_options, opt_rfolders()); std::vector inps = read_input(nt.setup(), opt_inp()); @@ -423,7 +427,7 @@ void tool_app_t::static_compile() nt.read_netlist(opt_file(), opt_name(), opt_logs(), - opt_defines(), opt_rfolders()); + m_options, opt_rfolders()); plib::putf8_writer w(&pout_strm); std::map mp; @@ -543,9 +547,9 @@ void tool_app_t::create_header() if (last_source != e->sourcefile()) { last_source = e->sourcefile(); - pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), 72)); + pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), opt_linewidth())); pout("{1}{2}\n", pstring("// Source: "), plib::replace_all(e->sourcefile(), "../", "")); - pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), 72)); + pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), opt_linewidth())); } cmac(e.get()); } @@ -697,7 +701,7 @@ int tool_app_t::execute() if (opt_version()) { pout( - "nltool (netlist) 0.1\n" + "nltool (netlist) " PSTRINGIFY(NLTOOL_VERSION) "\n" "Copyright (C) 2019 Couriersud\n" "License GPLv2+: GNU GPL version 2 or later .\n" "This is free software: you are free to change and redistribute it.\n" @@ -706,6 +710,9 @@ int tool_app_t::execute() return 0; } + m_options = opt_defines(); + m_options.push_back("NLTOOL_VERSION=" PSTRINGIFY(NLTOOL_VERSION)); + try { pstring cmd = opt_cmd.as_string(); diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 8116e48111a..c25330627b6 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -381,11 +381,11 @@ public: nlwav_app() : plib::app(), opt_fmt(*this, "f", "format", 0, std::vector({"wav","vcda","vcdd"}), - "output format. Available options are wav|vcda|vcdd.\n" - "wav : multichannel wav output\n" - "vcda : analog VCD output\n" - "vcdd : digital VCD output\n" - "Digital signals are created using the high and low options" + "output format. Available options are wav|vcda|vcdd." + " wav : multichannel wav output" + " vcda : analog VCD output" + " vcdd : digital VCD output" + " Digital signals are created using the --high and --low options" ), opt_out(*this, "o", "output", "-", "output file"), opt_rate(*this, "r", "rate", 48000, "sample rate of output file"), diff --git a/src/mame/audio/nl_kidniki.cpp b/src/mame/audio/nl_kidniki.cpp index 7865ea40750..9e8c47247af 100644 --- a/src/mame/audio/nl_kidniki.cpp +++ b/src/mame/audio/nl_kidniki.cpp @@ -2,8 +2,17 @@ // copyright-holders:Andrew Gardner, Couriersud #include "netlist/devices/net_lib.h" +#ifdef NLBASE_H_ +#error Somehow nl_base.h made it into the include chain. +#endif + +#ifndef NLTOOL_VERSION #define USE_FRONTIERS 1 #define USE_FIXED_STV 1 +#else +#define USE_FRONTIERS 0 +#define USE_FIXED_STV 1 +#endif /* ---------------------------------------------------------------------------- * Library section header START diff --git a/src/mame/machine/nl_breakout.cpp b/src/mame/machine/nl_breakout.cpp index 87426734036..0823df42350 100644 --- a/src/mame/machine/nl_breakout.cpp +++ b/src/mame/machine/nl_breakout.cpp @@ -1702,22 +1702,19 @@ CIRCUIT_LAYOUT( breakout ) NET_C(GND, D9.1, D9.2, D9.13, D9.3, D9.4, D9.5) - HINT(A3.1.sub, NO_DEACTIVATE) +#if 1 + // 158% -- manually optimized HINT(B6.s3, NO_DEACTIVATE) HINT(C4.s3, NO_DEACTIVATE) HINT(C4.s4, NO_DEACTIVATE) HINT(C5.s3, NO_DEACTIVATE) HINT(C5.s4, NO_DEACTIVATE) - HINT(D3.2.sub, NO_DEACTIVATE) HINT(E2.s2, NO_DEACTIVATE) HINT(E3.s2, NO_DEACTIVATE) HINT(E5.s4, NO_DEACTIVATE) - HINT(E8.2.sub, NO_DEACTIVATE) HINT(E9.s6, NO_DEACTIVATE) - HINT(F5.2.sub, NO_DEACTIVATE) HINT(H2.s1, NO_DEACTIVATE) HINT(H3.s1, NO_DEACTIVATE) - HINT(H6.sub, NO_DEACTIVATE) HINT(J3.s4, NO_DEACTIVATE) HINT(J5, NO_DEACTIVATE) HINT(J6.sub, NO_DEACTIVATE) @@ -1729,9 +1726,47 @@ CIRCUIT_LAYOUT( breakout ) HINT(M4.s2, NO_DEACTIVATE) HINT(M6.sub, NO_DEACTIVATE) HINT(M8.s1, NO_DEACTIVATE) - HINT(N6.sub, NO_DEACTIVATE) HINT(N7.s3, NO_DEACTIVATE) +#else + // 152% hints provided by log output + HINT(M4.s2, NO_DEACTIVATE) // 29.001761 197676 6816 + HINT(M3.s3, NO_DEACTIVATE) // inf 129571 0 + HINT(N7.s3, NO_DEACTIVATE) // inf 7850387 0 + HINT(M3.s2, NO_DEACTIVATE) // 23.234535 395870 17038 + HINT(M3.s1, NO_DEACTIVATE) // 14.500880 197676 13632 + HINT(L7.s3, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(L7.s2, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(K7.s4, NO_DEACTIVATE) // 122673.000000 122673 1 + HINT(K7.s3, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(K7.s2, NO_DEACTIVATE) // 122673.000000 122673 1 + HINT(K7.s1, NO_DEACTIVATE) // 122673.000000 122673 1 + HINT(K4.s4, NO_DEACTIVATE) // 1438.774735 4202661 2921 + HINT(K4.s2, NO_DEACTIVATE) // 3.939380 847790 215209 + HINT(E2.s2, NO_DEACTIVATE) // 108.050000 315506 2920 + HINT(L7.s4, NO_DEACTIVATE) // 122672.000000 122672 1 + HINT(E9.s6, NO_DEACTIVATE) // inf 129571 0 + HINT(J2.s6, NO_DEACTIVATE) // 493.408951 959187 1944 + HINT(C5.s3, NO_DEACTIVATE) // inf 195514 0 + HINT(M3.s4, NO_DEACTIVATE) // 27.744898 418726 15092 + HINT(J8.s1, NO_DEACTIVATE) // 40890.000000 122670 3 + HINT(E3.s2, NO_DEACTIVATE) // 203581.000000 203581 1 + HINT(M9.s4, NO_DEACTIVATE) // inf 323268 0 + HINT(L4.s2, NO_DEACTIVATE) // 7.290053 1192536 163584 + HINT(J3.s4, NO_DEACTIVATE) // 393.639951 957726 2433 + HINT(L7.s1, NO_DEACTIVATE) // inf 122672 0 + HINT(F2.s1, NO_DEACTIVATE) // 286289.000000 286289 1 + HINT(M8.s1, NO_DEACTIVATE) // 129571.000000 129571 1 + HINT(J7.s2, NO_DEACTIVATE) // inf 122672 0 + HINT(H2.s1, NO_DEACTIVATE) // 393.839704 958212 2433 + HINT(H3.s1, NO_DEACTIVATE) // 3.932473 850122 216180 + HINT(J2.s5, NO_DEACTIVATE) // 26.140344 203581 7788 + HINT(J7.s1, NO_DEACTIVATE) // inf 122672 0 + HINT(J8.s3, NO_DEACTIVATE) // 40890.000000 122670 3 + + +#endif + CIRCUIT_LAYOUT_END /*