- code maintenance. 
- added a parameter to various calls to indicate we are doing a
  newton-raphson. Preparation for relaxation.
- rename plinearlist_t to plist_t
- added parray_t
- minor renames
(nw)
This commit is contained in:
couriersud 2015-05-18 21:53:56 +02:00
parent 0ca552d593
commit ea1a9f0793
23 changed files with 376 additions and 312 deletions

View File

@ -556,7 +556,7 @@ void netlist_mame_sound_device_t::device_start()
// Configure outputs
plinearlist_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
plist_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
if (outdevs.count() == 0)
fatalerror("No output devices");
@ -582,7 +582,7 @@ void netlist_mame_sound_device_t::device_start()
m_num_inputs = 0;
m_in = NULL;
plinearlist_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
plist_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
if (indevs.count() > 1)
fatalerror("A maximum of one input device is allowed!");
if (indevs.count() == 1)

View File

@ -66,27 +66,6 @@
#define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
void _name(const double data, const attotime &time)
#if 0
#define NETDEV_ANALOG_CALLBACK(_name, _IN, _class, _member, _tag) \
{ \
NETLIB_NAME(analog_callback) *dev = downcast<NETLIB_NAME(analog_callback) *>(netlist.register_dev(NET_NEW(analog_callback), # _name)); \
netlist_analog_output_delegate d = netlist_analog_output_delegate(& _class :: _member, # _class "::" # _member, _tag, (_class *) 0); \
dev->register_callback(d); \
} \
NET_CONNECT(_name, IN, _IN)
#endif
#if 0
#define NETDEV_SOUND_OUT(_name, _v, _m) \
NET_REGISTER_DEV(sound_out, _name) \
PARAM(_name.CHAN, _v) \
PARAM(_name.MULT, _m)
#define NETDEV_SOUND_IN(_name) \
NET_REGISTER_DEV(sound_in, _name)
#endif
class netlist_mame_device_t;
class netlist_mame_t : public netlist_base_t
@ -518,7 +497,7 @@ class NETLIB_NAME(analog_callback) : public netlist_device_t
{
public:
NETLIB_NAME(analog_callback)()
: netlist_device_t(), m_cpu_device(NULL) { }
: netlist_device_t(), m_cpu_device(NULL), m_last(0) { }
ATTR_COLD void start()
{

View File

@ -25,14 +25,14 @@ public:
ATTR_HOT inline int N() const { return (m_N == 0 ? m_dim : m_N); }
ATTR_HOT inline int vsolve_non_dynamic();
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
protected:
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term);
ATTR_HOT virtual nl_double vsolve();
ATTR_HOT int solve_non_dynamic();
ATTR_HOT int solve_non_dynamic(const bool newton_raphson);
ATTR_HOT void build_LE_A();
ATTR_HOT void build_LE_RHS();
ATTR_HOT void LE_solve();
@ -394,7 +394,7 @@ ATTR_HOT nl_double netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve()
template <int m_N, int _storage_N>
ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic()
ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(const bool newton_raphson)
{
nl_double new_v[_storage_N]; // = { 0.0 };
@ -416,13 +416,13 @@ ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(
}
template <int m_N, int _storage_N>
ATTR_HOT inline int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic()
ATTR_HOT inline int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
{
this->build_LE_A();
this->build_LE_RHS();
this->LE_solve();
return this->solve_non_dynamic();
return this->solve_non_dynamic(newton_raphson);
}
template <int m_N, int _storage_N>

View File

@ -18,7 +18,7 @@ public:
netlist_matrix_solver_direct1_t(const netlist_solver_parameters_t &params)
: netlist_matrix_solver_direct_t<1, 1>(params, 1)
{}
ATTR_HOT inline int vsolve_non_dynamic();
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
protected:
ATTR_HOT virtual nl_double vsolve();
private:
@ -34,7 +34,7 @@ ATTR_HOT nl_double netlist_matrix_solver_direct1_t::vsolve()
return this->compute_next_timestep();
}
ATTR_HOT inline int netlist_matrix_solver_direct1_t::vsolve_non_dynamic()
ATTR_HOT inline int netlist_matrix_solver_direct1_t::vsolve_non_dynamic(const bool newton_raphson)
{
netlist_analog_net_t *net = m_nets[0];
this->build_LE_A();

View File

@ -20,7 +20,7 @@ public:
netlist_matrix_solver_direct2_t(const netlist_solver_parameters_t &params)
: netlist_matrix_solver_direct_t<2, 2>(params, 2)
{}
ATTR_HOT inline int vsolve_non_dynamic();
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
protected:
ATTR_HOT virtual nl_double vsolve();
private:
@ -36,7 +36,7 @@ ATTR_HOT nl_double netlist_matrix_solver_direct2_t::vsolve()
return this->compute_next_timestep();
}
ATTR_HOT inline int netlist_matrix_solver_direct2_t::vsolve_non_dynamic()
ATTR_HOT inline int netlist_matrix_solver_direct2_t::vsolve_non_dynamic(const bool newton_raphson)
{
build_LE_A();
build_LE_RHS();

View File

@ -39,7 +39,7 @@ public:
ATTR_COLD virtual void log_stats();
ATTR_HOT virtual int vsolve_non_dynamic();
ATTR_HOT virtual int vsolve_non_dynamic(const bool newton_raphson);
protected:
ATTR_HOT virtual nl_double vsolve();
@ -83,7 +83,7 @@ ATTR_HOT nl_double netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve()
}
template <int m_N, int _storage_N>
ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dynamic()
ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
{
const int iN = this->N();
bool resched = false;
@ -181,8 +181,17 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
resched_cnt++;
} while (resched && (resched_cnt < this->m_params.m_gs_loops));
for (int k = 0; k < iN; k++)
this->m_nets[k]->m_cur_Analog = new_V[k];
if (newton_raphson)
{
//printf("here %s\n", this->name().cstr());
for (int k = 0; k < iN; k++)
this->m_nets[k]->m_cur_Analog += 1.0 * (new_V[k] - this->m_nets[k]->m_cur_Analog);
}
else
{
for (int k = 0; k < iN; k++)
this->m_nets[k]->m_cur_Analog = new_V[k];
}
this->m_gs_total += resched_cnt;
this->m_stat_calculations++;
@ -191,7 +200,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
{
// Fallback to direct solver ...
this->m_gs_fail++;
return netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic();
return netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(newton_raphson);
}
else {
return resched_cnt;

View File

@ -40,7 +40,7 @@ public:
ATTR_COLD virtual void log_stats();
ATTR_HOT inline int vsolve_non_dynamic();
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
protected:
ATTR_HOT virtual nl_double vsolve();
@ -126,7 +126,7 @@ ATTR_HOT nl_double netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve()
}
template <int m_N, int _storage_N>
ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non_dynamic()
ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
{
/* The matrix based code looks a lot nicer but actually is 30% slower than
* the optimized code which works directly on the data structures.
@ -293,7 +293,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
this->LE_solve();
this->m_stat_calculations++;
return netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic();
return netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(newton_raphson);
}
else {
this->m_stat_calculations++;

View File

@ -236,7 +236,7 @@ void netlist_matrix_solver_t::solve_base(C *p)
{
update_dynamic();
// Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
this_resched = p->vsolve_non_dynamic();
this_resched = p->vsolve_non_dynamic(true);
newton_loops++;
} while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
@ -250,7 +250,7 @@ void netlist_matrix_solver_t::solve_base(C *p)
}
else
{
p->vsolve_non_dynamic();
p->vsolve_non_dynamic(false);
}
}

View File

@ -75,18 +75,18 @@ class ATTR_ALIGNED(64) terms_t
int m_railstart;
private:
plinearlist_t<netlist_terminal_t *> m_term;
plinearlist_t<int> m_net_other;
plinearlist_t<nl_double> m_go;
plinearlist_t<nl_double> m_gt;
plinearlist_t<nl_double> m_Idr;
plinearlist_t<nl_double *> m_other_curanalog;
plist_t<netlist_terminal_t *> m_term;
plist_t<int> m_net_other;
plist_t<nl_double> m_go;
plist_t<nl_double> m_gt;
plist_t<nl_double> m_Idr;
plist_t<nl_double *> m_other_curanalog;
};
class netlist_matrix_solver_t : public netlist_device_t
{
public:
typedef plinearlist_t<netlist_matrix_solver_t *> list_t;
typedef plist_t<netlist_matrix_solver_t *> list_t;
typedef netlist_core_device_t::list_t dev_list_t;
enum eSolverType
@ -134,8 +134,8 @@ protected:
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term) = 0;
plinearlist_t<netlist_analog_net_t *> m_nets;
plinearlist_t<netlist_analog_output_t *> m_inps;
plist_t<netlist_analog_net_t *> m_nets;
plist_t<netlist_analog_output_t *> m_inps;
int m_stat_calculations;
int m_stat_newton_raphson;

View File

@ -62,8 +62,7 @@ UINT32 truthtable_desc_t::get_ignored_extended(UINT32 i)
* may change the output
*/
int bits = (1<<count_bits(nign));
plinearlist_t<int> t;
t.set_count(bits);
parray_t<int> t(bits);
for (UINT32 j=1; j<bits; j++)
{
@ -172,8 +171,7 @@ ATTR_COLD void truthtable_desc_t::setup(const char **truthtable, UINT32 disabled
nl_assert_always(times.count() == m_NO, "timing count not matching");
UINT16 val = 0;
plinearlist_t<UINT8> tindex;
tindex.set_count(m_NO);
parray_t<UINT8> tindex(m_NO);
for (int j=0; j<m_NO; j++)
{
@ -196,8 +194,7 @@ ATTR_COLD void truthtable_desc_t::setup(const char **truthtable, UINT32 disabled
}
// determine ignore
plinearlist_t<UINT32> ign;
ign.set_count(m_size);
parray_t<UINT32> ign(m_size);
for (int j=0; j < m_size; j++)
ign[j] = -1;

View File

@ -421,7 +421,7 @@ class netlist_core_terminal_t : public netlist_owned_object_t, public plinkedlis
NETLIST_PREVENT_COPYING(netlist_core_terminal_t)
public:
typedef plinearlist_t<netlist_core_terminal_t *> list_t;
typedef plist_t<netlist_core_terminal_t *> list_t;
/* needed here ... */
@ -477,7 +477,7 @@ class ATTR_ALIGN netlist_terminal_t : public netlist_core_terminal_t
NETLIST_PREVENT_COPYING(netlist_terminal_t)
public:
typedef plinearlist_t<netlist_terminal_t * RESTRICT> list_t;
typedef plist_t<netlist_terminal_t * RESTRICT> list_t;
ATTR_COLD netlist_terminal_t();
@ -598,7 +598,7 @@ class netlist_net_t : public netlist_object_t
NETLIST_PREVENT_COPYING(netlist_net_t)
public:
typedef plinearlist_t<netlist_net_t *> list_t;
typedef plist_t<netlist_net_t *> list_t;
ATTR_COLD netlist_net_t(const family_t afamily);
ATTR_COLD virtual ~netlist_net_t();
@ -636,7 +636,7 @@ public:
ATTR_COLD void move_connections(netlist_net_t *new_net);
plinearlist_t<netlist_core_terminal_t *> m_core_terms; // save post-start m_list ...
plist_t<netlist_core_terminal_t *> m_core_terms; // save post-start m_list ...
ATTR_HOT inline void set_Q_time(const netlist_sig_t &newQ, const netlist_time &at)
{
@ -678,7 +678,7 @@ class netlist_logic_net_t : public netlist_net_t
NETLIST_PREVENT_COPYING(netlist_logic_net_t)
public:
typedef plinearlist_t<netlist_logic_net_t *> list_t;
typedef plist_t<netlist_logic_net_t *> list_t;
ATTR_COLD netlist_logic_net_t();
ATTR_COLD virtual ~netlist_logic_net_t() { };
@ -739,7 +739,7 @@ class netlist_analog_net_t : public netlist_net_t
NETLIST_PREVENT_COPYING(netlist_analog_net_t)
public:
typedef plinearlist_t<netlist_analog_net_t *> list_t;
typedef plist_t<netlist_analog_net_t *> list_t;
ATTR_COLD netlist_analog_net_t();
ATTR_COLD virtual ~netlist_analog_net_t() { };
@ -962,7 +962,7 @@ class netlist_core_device_t : public netlist_object_t, public netlist_logic_fami
NETLIST_PREVENT_COPYING(netlist_core_device_t)
public:
typedef plinearlist_t<netlist_core_device_t *> list_t;
typedef plist_t<netlist_core_device_t *> list_t;
ATTR_COLD netlist_core_device_t(const family_t afamily);
@ -1067,7 +1067,7 @@ public:
ATTR_COLD void connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2);
plinearlist_t<pstring, 20> m_terminals;
plist_t<pstring> m_terminals;
protected:
@ -1149,9 +1149,9 @@ public:
ATTR_COLD void log(const char *format, ...) const ATTR_PRINTF(2,3);
template<class _C>
plinearlist_t<_C *> get_device_list()
plist_t<_C *> get_device_list()
{
plinearlist_t<_C *> tmp;
plist_t<_C *> tmp;
for (netlist_device_t * const *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
{
_C *dev = dynamic_cast<_C *>(*entry);

View File

@ -87,7 +87,7 @@
// Solver defines
//============================================================
#define USE_MATRIX_GS (1)
#define USE_MATRIX_GS (0)
#define USE_PIVOT_SEARCH (0)
#define USE_GABS (1)
// savings are eaten up by effort

View File

@ -68,7 +68,7 @@ public:
class netlist_factory_t
{
public:
typedef plinearlist_t<net_device_t_base_factory *> list_t;
typedef plist_t<net_device_t_base_factory *> list_t;
ATTR_COLD netlist_factory_t();
ATTR_COLD ~netlist_factory_t();

View File

@ -194,7 +194,7 @@ ATTR_COLD void ptokenizer::error(const char *format, ...)
va_list ap;
va_start(ap, format);
pstring errmsg1 =pstring(format).vprintf(ap);
pstring errmsg1 = pstring(format).vprintf(ap);
va_end(ap);
verror(errmsg1, currentline_no(), currentline_str());

View File

@ -127,7 +127,7 @@ private:
pstring m_identifier_chars;
pstring m_number_chars;
plinearlist_t<pstring> m_tokens;
plist_t<pstring> m_tokens;
pstring m_whitespace;
char m_string;
@ -182,7 +182,7 @@ private:
class netlist_source_t
{
public:
typedef plinearlist_t<netlist_source_t> list_t;
typedef plist_t<netlist_source_t> list_t;
enum source_e
{

View File

@ -104,7 +104,7 @@ public:
typedef pnamedlist_t<link_t> tagmap_nstring_t;
typedef pnamedlist_t<netlist_param_t *> tagmap_param_t;
typedef pnamedlist_t<netlist_core_terminal_t *> tagmap_terminal_t;
typedef plinearlist_t<link_t> tagmap_link_t;
typedef plist_t<link_t> tagmap_link_t;
netlist_setup_t(netlist_base_t &netlist);
~netlist_setup_t();
@ -167,7 +167,7 @@ private:
netlist_factory_t *m_factory;
plinearlist_t<pstring> m_models;
plist_t<pstring> m_models;
int m_proxy_cnt;

View File

@ -8,6 +8,7 @@
#define NLTIME_H_
#include "nl_config.h"
#include "pstate.h"
//============================================================
// MACROS
@ -72,6 +73,11 @@ protected:
INTERNALTYPE m_time;
};
template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist_time &nlt, const void *owner, const pstring &stname)
{
save_state_ptr(stname, DT_INT64, owner, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
}
ATTR_HOT inline const netlist_time operator-(const netlist_time &left, const netlist_time &right)
{
return netlist_time::from_raw(left.m_time - right.m_time);

View File

@ -19,7 +19,7 @@ private:
nl_util() {};
public:
typedef plinearlist_t<pstring, 10> pstring_list;
typedef plist_t<pstring> pstring_list;
static pstring_list split(const pstring &str, const pstring &onstr, bool ignore_empty = false)
{

View File

@ -14,31 +14,101 @@
#include "pstring.h"
// ----------------------------------------------------------------------------------------
// plinearlist_t: a simple list
// parray_t: dynamic array
// ----------------------------------------------------------------------------------------
template <class _ListClass, int _NumElem = 0>
class plinearlist_t
template <class _ListClass>
class parray_t
{
public:
ATTR_COLD plinearlist_t(int numElements = _NumElem)
ATTR_COLD parray_t(int numElements)
: m_list(0), m_capacity(0)
{
m_num_elements = numElements;
if (m_num_elements == 0)
set_capacity(numElements);
}
ATTR_COLD parray_t(const parray_t &rhs)
: m_list(0), m_capacity(0)
{
set_capacity(rhs.capacity());
for (int i=0; i<m_capacity; i++)
m_list[i] = rhs[i];
}
ATTR_COLD parray_t &operator=(const parray_t &rhs)
{
set_capacity(rhs.capacity());
for (int i=0; i<m_capacity; i++)
m_list[i] = rhs[i];
return *this;
}
ATTR_COLD ~parray_t()
{
if (m_list != NULL)
nl_free_array(m_list);
m_list = NULL;
}
ATTR_HOT inline operator _ListClass * () { return m_list; }
ATTR_HOT inline operator const _ListClass * () const { return m_list; }
/* using the [] operator will not allow gcc to vectorize code because
* basically a pointer is returned.
* array works around this.
*/
ATTR_HOT inline _ListClass *array() { return m_list; }
ATTR_HOT inline _ListClass& operator[](const int index) { return m_list[index]; }
ATTR_HOT inline const _ListClass& operator[](const int index) const { return m_list[index]; }
ATTR_HOT inline int capacity() const { return m_capacity; }
protected:
ATTR_COLD void set_capacity(const int new_capacity)
{
if (m_list != NULL)
nl_free_array(m_list);
if (new_capacity > 0)
m_list = nl_alloc_array(_ListClass, new_capacity);
else
m_list = NULL;
m_capacity = new_capacity;
}
private:
_ListClass * m_list;
int m_capacity;
};
// ----------------------------------------------------------------------------------------
// plinearlist_t: a simple list
// ----------------------------------------------------------------------------------------
template <class _ListClass>
class plist_t
{
public:
ATTR_COLD plist_t(const int numElements = 0)
{
m_capacity = numElements;
if (m_capacity == 0)
m_list = NULL;
else
m_list = nl_alloc_array(_ListClass, m_num_elements);
m_list = nl_alloc_array(_ListClass, m_capacity);
m_count = 0;
}
ATTR_COLD plinearlist_t(const plinearlist_t &rhs)
ATTR_COLD plist_t(const plist_t &rhs)
{
m_num_elements = rhs.capacity();
if (m_num_elements == 0)
m_capacity = rhs.capacity();
if (m_capacity == 0)
m_list = NULL;
else
m_list = nl_alloc_array(_ListClass, m_num_elements);
m_list = nl_alloc_array(_ListClass, m_capacity);
m_count = 0;
for (int i=0; i<rhs.count(); i++)
{
@ -46,7 +116,7 @@ public:
}
}
ATTR_COLD plinearlist_t &operator=(const plinearlist_t &rhs)
ATTR_COLD plist_t &operator=(const plist_t &rhs)
{
this->clear();
for (int i=0; i<rhs.count(); i++)
@ -57,7 +127,7 @@ public:
}
ATTR_COLD ~plinearlist_t()
ATTR_COLD ~plist_t()
{
if (m_list != NULL)
nl_free_array(m_list);
@ -79,11 +149,11 @@ public:
ATTR_HOT inline void add(const _ListClass &elem)
{
if (m_count >= m_num_elements){
int new_size = m_num_elements * 2;
if (m_count >= m_capacity){
int new_size = m_capacity * 2;
if (new_size < 32)
new_size = 32;
resize(new_size);
set_capacity(new_size);
}
m_list[m_count++] = elem;
@ -151,7 +221,7 @@ public:
ATTR_HOT inline int count() const { return m_count; }
ATTR_HOT inline bool is_empty() const { return (m_count == 0); }
ATTR_HOT inline void clear() { m_count = 0; }
ATTR_HOT inline int capacity() const { return m_num_elements; }
ATTR_HOT inline int capacity() const { return m_capacity; }
ATTR_COLD void clear_and_free()
{
@ -162,28 +232,17 @@ public:
clear();
}
ATTR_COLD void set_count(const int new_count)
{
if (new_count < m_count)
m_count = new_count;
else
{
resize(new_count);
m_count = new_count;
}
}
private:
ATTR_COLD void resize(const int new_size)
ATTR_COLD void set_capacity(const int new_capacity)
{
int cnt = count();
if (new_size > 0)
if (new_capacity > 0)
{
_ListClass *m_new = nl_alloc_array(_ListClass, new_size);
_ListClass *m_new = nl_alloc_array(_ListClass, new_capacity);
_ListClass *pd = m_new;
if (cnt > new_size)
cnt = new_size;
if (cnt > new_capacity)
cnt = new_capacity;
for (_ListClass *ps = m_list; ps < m_list + cnt; ps++, pd++)
*pd = *ps;
if (m_list != NULL)
@ -198,55 +257,52 @@ private:
m_list = NULL;
m_count = 0;
}
m_num_elements = new_size;
m_capacity = new_capacity;
}
int m_count;
_ListClass * m_list /* ATTR_ALIGN */;
int m_num_elements;
int m_capacity;
};
// ----------------------------------------------------------------------------------------
// pnamedlist_t: a simple list
// pnamedlist_t: a simple list of elements which have a name() interface
// ----------------------------------------------------------------------------------------
#if (defined(__sun__) && defined(__svr4__)) || defined(__ANDROID__) || defined(__OpenBSD__)
#undef _C
#endif
template <class _C>
class pnamedlist_t : public plinearlist_t<_C>
template <class _ListClass>
class pnamedlist_t : public plist_t<_ListClass>
{
public:
_C find(const pstring name) const
_ListClass find(const pstring &name) const
{
for (int i=0; i < this->count(); i++)
if (get_name((*this)[i]) == name)
return (*this)[i];
return _C(NULL);
return _ListClass(NULL);
}
void remove_by_name(const pstring name)
void remove_by_name(const pstring &name)
{
plinearlist_t<_C>::remove(find(name));
plist_t<_ListClass>::remove(find(name));
}
bool add(_C dev, bool allow_duplicate)
bool add(_ListClass dev, bool allow_duplicate)
{
if (allow_duplicate)
plinearlist_t<_C>::add(dev);
plist_t<_ListClass>::add(dev);
else
{
if (!(this->find(get_name(dev)) == _C(NULL)))
if (!(this->find(get_name(dev)) == _ListClass(NULL)))
return false;
plinearlist_t<_C>::add(dev);
plist_t<_ListClass>::add(dev);
}
return true;
}
private:
template <typename T> static const pstring get_name(T &elem) { return elem.name(); }
template <typename T> static const pstring get_name(const T *elem) { return elem->name(); }
template <typename T> static const pstring get_name(T *elem) { return elem->name(); }
template <typename T> static const pstring get_name(const T &elem) { return elem.name(); }
};
@ -255,12 +311,12 @@ private:
// pstack_t: a simple stack
// ----------------------------------------------------------------------------------------
template <class _StackClass, int _NumElem = 128>
template <class _StackClass>
class pstack_t
{
public:
ATTR_COLD pstack_t(int numElements = _NumElem)
ATTR_COLD pstack_t(const int numElements = 128)
: m_list(numElements)
{
}
@ -304,7 +360,7 @@ public:
ATTR_HOT inline int capacity() const { return m_list.capacity(); }
private:
plinearlist_t<_StackClass, _NumElem> m_list;
plist_t<_StackClass> m_list;
};
template <class _ListClass>

View File

@ -8,8 +8,8 @@
#ifndef PSTATE_H_
#define PSTATE_H_
#include "nl_config.h"
#include "nl_time.h"
//#include "nl_config.h"
//#include "nl_time.h"
#include "plists.h"
#include "pstring.h"
@ -79,7 +79,7 @@ class pstate_manager_t;
class pstate_callback_t
{
public:
typedef plinearlist_t<pstate_callback_t *> list_t;
typedef plist_t<pstate_callback_t *> list_t;
virtual ~pstate_callback_t() { };
@ -91,7 +91,7 @@ protected:
struct pstate_entry_t
{
typedef plinearlist_t<pstate_entry_t *> list_t;
typedef plist_t<pstate_entry_t *> list_t;
pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const void *owner,
const int size, const int count, void *ptr, bool is_ptr)
@ -157,11 +157,5 @@ private:
template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state, const void *owner, const pstring &stname);
template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist_time &nlt, const void *owner, const pstring &stname)
{
save_state_ptr(stname, DT_INT64, owner, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
}
#endif /* PSTATE_H_ */

View File

@ -261,12 +261,6 @@ NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_vid)
col = rgb_t(colv, colv, colv);
}
while (0 && pixels >= m_htotal)
{
bm->plot_box(m_last_x, m_last_y + m_sig_field * has_fields, m_htotal - 1 - m_last_x, 1, col);
pixels -= m_htotal;
m_last_x = 0;
}
bm->plot_box(m_last_x, m_last_y + m_sig_field * has_fields, pixels - m_last_x, 1, col);
m_last_x = pixels;
}
@ -286,7 +280,7 @@ NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_vid)
if (sync & 1)
{
m_last_y = m_vbackporch - m_vsync; // 6; // FIXME: needed for pong - need to be able to adjust screen parameters
m_last_y = m_vbackporch - m_vsync;
// toggle bitmap
m_cur_bm ^= 1;
update_screen_parameters(time - m_last_vsync_time);

View File

@ -108,8 +108,6 @@ public:
NETDEV_ANALOG_CALLBACK_MEMBER(sound_cb)
{
//printf("snd %f\n", newval);
//dac_w(m_dac, 0, newval*64);
m_dac->write_unsigned8(64*data);
}

View File

@ -148,7 +148,7 @@ public:
void init()
{
m_setup = new netlist_setup_t(*this);
m_setup = nl_alloc(netlist_setup_t, *this);
this->init_object(*this, "netlist");
m_setup->init();
}
@ -302,181 +302,183 @@ static void listdevices()
convert - convert a spice netlist
-------------------------------------------------*/
struct sp_net_t
class convert_t
{
public:
sp_net_t(const pstring &aname)
: m_name(aname), m_no_export(false) {}
const pstring &name() { return m_name;}
nl_util::pstring_list &terminals() { return m_terminals; }
void set_no_export() { m_no_export = true; }
bool is_no_export() { return m_no_export; }
private:
pstring m_name;
bool m_no_export;
nl_util::pstring_list m_terminals;
};
struct sp_dev_t
{
public:
sp_dev_t(const pstring atype, const pstring aname, const pstring amodel)
: m_type(atype), m_name(aname), m_model(amodel), m_val(0), m_has_val(false)
{}
sp_dev_t(const pstring atype, const pstring aname, double aval)
: m_type(atype), m_name(aname), m_model(""), m_val(aval), m_has_val(true)
{}
const pstring &name() { return m_name;}
const pstring &type() { return m_type;}
const pstring &model() { return m_model;}
const double &value() { return m_val;}
bool has_model() { return m_model != ""; }
bool has_value() { return m_has_val; }
private:
pstring m_type;
pstring m_name;
pstring m_model;
double m_val;
bool m_has_val;
};
static pnamedlist_t<sp_net_t *> nets;
static pnamedlist_t<sp_dev_t *> devs;
static plinearlist_t<pstring> alias;
static void add_term(pstring netname, pstring termname)
{
sp_net_t * net = nets.find(netname);
if (net == NULL)
void convert(pstring contents)
{
net = new sp_net_t(netname);
nets.add(net, false);
nl_util::pstring_list spnl = nl_util::split(contents, "\n");
// Add gnd net
nets.add(nl_alloc(sp_net_t, "0"), false);
nets[0]->terminals().add("GND");
pstring line = "";
for (int i=0; i < spnl.count(); i++)
{
// Basic preprocessing
pstring inl = spnl[i].trim().ucase();
if (inl.startsWith("+"))
line = line + inl.substr(1);
else
{
process_line(line);
line = inl;
}
}
process_line(line);
dump_nl();
}
net->terminals().add(termname);
}
static struct {
pstring sp_unit;
pstring nl_func;
double mult;
} sp_units[] = {
{"T", "", 1.0e12 },
{"G", "", 1.0e9 },
{"MEG", "RES_M(%g)", 1.0e6 },
{"K", "RES_K(%g)", 1.0e3 },
{"", "%g", 1.0e0 },
{"M", "CAP_M(%g)", 1.0e-3 },
{"U", "CAP_U(%g)", 1.0e-6 },
{"µ", "CAP_U(%g)", 1.0e-6 },
{"N", "CAP_N(%g)", 1.0e-9 },
{"P", "CAP_P(%g)", 1.0e-12},
{"F", "%ge-15", 1.0e-15},
protected:
struct sp_net_t
{
public:
sp_net_t(const pstring &aname)
: m_name(aname), m_no_export(false) {}
{"MIL", "%e", 25.4e-6},
const pstring &name() { return m_name;}
nl_util::pstring_list &terminals() { return m_terminals; }
void set_no_export() { m_no_export = true; }
bool is_no_export() { return m_no_export; }
{"-", "%g", 1.0 }
};
private:
pstring m_name;
bool m_no_export;
nl_util::pstring_list m_terminals;
};
static const pstring get_nl_val(const double val)
{
struct sp_dev_t
{
public:
sp_dev_t(const pstring atype, const pstring aname, const pstring amodel)
: m_type(atype), m_name(aname), m_model(amodel), m_val(0), m_has_val(false)
{}
sp_dev_t(const pstring atype, const pstring aname, double aval)
: m_type(atype), m_name(aname), m_model(""), m_val(aval), m_has_val(true)
{}
const pstring &name() { return m_name;}
const pstring &type() { return m_type;}
const pstring &model() { return m_model;}
const double &value() { return m_val;}
bool has_model() { return m_model != ""; }
bool has_value() { return m_has_val; }
private:
pstring m_type;
pstring m_name;
pstring m_model;
double m_val;
bool m_has_val;
};
struct sp_unit {
pstring sp_unit;
pstring nl_func;
double mult;
};
void add_term(pstring netname, pstring termname)
{
sp_net_t * net = nets.find(netname);
if (net == NULL)
{
net = nl_alloc(sp_net_t, netname);
nets.add(net, false);
}
net->terminals().add(termname);
}
const pstring get_nl_val(const double val)
{
{
int i = 0;
while (m_sp_units[i].sp_unit != "-" )
{
if (m_sp_units[i].mult <= nl_math::abs(val))
break;
i++;
}
return pstring::sprintf(m_sp_units[i].nl_func.cstr(), val / m_sp_units[i].mult);
}
}
double get_sp_unit(const pstring &unit)
{
int i = 0;
while (sp_units[i].sp_unit != "-" )
while (m_sp_units[i].sp_unit != "-")
{
if (sp_units[i].mult <= nl_math::abs(val))
break;
if (m_sp_units[i].sp_unit == unit)
return m_sp_units[i].mult;
i++;
}
return pstring::sprintf(sp_units[i].nl_func.cstr(), val / sp_units[i].mult);
fprintf(stderr, "Unit %s unknown\n", unit.cstr());
return 0.0;
}
}
static double get_sp_unit(const pstring &unit)
{
int i = 0;
while (sp_units[i].sp_unit != "-")
{
if (sp_units[i].sp_unit == unit)
return sp_units[i].mult;
i++;
}
fprintf(stderr, "Unit %s unknown\n", unit.cstr());
return 0.0;
}
static double get_sp_val(const pstring &sin)
{
int p = sin.len() - 1;
while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9"))
p--;
pstring val = sin.substr(0,p + 1);
pstring unit = sin.substr(p + 1);
double get_sp_val(const pstring &sin)
{
int p = sin.len() - 1;
while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9"))
p--;
pstring val = sin.substr(0,p + 1);
pstring unit = sin.substr(p + 1);
double ret = get_sp_unit(unit) * val.as_double();
//printf("<%s> %s %d ==> %f\n", sin.cstr(), unit.cstr(), p, ret);
return ret;
}
double ret = get_sp_unit(unit) * val.as_double();
//printf("<%s> %s %d ==> %f\n", sin.cstr(), unit.cstr(), p, ret);
return ret;
}
static void convert_dump_nl()
{
for (int i=0; i<alias.count(); i++)
void dump_nl()
{
sp_net_t *net = nets.find(alias[i]);
// use the first terminal ...
printf("ALIAS(%s, %s)\n", alias[i].cstr(), net->terminals()[0].cstr());
// if the aliased net only has this one terminal connected ==> don't dump
if (net->terminals().count() == 1)
net->set_no_export();
}
for (int i=0; i<devs.count(); i++)
{
if (devs[i]->has_value())
printf("%s(%s, %s)\n", devs[i]->type().cstr(),
devs[i]->name().cstr(), get_nl_val(devs[i]->value()).cstr());
else if (devs[i]->has_model())
printf("%s(%s, \"%s\")\n", devs[i]->type().cstr(),
devs[i]->name().cstr(), devs[i]->model().cstr());
else
printf("%s(%s)\n", devs[i]->type().cstr(),
devs[i]->name().cstr());
}
// print nets
for (int i=0; i<nets.count(); i++)
{
sp_net_t * net = nets[i];
if (!net->is_no_export())
for (int i=0; i<alias.count(); i++)
{
//printf("Net %s\n", net->name().cstr());
printf("NET_C(%s", net->terminals()[0].cstr() );
for (int j=1; j<net->terminals().count(); j++)
{
printf(", %s", net->terminals()[j].cstr() );
}
printf(")\n");
sp_net_t *net = nets.find(alias[i]);
// use the first terminal ...
printf("ALIAS(%s, %s)\n", alias[i].cstr(), net->terminals()[0].cstr());
// if the aliased net only has this one terminal connected ==> don't dump
if (net->terminals().count() == 1)
net->set_no_export();
}
for (int i=0; i<devs.count(); i++)
{
if (devs[i]->has_value())
printf("%s(%s, %s)\n", devs[i]->type().cstr(),
devs[i]->name().cstr(), get_nl_val(devs[i]->value()).cstr());
else if (devs[i]->has_model())
printf("%s(%s, \"%s\")\n", devs[i]->type().cstr(),
devs[i]->name().cstr(), devs[i]->model().cstr());
else
printf("%s(%s)\n", devs[i]->type().cstr(),
devs[i]->name().cstr());
}
// print nets
for (int i=0; i<nets.count(); i++)
{
sp_net_t * net = nets[i];
if (!net->is_no_export())
{
//printf("Net %s\n", net->name().cstr());
printf("NET_C(%s", net->terminals()[0].cstr() );
for (int j=1; j<net->terminals().count(); j++)
{
printf(", %s", net->terminals()[j].cstr() );
}
printf(")\n");
}
}
devs.clear_and_free();
nets.clear_and_free();
alias.clear();
}
alias.clear();
devs.clear();
nets.clear();
}
static void convert(core_options &opts)
{
pstring spnlf = filetobuf(opts.value("f"));
nl_util::pstring_list spnl = nl_util::split(spnlf.replace("\n+",""), "\n");
// Add gnd net
nets.add(new sp_net_t("0"), false);
nets[0]->terminals().add("GND");
for (int i=0; i < spnl.count(); i++)
void process_line(const pstring &line)
{
pstring line = spnl[i].trim().ucase();
if (line != "")
{
nl_util::pstring_list tt = nl_util::split(line, " ", true);
@ -497,7 +499,7 @@ static void convert(core_options &opts)
}
else if (tt[0].equals(".ENDS"))
{
convert_dump_nl();
dump_nl();
printf("NETLIST_END()\n");
}
else
@ -511,21 +513,21 @@ static void convert(core_options &opts)
*/
int nval =tt[4].as_long(&cerr);
if ((!cerr || tt[4].startsWith("N")) && tt.count() > 5)
devs.add(new sp_dev_t("QBJT", tt[0], tt[5]), false);
devs.add(nl_alloc(sp_dev_t, "QBJT", tt[0], tt[5]), false);
else
devs.add(new sp_dev_t("QBJT", tt[0], tt[4]), false);
devs.add(nl_alloc(sp_dev_t, "QBJT", tt[0], tt[4]), false);
add_term(tt[1], tt[0] + ".C");
add_term(tt[2], tt[0] + ".B");
add_term(tt[3], tt[0] + ".E");
}
break;
case 'R':
devs.add(new sp_dev_t("RES", tt[0], get_sp_val(tt[3])), false);
devs.add(nl_alloc(sp_dev_t, "RES", tt[0], get_sp_val(tt[3])), false);
add_term(tt[1], tt[0] + ".1");
add_term(tt[2], tt[0] + ".2");
break;
case 'C':
devs.add(new sp_dev_t("CAP", tt[0], get_sp_val(tt[3])), false);
devs.add(nl_alloc(sp_dev_t, "CAP", tt[0], get_sp_val(tt[3])), false);
add_term(tt[1], tt[0] + ".1");
add_term(tt[2], tt[0] + ".2");
break;
@ -533,7 +535,7 @@ static void convert(core_options &opts)
// just simple Voltage sources ....
if (tt[2].equals("0"))
{
devs.add(new sp_dev_t("ANALOG_INPUT", tt[0], get_sp_val(tt[3])), false);
devs.add(nl_alloc(sp_dev_t, "ANALOG_INPUT", tt[0], get_sp_val(tt[3])), false);
add_term(tt[1], tt[0] + ".Q");
//add_term(tt[2], tt[0] + ".2");
}
@ -542,7 +544,7 @@ static void convert(core_options &opts)
break;
case 'D':
// FIXME: Rewrite resistor value
devs.add(new sp_dev_t("DIODE", tt[0], tt[3]), false);
devs.add(nl_alloc(sp_dev_t, "DIODE", tt[0], tt[3]), false);
add_term(tt[1], tt[0] + ".A");
add_term(tt[2], tt[0] + ".K");
break;
@ -551,8 +553,33 @@ static void convert(core_options &opts)
}
}
}
convert_dump_nl();
}
private:
pnamedlist_t<sp_net_t *> nets;
pnamedlist_t<sp_dev_t *> devs;
plist_t<pstring> alias;
static sp_unit m_sp_units[];
};
convert_t::sp_unit convert_t::m_sp_units[] = {
{"T", "", 1.0e12 },
{"G", "", 1.0e9 },
{"MEG", "RES_M(%g)", 1.0e6 },
{"K", "RES_K(%g)", 1.0e3 },
{"", "%g", 1.0e0 },
{"M", "CAP_M(%g)", 1.0e-3 },
{"U", "CAP_U(%g)", 1.0e-6 },
{"µ", "CAP_U(%g)", 1.0e-6 },
{"N", "CAP_N(%g)", 1.0e-9 },
{"P", "CAP_P(%g)", 1.0e-12},
{"F", "%ge-15", 1.0e-15},
{"MIL", "%e", 25.4e-6},
{"-", "%g", 1.0 }
};
/*-------------------------------------------------
@ -585,7 +612,11 @@ int main(int argc, char *argv[])
else if (cmd == "run")
run(opts);
else if (cmd == "convert")
convert(opts);
{
pstring contents = filetobuf(opts.value("f"));
convert_t converter;
converter.convert(contents);
}
else
{
fprintf(stderr, "Unknown command %s\n", cmd.cstr());