diff options
Diffstat (limited to 'src/emu/netlist/nl_parser.c')
-rw-r--r-- | src/emu/netlist/nl_parser.c | 213 |
1 files changed, 151 insertions, 62 deletions
diff --git a/src/emu/netlist/nl_parser.c b/src/emu/netlist/nl_parser.c index c7eb527d15a..efdac63c182 100644 --- a/src/emu/netlist/nl_parser.c +++ b/src/emu/netlist/nl_parser.c @@ -12,11 +12,13 @@ //#undef NL_VERBOSE_OUT //#define NL_VERBOSE_OUT(x) printf x +namespace netlist +{ // ---------------------------------------------------------------------------------------- // A netlist parser // ---------------------------------------------------------------------------------------- -ATTR_COLD void netlist_parser::verror(pstring msg, int line_num, pstring line) +ATTR_COLD void parser_t::verror(pstring msg, int line_num, pstring line) { m_setup.netlist().error("line %d: error: %s\n\t\t%s\n", line_num, msg.cstr(), line.cstr()); @@ -25,7 +27,7 @@ ATTR_COLD void netlist_parser::verror(pstring msg, int line_num, pstring line) } -bool netlist_parser::parse(const char *buf, const pstring nlname) +bool parser_t::parse(const char *buf, const pstring nlname) { ppreprocessor prepro; @@ -48,10 +50,14 @@ bool netlist_parser::parse(const char *buf, const pstring nlname) m_tok_comma = register_token(","); m_tok_ALIAS = register_token("ALIAS"); + m_tok_DIPPINS = register_token("DIPPINS"); m_tok_NET_C = register_token("NET_C"); + m_tok_FRONTIER = register_token("OPTIMIZE_FRONTIER"); m_tok_PARAM = register_token("PARAM"); m_tok_NET_MODEL = register_token("NET_MODEL"); m_tok_INCLUDE = register_token("INCLUDE"); + m_tok_LOCAL_SOURCE = register_token("LOCAL_SOURCE"); + m_tok_LOCAL_LIB_ENTRY = register_token("LOCAL_LIB_ENTRY"); m_tok_SUBMODEL = register_token("SUBMODEL"); m_tok_NETLIST_START = register_token("NETLIST_START"); m_tok_NETLIST_END = register_token("NETLIST_END"); @@ -59,6 +65,7 @@ bool netlist_parser::parse(const char *buf, const pstring nlname) m_tok_TRUTHTABLE_END = register_token("TRUTHTABLE_END"); m_tok_TT_HEAD = register_token("TT_HEAD"); m_tok_TT_LINE = register_token("TT_LINE"); + m_tok_TT_FAMILY = register_token("TT_FAMILY"); bool in_nl = false; @@ -100,7 +107,7 @@ bool netlist_parser::parse(const char *buf, const pstring nlname) } } -void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname) +void parser_t::parse_netlist(ATTR_UNUSED const pstring &nlname) { while (true) { @@ -114,8 +121,12 @@ void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname) if (token.is(m_tok_ALIAS)) net_alias(); + else if (token.is(m_tok_DIPPINS)) + dippins(); else if (token.is(m_tok_NET_C)) net_c(); + else if (token.is(m_tok_FRONTIER)) + frontier(); else if (token.is(m_tok_PARAM)) netdev_param(); else if (token.is(m_tok_NET_MODEL)) @@ -124,8 +135,15 @@ void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname) net_submodel(); else if (token.is(m_tok_INCLUDE)) net_include(); + else if (token.is(m_tok_LOCAL_SOURCE)) + net_local_source(); else if (token.is(m_tok_TRUTHTABLE_START)) net_truthtable_start(); + else if (token.is(m_tok_LOCAL_LIB_ENTRY)) + { + m_setup.register_lib_entry(get_identifier()); + require_token(m_tok_param_right); + } else if (token.is(m_tok_NETLIST_END)) { netdev_netlist_end(); @@ -136,7 +154,7 @@ void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname) } } -void netlist_parser::net_truthtable_start() +void parser_t::net_truthtable_start() { pstring name = get_identifier(); require_token(m_tok_comma); @@ -149,7 +167,7 @@ void netlist_parser::net_truthtable_start() pstring def_param = get_string(); require_token(m_tok_param_right); - netlist_base_factory_truthtable_t *ttd = nl_tt_factory_create(ni, no, hs, + netlist::devices::netlist_base_factory_truthtable_t *ttd = netlist::devices::nl_tt_factory_create(ni, no, hs, name, name, "+" + def_param); while (true) @@ -168,6 +186,12 @@ void netlist_parser::net_truthtable_start() ttd->m_desc.add(get_string()); require_token(m_tok_param_right); } + else if (token.is(m_tok_TT_FAMILY)) + { + require_token(m_tok_param_left); + ttd->m_family = netlist::logic_family_desc_t::from_model(m_setup.get_model_str(get_string())); + require_token(m_tok_param_right); + } else { require_token(token, m_tok_TRUTHTABLE_END); @@ -180,20 +204,20 @@ void netlist_parser::net_truthtable_start() } -void netlist_parser::netdev_netlist_start() +void parser_t::netdev_netlist_start() { // don't do much token_t name = get_token(); require_token(m_tok_param_right); } -void netlist_parser::netdev_netlist_end() +void parser_t::netdev_netlist_end() { // don't do much require_token(m_tok_param_right); } -void netlist_parser::net_model() +void parser_t::net_model() { // don't do much pstring model = get_string(); @@ -201,33 +225,52 @@ void netlist_parser::net_model() require_token(m_tok_param_right); } -void netlist_parser::net_submodel() +void parser_t::net_submodel() { // don't do much - pstring name = get_identifier(); - require_token(m_tok_comma); pstring model = get_identifier(); + require_token(m_tok_comma); + pstring name = get_identifier(); require_token(m_tok_param_right); m_setup.namespace_push(name); - netlist_parser subparser(m_setup); - subparser.parse(m_buf, model); + m_setup.include(model); m_setup.namespace_pop(); } -void netlist_parser::net_include() +void parser_t::frontier() +{ + // don't do much + pstring attachat = get_identifier(); + require_token(m_tok_comma); + double r_IN = eval_param(get_token()); + require_token(m_tok_comma); + double r_OUT = eval_param(get_token()); + require_token(m_tok_param_right); + + m_setup.register_frontier(attachat, r_IN, r_OUT); +} + +void parser_t::net_include() { // don't do much pstring name = get_identifier(); require_token(m_tok_param_right); - netlist_parser subparser(m_setup); - subparser.parse(m_buf, name); + m_setup.include(name); } -void netlist_parser::net_alias() +void parser_t::net_local_source() { - pstring alias = get_identifier(); + // This directive is only for hardcoded netlists. Ignore it here. + pstring name = get_identifier(); + require_token(m_tok_param_right); + +} + +void parser_t::net_alias() +{ + pstring alias = get_identifier_or_number(); require_token(m_tok_comma); @@ -239,7 +282,7 @@ void netlist_parser::net_alias() m_setup.register_alias(alias, out); } -void netlist_parser::net_c() +void parser_t::net_c() { pstring first = get_identifier(); require_token(m_tok_comma); @@ -258,69 +301,114 @@ void netlist_parser::net_c() } -void netlist_parser::netdev_param() +void parser_t::dippins() +{ + pstring_list_t pins; + + pins.add(get_identifier()); + require_token(m_tok_comma); + + while (true) + { + pstring t1 = get_identifier(); + pins.add(t1); + token_t n = get_token(); + if (n.is(m_tok_param_right)) + break; + if (!n.is(m_tok_comma)) + error("expected a comma, found <%s>", n.str().cstr()); + } + if ((pins.size() % 2) == 1) + error("You must pass an equal number of pins to DIPPINS"); + unsigned n = pins.size(); + for (unsigned i = 0; i < n / 2; i++) + { + m_setup.register_alias(pstring::sprintf("%d", i+1), pins[i*2]); + m_setup.register_alias(pstring::sprintf("%d", n-i), pins[i*2 + 1]); + } +} + +void parser_t::netdev_param() { pstring param; - nl_double val; param = get_identifier(); require_token(m_tok_comma); - val = eval_param(get_token()); + token_t tok = get_token(); + if (tok.is_type(STRING)) + { + NL_VERBOSE_OUT(("Parser: Param: %s %s\n", param.cstr(), tok.str().cstr())); + m_setup.register_param(param, tok.str()); + } + else + { + nl_double val = eval_param(tok); NL_VERBOSE_OUT(("Parser: Param: %s %f\n", param.cstr(), val)); m_setup.register_param(param, val); + } require_token(m_tok_param_right); } -void netlist_parser::device(const pstring &dev_type) +void parser_t::device(const pstring &dev_type) { - pstring devname; - netlist_base_factory_t *f = m_setup.factory().factory_by_name(dev_type, m_setup); - netlist_device_t *dev; - pstring_list_t termlist = f->term_param_list(); - pstring_list_t def_params = f->def_params(); - - std::size_t cnt; + if (m_setup.is_library_item(dev_type)) + { + pstring devname = get_identifier(); + m_setup.namespace_push(devname); + m_setup.include(dev_type); + m_setup.namespace_pop(); + require_token(m_tok_param_right); + } + else + { + base_factory_t *f = m_setup.factory().factory_by_name(dev_type, m_setup); + device_t *dev; + pstring_list_t termlist = f->term_param_list(); + pstring_list_t def_params = f->def_params(); - devname = get_identifier(); + std::size_t cnt; - dev = f->Create(); - m_setup.register_dev(dev, devname); + pstring devname = get_identifier(); - NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr())); + dev = f->Create(); + m_setup.register_dev(dev, devname); - cnt = 0; - while (cnt < def_params.size()) - { - pstring paramfq = devname + "." + def_params[cnt]; + NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr())); - NL_VERBOSE_OUT(("Defparam: %s\n", paramfq.cstr())); - require_token(m_tok_comma); - token_t tok = get_token(); - if (tok.is_type(STRING)) - { - m_setup.register_param(paramfq, tok.str()); - } - else + cnt = 0; + while (cnt < def_params.size()) { - nl_double val = eval_param(tok); - m_setup.register_param(paramfq, val); + pstring paramfq = devname + "." + def_params[cnt]; + + NL_VERBOSE_OUT(("Defparam: %s\n", paramfq.cstr())); + require_token(m_tok_comma); + token_t tok = get_token(); + if (tok.is_type(STRING)) + { + m_setup.register_param(paramfq, tok.str()); + } + else + { + nl_double val = eval_param(tok); + m_setup.register_param(paramfq, val); + } + cnt++; } - cnt++; - } - token_t tok = get_token(); - cnt = 0; - while (tok.is(m_tok_comma) && cnt < termlist.size()) - { - pstring output_name = get_identifier(); + token_t tok = get_token(); + cnt = 0; + while (tok.is(m_tok_comma) && cnt < termlist.size()) + { + pstring output_name = get_identifier(); - m_setup.register_link(devname + "." + termlist[cnt], output_name); + m_setup.register_link(devname + "." + termlist[cnt], output_name); - cnt++; - tok = get_token(); + cnt++; + tok = get_token(); + } + if (cnt != termlist.size()) + m_setup.netlist().error("netlist: input count mismatch for %s - expected %" SIZETFMT " found %" SIZETFMT "\n", devname.cstr(), SIZET_PRINTF(termlist.size()), SIZET_PRINTF(cnt)); + require_token(tok, m_tok_param_right); } - if (cnt != termlist.size()) - m_setup.netlist().error("netlist: input count mismatch for %s - expected %" SIZETFMT " found %" SIZETFMT "\n", devname.cstr(), termlist.size(), cnt); - require_token(tok, m_tok_param_right); } @@ -329,7 +417,7 @@ void netlist_parser::device(const pstring &dev_type) // ---------------------------------------------------------------------------------------- -nl_double netlist_parser::eval_param(const token_t tok) +nl_double parser_t::eval_param(const token_t tok) { static const char *macs[6] = {"", "RES_K", "RES_M", "CAP_U", "CAP_N", "CAP_P"}; static nl_double facs[6] = {1, 1e3, 1e6, 1e-6, 1e-9, 1e-12}; @@ -377,3 +465,4 @@ nl_double netlist_parser::eval_param(const token_t tok) return ret * facs[f]; #endif } +} |