Previous 199869 Revisions Next

r26183 Friday 15th November, 2013 at 19:57:34 UTC by Couriersud
Netlist: Need a checkpoint before I continue.
[src/emu/netlist]nl_base.c nl_base.h nl_config.h nl_parser.c nl_setup.c nl_setup.h
[src/emu/netlist/devices]net_lib.c net_lib.h nld_signal.h nld_system.c nld_system.h
[src/mame/drivers]pong.c

trunk/src/mame/drivers/pong.c
r26182r26183
464464   NETDEV_PARAM(videomix.R1, RES_K(1))
465465   NETDEV_PARAM(videomix.R2, RES_K(1.2))
466466   NETDEV_PARAM(videomix.R3, RES_K(22))
467
468#if 0
469   NETDEV_ANALOG_CONST(V5, 5)
470    NETDEV_ANALOG_CONST(V0, 0)
471    NETDEV_R(R1, 10)
472    NETDEV_R(R2, 10)
473    NET_C(V5,R1.1)
474    NET_C(R1.2, R2.1)
475    NET_C(R2.2, V0)
476#endif
467477NETLIST_END
468478
469479static NETLIST_START(pong)
trunk/src/emu/netlist/devices/nld_system.c
r26182r26183
3939    m_Q.initial(m_const.Value());
4040}
4141
42// ----------------------------------------------------------------------------------------
43// analog_callback
44// ----------------------------------------------------------------------------------------
45
4246NETLIB_UPDATE(analog_callback)
4347{
4448    // FIXME: Remove after device cleanup
r26182r26183
4650        m_callback(INPANALOG(m_in));
4751}
4852
53// ----------------------------------------------------------------------------------------
54// clock
55// ----------------------------------------------------------------------------------------
56
57NETLIB_START(clock)
58{
59    register_output("Q", m_Q);
60    //register_input("FB", m_feedback);
61
62    register_param("FREQ", m_freq, 7159000.0 * 5);
63    m_inc = netlist_time::from_hz(m_freq.Value()*2);
64
65    register_link_internal(m_feedback, m_Q, netlist_input_t::INP_STATE_ACTIVE);
66
67}
68
69NETLIB_UPDATE_PARAM(clock)
70{
71    m_inc = netlist_time::from_hz(m_freq.Value()*2);
72}
73
74NETLIB_UPDATE(clock)
75{
76    //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc  );
77    OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc  );
78}
trunk/src/emu/netlist/devices/net_lib.h
r26182r26183
6464// this is a bad hack
6565#define USE_OLD7493 (0)
6666
67
6768// ----------------------------------------------------------------------------------------
69// 2 terminal devices
70// ----------------------------------------------------------------------------------------
71
72#define NETDEV_R(_name, _R)                                                         \
73        NET_REGISTER_DEV(R, _name)                                                  \
74        NETDEV_PARAMI(_name, R, _R)                                           \
75
76
77// ----------------------------------------------------------------------------------------
6878// Special chips
6979// ----------------------------------------------------------------------------------------
7080
r26182r26183
7787#define NETDEV_ANALOG_INPUT(_name)                                                  \
7888      NET_REGISTER_DEV(analog_input, _name)
7989#define NETDEV_CALLBACK(_name, _IN)                                                 \
80      NET_REGISTER_DEV(analog_callback, _name)                             \
90      NET_REGISTER_DEV(analog_callback, _name)                                    \
8191      NET_CONNECT(_name, IN, _IN)
8292#define NETDEV_SWITCH2(_name, _i1, _i2)                                             \
8393      NET_REGISTER_DEV(nicMultiSwitch, _name)                                     \
r26182r26183
241251// ----------------------------------------------------------------------------------------
242252
243253
244NETLIB_DEVICE_WITH_PARAMS(clock,
245   netlist_ttl_input_t m_feedback;
246   netlist_ttl_output_t m_Q;
247254
248   netlist_param_t m_freq;
249   netlist_time m_inc;
250);
251255
252256NETLIB_DEVICE_WITH_PARAMS(nicMultiSwitch,
253257   netlist_analog_input_t m_I[8];
r26182r26183
301305   netlist_param_t m_C;
302306   netlist_param_t m_VS;
303307   netlist_param_t m_VL;
308
309   double nicNE555N_cv();
310   double nicNE555N_clamp(const double v, const double a, const double b);
311
304312);
305313
306314NETLIB_SIGNAL(nic7430, 8, 0, 0);
trunk/src/emu/netlist/devices/nld_system.h
r26182r26183
4343// ----------------------------------------------------------------------------------------
4444
4545NETLIB_DEVICE_WITH_PARAMS(mainclock,
46   netlist_ttl_output_t m_Q;
46public:
47    netlist_ttl_output_t m_Q;
4748
4849   netlist_param_t m_freq;
4950   netlist_time m_inc;
r26182r26183
5253);
5354
5455// ----------------------------------------------------------------------------------------
56// clock
57// ----------------------------------------------------------------------------------------
58
59NETLIB_DEVICE_WITH_PARAMS(clock,
60    netlist_ttl_input_t m_feedback;
61    netlist_ttl_output_t m_Q;
62
63    netlist_param_t m_freq;
64    netlist_time m_inc;
65);
66
67// ----------------------------------------------------------------------------------------
68// solver_clock
69// ----------------------------------------------------------------------------------------
70
71NETLIB_DEVICE_WITH_PARAMS_DERIVED(solver_clock, clock,
72public:
73);
74
75// ----------------------------------------------------------------------------------------
5576// netdev_callback
5677// ----------------------------------------------------------------------------------------
5778
trunk/src/emu/netlist/devices/net_lib.c
r26182r26183
7878   printf("%s: %d %d\n", name().cstr(), (UINT32) (netlist().time().as_raw() / 1000000), INPLOGIC(m_I));
7979}
8080
81NETLIB_START(clock)
82{
83   register_output("Q", m_Q);
84   //register_input("FB", m_feedback);
8581
86   register_param("FREQ", m_freq, 7159000.0 * 5);
87   m_inc = netlist_time::from_hz(m_freq.Value()*2);
88
89   register_link_internal(m_feedback, m_Q, netlist_input_t::INP_STATE_ACTIVE);
90
91}
92
93NETLIB_UPDATE_PARAM(clock)
94{
95   m_inc = netlist_time::from_hz(m_freq.Value()*2);
96}
97
98NETLIB_UPDATE(clock)
99{
100   //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc  );
101   OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc  );
102}
103
10482NETLIB_START(nicMultiSwitch)
10583{
10684   static const char *sIN[8] = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8" };
r26182r26183
223201   m_last = false;
224202}
225203
226INLINE double nicNE555N_cv(NETLIB_NAME(nicNE555N_MSTABLE) &dev)
204inline double NETLIB_NAME(nicNE555N_MSTABLE)::nicNE555N_cv()
227205{
228   return (dev.m_CV.is_highz() ? 0.67 * dev.m_VS.Value() : dev.INPANALOG(dev.m_CV));
206   return (m_CV.is_highz() ? 0.67 * m_VS.Value() : INPANALOG(m_CV));
229207}
230208
231INLINE double nicNE555N_clamp(NETLIB_NAME(nicNE555N_MSTABLE) &dev, const double v, const double a, const double b)
209inline double NETLIB_NAME(nicNE555N_MSTABLE)::nicNE555N_clamp(const double v, const double a, const double b)
232210{
233211   double ret = v;
234   if (ret >  dev.m_VS.Value() - a)
235      ret = dev.m_VS.Value() - a;
212   if (ret >  m_VS.Value() - a)
213      ret = m_VS.Value() - a;
236214   if (ret < b)
237215      ret = b;
238216   return ret;
r26182r26183
246224{
247225   update_param(); // FIXME : m_CV should be on a sub device ...
248226
249   double vt = nicNE555N_clamp(*this, nicNE555N_cv(*this), 0.7, 1.4);
227   double vt = nicNE555N_clamp(nicNE555N_cv(), 0.7, 1.4);
250228   bool bthresh = (INPANALOG(m_THRESHOLD) > vt);
251   bool btrig = (INPANALOG(m_trigger) > nicNE555N_clamp(*this, nicNE555N_cv(*this) * 0.5, 0.7, 1.4));
229   bool btrig = (INPANALOG(m_trigger) > nicNE555N_clamp(nicNE555N_cv() * 0.5, 0.7, 1.4));
252230   bool out = m_last;
253231
254232   if (!btrig)
r26182r26183
624602   register_output(C, "QC", C.m_Q);
625603   register_output(D, "QD", D.m_Q);
626604
627   //B.register_link_internal(B.m_I, A.m_Q);
628605   register_link_internal(C, C.m_I, B.m_Q, netlist_input_t::INP_STATE_HL);
629606   register_link_internal(D, D.m_I, C.m_Q, netlist_input_t::INP_STATE_HL);
630607
r26182r26183
972949
973950static const net_device_t_base_factory *netregistry[] =
974951{
952    ENTRY(R,                    NETDEV_R)
975953   ENTRY(ttl_const,            NETDEV_TTL_CONST)
976954   ENTRY(analog_const,         NETDEV_ANALOG_CONST)
977955   ENTRY(logic_input,          NETDEV_LOGIC_INPUT)
trunk/src/emu/netlist/devices/nld_signal.h
r26182r26183
9090      register_output("Q", m_Q);
9191      for (int i=0; i < _numdev; i++)
9292      {
93         register_input(sIN[i], m_i[i], netlist_input_t::INP_STATE_ACTIVE);
93         register_input(sIN[i], m_i[i]);
9494      }
9595   }
9696
trunk/src/emu/netlist/nl_base.c
r26182r26183
216216   m_setup->register_output(*this, dev, name, port);
217217}
218218
219void netlist_device_t::register_terminal(const astring &name, netlist_terminal_t &port)
220{
221    m_setup->register_terminal(*this,*this,name, port);
222}
223
219224void netlist_device_t::register_output(const astring &name, netlist_output_t &port)
220225{
221226   m_setup->register_output(*this,*this,name, port);
r26182r26183
234239void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::net_input_state aState)
235240{
236241    in.init_input(dev, aState);
237    out.init_terminal(dev);
242    // ensure we are not yet initialized ...
243    if (!out.net().isRailNet())
244        out.init_terminal(dev);
238245   //if (in.state() != net_input_t::INP_STATE_PASSIVE)
239246      out.net().register_con(in);
240247}
r26182r26183
274281    m_last.Q = 0;
275282};
276283
284ATTR_COLD void netlist_net_t::merge_net(netlist_net_t *othernet)
285{
286    if (othernet == NULL)
287        return; // Nothing to do
288
289    if (this->isRailNet() && othernet->isRailNet())
290        fatalerror("Trying to merge to rail nets\n");
291
292    if (othernet->isRailNet())
293        othernet->merge_net(this);
294    else
295    {
296        netlist_terminal_t *p = othernet->m_head;
297        if (p == NULL)
298            return;
299        if (m_head == NULL)
300        {
301            m_head = p;
302            m_head->set_net(*this);
303            p = p->m_update_list_next;
304        }
305        while (p != NULL)
306        {
307            netlist_terminal_t *pn = p->m_update_list_next;
308            p->m_update_list_next = m_head;
309            p->set_net(*this);
310            m_head = p;
311            p = pn;
312        }
313        othernet->m_head = NULL; // FIXME: othernet needs to be free'd from memory
314    }
315}
316
277317ATTR_COLD void netlist_net_t::register_con(netlist_terminal_t &terminal)
278318{
279319    terminal.set_net(*this);
r26182r26183
306346{
307347   assert(m_num_cons != 0);
308348
309   const UINT32 masks[4] = { 1, 5, 3, 1 };
310   m_cur = m_new;
311   m_in_queue = 2; /* mark as taken ... */
312
313   const UINT32 mask = masks[ (m_last.Q  << 1) | m_cur.Q ];
314
315    netlist_terminal_t *p = m_head;
316    switch (m_num_cons)
317    {
318    case 2:
319        update_dev(p, mask);
320        p = p->m_update_list_next;
321    case 1:
322        update_dev(p, mask);
323        break;
324    default:
349   //assert(this->isRailNet());
350   if (UNEXPECTED(!this->isRailNet()))
351   {
352       /* only inputs and terminals connected
353        * approach:
354        *
355        * a) Update voltage on this net
356        * b) Update devices
357        * c) If difference old - new > trigger schedule immediate update
358        *    of number of updates < max_update_count
359        *    else clear number of updates
360        */
361        m_in_queue = 2; /* mark as taken ... */
362       double gtot = 0;
363       double iIdr = 0;
364       netlist_terminal_t *p = m_head;
325365        do
326366        {
327            update_dev(p, mask);
367            p->netdev().update_dev();
368            gtot += p->m_g;
369            iIdr += p->m_Idr;
370
328371            p = p->m_update_list_next;
329372        } while (p != NULL);
330        break;
331    }
332   m_last = m_cur;
373        m_new.Analog = iIdr / gtot;
374        printf("New: %f\n", m_new.Analog);
375   }
376   else
377   {
378
379       const UINT32 masks[4] = { 1, 5, 3, 1 };
380       m_cur = m_new;
381       m_in_queue = 2; /* mark as taken ... */
382
383       const UINT32 mask = masks[ (m_last.Q  << 1) | m_cur.Q ];
384
385       netlist_terminal_t *p = m_head;
386       switch (m_num_cons)
387       {
388       case 2:
389           update_dev(p, mask);
390           p = p->m_update_list_next;
391       case 1:
392           update_dev(p, mask);
393           break;
394       default:
395           do
396           {
397               update_dev(p, mask);
398               p = p->m_update_list_next;
399           } while (p != NULL);
400           break;
401       }
402       m_last = m_cur;
403   }
333404}
334405
335406// ----------------------------------------------------------------------------------------
trunk/src/emu/netlist/nl_config.h
r26182r26183
3838
3939#define NETLIST_HIGHIMP_V   (1.23456e20)        /* some voltage we should never see */
4040
41#define NETLIST_GMIN    (1e-9)
42
4143typedef UINT8 netlist_sig_t;
4244
4345/* FIXME: We need a different solution to output delegates !
trunk/src/emu/netlist/nl_parser.c
r26182r26183
9595      m_p++;
9696      skipws();
9797      astring output_name = getname2(',', ')');
98      NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), dev->m_inputs.item(cnt)->cstr()));
98      NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), dev->m_terminals.item(cnt)->cstr()));
9999      m_setup.register_link(*dev->m_terminals.item(cnt), output_name);
100100      skipws();
101101      cnt++;
trunk/src/emu/netlist/nl_base.h
r26182r26183
170170#define NETLIB_UPDATE_PARAM(_chip) ATTR_HOT ATTR_ALIGN void NETLIB_NAME(_chip) :: update_param(void)
171171#define NETLIB_FUNC_VOID(_chip, _name, _params) ATTR_HOT ATTR_ALIGN inline void NETLIB_NAME(_chip) :: _name _params
172172
173#define NETLIB_DEVICE_BASE(_name, _pclass, _extra, _priv)                           \
174    class _name : public _pclass                                                    \
175    {                                                                               \
176    public:                                                                         \
177        _name()                                                                     \
178        : _pclass()    { }                                                          \
179    protected:                                                                      \
180        _extra                                                                      \
181        ATTR_HOT void update();                                                     \
182        ATTR_HOT void start();                                                      \
183        _priv                                                                       \
184    }
185
186#define NETLIB_DEVICE_DERIVED(_name, _pclass, _priv)                                \
187      NETLIB_DEVICE_BASE(NETLIB_NAME(_name), NETLIB_NAME(_pclass), , _priv)
188
173189#define NETLIB_DEVICE(_name, _priv)                                                 \
174   class NETLIB_NAME(_name) : public netlist_device_t                              \
175   {                                                                               \
176   public:                                                                         \
177      NETLIB_NAME(_name) ()                                                       \
178      : netlist_device_t()    { }                                                 \
179   protected:                                                                      \
180      ATTR_HOT void update();                                                     \
181      ATTR_HOT void start();                                                      \
182      _priv                                                                       \
183   }
190      NETLIB_DEVICE_BASE(NETLIB_NAME(_name), netlist_device_t, , _priv)
184191
185192#define NETLIB_SUBDEVICE(_name, _priv)                                              \
186193   class NETLIB_NAME(_name) : public netlist_core_device_t                         \
r26182r26183
195202   }
196203
197204#define NETLIB_DEVICE_WITH_PARAMS(_name, _priv)                                     \
198   class NETLIB_NAME(_name) : public netlist_device_t                              \
199   {                                                                               \
200   public:                                                                         \
201      NETLIB_NAME(_name) ()                                                       \
202      : netlist_device_t() { }                                                    \
203      ATTR_HOT void update_param();                                               \
204      ATTR_HOT void update();                                                     \
205      ATTR_HOT void start();                                                      \
206   /* protected: */                                                                \
207      _priv                                                                       \
208   }
205        NETLIB_DEVICE_BASE(NETLIB_NAME(_name), netlist_device_t,                    \
206           ATTR_HOT void update_param();                                           \
207       , _priv)
209208
209#define NETLIB_DEVICE_WITH_PARAMS_DERIVED(_name, _pclass, _priv)                    \
210        NETLIB_DEVICE_BASE(NETLIB_NAME(_name), NETLIB_NAME(_pclass),                \
211            ATTR_HOT void update_param();                                           \
212        , _priv)
213
210214// ----------------------------------------------------------------------------------------
211215// forward definitions
212216// ----------------------------------------------------------------------------------------
r26182r26183
287291
288292   ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily)
289293   : netlist_object_t(atype, afamily)
294   , m_Idr(0.0)
295   , m_g(NETLIST_GMIN)
290296    , m_update_list_next(NULL)
291297   , m_netdev(NULL)
292298    , m_net(NULL)
293299    , m_state(INP_STATE_ACTIVE)
294300   {}
295301
302    ATTR_COLD netlist_terminal_t()
303    : netlist_object_t(TERMINAL, ANALOG)
304    , m_Idr(0.0)
305    , m_update_list_next(NULL)
306    , m_netdev(NULL)
307    , m_net(NULL)
308    , m_state(INP_STATE_ACTIVE)
309    {}
310
296311   ATTR_COLD virtual void init_terminal(netlist_core_device_t &dev);
297312
298313    ATTR_COLD void set_net(netlist_net_t &anet)   { m_net = &anet; }
314    ATTR_COLD bool has_net() { return (m_net != NULL); }
299315
300316    ATTR_HOT inline const netlist_net_t & RESTRICT net() const { return *m_net;}
301317    ATTR_HOT inline netlist_net_t & RESTRICT net() { return *m_net;}
r26182r26183
306322
307323    ATTR_HOT inline netlist_core_device_t & RESTRICT netdev() const { return *m_netdev; }
308324
325    double m_Idr; // drive current
326    double m_g; // conductance
327
309328    netlist_terminal_t *m_update_list_next;
310329
311330private:
r26182r26183
421440    ATTR_COLD netlist_net_t(const type_t atype, const family_t afamily);
422441
423442    ATTR_COLD void register_con(netlist_terminal_t &terminal);
443    ATTR_COLD void merge_net(netlist_net_t *othernet);
424444    ATTR_COLD void register_railterminal(netlist_terminal_t &mr)
425445    {
426446        assert(m_railterminal == NULL);
r26182r26183
447467    ATTR_HOT inline const netlist_sig_t last_Q() const  { return m_last.Q;  }
448468    ATTR_HOT inline const netlist_sig_t new_Q() const   { return m_new.Q;   }
449469
470    ATTR_HOT inline const double Q_Analog() const
471    {
472        //assert(object_type(SIGNAL_MASK) == SIGNAL_ANALOG);
473        assert(family() == ANALOG);
474        return m_cur.Analog;
475    }
476
477    ATTR_HOT inline void push_to_queue(const netlist_time &delay);
478    ATTR_HOT bool is_queued() { return m_in_queue == 1; }
479
450480protected:
451481
452482    /* prohibit use in device functions
r26182r26183
458488      assert(family() == LOGIC);
459489        return m_cur.Q;
460490    }
461    ATTR_HOT inline const double Q_Analog() const
462    {
463        //assert(object_type(SIGNAL_MASK) == SIGNAL_ANALOG);
464      assert(family() == ANALOG);
465        return m_cur.Analog;
466    }
467491
468    ATTR_HOT inline void push_to_queue(const netlist_time &delay);
469
470492    hybrid_t m_last;
471493    hybrid_t m_cur;
472494    hybrid_t m_new;
r26182r26183
670692
671693   ATTR_COLD void register_sub(netlist_core_device_t &dev, const astring &name);
672694
695    ATTR_COLD void register_terminal(const astring &name, netlist_terminal_t &port);
696
673697   ATTR_COLD void register_output(const astring &name, netlist_output_t &out);
674698   ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &out);
675699
r26182r26183
850874   double m_high_V;
851875};
852876
877// ----------------------------------------------------------------------------------------
878// nld_twoterm
879// ----------------------------------------------------------------------------------------
853880
881class nld_twoterm : public netlist_device_t
882{
883public:
884    nld_twoterm()
885    : netlist_device_t(), m_g(0.0), m_V(0.0), m_I(0.0)
886    {
887    }
888
889    netlist_terminal_t m_P;
890    netlist_terminal_t m_N;
891
892protected:
893    virtual void start()
894    {
895    }
896
897    ATTR_HOT ATTR_ALIGN virtual void update()
898    {
899        m_N.m_Idr = (m_P.net().Q_Analog() - m_V) * m_g + m_I;
900        m_P.m_Idr = (m_N.net().Q_Analog() + m_V) * m_g - m_I;
901        printf("%f %f %f %f\n", m_N.m_Idr, m_P.m_Idr, m_N.net().Q_Analog(), m_P.net().Q_Analog());
902        if (!m_N.net().is_queued() && !m_N.net().isRailNet())
903            m_N.net().push_to_queue(NLTIME_FROM_NS(10));
904        if (!m_P.net().is_queued() && !m_P.net().isRailNet() )
905            m_P.net().push_to_queue(NLTIME_FROM_NS(10));
906    }
907
908    double m_g; // conductance
909    double m_V; // internal voltage source
910    double m_I; // internal current source
911private:
912};
913
914class nld_R : public nld_twoterm
915{
916public:
917    nld_R()
918    : nld_twoterm()
919    {
920    }
921
922    netlist_param_t m_R;
923
924protected:
925    void start()
926    {
927        register_terminal("1", m_P);
928        register_terminal("2", m_N);
929
930        register_param("R", m_R, NETLIST_GMIN);
931    }
932
933    virtual void update_param()
934    {
935        m_g = 1.0 / m_R.Value();
936        m_P.m_g = m_g;
937        m_N.m_g = m_g;
938    }
939
940private:
941};
942
854943// ----------------------------------------------------------------------------------------
855944// Inline implementations
856945// ----------------------------------------------------------------------------------------
trunk/src/emu/netlist/nl_setup.c
r26182r26183
2323
2424netlist_setup_t::netlist_setup_t(netlist_base_t &netlist)
2525   : m_netlist(netlist)
26    , m_proxy_cnt(0)
2627{
2728   NETLIST_NAME(base)(*this);
2829}
r26182r26183
110111      fatalerror("Error adding output %s to terminal list\n", name.cstr());
111112}
112113
114void netlist_setup_t::register_terminal(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_terminal_t &out)
115{
116    NL_VERBOSE_OUT(("output %s\n", name.cstr()));
117    assert(out.isType(netlist_terminal_t::TERMINAL));
118    astring temp = dev.name();
119    temp.cat(".");
120    temp.cat(name);
121    out.init_terminal(upd_dev);
122    if (!(m_terminals.add(temp, &out, false)==TMERR_NONE))
123        fatalerror("Error adding output %s to terminal list\n", name.cstr());
124}
125
113126void netlist_setup_t::register_input(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type)
114127{
115128   NL_VERBOSE_OUT(("input %s\n", name.cstr()));
r26182r26183
176189   return *ret;
177190}
178191
192netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in)
193{
194   const astring &tname = resolve_alias(terminal_in);
195   netlist_terminal_t *ret;
196
197   ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname));
198   /* look for default */
199   if (ret == NULL)
200   {
201      /* look for ".Q" std output */
202      astring s = tname;
203      s.cat(".Q");
204      ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s));
205   }
206   if (ret == NULL)
207      fatalerror("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr());
208   NL_VERBOSE_OUT(("Found input %s\n", tname.cstr()));
209   return *ret;
210}
211
179212netlist_param_t &netlist_setup_t::find_param(const astring &param_in)
180213{
181214   const astring &outname = resolve_alias(param_in);
r26182r26183
188221   return *ret;
189222}
190223
191void netlist_setup_t::resolve_inputs(void)
224
225void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t &out)
192226{
193   NL_VERBOSE_OUT(("Resolving ...\n"));
194   int proxy_cnt = 0;
195   for (tagmap_astring_t::entry_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry))
196   {
197      const astring *sout = entry->object();
198      astring sin = entry->tag();
199      netlist_input_t *in = dynamic_cast<netlist_input_t *>(m_terminals.find(sin));
227    if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC))
228    {
229        nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(in);
230        astring x = "";
231        x.printf("proxy_ad_%d", m_proxy_cnt++);
200232
201      if (in == NULL)
202         fatalerror("Unable to find %s\n", sin.cstr());
233        proxy->init(*this, x.cstr());
234        register_dev(proxy);
203235
204      netlist_output_t  &out = find_output(sout->cstr());
205      if (out.isFamily(netlist_terminal_t::ANALOG) && in->isFamily(netlist_terminal_t::LOGIC))
206      {
207         nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(*in);
208         astring x = "";
209         x.printf("proxy_ad_%d", proxy_cnt++);
236        proxy->m_Q.net().register_con(in);
237        out.net().register_con(proxy->m_I);
210238
211         proxy->init(*this, x.cstr());
212         register_dev(proxy);
239    }
240    else if (out.isFamily(netlist_terminal_t::LOGIC) && in.isFamily(netlist_terminal_t::ANALOG))
241    {
242        //printf("here 1\n");
243        nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out);
244        astring x = "";
245        x.printf("proxy_da_%d", m_proxy_cnt++);
246        proxy->init(*this, x.cstr());
247        register_dev(proxy);
213248
214         proxy->m_Q.net().register_con(*in);
215         out.net().register_con(proxy->m_I);
249        proxy->m_Q.net().register_con(in);
250        out.net().register_con(proxy->m_I);
251    }
252    else
253    {
254        out.net().register_con(in);
255    }
256}
216257
217      }
218      else if (out.isFamily(netlist_terminal_t::LOGIC) && in->isFamily(netlist_terminal_t::ANALOG))
219      {
220         //printf("here 1\n");
221         nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out);
222         astring x = "";
223         x.printf("proxy_da_%d", proxy_cnt++);
224         proxy->init(*this, x.cstr());
225         register_dev(proxy);
258// FIXME: optimize code  ...
259void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out)
260{
261    if (out.isFamily(netlist_terminal_t::ANALOG))
262    {
263        /* no proxy needed, just merge existing terminal net */
264        if (in.has_net())
265            out.net().merge_net(&in.net());
266        else
267            out.net().register_con(in);
226268
227            proxy->m_Q.net().register_con(*in);
228            out.net().register_con(proxy->m_I);
229      }
230      else
231      {
232          out.net().register_con(*in);
233      }
234   }
269    }
270    else if (out.isFamily(netlist_terminal_t::LOGIC))
271    {
272        //printf("here 1\n");
273        nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out);
274        astring x = "";
275        x.printf("proxy_da_%d", m_proxy_cnt++);
276        proxy->init(*this, x.cstr());
277        register_dev(proxy);
235278
236   /* find the main clock ... */
237   for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
238   {
239      netlist_device_t *dev = entry->object();
240      if (dynamic_cast<NETLIB_NAME(mainclock)*>(dev) != NULL)
241      {
242         m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(mainclock)*>(dev));
243      }
244   }
279        out.net().register_con(proxy->m_I);
245280
246   /* print all outputs */
247   for (tagmap_terminal_t::entry_t *entry = m_terminals.first(); entry != NULL; entry = m_terminals.next(entry))
248   {
249      ATTR_UNUSED netlist_output_t *out = dynamic_cast<netlist_output_t *>(entry->object());
250      //if (out != NULL)
251         //VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr()));
252   }
281        if (in.has_net())
282            proxy->m_Q.net().merge_net(&in.net());
283        else
284            proxy->m_Q.net().register_con(in);
285    }
286    else
287    {
288        fatalerror("Netlist: Severe Error");
289    }
290}
253291
292void netlist_setup_t::connect_terminals(netlist_terminal_t &in, netlist_terminal_t &out)
293{
294    assert(in.isType(netlist_terminal_t::TERMINAL));
295    assert(out.isType(netlist_terminal_t::TERMINAL));
254296
297    if (in.has_net() && out.has_net())
298    {
299        in.net().merge_net(&out.net());
300        //in.net().register_con(out);
301        //in.net().register_con(in);
302    }
303    else if (out.has_net())
304    {
305        out.net().register_con(in);
306        //out.net().register_con(out);
307    }
308    else if (in.has_net())
309    {
310        in.net().register_con(out);
311        //in.net().register_con(in);
312    }
313    else
314    {
315        NL_VERBOSE_OUT(("adding net ...\n"));
316        in.set_net(*(new netlist_net_t(netlist_object_t::NET, netlist_object_t::ANALOG)));
317        in.net().init_object(netlist());
318        in.net().register_con(out);
319        in.net().register_con(in);
320    }
255321}
256322
323void netlist_setup_t::resolve_inputs(void)
324{
325    NL_VERBOSE_OUT(("Searching for clocks ...\n"));
326    /* find the main clock ... */
327    for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
328    {
329        netlist_device_t *dev = entry->object();
330        if (dynamic_cast<NETLIB_NAME(mainclock)*>(dev) != NULL)
331        {
332            m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(mainclock)*>(dev));
333        }
334    }
335
336    NL_VERBOSE_OUT(("Resolving ...\n"));
337    for (tagmap_astring_t::entry_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry))
338    {
339        const astring t1s = *entry->object();
340        const astring t2s = entry->tag();
341        netlist_terminal_t &t1 = find_terminal(t1s);
342        netlist_terminal_t &t2 = find_terminal(t2s);
343
344        // FIXME: amend device design so that warnings can be turned into errors
345        //        Only variable inputs have this issue
346        if (t1.isType(netlist_terminal_t::OUTPUT) && t2.isType(netlist_terminal_t::INPUT))
347        {
348            if (t2.has_net())
349                mame_printf_warning("Input %s already connected\n", t2s.cstr());
350            connect_input_output(dynamic_cast<netlist_input_t &>(t2), dynamic_cast<netlist_output_t &>(t1));
351        }
352        else if (t1.isType(netlist_terminal_t::INPUT) && t2.isType(netlist_terminal_t::OUTPUT))
353        {
354            if (t1.has_net())
355                mame_printf_warning("Input %s already connected\n", t1s.cstr());
356            connect_input_output(dynamic_cast<netlist_input_t &>(t1), dynamic_cast<netlist_output_t &>(t2));
357        }
358        else if (t1.isType(netlist_terminal_t::OUTPUT) && t2.isType(netlist_terminal_t::TERMINAL))
359        {
360            connect_terminal_output(dynamic_cast<netlist_terminal_t &>(t2), dynamic_cast<netlist_output_t &>(t1));
361        }
362        else if (t1.isType(netlist_terminal_t::TERMINAL) && t2.isType(netlist_terminal_t::OUTPUT))
363        {
364            connect_terminal_output(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_output_t &>(t2));
365        }
366        else if (t1.isType(netlist_terminal_t::TERMINAL) && t2.isType(netlist_terminal_t::TERMINAL))
367        {
368            connect_terminals(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_terminal_t &>(t2));
369        }
370        else
371            fatalerror("Connecting %s to %s not supported!\n", t1s.cstr(), t2s.cstr());
372    }
373
374    /* print all outputs */
375    for (tagmap_terminal_t::entry_t *entry = m_terminals.first(); entry != NULL; entry = m_terminals.next(entry))
376    {
377        ATTR_UNUSED netlist_output_t *out = dynamic_cast<netlist_output_t *>(entry->object());
378        //if (out != NULL)
379            //VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr()));
380    }
381
382
383}
384
257385void netlist_setup_t::step_devices_once(void)
258386{
259387   /* make sure params are set now .. */
trunk/src/emu/netlist/nl_setup.h
r26182r26183
2828      NET_REGISTER_DEV(_type ## _ ## sig, _name)
2929#define NET_CONNECT(_name, _input, _output)                                         \
3030      netlist.register_link(# _name "." # _input, # _output);
31#define NET_C(_input, _output)                                                      \
32        netlist.register_link(# _input , # _output);
3133#define NETDEV_PARAM(_name, _val)                                                   \
3234      netlist.find_param(# _name).initial(_val);
35#define NETDEV_PARAMI(_name, _param, _val)                                           \
36        netlist.find_param(# _name "." # _param).initial(_val);
3337
38
3439#define NETLIST_NAME(_name) netlist ## _ ## _name
3540
3641#define NETLIST_START(_name) \
r26182r26183
7176   netlist_device_t *register_dev(netlist_device_t *dev);
7277   void remove_dev(const astring &name);
7378
79    void register_terminal(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_terminal_t &out);
7480   void register_output(netlist_core_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_output_t &out);
7581   void register_input(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_input_t &inp, netlist_input_t::net_input_state type);
7682   void register_alias(const astring &alias, const astring &out);
r26182r26183
7985   void register_link(const astring &sin, const astring &sout);
8086
8187   netlist_output_t &find_output(const astring &outname_in);
88    netlist_terminal_t &find_terminal(const astring &outname_in);
8289   netlist_param_t &find_param(const astring &param_in);
8390
8491   void register_callback(const astring &devname, netlist_output_delegate delegate);
r26182r26183
105112   tagmap_param_t  m_params;
106113   tagmap_astring_t  m_links;
107114
115   int m_proxy_cnt;
116
117   void connect_terminals(netlist_terminal_t &in, netlist_terminal_t &out);
118   void connect_input_output(netlist_input_t &in, netlist_output_t &out);
119    void connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out);
120
108121   netlist_output_t *find_output_exact(const astring &outname_in);
109122   const astring &resolve_alias(const astring &name) const;
110123};

Previous 199869 Revisions Next


© 1997-2024 The MAME Team