Previous 199869 Revisions Next

r26600 Thursday 12th December, 2013 at 20:19:29 UTC by Couriersud
Netlist:

- code cleanup
- logs on demand ... NL_LOGS=EBUF.OP:4V ./mame64 -np 4 pongf
 No recompile or dealing with roms
[src/emu/netlist]netlist.mak nl_base.c nl_base.h nl_config.h nl_lists.h nl_setup.c nl_util.h*
[src/emu/netlist/devices]net_lib.c net_lib.h nld_7483.c* nld_7483.h* nld_7490.c* nld_7490.h* nld_7493.h nld_9316.c* nld_9316.h* nld_log.c nld_log.h nld_solver.c* nld_solver.h* nld_system.c nld_system.h nld_twoterm.c

trunk/src/emu/netlist/netlist.mak
r26599r26600
2424   $(NETLISTOBJ)/nl_parser.o \
2525   $(NETLISTOBJ)/devices/nld_system.o \
2626   $(NETLISTOBJ)/devices/nld_twoterm.o \
27   $(NETLISTOBJ)/devices/nld_solver.o \
2728   $(NETLISTOBJ)/devices/net_lib.o \
2829   $(NETLISTOBJ)/devices/nld_7404.o \
2930   $(NETLISTOBJ)/devices/nld_7474.o \
31   $(NETLISTOBJ)/devices/nld_7483.o \
3032   $(NETLISTOBJ)/devices/nld_7486.o \
33   $(NETLISTOBJ)/devices/nld_7490.o \
3134   $(NETLISTOBJ)/devices/nld_7493.o \
35   $(NETLISTOBJ)/devices/nld_9316.o \
3236   $(NETLISTOBJ)/devices/nld_NE555.o \
3337   $(NETLISTOBJ)/devices/nld_log.o \
3438
trunk/src/emu/netlist/nl_base.h
r26599r26600
243243class netlist_setup_t;
244244class netlist_base_t;
245245class netlist_matrix_solver_t;
246class NETLIB_NAME(solver);
247class NETLIB_NAME(mainclock);
246248
247
248249// ----------------------------------------------------------------------------------------
249250// netlist_object_t
250251// ----------------------------------------------------------------------------------------
r26599r26600
339340   ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate);
340341
341342    ATTR_COLD void set_net(netlist_net_t &anet);
342    ATTR_COLD inline bool has_net() { return (m_net != NULL); }
343    ATTR_COLD inline bool has_net() const { return (m_net != NULL); }
343344    ATTR_HOT inline const netlist_net_t & RESTRICT net() const { return *m_net;}
344345    ATTR_HOT inline netlist_net_t & RESTRICT net() { return *m_net;}
345346
r26599r26600
483484    typedef netlist_list_t<netlist_net_t *> list_t;
484485
485486    friend class NETLIB_NAME(mainclock);
486    friend class NETLIB_NAME(solver);
487487    friend class netlist_matrix_solver_t;
488    friend class netlist_output_t;
489    friend class netlist_input_t;
490488    friend class netlist_logic_output_t;
491489    friend class netlist_analog_output_t;
492    friend class netlist_logic_input_t;
493    friend class netlist_analog_input_t;
494490
495491    // FIXME: union does not work
496492    typedef struct
r26599r26600
511507    ATTR_HOT inline const netlist_time time() const { return m_time; }
512508    ATTR_HOT inline void set_time(const netlist_time ntime) { m_time = ntime; }
513509
514    ATTR_HOT inline bool isRailNet() { return !(m_railterminal == NULL); }
510    ATTR_HOT inline bool isRailNet() const { return !(m_railterminal == NULL); }
515511    ATTR_HOT inline const netlist_core_terminal_t & RESTRICT  railterminal() const { return *m_railterminal; }
516    ATTR_HOT inline const netlist_core_terminal_t & RESTRICT railterminal() { return *m_railterminal; }
517512
518513    /* Everything below is used by the logic subsystem */
519514
r26599r26600
522517
523518    ATTR_HOT inline const int active_count() const { return m_active; }
524519
525    ATTR_HOT inline const netlist_sig_t last_Q() const  { return m_last.Q;  }
526    ATTR_HOT inline const netlist_sig_t new_Q() const   { return m_new.Q;   }
520    ATTR_HOT inline const netlist_sig_t Q() const
521    {
522        assert(family() == LOGIC);
523        return m_cur.Q;
524    }
527525
526    ATTR_HOT inline const netlist_sig_t last_Q() const
527    {
528        assert(family() == LOGIC);
529        return m_last.Q;
530    }
531
532    ATTR_HOT inline const netlist_sig_t new_Q() const
533    {
534        assert(family() == LOGIC);
535        return m_new.Q;
536    }
537
528538    ATTR_HOT inline const double Q_Analog() const
529539    {
530540        //assert(object_type(SIGNAL_MASK) == SIGNAL_ANALOG);
r26599r26600
544554
545555protected:
546556
547    /* prohibit use in device functions
548     * current (pending) state can be inquired using new_Q()
549     */
550    ATTR_HOT inline const netlist_sig_t Q() const
551    {
552        //assert(object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
553      assert(family() == LOGIC);
554        return m_cur.Q;
555    }
556557
557558    hybrid_t m_last;
558559    hybrid_t m_cur;
r26599r26600
561562    UINT32 m_num_cons;
562563
563564private:
564    ATTR_HOT void update_dev(const netlist_core_terminal_t *inp, const UINT32 mask);
565    ATTR_HOT void update_dev(const netlist_core_terminal_t *inp, const UINT32 mask) const;
565566
566567    netlist_time m_time;
567568    INT32        m_active;
r26599r26600
575576// net_output_t
576577// ----------------------------------------------------------------------------------------
577578
578class NETLIB_NAME(mainclock);
579class NETLIB_NAME(solver);
580
581579class netlist_output_t : public netlist_core_terminal_t
582580{
583581public:
r26599r26600
860858
861859   ATTR_COLD netlist_setup_t *setup() const { return m_setup; }
862860
863   ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
861   // FIXME: Legacy ... this needs to disappear
862   ATTR_COLD bool variable_input_count() const { return m_variable_input_count; }
864863
865864   ATTR_COLD void register_sub(netlist_device_t &dev, const pstring &name);
866    ATTR_COLD void register_subalias(const pstring &name, netlist_core_terminal_t &term);
865    ATTR_COLD void register_subalias(const pstring &name, const netlist_core_terminal_t &term);
867866
868867    ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port);
869868
870869   ATTR_COLD void register_output(const pstring &name, netlist_output_t &out);
871870
872   ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
871   ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, const netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
873872
874   ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState);
875   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);
873   ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState);
874   ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState);
876875
877    ATTR_HOT virtual void update_terminals() { }
878
879876    /* driving logic outputs don't count in here */
880877   netlist_list_t<pstring, 20> m_terminals;
881878
882879protected:
883880
884   virtual void update() { }
885   virtual void start() { }
881   ATTR_HOT virtual void update() { }
882   ATTR_HOT virtual void start() { }
883    ATTR_HOT virtual void update_terminals() { }
886884
887885    template <class C, class T>
888886   ATTR_COLD void register_param(const pstring &sname, C &param, const T initialVal)
r26599r26600
915913
916914   ATTR_COLD void set_clock_freq(UINT64 clockfreq);
917915
916    ATTR_HOT inline const queue_t &queue() const { return m_queue; }
918917    ATTR_HOT inline queue_t &queue() { return m_queue; }
919918
920919   ATTR_HOT inline void push_to_queue(netlist_net_t &out, const netlist_time &attime)
r26599r26600
922921      m_queue.push(queue_t::entry_t(attime, out));
923922   }
924923
925   ATTR_HOT NETLIB_NAME(solver) *solver() { return m_solver; }
924   ATTR_HOT NETLIB_NAME(solver) *solver() const { return m_solver; }
926925
927926   ATTR_HOT void process_queue(INT32 &atime);
928927
r26599r26600
961960class nld_a_to_d_proxy : public netlist_device_t
962961{
963962public:
964   nld_a_to_d_proxy(netlist_input_t &in_proxied)
963   ATTR_COLD nld_a_to_d_proxy(netlist_input_t &in_proxied)
965964         : netlist_device_t()
966965   {
967966      //assert(in_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
r26599r26600
970969      m_I.m_low_thresh_V = in_proxied.m_low_thresh_V;
971970   }
972971
973   virtual ~nld_a_to_d_proxy() {}
972   ATTR_COLD virtual ~nld_a_to_d_proxy() {}
974973
975974   netlist_analog_input_t m_I;
976975   netlist_ttl_output_t m_Q;
977976
978977protected:
979   void start()
978   ATTR_COLD void start()
980979   {
981980      m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE);
982981
r26599r26600
10031002class nld_d_to_a_proxy : public netlist_device_t
10041003{
10051004public:
1006   nld_d_to_a_proxy(netlist_output_t &out_proxied)
1005    ATTR_COLD nld_d_to_a_proxy(netlist_output_t &out_proxied)
10071006         : netlist_device_t()
10081007   {
10091008      //assert(out_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
r26599r26600
10121011      m_high_V = out_proxied.m_high_V;
10131012   }
10141013
1015   virtual ~nld_d_to_a_proxy() {}
1014    ATTR_COLD virtual ~nld_d_to_a_proxy() {}
10161015
10171016   netlist_ttl_input_t m_I;
10181017   netlist_analog_output_t m_Q;
10191018
10201019protected:
1021   void start()
1020   ATTR_COLD void start()
10221021   {
10231022      m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE);
10241023      m_Q.init_object(*this, "Q");
r26599r26600
11581157   return net().Q_Analog();
11591158}
11601159
1160//FIXME: Legacy ... must be removed
11611161ATTR_HOT inline const bool netlist_analog_input_t::is_highz() const
11621162{
11631163   return (net().Q_Analog() == NETLIST_HIGHIMP_V);
trunk/src/emu/netlist/nl_setup.c
r26599r26600
88#include "nl_base.h"
99#include "nl_setup.h"
1010#include "nl_parser.h"
11#include "nl_util.h"
1112#include "devices/nld_system.h"
13#include "devices/nld_solver.h"
1214
1315static NETLIST_START(base)
1416   NETDEV_TTL_CONST(ttlhigh, 1)
r26599r26600
139141    fatalerror("Unknown object type %d\n", in.type());
140142}
141143
142void 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)
144void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, const netlist_input_t::state_e state)
143145{
144146    switch (obj.type())
145147    {
r26599r26600
248250       if (dev == NULL)
249251           fatalerror("Device for %s not found\n", name.cstr());
250252       int c = atoi(ret.substr(p+2,ret.len()-p-3));
251       temp = dev->name() + "." + dev->m_terminals.item(c)->object();
253       temp = dev->name() + "." + dev->m_terminals[c];
252254       // reresolve ....
253255       do {
254256           ret = temp;
r26599r26600
517519void netlist_setup_t::start_devices(void)
518520{
519521
522    if (getenv("NL_LOGS"))
523    {
524        NL_VERBOSE_OUT(("Creating dynamic logs ...\n"));
525        nl_util::pstring_list ll = nl_util::split(getenv("NL_LOGS"), ":");
526        for (int i=0; i < ll.count(); i++)
527        {
528            printf("%d: <%s>\n",i, ll[i].cstr());
529            netlist_device_t *nc = factory().new_device_by_classname("nld_log", *this);
530            pstring name = "log" + ll[i];
531            register_dev(nc, name);
532            register_link(name + ".I", ll[i]);
533        }
534    }
535
536
520537    NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n"));
521538    /* find the main clock ... */
522539    for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
trunk/src/emu/netlist/nl_util.h
r0r26600
1/*
2 * nl_util.h
3 *
4 */
5
6#ifndef NL_UTIL_H_
7#define NL_UTIL_H_
8
9#include "pstring.h"
10#include "nl_lists.h"
11
12class nl_util
13{
14// this is purely static
15private:
16    nl_util() {};
17
18public:
19    typedef netlist_list_t<pstring, 10> pstring_list;
20
21    static pstring_list split(const pstring &str, const pstring &onstr)
22    {
23        pstring_list temp;
24
25        int p = 0;
26        int pn;
27
28        pn = str.find(onstr, p);
29        while (pn>=0)
30        {
31            temp.add(str.substr(p, pn - p));
32            p = pn + onstr.len();
33            pn = str.find(onstr, p);
34        }
35        if (p<str.len())
36            temp.add(str.substr(p));
37        return temp;
38    }
39};
40
41#endif /* NL_UTIL_H_ */
Property changes on: trunk/src/emu/netlist/nl_util.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/emu/netlist/nl_lists.h
r26599r26600
3535      m_ptr = m_list;
3636      m_ptr--;
3737   }
38
39    ATTR_COLD netlist_list_t(const netlist_list_t &rhs)
40    {
41        m_list = new entry_t[m_num_elements];
42        m_ptr = m_list;
43        m_ptr--;
44        for (int i=0; i<rhs.count(); i++)
45        {
46            this->add(rhs[i]);
47        }
48    }
49
50    ATTR_COLD netlist_list_t &operator=(const netlist_list_t &rhs)
51    {
52        for (int i=0; i<rhs.count(); i++)
53        {
54            this->add(rhs[i]);
55        }
56        return *this;
57    }
58
59
3860   ATTR_COLD ~netlist_list_t()
3961   {
4062      delete[] m_list;
r26599r26600
87109   ATTR_HOT inline entry_t *first() const { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
88110    ATTR_HOT inline entry_t *next(entry_t *lc) const { return (lc < last() ? lc + 1 : NULL ); }
89111   ATTR_HOT inline entry_t *last() const { return m_ptr; }
90   ATTR_HOT inline entry_t *item(int i) const { return &m_list[i]; }
91112   ATTR_HOT inline int count() const { return m_ptr - m_list + 1; }
92113   ATTR_HOT inline bool empty() const { return (m_ptr < m_list); }
93114   ATTR_HOT inline void reset() { m_ptr = m_list - 1; }
115
116    //ATTR_HOT inline entry_t *item(int i) const { return &m_list[i]; }
117   ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index].m_obj; }
118    ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index].m_obj; }
119
94120private:
95121   entry_t * m_ptr;
96122   entry_t * m_list;
trunk/src/emu/netlist/devices/nld_log.c
r26599r26600
2424    fclose(m_file);
2525}
2626
27NETLIB_START(logD)
28{
29    NETLIB_NAME(log)::start();
30    register_input("I2", m_I2);
31}
32
33NETLIB_UPDATE(logD)
34{
35    fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I) - INPANALOG(m_I2));
36}
37
2738// FIXME: Implement wav later, this must be clock triggered device where the input to be written
2839//        is on a subdevice ...
2940#if 0
trunk/src/emu/netlist/devices/nld_system.c
r26599r26600
7878}
7979
8080// ----------------------------------------------------------------------------------------
81// netlist_matrix_solver
81// logic_input
8282// ----------------------------------------------------------------------------------------
8383
84
85ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets)
84NETLIB_START(logic_input)
8685{
87    for (netlist_net_t::list_t::entry_t *pn = nets.first(); pn != NULL; pn = nets.next(pn))
88    {
89        NL_VERBOSE_OUT(("setting up net\n"));
90
91        m_nets.add(pn->object());
92        pn->object()->m_solver = this;
93
94        for (netlist_core_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
95        {
96            switch (p->type())
97            {
98                case netlist_terminal_t::TERMINAL:
99                    switch (p->netdev().family())
100                    {
101                        case netlist_device_t::CAPACITOR:
102                            if (!m_steps.contains(&p->netdev()))
103                                m_steps.add(&p->netdev());
104                            break;
105                        case netlist_device_t::DIODE:
106                        //case netlist_device_t::VCVS:
107                        //case netlist_device_t::BJT_SWITCH:
108                            if (!m_dynamic.contains(&p->netdev()))
109                                m_dynamic.add(&p->netdev());
110                            break;
111                        default:
112                            break;
113                    }
114                    pn->object()->m_terms.add(static_cast<netlist_terminal_t *>(p));
115                    NL_VERBOSE_OUT(("Added terminal\n"));
116                    break;
117                case netlist_terminal_t::INPUT:
118                    if (!m_inps.contains(&p->netdev()))
119                        m_inps.add(&p->netdev());
120                    NL_VERBOSE_OUT(("Added input\n"));
121                    break;
122                default:
123                    fatalerror("unhandled element found\n");
124                    break;
125            }
126        }
127    }
86    register_output("Q", m_Q);
12887}
12988
130ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta)
89NETLIB_UPDATE(logic_input)
13190{
132    const double dd = delta.as_double();
133    for (dev_list_t::entry_t *p = m_steps.first(); p != NULL; p = m_steps.next(p))
134        p->object()->step_time(dd);
13591}
13692
137ATTR_HOT inline void netlist_matrix_solver_t::update_inputs()
138{
139    for (dev_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
140        p->object()->update_dev();
141}
142
143
144ATTR_HOT inline bool netlist_matrix_solver_t::solve()
145{
146    bool resched = false;
147
148    /* update all non-linear devices  */
149    for (dev_list_t::entry_t *p = m_dynamic.first(); p != NULL; p = m_dynamic.next(p))
150        p->object()->update_terminals();
151
152    for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
153    {
154        netlist_net_t *net = pn->object();
155
156        double gtot = 0;
157        double gabs = 0;
158        double iIdr = 0;
159        const netlist_net_t::terminal_list_t &terms = net->m_terms;
160#if 1
161        switch (terms.count())
162        {
163            case 1:
164                {
165                    const netlist_terminal_t *pt = terms.first()->object();
166                    gtot = pt->m_gt;
167                    gabs = fabs(pt->m_go);
168                    iIdr = pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
169                }
170                break;
171            case 2:
172                {
173                    const netlist_terminal_t *pt1 = terms.first()->object();
174                    const netlist_terminal_t *pt2 = terms.item(1)->object();
175                    gtot = pt1->m_gt + pt2->m_gt;
176                    gabs = fabs(pt1->m_go) + fabs(pt2->m_go);
177                    iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
178                         + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog();
179                }
180                break;
181            case 3:
182                {
183                    const netlist_terminal_t *pt1 = terms.first()->object();
184                    const netlist_terminal_t *pt2 = terms.item(1)->object();
185                    const netlist_terminal_t *pt3 = terms.item(2)->object();
186                    gtot = pt1->m_gt + pt2->m_gt + pt3->m_gt;
187                    gabs = fabs(pt1->m_go) + fabs(pt2->m_go) + fabs(pt3->m_go);
188                    iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
189                         + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog()
190                         + pt3->m_Idr + pt3->m_go * pt3->m_otherterm->net().Q_Analog();
191                }
192                break;
193            default:
194                for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
195                {
196                    netlist_terminal_t *pt = e->object();
197                    gtot += pt->m_gt;
198                    gabs += fabs(pt->m_go);
199                    iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
200                }
201                break;
202        }
203#else
204        for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
205        {
206            netlist_terminal_t *pt = e->object();
207            gtot += pt->m_gt;
208            gabs += fabs(pt->m_go);
209            iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
210        }
211#endif
212        double new_val;
213        gabs *= m_convergence_factor;
214        if (gabs > gtot)
215            new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
216        else
217            new_val = iIdr / gtot;
218
219        if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
220            resched = true;
221        net->m_cur.Analog = net->m_new.Analog = new_val;
222
223        NL_VERBOSE_OUT(("Info: %d\n", pn->object()->m_num_cons));
224        NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
225    }
226    return resched;
227}
228
22993// ----------------------------------------------------------------------------------------
230// solver
94// analog_input
23195// ----------------------------------------------------------------------------------------
23296
233typedef netlist_net_t::list_t  *net_groups_t;
234
235static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t *net)
97NETLIB_START(analog_input)
23698{
237    if (net->isRailNet())
238        return true;
239    for (int i = 0; i <= cur_group; i++)
240    {
241        if (groups[i].contains(net))
242            return true;
243    }
244    return false;
99    register_output("Q", m_Q);
245100}
246101
247static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net)
102NETLIB_UPDATE(analog_input)
248103{
249    /* add the net */
250    groups[cur_group].add(net);
251    for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next)
252    {
253        if (p->isType(netlist_terminal_t::TERMINAL))
254        {
255            netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p);
256            netlist_net_t *nnet = &pt->m_otherterm->net();
257            if (!already_processed(groups, cur_group, nnet))
258                process_net(groups, cur_group, nnet);
259        }
260    }
261104}
262
263
264NETLIB_START(solver)
265{
266    register_output("Q_sync", m_Q_sync);
267    register_output("Q_step", m_Q_step);
268    //register_input("FB", m_feedback);
269
270    register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(10).as_double());
271    m_nt_sync_delay = m_sync_delay.Value();
272
273    register_param("FREQ", m_freq, 48000.0);
274    m_inc = netlist_time::from_hz(m_freq.Value());
275
276    register_param("ACCURACY", m_accuracy, 1e-3);
277    register_param("CONVERG", m_convergence, 0.3);
278
279    register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE);
280    register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE);
281    m_last_step = netlist_time::zero;
282
283}
284
285NETLIB_UPDATE_PARAM(solver)
286{
287    m_inc = netlist_time::from_hz(m_freq.Value());
288}
289
290NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
291{
292    netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first();
293    while (e != NULL)
294    {
295        netlist_matrix_solver_t::list_t::entry_t *en = m_mat_solvers.next(e);
296        delete e->object();
297        e = en;
298    }
299
300    netlist_net_t::list_t::entry_t *p = m_nets.first();
301    while (p != NULL)
302    {
303        netlist_net_t::list_t::entry_t *pn = m_nets.next(p);
304        delete p->object();
305        p = pn;
306    }
307}
308
309NETLIB_FUNC_VOID(solver, post_start, ())
310{
311    netlist_net_t::list_t groups[100];
312    int cur_group = -1;
313
314    NL_VERBOSE_OUT(("post start solver ...\n"));
315
316    // delete empty nets ...
317    for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
318    {
319        if (pn->object()->m_head == NULL)
320        {
321            NL_VERBOSE_OUT(("Deleting net ...\n"));
322            netlist_net_t *to_delete = pn->object();
323            m_nets.remove(to_delete);
324            delete to_delete;
325            pn--;
326        }
327    }
328
329    printf("Scanning net groups ...\n");
330    // determine net groups
331    for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
332    {
333        if (!already_processed(groups, cur_group, pn->object()))
334        {
335            cur_group++;
336            process_net(groups, cur_group, pn->object());
337        }
338    }
339
340    // setup the solvers
341    printf("Found %d net groups in %d nets\n", cur_group + 1, m_nets.count());
342    for (int i = 0; i <= cur_group; i++)
343    {
344        netlist_matrix_solver_t *ms = new netlist_matrix_solver_t;
345        ms->m_accuracy = m_accuracy.Value();
346        ms->m_convergence_factor = m_convergence.Value();
347        ms->setup(groups[i]);
348        m_mat_solvers.add(ms);
349        printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
350        printf("  has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic");
351    }
352
353}
354
355NETLIB_UPDATE(solver)
356{
357    //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc  );
358    //OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc  );
359
360    bool resched = false;
361    int  resched_cnt = 0;
362    netlist_time now = netlist().time();
363    netlist_time delta = now - m_last_step;
364
365    if (delta >= m_inc)
366    {
367        NL_VERBOSE_OUT(("Step!\n"));
368        /* update all terminals for new time step */
369        m_last_step = now;
370        for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
371        {
372            e->object()->step(delta);
373        }
374    }
375    bool global_resched = false;
376    for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
377    {
378        resched_cnt = (e->object()->is_dynamic() ? 0 : 1);
379        do {
380            resched = e->object()->solve();
381            resched_cnt++;
382        } while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
383        global_resched = global_resched || resched;
384    }
385    //if (global_resched)
386    //    printf("rescheduled\n");
387    if (global_resched)
388    {
389        schedule();
390    }
391    else
392    {
393        /* update all inputs connected */
394        for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
395        {
396            e->object()->update_inputs();
397        }
398
399        /* step circuit */
400        if (!m_Q_step.net().is_queued())
401            m_Q_step.net().push_to_queue(m_inc);
402    }
403
404}
trunk/src/emu/netlist/devices/nld_log.h
r26599r26600
2727NETLIB_DEVICE(log,
2828    ~NETLIB_NAME(log)();
2929    netlist_analog_input_t m_I;
30private:
30protected:
3131    FILE *m_file;
3232);
3333
34#define NETDEV_LOGD(_name, _I, _I2)                                                 \
35        NET_REGISTER_DEV(logD, _name)                                               \
36        NET_CONNECT(_name, I, _I)                                                   \
37        NET_CONNECT(_name, I2, _I2)
38
39NETLIB_DEVICE_DERIVED(logD, log,
40    netlist_analog_input_t m_I2;
41);
42
3443#if 0
3544NETLIB_DEVICE(wav,
3645    ~NETLIB_NAME(wav)();
trunk/src/emu/netlist/devices/nld_system.h
r26599r26600
3030#define NETDEV_CLOCK(_name)                                                         \
3131        NET_REGISTER_DEV(clock, _name)
3232
33#define NETDEV_SOLVER(_name)                                                        \
34        NET_REGISTER_DEV(solver, _name)
33#define NETDEV_LOGIC_INPUT(_name)                                                   \
34        NET_REGISTER_DEV(logic_input, _name)
3535
36// .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)
36#define NETDEV_ANALOG_INPUT(_name)                                                  \
37        NET_REGISTER_DEV(analog_input, _name)
3738
39#define NETDEV_CALLBACK(_name, _IN)                                                 \
40        NET_REGISTER_DEV(analog_callback, _name)                                    \
41        NET_CONNECT(_name, IN, _IN)
42
3843// ----------------------------------------------------------------------------------------
3944// netdev_*_const
4045// ----------------------------------------------------------------------------------------
r26599r26600
7580    netlist_time m_inc;
7681);
7782
78// ----------------------------------------------------------------------------------------
79// solver
80// ----------------------------------------------------------------------------------------
8183
82class netlist_matrix_solver_t
83{
84public:
85    typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
86    typedef netlist_core_device_t::list_t dev_list_t;
87    ATTR_COLD void setup(netlist_net_t::list_t &nets);
88
89    // return true if a reschedule is needed ...
90    ATTR_HOT bool solve();
91    ATTR_HOT void step(const netlist_time delta);
92    ATTR_HOT void update_inputs();
93
94    ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
95
96    double m_accuracy;
97    double m_convergence_factor;
98
99private:
100    netlist_net_t::list_t m_nets;
101    dev_list_t m_dynamic;
102    dev_list_t m_inps;
103    dev_list_t m_steps;
104};
105
106NETLIB_DEVICE_WITH_PARAMS(solver,
107        typedef netlist_core_device_t::list_t dev_list_t;
108
109        netlist_ttl_input_t m_fb_sync;
110        netlist_ttl_output_t m_Q_sync;
111
112        netlist_ttl_input_t m_fb_step;
113        netlist_ttl_output_t m_Q_step;
114
115        netlist_param_double_t m_freq;
116        netlist_param_double_t m_sync_delay;
117        netlist_param_double_t m_accuracy;
118        netlist_param_double_t m_convergence;
119
120        netlist_time m_inc;
121        netlist_time m_last_step;
122        netlist_time m_nt_sync_delay;
123
124        netlist_matrix_solver_t::list_t m_mat_solvers;
125public:
126
127        ~NETLIB_NAME(solver)();
128
129        netlist_net_t::list_t m_nets;
130
131        ATTR_HOT inline void schedule();
132
133        ATTR_COLD void post_start();
134);
135
136inline void NETLIB_NAME(solver)::schedule()
137{
138    // FIXME: time should be parameter;
139    if (!m_Q_sync.net().is_queued())
140        m_Q_sync.net().push_to_queue(m_nt_sync_delay);
141}
142
14384// ----------------------------------------------------------------------------------------
14485// netdev_callback
14586// ----------------------------------------------------------------------------------------
r26599r26600
168109   netlist_output_delegate m_callback;
169110};
170111
112// ----------------------------------------------------------------------------------------
113// Special support devices ...
114// ----------------------------------------------------------------------------------------
171115
116NETLIB_DEVICE(logic_input,
117    netlist_ttl_output_t m_Q;
118);
172119
120NETLIB_DEVICE(analog_input,
121    netlist_analog_output_t m_Q;
122);
123
124
125
173126#endif /* NLD_SYSTEM_H_ */
trunk/src/emu/netlist/devices/nld_twoterm.c
r26599r26600
55
66#include "nld_twoterm.h"
77#include "nld_system.h"
8#include "nld_solver.h"
89
910// ----------------------------------------------------------------------------------------
1011// nld_twoterm
trunk/src/emu/netlist/devices/nld_9316.c
r0r26600
1/*
2 * nld_9316.c
3 *
4 */
5
6#include "nld_9316.h"
7
8NETLIB_START(nic9316)
9{
10    register_sub(sub, "sub");
11
12    register_subalias("CLK", sub.m_clk);
13
14    register_input("ENP", m_ENP);
15    register_input("ENT", m_ENT);
16    register_input("CLRQ", m_CLRQ);
17    register_input("LOADQ", m_LOADQ);
18
19    register_subalias("A", sub.m_A);
20    register_subalias("B", sub.m_B);
21    register_subalias("C", sub.m_C);
22    register_subalias("D", sub.m_D);
23
24    register_subalias("QA", sub.m_QA);
25    register_subalias("QB", sub.m_QB);
26    register_subalias("QC", sub.m_QC);
27    register_subalias("QD", sub.m_QD);
28    register_subalias("RC", sub.m_RC);
29
30}
31
32NETLIB_START(nic9316_sub)
33{
34    m_cnt = 0;
35    m_loadq = 1;
36    m_ent = 1;
37
38    register_input("CLK", m_clk, netlist_input_t::STATE_INP_LH);
39
40    register_input("A", m_A, netlist_input_t::STATE_INP_PASSIVE);
41    register_input("B", m_B, netlist_input_t::STATE_INP_PASSIVE);
42    register_input("C", m_C, netlist_input_t::STATE_INP_PASSIVE);
43    register_input("D", m_D, netlist_input_t::STATE_INP_PASSIVE);
44
45    register_output("QA", m_QA);
46    register_output("QB", m_QB);
47    register_output("QC", m_QC);
48    register_output("QD", m_QD);
49    register_output("RC", m_RC);
50
51}
52
53NETLIB_UPDATE(nic9316_sub)
54{
55    if (m_loadq)
56    {
57        m_cnt = ( m_cnt + 1) & 0x0f;
58        update_outputs();
59    }
60    else
61    {
62        m_cnt = (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
63        update_outputs_all();
64    }
65    OUTLOGIC(m_RC, m_ent & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
66}
67
68NETLIB_UPDATE(nic9316)
69{
70    sub.m_loadq = INPLOGIC(m_LOADQ);
71    sub.m_ent = INPLOGIC(m_ENT);
72    const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
73
74    if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) & clrq)
75    {
76        sub.m_clk.activate_lh();
77    }
78    else
79    {
80        sub.m_clk.inactivate();
81        if (!clrq & (sub.m_cnt>0))
82        {
83            sub.m_cnt = 0;
84            sub.update_outputs();
85            OUTLOGIC(sub.m_RC, 0, NLTIME_FROM_NS(20));
86            return;
87        }
88    }
89    OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
90}
91
92NETLIB_FUNC_VOID(nic9316_sub, update_outputs_all, (void))
93{
94    const netlist_time out_delay = NLTIME_FROM_NS(20);
95    OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
96    OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
97    OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
98    OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
99}
100
101NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
102{
103    const netlist_time out_delay = NLTIME_FROM_NS(20);
104#if 0
105    OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
106    OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
107    OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
108    OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
109#else
110    if ((m_cnt & 1) == 1)
111        OUTLOGIC(m_QA, 1, out_delay);
112    else
113    {
114        OUTLOGIC(m_QA, 0, out_delay);
115        switch (m_cnt)
116        {
117        case 0x00:
118            OUTLOGIC(m_QB, 0, out_delay);
119            OUTLOGIC(m_QC, 0, out_delay);
120            OUTLOGIC(m_QD, 0, out_delay);
121            break;
122        case 0x02:
123        case 0x06:
124        case 0x0A:
125        case 0x0E:
126            OUTLOGIC(m_QB, 1, out_delay);
127            break;
128        case 0x04:
129        case 0x0C:
130            OUTLOGIC(m_QB, 0, out_delay);
131            OUTLOGIC(m_QC, 1, out_delay);
132            break;
133        case 0x08:
134            OUTLOGIC(m_QB, 0, out_delay);
135            OUTLOGIC(m_QC, 0, out_delay);
136            OUTLOGIC(m_QD, 1, out_delay);
137            break;
138        }
139
140    }
141#endif
142}
143
Property changes on: trunk/src/emu/netlist/devices/nld_9316.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/netlist/devices/nld_7490.c
r0r26600
1/*
2 * nld_7490.c
3 *
4 */
5
6#include "nld_7490.h"
7
8NETLIB_START(nic7490)
9{
10    m_cnt = 0;
11
12    register_input("CLK", m_clk);
13    register_input("R1",  m_R1);
14    register_input("R2",  m_R2);
15    register_input("R91", m_R91);
16    register_input("R92", m_R92);
17
18    register_output("QA", m_Q[0]);
19    register_output("QB", m_Q[1]);
20    register_output("QC", m_Q[2]);
21    register_output("QD", m_Q[3]);
22}
23
24NETLIB_UPDATE(nic7490)
25{
26    if (INPLOGIC(m_R91) & INPLOGIC(m_R92))
27    {
28        m_cnt = 9;
29        update_outputs();
30    }
31    else if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
32    {
33        m_cnt = 0;
34        update_outputs();
35    }
36    else if (INP_HL(m_clk))
37    {
38        m_cnt++;
39        if (m_cnt >= 10)
40            m_cnt = 0;
41        update_outputs();
42    }
43}
44#if 0
45NETLIB_FUNC_VOID(nic7490, update_outputs)
46{
47    OUTLOGIC(m_QA, (m_cnt >> 0) & 1, NLTIME_FROM_NS(18));
48    OUTLOGIC(m_QB, (m_cnt >> 1) & 1, NLTIME_FROM_NS(36));
49    OUTLOGIC(m_QC, (m_cnt >> 2) & 1, NLTIME_FROM_NS(54));
50    OUTLOGIC(m_QD, (m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
51}
52#else
53NETLIB_FUNC_VOID(nic7490, update_outputs, (void))
54{
55    const netlist_time delay[4] = { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54), NLTIME_FROM_NS(72) };
56    for (int i=0; i<4; i++)
57        OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
58}
59#endif
Property changes on: trunk/src/emu/netlist/devices/nld_7490.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/netlist/devices/nld_9316.h
r0r26600
1// license:GPL-2.0+
2// copyright-holders:Couriersud
3/*
4 * nld_9316.h
5 *
6 *  DM9316: Synchronous 4-Bit Counters
7 *
8 *          +--------------+
9 *    CLEAR |1     ++    16| VCC
10 *    CLOCK |2           15| RC (Ripple Carry)
11 *        A |3           14| QA
12 *        B |4    9316   13| QB
13 *        C |5           12| QC
14 *        D |6           11| QD
15 * Enable P |7           10| Enable T
16 *      GND |8            9| LOAD
17 *          +--------------+
18 *
19 *          Counter Sequence
20 *
21 *          +-------++----+----+----+----+----+
22 *          | COUNT || QD | QC | QB | QA | RC |
23 *          +=======++====+====+====+====+====+
24 *          |    0  ||  0 |  0 |  0 |  0 |  0 |
25 *          |    1  ||  0 |  0 |  0 |  1 |  0 |
26 *          |    2  ||  0 |  0 |  1 |  0 |  0 |
27 *          |    3  ||  0 |  0 |  1 |  1 |  0 |
28 *          |    4  ||  0 |  1 |  0 |  0 |  0 |
29 *          |    5  ||  0 |  1 |  0 |  1 |  0 |
30 *          |    6  ||  0 |  1 |  1 |  0 |  0 |
31 *          |    7  ||  0 |  1 |  1 |  1 |  0 |
32 *          |    8  ||  1 |  0 |  0 |  0 |  0 |
33 *          |    9  ||  1 |  0 |  0 |  1 |  0 |
34 *          |   10  ||  1 |  0 |  1 |  0 |  0 |
35 *          |   11  ||  1 |  0 |  1 |  1 |  0 |
36 *          |   12  ||  1 |  1 |  0 |  0 |  0 |
37 *          |   13  ||  1 |  1 |  0 |  1 |  0 |
38 *          |   14  ||  1 |  1 |  1 |  0 |  0 |
39 *          |   15  ||  1 |  1 |  1 |  1 |  1 |
40 *          +-------++----+----+----+----+----+
41 *
42 *          Reset count function: Please refer to
43 *          National Semiconductor datasheet (timing diagramm)
44 *
45 *  Naming conventions follow National Semiconductor datasheet
46 *
47 */
48
49#ifndef NLD_9316_H_
50#define NLD_9316_H_
51
52#include "../nl_base.h"
53
54#define TTL_9316(_name, _CLK, _ENP, _ENT, _CLRQ, _LOADQ, _A, _B, _C, _D)            \
55        NET_REGISTER_DEV(nic9316, _name)                                            \
56        NET_CONNECT(_name, CLK, _CLK)                                               \
57        NET_CONNECT(_name, ENP,  _ENP)                                              \
58        NET_CONNECT(_name, ENT,  _ENT)                                              \
59        NET_CONNECT(_name, CLRQ, _CLRQ)                                             \
60        NET_CONNECT(_name, LOADQ,_LOADQ)                                            \
61        NET_CONNECT(_name, A,    _A)                                                \
62        NET_CONNECT(_name, B,    _B)                                                \
63        NET_CONNECT(_name, C,    _C)                                                \
64        NET_CONNECT(_name, D,    _D)
65
66NETLIB_SUBDEVICE(nic9316_sub,
67    ATTR_HOT void update_outputs_all();
68    ATTR_HOT void update_outputs();
69
70    netlist_ttl_input_t m_clk;
71
72    netlist_ttl_input_t m_A;
73    netlist_ttl_input_t m_B;
74    netlist_ttl_input_t m_C;
75    netlist_ttl_input_t m_D;
76
77    UINT8 m_cnt;
78    netlist_sig_t m_loadq;
79    netlist_sig_t m_ent;
80
81    netlist_ttl_output_t m_QA;
82    netlist_ttl_output_t m_QB;
83    netlist_ttl_output_t m_QC;
84    netlist_ttl_output_t m_QD;
85    netlist_ttl_output_t m_RC;
86);
87
88NETLIB_DEVICE(nic9316,
89    NETLIB_NAME(nic9316_sub) sub;
90    netlist_ttl_input_t m_ENP;
91    netlist_ttl_input_t m_ENT;
92    netlist_ttl_input_t m_CLRQ;
93    netlist_ttl_input_t m_LOADQ;
94);
95
96#endif /* NLD_9316_H_ */
Property changes on: trunk/src/emu/netlist/devices/nld_9316.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/netlist/devices/nld_7490.h
r0r26600
1// license:GPL-2.0+
2// copyright-holders:Couriersud
3/*
4 * nld_7490.h
5 *
6 *  DM7490: Decade Counters
7 *
8 *          +--------------+
9 *        B |1     ++    14| A
10 *      R01 |2           13| NC
11 *      R02 |3           12| QA
12 *       NC |4    7490   11| QD
13 *      VCC |5           10| GND
14 *      R91 |6            9| QB
15 *      R92 |7            8| QC
16 *          +--------------+
17 *
18 *          Counter Sequence
19 *
20 *          +-------++----+----+----+----+
21 *          | COUNT || QD | QC | QB | QA |
22 *          +=======++====+====+====+====+
23 *          |    0  ||  0 |  0 |  0 |  0 |
24 *          |    1  ||  0 |  0 |  0 |  1 |
25 *          |    2  ||  0 |  0 |  1 |  0 |
26 *          |    3  ||  0 |  0 |  1 |  1 |
27 *          |    4  ||  0 |  1 |  0 |  0 |
28 *          |    5  ||  0 |  1 |  0 |  1 |
29 *          |    6  ||  0 |  1 |  1 |  0 |
30 *          |    7  ||  0 |  1 |  1 |  1 |
31 *          |    8  ||  1 |  0 |  0 |  0 |
32 *          |    9  ||  1 |  0 |  0 |  1 |
33 *          +-------++----+----+----+----+
34 *
35 *          Note A Output QA is connected to input B for BCD count
36 *
37 *          Reset Count Function table
38 *
39 *          +-----+-----+-----+-----++----+----+----+----+
40 *          | R01 | R02 | R91 | R92 || QD | QC | QB | QA |
41 *          +=====+=====+=====+=====++====+====+====+====+
42 *          |  1  |  1  |  0  |  X  ||  0 |  0 |  0 |  0 |
43 *          |  1  |  1  |  X  |  0  ||  0 |  0 |  0 |  0 |
44 *          |  X  |  X  |  1  |  1  ||  1 |  0 |  0 |  1 |
45 *          |  X  |  0  |  X  |  0  ||       COUNT       |
46 *          |  0  |  X  |  0  |  X  ||       COUNT       |
47 *          |  0  |  X  |  X  |  0  ||       COUNT       |
48 *          |  X  |  0  |  0  |  X  ||       COUNT       |
49 *          +-----+-----+-----+-----++----+----+----+----+
50 *
51 *  Naming conventions follow National Semiconductor datasheet
52 *
53 */
54
55#ifndef NLD_7490_H_
56#define NLD_7490_H_
57
58#include "../nl_base.h"
59
60#define TTL_7490(_name, _CLK, _R1, _R2, _R91, _R92)                                 \
61        NET_REGISTER_DEV(nic7490, _name)                                            \
62        NET_CONNECT(_name, CLK, _CLK)                                               \
63        NET_CONNECT(_name, R1,  _R1)                                                \
64        NET_CONNECT(_name, R2,  _R2)                                                \
65        NET_CONNECT(_name, R91, _R91)                                               \
66        NET_CONNECT(_name, R92, _R92)
67
68
69NETLIB_DEVICE(nic7490,
70    ATTR_HOT void update_outputs();
71
72    netlist_ttl_input_t m_R1;
73    netlist_ttl_input_t m_R2;
74    netlist_ttl_input_t m_R91;
75    netlist_ttl_input_t m_R92;
76    netlist_ttl_input_t m_clk;
77
78    UINT8 m_cnt;
79
80    netlist_ttl_output_t m_Q[4];
81);
82
83#endif /* NLD_7490_H_ */
Property changes on: trunk/src/emu/netlist/devices/nld_7490.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/netlist/devices/nld_solver.c
r0r26600
1/*
2 * nld_solver.c
3 *
4 */
5
6#include "nld_solver.h"
7
8// ----------------------------------------------------------------------------------------
9// netlist_matrix_solver
10// ----------------------------------------------------------------------------------------
11
12
13ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets)
14{
15    for (netlist_net_t::list_t::entry_t *pn = nets.first(); pn != NULL; pn = nets.next(pn))
16    {
17        NL_VERBOSE_OUT(("setting up net\n"));
18
19        m_nets.add(pn->object());
20        pn->object()->m_solver = this;
21
22        for (netlist_core_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
23        {
24            switch (p->type())
25            {
26                case netlist_terminal_t::TERMINAL:
27                    switch (p->netdev().family())
28                    {
29                        case netlist_device_t::CAPACITOR:
30                            if (!m_steps.contains(&p->netdev()))
31                                m_steps.add(&p->netdev());
32                            break;
33                        case netlist_device_t::DIODE:
34                        //case netlist_device_t::VCVS:
35                        //case netlist_device_t::BJT_SWITCH:
36                            if (!m_dynamic.contains(&p->netdev()))
37                                m_dynamic.add(&p->netdev());
38                            break;
39                        default:
40                            break;
41                    }
42                    pn->object()->m_terms.add(static_cast<netlist_terminal_t *>(p));
43                    NL_VERBOSE_OUT(("Added terminal\n"));
44                    break;
45                case netlist_terminal_t::INPUT:
46                    if (!m_inps.contains(&p->netdev()))
47                        m_inps.add(&p->netdev());
48                    NL_VERBOSE_OUT(("Added input\n"));
49                    break;
50                default:
51                    fatalerror("unhandled element found\n");
52                    break;
53            }
54        }
55    }
56}
57
58ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta)
59{
60    const double dd = delta.as_double();
61    for (dev_list_t::entry_t *p = m_steps.first(); p != NULL; p = m_steps.next(p))
62        p->object()->step_time(dd);
63}
64
65ATTR_HOT inline void netlist_matrix_solver_t::update_inputs()
66{
67    for (dev_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
68        p->object()->update_dev();
69}
70
71
72ATTR_HOT inline bool netlist_matrix_solver_t::solve()
73{
74    bool resched = false;
75
76    /* update all non-linear devices  */
77    for (dev_list_t::entry_t *p = m_dynamic.first(); p != NULL; p = m_dynamic.next(p))
78        p->object()->update_terminals();
79
80    for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
81    {
82        netlist_net_t *net = pn->object();
83
84        double gtot = 0;
85        double gabs = 0;
86        double iIdr = 0;
87        const netlist_net_t::terminal_list_t &terms = net->m_terms;
88#if 1
89        switch (terms.count())
90        {
91            case 1:
92                {
93                    const netlist_terminal_t *pt = terms.first()->object();
94                    gtot = pt->m_gt;
95                    gabs = fabs(pt->m_go);
96                    iIdr = pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
97                }
98                break;
99            case 2:
100                {
101                    const netlist_terminal_t *pt1 = terms[0];
102                    const netlist_terminal_t *pt2 = terms[1];
103                    gtot = pt1->m_gt + pt2->m_gt;
104                    gabs = fabs(pt1->m_go) + fabs(pt2->m_go);
105                    iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
106                         + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog();
107                }
108                break;
109            case 3:
110                {
111                    const netlist_terminal_t *pt1 = terms[0];
112                    const netlist_terminal_t *pt2 = terms[1];
113                    const netlist_terminal_t *pt3 = terms[2];
114                    gtot = pt1->m_gt + pt2->m_gt + pt3->m_gt;
115                    gabs = fabs(pt1->m_go) + fabs(pt2->m_go) + fabs(pt3->m_go);
116                    iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
117                         + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog()
118                         + pt3->m_Idr + pt3->m_go * pt3->m_otherterm->net().Q_Analog();
119                }
120                break;
121            default:
122                for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
123                {
124                    netlist_terminal_t *pt = e->object();
125                    gtot += pt->m_gt;
126                    gabs += fabs(pt->m_go);
127                    iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
128                }
129                break;
130        }
131#else
132        for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
133        {
134            netlist_terminal_t *pt = e->object();
135            gtot += pt->m_gt;
136            gabs += fabs(pt->m_go);
137            iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
138        }
139#endif
140        double new_val;
141        gabs *= m_convergence_factor;
142        if (gabs > gtot)
143            new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
144        else
145            new_val = iIdr / gtot;
146
147        if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
148            resched = true;
149        net->m_cur.Analog = net->m_new.Analog = new_val;
150
151        NL_VERBOSE_OUT(("Info: %d\n", pn->object()->m_num_cons));
152        NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
153    }
154    return resched;
155}
156
157// ----------------------------------------------------------------------------------------
158// solver
159// ----------------------------------------------------------------------------------------
160
161typedef netlist_net_t::list_t  *net_groups_t;
162
163static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t *net)
164{
165    if (net->isRailNet())
166        return true;
167    for (int i = 0; i <= cur_group; i++)
168    {
169        if (groups[i].contains(net))
170            return true;
171    }
172    return false;
173}
174
175static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net)
176{
177    /* add the net */
178    groups[cur_group].add(net);
179    for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next)
180    {
181        if (p->isType(netlist_terminal_t::TERMINAL))
182        {
183            netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p);
184            netlist_net_t *nnet = &pt->m_otherterm->net();
185            if (!already_processed(groups, cur_group, nnet))
186                process_net(groups, cur_group, nnet);
187        }
188    }
189}
190
191
192NETLIB_START(solver)
193{
194    register_output("Q_sync", m_Q_sync);
195    register_output("Q_step", m_Q_step);
196    //register_input("FB", m_feedback);
197
198    register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(10).as_double());
199    m_nt_sync_delay = m_sync_delay.Value();
200
201    register_param("FREQ", m_freq, 48000.0);
202    m_inc = netlist_time::from_hz(m_freq.Value());
203
204    register_param("ACCURACY", m_accuracy, 1e-3);
205    register_param("CONVERG", m_convergence, 0.3);
206
207    register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE);
208    register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE);
209    m_last_step = netlist_time::zero;
210
211}
212
213NETLIB_UPDATE_PARAM(solver)
214{
215    m_inc = netlist_time::from_hz(m_freq.Value());
216}
217
218NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
219{
220    netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first();
221    while (e != NULL)
222    {
223        netlist_matrix_solver_t::list_t::entry_t *en = m_mat_solvers.next(e);
224        delete e->object();
225        e = en;
226    }
227
228    netlist_net_t::list_t::entry_t *p = m_nets.first();
229    while (p != NULL)
230    {
231        netlist_net_t::list_t::entry_t *pn = m_nets.next(p);
232        delete p->object();
233        p = pn;
234    }
235}
236
237NETLIB_FUNC_VOID(solver, post_start, ())
238{
239    netlist_net_t::list_t groups[100];
240    int cur_group = -1;
241
242    NL_VERBOSE_OUT(("post start solver ...\n"));
243
244    // delete empty nets ...
245    for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
246    {
247        if (pn->object()->m_head == NULL)
248        {
249            NL_VERBOSE_OUT(("Deleting net ...\n"));
250            netlist_net_t *to_delete = pn->object();
251            m_nets.remove(to_delete);
252            delete to_delete;
253            pn--;
254        }
255    }
256
257    printf("Scanning net groups ...\n");
258    // determine net groups
259    for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
260    {
261        if (!already_processed(groups, cur_group, pn->object()))
262        {
263            cur_group++;
264            process_net(groups, cur_group, pn->object());
265        }
266    }
267
268    // setup the solvers
269    printf("Found %d net groups in %d nets\n", cur_group + 1, m_nets.count());
270    for (int i = 0; i <= cur_group; i++)
271    {
272        netlist_matrix_solver_t *ms = new netlist_matrix_solver_t;
273        ms->m_accuracy = m_accuracy.Value();
274        ms->m_convergence_factor = m_convergence.Value();
275        ms->setup(groups[i]);
276        m_mat_solvers.add(ms);
277        printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
278        printf("  has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic");
279    }
280
281}
282
283NETLIB_UPDATE(solver)
284{
285    //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc  );
286    //OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc  );
287
288    bool resched = false;
289    int  resched_cnt = 0;
290    netlist_time now = netlist().time();
291    netlist_time delta = now - m_last_step;
292
293    if (delta >= m_inc)
294    {
295        NL_VERBOSE_OUT(("Step!\n"));
296        /* update all terminals for new time step */
297        m_last_step = now;
298        for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
299        {
300            e->object()->step(delta);
301        }
302    }
303    bool global_resched = false;
304    for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
305    {
306        resched_cnt = (e->object()->is_dynamic() ? 0 : 1);
307        do {
308            resched = e->object()->solve();
309            resched_cnt++;
310        } while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
311        global_resched = global_resched || resched;
312    }
313    //if (global_resched)
314    //    printf("rescheduled\n");
315    if (global_resched)
316    {
317        schedule();
318    }
319    else
320    {
321        /* update all inputs connected */
322        for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
323        {
324            e->object()->update_inputs();
325        }
326
327        /* step circuit */
328        if (!m_Q_step.net().is_queued())
329            m_Q_step.net().push_to_queue(m_inc);
330    }
331
332}
333
Property changes on: trunk/src/emu/netlist/devices/nld_solver.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/netlist/devices/nld_7493.h
r26599r26600
33/*
44 * nld_7493.h
55 *
6 *  DM7493: Quad 2-Input NAND Gates
6 *  DM7493: Binary Counters
77 *
88 *          +--------------+
99 *        B |1     ++    14| A
r26599r26600
3838 *          |   15  ||  1 |  1 |  1 |  1 |
3939 *          +-------++----+----+----+----+
4040 *
41 *          Note C Output QA is connected to input B
42 *
4143 *          Reset Count Function table
4244 *
4345 *          +-----+-----++----+----+----+----+
44 *          | R01 | R01 || QD | QC | QB | QA |
46 *          | R01 | R02 || QD | QC | QB | QA |
4547 *          +=====+=====++====+====+====+====+
4648 *          |  1  |  1  ||  0 |  0 |  0 |  0 |
4749 *          |  0  |  X  ||       COUNT       |
trunk/src/emu/netlist/devices/nld_solver.h
r0r26600
1/*
2 * nld_solver.h
3 *
4 */
5
6#ifndef NLD_SOLVER_H_
7#define NLD_SOLVER_H_
8
9#include "../nl_setup.h"
10#include "../nl_base.h"
11
12// ----------------------------------------------------------------------------------------
13// Macros
14// ----------------------------------------------------------------------------------------
15
16#define NETDEV_SOLVER(_name)                                                        \
17        NET_REGISTER_DEV(solver, _name)
18
19// ----------------------------------------------------------------------------------------
20// solver
21// ----------------------------------------------------------------------------------------
22
23class netlist_matrix_solver_t
24{
25public:
26    typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
27    typedef netlist_core_device_t::list_t dev_list_t;
28    ATTR_COLD void setup(netlist_net_t::list_t &nets);
29
30    // return true if a reschedule is needed ...
31    ATTR_HOT bool solve();
32    ATTR_HOT void step(const netlist_time delta);
33    ATTR_HOT void update_inputs();
34
35    ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
36
37    double m_accuracy;
38    double m_convergence_factor;
39
40private:
41    netlist_net_t::list_t m_nets;
42    dev_list_t m_dynamic;
43    dev_list_t m_inps;
44    dev_list_t m_steps;
45};
46
47NETLIB_DEVICE_WITH_PARAMS(solver,
48        typedef netlist_core_device_t::list_t dev_list_t;
49
50        netlist_ttl_input_t m_fb_sync;
51        netlist_ttl_output_t m_Q_sync;
52
53        netlist_ttl_input_t m_fb_step;
54        netlist_ttl_output_t m_Q_step;
55
56        netlist_param_double_t m_freq;
57        netlist_param_double_t m_sync_delay;
58        netlist_param_double_t m_accuracy;
59        netlist_param_double_t m_convergence;
60
61        netlist_time m_inc;
62        netlist_time m_last_step;
63        netlist_time m_nt_sync_delay;
64
65        netlist_matrix_solver_t::list_t m_mat_solvers;
66public:
67
68        ~NETLIB_NAME(solver)();
69
70        netlist_net_t::list_t m_nets;
71
72        ATTR_HOT inline void schedule();
73
74        ATTR_COLD void post_start();
75);
76
77inline void NETLIB_NAME(solver)::schedule()
78{
79    // FIXME: time should be parameter;
80    if (!m_Q_sync.net().is_queued())
81        m_Q_sync.net().push_to_queue(m_nt_sync_delay);
82}
83
84
85#endif /* NLD_SOLVER_H_ */
Property changes on: trunk/src/emu/netlist/devices/nld_solver.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/emu/netlist/devices/net_lib.c
r26599r26600
5050#include "net_lib.h"
5151#include "nld_system.h"
5252
53NETLIB_START(logic_input)
54{
55   register_output("Q", m_Q);
56}
57
58NETLIB_UPDATE(logic_input)
59{
60}
61
62NETLIB_START(analog_input)
63{
64   register_output("Q", m_Q);
65}
66
67NETLIB_UPDATE(analog_input)
68{
69}
70
7153NETLIB_START(nicMultiSwitch)
7254{
73   static const char *sIN[8] = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8" };
74   int i;
55    static const char *sIN[8] = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8" };
56    int i;
7557
76   m_position = 0;
77   m_low.initial(0);
58    m_position = 0;
59    m_low.initial(0);
7860
79   for (i=0; i<8; i++)
80   {
81      register_input(sIN[i], m_I[i]);
82      m_low.net().register_con(m_I[i]);
83      //m_I[i].set_net(m_low.m_net);
84   }
85   register_param("POS", m_POS, 0);
86   register_output("Q", m_Q);
61    for (i=0; i<8; i++)
62    {
63        register_input(sIN[i], m_I[i]);
64        m_low.net().register_con(m_I[i]);
65        //m_I[i].set_net(m_low.m_net);
66    }
67    register_param("POS", m_POS, 0);
68    register_output("Q", m_Q);
8769
88   m_variable_input_count = true;
70    m_variable_input_count = true;
8971}
9072
9173NETLIB_UPDATE(nicMultiSwitch)
9274{
93   assert(m_position<8);
94   OUTANALOG(m_Q, INPANALOG(m_I[m_position]), NLTIME_FROM_NS(1));
75    assert(m_position<8);
76    OUTANALOG(m_Q, INPANALOG(m_I[m_position]), NLTIME_FROM_NS(1));
9577}
9678
9779NETLIB_UPDATE_PARAM(nicMultiSwitch)
9880{
99   m_position = m_POS.Value();
100   //update();
81    m_position = m_POS.Value();
82    //update();
10183}
10284
10385NETLIB_START(nicMixer8)
10486{
105   static const char *sI[8] = { "I1", "I2", "I3", "I4", "I5", "I6", "I7", "I8" };
106   static const char *sR[8] = { "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8" };
107   int i;
87    static const char *sI[8] = { "I1", "I2", "I3", "I4", "I5", "I6", "I7", "I8" };
88    static const char *sR[8] = { "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8" };
89    int i;
10890
109   m_low.initial(0);
91    m_low.initial(0);
11092
111   for (i=0; i<8; i++)
112   {
113      register_input(sI[i], m_I[i]);
114      m_low.net().register_con(m_I[i]);
115      //m_I[i].set_output(m_low);
116      register_param(sR[i], m_R[i], 1e12);
117   }
118   register_output("Q", m_Q);
93    for (i=0; i<8; i++)
94    {
95        register_input(sI[i], m_I[i]);
96        m_low.net().register_con(m_I[i]);
97        //m_I[i].set_output(m_low);
98        register_param(sR[i], m_R[i], 1e12);
99    }
100    register_output("Q", m_Q);
119101
120   m_variable_input_count = true;
102    m_variable_input_count = true;
121103}
122104
123105NETLIB_UPDATE(nicMixer8)
124106{
125   int i;
126   double r = 0;
107    int i;
108    double r = 0;
127109
128   for (i=0; i<8; i++)
129   {
130      r += m_w[i] * INPANALOG(m_I[i]);
131   }
132   OUTANALOG(m_Q, r, NLTIME_IMMEDIATE);
110    for (i=0; i<8; i++)
111    {
112        r += m_w[i] * INPANALOG(m_I[i]);
113    }
114    OUTANALOG(m_Q, r, NLTIME_IMMEDIATE);
133115}
134116
135117NETLIB_UPDATE_PARAM(nicMixer8)
136118{
137   double t = 0;
138   int i;
119    double t = 0;
120    int i;
139121
140   for (i=0; i<8; i++)
141      t += 1.0 / m_R[i].Value();
142   t = 1.0 / t;
122    for (i=0; i<8; i++)
123        t += 1.0 / m_R[i].Value();
124    t = 1.0 / t;
143125
144   for (i=0; i<8; i++)
145      m_w[i] = t / m_R[i].Value();
126    for (i=0; i<8; i++)
127        m_w[i] = t / m_R[i].Value();
146128}
147129
148130
149131
150132NETLIB_START(nicRSFF)
151133{
152   register_input("S", m_S);
153   register_input("R", m_R);
154   register_output("Q", m_Q);
155   register_output("QQ", m_QQ);
156   m_Q.initial(0);
157   m_QQ.initial(1);
134    register_input("S", m_S);
135    register_input("R", m_R);
136    register_output("Q", m_Q);
137    register_output("QQ", m_QQ);
138    m_Q.initial(0);
139    m_QQ.initial(1);
158140}
159141
160142NETLIB_UPDATE(nicRSFF)
161143{
162   if (INPLOGIC(m_S))
163   {
164      OUTLOGIC(m_Q,  1, NLTIME_FROM_NS(10));
165      OUTLOGIC(m_QQ, 0, NLTIME_FROM_NS(10));
166   }
167   else if (INPLOGIC(m_R))
168   {
169      OUTLOGIC(m_Q,  0, NLTIME_FROM_NS(10));
170      OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10));
171   }
144    if (INPLOGIC(m_S))
145    {
146        OUTLOGIC(m_Q,  1, NLTIME_FROM_NS(10));
147        OUTLOGIC(m_QQ, 0, NLTIME_FROM_NS(10));
148    }
149    else if (INPLOGIC(m_R))
150    {
151        OUTLOGIC(m_Q,  0, NLTIME_FROM_NS(10));
152        OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10));
153    }
172154}
173155
174156
175157NETLIB_START(nicNE555N_MSTABLE)
176158{
177   register_input("TRIG", m_trigger);
178   register_input("CV", m_CV);
159    register_input("TRIG", m_trigger);
160    register_input("CV", m_CV);
179161
180   register_output("Q", m_Q);
181   register_param("R", m_R, 0.0);
182   register_param("C", m_C, 0.0);
183   register_param("VS", m_VS, 5.0);
184   register_param("VL", m_VL, 0.0 *5.0);
162    register_output("Q", m_Q);
163    register_param("R", m_R, 0.0);
164    register_param("C", m_C, 0.0);
165    register_param("VS", m_VS, 5.0);
166    register_param("VL", m_VL, 0.0 *5.0);
185167
186   m_THRESHOLD_OUT.init_object(*this, "THRESHOLD");
187   register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, netlist_input_t::STATE_INP_ACTIVE);
168    m_THRESHOLD_OUT.init_object(*this, "THRESHOLD");
169    register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, netlist_input_t::STATE_INP_ACTIVE);
188170
189   m_Q.initial(5.0 * 0.4);
190   m_last = false;
171    m_Q.initial(5.0 * 0.4);
172    m_last = false;
191173}
192174
193175inline double NETLIB_NAME(nicNE555N_MSTABLE)::nicNE555N_cv()
194176{
195   return (m_CV.is_highz() ? 0.67 * m_VS.Value() : INPANALOG(m_CV));
177    return (m_CV.is_highz() ? 0.67 * m_VS.Value() : INPANALOG(m_CV));
196178}
197179
198180inline double NETLIB_NAME(nicNE555N_MSTABLE)::nicNE555N_clamp(const double v, const double a, const double b)
199181{
200   double ret = v;
201   if (ret >  m_VS.Value() - a)
202      ret = m_VS.Value() - a;
203   if (ret < b)
204      ret = b;
205   return ret;
182    double ret = v;
183    if (ret >  m_VS.Value() - a)
184        ret = m_VS.Value() - a;
185    if (ret < b)
186        ret = b;
187    return ret;
206188}
207189
208190NETLIB_UPDATE_PARAM(nicNE555N_MSTABLE)
r26599r26600
211193
212194NETLIB_UPDATE(nicNE555N_MSTABLE)
213195{
214   update_param(); // FIXME : m_CV should be on a sub device ...
196    update_param(); // FIXME : m_CV should be on a sub device ...
215197
216   double vt = nicNE555N_clamp(nicNE555N_cv(), 0.7, 1.4);
217   bool bthresh = (INPANALOG(m_THRESHOLD) > vt);
218   bool btrig = (INPANALOG(m_trigger) > nicNE555N_clamp(nicNE555N_cv() * 0.5, 0.7, 1.4));
219   bool out = m_last;
198    double vt = nicNE555N_clamp(nicNE555N_cv(), 0.7, 1.4);
199    bool bthresh = (INPANALOG(m_THRESHOLD) > vt);
200    bool btrig = (INPANALOG(m_trigger) > nicNE555N_clamp(nicNE555N_cv() * 0.5, 0.7, 1.4));
201    bool out = m_last;
220202
221   if (!btrig)
222   {
223      out = true;
224   }
225   else if (bthresh)
226   {
227      out = false;
228   }
203    if (!btrig)
204    {
205        out = true;
206    }
207    else if (bthresh)
208    {
209        out = false;
210    }
229211
230   if (!m_last && out)
231   {
232      double vl = m_VL.Value();
233      double time;
212    if (!m_last && out)
213    {
214        double vl = m_VL.Value();
215        double time;
234216
235      // FIXME : m_CV should be on a sub device ...
217        // FIXME : m_CV should be on a sub device ...
236218
237      // TI datasheet states minimum pulse of 10 us
238      if (vt<vl)
239         time = 10;
240      else
241      {
242         time = - log((m_VS.Value()-vt)/(m_VS.Value()-vl)) * m_R.Value() * m_C.Value() * 1.0e6; // in us
243         if (time < 10.0)
244            time = 10.0;
245      }
219        // TI datasheet states minimum pulse of 10 us
220        if (vt<vl)
221            time = 10;
222        else
223        {
224            time = - log((m_VS.Value()-vt)/(m_VS.Value()-vl)) * m_R.Value() * m_C.Value() * 1.0e6; // in us
225            if (time < 10.0)
226                time = 10.0;
227        }
246228
247      OUTANALOG(m_Q, m_VS.Value() * 0.7, NLTIME_FROM_NS(100));
248      OUTANALOG(m_THRESHOLD_OUT, m_VS.Value(), NLTIME_FROM_US(time ));
249   }
250   else if (m_last && !out)
251   {
252      OUTANALOG(m_Q, 0.25, NLTIME_FROM_NS(100));
253      OUTANALOG(m_THRESHOLD_OUT, 0.0, NLTIME_FROM_NS(1));
254   }
255   m_last = out;
229        OUTANALOG(m_Q, m_VS.Value() * 0.7, NLTIME_FROM_NS(100));
230        OUTANALOG(m_THRESHOLD_OUT, m_VS.Value(), NLTIME_FROM_US(time ));
231    }
232    else if (m_last && !out)
233    {
234        OUTANALOG(m_Q, 0.25, NLTIME_FROM_NS(100));
235        OUTANALOG(m_THRESHOLD_OUT, 0.0, NLTIME_FROM_NS(1));
236    }
237    m_last = out;
256238}
257239
258240NETLIB_START(nic7448)
259241{
260   register_sub(sub, "sub");
242    register_sub(sub, "sub");
261243
262   register_subalias("A0", sub.m_A0);
263   register_subalias("A1", sub.m_A1);
264   register_subalias("A2", sub.m_A2);
265   register_subalias("A3", sub.m_A3);
266   register_input("LTQ", m_LTQ);
267   register_input("BIQ", m_BIQ);
268   register_subalias("RBIQ",sub.m_RBIQ);
244    register_subalias("A0", sub.m_A0);
245    register_subalias("A1", sub.m_A1);
246    register_subalias("A2", sub.m_A2);
247    register_subalias("A3", sub.m_A3);
248    register_input("LTQ", m_LTQ);
249    register_input("BIQ", m_BIQ);
250    register_subalias("RBIQ",sub.m_RBIQ);
269251
270   register_subalias("a", sub.m_a);
271   register_subalias("b", sub.m_b);
272   register_subalias("c", sub.m_c);
273   register_subalias("d", sub.m_d);
274   register_subalias("e", sub.m_e);
275   register_subalias("f", sub.m_f);
276   register_subalias("g", sub.m_g);
252    register_subalias("a", sub.m_a);
253    register_subalias("b", sub.m_b);
254    register_subalias("c", sub.m_c);
255    register_subalias("d", sub.m_d);
256    register_subalias("e", sub.m_e);
257    register_subalias("f", sub.m_f);
258    register_subalias("g", sub.m_g);
277259}
278260
279261NETLIB_UPDATE(nic7448)
280262{
281   if (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ))
282   {
283      sub.update_outputs(8);
284   }
285   else if (!INPLOGIC(m_BIQ))
286   {
287      sub.update_outputs(15);
288   }
263    if (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ))
264    {
265        sub.update_outputs(8);
266    }
267    else if (!INPLOGIC(m_BIQ))
268    {
269        sub.update_outputs(15);
270    }
289271
290   if (!INPLOGIC(m_BIQ) || (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ)))
291   {
292      sub.m_A0.inactivate();
293      sub.m_A1.inactivate();
294      sub.m_A2.inactivate();
295      sub.m_A3.inactivate();
296      sub.m_RBIQ.inactivate();
297   } else {
298      sub.m_RBIQ.activate();
299      sub.m_A3.activate();
300      sub.m_A2.activate();
301      sub.m_A1.activate();
302      sub.m_A0.activate();
303      sub.update();
304   }
272    if (!INPLOGIC(m_BIQ) || (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ)))
273    {
274        sub.m_A0.inactivate();
275        sub.m_A1.inactivate();
276        sub.m_A2.inactivate();
277        sub.m_A3.inactivate();
278        sub.m_RBIQ.inactivate();
279    } else {
280        sub.m_RBIQ.activate();
281        sub.m_A3.activate();
282        sub.m_A2.activate();
283        sub.m_A1.activate();
284        sub.m_A0.activate();
285        sub.update();
286    }
305287
306288}
307289
r26599r26600
326308
327309NETLIB_UPDATE(nic7448_sub)
328310{
329   UINT8 v;
311    UINT8 v;
330312
331   v = (INPLOGIC(m_A0) << 0) | (INPLOGIC(m_A1) << 1) | (INPLOGIC(m_A2) << 2) | (INPLOGIC(m_A3) << 3);
332   if ((!INPLOGIC(m_RBIQ) && (v==0)))
333         v = 15;
334   update_outputs(v);
313    v = (INPLOGIC(m_A0) << 0) | (INPLOGIC(m_A1) << 1) | (INPLOGIC(m_A2) << 2) | (INPLOGIC(m_A3) << 3);
314    if ((!INPLOGIC(m_RBIQ) && (v==0)))
315            v = 15;
316    update_outputs(v);
335317}
336318
337319NETLIB_FUNC_VOID(nic7448_sub, update_outputs, (UINT8 v))
338320{
339   assert(v<16);
340   if (v != m_state)
341   {
342      OUTLOGIC(m_a, tab7448[v][0], NLTIME_FROM_NS(100));
343      OUTLOGIC(m_b, tab7448[v][1], NLTIME_FROM_NS(100));
344      OUTLOGIC(m_c, tab7448[v][2], NLTIME_FROM_NS(100));
345      OUTLOGIC(m_d, tab7448[v][3], NLTIME_FROM_NS(100));
346      OUTLOGIC(m_e, tab7448[v][4], NLTIME_FROM_NS(100));
347      OUTLOGIC(m_f, tab7448[v][5], NLTIME_FROM_NS(100));
348      OUTLOGIC(m_g, tab7448[v][6], NLTIME_FROM_NS(100));
349      m_state = v;
350   }
321    assert(v<16);
322    if (v != m_state)
323    {
324        OUTLOGIC(m_a, tab7448[v][0], NLTIME_FROM_NS(100));
325        OUTLOGIC(m_b, tab7448[v][1], NLTIME_FROM_NS(100));
326        OUTLOGIC(m_c, tab7448[v][2], NLTIME_FROM_NS(100));
327        OUTLOGIC(m_d, tab7448[v][3], NLTIME_FROM_NS(100));
328        OUTLOGIC(m_e, tab7448[v][4], NLTIME_FROM_NS(100));
329        OUTLOGIC(m_f, tab7448[v][5], NLTIME_FROM_NS(100));
330        OUTLOGIC(m_g, tab7448[v][6], NLTIME_FROM_NS(100));
331        m_state = v;
332    }
351333}
352334
353335const UINT8 NETLIB_NAME(nic7448_sub)::tab7448[16][7] =
354336{
355      {   1, 1, 1, 1, 1, 1, 0 },  /* 00 - not blanked ! */
356      {   0, 1, 1, 0, 0, 0, 0 },  /* 01 */
357      {   1, 1, 0, 1, 1, 0, 1 },  /* 02 */
358      {   1, 1, 1, 1, 0, 0, 1 },  /* 03 */
359      {   0, 1, 1, 0, 0, 1, 1 },  /* 04 */
360      {   1, 0, 1, 1, 0, 1, 1 },  /* 05 */
361      {   0, 0, 1, 1, 1, 1, 1 },  /* 06 */
362      {   1, 1, 1, 0, 0, 0, 0 },  /* 07 */
363      {   1, 1, 1, 1, 1, 1, 1 },  /* 08 */
364      {   1, 1, 1, 0, 0, 1, 1 },  /* 09 */
365      {   0, 0, 0, 1, 1, 0, 1 },  /* 10 */
366      {   0, 0, 1, 1, 0, 0, 1 },  /* 11 */
367      {   0, 1, 0, 0, 0, 1, 1 },  /* 12 */
368      {   1, 0, 0, 1, 0, 1, 1 },  /* 13 */
369      {   0, 0, 0, 1, 1, 1, 1 },  /* 14 */
370      {   0, 0, 0, 0, 0, 0, 0 },  /* 15 */
337        {   1, 1, 1, 1, 1, 1, 0 },  /* 00 - not blanked ! */
338        {   0, 1, 1, 0, 0, 0, 0 },  /* 01 */
339        {   1, 1, 0, 1, 1, 0, 1 },  /* 02 */
340        {   1, 1, 1, 1, 0, 0, 1 },  /* 03 */
341        {   0, 1, 1, 0, 0, 1, 1 },  /* 04 */
342        {   1, 0, 1, 1, 0, 1, 1 },  /* 05 */
343        {   0, 0, 1, 1, 1, 1, 1 },  /* 06 */
344        {   1, 1, 1, 0, 0, 0, 0 },  /* 07 */
345        {   1, 1, 1, 1, 1, 1, 1 },  /* 08 */
346        {   1, 1, 1, 0, 0, 1, 1 },  /* 09 */
347        {   0, 0, 0, 1, 1, 0, 1 },  /* 10 */
348        {   0, 0, 1, 1, 0, 0, 1 },  /* 11 */
349        {   0, 1, 0, 0, 0, 1, 1 },  /* 12 */
350        {   1, 0, 0, 1, 0, 1, 1 },  /* 13 */
351        {   0, 0, 0, 1, 1, 1, 1 },  /* 14 */
352        {   0, 0, 0, 0, 0, 0, 0 },  /* 15 */
371353};
372354
373355NETLIB_START(nic7450)
374356{
375   register_input("I1", m_I0);
376   register_input("I2", m_I1);
377   register_input("I3", m_I2);
378   register_input("I4", m_I3);
379   register_output("Q", m_Q);
357    register_input("I1", m_I0);
358    register_input("I2", m_I1);
359    register_input("I3", m_I2);
360    register_input("I4", m_I3);
361    register_output("Q", m_Q);
380362}
381363
382364NETLIB_UPDATE(nic7450)
383365{
384   m_I0.activate();
385   m_I1.activate();
386   m_I2.activate();
387   m_I3.activate();
388   UINT8 t1 = INPLOGIC(m_I0) & INPLOGIC(m_I1);
389   UINT8 t2 = INPLOGIC(m_I2) & INPLOGIC(m_I3);
366    m_I0.activate();
367    m_I1.activate();
368    m_I2.activate();
369    m_I3.activate();
370    UINT8 t1 = INPLOGIC(m_I0) & INPLOGIC(m_I1);
371    UINT8 t2 = INPLOGIC(m_I2) & INPLOGIC(m_I3);
390372#if 0
391   UINT8 t =  (t1 | t2) ^ 1;
392   OUTLOGIC(m_Q, t, t ? NLTIME_FROM_NS(22) : NLTIME_FROM_NS(15));
373    UINT8 t =  (t1 | t2) ^ 1;
374    OUTLOGIC(m_Q, t, t ? NLTIME_FROM_NS(22) : NLTIME_FROM_NS(15));
393375#else
394   const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
376    const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
395377
396   UINT8 res = 0;
397   if (t1 ^ 1)
398   {
399      if (t2 ^ 1)
400      {
401         res = 1;
402      }
403      else
404      {
405         m_I0.inactivate();
406         m_I1.inactivate();
407      }
408   } else {
409      if (t2 ^ 1)
410      {
411         m_I2.inactivate();
412         m_I3.inactivate();
413      }
414   }
415   OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
378    UINT8 res = 0;
379    if (t1 ^ 1)
380    {
381        if (t2 ^ 1)
382        {
383            res = 1;
384        }
385        else
386        {
387            m_I0.inactivate();
388            m_I1.inactivate();
389        }
390    } else {
391        if (t2 ^ 1)
392        {
393            m_I2.inactivate();
394            m_I3.inactivate();
395        }
396    }
397    OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
416398
417399#endif
418400}
419401
420402
421NETLIB_START(nic7483)
422{
423   m_lastr = 0;
424403
425   register_input("A1", m_A1);
426   register_input("A2", m_A2);
427   register_input("A3", m_A3);
428   register_input("A4", m_A4);
429   register_input("B1", m_B1);
430   register_input("B2", m_B2);
431   register_input("B3", m_B3);
432   register_input("B4", m_B4);
433   register_input("CI", m_CI);
434404
435   register_output("SA", m_SA);
436   register_output("SB", m_SB);
437   register_output("SC", m_SC);
438   register_output("SD", m_SD);
439   register_output("CO", m_CO);
440}
441405
442NETLIB_UPDATE(nic7483)
443{
444   UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
445   UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
446
447   UINT8 r = a + b + INPLOGIC(m_CI);
448
449   if (r != m_lastr)
450   {
451      m_lastr = r;
452      OUTLOGIC(m_SA, (r >> 0) & 1, NLTIME_FROM_NS(23));
453      OUTLOGIC(m_SB, (r >> 1) & 1, NLTIME_FROM_NS(23));
454      OUTLOGIC(m_SC, (r >> 2) & 1, NLTIME_FROM_NS(23));
455      OUTLOGIC(m_SD, (r >> 3) & 1, NLTIME_FROM_NS(23));
456      OUTLOGIC(m_CO, (r >> 4) & 1, NLTIME_FROM_NS(23));
457   }
458}
459
460NETLIB_START(nic7490)
461{
462   m_cnt = 0;
463
464   register_input("CLK", m_clk);
465   register_input("R1",  m_R1);
466   register_input("R2",  m_R2);
467   register_input("R91", m_R91);
468   register_input("R92", m_R92);
469
470   register_output("QA", m_Q[0]);
471   register_output("QB", m_Q[1]);
472   register_output("QC", m_Q[2]);
473   register_output("QD", m_Q[3]);
474}
475
476NETLIB_UPDATE(nic7490)
477{
478   if (INPLOGIC(m_R91) & INPLOGIC(m_R92))
479   {
480      m_cnt = 9;
481      update_outputs();
482   }
483   else if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
484   {
485      m_cnt = 0;
486      update_outputs();
487   }
488   else if (INP_HL(m_clk))
489   {
490      m_cnt++;
491      if (m_cnt >= 10)
492         m_cnt = 0;
493      update_outputs();
494   }
495}
496#if 0
497NETLIB_FUNC_VOID(nic7490, update_outputs)
498{
499   OUTLOGIC(m_QA, (m_cnt >> 0) & 1, NLTIME_FROM_NS(18));
500   OUTLOGIC(m_QB, (m_cnt >> 1) & 1, NLTIME_FROM_NS(36));
501   OUTLOGIC(m_QC, (m_cnt >> 2) & 1, NLTIME_FROM_NS(54));
502   OUTLOGIC(m_QD, (m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
503}
504#else
505NETLIB_FUNC_VOID(nic7490, update_outputs, (void))
506{
507   const netlist_time delay[4] = { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54), NLTIME_FROM_NS(72) };
508   for (int i=0; i<4; i++)
509      OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
510}
511#endif
512
513406NETLIB_START(nic74107Asub)
514407{
515408    register_input("CLK", m_clk, netlist_input_t::STATE_INP_HL);
r26599r26600
522415
523416NETLIB_START(nic74107A)
524417{
525   register_sub(sub, "sub");
418    register_sub(sub, "sub");
526419
527   register_subalias("CLK", sub.m_clk);
528   register_input("J", m_J);
529   register_input("K", m_K);
530   register_input("CLRQ", m_clrQ);
531   register_subalias("Q", sub.m_Q);
532   register_subalias("QQ", sub.m_QQ);
420    register_subalias("CLK", sub.m_clk);
421    register_input("J", m_J);
422    register_input("K", m_K);
423    register_input("CLRQ", m_clrQ);
424    register_subalias("Q", sub.m_Q);
425    register_subalias("QQ", sub.m_QQ);
533426
534   sub.m_Q.initial(0);
535   sub.m_QQ.initial(1);
427    sub.m_Q.initial(0);
428    sub.m_QQ.initial(1);
536429}
537430
538431ATTR_HOT inline void NETLIB_NAME(nic74107Asub)::newstate(const netlist_sig_t state)
539432{
540   const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
433    const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
541434#if 1
542   OUTLOGIC(m_Q, state, delay[state ^ 1]);
543   OUTLOGIC(m_QQ, state ^ 1, delay[state]);
435    OUTLOGIC(m_Q, state, delay[state ^ 1]);
436    OUTLOGIC(m_QQ, state ^ 1, delay[state]);
544437#else
545   if (state != Q.new_Q())
546   {
547      Q.setToNoCheck(state, delay[1-state]);
548      QQ.setToNoCheck(1-state, delay[state]);
549   }
438    if (state != Q.new_Q())
439    {
440        Q.setToNoCheck(state, delay[1-state]);
441        QQ.setToNoCheck(1-state, delay[state]);
442    }
550443#endif
551444}
552445
553446NETLIB_UPDATE(nic74107Asub)
554447{
555   {
556      const netlist_sig_t t = m_Q.net().new_Q();
557      newstate((!t & m_Q1) | (t & m_Q2) | m_F);
558      if (!m_Q1)
559         m_clk.inactivate();
560   }
448    {
449        const netlist_sig_t t = m_Q.net().new_Q();
450        newstate((!t & m_Q1) | (t & m_Q2) | m_F);
451        if (!m_Q1)
452            m_clk.inactivate();
453    }
561454}
562455
563456NETLIB_UPDATE(nic74107A)
564457{
565   if (INPLOGIC(m_J) & INPLOGIC(m_K))
566   {
567      sub.m_Q1 = 1;
568      sub.m_Q2 = 0;
569      sub.m_F  = 0;
570   }
571   else if (!INPLOGIC(m_J) & INPLOGIC(m_K))
572   {
573      sub.m_Q1 = 0;
574      sub.m_Q2 = 0;
575      sub.m_F  = 0;
576   }
577   else if (INPLOGIC(m_J) & !INPLOGIC(m_K))
578   {
579      sub.m_Q1 = 0;
580      sub.m_Q2 = 0;
581      sub.m_F  = 1;
582   }
583   else
584   {
585      sub.m_Q1 = 0;
586      sub.m_Q2 = 1;
587      sub.m_F  = 0;
588      sub.m_clk.inactivate();
589   }
590   if (!INPLOGIC(m_clrQ))
591   {
592      sub.m_clk.inactivate();
593      sub.newstate(0);
594   }
595   else if (!sub.m_Q2)
596      sub.m_clk.activate_hl();
597   //if (!sub.m_Q2 & INPLOGIC(m_clrQ))
598   //  sub.m_clk.activate_hl();
458    if (INPLOGIC(m_J) & INPLOGIC(m_K))
459    {
460        sub.m_Q1 = 1;
461        sub.m_Q2 = 0;
462        sub.m_F  = 0;
463    }
464    else if (!INPLOGIC(m_J) & INPLOGIC(m_K))
465    {
466        sub.m_Q1 = 0;
467        sub.m_Q2 = 0;
468        sub.m_F  = 0;
469    }
470    else if (INPLOGIC(m_J) & !INPLOGIC(m_K))
471    {
472        sub.m_Q1 = 0;
473        sub.m_Q2 = 0;
474        sub.m_F  = 1;
475    }
476    else
477    {
478        sub.m_Q1 = 0;
479        sub.m_Q2 = 1;
480        sub.m_F  = 0;
481        sub.m_clk.inactivate();
482    }
483    if (!INPLOGIC(m_clrQ))
484    {
485        sub.m_clk.inactivate();
486        sub.newstate(0);
487    }
488    else if (!sub.m_Q2)
489        sub.m_clk.activate_hl();
490    //if (!sub.m_Q2 & INPLOGIC(m_clrQ))
491    //  sub.m_clk.activate_hl();
599492}
600493
601494NETLIB_START(nic74153)
602495{
603   register_input("A1", m_I[0]);
604   register_input("A2", m_I[1]);
605   register_input("A3", m_I[2]);
606   register_input("A4", m_I[3]);
607   register_input("A", m_A);
608   register_input("B", m_B);
609   register_input("GA", m_GA);
496    register_input("A1", m_I[0]);
497    register_input("A2", m_I[1]);
498    register_input("A3", m_I[2]);
499    register_input("A4", m_I[3]);
500    register_input("A", m_A);
501    register_input("B", m_B);
502    register_input("GA", m_GA);
610503
611   register_output("AY", m_AY);
504    register_output("AY", m_AY);
612505}
613506
614507NETLIB_UPDATE(nic74153)
615508{
616   const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
617   if (!INPLOGIC(m_GA))
618   {
619      UINT8 chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1));
620      UINT8 t = INPLOGIC(m_I[chan]);
621      OUTLOGIC(m_AY, t, delay[t] ); /* data to y only, FIXME */
622   }
623   else
624   {
625      OUTLOGIC(m_AY, 0, delay[0]);
626   }
509    const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
510    if (!INPLOGIC(m_GA))
511    {
512        UINT8 chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1));
513        UINT8 t = INPLOGIC(m_I[chan]);
514        OUTLOGIC(m_AY, t, delay[t] ); /* data to y only, FIXME */
515    }
516    else
517    {
518        OUTLOGIC(m_AY, 0, delay[0]);
519    }
627520}
628521
629NETLIB_START(nic9316)
630{
631   register_sub(sub, "sub");
632522
633   register_subalias("CLK", sub.m_clk);
634
635   register_input("ENP", m_ENP);
636   register_input("ENT", m_ENT);
637   register_input("CLRQ", m_CLRQ);
638   register_input("LOADQ", m_LOADQ);
639
640   register_subalias("A", sub.m_A);
641   register_subalias("B", sub.m_B);
642   register_subalias("C", sub.m_C);
643   register_subalias("D", sub.m_D);
644
645   register_subalias("QA", sub.m_QA);
646   register_subalias("QB", sub.m_QB);
647   register_subalias("QC", sub.m_QC);
648   register_subalias("QD", sub.m_QD);
649   register_subalias("RC", sub.m_RC);
650
651}
652
653NETLIB_START(nic9316_sub)
654{
655    m_cnt = 0;
656    m_loadq = 1;
657    m_ent = 1;
658
659    register_input("CLK", m_clk, netlist_input_t::STATE_INP_LH);
660
661    register_input("A", m_A, netlist_input_t::STATE_INP_PASSIVE);
662    register_input("B", m_B, netlist_input_t::STATE_INP_PASSIVE);
663    register_input("C", m_C, netlist_input_t::STATE_INP_PASSIVE);
664    register_input("D", m_D, netlist_input_t::STATE_INP_PASSIVE);
665
666    register_output("QA", m_QA);
667    register_output("QB", m_QB);
668    register_output("QC", m_QC);
669    register_output("QD", m_QD);
670    register_output("RC", m_RC);
671
672}
673
674NETLIB_UPDATE(nic9316_sub)
675{
676   if (m_loadq)
677   {
678      m_cnt = ( m_cnt + 1) & 0x0f;
679      update_outputs();
680   }
681   else
682   {
683      m_cnt = (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
684      update_outputs_all();
685   }
686   OUTLOGIC(m_RC, m_ent & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
687}
688
689NETLIB_UPDATE(nic9316)
690{
691   sub.m_loadq = INPLOGIC(m_LOADQ);
692   sub.m_ent = INPLOGIC(m_ENT);
693   const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
694
695   if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) & clrq)
696   {
697      sub.m_clk.activate_lh();
698   }
699   else
700   {
701      sub.m_clk.inactivate();
702      if (!clrq & (sub.m_cnt>0))
703      {
704         sub.m_cnt = 0;
705         sub.update_outputs();
706         OUTLOGIC(sub.m_RC, 0, NLTIME_FROM_NS(20));
707         return;
708      }
709   }
710   OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
711}
712
713NETLIB_FUNC_VOID(nic9316_sub, update_outputs_all, (void))
714{
715   const netlist_time out_delay = NLTIME_FROM_NS(20);
716   OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
717   OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
718   OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
719   OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
720}
721
722NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
723{
724   const netlist_time out_delay = NLTIME_FROM_NS(20);
725#if 0
726   OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
727   OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
728   OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
729   OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
730#else
731   if ((m_cnt & 1) == 1)
732      OUTLOGIC(m_QA, 1, out_delay);
733   else
734   {
735      OUTLOGIC(m_QA, 0, out_delay);
736      switch (m_cnt)
737      {
738      case 0x00:
739         OUTLOGIC(m_QB, 0, out_delay);
740         OUTLOGIC(m_QC, 0, out_delay);
741         OUTLOGIC(m_QD, 0, out_delay);
742         break;
743      case 0x02:
744      case 0x06:
745      case 0x0A:
746      case 0x0E:
747         OUTLOGIC(m_QB, 1, out_delay);
748         break;
749      case 0x04:
750      case 0x0C:
751         OUTLOGIC(m_QB, 0, out_delay);
752         OUTLOGIC(m_QC, 1, out_delay);
753         break;
754      case 0x08:
755         OUTLOGIC(m_QB, 0, out_delay);
756         OUTLOGIC(m_QC, 0, out_delay);
757         OUTLOGIC(m_QD, 1, out_delay);
758         break;
759      }
760
761   }
762#endif
763}
764
765523#define xstr(s) # s
766524#define ENTRY1(_nic, _name) m_list.add(new net_device_t_factory< _nic >( # _name, xstr(_nic) ));
767525#define ENTRY(_nic, _name) ENTRY1(NETLIB_NAME(_nic), _name)
r26599r26600
795553    ENTRY(logic_input,          NETDEV_LOGIC_INPUT)
796554    ENTRY(analog_input,         NETDEV_ANALOG_INPUT)
797555    ENTRY(log,                  NETDEV_LOG)
556    ENTRY(logD,                 NETDEV_LOGD)
798557    ENTRY(clock,                NETDEV_CLOCK)
799558    ENTRY(mainclock,            NETDEV_MAINCLOCK)
800559    ENTRY(solver,               NETDEV_SOLVER)
trunk/src/emu/netlist/devices/net_lib.h
r26599r26600
6464#include "nld_7427.h"
6565#include "nld_7430.h"
6666#include "nld_7474.h"
67#include "nld_7483.h"
6768#include "nld_7486.h"
69#include "nld_7490.h"
6870#include "nld_7493.h"
71#include "nld_9316.h"
6972
7073#include "nld_NE555.h"
7174
7275#include "nld_log.h"
7376
77#include "nld_solver.h"
78
7479// this is a bad hack
7580
7681// ----------------------------------------------------------------------------------------
7782// Special chips
7883// ----------------------------------------------------------------------------------------
7984
80#define NETDEV_LOGIC_INPUT(_name)                                                   \
81      NET_REGISTER_DEV(logic_input, _name)
82#define NETDEV_ANALOG_INPUT(_name)                                                  \
83      NET_REGISTER_DEV(analog_input, _name)
84#define NETDEV_CALLBACK(_name, _IN)                                                 \
85      NET_REGISTER_DEV(analog_callback, _name)                                    \
86      NET_CONNECT(_name, IN, _IN)
8785#define NETDEV_SWITCH2(_name, _i1, _i2)                                             \
8886      NET_REGISTER_DEV(nicMultiSwitch, _name)                                     \
8987      NET_CONNECT(_name, i1, _i1)                                                 \
r26599r26600
120118      NET_CONNECT(_name, BIQ, _BIQ)                                               \
121119      NET_CONNECT(_name, RBIQ, _RBIQ)
122120
123#define TTL_7483(_name, _A1, _A2, _A3, _A4, _B1, _B2, _B3, _B4, _CI)                \
124      NET_REGISTER_DEV(nic7483, _name)                                            \
125      NET_CONNECT(_name, A1, _A1)                                                 \
126      NET_CONNECT(_name, A2, _A2)                                                 \
127      NET_CONNECT(_name, A3, _A3)                                                 \
128      NET_CONNECT(_name, A4, _A4)                                                 \
129      NET_CONNECT(_name, B1, _B1)                                                 \
130      NET_CONNECT(_name, B2, _B2)                                                 \
131      NET_CONNECT(_name, B3, _B3)                                                 \
132      NET_CONNECT(_name, B4, _B4)                                                 \
133      NET_CONNECT(_name, CI, _CI)
134
135#define TTL_7490(_name, _CLK, _R1, _R2, _R91, _R92)                                 \
136      NET_REGISTER_DEV(nic7490, _name)                                            \
137      NET_CONNECT(_name, CLK, _CLK)                                               \
138      NET_CONNECT(_name, R1,  _R1)                                                \
139      NET_CONNECT(_name, R2,  _R2)                                                \
140      NET_CONNECT(_name, R91, _R91)                                               \
141      NET_CONNECT(_name, R92, _R92)
142
143121#define TTL_74107A(_name, _CLK, _J, _K, _CLRQ)                                      \
144122      NET_REGISTER_DEV(nic74107A, _name)                                          \
145123      NET_CONNECT(_name, CLK, _CLK)                                               \
r26599r26600
160138      NET_CONNECT(_name, B, _B)                                                   \
161139      NET_CONNECT(_name, GA, _GA)
162140
163#define TTL_9316(_name, _CLK, _ENP, _ENT, _CLRQ, _LOADQ, _A, _B, _C, _D)            \
164      NET_REGISTER_DEV(nic9316, _name)                                            \
165      NET_CONNECT(_name, CLK, _CLK)                                               \
166      NET_CONNECT(_name, ENP,  _ENP)                                              \
167      NET_CONNECT(_name, ENT,  _ENT)                                              \
168      NET_CONNECT(_name, CLRQ, _CLRQ)                                             \
169      NET_CONNECT(_name, LOADQ,_LOADQ)                                            \
170      NET_CONNECT(_name, A,    _A)                                                \
171      NET_CONNECT(_name, B,    _B)                                                \
172      NET_CONNECT(_name, C,    _C)                                                \
173      NET_CONNECT(_name, D,    _D)
174
175141#define NE555N_MSTABLE(_name, _TRIG, _CV)                                           \
176142      NET_REGISTER_DEV(nicNE555N_MSTABLE, _name)                                  \
177143      NET_CONNECT(_name, TRIG, _TRIG)                                             \
r26599r26600
184150      NET_CONNECT(_name, I3, _I3)
185151
186152// ----------------------------------------------------------------------------------------
187// Special support devices ...
188// ----------------------------------------------------------------------------------------
189
190NETLIB_DEVICE(logic_input,
191   netlist_ttl_output_t m_Q;
192);
193
194NETLIB_DEVICE(analog_input,
195   netlist_analog_output_t m_Q;
196);
197
198// ----------------------------------------------------------------------------------------
199153// Special devices ...
200154// ----------------------------------------------------------------------------------------
201155
r26599r26600
308262};
309263
310264
311NETLIB_DEVICE(nic7490,
312   ATTR_HOT void update_outputs();
313
314   netlist_ttl_input_t m_R1;
315   netlist_ttl_input_t m_R2;
316   netlist_ttl_input_t m_R91;
317   netlist_ttl_input_t m_R92;
318   netlist_ttl_input_t m_clk;
319
320   UINT8 m_cnt;
321
322   netlist_ttl_output_t m_Q[4];
323);
324
325265/* ripple-carry counter on low-high clock transition */
326266
327NETLIB_SUBDEVICE(nic9316_sub,
328   ATTR_HOT void update_outputs_all();
329   ATTR_HOT void update_outputs();
330267
331   netlist_ttl_input_t m_clk;
332268
333   netlist_ttl_input_t m_A;
334   netlist_ttl_input_t m_B;
335   netlist_ttl_input_t m_C;
336   netlist_ttl_input_t m_D;
337
338   UINT8 m_cnt;
339   netlist_sig_t m_loadq;
340   netlist_sig_t m_ent;
341
342   netlist_ttl_output_t m_QA;
343   netlist_ttl_output_t m_QB;
344   netlist_ttl_output_t m_QC;
345   netlist_ttl_output_t m_QD;
346   netlist_ttl_output_t m_RC;
347);
348
349NETLIB_DEVICE(nic9316,
350   NETLIB_NAME(nic9316_sub) sub;
351   netlist_ttl_input_t m_ENP;
352   netlist_ttl_input_t m_ENT;
353   netlist_ttl_input_t m_CLRQ;
354   netlist_ttl_input_t m_LOADQ;
355);
356
357NETLIB_DEVICE(nic7483,
358   netlist_ttl_input_t m_CI;
359   netlist_ttl_input_t m_A1;
360   netlist_ttl_input_t m_A2;
361   netlist_ttl_input_t m_A3;
362   netlist_ttl_input_t m_A4;
363   netlist_ttl_input_t m_B1;
364   netlist_ttl_input_t m_B2;
365   netlist_ttl_input_t m_B3;
366   netlist_ttl_input_t m_B4;
367   netlist_ttl_input_t m_clk;
368
369   UINT8 m_lastr;
370
371   netlist_ttl_output_t m_SA;
372   netlist_ttl_output_t m_SB;
373   netlist_ttl_output_t m_SC;
374   netlist_ttl_output_t m_SD;
375   netlist_ttl_output_t m_CO;
376
377);
378
379269/* one half of a nic74153 */
380270
381271NETLIB_DEVICE(nic74153,
trunk/src/emu/netlist/devices/nld_7483.c
r0r26600
1/*
2 * nld_7483.c
3 *
4 */
5
6#include "nld_7483.h"
7
8NETLIB_START(nic7483)
9{
10    m_lastr = 0;
11
12    register_input("A1", m_A1);
13    register_input("A2", m_A2);
14    register_input("A3", m_A3);
15    register_input("A4", m_A4);
16    register_input("B1", m_B1);
17    register_input("B2", m_B2);
18    register_input("B3", m_B3);
19    register_input("B4", m_B4);
20    register_input("C0", m_C0);
21
22    register_output("SA", m_SA);
23    register_output("SB", m_SB);
24    register_output("SC", m_SC);
25    register_output("SD", m_SD);
26    register_output("C4", m_C4);
27}
28
29NETLIB_UPDATE(nic7483)
30{
31    UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
32    UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
33
34    UINT8 r = a + b + INPLOGIC(m_C0);
35
36    if (r != m_lastr)
37    {
38        m_lastr = r;
39        OUTLOGIC(m_SA, (r >> 0) & 1, NLTIME_FROM_NS(23));
40        OUTLOGIC(m_SB, (r >> 1) & 1, NLTIME_FROM_NS(23));
41        OUTLOGIC(m_SC, (r >> 2) & 1, NLTIME_FROM_NS(23));
42        OUTLOGIC(m_SD, (r >> 3) & 1, NLTIME_FROM_NS(23));
43        OUTLOGIC(m_C4, (r >> 4) & 1, NLTIME_FROM_NS(23));
44    }
45}
46
Property changes on: trunk/src/emu/netlist/devices/nld_7483.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/emu/netlist/devices/nld_7483.h
r0r26600
1// license:GPL-2.0+
2// copyright-holders:Couriersud
3/*
4 * nld_7483.h
5 *
6 *  DM7483: 4-Bit Binary Adder with Fast Carry
7 *
8 *          +--------------+
9 *       A4 |1     ++    16| B4
10 *       Ʃ3 |2           15| Ʃ3
11 *       A3 |3           14| C4
12 *       B3 |4    7483   13| C0
13 *      VCC |5           12| GND
14 *       Ʃ3 |6           11| B1
15 *       B2 |7           10| A1
16 *       A2 |8            9| Ʃ3
17 *          +--------------+
18 *
19 *          Ʃ = (A + B + C) & 0x0f
20 *
21 *          C4 = (A + B + C) > 15 ? 1 : 0
22 *
23 *  Naming conventions follow Fairchild Semiconductor datasheet
24 *
25 */
26
27#ifndef NLD_7483_H_
28#define NLD_7483_H_
29
30#include "../nl_base.h"
31
32#define TTL_7483(_name, _A1, _A2, _A3, _A4, _B1, _B2, _B3, _B4, _CI)                \
33        NET_REGISTER_DEV(nic7483, _name)                                            \
34        NET_CONNECT(_name, A1, _A1)                                                 \
35        NET_CONNECT(_name, A2, _A2)                                                 \
36        NET_CONNECT(_name, A3, _A3)                                                 \
37        NET_CONNECT(_name, A4, _A4)                                                 \
38        NET_CONNECT(_name, B1, _B1)                                                 \
39        NET_CONNECT(_name, B2, _B2)                                                 \
40        NET_CONNECT(_name, B3, _B3)                                                 \
41        NET_CONNECT(_name, B4, _B4)                                                 \
42        NET_CONNECT(_name, C0, _CI)
43
44NETLIB_DEVICE(nic7483,
45    netlist_ttl_input_t m_C0;
46    netlist_ttl_input_t m_A1;
47    netlist_ttl_input_t m_A2;
48    netlist_ttl_input_t m_A3;
49    netlist_ttl_input_t m_A4;
50    netlist_ttl_input_t m_B1;
51    netlist_ttl_input_t m_B2;
52    netlist_ttl_input_t m_B3;
53    netlist_ttl_input_t m_B4;
54
55    UINT8 m_lastr;
56
57    netlist_ttl_output_t m_SA;
58    netlist_ttl_output_t m_SB;
59    netlist_ttl_output_t m_SC;
60    netlist_ttl_output_t m_SD;
61    netlist_ttl_output_t m_C4;
62
63);
64
65#endif /* NLD_7483_H_ */
Property changes on: trunk/src/emu/netlist/devices/nld_7483.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/netlist/nl_config.h
r26599r26600
6666//  MACROS
6767//============================================================
6868
69// prevent implicit copying
70#define NETLIST_PREVENT_COPYING(_name)          \
71    private:                                    \
72        _name(const _name &);                   \
73        _name &operator=(const _name &);        \
74
6975#if NL_KEEP_STATISTICS
7076#define add_to_stat(v,x)        do { v += (x); } while (0)
7177#define inc_stat(v)             add_to_stat(v, 1)
trunk/src/emu/netlist/nl_base.c
r26599r26600
66#include "nl_base.h"
77#include "devices/nld_system.h"
88#include "pstring.h"
9#include "nl_util.h"
910
1011const netlist_time netlist_time::zero = netlist_time::from_raw(0);
1112
r26599r26600
280281   dev.init(*m_setup, this->name() + "." + name);
281282}
282283
283ATTR_COLD void netlist_device_t::register_subalias(const pstring &name, netlist_core_terminal_t &term)
284ATTR_COLD void netlist_device_t::register_subalias(const pstring &name, const netlist_core_terminal_t &term)
284285{
285286    pstring alias = this->name() + "." + name;
286287
r26599r26600
330331}
331332
332333// FIXME: Revise internal links ...
333ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState)
334ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState)
334335{
335336    init_term(dev, in, aState);
336337    init_term(dev, out, aState);
337338    m_setup->connect(in, out);
338339}
339340
340ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState)
341ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState)
341342{
342343   register_link_internal(*this, in, out, aState);
343344}
r26599r26600
422423        m_active++;
423424}
424425
425ATTR_HOT inline void netlist_net_t::update_dev(const netlist_core_terminal_t *inp, const UINT32 mask)
426ATTR_HOT inline void netlist_net_t::update_dev(const netlist_core_terminal_t *inp, const UINT32 mask) const
426427{
427428   if ((inp->state() & mask) != 0)
428429   {
r26599r26600
602603
603604   register_param("FREQ", m_freq, 7159000.0 * 5);
604605   m_inc = netlist_time::from_hz(m_freq.Value()*2);
605
606606}
607607
608608NETLIB_UPDATE_PARAM(mainclock)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team