mirror of
https://github.com/holub/mame
synced 2025-04-27 18:53:05 +03:00
Improved kidniki sound quality while maintaining speed by adding more
frontiers. Added LOGIC_INPUT to netlist which allows to specify a logic family, i.e. output characterics. Used this for improved AY8910 port modeling. [Couriersud]
This commit is contained in:
parent
6790076cc3
commit
b4d3ecac8b
@ -57,7 +57,8 @@ void initialize_factory(factory_list_t &factory)
|
||||
ENTRY(frontier, FRONTIER_DEV, "+I,G,Q") // not intended to be used directly
|
||||
ENTRY(QBJT_EB, QBJT_EB, "model")
|
||||
ENTRY(QBJT_switch, QBJT_SW, "model")
|
||||
ENTRY(ttl_input, TTL_INPUT, "IN")
|
||||
ENTRY(logic_input, TTL_INPUT, "IN")
|
||||
ENTRY(logic_input, LOGIC_INPUT, "IN,FAMILY")
|
||||
ENTRY(analog_input, ANALOG_INPUT, "IN")
|
||||
ENTRY(log, LOG, "+I")
|
||||
ENTRY(logD, LOGD, "+I,I2")
|
||||
|
@ -131,22 +131,34 @@ NETLIB_UPDATE(extclock)
|
||||
// logic_input
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_START(ttl_input)
|
||||
NETLIB_START(logic_input)
|
||||
{
|
||||
/* make sure we get the family first */
|
||||
register_param("FAMILY", m_FAMILY, ".model FAMILY(TYPE=TTL)");
|
||||
set_logic_family(logic_family_desc_t::from_model(m_FAMILY.Value()));
|
||||
|
||||
register_output("Q", m_Q);
|
||||
register_param("IN", m_IN, 0);
|
||||
}
|
||||
|
||||
NETLIB_RESET(ttl_input)
|
||||
NETLIB_RESET(logic_input)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(ttl_input)
|
||||
NETLIB_STOP(logic_input)
|
||||
{
|
||||
if (logic_family() != NULL)
|
||||
if (!logic_family()->m_is_static)
|
||||
pfree(logic_family());
|
||||
}
|
||||
|
||||
|
||||
NETLIB_UPDATE(logic_input)
|
||||
{
|
||||
OUTLOGIC(m_Q, m_IN.Value() & 1, netlist_time::from_nsec(1));
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(ttl_input)
|
||||
NETLIB_UPDATE_PARAM(logic_input)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
@ -18,9 +18,14 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define TTL_INPUT(_name, _v) \
|
||||
NET_REGISTER_DEV(ttl_input, _name) \
|
||||
NET_REGISTER_DEV(logic_input, _name) \
|
||||
PARAM(_name.IN, _v)
|
||||
|
||||
#define LOGIC_INPUT(_name, _v, _family) \
|
||||
NET_REGISTER_DEV(logic_input, _name) \
|
||||
PARAM(_name.IN, _v) \
|
||||
PARAM(_name.FAMILY, _family)
|
||||
|
||||
#define ANALOG_INPUT(_name, _v) \
|
||||
NET_REGISTER_DEV(analog_input, _name) \
|
||||
PARAM(_name.IN, _v)
|
||||
@ -123,10 +128,13 @@ NETLIB_DEVICE_WITH_PARAMS(extclock,
|
||||
// Special support devices ...
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_DEVICE_WITH_PARAMS(ttl_input,
|
||||
NETLIB_DEVICE_WITH_PARAMS(logic_input,
|
||||
|
||||
virtual void stop();
|
||||
logic_output_t m_Q;
|
||||
|
||||
param_logic_t m_IN;
|
||||
param_model_t m_FAMILY;
|
||||
);
|
||||
|
||||
NETLIB_DEVICE_WITH_PARAMS(analog_input,
|
||||
|
@ -333,6 +333,7 @@ namespace netlist
|
||||
public:
|
||||
|
||||
logic_family_t() : m_logic_family(NULL) {}
|
||||
~logic_family_t() { }
|
||||
|
||||
ATTR_HOT const logic_family_desc_t *logic_family() const { return m_logic_family; }
|
||||
ATTR_COLD void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; }
|
||||
|
@ -860,6 +860,8 @@ const pstring setup_t::model_value_str(const pstring &model_str, const pstring &
|
||||
int pblank = tmp.find(" ", p);
|
||||
if (pblank < 0) pblank = tmp.len() + 1;
|
||||
tmp = tmp.substr(p, pblank - p);
|
||||
if (tmp.right(1) == ")")
|
||||
tmp = tmp.left(tmp.len()-1);
|
||||
int pequal = tmp.find("=", 0);
|
||||
if (pequal < 0)
|
||||
fatalerror_e("parameter %s misformat in model %s temp %s\n", entity.cstr(), model_str.cstr(), tmp.cstr());
|
||||
@ -883,6 +885,7 @@ nl_double setup_t::model_value(const pstring &model_str, const pstring &entity,
|
||||
char numfac = *(tmp.right(1).cstr());
|
||||
switch (numfac)
|
||||
{
|
||||
case 'k': factor = 1e3; break;
|
||||
case 'm': factor = 1e-3; break;
|
||||
case 'u': factor = 1e-6; break;
|
||||
case 'n': factor = 1e-9; break;
|
||||
|
@ -279,7 +279,8 @@ ATTR_HOT nl_double matrix_solver_t::solve()
|
||||
|
||||
// We are already up to date. Avoid oscillations.
|
||||
// FIXME: Make this a parameter!
|
||||
if (delta < netlist_time::from_nsec(1)) // 20000
|
||||
//if (delta < netlist_time::from_nsec(1)) // 20000
|
||||
if (delta < netlist_time::from_nsec(20000)) // 20000
|
||||
return -1.0;
|
||||
|
||||
/* update all terminals for new time step */
|
||||
@ -382,8 +383,8 @@ NETLIB_UPDATE(solver)
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
if (m_parallel.Value())
|
||||
{
|
||||
omp_set_num_threads(4);
|
||||
omp_set_dynamic(0);
|
||||
omp_set_num_threads(3);
|
||||
//omp_set_dynamic(0);
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp for
|
||||
|
@ -30,27 +30,26 @@ private:
|
||||
};
|
||||
#endif
|
||||
|
||||
inline void vec_set (const unsigned n, const double &scalar, double * RESTRICT result)
|
||||
inline void vec_set (const std::size_t n, const double &scalar, double * RESTRICT result)
|
||||
{
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
result[i] = scalar;
|
||||
}
|
||||
|
||||
inline double vecmult (const unsigned n, const double * RESTRICT a1, const double * RESTRICT a2 )
|
||||
#include "omp.h"
|
||||
inline double vecmult (const std::size_t n, const double * RESTRICT a1, const double * RESTRICT a2 )
|
||||
{
|
||||
double value = 0.0;
|
||||
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
double value = 0.0;
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
value = value + a1[i] * a2[i];
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
inline double vecmult2 (const unsigned n, const double *a1)
|
||||
inline double vecmult2 (const std::size_t n, const double *a1)
|
||||
{
|
||||
double value = 0.0;
|
||||
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
{
|
||||
const double temp = a1[i];
|
||||
value = value + temp * temp;
|
||||
@ -58,9 +57,9 @@ inline double vecmult2 (const unsigned n, const double *a1)
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void vec_mult_scalar (const int n, const double * RESTRICT v, const double scalar, double * RESTRICT result)
|
||||
inline void vec_mult_scalar (const std::size_t n, const double * RESTRICT v, const double scalar, double * RESTRICT result)
|
||||
{
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
{
|
||||
result[i] = scalar * v[i];
|
||||
}
|
||||
@ -70,37 +69,37 @@ inline void vec_mult_scalar (const int n, const double * RESTRICT v, const doubl
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
inline void vec_add_mult_scalar (const int n, const double * RESTRICT v, const double scalar, double * RESTRICT result)
|
||||
inline void vec_add_mult_scalar (const std::size_t n, const double * RESTRICT v, const double scalar, double * RESTRICT result)
|
||||
{
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t 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)
|
||||
inline void vec_add_ip(const std::size_t n, const double * RESTRICT v, double * RESTRICT result)
|
||||
{
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t 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)
|
||||
inline void vec_sub(const std::size_t n, const double * RESTRICT v1, const double * RESTRICT v2, double * RESTRICT result)
|
||||
{
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
result[i] = v1[i] - v2[i];
|
||||
}
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
inline void vec_scale (const int n, double * RESTRICT v, const double scalar)
|
||||
inline void vec_scale (const std::size_t n, double * RESTRICT v, const double scalar)
|
||||
{
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
v[i] = scalar * v[i];
|
||||
}
|
||||
|
||||
inline double vec_maxabs(const int n, const double * RESTRICT v)
|
||||
inline double vec_maxabs(const std::size_t n, const double * RESTRICT v)
|
||||
{
|
||||
double ret = 0.0;
|
||||
for ( unsigned i = 0; i < n; i++ )
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
ret = std::max(ret, std::abs(v[i]));
|
||||
|
||||
return ret;
|
||||
|
@ -389,30 +389,35 @@ ADDRESS_MAP_END
|
||||
* https://www.youtube.com/watch?v=aarl0xfBQf0
|
||||
*
|
||||
*/
|
||||
|
||||
#define USE_FRONTIERS 1
|
||||
#define USE_FIXED_STV 1
|
||||
|
||||
#include "nl_kidniki.c"
|
||||
|
||||
NETLIST_START(kidniki_interface)
|
||||
#if 0
|
||||
SOLVER(Solver, 12000)
|
||||
PARAM(Solver.ACCURACY, 1e-8)
|
||||
PARAM(Solver.NR_LOOPS, 300)
|
||||
PARAM(Solver.GS_LOOPS, 2)
|
||||
#else
|
||||
SOLVER(Solver, 12000)
|
||||
PARAM(Solver.ACCURACY, 1e-9)
|
||||
|
||||
#if (USE_FRONTIERS)
|
||||
SOLVER(Solver, 18000)
|
||||
PARAM(Solver.ACCURACY, 1e-7)
|
||||
PARAM(Solver.NR_LOOPS, 300)
|
||||
PARAM(Solver.GS_LOOPS, 1)
|
||||
PARAM(Solver.GS_THRESHOLD, 99)
|
||||
PARAM(Solver.ITERATIVE, "SOR")
|
||||
#endif
|
||||
//PARAM(Solver.GS_THRESHOLD, 99) // Force Gaussian elimination here
|
||||
PARAM(Solver.PARALLEL, 1)
|
||||
PARAM(Solver.SOR_FACTOR, 1.00)
|
||||
//FIXME proper models!
|
||||
NET_MODEL(".model 2SC945 NPN(Is=2.04f Xti=3 Eg=1.11 Vaf=6 Bf=400 Ikf=20m Xtb=1.5 Br=3.377 Rc=1 Cjc=1p Mjc=.3333 Vjc=.75 Fc=.5 Cje=25p Mje=.3333 Vje=.75 Tr=450n Tf=20n Itf=0 Vtf=0 Xtf=0 VCEO=45V ICrating=150M MFG=Toshiba)")
|
||||
NET_MODEL(".model 1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
|
||||
#else
|
||||
SOLVER(Solver, 12000)
|
||||
PARAM(Solver.ACCURACY, 1e-8)
|
||||
PARAM(Solver.NR_LOOPS, 300)
|
||||
PARAM(Solver.GS_LOOPS, 20)
|
||||
PARAM(Solver.ITERATIVE, "GMRES")
|
||||
PARAM(Solver.PARALLEL, 0)
|
||||
#endif
|
||||
|
||||
NET_MODEL(".model 2SC945 NPN(IS=3.577E-14 BF=2.382E+02 NF=1.01 VAF=1.206E+02 IKF=3.332E-01 ISE=3.038E-16 NE=1.205 BR=1.289E+01 NR=1.015 VAR=1.533E+01 IKR=2.037E-01 ISC=3.972E-14 NC=1.115 RB=3.680E+01 IRB=1.004E-04 RBM=1 RE=8.338E-01 RC=1.557E+00 CJE=1.877E-11 VJE=7.211E-01 MJE=3.486E-01 TF=4.149E-10 XTF=1.000E+02 VTF=9.956 ITF=5.118E-01 PTF=0 CJC=6.876p VJC=3.645E-01 MJC=3.074E-01 TR=5.145E-08 XTB=1.5 EG=1.11 XTI=3 FC=0.5 Vceo=50 Icrating=100m MFG=NEC)")
|
||||
// Equivalent to 1N914
|
||||
NET_MODEL(".model 1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75)")
|
||||
|
||||
LOCAL_SOURCE(kidniki_schematics)
|
||||
|
||||
@ -461,13 +466,15 @@ NETLIST_START(kidniki_interface)
|
||||
ALIAS(I_SINH0, SINH_DUMMY.2)
|
||||
#endif
|
||||
|
||||
TTL_INPUT(I_SD0, 1)
|
||||
NET_MODEL(".model AY8910PORT FAMILY(OVL=0.05 OVH=4.95 ORL=100.0 ORH=0.5k)")
|
||||
|
||||
LOGIC_INPUT(I_SD0, 1, "AY8910PORT")
|
||||
//CLOCK(I_SD0, 5)
|
||||
TTL_INPUT(I_BD0, 1)
|
||||
LOGIC_INPUT(I_BD0, 1, "AY8910PORT")
|
||||
//CLOCK(I_BD0, 5)
|
||||
TTL_INPUT(I_CH0, 1)
|
||||
LOGIC_INPUT(I_CH0, 1, "AY8910PORT")
|
||||
//CLOCK(I_CH0, 2.2 )
|
||||
TTL_INPUT(I_OH0, 1)
|
||||
LOGIC_INPUT(I_OH0, 1, "AY8910PORT")
|
||||
//CLOCK(I_OH0, 1.0)
|
||||
ANALOG_INPUT(I_MSM2K0, 0)
|
||||
ANALOG_INPUT(I_MSM3K0, 0)
|
||||
@ -489,6 +496,11 @@ NETLIST_START(kidniki_interface)
|
||||
OPTIMIZE_FRONTIER(R31.2, RES_K(5.1), 50)
|
||||
OPTIMIZE_FRONTIER(R29.2, RES_K(2.7), 50)
|
||||
OPTIMIZE_FRONTIER(R87.2, RES_K(68), 50)
|
||||
|
||||
OPTIMIZE_FRONTIER(R50.1, RES_K(2.2), 50)
|
||||
OPTIMIZE_FRONTIER(R55.1, RES_K(510), 50)
|
||||
OPTIMIZE_FRONTIER(R84.2, RES_K(50), RES_K(5))
|
||||
|
||||
#endif
|
||||
|
||||
NETLIST_END()
|
||||
|
@ -140,6 +140,7 @@ NETLIST_START(kidniki_schematics)
|
||||
RES(R29, RES_K(2.7))
|
||||
RES(R30, RES_K(10))
|
||||
RES(R31, RES_K(5.1))
|
||||
//RES(R32, RES_K(1))
|
||||
RES(R32, RES_K(4.7))
|
||||
RES(R34, RES_K(100))
|
||||
RES(R35, RES_K(100))
|
||||
|
Loading…
Reference in New Issue
Block a user