From cb6f1d0194b07e3817131d9b589797f7b67a7d59 Mon Sep 17 00:00:00 2001 From: Couriersud Date: Sun, 24 Nov 2013 20:08:04 +0000 Subject: [PATCH] Netlist: Added pascal like strings (pstring) class. These use only size(void *) in objects. Uses reference counter to share identical string between various pstrings. In addition, fixed some bugs and added auto-sizing to netlist_list_t. There shouldn't be memory holes left now, apart from memory allocated in a static class factory. --- .gitattributes | 2 + src/emu/machine/netlist.c | 6 +- src/emu/machine/netlist.h | 4 +- src/emu/netlist/devices/net_lib.c | 4 +- src/emu/netlist/devices/nld_system.c | 37 +++-- src/emu/netlist/devices/nld_system.h | 12 +- src/emu/netlist/netlist.mak | 3 +- src/emu/netlist/nl_base.c | 65 ++++---- src/emu/netlist/nl_base.h | 64 ++++---- src/emu/netlist/nl_config.h | 2 + src/emu/netlist/nl_lists.h | 63 +++++--- src/emu/netlist/nl_parser.c | 35 ++--- src/emu/netlist/nl_parser.h | 8 +- src/emu/netlist/nl_setup.c | 139 +++++++++-------- src/emu/netlist/nl_setup.h | 53 ++++--- src/emu/netlist/nl_time.h | 56 +++---- src/emu/netlist/pstring.c | 218 +++++++++++++++++++++++++++ src/emu/netlist/pstring.h | 164 ++++++++++++++++++++ 18 files changed, 690 insertions(+), 245 deletions(-) create mode 100644 src/emu/netlist/pstring.c create mode 100644 src/emu/netlist/pstring.h diff --git a/.gitattributes b/.gitattributes index 8c5b99a3cd4..dd2cb945d36 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2144,6 +2144,8 @@ src/emu/netlist/nl_parser.h svneol=native#text/plain src/emu/netlist/nl_setup.c svneol=native#text/plain src/emu/netlist/nl_setup.h svneol=native#text/plain src/emu/netlist/nl_time.h svneol=native#text/plain +src/emu/netlist/pstring.c svneol=native#text/plain +src/emu/netlist/pstring.h svneol=native#text/plain src/emu/network.c svneol=native#text/plain src/emu/network.h svneol=native#text/plain src/emu/output.c svneol=native#text/plain diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index 81bee490d21..55fbb9782b5 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -49,8 +49,6 @@ #include "netlist/nl_setup.h" #include "netlist/devices/net_lib.h" -const netlist_time netlist_time::zero = netlist_time::from_raw(0); - // ---------------------------------------------------------------------------------------- // netlist_mame_device // ---------------------------------------------------------------------------------------- @@ -91,8 +89,8 @@ void netlist_mame_device::device_start() m_setup->start_devices(); bool allok = true; - for (on_device_start **ods = m_device_start_list.first(); ods <= m_device_start_list.last(); ods++) - allok &= (*ods)->OnDeviceStart(); + for (device_start_list_t::entry_t *ods = m_device_start_list.first(); ods != NULL; ods = m_device_start_list.next(ods)) + allok &= ods->object()->OnDeviceStart(); if (!allok) fatalerror("required elements not found\n"); diff --git a/src/emu/machine/netlist.h b/src/emu/machine/netlist.h index b3704b0d0d9..d79b0c4f783 100644 --- a/src/emu/machine/netlist.h +++ b/src/emu/machine/netlist.h @@ -118,7 +118,9 @@ public: netlist_setup_t &setup() { return *m_setup; } netlist_t &netlist() { return *m_netlist; } - netlist_list_t m_device_start_list; + typedef netlist_list_t device_start_list_t; + + device_start_list_t m_device_start_list; protected: // device-level overrides diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c index e646dd46e85..86feecff40b 100644 --- a/src/emu/netlist/devices/net_lib.c +++ b/src/emu/netlist/devices/net_lib.c @@ -987,7 +987,7 @@ static const net_device_t_base_factory *netregistry[] = NULL }; -netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup) +netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup) { const net_device_t_base_factory **p = &netregistry[0]; while (*p != NULL) @@ -1003,7 +1003,7 @@ netlist_device_t *net_create_device_by_classname(const astring &classname, netli return NULL; // appease code analysis } -netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup) +netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup) { const net_device_t_base_factory **p = &netregistry[0]; while (*p != NULL) diff --git a/src/emu/netlist/devices/nld_system.c b/src/emu/netlist/devices/nld_system.c index 0d34efba4af..747088b9077 100644 --- a/src/emu/netlist/devices/nld_system.c +++ b/src/emu/netlist/devices/nld_system.c @@ -98,13 +98,24 @@ NETLIB_UPDATE_PARAM(solver) m_inc = netlist_time::from_hz(m_freq.Value()); } +NETLIB_NAME(solver)::~NETLIB_NAME(solver)() +{ + net_list_t::entry_t *p = m_nets.first(); + while (p != NULL) + { + net_list_t::entry_t *pn = m_nets.next(pn); + delete pn->object(); + p = pn; + } +} + NETLIB_FUNC_VOID(solver, post_start, ()) { NL_VERBOSE_OUT(("post start solver ...\n")); - for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) + for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) { NL_VERBOSE_OUT(("setting up net\n")); - for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next) + for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next) { switch (p->type()) { @@ -121,11 +132,11 @@ NETLIB_FUNC_VOID(solver, post_start, ()) break; } } - if ((*pn)->m_head == NULL) + if (pn->object()->m_head == NULL) { NL_VERBOSE_OUT(("Deleting net ...\n")); - netlist_net_t *to_delete = *pn; - m_nets.del(to_delete); + netlist_net_t *to_delete = pn->object(); + m_nets.remove(to_delete); delete to_delete; pn--; } @@ -146,15 +157,15 @@ NETLIB_UPDATE(solver) NL_VERBOSE_OUT(("Step!\n")); /* update all terminals for new time step */ m_last_step = now; - for (netlist_terminal_t **p = m_terms.first(); p != NULL; p = m_terms.next(p)) - (*p)->netdev().step_time(delta.as_double()); + for (terminal_list_t::entry_t *p = m_terms.first(); p != NULL; p = m_terms.next(p)) + p->object()->netdev().step_time(delta.as_double()); } - for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) + for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) { double gtot = 0; double iIdr = 0; - for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next) + for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next) { if (p->isType(netlist_terminal_t::TERMINAL)) { @@ -165,9 +176,9 @@ NETLIB_UPDATE(solver) } double new_val = iIdr / gtot; - if (fabs(new_val - (*pn)->m_cur.Analog) > 1e-4) + if (fabs(new_val - pn->object()->m_cur.Analog) > 1e-4) resched = true; - (*pn)->m_cur.Analog = (*pn)->m_new.Analog = new_val; + pn->object()->m_cur.Analog = pn->object()->m_new.Analog = new_val; NL_VERBOSE_OUT(("Info: %d\n", (*pn)->m_num_cons)); NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val)); @@ -179,8 +190,8 @@ NETLIB_UPDATE(solver) else { /* update all inputs connected */ - for (netlist_terminal_t **p = m_inps.first(); p != NULL; p = m_inps.next(p)) - (*p)->netdev().update_dev(); + for (terminal_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p)) + p->object()->netdev().update_dev(); /* step circuit */ if (!m_Q.net().is_queued()) { diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h index bd62ed4bfac..20ba1f21f75 100644 --- a/src/emu/netlist/devices/nld_system.h +++ b/src/emu/netlist/devices/nld_system.h @@ -96,6 +96,9 @@ NETLIB_DEVICE_WITH_PARAMS(clock, // ---------------------------------------------------------------------------------------- NETLIB_DEVICE_WITH_PARAMS(solver, + typedef netlist_list_t terminal_list_t; + typedef netlist_list_t net_list_t; + netlist_ttl_input_t m_feedback; netlist_ttl_output_t m_Q; @@ -104,11 +107,14 @@ NETLIB_DEVICE_WITH_PARAMS(solver, netlist_time m_inc; netlist_time m_last_step; - netlist_list_t m_terms; - netlist_list_t m_inps; + terminal_list_t m_terms; + terminal_list_t m_inps; public: - netlist_list_t m_nets; + + ~NETLIB_NAME(solver)(); + + net_list_t m_nets; ATTR_HOT inline void schedule(); diff --git a/src/emu/netlist/netlist.mak b/src/emu/netlist/netlist.mak index 0580146c918..c0d215d2e5c 100644 --- a/src/emu/netlist/netlist.mak +++ b/src/emu/netlist/netlist.mak @@ -18,8 +18,9 @@ NETLISTOBJ = $(EMUOBJ)/netlist #------------------------------------------------- NETLISTOBJS+= \ - $(NETLISTOBJ)/nl_setup.o \ $(NETLISTOBJ)/nl_base.o \ + $(NETLISTOBJ)/pstring.o \ + $(NETLISTOBJ)/nl_setup.o \ $(NETLISTOBJ)/nl_parser.o \ $(NETLISTOBJ)/devices/nld_system.o \ $(NETLISTOBJ)/devices/net_lib.o \ diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index 2ee646a48aa..c9892b98fcc 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -5,6 +5,9 @@ #include "nl_base.h" #include "devices/nld_system.h" +#include "pstring.h" + +const netlist_time netlist_time::zero = netlist_time::from_raw(0); // ---------------------------------------------------------------------------------------- // netlist_object_t @@ -14,25 +17,24 @@ ATTR_COLD netlist_object_t::netlist_object_t(const type_t atype, const family_t : m_objtype(atype) , m_family(afamily) , m_netlist(NULL) -, m_name(NULL) {} ATTR_COLD netlist_object_t::~netlist_object_t() { - delete m_name; + //delete m_name; } -ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const astring &aname) +ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const pstring &aname) { m_netlist = &nl; - m_name = new astring(aname); + m_name = aname; } -ATTR_COLD const astring &netlist_object_t::name() const +ATTR_COLD const pstring &netlist_object_t::name() const { - if (m_name == NULL) + if (m_name == "") fatalerror("object not initialized"); - return *m_name; + return m_name; } // ---------------------------------------------------------------------------------------- @@ -47,7 +49,7 @@ ATTR_COLD netlist_owned_object_t::netlist_owned_object_t(const type_t atype, } ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev, - const astring &aname) + const pstring &aname) { netlist_object_t::init_object(dev.netlist(), aname); m_netdev = &dev; @@ -58,15 +60,17 @@ ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev, // ---------------------------------------------------------------------------------------- netlist_base_t::netlist_base_t() - : m_mainclock(NULL), - m_time_ps(netlist_time::zero), + : m_time_ps(netlist_time::zero), m_rem(0), - m_div(NETLIST_DIV) + m_div(NETLIST_DIV), + m_mainclock(NULL), + m_solver(NULL) { } netlist_base_t::~netlist_base_t() { + pstring::resetmem(); } ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(mainclock) *dev) @@ -81,11 +85,12 @@ ATTR_COLD void netlist_base_t::set_solver_dev(NETLIB_NAME(solver) *dev) ATTR_COLD void netlist_base_t::reset() { - m_time_ps = netlist_time::zero; - m_rem = 0; - m_queue.clear(); - if (m_mainclock != NULL) - m_mainclock->m_Q.net().set_time(netlist_time::zero); + m_time_ps = netlist_time::zero; + m_rem = 0; + m_queue.clear(); + if (m_mainclock != NULL) + m_mainclock->m_Q.net().set_time(netlist_time::zero); + } @@ -121,7 +126,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime) { while ( (atime > 0) && (m_queue.is_not_empty())) { - const queue_t::entry_t e = m_queue.pop(); + const queue_t::entry_t &e = m_queue.pop(); update_time(e.time(), atime); //if (FATAL_ERROR_AFTER_NS) @@ -156,7 +161,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime) NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc); } - const queue_t::entry_t e = m_queue.pop(); + const queue_t::entry_t &e = m_queue.pop(); update_time(e.time(), atime); @@ -197,7 +202,7 @@ netlist_core_device_t::netlist_core_device_t() { } -ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const astring &name) +ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const pstring &name) { init_object(setup.netlist(), name); @@ -248,7 +253,7 @@ netlist_device_t::~netlist_device_t() //NL_VERBOSE_OUT(("~net_device_t\n"); } -ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &name) +ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const pstring &name) { netlist_core_device_t::init(setup, name); m_setup = &setup; @@ -256,33 +261,33 @@ ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &nam } -ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const astring &name) +ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const pstring &name) { dev.init(*m_setup, this->name() + "." + name); } -ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &port) +ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &port) { m_setup->register_object(*this, dev, name, port, netlist_terminal_t::STATE_OUT); } -ATTR_COLD void netlist_device_t::register_terminal(const astring &name, netlist_terminal_t &port) +ATTR_COLD void netlist_device_t::register_terminal(const pstring &name, netlist_terminal_t &port) { m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_INP_ACTIVE); } -ATTR_COLD void netlist_device_t::register_output(const astring &name, netlist_output_t &port) +ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_output_t &port) { m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_OUT); } -ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &inp, netlist_input_t::state_e type) +ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type) { m_terminals.add(name); m_setup->register_object(*this, dev, name, inp, type); } -ATTR_COLD void netlist_device_t::register_input(const astring &name, netlist_input_t &inp, netlist_input_t::state_e type) +ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type) { register_input(*this, name, inp, type); } @@ -303,14 +308,14 @@ ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, net register_link_internal(*this, in, out, aState); } -ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const astring &name, netlist_param_t ¶m, double initialVal) +ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &name, netlist_param_t ¶m, double initialVal) { param.set_netdev(dev); param.initial(initialVal); m_setup->register_object(*this, *this, name, param, netlist_terminal_t::STATE_NONEX); } -ATTR_COLD void netlist_device_t::register_param(const astring &name, netlist_param_t ¶m, double initialVal) +ATTR_COLD void netlist_device_t::register_param(const pstring &name, netlist_param_t ¶m, double initialVal) { register_param(*this,name, param, initialVal); } @@ -451,7 +456,7 @@ ATTR_COLD netlist_terminal_t::netlist_terminal_t() } -ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate) +ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate) { set_state(astate); netlist_owned_object_t::init_object(dev, aname); @@ -480,7 +485,7 @@ netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily) this->set_net(m_my_net); } -ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const astring &aname) +ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) { netlist_terminal_t::init_object(dev, aname, STATE_OUT); net().init_object(dev.netlist(), aname); diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index 9901716c4f7..22c813e2c3e 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -138,6 +138,7 @@ #include "nl_config.h" #include "nl_lists.h" #include "nl_time.h" +#include "pstring.h" // ---------------------------------------------------------------------------------------- // Type definitions @@ -248,9 +249,9 @@ public: virtual ~netlist_object_t(); - ATTR_COLD void init_object(netlist_base_t &nl, const astring &aname); + ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname); - ATTR_COLD const astring &name() const; + ATTR_COLD const pstring &name() const; ATTR_HOT inline const type_t type() const { return m_objtype; } ATTR_HOT inline const family_t family() const { return m_family; } @@ -262,10 +263,10 @@ public: ATTR_HOT inline const netlist_base_t & RESTRICT netlist() const { return *m_netlist; } private: + pstring m_name; const type_t m_objtype; const family_t m_family; netlist_base_t * RESTRICT m_netlist; - astring *m_name; }; // ---------------------------------------------------------------------------------------- @@ -277,7 +278,7 @@ class netlist_owned_object_t : public netlist_object_t public: ATTR_COLD netlist_owned_object_t(const type_t atype, const family_t afamily); - ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname); + ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname); ATTR_HOT inline netlist_core_device_t & RESTRICT netdev() const { return *m_netdev; } private: @@ -306,7 +307,7 @@ public: ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily); ATTR_COLD netlist_terminal_t(); - ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate); + ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate); ATTR_COLD void set_net(netlist_net_t &anet); ATTR_COLD inline bool has_net() { return (m_net != NULL); } @@ -515,7 +516,7 @@ public: ATTR_COLD netlist_output_t(const type_t atype, const family_t afamily); - ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname); + ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname); double m_low_V; double m_high_V; @@ -601,7 +602,7 @@ public: ATTR_COLD virtual ~netlist_core_device_t(); - ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name); + ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name); ATTR_HOT virtual void update_param() {} @@ -656,9 +657,11 @@ public: ATTR_HOT virtual void step_time(const double st) { } ATTR_HOT virtual void update_terminals() { } - /* stats */ +#if (NL_KEEP_STATISTICS) + /* stats */ osd_ticks_t total_time; INT32 stat_count; +#endif #if USE_DELEGATES net_update_delegate static_update; @@ -681,21 +684,21 @@ public: ATTR_COLD virtual ~netlist_device_t(); - ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name); + ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name); ATTR_COLD const netlist_setup_t *setup() const { return m_setup; } ATTR_COLD bool variable_input_count() { return m_variable_input_count; } - ATTR_COLD void register_sub(netlist_core_device_t &dev, const astring &name); + ATTR_COLD void register_sub(netlist_core_device_t &dev, const pstring &name); - ATTR_COLD void register_terminal(const astring &name, netlist_terminal_t &port); + ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port); - ATTR_COLD void register_output(const astring &name, netlist_output_t &out); - ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &out); + ATTR_COLD void register_output(const pstring &name, netlist_output_t &out); + ATTR_COLD void register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &out); - ATTR_COLD void register_input(const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); - ATTR_COLD void register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); + ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); + ATTR_COLD void register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE); ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState); ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState); @@ -703,15 +706,15 @@ public: ATTR_HOT virtual void update_terminals() { } /* driving logic outputs don't count in here */ - netlist_list_t m_terminals; + netlist_list_t m_terminals; protected: virtual void update() { } virtual void start() { } - ATTR_COLD void register_param(const astring &sname, netlist_param_t ¶m, const double initialVal = 0.0); - ATTR_COLD void register_param(netlist_core_device_t &dev, const astring &sname, netlist_param_t ¶m, const double initialVal = 0.0); + ATTR_COLD void register_param(const pstring &sname, netlist_param_t ¶m, const double initialVal = 0.0); + ATTR_COLD void register_param(netlist_core_device_t &dev, const pstring &sname, netlist_param_t ¶m, const double initialVal = 0.0); netlist_setup_t *m_setup; bool m_variable_input_count; @@ -780,19 +783,22 @@ public: ATTR_COLD void reset(); protected: +#if (NL_KEEP_STATISTICS) // performance int m_perf_out_processed; int m_perf_inp_processed; int m_perf_inp_active; +#endif private: + netlist_time m_time_ps; queue_t m_queue; - NETLIB_NAME(mainclock) * m_mainclock; - NETLIB_NAME(solver) * m_solver; - netlist_time m_time_ps; UINT32 m_rem; UINT32 m_div; + NETLIB_NAME(mainclock) * m_mainclock; + NETLIB_NAME(solver) * m_solver; + ATTR_HOT void update_time(const netlist_time t, INT32 &atime); }; @@ -994,7 +1000,7 @@ ATTR_HOT inline const bool netlist_analog_input_t::is_highz() const class net_device_t_base_factory { public: - net_device_t_base_factory(const astring &name, const astring &classname) + net_device_t_base_factory(const pstring &name, const pstring &classname) : m_name(name), m_classname(classname) {} @@ -1002,18 +1008,18 @@ public: virtual netlist_device_t *Create() const = 0; - const astring &name() const { return m_name; } - const astring &classname() const { return m_classname; } + const pstring &name() const { return m_name; } + const pstring &classname() const { return m_classname; } protected: - astring m_name; /* device name */ - astring m_classname; /* device class name */ + pstring m_name; /* device name */ + pstring m_classname; /* device class name */ }; template class net_device_t_factory : public net_device_t_base_factory { public: - net_device_t_factory(const astring &name, const astring &classname) + net_device_t_factory(const pstring &name, const pstring &classname) : net_device_t_base_factory(name, classname) { } netlist_device_t *Create() const @@ -1024,8 +1030,8 @@ public: } }; -netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup); -netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup); +netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup); +netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup); #endif /* NLBASE_H_ */ diff --git a/src/emu/netlist/nl_config.h b/src/emu/netlist/nl_config.h index e68fdf35a27..1f07d4c8354 100644 --- a/src/emu/netlist/nl_config.h +++ b/src/emu/netlist/nl_config.h @@ -16,6 +16,8 @@ // SETUP //============================================================ +//#define astring breakme() + #define USE_DELEGATES (0) /* * The next options needs -Wno-pmf-conversions to compile and gcc diff --git a/src/emu/netlist/nl_lists.h b/src/emu/netlist/nl_lists.h index 8d73ddcae0f..a42a7a339a1 100644 --- a/src/emu/netlist/nl_lists.h +++ b/src/emu/netlist/nl_lists.h @@ -15,14 +15,23 @@ // ---------------------------------------------------------------------------------------- -template +template struct netlist_list_t { public: - ATTR_COLD netlist_list_t(int numElements = 100) + + struct entry_t { + + // keep compatibility with tagmap + _ListClass object() { return m_obj; } + + _ListClass m_obj; + }; + + ATTR_COLD netlist_list_t(int numElements = _NumElem) { m_num_elements = numElements; - m_list = new _ListClass[m_num_elements]; + m_list = new entry_t[m_num_elements]; m_ptr = m_list; m_ptr--; } @@ -32,24 +41,29 @@ public: } ATTR_HOT inline void add(const _ListClass elem) { - assert(m_ptr-m_list <= m_num_elements - 1); + if (m_ptr-m_list >= m_num_elements - 1) + resize(m_num_elements * 2); - *(++m_ptr) = elem; + (++m_ptr)->m_obj = elem; } ATTR_HOT inline void resize(const int new_size) { int cnt = count(); - _ListClass *m_new = new _ListClass[new_size]; - memcpy(m_new, m_list, new_size * sizeof(_ListClass)); + entry_t *m_new = new entry_t[new_size]; + entry_t *pd = m_new; + + for (entry_t *ps = m_list; ps <= m_ptr; ps++, pd++) + *pd = *ps; delete[] m_list; m_list = m_new; m_ptr = m_list + cnt - 1; + m_num_elements = new_size; } - ATTR_HOT inline void del(const _ListClass elem) + ATTR_HOT inline void remove(const _ListClass elem) { - for (_ListClass * i=m_list; i<=m_ptr; i++) + for (entry_t *i = m_list; i <= m_ptr; i++) { - if (*i == elem) + if (i->object() == elem) { while (i <= m_ptr) { @@ -61,16 +75,16 @@ public: } } } - ATTR_HOT inline _ListClass *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); } - ATTR_HOT inline _ListClass *next(_ListClass *lc) { return (lc < last() ? lc + 1 : NULL ); } - ATTR_HOT inline _ListClass *last() { return m_ptr; } - ATTR_HOT inline _ListClass *item(int i) { return &m_list[i]; } + ATTR_HOT inline entry_t *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); } + ATTR_HOT inline entry_t *next(entry_t *lc) { return (lc < last() ? lc + 1 : NULL ); } + ATTR_HOT inline entry_t *last() { return m_ptr; } + ATTR_HOT inline entry_t *item(int i) { return &m_list[i]; } ATTR_HOT inline int count() const { return m_ptr - m_list + 1; } ATTR_HOT inline bool empty() { return (m_ptr < m_list); } - ATTR_HOT inline void clear() { m_ptr = m_list - 1; } + ATTR_HOT inline void reset() { m_ptr = m_list - 1; } private: - _ListClass * m_ptr; - _ListClass * m_list; + entry_t * m_ptr; + entry_t * m_list; int m_num_elements; //_ListClass m_list[_NumElements]; }; @@ -111,7 +125,7 @@ public: if (is_empty() || (e.time() <= (m_end - 1)->time())) { *m_end++ = e; - //inc_stat(m_prof_end); + inc_stat(m_prof_end); } else { @@ -120,20 +134,20 @@ public: { i--; *(i+1) = *i; - //inc_stat(m_prof_sortmove); + inc_stat(m_prof_sortmove); } *i = e; - //inc_stat(m_prof_sort); + inc_stat(m_prof_sort); } assert(m_end - m_list < _Size); } - ATTR_HOT inline const entry_t pop() + ATTR_HOT inline const entry_t &pop() { return *--m_end; } - ATTR_HOT inline const entry_t peek() const + ATTR_HOT inline const entry_t &peek() const { return *(m_end-1); } @@ -142,12 +156,15 @@ public: { m_end = &m_list[0]; } - // profiling +#if (NL_KEEP_STATISTICS) + // profiling INT32 m_prof_start; INT32 m_prof_end; INT32 m_prof_sortmove; INT32 m_prof_sort; +#endif + private: entry_t * RESTRICT m_end; diff --git a/src/emu/netlist/nl_parser.c b/src/emu/netlist/nl_parser.c index e47e7d644c5..3233b4c3773 100644 --- a/src/emu/netlist/nl_parser.c +++ b/src/emu/netlist/nl_parser.c @@ -16,7 +16,7 @@ void netlist_parser::parse(char *buf) m_p = buf; while (*m_p) { - astring n; + pstring n; skipws(); if (!*m_p) break; n = getname('('); @@ -34,8 +34,8 @@ void netlist_parser::parse(char *buf) void netlist_parser::net_alias() { - astring alias; - astring out; + pstring alias; + pstring out; skipws(); alias = getname(','); skipws(); @@ -46,7 +46,7 @@ void netlist_parser::net_alias() void netlist_parser::netdev_param() { - astring param; + pstring param; double val; skipws(); param = getname(','); @@ -58,11 +58,11 @@ void netlist_parser::netdev_param() check_char(')'); } -void netlist_parser::netdev_const(const astring &dev_name) +void netlist_parser::netdev_const(const pstring &dev_name) { - astring name; + pstring name; netlist_device_t *dev; - astring paramfq; + pstring paramfq; double val; skipws(); @@ -72,16 +72,15 @@ void netlist_parser::netdev_const(const astring &dev_name) skipws(); val = eval_param(); check_char(')'); - paramfq = name; - paramfq.cat(".CONST"); + paramfq = name + ".CONST"; NL_VERBOSE_OUT(("Parser: Const: %s %f\n", name.cstr(), val)); //m_setup.find_param(paramfq).initial(val); m_setup.register_param(paramfq, val); } -void netlist_parser::netdev_device(const astring &dev_type) +void netlist_parser::netdev_device(const pstring &dev_type) { - astring devname; + pstring devname; netlist_device_t *dev; int cnt; @@ -96,11 +95,9 @@ void netlist_parser::netdev_device(const astring &dev_type) { m_p++; skipws(); - astring output_name = getname2(',', ')'); + pstring output_name = getname2(',', ')'); NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), dev->m_terminals.item(cnt)->cstr())); - astring temp; - temp.printf("%s.[%d]", devname.cstr(), cnt); - m_setup.register_link(temp, output_name); + m_setup.register_link(pstring::sprintf("%s.[%d]", devname.cstr(), cnt), output_name); skipws(); cnt++; } @@ -156,7 +153,7 @@ void netlist_parser::skipws() } } -astring netlist_parser::getname(char sep) +pstring netlist_parser::getname(char sep) { char buf[300]; char *p1 = buf; @@ -165,10 +162,10 @@ astring netlist_parser::getname(char sep) *p1++ = *m_p++; *p1 = 0; m_p++; - return astring(buf); + return pstring(buf); } -astring netlist_parser::getname2(char sep1, char sep2) +pstring netlist_parser::getname2(char sep1, char sep2) { char buf[300]; char *p1 = buf; @@ -176,7 +173,7 @@ astring netlist_parser::getname2(char sep1, char sep2) while ((*m_p != sep1) && (*m_p != sep2)) *p1++ = *m_p++; *p1 = 0; - return astring(buf); + return pstring(buf); } void netlist_parser::check_char(char ctocheck) diff --git a/src/emu/netlist/nl_parser.h b/src/emu/netlist/nl_parser.h index 79b3882ac37..892c167c660 100644 --- a/src/emu/netlist/nl_parser.h +++ b/src/emu/netlist/nl_parser.h @@ -19,15 +19,15 @@ public: void parse(char *buf); void net_alias(); void netdev_param(); - void netdev_const(const astring &dev_name); - void netdev_device(const astring &dev_type); + void netdev_const(const pstring &dev_name); + void netdev_device(const pstring &dev_type); private: void skipeol(); void skipws(); - astring getname(char sep); - astring getname2(char sep1, char sep2); + pstring getname(char sep); + pstring getname2(char sep1, char sep2); void check_char(char ctocheck); double eval_param(); diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index d5c0d566f3c..d2786cd8730 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -41,13 +41,17 @@ static void tagmap_free_entries(T &tm) netlist_setup_t::~netlist_setup_t() { tagmap_free_entries(m_devices); - tagmap_free_entries(m_links); - tagmap_free_entries(m_alias); + //tagmap_free_entries(m_links); + //tagmap_free_entries(m_alias); + m_links.reset(); + m_alias.reset(); m_params.reset(); m_terminals.reset(); + m_params_temp.reset(); + pstring::resetmem(); } -netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const astring &name) +netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const pstring &name) { if (!(m_devices.add(name, dev, false)==TMERR_NONE)) fatalerror("Error adding %s to device list\n", name.cstr()); @@ -55,13 +59,14 @@ netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const ast } template -static void remove_start_with(T &hm, astring &sw) +static void remove_start_with(T &hm, pstring &sw) { typename T::entry_t *entry = hm.first(); while (entry != NULL) { typename T::entry_t *next = hm.next(entry); - if (sw.cmpsubstr(entry->tag(), 0, sw.len()) == 0) + pstring x = entry->tag().cstr(); + if (sw.equals(x.substr(0, sw.len()))) { NL_VERBOSE_OUT(("removing %s\n", entry->tag().cstr())); hm.remove(entry->object()); @@ -70,15 +75,13 @@ static void remove_start_with(T &hm, astring &sw) } } -void netlist_setup_t::remove_dev(const astring &name) +void netlist_setup_t::remove_dev(const pstring &name) { netlist_device_t *dev = m_devices.find(name); - astring temp = name; + pstring temp = name + "."; if (dev == NULL) fatalerror("Device %s does not exist\n", name.cstr()); - temp.cat("."); - //remove_start_with(m_inputs, temp); remove_start_with(m_terminals, temp); remove_start_with(m_params, temp); @@ -87,14 +90,14 @@ void netlist_setup_t::remove_dev(const astring &name) while (p != NULL) { tagmap_link_t::entry_t *n = m_links.next(p); - if (temp.cmpsubstr(p->object()->e1,0,temp.len()) == 0 || temp.cmpsubstr(p->object()->e2,0,temp.len()) == 0) + if (temp.equals(p->object().e1.substr(0,temp.len())) || temp.equals(p->object().e2.substr(0,temp.len()))) m_links.remove(p->object()); p = n; } m_devices.remove(name); } -void netlist_setup_t::register_callback(const astring &devname, netlist_output_delegate delegate) +void netlist_setup_t::register_callback(const pstring &devname, netlist_output_delegate delegate) { NETLIB_NAME(analog_callback) *dev = (NETLIB_NAME(analog_callback) *) m_devices.find(devname); if (dev == NULL) @@ -102,13 +105,14 @@ void netlist_setup_t::register_callback(const astring &devname, netlist_output_d dev->register_callback(delegate); } -void netlist_setup_t::register_alias(const astring &alias, const astring &out) +void netlist_setup_t::register_alias(const pstring &alias, const pstring &out) { - if (!(m_alias.add(alias, new astring(out), false)==TMERR_NONE)) + //if (!(m_alias.add(alias, new nstring(out), false)==TMERR_NONE)) + if (!(m_alias.add(alias, out, false)==TMERR_NONE)) fatalerror("Error adding alias %s to alias list\n", alias.cstr()); } -astring netlist_setup_t::objtype_as_astr(netlist_object_t &in) +pstring netlist_setup_t::objtype_as_astr(netlist_object_t &in) { switch (in.type()) { @@ -134,7 +138,7 @@ astring netlist_setup_t::objtype_as_astr(netlist_object_t &in) fatalerror("Unknown object type %d\n", in.type()); } -void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state) +void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state) { switch (obj.type()) { @@ -157,17 +161,16 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device break; case netlist_terminal_t::PARAM: { + netlist_param_t ¶m = dynamic_cast(obj); - astring temp = param.netdev().name(); - temp.cat("."); - temp.cat(name); - const astring *val = m_params_temp.find(temp); - if (val != NULL) + pstring temp = param.netdev().name() + "." + name; + const pstring val = m_params_temp.find(temp); + if (val != "") { //printf("Found parameter ... %s : %s\n", temp.cstr(), val->cstr()); double vald = 0; - if (sscanf(val->cstr(), "%lf", &vald) != 1) - fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val->cstr()); + if (sscanf(val.cstr(), "%lf", &vald) != 1) + fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr()); param.initial(vald); } if (!(m_params.add(temp, ¶m, false)==TMERR_NONE)) @@ -179,52 +182,52 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device } } -void netlist_setup_t::register_link(const astring &sin, const astring &sout) +void netlist_setup_t::register_link(const pstring &sin, const pstring &sout) { - link_t *temp = new link_t(sin, sout); + link_t temp = link_t(sin, sout); NL_VERBOSE_OUT(("link %s <== %s\n", sin.cstr(), sout.cstr())); - if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE)) - fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr()); + m_links.add(temp); + //if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE)) + // fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr()); } -void netlist_setup_t::register_param(const astring ¶m, const double value) +void netlist_setup_t::register_param(const pstring ¶m, const double value) { // FIXME: there should be a better way - astring temp; - temp.printf("%.9e", value); - register_param(param, temp); + register_param(param, pstring::sprintf("%.9e", value)); } -void netlist_setup_t::register_param(const astring ¶m, const astring &value) +void netlist_setup_t::register_param(const pstring ¶m, const pstring &value) { - if (!(m_params_temp.add(param, new astring(value), false)==TMERR_NONE)) + //if (!(m_params_temp.add(param, new nstring(value), false)==TMERR_NONE)) + if (!(m_params_temp.add(param, value, false)==TMERR_NONE)) fatalerror("Error adding parameter %s to parameter list\n", param.cstr()); } -const astring netlist_setup_t::resolve_alias(const astring &name) const +const pstring netlist_setup_t::resolve_alias(const pstring &name) const { - const astring *temp = m_alias.find(name); - astring ret = name; - if (temp != NULL) - ret = *temp; + const pstring temp = m_alias.find(name); + pstring ret = name; + if (temp != "") + ret = temp; int p = ret.find(".["); if (p > 0) { - astring dname = ret; + pstring dname = ret; netlist_device_t *dev = m_devices.find(dname.substr(0,p)); if (dev == NULL) fatalerror("Device for %s not found\n", name.cstr()); - ret.substr(p+2,ret.len()-p-3); - int c = atoi(ret); - ret = dev->name() + "." + *(dev->m_terminals.item(c)); + int c = atoi(ret.substr(p+2,ret.len()-p-3)); + ret = dev->name() + "." + dev->m_terminals.item(c)->object(); } + //printf("%s==>%s\n", name.cstr(), ret.cstr()); return ret; } -netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in) +netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in) { - const astring &tname = resolve_alias(terminal_in); + const pstring &tname = resolve_alias(terminal_in); netlist_terminal_t *ret; ret = dynamic_cast(m_terminals.find(tname)); @@ -232,8 +235,7 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in) if (ret == NULL) { /* look for ".Q" std output */ - astring s = tname; - s.cat(".Q"); + pstring s = tname + ".Q"; ret = dynamic_cast(m_terminals.find(s)); } if (ret == NULL) @@ -242,9 +244,9 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in) return *ret; } -netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, netlist_object_t::type_t atype) +netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in, netlist_object_t::type_t atype) { - const astring &tname = resolve_alias(terminal_in); + const pstring &tname = resolve_alias(terminal_in); netlist_terminal_t *ret; ret = dynamic_cast(m_terminals.find(tname)); @@ -252,8 +254,7 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, n if (ret == NULL && atype == netlist_object_t::OUTPUT) { /* look for ".Q" std output */ - astring s = tname; - s.cat(".Q"); + pstring s = tname + ".Q"; ret = dynamic_cast(m_terminals.find(s)); } if (ret == NULL) @@ -264,9 +265,9 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, n return *ret; } -netlist_param_t &netlist_setup_t::find_param(const astring ¶m_in) +netlist_param_t &netlist_setup_t::find_param(const pstring ¶m_in) { - const astring &outname = resolve_alias(param_in); + const pstring &outname = resolve_alias(param_in); netlist_param_t *ret; ret = m_params.find(outname); @@ -282,10 +283,10 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC)) { nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(in); - astring x = ""; - x.printf("proxy_ad_%d", m_proxy_cnt++); + pstring x = pstring::sprintf("proxy_ad_%d", m_proxy_cnt); + m_proxy_cnt++; - proxy->init(*this, x.cstr()); + proxy->init(*this, x); register_dev(proxy, x); proxy->m_Q.net().register_con(in); @@ -296,9 +297,10 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t { //printf("here 1\n"); nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out); - astring x = ""; - x.printf("proxy_da_%d", m_proxy_cnt++); - proxy->init(*this, x.cstr()); + pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt); + m_proxy_cnt++; + + proxy->init(*this, x); register_dev(proxy, x); proxy->m_Q.net().register_con(in); @@ -320,9 +322,10 @@ void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_i { NL_VERBOSE_OUT(("connect_terminal_input: connecting proxy\n")); nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(inp); - astring x = ""; - x.printf("proxy_da_%d", m_proxy_cnt++); - proxy->init(*this, x.cstr()); + pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt); + m_proxy_cnt++; + + proxy->init(*this, x); register_dev(proxy, x); connect_terminals(term, proxy->m_I); @@ -355,9 +358,10 @@ void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_ou { NL_VERBOSE_OUT(("connect_terminal_output: connecting proxy\n")); nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out); - astring x = ""; - x.printf("proxy_da_%d", m_proxy_cnt++); - proxy->init(*this, x.cstr()); + pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt); + m_proxy_cnt++; + + proxy->init(*this, x); register_dev(proxy, x); out.net().register_con(proxy->m_I); @@ -426,8 +430,8 @@ void netlist_setup_t::resolve_inputs(void) NL_VERBOSE_OUT(("Resolving ...\n")); for (tagmap_link_t::entry_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry)) { - const astring t1s = entry->object()->e1; - const astring t2s = entry->object()->e2; + const pstring t1s = entry->object().e1; + const pstring t2s = entry->object().e2; netlist_terminal_t &t1 = find_terminal(t1s); netlist_terminal_t &t2 = find_terminal(t2s); @@ -490,7 +494,7 @@ void netlist_setup_t::start_devices(void) for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) { netlist_device_t *dev = entry->object(); - dev->init(*this, entry->tag()); + dev->init(*this, entry->tag().cstr()); } } @@ -518,7 +522,7 @@ void netlist_setup_t::parse(char *buf) void netlist_setup_t::print_stats() { - if (NL_KEEP_STATISTICS) +#if (NL_KEEP_STATISTICS) { for (netlist_setup_t::tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) { @@ -530,4 +534,5 @@ void netlist_setup_t::print_stats() printf("Queue Sort %15d\n", m_netlist.queue().m_prof_sort); printf("Queue Move %15d\n", m_netlist.queue().m_prof_sortmove); } +#endif } diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index de8452c3806..ba4b5ad3d13 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -68,42 +68,53 @@ public: struct link_t { - link_t(const astring &ae1, const astring &ae2) + link_t() { } + // Copy constructor + link_t(const link_t &from) + { + e1 = from.e1; + e2 = from.e2; + } + + link_t(const pstring &ae1, const pstring &ae2) { e1 = ae1; e2 = ae2; } - astring e1; - astring e2; + pstring e1; + pstring e2; + + bool operator==(const link_t &rhs) const { return (e1 == rhs.e1) && (e2 == rhs.e2); } + link_t &operator=(const link_t &rhs) { e1 = rhs.e1; e2 = rhs.e2; return *this; } }; typedef tagmap_t tagmap_devices_t; - typedef tagmap_t tagmap_link_t; - typedef tagmap_t tagmap_astring_t; + typedef tagmap_t tagmap_nstring_t; typedef tagmap_t tagmap_param_t; typedef tagmap_t tagmap_terminal_t; + typedef netlist_list_t tagmap_link_t; netlist_setup_t(netlist_base_t &netlist); ~netlist_setup_t(); netlist_base_t &netlist() { return m_netlist; } - netlist_device_t *register_dev(netlist_device_t *dev, const astring &name); - void remove_dev(const astring &name); + netlist_device_t *register_dev(netlist_device_t *dev, const pstring &name); + void remove_dev(const pstring &name); - void register_alias(const astring &alias, const astring &out); - void register_link(const astring &sin, const astring &sout); - void register_param(const astring ¶m, const astring &value); - void register_param(const astring ¶m, const double value); + void register_alias(const pstring &alias, const pstring &out); + void register_link(const pstring &sin, const pstring &sout); + void register_param(const pstring ¶m, const pstring &value); + void register_param(const pstring ¶m, const double value); - void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state); + void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state); - netlist_terminal_t &find_terminal(const astring &outname_in); - netlist_terminal_t &find_terminal(const astring &outname_in, netlist_object_t::type_t atype); + netlist_terminal_t &find_terminal(const pstring &outname_in); + netlist_terminal_t &find_terminal(const pstring &outname_in, netlist_object_t::type_t atype); - netlist_param_t &find_param(const astring ¶m_in); + netlist_param_t &find_param(const pstring ¶m_in); - void register_callback(const astring &devname, netlist_output_delegate delegate); + void register_callback(const pstring &devname, netlist_output_delegate delegate); void parse(char *buf); @@ -123,10 +134,10 @@ private: netlist_base_t &m_netlist; tagmap_devices_t m_devices; - tagmap_astring_t m_alias; + tagmap_nstring_t m_alias; tagmap_param_t m_params; - tagmap_link_t m_links; - tagmap_astring_t m_params_temp; + tagmap_link_t m_links; + tagmap_nstring_t m_params_temp; int m_proxy_cnt; @@ -136,9 +147,9 @@ private: void connect_terminal_input(netlist_terminal_t &term, netlist_input_t &inp); // helpers - astring objtype_as_astr(netlist_object_t &in); + pstring objtype_as_astr(netlist_object_t &in); - const astring resolve_alias(const astring &name) const; + const pstring resolve_alias(const pstring &name) const; }; #endif /* NLSETUP_H_ */ diff --git a/src/emu/netlist/nl_time.h b/src/emu/netlist/nl_time.h index 61b8ebfea6f..2935e35e6af 100644 --- a/src/emu/netlist/nl_time.h +++ b/src/emu/netlist/nl_time.h @@ -26,50 +26,50 @@ struct netlist_time { public: - typedef UINT64 INTERNALTYPE; + typedef UINT64 INTERNALTYPE; - static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES; + static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES; - ATTR_HOT inline netlist_time() : m_time(0) {} + ATTR_HOT inline netlist_time() : m_time(0) {} - ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor); + ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor); ATTR_HOT friend inline const UINT32 operator/(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right); - ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right); - ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } - ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; } + ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } + ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; } - ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; } + ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; } ATTR_HOT inline const double as_double() const { return (double) m_time / (double) RESOLUTION; } - ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); } - ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); } - ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); } - ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); } - ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); } + ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); } + ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); } + ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); } + ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); } + ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); } - static const netlist_time zero; + static const netlist_time zero; protected: - ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {} + ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {} - INTERNALTYPE m_time; + INTERNALTYPE m_time; }; ATTR_HOT inline const netlist_time operator-(const netlist_time &left, const netlist_time &right) { - return netlist_time::from_raw(left.m_time - right.m_time); + return netlist_time::from_raw(left.m_time - right.m_time); } ATTR_HOT inline const netlist_time operator*(const netlist_time &left, const UINT32 factor) { - return netlist_time::from_raw(left.m_time * factor); + return netlist_time::from_raw(left.m_time * factor); } ATTR_HOT inline const UINT32 operator/(const netlist_time &left, const netlist_time &right) @@ -79,27 +79,27 @@ ATTR_HOT inline const UINT32 operator/(const netlist_time &left, const netlist_t ATTR_HOT inline const netlist_time operator+(const netlist_time &left, const netlist_time &right) { - return netlist_time::from_raw(left.m_time + right.m_time); + return netlist_time::from_raw(left.m_time + right.m_time); } ATTR_HOT inline bool operator<(const netlist_time &left, const netlist_time &right) { - return (left.m_time < right.m_time); + return (left.m_time < right.m_time); } ATTR_HOT inline bool operator>(const netlist_time &left, const netlist_time &right) { - return (left.m_time > right.m_time); + return (left.m_time > right.m_time); } ATTR_HOT inline bool operator<=(const netlist_time &left, const netlist_time &right) { - return (left.m_time <= right.m_time); + return (left.m_time <= right.m_time); } ATTR_HOT inline bool operator>=(const netlist_time &left, const netlist_time &right) { - return (left.m_time >= right.m_time); + return (left.m_time >= right.m_time); } diff --git a/src/emu/netlist/pstring.c b/src/emu/netlist/pstring.c new file mode 100644 index 00000000000..e23718a16a9 --- /dev/null +++ b/src/emu/netlist/pstring.c @@ -0,0 +1,218 @@ +/* + * nl_string.c + * + */ + +#include "pstring.h" +#include + +//nstring::str_t *nstring::m_zero = NULL; +pstring::str_t *pstring::m_zero = pstring::salloc(0); +pstring::memblock *pstring::m_first = NULL; + +#define IMMEDIATE_MODE (1) +#define DEBUG_MODE (0) + +pstring::~pstring() +{ + sfree(m_ptr); +} + +void pstring::init() +{ + if (m_zero == NULL) + { + m_zero = (str_t *) alloc_str(sizeof(str_t) + 1); + m_zero->reference_count = 1; + m_zero->m_len = 0; + m_zero->m_str[0] = 0; + } + m_ptr = m_zero; + m_ptr->reference_count++; +} + +void pstring::pcat(const char *s) +{ + int slen = strlen(s); + str_t *n = salloc(m_ptr->len() + slen); + if (m_ptr->len() > 0) + memcpy(n->str(), m_ptr->str(), m_ptr->len()); + if (slen > 0) + memcpy(n->str() + m_ptr->len(), s, slen); + *(n->str() + n->len()) = 0; + sfree(m_ptr); + m_ptr = n; +} + +void pstring::pcopy(const char *from, int size) +{ + str_t *n = salloc(size); + if (size > 0) + memcpy(n->str(), from, size); + *(n->str() + size) = 0; + sfree(m_ptr); + m_ptr = n; +} + +pstring pstring::substr(unsigned int start, int count) const +{ + int alen = len(); + if (start >= alen) + return pstring(); + if (count <0 || start + count > alen) + count = alen - start; + pstring ret; + ret.pcopy(cstr() + start, count); + return ret; +} + +pstring pstring::vprintf(va_list args) const +{ + // sprintf into the temporary buffer + char tempbuf[4096]; + vsprintf(tempbuf, cstr(), args); + + return pstring(tempbuf); +} + +// ---------------------------------------------------------------------------------------- +// static stuff ... +// ---------------------------------------------------------------------------------------- + +void pstring::sfree(str_t *s) +{ + s->reference_count--; + if (s->reference_count == 0) + dealloc_str(s); +} + +pstring::str_t *pstring::salloc(int n) +{ + str_t *ret = (str_t *) alloc_str(sizeof(str_t) + n + 1); + ret->reference_count = 1; + ret->m_len = n; + ret->m_str[0] = 0; + return ret; + //std::printf("old string %d <%s> %p %p\n", n, old, old, m_ptr); +} + +pstring pstring::sprintf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + pstring ret = pstring(format).vprintf(ap); + va_end(ap); + return ret; +} + +char *pstring::alloc_str(int n) +{ +#if (IMMEDIATE_MODE) + return (char *) malloc(n); +#else +#if (DEBUG_MODE) + int min_alloc = MAX(0, n+sizeof(memblock)); +#else + int min_alloc = MAX(8192, n+sizeof(memblock)); +#endif + char *ret = NULL; + + //std::printf("m_first %p\n", m_first); + for (memblock *p = m_first; p != NULL && ret == NULL; p = p->next) + { + if (p->remaining > n) + { + ret = p->cur; + p->cur += n; + p->allocated += 1; + p->remaining -= n; + } + } + + if (ret == NULL) + { + // need to allocate a new block + memblock *p = (memblock *) malloc(min_alloc); //new char[min_alloc]; + p->allocated = 0; + p->cur = &p->data[0]; + p->size = p->remaining = min_alloc - sizeof(memblock); + p->next = m_first; + //std::printf("allocated block size %d\n", p->size); + + ret = p->cur; + p->cur += n; + p->allocated += 1; + p->remaining -= n; + + m_first = p; + } + + return ret; +#endif +} + +void pstring::dealloc_str(void *ptr) +{ +#if (IMMEDIATE_MODE) + free(ptr); +#else + for (memblock *p = m_first; p != NULL; p = p->next) + { + if (ptr >= &p->data[0] && ptr < &p->data[p->size]) + { + p->allocated -= 1; + if (p->allocated < 0) + fatalerror("nstring: memory corruption\n"); + if (p->allocated == 0) + { + //std::printf("Block entirely freed\n"); + p->remaining = p->size; + p->cur = &p->data[0]; + } + // shutting down ? + if (m_zero == NULL) + resetmem(); // try to free blocks + return; + } + } + fatalerror("nstring: string <%p> not found\n", ptr); +#endif +} + +void pstring::resetmem() +{ +#if (IMMEDIATE_MODE) +#else + memblock **p = &m_first; + int totalblocks = 0; + int freedblocks = 0; + + // Release the 0 string + if (m_zero != NULL) sfree(m_zero); + m_zero = NULL; + + while (*p != NULL) + { + totalblocks++; + memblock **next = &((*p)->next); + if ((*p)->allocated == 0) + { + //std::printf("freeing block %p\n", *p); + memblock *freeme = *p; + *p = *next; + free(freeme); //delete[] *p; + freedblocks++; + } + else + { +#if (DEBUG_MODE) + std::printf("Allocated: <%s>\n", ((str_t *)(&(*p)->data[0]))->str()); +#endif + p = next; + } + } +#if (DEBUG_MODE) + std::printf("Freed %d out of total %d blocks\n", freedblocks, totalblocks); +#endif +#endif +} diff --git a/src/emu/netlist/pstring.h b/src/emu/netlist/pstring.h new file mode 100644 index 00000000000..0481b381c35 --- /dev/null +++ b/src/emu/netlist/pstring.h @@ -0,0 +1,164 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * pstring.h + */ + +#ifndef _PSTRING_H_ +#define _PSTRING_H_ + +#include "nl_config.h" + +// ---------------------------------------------------------------------------------------- +// nstring: immutable strings ... +// +// nstrings are just a pointer to a "pascal-style" string representation. +// It uses reference counts and only uses new memory when a string changes. +// ---------------------------------------------------------------------------------------- + +struct pstring +{ +public: + // simple construction/destruction + pstring() + { + init(); + } + ~pstring(); + + // construction with copy + pstring(const char *string) {init(); if (string != NULL) pcopy(string); } + pstring(const pstring &string) {init(); pcopy(string); } + + // assignment operators + pstring &operator=(const char *string) { pcopy(string); return *this; } + pstring &operator=(const pstring &string) { pcopy(string); return *this; } + + // C string conversion operators and helpers + operator const char *() const { return m_ptr->str(); } + inline const char *cstr() const { return m_ptr->str(); } + + // concatenation operators + pstring& operator+=(const pstring &string) { pcat(string.cstr()); return *this; } + friend pstring operator+(const pstring &lhs, const pstring &rhs) { return pstring(lhs) += rhs; } + friend pstring operator+(const pstring &lhs, const char *rhs) { return pstring(lhs) += rhs; } + friend pstring operator+(const char *lhs, const pstring &rhs) { return pstring(lhs) += rhs; } + + // comparison operators + bool operator==(const char *string) const { return (pcmp(string) == 0); } + bool operator==(const pstring &string) const { return (pcmp(string.cstr()) == 0); } + bool operator!=(const char *string) const { return (pcmp(string) != 0); } + bool operator!=(const pstring &string) const { return (pcmp(string.cstr()) != 0); } + bool operator<(const char *string) const { return (pcmp(string) < 0); } + bool operator<(const pstring &string) const { return (pcmp(string.cstr()) < 0); } + bool operator<=(const char *string) const { return (pcmp(string) <= 0); } + bool operator<=(const pstring &string) const { return (pcmp(string.cstr()) <= 0); } + bool operator>(const char *string) const { return (pcmp(string) > 0); } + bool operator>(const pstring &string) const { return (pcmp(string.cstr()) > 0); } + bool operator>=(const char *string) const { return (pcmp(string) >= 0); } + bool operator>=(const pstring &string) const { return (pcmp(string.cstr()) >= 0); } + + // + inline const int len() const { return m_ptr->len(); } + + inline bool equals(const pstring &string) { return (pcmp(string.cstr(), m_ptr->str()) == 0); } + int cmp(pstring &string) { return pcmp(string.cstr()); } + + int find(const char *search, int start = 0) const + { + int alen = len(); + const char *result = strstr(cstr() + MIN(start, alen), search); + return (result != NULL) ? (result - cstr()) : -1; + } + + // various + + bool startsWith(pstring &arg) { return (pcmp(cstr(), arg.cstr(), arg.len()) == 0); } + bool startsWith(const char *arg) { return (pcmp(cstr(), arg, strlen(arg)) == 0); } + + // these return nstring ... + pstring cat(const pstring &s) const { return *this + s; } + pstring cat(const char *s) const { return *this + s; } + + pstring substr(unsigned int start, int count = -1) const ; + + pstring left(unsigned int count) const { return substr(0, count); } + pstring right(unsigned int count) const { return substr(len() - count, count); } + + // printf using string as format ... + + pstring vprintf(va_list args) const; + + // static + static pstring sprintf(const char *format, ...); + static void resetmem(); + +protected: + + struct str_t + { + int reference_count; + char *str() { return &m_str[0]; } + int len() { return m_len; } + //private: + int m_len; + char m_str[]; + }; + + str_t *m_ptr; + +private: + void init(); + + inline int pcmp(const char *right) const + { + return pcmp(m_ptr->str(), right); + } + + inline int pcmp(const char *left, const char *right, int count = -1) const + { + if (count < 0) + return strcmp(left, right); + else + return strncmp(left, right, count); + } + + void pcopy(const char *from, int size); + + inline void pcopy(const char *from) + { + pcopy(from, strlen(from)); + } + + inline void pcopy(const pstring &from) + { + sfree(m_ptr); + m_ptr = from.m_ptr; + m_ptr->reference_count++; + } + + void pcat(const char *s); + + static str_t *m_zero; + + static str_t *salloc(int n); + static void sfree(str_t *s); + + struct memblock + { + memblock *next; + int size; + int allocated; + int remaining; + char *cur; + char data[]; + }; + + static memblock *m_first; + static char *alloc_str(int n); + static void dealloc_str(void *ptr); +}; + + +#endif /* _PSTRING_H_ */ +