diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index dd8fa0c400e..c04d07cb4e6 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -136,27 +136,6 @@ device_t *setup_t::register_dev(const pstring &classname, const pstring &name) } } -void setup_t::remove_dev(const pstring &name) -{ - device_t *dev = netlist().m_devices.find_by_name(name); - pstring temp = name + "."; - if (dev == NULL) - netlist().error("Device %s does not exist\n", name.cstr()); - - remove_start_with(m_terminals, temp); - remove_start_with(m_params, temp); - - const link_t *p = m_links.data(); - while (p != NULL) - { - const link_t *n = p+1; - if (temp.equals(p->e1.substr(0,temp.len())) || temp.equals(p->e2.substr(0,temp.len()))) - m_links.remove(*p); - p = n; - } - netlist().m_devices.remove_by_name(name); -} - void setup_t::register_model(const pstring &model) { m_models.add(model); @@ -164,7 +143,7 @@ void setup_t::register_model(const pstring &model) void setup_t::register_alias_nofqn(const pstring &alias, const pstring &out) { - if (!(m_alias.add(link_t(alias, out), false)==true)) + if (!m_alias.add(alias, out)) netlist().error("Error adding alias %s to alias list\n", alias.cstr()); } @@ -266,9 +245,9 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj) { param_t ¶m = dynamic_cast(obj); //printf("name: %s\n", name.cstr()); - const pstring val = m_params_temp.find_by_name(name).e2; - if (val != "") + if (m_params_temp.contains(name)) { + const pstring val = m_params_temp[name]; switch (param.param_type()) { case param_t::DOUBLE: @@ -302,7 +281,7 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj) netlist().error("Parameter is not supported %s : %s\n", name.cstr(), val.cstr()); } } - if (!(m_params.add(¶m, false)==true)) + if (!m_params.add(param.name(), ¶m)) netlist().error("Error adding parameter %s to parameter list\n", name.cstr()); } break; @@ -400,16 +379,16 @@ void setup_t::register_param(const pstring ¶m, const pstring &value) { pstring fqn = build_fqn(param); - int idx = m_params_temp.index_by_name(fqn); + int idx = m_params_temp.index_of(fqn); if (idx < 0) { - if (!(m_params_temp.add(link_t(fqn, value), false)==true)) + if (!m_params_temp.add(fqn, value)) netlist().error("Unexpected error adding parameter %s to parameter list\n", param.cstr()); } else { - netlist().warning("Overwriting %s old <%s> new <%s>\n", fqn.cstr(), m_params_temp[idx].e2.cstr(), value.cstr()); - m_params_temp[idx].e2 = value; + netlist().warning("Overwriting %s old <%s> new <%s>\n", fqn.cstr(), m_params_temp.value_at(idx).cstr(), value.cstr()); + m_params_temp[fqn] = value; } } @@ -421,7 +400,8 @@ const pstring setup_t::resolve_alias(const pstring &name) const /* FIXME: Detect endless loop */ do { ret = temp; - temp = m_alias.find_by_name(ret).e2; + int p = m_alias.index_of(ret); + temp = (p>=0 ? m_alias.value_at(p) : ""); } while (temp != ""); NL_VERBOSE_OUT(("%s==>%s\n", name.cstr(), ret.cstr())); @@ -480,14 +460,14 @@ param_t *setup_t::find_param(const pstring ¶m_in, bool required) const pstring param_in_fqn = build_fqn(param_in); const pstring &outname = resolve_alias(param_in_fqn); - param_t *ret; + int ret; - ret = m_params.find_by_name(outname); - if (ret == NULL && required) + ret = m_params.index_of(outname); + if (ret < 0 && required) netlist().error("parameter %s(%s) not found!\n", param_in_fqn.cstr(), outname.cstr()); - if (ret != NULL) + if (ret != -1) NL_VERBOSE_OUT(("Found parameter %s\n", outname.cstr())); - return ret; + return (ret == -1 ? NULL : m_params.value_at(ret)); } // FIXME avoid dynamic cast here diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index 51800f4c199..b5507904861 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -32,9 +32,6 @@ #define NET_REGISTER_DEV_X(_type, _name) \ setup.register_dev(# _type, # _name); -#define NET_REMOVE_DEV(_name) \ - setup.remove_dev(# _name); - #define NET_REGISTER_SIGNAL(_type, _name) \ NET_REGISTER_DEV(_type ## _ ## sig, _name) @@ -133,10 +130,8 @@ namespace netlist const pstring &name() const { return e1; } }; - typedef pnamedlist_t tagmap_nstring_t; - typedef pnamedlist_t tagmap_param_t; + //typedef pnamedlist_t tagmap_nstring_t; typedef pnamedlist_t tagmap_terminal_t; - typedef plist_t tagmap_link_t; setup_t(netlist_t *netlist); ~setup_t(); @@ -217,10 +212,11 @@ namespace netlist netlist_t *m_netlist; - tagmap_nstring_t m_alias; - tagmap_param_t m_params; - tagmap_link_t m_links; - tagmap_nstring_t m_params_temp; + phashmap_t m_alias; + phashmap_t m_params; + phashmap_t m_params_temp; + + plist_t m_links; factory_list_t *m_factory; @@ -245,6 +241,7 @@ namespace netlist const pstring resolve_alias(const pstring &name) const; devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out); +#if 0 template void remove_start_with(T &hm, pstring &sw) { @@ -258,6 +255,7 @@ namespace netlist } } } +#endif }; // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/plib/plists.h b/src/emu/netlist/plib/plists.h index 0430c5aebf6..ac92843b5b6 100644 --- a/src/emu/netlist/plib/plists.h +++ b/src/emu/netlist/plib/plists.h @@ -606,6 +606,146 @@ public: } }; +// ---------------------------------------------------------------------------------------- +// hashmap list +// ---------------------------------------------------------------------------------------- + + +template +struct phash_functor +{ + unsigned hash(const C &v) { return (unsigned) v; } +}; + +template <> +struct phash_functor +{ + unsigned hash(const pstring &v) + { + const char *string = v.cstr(); + unsigned result = *string++; + for (UINT8 c = *string++; c != 0; c = *string++) + result = (result*33) ^ c; + return result; + } +}; + +/* some primes 53, 97, 193, 389, 769, 1543, 3079, 6151 */ +template > +class phashmap_t +{ +public: + phashmap_t() : m_hash(389) + { + for (unsigned i=0; i= 0); + } + + int index_of(const K &key) const + { + return get_idx(key); + } + + unsigned size() const { return m_values.size(); } + + bool add(const K &key, const V &value) + { + H h; + const unsigned hash=h.hash(key); + const unsigned pos = hash % m_hash.size(); + if (m_hash[pos] == -1) + { + unsigned vpos = m_values.size(); + m_values.add(element_t(key, hash, value)); + m_hash[pos] = vpos; + } + else + { + int ep = m_hash[pos]; + + for (; ep != -1; ep = m_values[ep].m_next) + { + if (m_values[ep].m_hash == hash && m_values[ep].m_key == key ) + return false; /* duplicate */ + } + unsigned vpos = m_values.size(); + m_values.add(element_t(key, hash, value)); + m_values[vpos].m_next = m_hash[pos]; + m_hash[pos] = vpos; + } + return true; + } + + V& operator[](const K &key) + { + int p = get_idx(key); + if (p == -1) + { + p = m_values.size(); + add(key, V()); + } + return m_values[p].m_value; + } + + const V& operator[](const K &key) const + { + int p = get_idx(key); + if (p == -1) + { + p = m_values.size(); + add(key, V()); + } + return m_values[p].m_value; + } + + V& value_at(const unsigned pos) { return m_values[pos].m_value; } + const V& value_at(const unsigned pos) const { return m_values[pos].m_value; } + + V& key_at(const unsigned pos) const { return m_values[pos].m_key; } +private: + + int get_idx(const K &key) const + { + H h; + const unsigned hash=h.hash(key); + const unsigned pos = hash % m_hash.size(); + + for (int ep = m_hash[pos]; ep != -1; ep = m_values[ep].m_next) + { + if (m_values[ep].m_hash == hash && m_values[ep].m_key == key ) + return ep; + } + return -1; + } + + plist_t m_values; + parray_t m_hash; +}; + // ---------------------------------------------------------------------------------------- // sort a list ... slow, I am lazy // elements must support ">" operator. diff --git a/src/emu/netlist/plib/pstate.c b/src/emu/netlist/plib/pstate.c index 326eb13fe49..909bfcb2e58 100644 --- a/src/emu/netlist/plib/pstate.c +++ b/src/emu/netlist/plib/pstate.c @@ -75,3 +75,4 @@ template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state, m_save.add(p); state.register_state(*this, stname); } +