Previous 199869 Revisions Next

r30724 Friday 30th May, 2014 at 16:04:08 UTC by Couriersud
Netlist changes:
- Reworked the analog storage model to better support the compiler.
 This will most likely only pay off on larger matrices than currently used.
 Investment for future platforms with larger vectors
- Added parameter "GS_THRESHOLD" to select the minimum matrix size for Gauss-Seidel solver
- pstate: pointer will be resolved late, i.e. after all initialization is finished.
 State is registered during start, but some pointers are only set during post_load in the solver.
[src/emu/machine]netlist.c
[src/emu/netlist]nl_base.c nl_base.h pstate.c pstate.h
[src/emu/netlist/analog]nld_solver.c nld_solver.h nld_twoterm.c nld_twoterm.h

trunk/src/emu/machine/netlist.c
r30723r30724
439439      switch (s->m_dt)
440440      {
441441         case DT_DOUBLE:
442            save_pointer((double *) s->m_ptr, s->m_name, s->m_count);
442                {
443                    double *td = s->resolved<double>();
444                    if (td != NULL) save_pointer(td, s->m_name, s->m_count);
445                }
443446            break;
444447         case DT_INT64:
445448            save_pointer((INT64 *) s->m_ptr, s->m_name, s->m_count);
trunk/src/emu/netlist/analog/nld_twoterm.h
r30723r30724
9898
9999   ATTR_HOT inline void set(const double G, const double V, const double I)
100100   {
101      m_P.m_go = m_N.m_go = m_P.m_gt = m_N.m_gt = G;
102      m_N.m_Idr = ( -V) * G + I;
103      m_P.m_Idr = (  V) * G - I;
101       /*      GO, GT, I                */
102      m_P.set( G,  G, (  V) * G - I);
103      m_N.set( G,  G, ( -V) * G + I);
104104   }
105105
106106   ATTR_HOT inline double deltaV()
r30723r30724
110110
111111   ATTR_HOT void set_mat(double a11, double a12, double a21, double a22, double r1, double r2)
112112   {
113      m_P.m_gt = a11;
114      m_P.m_go = -a12;
115      m_N.m_gt = a22;
116      m_N.m_go = -a21;
117
118      m_P.m_Idr = -r1;
119      m_N.m_Idr = -r2;
120
113        /*      GO, GT, I                */
114       m_P.set(-a12, a11, -r1);
115       m_N.set(-a21, a22, -r2);
121116   }
122117
123118protected:
trunk/src/emu/netlist/analog/nld_solver.c
r30723r30724
1818#define SOLVER_VERBOSE_OUT(x) do {} while (0)
1919//#define SOLVER_VERBOSE_OUT(x) printf x
2020
21/* Commented out for now. Relatively low number of terminals / net makes
22 * the vectorizations this enables pretty expensive
23 */
24
25//#pragma GCC optimize "-ffast-math"
26
2127// ----------------------------------------------------------------------------------------
2228// netlist_matrix_solver
2329// ----------------------------------------------------------------------------------------
r30723r30724
122128    if (m_params.m_dynamic)
123129    {
124130        /*
125         * FIXME: this is a reduced LTE focusing on the nets which drive other nets
126         *        The academically correct version using all nets is the one commented out
127         *        This causes really bad performance due to rounding errors.
131         * FIXME: We should extend the logic to use either all nets or
132         *        only output nets.
128133         */
129134#if 0
130135        for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
r30723r30724
140145            if (fabs(DD_n) < 2.0 * m_params.m_accuracy)
141146                DD_n = 0.0;
142147            else
143                DD_n = DD_n / hn;
148                DD_n = copysign(fabs(DD_n) - 2.0 * m_params.m_accuracy, DD_n) / hn;
144149
145150            double h_n_m_1 = n->m_h_n_m_1;
146151            // limit last timestep in equation.
r30723r30724
361366
362367    netlist_matrix_solver_t::setup(nets);
363368
364#if 0
365   for (int k = 0; k < N(); k++)
366   {
367      const netlist_terminal_t::list_t &terms = m_nets[k].m_terms;
368      for (int i = 0; i < terms.count(); i++)
369      {
370         int ot = get_net_idx(&terms[i]->m_otherterm->net());
371         if (ot>=0)
372         {
373             m_terms[k].add(terms_t(terms[i], ot));
374            SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go));
375         }
376      }
377   }
378
379    /* Should this be allowed ? */
380   for (int k = 0; k < N(); k++)
381   {
382      const netlist_terminal_t::list_t &terms = m_nets[k].m_terms;
383      for (int i = 0; i < terms.count(); i++)
384      {
385            int ot = get_net_idx(&terms[i]->m_otherterm->net());
386         if (ot<0)
387         {
388                m_rails[k].add(terms_t(terms[i], ot));
389            netlist().warning("found term with missing othernet %s\n", terms[i]->name().cstr());
390         }
391      }
369    for (int k = 0; k < N(); k++)
370    {
371        m_terms[k].set_pointers();
372        m_rails[k].set_pointers();
392373    }
393374
394
395   for (int k = 0; k < N(); k++)
396   {
397      const netlist_terminal_t::list_t &rails = m_nets[k].m_rails;
398      for (int i = 0; i < rails.count(); i++)
399      {
400            m_rails[k].add(terms_t(rails[i], -1));
401         SOLVER_VERBOSE_OUT(("Net %d Rail %s %f %f\n", k, rails[i]->name().cstr(), rails[i]->m_gt, rails[i]->m_go));
402      }
403   }
404#endif
405375}
406376
407377template <int m_N, int _storage_N>
r30723r30724
415385   {
416386        double rhsk = 0.0;
417387        double akk  = 0.0;
418        const int terms_count = m_terms[k].count();
419        const netlist_terminal_t * const *terms = m_terms[k].terms();
420        const int *net_other = m_terms[k].net_other();
388        {
389            const int terms_count = m_terms[k].count();
390            //const netlist_terminal_t * const *terms = m_terms[k].terms();
391            const int *net_other = m_terms[k].net_other();
392            const double *gt = m_terms[k].gt();
393            const double *go = m_terms[k].go();
394            const double *Idr = m_terms[k].Idr();
421395
422        for (int i = 0; i < terms_count; i++)
423      {
424            //printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go);
396            for (int i = 0; i < terms_count; i++)
397            {
398                //printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go);
425399
426            rhsk = rhsk + terms[i]->m_Idr;
427            akk = akk + terms[i]->m_gt;
428            m_A[k][net_other[i]] += -terms[i]->m_go;
429      }
430
431        const int rails_count = m_rails[k].count();
432        const netlist_terminal_t * const *rails = m_rails[k].terms();
433
434        for (int i = 0; i < rails_count; i++)
400                rhsk = rhsk + Idr[i];
401                akk = akk + gt[i];
402                m_A[k][net_other[i]] += -go[i];
403            }
404        }
435405        {
436            rhsk = rhsk + rails[i]->m_Idr + rails[i]->m_go * rails[i]->m_otherterm->net().as_analog().Q_Analog();
437            akk = akk + rails[i]->m_gt;
406            const int rails_count = m_rails[k].count();
407            const netlist_terminal_t * const *rails = m_rails[k].terms();
408            const double *gt = m_rails[k].gt();
409            const double *go = m_rails[k].go();
410            const double *Idr = m_rails[k].Idr();
411
412            for (int i = 0; i < rails_count; i++)
413            {
414                rhsk = rhsk + Idr[i];
415                akk = akk + gt[i];
416                rhsk = rhsk + go[i] * rails[i]->m_otherterm->net().as_analog().Q_Analog();
417            }
438418        }
439419        m_RHS[k] = rhsk;
440420        m_A[k][k] += akk;
r30723r30724
479459           }
480460       }
481461
482       /* Singular matrix? */
483      double f = m_A[i][i];
484      //if (fabs(f) < 1e-20) printf("Singular!");
485      f = 1.0 / f;
462       /* FIXME: Singular matrix? */
463      const double f = 1.0 / m_A[i][i];
486464
487465      /* Eliminate column i from row j */
488466
489467      for (int j = i + 1; j < kN; j++)
490468      {
491            //__builtin_prefetch(&A[j+1][i], 1);
492469            const double f1 = m_A[j][i] * f;
493470         if (f1 != 0.0)
494471         {
495                for (int k = i; k < kN; k++)
472                for (int k = i + 1; k < kN; k++)
496473                    m_A[j][k] -= m_A[i][k] * f1;
497474               m_RHS[j] -= m_RHS[i] * f1;
498475         }
r30723r30724
501478   /* back substitution */
502479   for (int j = kN - 1; j >= 0; j--)
503480   {
504        //__builtin_prefetch(&A[j-1][j], 0);
481        //__builtin_prefetch(&m_A[j-1][j], 0);
505482      double tmp = 0;
506483        for (int k = j + 1; k < kN; k++)
507484            tmp += m_A[j][k] * x[k];
r30723r30724
650627// netlist_matrix_solver - Gauss - Seidel
651628// ----------------------------------------------------------------------------------------
652629
630template<int _N>
631static inline const double sum(const double *v)
632{
633    double tmp = 0.0;
634    for (int i=0; i < _N; i++)
635        tmp += v[i];
636    return tmp;
637}
638
639template<int _N>
640static inline const double sumabs(const double *v)
641{
642    double tmp = 0.0;
643    for (int i=0; i < _N; i++)
644        tmp += fabs(v[i]);
645    return tmp;
646}
647
653648template <int m_N, int _storage_N>
654649ATTR_HOT int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolve_non_dynamic()
655650{
r30723r30724
659654     */
660655
661656#if 0
662    double new_v[_storage_N] = { 0.0 };
657    ATTR_ALIGN double new_v[_storage_N] = { 0.0 };
663658    const int iN = this->N();
664659
665660    bool resched = false;
r30723r30724
680675        {
681676            double Idrive = 0;
682677
683            // loop auto-vectorized
678            // Reduction loops need -ffast-math
684679            for (int i = 0; i < iN; i++)
685680                Idrive -= this->m_A[k][i] * new_v[i];
686681
r30723r30724
726721   //const double w = 1.0; //2.0 / (1.0 + sin(3.14159 / (m_nets.count()+1)));
727722   //const double w1 = 1.0 - w;
728723
729   double w[_storage_N];
730   double one_m_w[_storage_N];
731   double RHS[_storage_N];
732   double new_V[_storage_N];
724   ATTR_ALIGN double w[_storage_N];
725   ATTR_ALIGN double one_m_w[_storage_N];
726   ATTR_ALIGN double RHS[_storage_N];
727   ATTR_ALIGN double new_V[_storage_N];
733728
734729    for (int k = 0; k < iN; k++)
735730    {
r30723r30724
746741           const netlist_terminal_t * const * rails = this->m_rails[k].terms();
747742           //const int * othernet = this->m_rails[k].m_othernet;
748743           const int rail_count = this->m_rails[k].count();
744           const double *gt = this->m_rails[k].gt();
745            const double *go = this->m_rails[k].go();
746            const double *Idr = this->m_rails[k].Idr();
749747
750           for (int i = 0; i < rail_count; i++)
751           {
752               const netlist_terminal_t *rail = rails[i];
753               gtot_t += rail->m_gt;
754               gabs_t += fabs(rail->m_go);
755               RHS_t += rail->m_Idr;
756               // this may point to a rail net ...
757               RHS_t += rail->m_go * rail->m_otherterm->net().as_analog().Q_Analog();
758           }
748            for (int i = 0; i < rail_count; i++)
749            {
750                RHS_t += go[i] * rails[i]->m_otherterm->net().as_analog().Q_Analog();
751                gtot_t += gt[i];
752                gabs_t += fabs(go[i]);
753                RHS_t += Idr[i];
754                // this may point to a rail net ...
755            }
759756      }
760757      {
761            const netlist_terminal_t * const * terms = this->m_terms[k].terms();
762758            const int term_count = this->m_terms[k].count();
759            const double *gt = this->m_terms[k].gt();
760            const double *go = this->m_terms[k].go();
761            const double *Idr = this->m_terms[k].Idr();
763762
764763            for (int i = 0; i < term_count; i++)
765764            {
766                const netlist_terminal_t *term = terms[i];
767                gtot_t += term->m_gt;
768                gabs_t += fabs(term->m_go);
769                RHS_t += term->m_Idr;
765                gtot_t += gt[i];
766                gabs_t += fabs(go[i]);
767                RHS_t += Idr[i];
770768            }
771769      }
772770      gabs_t *= 1.0;
r30723r30724
791789
792790      for (int k = 0; k < iN; k++)
793791      {
794         //netlist_analog_net_t & RESTRICT net = *this->m_nets[k];
795           const netlist_terminal_t * const * terms = this->m_terms[k].terms();
796792            const int * net_other = this->m_terms[k].net_other();
797793         const int term_count = this->m_terms[k].count();
794            const double *go = this->m_terms[k].go();
795            // -msse2 -msse3 -msse4.1 -msse4.2 -mfpmath=sse -ftree-vectorizer-verbose=3 -fprefetch-loop-arrays -ffast-math
798796
799797         double Idrive = 0;
800798
801799            for (int i = 0; i < term_count; i++)
802                Idrive += terms[i]->m_go * new_V[net_other[i]];
800                Idrive = Idrive + go[i] * new_V[net_other[i]];
803801
804802            //double new_val = (net->m_cur_Analog * gabs[k] + iIdr) / (gtot[k]);
805803         const double new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k];
r30723r30724
856854
857855   register_param("FREQ", m_freq, 48000.0);
858856
859   register_param("ACCURACY", m_accuracy, 1e-4);
860   register_param("GS_LOOPS", m_gs_loops, 5);              // Gauss-Seidel loops
857   register_param("ACCURACY", m_accuracy, 1e-7);
858   register_param("GS_LOOPS", m_gs_loops, 9);              // Gauss-Seidel loops
859    register_param("GS_THRESHOLD", m_gs_threshold, 5);          // below this value, gaussian elimination is used
861860    register_param("NR_LOOPS", m_nr_loops, 25);             // Newton-Raphson loops
862861   register_param("PARALLEL", m_parallel, 0);
863862    register_param("GMIN", m_gmin, NETLIST_GMIN_DEFAULT);
864863    register_param("DYNAMIC_TS", m_dynamic, 0);
865    register_param("LTE", m_lte, 1e-2);                     // 100mV diff/timestep
866   register_param("MIN_TIMESTEP", m_min_timestep, 2e-9);   // double timestep resolution
864    register_param("LTE", m_lte, 5e-5);                     // diff/timestep
865   register_param("MIN_TIMESTEP", m_min_timestep, 1e-6);   // double timestep resolution
867866
868867   // internal staff
869868
r30723r30724
927926            this_resched[i] = m_mat_solvers[i]->solve();
928927      }
929928#else
930   // FIXME: parameter
931929    for (int i = 0; i < t_cnt; i++)
932930    {
933931        if (m_mat_solvers[i]->is_timestep())
934932            {
935            // Ignore return value
933                // Ignore return value
936934                ATTR_UNUSED const double ts = m_mat_solvers[i]->solve();
937935            }
938936    }
r30723r30724
965963{
966964   netlist_analog_net_t::list_t groups[100];
967965   int cur_group = -1;
968   // FIXME: Turn into parameters ...
969   const int gs_threshold = 5;
966   const int gs_threshold = m_gs_threshold.Value();
970967   const bool use_specific = true;
971968
972969    m_params.m_accuracy = m_accuracy.Value();
trunk/src/emu/netlist/analog/nld_solver.h
r30723r30724
7979        {
8080            m_term.clear();
8181            m_net_other.clear();
82            m_gt.clear();
8283        }
8384
8485        void add(netlist_terminal_t *term, int net_other)
8586        {
8687            m_term.add(term);
8788            m_net_other.add(net_other);
89            m_gt.add(0.0);
90            m_go.add(0.0);
91            m_Idr.add(0.0);
8892        }
8993
9094        inline int count() { return m_term.count(); }
9195
9296        inline netlist_terminal_t **terms() { return m_term; }
9397        inline int *net_other() { return m_net_other; }
98        inline double *gt() { return m_gt; }
99        inline double *go() { return m_go; }
100        inline double *Idr() { return m_Idr; }
94101
102        void set_pointers()
103        {
104            for (int i = 0; i < count(); i++)
105            {
106                m_term[i]->m_gt1 = &m_gt[i];
107                m_term[i]->m_go1 = &m_go[i];
108                m_term[i]->m_Idr1 = &m_Idr[i];
109            }
110        }
111
95112    private:
96113        plinearlist_t<netlist_terminal_t *> m_term;
97114        plinearlist_t<int> m_net_other;
115        plinearlist_t<double> m_gt;
116        plinearlist_t<double> m_go;
117        plinearlist_t<double> m_Idr;
98118
99119    };
100120
r30723r30724
230250    ATTR_HOT void reset();
231251    ATTR_HOT void update_param();
232252
233    //typedef netlist_core_device_t::list_t dev_list_t;
253    netlist_ttl_input_t m_fb_step;
254    netlist_ttl_output_t m_Q_step;
234255
235        netlist_ttl_input_t m_fb_step;
236        netlist_ttl_output_t m_Q_step;
256    netlist_param_double_t m_freq;
257    netlist_param_double_t m_sync_delay;
258    netlist_param_double_t m_accuracy;
259    netlist_param_double_t m_gmin;
260    netlist_param_double_t m_lte;
261    netlist_param_logic_t  m_dynamic;
262    netlist_param_double_t m_min_timestep;
237263
238      netlist_param_double_t m_freq;
239      netlist_param_double_t m_sync_delay;
240      netlist_param_double_t m_accuracy;
241      netlist_param_double_t m_gmin;
242      netlist_param_double_t m_lte;
243        netlist_param_logic_t  m_dynamic;
244      netlist_param_double_t m_min_timestep;
264    netlist_param_int_t m_nr_loops;
265    netlist_param_int_t m_gs_loops;
266    netlist_param_int_t m_gs_threshold;
267    netlist_param_int_t m_parallel;
245268
246        netlist_param_int_t m_nr_loops;
247      netlist_param_int_t m_gs_loops;
248      netlist_param_int_t m_parallel;
249
250      netlist_matrix_solver_t::list_t m_mat_solvers;
269    netlist_matrix_solver_t::list_t m_mat_solvers;
251270private:
252271
253272    netlist_solver_parameters_t m_params;
trunk/src/emu/netlist/analog/nld_twoterm.c
r30723r30724
3939// nld_twoterm
4040// ----------------------------------------------------------------------------------------
4141
42ATTR_COLD NETLIB_NAME(twoterm)::NETLIB_NAME(twoterm)(const family_t afamily) :
43      netlist_device_t(afamily)
42ATTR_COLD NETLIB_NAME(twoterm)::NETLIB_NAME(twoterm)(const family_t afamily)
43        : netlist_device_t(afamily)
4444{
4545   m_P.m_otherterm = &m_N;
4646   m_N.m_otherterm = &m_P;
r30723r30724
177177   register_param("C", m_C, 1e-6);
178178
179179   // set up the element
180   set(netlist().gmin(), 0.0, -5.0 / netlist().gmin());
180   //set(netlist().gmin(), 0.0, -5.0 / netlist().gmin());
181181   //set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN);
182182}
183183
trunk/src/emu/netlist/pstate.c
r30723r30724
1212
1313
1414
15ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pstate_data_type_e dt, const void *owner, const int size, const int count, void *ptr)
15ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pstate_data_type_e dt, const void *owner, const int size, const int count, void *ptr, bool is_ptr)
1616{
1717   pstring fullname = stname;
1818   ATTR_UNUSED  pstring ts[] = {
r30723r30724
2727   };
2828
2929   NL_VERBOSE_OUT(("SAVE: <%s> %s(%d) %p\n", fullname.cstr(), ts[dt].cstr(), size, ptr));
30   pstate_entry_t *p = new pstate_entry_t(stname, dt, owner, size, count, ptr);
30   pstate_entry_t *p = new pstate_entry_t(stname, dt, owner, size, count, ptr, is_ptr);
3131   m_save.add(p);
3232}
3333
trunk/src/emu/netlist/nl_base.c
r30723r30724
767767
768768ATTR_COLD netlist_terminal_t::netlist_terminal_t()
769769: netlist_core_terminal_t(TERMINAL, ANALOG)
770, m_Idr(0.0)
771, m_go(NETLIST_GMIN_DEFAULT)
772, m_gt(NETLIST_GMIN_DEFAULT)
770, m_Idr1(NULL)
771, m_go1(NULL)
772, m_gt1(NULL)
773773, m_otherterm(NULL)
774774{
775775}
r30723r30724
779779{
780780   //netlist_terminal_core_terminal_t::reset();
781781   set_state(STATE_INP_ACTIVE);
782   m_Idr = 0.0;
783   m_go = netlist().gmin();
784   m_gt = netlist().gmin();
782   set_ptr(m_Idr1, 0.0);
783   set_ptr(m_go1, netlist().gmin());
784   set_ptr(m_gt1, netlist().gmin());
785785}
786786
787787ATTR_COLD void netlist_terminal_t::save_register()
788788{
789   save(NAME(m_Idr));
790   save(NAME(m_go));
791   save(NAME(m_gt));
789   save(NAME(m_Idr1));
790   save(NAME(m_go1));
791   save(NAME(m_gt1));
792792   netlist_core_terminal_t::save_register();
793793}
794794
trunk/src/emu/netlist/pstate.h
r30723r30724
3535   DT_BOOLEAN
3636};
3737
38template<typename _ItemType> struct nl_datatype { static const pstate_data_type_e type = pstate_data_type_e(NOT_SUPPORTED); };
38template<typename _ItemType> struct nl_datatype
39{
40    static const pstate_data_type_e type = pstate_data_type_e(NOT_SUPPORTED);
41    static const bool is_ptr = false;
42};
43
44template<typename _ItemType> struct nl_datatype<_ItemType *>
45{
46    static const pstate_data_type_e type = pstate_data_type_e(NOT_SUPPORTED);
47    static const bool is_ptr = true;
48};
49
3950//template<typename _ItemType> struct type_checker<_ItemType*> { static const bool is_atom = false; static const bool is_pointer = true; };
4051
41#define NETLIST_SAVE_TYPE(TYPE, TYPEDESC) template<> struct nl_datatype<TYPE>{ static const pstate_data_type_e type = pstate_data_type_e(TYPEDESC); }
52#define NETLIST_SAVE_TYPE(TYPE, TYPEDESC) \
53        template<> struct nl_datatype<TYPE>{ static const pstate_data_type_e type = pstate_data_type_e(TYPEDESC); static const bool is_ptr = false;}; \
54        template<> struct nl_datatype<TYPE *>{ static const pstate_data_type_e type = pstate_data_type_e(TYPEDESC); static const bool is_ptr = true;};
4255
4356NETLIST_SAVE_TYPE(char, DT_INT8);
4457NETLIST_SAVE_TYPE(double, DT_DOUBLE);
r30723r30724
7386   typedef plinearlist_t<pstate_entry_t *> list_t;
7487
7588   pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const void *owner,
76         const int size, const int count, void *ptr)
77   : m_name(stname), m_dt(dt), m_owner(owner), m_callback(NULL), m_size(size), m_count(count), m_ptr(ptr) { }
89         const int size, const int count, void *ptr, bool is_ptr)
90   : m_name(stname), m_dt(dt), m_owner(owner), m_callback(NULL), m_size(size), m_count(count), m_ptr(ptr), m_is_ptr(is_ptr) { }
7891
7992   pstate_entry_t(const pstring &stname, const void *owner, pstate_callback_t *callback)
80   : m_name(stname), m_dt(DT_CUSTOM), m_owner(owner), m_callback(callback), m_size(0), m_count(0), m_ptr(NULL) { }
93   : m_name(stname), m_dt(DT_CUSTOM), m_owner(owner), m_callback(callback), m_size(0), m_count(0), m_ptr(NULL), m_is_ptr(false) { }
8194
8295   pstring m_name;
8396   const pstate_data_type_e m_dt;
r30723r30724
8699   const int m_size;
87100   const int m_count;
88101   void *m_ptr;
102   bool m_is_ptr;
103
104   template<typename T>
105   T *resolved()
106   {
107       if (m_is_ptr)
108           return *static_cast<T **>(m_ptr);
109       else
110           return static_cast<T *>(m_ptr);
111   }
89112};
90113
91114class pstate_manager_t
r30723r30724
96119
97120   template<typename C> ATTR_COLD void save_item(C &state, const void *owner, const pstring &stname)
98121   {
99      save_state_ptr(stname, nl_datatype<C>::type, owner, sizeof(C), 1, &state);
122      save_state_ptr(stname, nl_datatype<C>::type, owner, sizeof(C), 1, &state, nl_datatype<C>::is_ptr);
100123   }
101124
102125   template<typename C, std::size_t N> ATTR_COLD void save_item(C (&state)[N], const void *owner, const pstring &stname)
103126   {
104      save_state_ptr(stname, nl_datatype<C>::type, owner, sizeof(state[0]), N, &(state[0]));
127      save_state_ptr(stname, nl_datatype<C>::type, owner, sizeof(state[0]), N, &(state[0]), false);
105128   }
106129
107130   template<typename C> ATTR_COLD void save_item(C *state, const void *owner, const pstring &stname, const int count)
108131   {
109      save_state_ptr(stname, nl_datatype<C>::type, owner, sizeof(C), count, state);
132      save_state_ptr(stname, nl_datatype<C>::type, owner, sizeof(C), count, state, false);
110133   }
111134
112135   ATTR_COLD void pre_save();
r30723r30724
116139   inline const pstate_entry_t::list_t &save_list() const { return m_save; }
117140
118141protected:
119   ATTR_COLD void save_state_ptr(const pstring &stname, const pstate_data_type_e, const void *owner, const int size, const int count, void *ptr);
142   ATTR_COLD void save_state_ptr(const pstring &stname, const pstate_data_type_e, const void *owner, const int size, const int count, void *ptr, bool is_ptr);
120143
121144private:
122145   pstate_entry_t::list_t m_save;
r30723r30724
132155
133156template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist_time &nlt, const void *owner, const pstring &stname)
134157{
135   save_state_ptr(stname, DT_INT64, owner, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr());
158   save_state_ptr(stname, DT_INT64, owner, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
136159}
137160
138161
trunk/src/emu/netlist/nl_base.h
r30723r30724
433433
434434   ATTR_COLD netlist_terminal_t();
435435
436   double m_Idr; // drive current
437   double m_go;  // conductance for Voltage from other term
438   double m_gt;  // conductance for total conductance
436   double *m_Idr1; // drive current
437   double *m_go1;  // conductance for Voltage from other term
438   double *m_gt1;  // conductance for total conductance
439439
440440   ATTR_HOT inline void set(const double G)
441441   {
442      m_Idr = 0;
443      m_go = m_gt = G;
442       set_ptr(m_Idr1, 0);
443      set_ptr(m_go1, G);
444      set_ptr(m_gt1, G);
444445   }
445446
446447   ATTR_HOT inline void set(const double GO, const double GT)
447448   {
448      m_Idr = 0;
449      m_go = GO;
450      m_gt = GT;
449       set_ptr(m_Idr1, 0);
450      set_ptr(m_go1, GO);
451      set_ptr(m_gt1, GT);
451452   }
452453
453454   ATTR_HOT inline void set(const double GO, const double GT, const double I)
454455   {
455      m_Idr = I;
456      m_go = GO;
457      m_gt = GT;
456       set_ptr(m_Idr1, I);
457      set_ptr(m_go1, GO);
458      set_ptr(m_gt1, GT);
458459   }
459460
460461
r30723r30724
464465   ATTR_COLD virtual void save_register();
465466
466467   ATTR_COLD virtual void reset();
468private:
469    inline void set_ptr(double *ptr, const double val)
470    {
471        if (ptr != NULL)
472            *ptr = val;
473    }
467474};
468475
469476

Previous 199869 Revisions Next


© 1997-2024 The MAME Team