diff --git a/nl_examples/opamp.c b/nl_examples/opamp.c index 57daf960e9c..07d7df47135 100644 --- a/nl_examples/opamp.c +++ b/nl_examples/opamp.c @@ -6,6 +6,45 @@ #include "netlist/devices/net_lib.h" +NETLIST_START(main) + + /* Standard stuff */ + + CLOCK(clk, 1000) // 1000 Hz + SOLVER(Solver, 48000) + //PARAM(Solver.ACCURACY, 1e-3) + //PARAM(Solver.CONVERG, 1.0) + //PARAM(Solver.RESCHED_LOOPS, 30) + + /* Opamp wired as impedance changer */ + SUBMODEL(op, opamp) + + NET_C(op.GND, GND) + NET_C(op.PLUS, clk) + NET_C(op.MINUS, op.OUT) + + SUBMODEL(op1, opamp) + /* Wired as inverting amplifier connected to output of first opamp */ + + RES(R1, 100000) + RES(R2, 200000) + + NET_C(op1.GND, GND) + NET_C(op1.PLUS, GND) + NET_C(op1.MINUS, R2.2) + NET_C(op1.MINUS, R1.2) + + NET_C(op.OUT, R1.1) + NET_C(op1.OUT, R2.1) + + RES(RL, 1000) + NET_C(RL.2, GND) + NET_C(RL.1, op1.OUT) + + //LOG(logX, op1.OUT) + //LOG(logY, clk) +NETLIST_END() + NETLIST_START(opamp) /* Opamp model from @@ -14,19 +53,15 @@ NETLIST_START(opamp) * * Bandwidth 10Mhz * - * This one is connected as a impedance changer */ - /* Standard stuff */ + /* Terminal definitions for calling netlists */ - CLOCK(clk, 1000) // 1000 Hz - SOLVER(Solver, 48000) - PARAM(Solver.ACCURACY, 1e-6) + ALIAS(PLUS, G1.IP) // Positive input + ALIAS(MINUS, G1.IN) // Negative input + ALIAS(OUT, EBUF.OP) // Opamp output ... - /* Wiring up the opamp */ - - NET_C(PLUS, clk) - NET_C(MINUS, OUT) + ALIAS(GND, EBUF.ON) // GND terminal /* The opamp model */ @@ -38,11 +73,7 @@ NETLIST_START(opamp) PARAM(EBUF.RO, 50) PARAM(EBUF.G, 1) - ALIAS(PLUS, G1.IP) // Positive input - ALIAS(MINUS, G1.IN) // Negative input - ALIAS(OUT, EBUF.OP) // Opamp output ... - - NET_C(EBUF.ON, GND) +// NET_C(EBUF.ON, GND) NET_C(G1.ON, GND) NET_C(RP1.2, GND) @@ -53,10 +84,4 @@ NETLIST_START(opamp) NET_C(CP1.1, RP1.1) NET_C(EBUF.IP, RP1.1) - RES(RL, 1000) - NET_C(RL.2, GND) - NET_C(RL.1, OUT) - - //LOG(logX, OUT) - //LOG(logY, clk) NETLIST_END() diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index e6acdea8be2..8f9ee0e53b1 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -118,7 +118,7 @@ void netlist_matrix_solver_t::schedule() } else { - //m_owner->netlist().warning("Matrix solver reschedule .. Consider increasing RESCHED_LOOPS"); + m_owner->netlist().warning("Matrix solver reschedule .. Consider increasing RESCHED_LOOPS"); if (m_owner != NULL) this->m_owner->schedule(); } @@ -167,6 +167,7 @@ ATTR_HOT inline bool netlist_matrix_solver_t::solve() else { resched_cnt = solve_non_dynamic(); + //printf("resched_cnt %d %d\n", resched_cnt, m_resched_loops); } return (resched_cnt >= m_resched_loops); } @@ -750,7 +751,7 @@ NETLIB_UPDATE(solver) if (global_resched) { - //netlist().warning("Gobal reschedule .. Consider increasing RESCHED_LOOPS"); + netlist().warning("Gobal reschedule .. Consider increasing RESCHED_LOOPS"); schedule(); } else diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h index 740ec26c0e7..0618a5f6f0b 100644 --- a/src/emu/netlist/analog/nld_solver.h +++ b/src/emu/netlist/analog/nld_solver.h @@ -120,6 +120,9 @@ public: ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner) { netlist_matrix_solver_t::setup(nets, owner); + m_fallback.m_accuracy = m_accuracy; + m_fallback.m_convergence_factor = m_convergence_factor; + m_fallback.m_resched_loops = m_resched_loops; m_fallback.setup(nets, owner); } diff --git a/src/emu/netlist/nl_lists.h b/src/emu/netlist/nl_lists.h index 0c4d0f89ca1..40d08fc1011 100644 --- a/src/emu/netlist/nl_lists.h +++ b/src/emu/netlist/nl_lists.h @@ -92,6 +92,16 @@ public: } } + ATTR_HOT inline void remove_at(const int pos) + { + assert((pos>=0) && (pos +class netlist_stack_t +{ +public: + + ATTR_COLD netlist_stack_t(int numElements = _NumElem) + : m_list(numElements) + { + } + + ATTR_COLD netlist_stack_t(const netlist_stack_t &rhs) + : m_list(rhs.m_list) + { + } + + ATTR_COLD netlist_stack_t &operator=(const netlist_stack_t &rhs) + { + m_list = rhs.m_list; + return *this; + } + + + ATTR_COLD ~netlist_stack_t() + { + } + + ATTR_HOT inline void push(const _StackClass &elem) + { + m_list.add(elem); + } + + ATTR_HOT inline _StackClass peek() const + { + return m_list[m_list.count() - 1]; + } + + ATTR_HOT inline _StackClass pop() + { + _StackClass ret = peek(); + m_list.remove_at(m_list.count() - 1); + return ret; + } + + ATTR_HOT inline int count() const { return m_list.count(); } + ATTR_HOT inline bool empty() const { return (m_list.count() == 0); } + ATTR_HOT inline void reset() { m_list.reset(); } + ATTR_HOT inline int capacity() const { return m_list.capacity(); } + +private: + netlist_list_t<_StackClass, _NumElem> m_list; +}; + #endif /* NLLISTS_H_ */ diff --git a/src/emu/netlist/nl_parser.c b/src/emu/netlist/nl_parser.c index 3f36f676297..a8a5174aca8 100644 --- a/src/emu/netlist/nl_parser.c +++ b/src/emu/netlist/nl_parser.c @@ -214,8 +214,10 @@ ATTR_COLD void netlist_parser::verror(pstring msg, int line_num, pstring line) } -void netlist_parser::parse(const char *buf) +void netlist_parser::parse(const char *buf, const pstring nlname) { + m_buf = buf; + reset(buf); set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-"); set_number_chars("01234567890eE-."); //FIXME: processing of numbers @@ -234,19 +236,20 @@ void netlist_parser::parse(const char *buf) m_tok_ALIAS = register_token("ALIAS"); m_tok_NET_C = register_token("NET_C"); m_tok_PARAM = register_token("PARAM"); - m_tok_NET_MODEL = register_token("PARAM"); + m_tok_NET_MODEL = register_token("NET_MODEL"); + m_tok_INCLUDE = register_token("INCLUDE"); + m_tok_SUBMODEL = register_token("SUBMODEL"); m_tok_NETLIST_START = register_token("NETLIST_START"); m_tok_NETLIST_END = register_token("NETLIST_END"); bool in_nl = false; - pstring nlname = ""; - while (true) + while (true) { token_t token = get_token(); if (token.is_type(ENDOFFILE)) - return; + error("EOF while searching for <%s>", nlname.cstr()); if (token.is(m_tok_NETLIST_END)) { @@ -297,6 +300,10 @@ void netlist_parser::parse_netlist(const pstring &nlname) netdev_param(); else if (token.is(m_tok_NET_MODEL)) net_model(); + else if (token.is(m_tok_SUBMODEL)) + net_submodel(); + else if (token.is(m_tok_INCLUDE)) + net_include(); else if (token.is(m_tok_NETLIST_END)) { netdev_netlist_end(); @@ -329,6 +336,30 @@ void netlist_parser::net_model() require_token(m_tok_param_right); } +void netlist_parser::net_submodel() +{ + // don't do much + pstring name = get_identifier(); + require_token(m_tok_comma); + pstring model = 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.namespace_pop(); +} + +void netlist_parser::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); +} + void netlist_parser::net_alias() { pstring alias = get_identifier(); diff --git a/src/emu/netlist/nl_parser.h b/src/emu/netlist/nl_parser.h index 7a84b5938c3..26309225377 100644 --- a/src/emu/netlist/nl_parser.h +++ b/src/emu/netlist/nl_parser.h @@ -144,7 +144,7 @@ public: netlist_parser(netlist_setup_t &setup) : ptokenizer(), m_setup(setup) {} - void parse(const char *buf); + void parse(const char *buf, const pstring nlname = ""); void parse_netlist(const pstring &nlname); void net_alias(); @@ -154,6 +154,8 @@ public: void netdev_netlist_start(); void netdev_netlist_end(); void net_model(); + void net_submodel(); + void net_include(); protected: virtual void verror(pstring msg, int line_num, pstring line); @@ -170,8 +172,12 @@ private: token_id_t m_tok_NET_MODEL; token_id_t m_tok_NETLIST_START; token_id_t m_tok_NETLIST_END; + token_id_t m_tok_SUBMODEL; + token_id_t m_tok_INCLUDE; netlist_setup_t &m_setup; + + const char *m_buf; }; diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index a8a7351fba2..ebcd71b02ec 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -58,9 +58,26 @@ netlist_setup_t::~netlist_setup_t() ATTR_COLD pstring netlist_setup_t::build_fqn(const pstring &obj_name) const { - return netlist().name() + "." + obj_name; + if (m_stack.empty()) + return netlist().name() + "." + obj_name; + else + return m_stack.peek() + "." + obj_name; } +void netlist_setup_t::namespace_push(const pstring &aname) +{ + if (m_stack.empty()) + m_stack.push(netlist().name() + "." + aname); + else + m_stack.push(m_stack.peek() + "." + aname); +} + +void netlist_setup_t::namespace_pop() +{ + m_stack.pop(); +} + + netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const pstring &name) { pstring fqn = build_fqn(name); diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index d8d6848a397..5de2022b95f 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -55,9 +55,14 @@ ATTR_COLD void NETLIST_NAME(_name)(netlist_setup_t &netlist) #define NETLIST_END() } -#define NETLIST_INCLUDE(_name) \ +#define INCLUDE(_name) \ NETLIST_NAME(_name)(netlist); +#define SUBMODEL(_name, _model) \ + netlist.namespace_push(# _name); \ + NETLIST_NAME(_model)(netlist); \ + netlist.namespace_pop(); + // ---------------------------------------------------------------------------------------- // FIXME: Clean this up // ---------------------------------------------------------------------------------------- @@ -135,6 +140,11 @@ public: void start_devices(); void resolve_inputs(); + /* handle namespace */ + + void namespace_push(const pstring &aname); + void namespace_pop(); + /* not ideal, but needed for save_state */ tagmap_terminal_t m_terminals; @@ -157,6 +167,9 @@ private: int m_proxy_cnt; + netlist_stack_t m_stack; + + void connect_terminals(netlist_core_terminal_t &in, netlist_core_terminal_t &out); void connect_input_output(netlist_input_t &in, netlist_output_t &out); void connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out); diff --git a/src/mame/drivers/pong.c b/src/mame/drivers/pong.c index 927bb535d37..8f0199c494a 100644 --- a/src/mame/drivers/pong.c +++ b/src/mame/drivers/pong.c @@ -732,7 +732,7 @@ NETLIST_END() static NETLIST_START(pong_fast) - NETLIST_INCLUDE(pong_schematics) + INCLUDE(pong_schematics) //NETDEV_ANALOG_CALLBACK(sound_cb, sound, pong_state, sound_cb, "") //NETDEV_ANALOG_CALLBACK(video_cb, videomix, fixedfreq_device, update_vid, "fixfreq")