diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index b8a50ecece2..355199a8328 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -294,8 +294,8 @@ void netlist_mame_device_t::device_start() //printf("clock is %d\n", clock()); - m_netlist = global_alloc_clear(netlist_mame_t(*this)); - m_setup = global_alloc_clear(netlist::setup_t(m_netlist)); + m_netlist = global_alloc(netlist_mame_t(*this)); + m_setup = global_alloc(netlist::setup_t(m_netlist)); netlist().init_object(*m_netlist, "netlist"); m_setup->init(); @@ -459,7 +459,7 @@ void netlist_mame_cpu_device_t::device_start() { netlist_mame_device_t::device_start(); - LOG_DEV_CALLS(("device_start %s\n", tag())); + LOG_DEV_CALLS(("cpu device_start %s\n", tag())); // State support @@ -550,12 +550,11 @@ netlist_mame_sound_device_t::netlist_mame_sound_device_t(const machine_config &m { } - void netlist_mame_sound_device_t::device_start() { netlist_mame_device_t::device_start(); - LOG_DEV_CALLS(("device_start %s\n", tag())); + LOG_DEV_CALLS(("sound device_start %s\n", tag())); // Configure outputs diff --git a/src/emu/netlist/devices/nld_7404.h b/src/emu/netlist/devices/nld_7404.h index 9b88306fc29..7cf3a1acb98 100644 --- a/src/emu/netlist/devices/nld_7404.h +++ b/src/emu/netlist/devices/nld_7404.h @@ -38,7 +38,7 @@ NET_CONNECT(_name, A, _A) #define TTL_7404_DIP(_name) \ - NET_REGISTER_DEV(7402_dip, _name) + NET_REGISTER_DEV(7404_dip, _name) NETLIB_NAMESPACE_DEVICES_START() diff --git a/src/emu/netlist/devices/nld_system.c b/src/emu/netlist/devices/nld_system.c index bf998170400..478c4d0f0aa 100644 --- a/src/emu/netlist/devices/nld_system.c +++ b/src/emu/netlist/devices/nld_system.c @@ -191,15 +191,17 @@ void nld_d_to_a_proxy::start() register_subalias("Q", m_RV.m_P); connect(m_RV.m_N, m_Q); - m_Q.initial(0.0); save(NLNAME(m_last_state)); } void nld_d_to_a_proxy::reset() { + m_Q.initial(0.0); + m_last_state = -1; m_RV.do_reset(); m_is_timestep = m_RV.m_P.net().as_analog().solver()->is_timestep(); + m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0); } ATTR_HOT void nld_d_to_a_proxy::update() diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h index bf00fc9227e..1da91d2a813 100644 --- a/src/emu/netlist/devices/nld_system.h +++ b/src/emu/netlist/devices/nld_system.h @@ -342,6 +342,7 @@ protected: ATTR_HOT void update() { + //printf("%s: %f\n", name().cstr(), m_I.Q_Analog()); if (m_I.Q_Analog() > logic_family().m_high_thresh_V) OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1)); else if (m_I.Q_Analog() < logic_family().m_low_thresh_V) diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index 2e016e040b6..e837c4d27e2 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -50,11 +50,12 @@ #define NETLIST_NAME(_name) netlist ## _ ## _name #define NETLIST_EXTERNAL(_name) \ -ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup) + ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup); #define NETLIST_START(_name) \ ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup) \ { + #define NETLIST_END() } #define LOCAL_SOURCE(_name) \ diff --git a/src/emu/netlist/solver/nld_ms_gmres.h b/src/emu/netlist/solver/nld_ms_gmres.h index 66593a2f320..6ed58ac4498 100644 --- a/src/emu/netlist/solver/nld_ms_gmres.h +++ b/src/emu/netlist/solver/nld_ms_gmres.h @@ -30,6 +30,7 @@ public: : matrix_solver_direct_t(matrix_solver_t::GAUSS_SEIDEL, params, size) , m_use_iLU_preconditioning(true) , m_use_more_precise_stop_condition(false) + , m_accuracy_mult(1.0) , m_gs_fail(0) , m_gs_total(0) { @@ -82,6 +83,8 @@ private: double * RESTRICT m_v[_storage_N + 1]; /*(mr + 1), n */ //double m_y[_storage_N]; /* mr + 1 */ + double m_accuracy_mult; + int m_gs_fail; int m_gs_total; }; @@ -218,7 +221,7 @@ ATTR_HOT inline int matrix_solver_GMRES_t::vsolve_non_dynamic(c #if 1 int mr = std::min(iN-1,(int) sqrt(iN)); int iter = 4; - int gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy * 2.0); // * (double) (iN)); + int gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy); int failed = mr * iter; #else int failed = 6; @@ -294,6 +297,7 @@ int matrix_solver_GMRES_t::solve_ilu_gmres (double * RESTRICT x *------------------------------------------------------------------------*/ unsigned itr_used = 0; + double rho_delta = 0.0; const unsigned n = this->N(); @@ -323,10 +327,10 @@ int matrix_solver_GMRES_t::solve_ilu_gmres (double * RESTRICT x //printf("rho/accuracy = %f\n", rho_to_accuracy); - accuracy *= rho_to_accuracy; + rho_delta = accuracy * rho_to_accuracy; } else - accuracy *= std::sqrt((double) n); + rho_delta = accuracy * std::sqrt((double) n) * m_accuracy_mult; for (unsigned itr = 0; itr < restart_max; itr++) { @@ -391,7 +395,7 @@ int matrix_solver_GMRES_t::solve_ilu_gmres (double * RESTRICT x itr_used = itr_used + 1; - if (rho <= accuracy) + if (rho <= rho_delta) { last_k = k; break; @@ -419,10 +423,25 @@ int matrix_solver_GMRES_t::solve_ilu_gmres (double * RESTRICT x for (unsigned i = 0; i <= last_k; i++) vec_add_mult_scalar(n, m_v[i], m_y[i], x); - if (rho <= accuracy) +#if 1 + if (rho <= rho_delta) { break; } +#else + /* we try to approximate the x difference between to steps using m_v[last_k] */ + + double xdelta = m_y[last_k] * vec_maxabs(n, m_v[last_k]); + if (xdelta < accuracy) + { + if (m_accuracy_mult < 16384.0) + m_accuracy_mult = m_accuracy_mult * 2.0; + break; + } + else + m_accuracy_mult = m_accuracy_mult / 2.0; + +#endif } return itr_used; diff --git a/src/emu/netlist/solver/nld_solver.c b/src/emu/netlist/solver/nld_solver.c index c848b599b8a..e8ba510a888 100644 --- a/src/emu/netlist/solver/nld_solver.c +++ b/src/emu/netlist/solver/nld_solver.c @@ -428,8 +428,8 @@ matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const int gs_thre } else { - typedef matrix_solver_SOR_t solver_GS; - //typedef matrix_solver_GMRES_t solver_GS; + //typedef matrix_solver_SOR_t solver_GS; + typedef matrix_solver_GMRES_t solver_GS; return palloc(solver_GS, &m_params, size); } } @@ -501,7 +501,6 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() switch (net_count) { -#if 1 case 1: ms = create_solver<1,1>(1, gs_threshold, use_specific); break; @@ -532,9 +531,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() case 87: ms = create_solver<87,87>(87, gs_threshold, use_specific); break; -#endif default: -#if 0 if (net_count <= 16) { ms = create_solver<0,16>(net_count, gs_threshold, use_specific); @@ -548,7 +545,6 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() ms = create_solver<0,64>(net_count, gs_threshold, use_specific); } else -#endif if (net_count <= 128) { ms = create_solver<0,128>(net_count, gs_threshold, use_specific); diff --git a/src/emu/netlist/solver/vector_base.h b/src/emu/netlist/solver/vector_base.h index 6374fc91095..3d3a1028b2a 100644 --- a/src/emu/netlist/solver/vector_base.h +++ b/src/emu/netlist/solver/vector_base.h @@ -70,17 +70,13 @@ inline void vec_mult_scalar (const int n, const double * RESTRICT v, const doubl inline void vec_add_mult_scalar (const int n, const double * RESTRICT v, const double scalar, double * RESTRICT result) { for ( unsigned i = 0; i < n; i++ ) - { result[i] += scalar * v[i]; - } } inline void vec_add_ip(const int n, const double * RESTRICT v, double * RESTRICT result) { for ( unsigned i = 0; i < n; i++ ) - { result[i] += v[i]; - } } inline void vec_sub(const int n, const double * RESTRICT v1, const double * RESTRICT v2, double * RESTRICT result) @@ -89,13 +85,21 @@ inline void vec_sub(const int n, const double * RESTRICT v1, const double * REST result[i] = v1[i] - v2[i]; } - inline void vec_scale (const int n, double * RESTRICT v, const double scalar) { for ( unsigned i = 0; i < n; i++ ) - { v[i] = scalar * v[i]; - } } +inline double vec_maxabs(const int n, const double * RESTRICT v) +{ + double ret = 0.0; + for ( unsigned i = 0; i < n; i++ ) + ret = std::max(ret, std::abs(v[i])); + + return ret; +} + + + #endif /* MAT_CR_H_ */