Discrete cleanups and fixed discrete logging.

This commit is contained in:
Derrick Renaud 2008-08-20 01:02:57 +00:00
parent 39ea677641
commit 384422ee09
20 changed files with 1634 additions and 1414 deletions

File diff suppressed because it is too large Load Diff

View File

@ -39,22 +39,22 @@ struct dss_filter2_context
struct dst_op_amp_filt_context struct dst_op_amp_filt_context
{ {
int type; // What kind of filter int type; /* What kind of filter */
int is_norton; // 1 = Norton op-amps int is_norton; /* 1 = Norton op-amps */
double vRef; double vRef;
double vP; double vP;
double vN; double vN;
double rTotal; // All input resistance in parallel. double rTotal; /* All input resistance in parallel. */
double iFixed; // Current supplied by r3 & r4 if used. double iFixed; /* Current supplied by r3 & r4 if used. */
double exponentC1; double exponentC1;
double exponentC2; double exponentC2;
double exponentC3; double exponentC3;
double rRatio; // divide ratio of resistance network double rRatio; /* divide ratio of resistance network */
double vC1; // Charge on C1 double vC1; /* Charge on C1 */
double vC1b; // Charge on C1, part of C1 charge if needed double vC1b; /* Charge on C1, part of C1 charge if needed */
double vC2; // Charge on C2 double vC2; /* Charge on C2 */
double vC3; // Charge on C2 double vC3; /* Charge on C2 */
double gain; // Gain of the filter double gain; /* Gain of the filter */
double x1, x2; /* x[k-1], x[k-2], previous 2 input values */ double x1, x2; /* x[k-1], x[k-2], previous 2 input values */
double y1, y2; /* y[k-1], y[k-2], previous 2 output values */ double y1, y2; /* y[k-1], y[k-2], previous 2 output values */
double a1,a2; /* digital filter coefficients, denominator */ double a1,a2; /* digital filter coefficients, denominator */
@ -64,18 +64,18 @@ struct dst_op_amp_filt_context
struct dst_rcdisc_context struct dst_rcdisc_context
{ {
int state; int state;
double t; // time double t; /* time */
double f; // RCINTEGRATE double f; /* RCINTEGRATE */
double R1; // RCINTEGRATE double R1; /* RCINTEGRATE */
double R2; // RCINTEGRATE double R2; /* RCINTEGRATE */
double R3; // RCINTEGRATE double R3; /* RCINTEGRATE */
double C; // RCINTEGRATE double C; /* RCINTEGRATE */
double vCap; // RCDISC_MOD double vCap; /* RCDISC_MOD */
double vCE; // RCINTEGRATE double vCE; /* RCINTEGRATE */
double exponent0; double exponent0;
double exponent1; double exponent1;
double exp_exponent0;// RCINTEGRATE double exp_exponent0;/* RCINTEGRATE */
double exp_exponent1;// RCINTEGRATE double exp_exponent1;/* RCINTEGRATE */
}; };
struct dst_rcdisc4_context struct dst_rcdisc4_context
@ -186,6 +186,7 @@ static void calculate_filter1_coefficients(double fc, double type,
static void dst_filter1_step(node_description *node) static void dst_filter1_step(node_description *node)
{ {
struct dss_filter1_context *context = node->context; struct dss_filter1_context *context = node->context;
\
double gain = 1.0; double gain = 1.0;
if (DST_FILTER1__ENABLE == 0.0) if (DST_FILTER1__ENABLE == 0.0)
@ -270,6 +271,7 @@ static void calculate_filter2_coefficients(double fc, double d, double type,
static void dst_filter2_step(node_description *node) static void dst_filter2_step(node_description *node)
{ {
struct dss_filter2_context *context = node->context; struct dss_filter2_context *context = node->context;
double gain = 1.0; double gain = 1.0;
if (DST_FILTER2__ENABLE == 0.0) if (DST_FILTER2__ENABLE == 0.0)
@ -315,6 +317,7 @@ static void dst_filter2_reset(node_description *node)
static void dst_sallen_key_step(node_description *node) static void dst_sallen_key_step(node_description *node)
{ {
struct dss_filter2_context *context = node->context; struct dss_filter2_context *context = node->context;
double gain = 1.0; double gain = 1.0;
if (DST_SALLEN_KEY__ENABLE == 0.0) if (DST_SALLEN_KEY__ENABLE == 0.0)
@ -335,6 +338,7 @@ static void dst_sallen_key_reset(node_description *node)
{ {
struct dss_filter2_context *context = node->context; struct dss_filter2_context *context = node->context;
const discrete_op_amp_filt_info *info = node->custom; const discrete_op_amp_filt_info *info = node->custom;
double freq, q; double freq, q;
switch ((int) DST_SALLEN_KEY__TYPE) switch ((int) DST_SALLEN_KEY__TYPE)
@ -485,7 +489,7 @@ static void dst_op_amp_filt_reset(node_description *node)
context->vN = info->vN; context->vN = info->vN;
/* Work out the input resistance. It is all input and bias resistors in parallel. */ /* Work out the input resistance. It is all input and bias resistors in parallel. */
context->rTotal = 1.0 / info->r1; // There has to be an R1. Otherwise the table is wrong. context->rTotal = 1.0 / info->r1; /* There has to be an R1. Otherwise the table is wrong. */
if (info->r2 != 0) context->rTotal += 1.0 / info->r2; if (info->r2 != 0) context->rTotal += 1.0 / info->r2;
if (info->r3 != 0) context->rTotal += 1.0 / info->r3; if (info->r3 != 0) context->rTotal += 1.0 / info->r3;
context->rTotal = 1.0 / context->rTotal; context->rTotal = 1.0 / context->rTotal;
@ -633,9 +637,10 @@ static void dst_rcdisc_reset(node_description *node)
static void dst_rcdisc2_step(node_description *node) static void dst_rcdisc2_step(node_description *node)
{ {
double diff;
struct dst_rcdisc_context *context = node->context; struct dst_rcdisc_context *context = node->context;
double diff;
/* Works differently to other as we are always on, no enable */ /* Works differently to other as we are always on, no enable */
/* exponential based in difference between input/output */ /* exponential based in difference between input/output */
@ -678,9 +683,10 @@ static void dst_rcdisc2_reset(node_description *node)
static void dst_rcdisc3_step(node_description *node) static void dst_rcdisc3_step(node_description *node)
{ {
double diff;
struct dst_rcdisc_context *context = node->context; struct dst_rcdisc_context *context = node->context;
double diff;
/* Exponential based in difference between input/output */ /* Exponential based in difference between input/output */
if(DST_RCDISC3__ENABLE) if(DST_RCDISC3__ENABLE)
@ -742,6 +748,7 @@ static void dst_rcdisc3_reset(node_description *node)
static void dst_rcdisc4_step(node_description *node) static void dst_rcdisc4_step(node_description *node)
{ {
struct dst_rcdisc4_context *context = node->context; struct dst_rcdisc4_context *context = node->context;
int inp1 = (DST_RCDISC4__IN == 0) ? 0 : 1; int inp1 = (DST_RCDISC4__IN == 0) ? 0 : 1;
if (DST_RCDISC4__ENABLE == 0) if (DST_RCDISC4__ENABLE == 0)
@ -767,6 +774,7 @@ static void dst_rcdisc4_step(node_description *node)
static void dst_rcdisc4_reset(node_description *node) static void dst_rcdisc4_reset(node_description *node)
{ {
struct dst_rcdisc4_context *context = node->context; struct dst_rcdisc4_context *context = node->context;
double v, i, r, rT; double v, i, r, rT;
context->type = 0; context->type = 0;
@ -855,9 +863,10 @@ static void dst_rcdisc4_reset(node_description *node)
static void dst_rcdisc5_step(node_description *node) static void dst_rcdisc5_step(node_description *node)
{ {
double diff,u;
struct dst_rcdisc_context *context = node->context; struct dst_rcdisc_context *context = node->context;
double diff,u;
/* Exponential based in difference between input/output */ /* Exponential based in difference between input/output */
if(DST_RCDISC5__ENABLE) if(DST_RCDISC5__ENABLE)
@ -930,8 +939,9 @@ static void dst_rcdisc5_reset(node_description *node)
static void dst_rcintegrate_step(node_description *node) static void dst_rcintegrate_step(node_description *node)
{ {
double diff,u,iQ,iQc,iC,RG,vE;
struct dst_rcdisc_context *context = node->context; struct dst_rcdisc_context *context = node->context;
double diff, u, iQ, iQc, iC, RG, vE;
double dt, vP; double dt, vP;
if(DST_RCINTEGRATE__ENABLE) if(DST_RCINTEGRATE__ENABLE)
@ -942,8 +952,8 @@ static void dst_rcintegrate_step(node_description *node)
if ( u-0.7 < context->vCap*context->R2/(context->R1+context->R2)) if ( u-0.7 < context->vCap*context->R2/(context->R1+context->R2))
{ {
/* discharge .... */ /* discharge .... */
diff = 0 - context->vCap; diff = 0.0 - context->vCap;
iC = 0.0 - context->C / context->exponent1 * diff * context->exp_exponent1; // iC iC = 0.0 - context->C / context->exponent1 * diff * context->exp_exponent1; /* iC */
diff = diff - (diff * context->exp_exponent1); diff = diff - (diff * context->exp_exponent1);
context->vCap += diff; context->vCap += diff;
iQ = 0; iQ = 0;
@ -954,7 +964,7 @@ static void dst_rcintegrate_step(node_description *node)
{ {
/* charging */ /* charging */
diff = (vP - context->vCE) * context->f - context->vCap; diff = (vP - context->vCE) * context->f - context->vCap;
iC = 0.0 - context->C / context->exponent0 * diff * context->exp_exponent0; // iC iC = 0.0 - context->C / context->exponent0 * diff * context->exp_exponent0; /* iC */
diff = diff - (diff * context->exp_exponent0); diff = diff - (diff * context->exp_exponent0);
context->vCap += diff; context->vCap += diff;
iQ = iC + (iC * context->R1 + context->vCap) / context->R2; iQ = iC + (iC * context->R1 + context->vCap) / context->R2;
@ -998,6 +1008,7 @@ static void dst_rcintegrate_step(node_description *node)
static void dst_rcintegrate_reset(node_description *node) static void dst_rcintegrate_reset(node_description *node)
{ {
struct dst_rcdisc_context *context = node->context; struct dst_rcdisc_context *context = node->context;
double r; double r;
double dt = discrete_current_context->sample_time; double dt = discrete_current_context->sample_time;
@ -1049,9 +1060,10 @@ static void dst_rcintegrate_reset(node_description *node)
static void dst_rcdisc_mod_step(node_description *node) static void dst_rcdisc_mod_step(node_description *node)
{ {
double diff,Rc,Rc2,vCap,u,vD=0.0;
struct dst_rcdisc_context *context = node->context; struct dst_rcdisc_context *context = node->context;
double diff, Rc, Rc2, vCap, u, vD=0.0;
/* Exponential based in difference between input/output */ /* Exponential based in difference between input/output */
vCap = context->vCap; vCap = context->vCap;
@ -1164,6 +1176,7 @@ static void dst_rcfilter_reset(node_description *node)
static void dst_rcfilter_sw_step(node_description *node) static void dst_rcfilter_sw_step(node_description *node)
{ {
struct dst_rcfilter_sw_context *context = node->context; struct dst_rcfilter_sw_context *context = node->context;
int i; int i;
double rcexp; double rcexp;
int bits = (int)DST_RCFILTER_SW__SWITCH; int bits = (int)DST_RCFILTER_SW__SWITCH;
@ -1198,6 +1211,7 @@ static void dst_rcfilter_sw_step(node_description *node)
static void dst_rcfilter_sw_reset(node_description *node) static void dst_rcfilter_sw_reset(node_description *node)
{ {
struct dst_rcfilter_sw_context *context = node->context; struct dst_rcfilter_sw_context *context = node->context;
int i; int i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@ -1225,16 +1239,18 @@ static void dst_rcfilter_sw_reset(node_description *node)
static void dst_rcfilterN_reset(node_description *node) static void dst_rcfilterN_reset(node_description *node)
{ {
// double f=1.0/(2*M_PI* DST_RCFILTERN__R * DST_RCFILTERN__C); #if 0
double f=1.0/(2*M_PI* DST_RCFILTERN__R * DST_RCFILTERN__C);
// !!!!!!!!!!!!!! CAN'T CHEAT LIKE THIS !!!!!!!!!!!!!!!! /* !!!!!!!!!!!!!! CAN'T CHEAT LIKE THIS !!!!!!!!!!!!!!!! */
// Put this stuff in a context /* Put this stuff in a context */
//
// node->input[2] = f; node->input[2] = f;
// node->input[3] = DISC_FILTER_LOWPASS; node->input[3] = DISC_FILTER_LOWPASS;
/* Use first order filter */ /* Use first order filter */
dst_filter1_reset(node); dst_filter1_reset(node);
#endif
} }
@ -1256,21 +1272,24 @@ static void dst_rcfilterN_reset(node_description *node)
static void dst_rcdiscN_reset(node_description *node) static void dst_rcdiscN_reset(node_description *node)
{ {
// double f=1.0/(2*M_PI* DST_RCDISCN__R * DST_RCDISCN__C); #if 0
double f = 1.0 / (2 * M_PI * DST_RCDISCN__R * DST_RCDISCN__C);
// !!!!!!!!!!!!!! CAN'T CHEAT LIKE THIS !!!!!!!!!!!!!!!! /* !!!!!!!!!!!!!! CAN'T CHEAT LIKE THIS !!!!!!!!!!!!!!!! */
// Put this stuff in a context /* Put this stuff in a context */
//
// node->input[2] = f; node->input[2] = f;
// node->input[3] = DISC_FILTER_LOWPASS; node->input[3] = DISC_FILTER_LOWPASS;
/* Use first order filter */ /* Use first order filter */
dst_filter1_reset(node); dst_filter1_reset(node);
#endif
} }
static void dst_rcdiscN_step(node_description *node) static void dst_rcdiscN_step(node_description *node)
{ {
struct dss_filter1_context *context = node->context; struct dss_filter1_context *context = node->context;
double gain = 1.0; double gain = 1.0;
if (DST_RCDISCN__ENABLE == 0.0) if (DST_RCDISCN__ENABLE == 0.0)
@ -1321,6 +1340,7 @@ struct dss_rcdisc2_context
static void dst_rcdisc2N_step(node_description *node) static void dst_rcdisc2N_step(node_description *node)
{ {
struct dss_rcdisc2_context *context = node->context; struct dss_rcdisc2_context *context = node->context;
double input = ((DST_RCDISC2N__ENABLE == 0) ? DST_RCDISC2N__IN0 : DST_RCDISC2N__IN1); double input = ((DST_RCDISC2N__ENABLE == 0) ? DST_RCDISC2N__IN0 : DST_RCDISC2N__IN1);
if (DST_RCDISC2N__ENABLE == 0) if (DST_RCDISC2N__ENABLE == 0)

View File

@ -35,6 +35,7 @@ READ8_HANDLER(discrete_sound_r)
{ {
discrete_info *info = sndti_token(SOUND_DISCRETE, 0); discrete_info *info = sndti_token(SOUND_DISCRETE, 0);
node_description *node = discrete_find_node(info, offset); node_description *node = discrete_find_node(info, offset);
UINT8 data = 0; UINT8 data = 0;
/* Read the node input value if allowed */ /* Read the node input value if allowed */
@ -122,6 +123,7 @@ WRITE8_HANDLER(discrete_sound_w)
static void dss_adjustment_step(node_description *node) static void dss_adjustment_step(node_description *node)
{ {
struct dss_adjustment_context *context = node->context; struct dss_adjustment_context *context = node->context;
INT32 rawportval = input_port_read_direct(context->port); INT32 rawportval = input_port_read_direct(context->port);
/* only recompute if the value changed from last time */ /* only recompute if the value changed from last time */
@ -141,6 +143,7 @@ static void dss_adjustment_step(node_description *node)
static void dss_adjustment_reset(node_description *node) static void dss_adjustment_reset(node_description *node)
{ {
struct dss_adjustment_context *context = node->context; struct dss_adjustment_context *context = node->context;
double min, max; double min, max;
if (node->custom) if (node->custom)
@ -249,7 +252,7 @@ static void dss_input_pulse_step(node_description *node)
static void dss_input_stream_step(node_description *node) static void dss_input_stream_step(node_description *node)
{ {
// the context pointer is set to point to the current input stream data in discrete_stream_update /* the context pointer is set to point to the current input stream data in discrete_stream_update */
stream_sample_t **ptr = node->context; stream_sample_t **ptr = node->context;
stream_sample_t *data = *ptr; stream_sample_t *data = *ptr;

View File

@ -45,9 +45,10 @@
struct dst_dac_r1_context struct dst_dac_r1_context
{ {
double iBias; // current of the bias circuit double i_bias; /* current of the bias circuit */
double exponent; // smoothing curve double exponent; /* smoothing curve */
double rTotal; // all resistors in parallel double r_total; /* all resistors in parallel */
int last_data;
}; };
struct dst_flipflop_context struct dst_flipflop_context
@ -58,9 +59,9 @@ struct dst_flipflop_context
struct dst_integrate_context struct dst_integrate_context
{ {
double change; double change;
double vMaxIn; // v1 - norton VBE double v_max_in; /* v1 - norton VBE */
double vMaxInD; // v1 - norton VBE - diode drop double v_max_in_d; /* v1 - norton VBE - diode drop */
double vMaxOut; double v_max_out;
}; };
#define DISC_MIXER_MAX_INPS 8 #define DISC_MIXER_MAX_INPS 8
@ -69,22 +70,22 @@ struct dst_mixer_context
{ {
int type; int type;
int size; int size;
double rTotal; double r_total;
double *rNode[DISC_MIXER_MAX_INPS]; // Either pointer to resistance node output OR NULL double *r_node[DISC_MIXER_MAX_INPS]; /* Either pointer to resistance node output OR NULL */
double exponent_rc[DISC_MIXER_MAX_INPS]; // For high pass filtering cause by cIn double exponent_rc[DISC_MIXER_MAX_INPS]; /* For high pass filtering cause by cIn */
double vCap[DISC_MIXER_MAX_INPS]; // cap voltage of each input double v_cap[DISC_MIXER_MAX_INPS]; /* cap voltage of each input */
double exponent_cF; // Low pass on mixed inputs double exponent_c_f; /* Low pass on mixed inputs */
double exponent_cAmp; // Final high pass caused by out cap and amp input impedance double exponent_c_amp; /* Final high pass caused by out cap and amp input impedance */
double vCapF; // cap voltage of cF double v_cap_f; /* cap voltage of cF */
double vCapAmp; // cap voltage of cAmp double v_cap_amp; /* cap voltage of cAmp */
double gain; // used for DISC_MIXER_IS_OP_AMP_WITH_RI double gain; /* used for DISC_MIXER_IS_OP_AMP_WITH_RI */
}; };
struct dst_oneshot_context struct dst_oneshot_context
{ {
double countdown; double countdown;
int state; int state;
int lastTrig; int last_trig;
}; };
struct dss_ramp_context struct dss_ramp_context
@ -96,7 +97,7 @@ struct dss_ramp_context
struct dst_samphold_context struct dst_samphold_context
{ {
double lastinput; double last_input;
int clocktype; int clocktype;
}; };
@ -110,19 +111,19 @@ struct dst_op_amp_context
UINT8 has_cap; UINT8 has_cap;
UINT8 has_r1; UINT8 has_r1;
UINT8 has_r4; UINT8 has_r4;
double vMax; double v_max;
double iFixed; double i_fixed;
double vCap; double v_cap;
double exponent; double exponent;
}; };
struct dst_op_amp_1sht_context struct dst_op_amp_1sht_context
{ {
double iFixed; double i_fixed;
double vMax; double v_max;
double r34ratio; double r34ratio;
double vCap1; double v_cap1;
double vCap2; double v_cap2;
double exponent1c; double exponent1c;
double exponent1d; double exponent1d;
double exponent2; double exponent2;
@ -130,19 +131,19 @@ struct dst_op_amp_1sht_context
struct dst_tvca_op_amp_context struct dst_tvca_op_amp_context
{ {
double vOutMax; // Maximum output voltage double v_out_max; /* Maximum output voltage */
double vTrig[2]; // Voltage used to charge cap1 based on function F3 double v_trig[2]; /* Voltage used to charge cap1 based on function F3 */
double vTrig2; // Voltage used to charge cap2 double v_trig2; /* Voltage used to charge cap2 */
double vTrig3; // Voltage used to charge cap3 double v_trig3; /* Voltage used to charge cap3 */
double iFixed; // Fixed current going into - input double i_fixed; /* Fixed current going into - input */
double exponentC[2]; // Charge exponents based on function F3 double exponent_c[2]; /* Charge exponents based on function F3 */
double exponentD[2]; // Discharge exponents based on function F3 double exponent_d[2]; /* Discharge exponents based on function F3 */
double exponent2[2]; // Discharge/charge exponents based on function F4 double exponent2[2]; /* Discharge/charge exponents based on function F4 */
double exponent3[2]; // Discharge/charge exponents based on function F5 double exponent3[2]; /* Discharge/charge exponents based on function F5 */
double vCap1; // charge on cap c1 double v_cap1; /* charge on cap c1 */
double vCap2; // charge on cap c2 double v_cap2; /* charge on cap c2 */
double vCap3; // charge on cap c3 double v_cap3; /* charge on cap c3 */
double r67; // = r6 + r7 (for easy use later) double r67; /* = r6 + r7 (for easy use later) */
}; };
@ -276,23 +277,43 @@ static void dst_dac_r1_step(node_description *node)
const discrete_dac_r1_ladder *info = node->custom; const discrete_dac_r1_ladder *info = node->custom;
struct dst_dac_r1_context *context = node->context; struct dst_dac_r1_context *context = node->context;
int bit; int bit, bit_val, data;
double v; double v, i_bit, i_total, x_time;
double i;
i = context->iBias; i_total = context->i_bias;
data = (int)DST_DAC_R1__DATA;
x_time = DST_DAC_R1__DATA - data;
if (DST_DAC_R1__ENABLE) if (DST_DAC_R1__ENABLE)
{ {
for (bit=0; bit < info->ladderLength; bit++) for (bit=0; bit < info->ladderLength; bit++)
{ {
/* Add up currents of ON circuits per Millman. */ /* Add up currents of ON circuits per Millman. */
/* Off, being 0V and having no current, can be ignored. */
if ((DST_DAC_R1__DATA & (1 << bit)) && info->r[bit]) /* ignore if no resistor present */
i += DST_DAC_R1__VON / info->r[bit]; if (info->r[bit] != 0)
{
i_bit = DST_DAC_R1__VON / info->r[bit];
bit_val = (data >> bit) & 0x01;
if ((x_time != 0) && (bit_val != ((context->last_data >> bit) & 0x01)))
{
/* there is x_time and a change in bit,
* so anti-alias the current */
i_bit *= bit_val ? x_time : 1.0 - x_time;
}
else
{
/* there is no x_time or a change in bit,
* so 0 the current if the bit value is 0 */
if (bit_val == 0) i_bit = 0;
}
i_total += i_bit;
}
} }
v = i * context->rTotal; v = i_total * context->r_total;
/* Filter if needed, else just output voltage */ /* Filter if needed, else just output voltage */
node->output[0] = info->cFilter ? node->output[0] + ((v - node->output[0]) * context->exponent) : v; node->output[0] = info->cFilter ? node->output[0] + ((v - node->output[0]) * context->exponent) : v;
@ -316,9 +337,9 @@ static void dst_dac_r1_reset(node_description *node)
/* Calculate the Millman current of the bias circuit */ /* Calculate the Millman current of the bias circuit */
if (info->rBias) if (info->rBias)
context->iBias = info->vBias / info->rBias; context->i_bias = info->vBias / info->rBias;
else else
context->iBias = 0; context->i_bias = 0;
/* /*
* We will do a small amount of error checking. * We will do a small amount of error checking.
@ -340,22 +361,22 @@ static void dst_dac_r1_reset(node_description *node)
* This is the combined resistance of the voltage sources. * This is the combined resistance of the voltage sources.
* This is used for the charging curve. * This is used for the charging curve.
*/ */
context->rTotal = 0; context->r_total = 0;
for(bit = 0; bit < info->ladderLength; bit++) for(bit = 0; bit < info->ladderLength; bit++)
{ {
if (info->r[bit]) if (info->r[bit])
context->rTotal += 1.0 / info->r[bit]; context->r_total += 1.0 / info->r[bit];
} }
if (info->rBias) context->rTotal += 1.0 / info->rBias; if (info->rBias) context->r_total += 1.0 / info->rBias;
if (info->rGnd) context->rTotal += 1.0 / info->rGnd; if (info->rGnd) context->r_total += 1.0 / info->rGnd;
context->rTotal = 1.0 / context->rTotal; context->r_total = 1.0 / context->r_total;
node->output[0] = 0; node->output[0] = 0;
if (info->cFilter) if (info->cFilter)
{ {
/* Setup filter constants */ /* Setup filter constants */
context->exponent = -1.0 / (context->rTotal * info->cFilter * discrete_current_context->sample_rate); context->exponent = -1.0 / (context->r_total * info->cFilter * discrete_current_context->sample_rate);
context->exponent = 1.0 - exp(context->exponent); context->exponent = 1.0 - exp(context->exponent);
} }
} }
@ -379,6 +400,7 @@ static void dst_dac_r1_reset(node_description *node)
static void dst_diode_mix_step(node_description *node) static void dst_diode_mix_step(node_description *node)
{ {
struct dst_size_context *context = node->context; struct dst_size_context *context = node->context;
double max = 0; double max = 0;
int addr; int addr;
@ -524,8 +546,8 @@ static void dst_integrate_step(node_description *node)
struct dst_integrate_context *context = node->context; struct dst_integrate_context *context = node->context;
int trig0, trig1; int trig0, trig1;
double iNeg = 0; // current into - input double i_neg = 0; /* current into - input */
double iPos = 0; // current into + input double i_pos = 0; /* current into + input */
switch (info->type) switch (info->type)
{ {
@ -535,32 +557,32 @@ static void dst_integrate_step(node_description *node)
/* This forces the cap to completely charge, /* This forces the cap to completely charge,
* and the output to go to it's max value. * and the output to go to it's max value.
*/ */
node->output[0] = context->vMaxOut; node->output[0] = context->v_max_out;
return; return;
} }
node->output[0] -= context->change; node->output[0] -= context->change;
break; break;
case DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON: case DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON:
iNeg = context->vMaxIn / info->r1; i_neg = context->v_max_in / info->r1;
iPos = (DST_INTEGRATE__TRG0 - OP_AMP_NORTON_VBE) / info->r2; i_pos = (DST_INTEGRATE__TRG0 - OP_AMP_NORTON_VBE) / info->r2;
if (iPos < 0) iPos = 0; if (i_pos < 0) i_pos = 0;
node->output[0] += (iPos - iNeg) / discrete_current_context->sample_rate / info->c; node->output[0] += (i_pos - i_neg) / discrete_current_context->sample_rate / info->c;
break; break;
case DISC_INTEGRATE_OP_AMP_2 | DISC_OP_AMP_IS_NORTON: case DISC_INTEGRATE_OP_AMP_2 | DISC_OP_AMP_IS_NORTON:
trig0 = (int)DST_INTEGRATE__TRG0; trig0 = (int)DST_INTEGRATE__TRG0;
trig1 = (int)DST_INTEGRATE__TRG1; trig1 = (int)DST_INTEGRATE__TRG1;
iNeg = dst_trigger_function(trig0, trig1, 0, info->f0) ? context->vMaxInD / info->r1 : 0; i_neg = dst_trigger_function(trig0, trig1, 0, info->f0) ? context->v_max_in_d / info->r1 : 0;
iPos = dst_trigger_function(trig0, trig1, 0, info->f1) ? context->vMaxIn / info->r2 : 0; i_pos = dst_trigger_function(trig0, trig1, 0, info->f1) ? context->v_max_in / info->r2 : 0;
iPos += dst_trigger_function(trig0, trig1, 0, info->f2) ? context->vMaxInD / info->r3 : 0; i_pos += dst_trigger_function(trig0, trig1, 0, info->f2) ? context->v_max_in_d / info->r3 : 0;
node->output[0] += (iPos - iNeg) / discrete_current_context->sample_rate / info->c; node->output[0] += (i_pos - i_neg) / discrete_current_context->sample_rate / info->c;
break; break;
} }
/* Clip the output. */ /* Clip the output. */
if (node->output[0] < 0) node->output[0] = 0; if (node->output[0] < 0) node->output[0] = 0;
if (node->output[0] > context->vMaxOut) node->output[0] = context->vMaxOut; if (node->output[0] > context->v_max_out) node->output[0] = context->v_max_out;
} }
static void dst_integrate_reset(node_description *node) static void dst_integrate_reset(node_description *node)
@ -571,13 +593,13 @@ static void dst_integrate_reset(node_description *node)
if (info->type & DISC_OP_AMP_IS_NORTON) if (info->type & DISC_OP_AMP_IS_NORTON)
{ {
context->vMaxOut = info->vP - OP_AMP_NORTON_VBE; context->v_max_out = info->vP - OP_AMP_NORTON_VBE;
context->vMaxIn = info->v1 - OP_AMP_NORTON_VBE; context->v_max_in = info->v1 - OP_AMP_NORTON_VBE;
context->vMaxInD = context->vMaxIn - OP_AMP_NORTON_VBE; context->v_max_in_d = context->v_max_in - OP_AMP_NORTON_VBE;
} }
else else
{ {
context->vMaxOut = info->vP - OP_AMP_VP_RAIL_OFFSET; context->v_max_out = info->vP - OP_AMP_VP_RAIL_OFFSET;
v = info->v1 * info->r3 / (info->r2 + info->r3); /* vRef */ v = info->v1 * info->r3 / (info->r2 + info->r3); /* vRef */
v = info->v1 - v; /* actual charging voltage */ v = info->v1 - v; /* actual charging voltage */
@ -798,6 +820,7 @@ static void dst_logic_nxor_step(node_description *node)
static void dst_logic_dff_step(node_description *node) static void dst_logic_dff_step(node_description *node)
{ {
struct dst_flipflop_context *context = node->context; struct dst_flipflop_context *context = node->context;
int clk = (int)DST_LOGIC_DFF__CLOCK; int clk = (int)DST_LOGIC_DFF__CLOCK;
if (DST_LOGIC_DFF__ENABLE) if (DST_LOGIC_DFF__ENABLE)
@ -807,10 +830,8 @@ static void dst_logic_dff_step(node_description *node)
else if (DST_LOGIC_DFF__SET) else if (DST_LOGIC_DFF__SET)
node->output[0] = 1; node->output[0] = 1;
else if (!context->last_clk && clk) /* low to high */ else if (!context->last_clk && clk) /* low to high */
{
node->output[0] = DST_LOGIC_DFF__DATA; node->output[0] = DST_LOGIC_DFF__DATA;
} }
}
else else
{ {
node->output[0] = 0; node->output[0] = 0;
@ -821,6 +842,7 @@ static void dst_logic_dff_step(node_description *node)
static void dst_logic_ff_reset(node_description *node) static void dst_logic_ff_reset(node_description *node)
{ {
struct dst_flipflop_context *context = node->context; struct dst_flipflop_context *context = node->context;
context->last_clk = 0; context->last_clk = 0;
node->output[0] = 0; node->output[0] = 0;
} }
@ -848,6 +870,7 @@ static void dst_logic_ff_reset(node_description *node)
static void dst_logic_jkff_step(node_description *node) static void dst_logic_jkff_step(node_description *node)
{ {
struct dst_flipflop_context *context = node->context; struct dst_flipflop_context *context = node->context;
int clk = (int)DST_LOGIC_JKFF__CLOCK; int clk = (int)DST_LOGIC_JKFF__CLOCK;
int j = (int)DST_LOGIC_JKFF__J; int j = (int)DST_LOGIC_JKFF__J;
int k = (int)DST_LOGIC_JKFF__K; int k = (int)DST_LOGIC_JKFF__K;
@ -905,6 +928,7 @@ static void dst_logic_jkff_step(node_description *node)
static void dst_lookup_table_step(node_description *node) static void dst_lookup_table_step(node_description *node)
{ {
const double *table = node->custom; const double *table = node->custom;
int addr = DST_LOOKUP_TABLE__IN; int addr = DST_LOOKUP_TABLE__IN;
if (!DST_LOOKUP_TABLE__ENABLE || addr < 0 || addr >= DST_LOOKUP_TABLE__SIZE) if (!DST_LOOKUP_TABLE__ENABLE || addr < 0 || addr >= DST_LOOKUP_TABLE__SIZE)
@ -971,13 +995,13 @@ static void dst_mixer_step(node_description *node)
const discrete_mixer_desc *info = node->custom; const discrete_mixer_desc *info = node->custom;
struct dst_mixer_context *context = node->context; struct dst_mixer_context *context = node->context;
double v, vTemp, rTotal, rTemp, rTemp2 = 0; double v, vTemp, r_total, rTemp, rTemp2 = 0;
double i = 0; // total current of inputs double i = 0; /* total current of inputs */
int bit, connected; int bit, connected;
if (DST_MIXER__ENABLE) if (DST_MIXER__ENABLE)
{ {
rTotal = context->rTotal; r_total = context->r_total;
if (context->type & DISC_MIXER_HAS_R_NODE) if (context->type & DISC_MIXER_HAS_R_NODE)
{ {
@ -987,15 +1011,15 @@ static void dst_mixer_step(node_description *node)
connected = 1; connected = 1;
vTemp = DST_MIXER__IN(bit); vTemp = DST_MIXER__IN(bit);
if (info->rNode[bit]) if (info->r_node[bit])
{ {
/* a node has the posibility of being disconnected from the circuit. */ /* a node has the posibility of being disconnected from the circuit. */
if (*context->rNode[bit] == 0) if (*context->r_node[bit] == 0)
connected = 0; connected = 0;
else else
{ {
rTemp += *context->rNode[bit]; rTemp += *context->r_node[bit];
rTotal += 1.0 / rTemp; r_total += 1.0 / rTemp;
if (info->c[bit] != 0) if (info->c[bit] != 0)
{ {
switch (context->type & DISC_MIXER_TYPE_MASK) switch (context->type & DISC_MIXER_TYPE_MASK)
@ -1027,8 +1051,8 @@ static void dst_mixer_step(node_description *node)
if (info->c[bit] != 0) if (info->c[bit] != 0)
{ {
/* do input high pass filtering if needed. */ /* do input high pass filtering if needed. */
context->vCap[bit] += (vTemp - info->vRef - context->vCap[bit]) * context->exponent_rc[bit]; context->v_cap[bit] += (vTemp - info->vRef - context->v_cap[bit]) * context->exponent_rc[bit];
vTemp -= context->vCap[bit]; vTemp -= context->v_cap[bit];
} }
i += (((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP) ? info->vRef - vTemp : vTemp) / rTemp; i += (((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP) ? info->vRef - vTemp : vTemp) / rTemp;
} }
@ -1044,8 +1068,8 @@ static void dst_mixer_step(node_description *node)
if (info->c[bit] != 0) if (info->c[bit] != 0)
{ {
/* do input high pass filtering if needed. */ /* do input high pass filtering if needed. */
context->vCap[bit] += (vTemp - info->vRef - context->vCap[bit]) * context->exponent_rc[bit]; context->v_cap[bit] += (vTemp - info->vRef - context->v_cap[bit]) * context->exponent_rc[bit];
vTemp -= context->vCap[bit]; vTemp -= context->v_cap[bit];
} }
i += (((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP) ? info->vRef - vTemp : vTemp) / rTemp; i += (((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP) ? info->vRef - vTemp : vTemp) / rTemp;
} }
@ -1054,11 +1078,11 @@ static void dst_mixer_step(node_description *node)
if ((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP_WITH_RI) if ((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP_WITH_RI)
i += info->vRef / info->rI; i += info->vRef / info->rI;
rTotal = 1.0 / rTotal; r_total = 1.0 / r_total;
/* If resistor network or has rI then Millman is used. /* If resistor network or has rI then Millman is used.
* If op-amp then summing formula is used. */ * If op-amp then summing formula is used. */
v = i * (((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP) ? info->rF : rTotal); v = i * (((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP) ? info->rF : r_total);
if ((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP_WITH_RI) if ((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP_WITH_RI)
v = info->vRef + (context->gain * (info->vRef - v)); v = info->vRef + (context->gain * (info->vRef - v));
@ -1069,18 +1093,18 @@ static void dst_mixer_step(node_description *node)
if (context->type & DISC_MIXER_HAS_R_NODE) if (context->type & DISC_MIXER_HAS_R_NODE)
{ {
/* Re-calculate exponent if resistor nodes are used */ /* Re-calculate exponent if resistor nodes are used */
context->exponent_cF = -1.0 / (rTotal * info->cF * discrete_current_context->sample_rate); context->exponent_c_f = -1.0 / (r_total * info->cF * discrete_current_context->sample_rate);
context->exponent_cF = 1.0 - exp(context->exponent_cF); context->exponent_c_f = 1.0 - exp(context->exponent_c_f);
} }
context->vCapF += (v -info->vRef - context->vCapF) * context->exponent_cF; context->v_cap_f += (v -info->vRef - context->v_cap_f) * context->exponent_c_f;
v = context->vCapF; v = context->v_cap_f;
} }
/* Do the high pass filtering for cAmp */ /* Do the high pass filtering for cAmp */
if (info->cAmp != 0) if (info->cAmp != 0)
{ {
context->vCapAmp += (v - context->vCapAmp) * context->exponent_cAmp; context->v_cap_amp += (v - context->v_cap_amp) * context->exponent_c_amp;
v -= context->vCapAmp; v -= context->v_cap_amp;
} }
node->output[0] = v * info->gain; node->output[0] = v * info->gain;
} }
@ -1099,14 +1123,14 @@ static void dst_mixer_reset(node_description *node)
int bit; int bit;
double rTemp = 0; double rTemp = 0;
/* link to rNode outputs */ /* link to r_node outputs */
for (bit = 0; bit < 8; bit ++) for (bit = 0; bit < 8; bit ++)
{ {
r_node = discrete_find_node(NULL, info->rNode[bit]); r_node = discrete_find_node(NULL, info->r_node[bit]);
if (r_node) if (r_node)
context->rNode[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->rNode[bit])]); context->r_node[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->r_node[bit])]);
else else
context->rNode[bit] = NULL; context->r_node[bit] = NULL;
} }
context->size = node->active_inputs - 1; context->size = node->active_inputs - 1;
@ -1124,20 +1148,20 @@ static void dst_mixer_reset(node_description *node)
* This is the combined resistance of the voltage sources. * This is the combined resistance of the voltage sources.
* Also calculate the exponents while we are here. * Also calculate the exponents while we are here.
*/ */
context->rTotal = 0; context->r_total = 0;
for(bit = 0; bit < context->size; bit++) for(bit = 0; bit < context->size; bit++)
{ {
if (info->rNode[bit]) if (info->r_node[bit])
context->type = context->type | DISC_MIXER_HAS_R_NODE; context->type = context->type | DISC_MIXER_HAS_R_NODE;
if ((info->r[bit] != 0) && !info->rNode[bit] ) if ((info->r[bit] != 0) && !info->r_node[bit] )
{ {
context->rTotal += 1.0 / info->r[bit]; context->r_total += 1.0 / info->r[bit];
} }
context->vCap[bit] = 0; context->v_cap[bit] = 0;
context->exponent_rc[bit] = 0; context->exponent_rc[bit] = 0;
if ((info->c[bit] != 0) && !info->rNode[bit]) if ((info->c[bit] != 0) && !info->r_node[bit])
{ {
switch (context->type) switch (context->type)
{ {
@ -1164,28 +1188,28 @@ static void dst_mixer_reset(node_description *node)
if (info->rF != 0) if (info->rF != 0)
{ {
if (info->type == DISC_MIXER_IS_RESISTOR) context->rTotal += 1.0 / info->rF; if (info->type == DISC_MIXER_IS_RESISTOR) context->r_total += 1.0 / info->rF;
} }
if (context->type == DISC_MIXER_IS_OP_AMP_WITH_RI) context->rTotal += 1.0 / info->rI; if (context->type == DISC_MIXER_IS_OP_AMP_WITH_RI) context->r_total += 1.0 / info->rI;
context->vCapF = 0; context->v_cap_f = 0;
context->exponent_cF = 0; context->exponent_c_f = 0;
if (info->cF != 0) if (info->cF != 0)
{ {
/* Setup filter constants */ /* Setup filter constants */
context->exponent_cF = -1.0 / (((info->type == DISC_MIXER_IS_OP_AMP) ? info->rF : (1.0 / context->rTotal))* info->cF * discrete_current_context->sample_rate); context->exponent_c_f = -1.0 / (((info->type == DISC_MIXER_IS_OP_AMP) ? info->rF : (1.0 / context->r_total))* info->cF * discrete_current_context->sample_rate);
context->exponent_cF = 1.0 - exp(context->exponent_cF); context->exponent_c_f = 1.0 - exp(context->exponent_c_f);
} }
context->vCapAmp = 0; context->v_cap_amp = 0;
context->exponent_cAmp = 0; context->exponent_c_amp = 0;
if (info->cAmp != 0) if (info->cAmp != 0)
{ {
/* Setup filter constants */ /* Setup filter constants */
/* We will use 100000 ohms as an average final stage impedance. */ /* We will use 100000 ohms as an average final stage impedance. */
/* Your amp/speaker system will have more effect on incorrect filtering then any value used here. */ /* Your amp/speaker system will have more effect on incorrect filtering then any value used here. */
context->exponent_cAmp = -1.0 / (100000 * info->cAmp * discrete_current_context->sample_rate); context->exponent_c_amp = -1.0 / (100000 * info->cAmp * discrete_current_context->sample_rate);
context->exponent_cAmp = 1.0 - exp(context->exponent_cAmp); context->exponent_c_amp = 1.0 - exp(context->exponent_c_amp);
} }
if ((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP_WITH_RI) context->gain = info->rF / info->rI; if ((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP_WITH_RI) context->gain = info->rF / info->rI;
@ -1213,11 +1237,12 @@ static void dst_mixer_reset(node_description *node)
static void dst_multiplex_step(node_description *node) static void dst_multiplex_step(node_description *node)
{ {
struct dst_size_context *context = node->context; struct dst_size_context *context = node->context;
int addr; int addr;
if(DST_MULTIPLEX__ENABLE) if(DST_MULTIPLEX__ENABLE)
{ {
addr = DST_MULTIPLEX__ADDR; // FP to INT addr = DST_MULTIPLEX__ADDR; /* FP to INT */
if ((addr >= 0) && (addr < context->size)) if ((addr >= 0) && (addr < context->size))
{ {
node->output[0] = DST_MULTIPLEX__INP(addr); node->output[0] = DST_MULTIPLEX__INP(addr);
@ -1265,10 +1290,11 @@ static void dst_multiplex_reset(node_description *node)
static void dst_oneshot_step(node_description *node) static void dst_oneshot_step(node_description *node)
{ {
struct dst_oneshot_context *context = node->context; struct dst_oneshot_context *context = node->context;
int trigger = (DST_ONESHOT__TRIG != 0); int trigger = (DST_ONESHOT__TRIG != 0);
/* If the state is triggered we will need to countdown later */ /* If the state is triggered we will need to countdown later */
int doCount = context->state; int do_count = context->state;
if (DST_ONESHOT__RESET) if (DST_ONESHOT__RESET)
{ {
@ -1279,10 +1305,10 @@ static void dst_oneshot_step(node_description *node)
else else
{ {
/* are we at an edge? */ /* are we at an edge? */
if (trigger != context->lastTrig) if (trigger != context->last_trig)
{ {
/* There has been a trigger edge */ /* There has been a trigger edge */
context->lastTrig = trigger; context->last_trig = trigger;
/* Is it the proper edge trigger */ /* Is it the proper edge trigger */
if ((DST_ONESHOT__TYPE & DISC_ONESHOT_REDGE) ? trigger : !trigger) if ((DST_ONESHOT__TYPE & DISC_ONESHOT_REDGE) ? trigger : !trigger)
@ -1301,13 +1327,13 @@ static void dst_oneshot_step(node_description *node)
{ {
/* Retrigger */ /* Retrigger */
context->countdown = DST_ONESHOT__WIDTH; context->countdown = DST_ONESHOT__WIDTH;
doCount = 0; do_count = 0;
} }
} }
} }
} }
if (doCount) if (do_count)
{ {
context->countdown -= discrete_current_context->sample_time; context->countdown -= discrete_current_context->sample_time;
if(context->countdown <= 0.0) if(context->countdown <= 0.0)
@ -1324,10 +1350,11 @@ static void dst_oneshot_step(node_description *node)
static void dst_oneshot_reset(node_description *node) static void dst_oneshot_reset(node_description *node)
{ {
struct dst_oneshot_context *context = node->context; struct dst_oneshot_context *context = node->context;
context->countdown = 0; context->countdown = 0;
context->state = 0; context->state = 0;
context->lastTrig = 0; context->last_trig = 0;
node->output[0] = (DST_ONESHOT__TYPE & DISC_OUT_ACTIVE_LOW) ? DST_ONESHOT__AMP : 0; node->output[0] = (DST_ONESHOT__TYPE & DISC_OUT_ACTIVE_LOW) ? DST_ONESHOT__AMP : 0;
} }
@ -1373,7 +1400,7 @@ static void dst_ramp_step(node_description *node)
else else
{ {
context->last_en = 0; context->last_en = 0;
// Disabled so clamp to output /* Disabled so clamp to output */
node->output[0] = DST_RAMP__CLAMP; node->output[0] = DST_RAMP__CLAMP;
} }
} }
@ -1414,11 +1441,11 @@ static void dst_samphold_step(node_description *node)
{ {
case DISC_SAMPHOLD_REDGE: case DISC_SAMPHOLD_REDGE:
/* Clock the whole time the input is rising */ /* Clock the whole time the input is rising */
if(DST_SAMPHOLD__CLOCK > context->lastinput) node->output[0]=DST_SAMPHOLD__IN0; if (DST_SAMPHOLD__CLOCK > context->last_input) node->output[0] = DST_SAMPHOLD__IN0;
break; break;
case DISC_SAMPHOLD_FEDGE: case DISC_SAMPHOLD_FEDGE:
/* Clock the whole time the input is falling */ /* Clock the whole time the input is falling */
if(DST_SAMPHOLD__CLOCK < context->lastinput) node->output[0]=DST_SAMPHOLD__IN0; if(DST_SAMPHOLD__CLOCK < context->last_input) node->output[0] = DST_SAMPHOLD__IN0;
break; break;
case DISC_SAMPHOLD_HLATCH: case DISC_SAMPHOLD_HLATCH:
/* Output follows input if clock != 0 */ /* Output follows input if clock != 0 */
@ -1438,7 +1465,7 @@ static void dst_samphold_step(node_description *node)
node->output[0] = 0; node->output[0] = 0;
} }
/* Save the last value */ /* Save the last value */
context->lastinput=DST_SAMPHOLD__CLOCK; context->last_input = DST_SAMPHOLD__CLOCK;
} }
static void dst_samphold_reset(node_description *node) static void dst_samphold_reset(node_description *node)
@ -1446,7 +1473,7 @@ static void dst_samphold_reset(node_description *node)
struct dst_samphold_context *context = node->context; struct dst_samphold_context *context = node->context;
node->output[0] = 0; node->output[0] = 0;
context->lastinput=-1; context->last_input = -1;
/* Only stored in here to speed up and save casting in the step function */ /* Only stored in here to speed up and save casting in the step function */
context->clocktype = (int)DST_SAMPHOLD__TYPE; context->clocktype = (int)DST_SAMPHOLD__TYPE;
dst_samphold_step(node); dst_samphold_step(node);
@ -1600,33 +1627,33 @@ static void dst_transform_step(node_description *node)
case 'P': case 'P':
dst_transform_push(trans_stack, &trans_stack_ptr, top); dst_transform_push(trans_stack, &trans_stack_ptr, top);
break; break;
case 'i': // * -1 case 'i': /* * -1 */
top = -top; top = -top;
break; break;
case '!': // Logical NOT of Last Value case '!': /* Logical NOT of Last Value */
top = !top; top = !top;
break; break;
case '=': // Logical = case '=': /* Logical = */
number1 = dst_transform_pop(trans_stack, &trans_stack_ptr); number1 = dst_transform_pop(trans_stack, &trans_stack_ptr);
top = (int)number1 == (int)top; top = (int)number1 == (int)top;
break; break;
case '>': // Logical > case '>': /* Logical > */
number1 = dst_transform_pop(trans_stack, &trans_stack_ptr); number1 = dst_transform_pop(trans_stack, &trans_stack_ptr);
top = number1 > top; top = number1 > top;
break; break;
case '<': // Logical < case '<': /* Logical < */
number1 = dst_transform_pop(trans_stack, &trans_stack_ptr); number1 = dst_transform_pop(trans_stack, &trans_stack_ptr);
top = number1 < top; top = number1 < top;
break; break;
case '&': // Bitwise AND case '&': /* Bitwise AND */
number1 = dst_transform_pop(trans_stack, &trans_stack_ptr); number1 = dst_transform_pop(trans_stack, &trans_stack_ptr);
top = (int)number1 & (int)top; top = (int)number1 & (int)top;
break; break;
case '|': // Bitwise OR case '|': /* Bitwise OR */
number1 = dst_transform_pop(trans_stack, &trans_stack_ptr); number1 = dst_transform_pop(trans_stack, &trans_stack_ptr);
top = (int)number1 | (int)top; top = (int)number1 | (int)top;
break; break;
case '^': // Bitwise XOR case '^': /* Bitwise XOR */
number1 = dst_transform_pop(trans_stack, &trans_stack_ptr); number1 = dst_transform_pop(trans_stack, &trans_stack_ptr);
top = (int)number1 ^ (int)top; top = (int)number1 ^ (int)top;
break; break;
@ -1666,8 +1693,8 @@ static void dst_op_amp_step(node_description *node)
const discrete_op_amp_info *info = node->custom; const discrete_op_amp_info *info = node->custom;
struct dst_op_amp_context *context = node->context; struct dst_op_amp_context *context = node->context;
double iPos = 0; double i_pos = 0;
double iNeg = 0; double i_neg = 0;
double i = 0; double i = 0;
if (DST_OP_AMP__ENABLE) if (DST_OP_AMP__ENABLE)
@ -1678,17 +1705,17 @@ static void dst_op_amp_step(node_description *node)
/* work out neg pin current */ /* work out neg pin current */
if (context->has_r1) if (context->has_r1)
{ {
iNeg = (DST_OP_AMP__INP0 - OP_AMP_NORTON_VBE) / info->r1; i_neg = (DST_OP_AMP__INP0 - OP_AMP_NORTON_VBE) / info->r1;
if (iNeg < 0) iNeg = 0; if (i_neg < 0) i_neg = 0;
} }
iNeg += context->iFixed; i_neg += context->i_fixed;
/* work out neg pin current */ /* work out neg pin current */
iPos = (DST_OP_AMP__INP1 - OP_AMP_NORTON_VBE) / info->r2; i_pos = (DST_OP_AMP__INP1 - OP_AMP_NORTON_VBE) / info->r2;
if (iPos < 0) iPos = 0; if (i_pos < 0) i_pos = 0;
/* work out current across r4 */ /* work out current across r4 */
i = iPos - iNeg; i = i_pos - i_neg;
if (context->has_cap) if (context->has_cap)
{ {
@ -1697,20 +1724,20 @@ static void dst_op_amp_step(node_description *node)
/* voltage across r4 charging cap */ /* voltage across r4 charging cap */
i *= info->r4; i *= info->r4;
/* exponential charge */ /* exponential charge */
context->vCap += (i - context->vCap) * context->exponent; context->v_cap += (i - context->v_cap) * context->exponent;
} }
else else
/* linear charge */ /* linear charge */
context->vCap += i / context->exponent; context->v_cap += i / context->exponent;
node->output[0] = context->vCap; node->output[0] = context->v_cap;
} }
else else
node->output[0] = i * info->r4; node->output[0] = i * info->r4;
/* clamp output */ /* clamp output */
if (node->output[0] > context->vMax) node->output[0] = context->vMax; if (node->output[0] > context->v_max) node->output[0] = context->v_max;
else if (node->output[0] < info->vN) node->output[0] = info->vN; else if (node->output[0] < info->vN) node->output[0] = info->vN;
context->vCap = node->output[0]; context->v_cap = node->output[0];
break; break;
default: default:
@ -1729,9 +1756,9 @@ static void dst_op_amp_reset(node_description *node)
context->has_r1 = info->r1 > 0; context->has_r1 = info->r1 > 0;
context->has_r4 = info->r4 > 0; context->has_r4 = info->r4 > 0;
context->vMax = info->vP - OP_AMP_NORTON_VBE; context->v_max = info->vP - OP_AMP_NORTON_VBE;
context->vCap = 0; context->v_cap = 0;
if (info->c > 0) if (info->c > 0)
{ {
context->has_cap = 1; context->has_cap = 1;
@ -1748,7 +1775,7 @@ static void dst_op_amp_reset(node_description *node)
} }
if (info->r3 >= 0) if (info->r3 >= 0)
context->iFixed = (info->vP - OP_AMP_NORTON_VBE) / info->r3; context->i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r3;
} }
@ -1769,39 +1796,39 @@ static void dst_op_amp_1sht_step(node_description *node)
const discrete_op_amp_1sht_info *info = node->custom; const discrete_op_amp_1sht_info *info = node->custom;
struct dst_op_amp_1sht_context *context = node->context; struct dst_op_amp_1sht_context *context = node->context;
double iPos; double i_pos;
double iNeg; double i_neg;
double v; double v;
/* update trigger circuit */ /* update trigger circuit */
iPos = (DST_OP_AMP_1SHT__TRIGGER - context->vCap2) / info->r2; i_pos = (DST_OP_AMP_1SHT__TRIGGER - context->v_cap2) / info->r2;
iPos += node->output[0] / info->r5; i_pos += node->output[0] / info->r5;
context->vCap2 += (DST_OP_AMP_1SHT__TRIGGER - context->vCap2) * context->exponent2; context->v_cap2 += (DST_OP_AMP_1SHT__TRIGGER - context->v_cap2) * context->exponent2;
/* calculate currents and output */ /* calculate currents and output */
iNeg = (context->vCap1 - OP_AMP_NORTON_VBE) / info->r3; i_neg = (context->v_cap1 - OP_AMP_NORTON_VBE) / info->r3;
if (iNeg < 0) iNeg = 0; if (i_neg < 0) i_neg = 0;
iNeg += context->iFixed; i_neg += context->i_fixed;
if (iPos > iNeg) node->output[0] = context->vMax; if (i_pos > i_neg) node->output[0] = context->v_max;
else node->output[0] = info->vN; else node->output[0] = info->vN;
/* update c1 */ /* update c1 */
/* rough value of voltage at anode of diode if discharging */ /* rough value of voltage at anode of diode if discharging */
v = node->output[0] + 0.6; v = node->output[0] + 0.6;
if (context->vCap1 > node->output[0]) if (context->v_cap1 > node->output[0])
{ {
/* discharge */ /* discharge */
if (context->vCap1 > v) if (context->v_cap1 > v)
/* immediate discharge through diode */ /* immediate discharge through diode */
context->vCap1 = v; context->v_cap1 = v;
else else
/* discharge through r4 */ /* discharge through r4 */
context->vCap1 += (node->output[0] - context->vCap1) * context->exponent1d; context->v_cap1 += (node->output[0] - context->v_cap1) * context->exponent1d;
} }
else else
/* charge */ /* charge */
context->vCap1 += ((node->output[0] - OP_AMP_NORTON_VBE) * context->r34ratio + OP_AMP_NORTON_VBE - context->vCap1) * context->exponent1c; context->v_cap1 += ((node->output[0] - OP_AMP_NORTON_VBE) * context->r34ratio + OP_AMP_NORTON_VBE - context->v_cap1) * context->exponent1c;
} }
static void dst_op_amp_1sht_reset(node_description *node) static void dst_op_amp_1sht_reset(node_description *node)
@ -1815,9 +1842,9 @@ static void dst_op_amp_1sht_reset(node_description *node)
context->exponent1d = 1.0 - exp(context->exponent1d); context->exponent1d = 1.0 - exp(context->exponent1d);
context->exponent2 = -1.0 / (info->r2 * info->c2 * discrete_current_context->sample_rate); context->exponent2 = -1.0 / (info->r2 * info->c2 * discrete_current_context->sample_rate);
context->exponent2 = 1.0 - exp(context->exponent2); context->exponent2 = 1.0 - exp(context->exponent2);
context->iFixed = (info->vP - OP_AMP_NORTON_VBE) / info->r1; context->i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r1;
context->vCap1 = context->vCap2 = 0; context->v_cap1 = context->v_cap2 = 0;
context->vMax = info->vP - OP_AMP_NORTON_VBE; context->v_max = info->vP - OP_AMP_NORTON_VBE;
context->r34ratio = info->r3 / (info->r3 + info->r4); context->r34ratio = info->r3 / (info->r3 + info->r4);
} }
@ -1848,11 +1875,11 @@ static void dst_tvca_op_amp_step(node_description *node)
struct dst_tvca_op_amp_context *context = node->context; struct dst_tvca_op_amp_context *context = node->context;
int trig0, trig1, trig2, f3; int trig0, trig1, trig2, f3;
double i2 = 0; // current through r2 double i2 = 0; /* current through r2 */
double i3 = 0; // current through r3 double i3 = 0; /* current through r3 */
double iNeg = 0; // current into - input double i_neg = 0; /* current into - input */
double iPos = 0; // current into + input double i_pos = 0; /* current into + input */
double iOut = 0; // current at output double i_out = 0; /* current at output */
trig0 = (int)DST_TVCA_OP_AMP__TRG0; trig0 = (int)DST_TVCA_OP_AMP__TRG0;
trig1 = (int)DST_TVCA_OP_AMP__TRG1; trig1 = (int)DST_TVCA_OP_AMP__TRG1;
@ -1875,13 +1902,13 @@ static void dst_tvca_op_amp_step(node_description *node)
} }
/* Calculate current going in to - input. */ /* Calculate current going in to - input. */
iNeg = context->iFixed + i2 + i3; i_neg = context->i_fixed + i2 + i3;
/* Update the c1 cap voltage. */ /* Update the c1 cap voltage. */
if (dst_trigger_function(trig0, trig1, trig2, info->f2)) if (dst_trigger_function(trig0, trig1, trig2, info->f2))
{ {
/* F2 is not grounding the circuit so we charge the cap. */ /* F2 is not grounding the circuit so we charge the cap. */
context->vCap1 += (context->vTrig[f3] - context->vCap1) * context->exponentC[f3]; context->v_cap1 += (context->v_trig[f3] - context->v_cap1) * context->exponent_c[f3];
} }
else else
{ {
@ -1889,37 +1916,37 @@ static void dst_tvca_op_amp_step(node_description *node)
* So now the discharge rate is dependent upon F3. * So now the discharge rate is dependent upon F3.
* If F3 is at ground then we discharge to 0V through r6. * If F3 is at ground then we discharge to 0V through r6.
* If F3 is out of circuit then we discharge to OP_AMP_NORTON_VBE through r6+r7. */ * If F3 is out of circuit then we discharge to OP_AMP_NORTON_VBE through r6+r7. */
context->vCap1 += ((f3 ? OP_AMP_NORTON_VBE : 0.0) - context->vCap1) * context->exponentD[f3]; context->v_cap1 += ((f3 ? OP_AMP_NORTON_VBE : 0.0) - context->v_cap1) * context->exponent_d[f3];
} }
/* Calculate c1 current going in to + input. */ /* Calculate c1 current going in to + input. */
iPos = (context->vCap1 - OP_AMP_NORTON_VBE) / context->r67; i_pos = (context->v_cap1 - OP_AMP_NORTON_VBE) / context->r67;
if ((iPos < 0) || !f3) iPos = 0; if ((i_pos < 0) || !f3) i_pos = 0;
/* Update the c2 cap voltage and current. */ /* Update the c2 cap voltage and current. */
if (info->r9 != 0) if (info->r9 != 0)
{ {
f3 = dst_trigger_function(trig0, trig1, trig2, info->f4); f3 = dst_trigger_function(trig0, trig1, trig2, info->f4);
context->vCap2 += ((f3 ? context->vTrig2 : 0) - context->vCap2) * context->exponent2[f3]; context->v_cap2 += ((f3 ? context->v_trig2 : 0) - context->v_cap2) * context->exponent2[f3];
iPos += context->vCap2 / info->r9; i_pos += context->v_cap2 / info->r9;
} }
/* Update the c3 cap voltage and current. */ /* Update the c3 cap voltage and current. */
if (info->r11 != 0) if (info->r11 != 0)
{ {
f3 = dst_trigger_function(trig0, trig1, trig2, info->f5); f3 = dst_trigger_function(trig0, trig1, trig2, info->f5);
context->vCap3 += ((f3 ? context->vTrig3 : 0) - context->vCap3) * context->exponent3[f3]; context->v_cap3 += ((f3 ? context->v_trig3 : 0) - context->v_cap3) * context->exponent3[f3];
iPos += context->vCap3 / info->r11; i_pos += context->v_cap3 / info->r11;
} }
/* Calculate output current. */ /* Calculate output current. */
iOut = iPos - iNeg; i_out = i_pos - i_neg;
if (iOut < 0) iOut = 0; if (i_out < 0) i_out = 0;
/* Convert to voltage for final output. */ /* Convert to voltage for final output. */
node->output[0] = iOut * info->r4; node->output[0] = i_out * info->r4;
/* Clip the output if needed. */ /* Clip the output if needed. */
if (node->output[0] > context->vOutMax) node->output[0] = context->vOutMax; if (node->output[0] > context->v_out_max) node->output[0] = context->v_out_max;
} }
static void dst_tvca_op_amp_reset(node_description *node) static void dst_tvca_op_amp_reset(node_description *node)
@ -1929,37 +1956,37 @@ static void dst_tvca_op_amp_reset(node_description *node)
context->r67 = info->r6 + info->r7; context->r67 = info->r6 + info->r7;
context->vOutMax = info->vP - OP_AMP_NORTON_VBE; context->v_out_max = info->vP - OP_AMP_NORTON_VBE;
/* This is probably overkill because R5 is usually much lower then r6 or r7, /* This is probably overkill because R5 is usually much lower then r6 or r7,
* but it is better to play it safe. */ * but it is better to play it safe. */
context->vTrig[0] = (info->v1 - 0.6) * (info->r6 / (info->r6 + info->r5)); context->v_trig[0] = (info->v1 - 0.6) * (info->r6 / (info->r6 + info->r5));
context->vTrig[1] = (info->v1 - 0.6 - OP_AMP_NORTON_VBE) * (context->r67 / (context->r67 + info->r5)) + OP_AMP_NORTON_VBE; context->v_trig[1] = (info->v1 - 0.6 - OP_AMP_NORTON_VBE) * (context->r67 / (context->r67 + info->r5)) + OP_AMP_NORTON_VBE;
context->iFixed = context->vOutMax / info->r1; context->i_fixed = context->v_out_max / info->r1;
context->vCap1 = 0; context->v_cap1 = 0;
/* Charge rate thru r5 */ /* Charge rate thru r5 */
/* There can be a different charge rates depending on function F3. */ /* There can be a different charge rates depending on function F3. */
context->exponentC[0] = -1.0 / ((1.0 / (1.0 / info->r5 + 1.0 / info->r6)) * info->c1 * discrete_current_context->sample_rate); context->exponent_c[0] = -1.0 / ((1.0 / (1.0 / info->r5 + 1.0 / info->r6)) * info->c1 * discrete_current_context->sample_rate);
context->exponentC[0] = 1.0 - exp(context->exponentC[0]); context->exponent_c[0] = 1.0 - exp(context->exponent_c[0]);
context->exponentC[1] = -1.0 / ((1.0 / (1.0 / info->r5 + 1.0 / context->r67)) * info->c1 * discrete_current_context->sample_rate); context->exponent_c[1] = -1.0 / ((1.0 / (1.0 / info->r5 + 1.0 / context->r67)) * info->c1 * discrete_current_context->sample_rate);
context->exponentC[1] = 1.0 - exp(context->exponentC[1]); context->exponent_c[1] = 1.0 - exp(context->exponent_c[1]);
/* Discharge rate thru r6 + r7 */ /* Discharge rate thru r6 + r7 */
context->exponentD[1] = -1.0 / (context->r67 * info->c1 * discrete_current_context->sample_rate); context->exponent_d[1] = -1.0 / (context->r67 * info->c1 * discrete_current_context->sample_rate);
context->exponentD[1] = 1.0 - exp(context->exponentD[1]); context->exponent_d[1] = 1.0 - exp(context->exponent_d[1]);
/* Discharge rate thru r6 */ /* Discharge rate thru r6 */
if (info->r6 != 0) if (info->r6 != 0)
{ {
context->exponentD[0] = -1.0 / (info->r6 * info->c1 * discrete_current_context->sample_rate); context->exponent_d[0] = -1.0 / (info->r6 * info->c1 * discrete_current_context->sample_rate);
context->exponentD[0] = 1.0 - exp(context->exponentD[0]); context->exponent_d[0] = 1.0 - exp(context->exponent_d[0]);
} }
context->vCap2 = 0; context->v_cap2 = 0;
context->vTrig2 = (info->v2 - 0.6 - OP_AMP_NORTON_VBE) * (info->r9 / (info->r8 + info->r9)); context->v_trig2 = (info->v2 - 0.6 - OP_AMP_NORTON_VBE) * (info->r9 / (info->r8 + info->r9));
context->exponent2[0] = -1.0 / (info->r9 * info->c2 * discrete_current_context->sample_rate); context->exponent2[0] = -1.0 / (info->r9 * info->c2 * discrete_current_context->sample_rate);
context->exponent2[0] = 1.0 - exp(context->exponent2[0]); context->exponent2[0] = 1.0 - exp(context->exponent2[0]);
context->exponent2[1] = -1.0 / ((1.0 / (1.0 / info->r8 + 1.0 / info->r9)) * info->c2 * discrete_current_context->sample_rate); context->exponent2[1] = -1.0 / ((1.0 / (1.0 / info->r8 + 1.0 / info->r9)) * info->c2 * discrete_current_context->sample_rate);
context->exponent2[1] = 1.0 - exp(context->exponent2[1]); context->exponent2[1] = 1.0 - exp(context->exponent2[1]);
context->vCap3 = 0; context->v_cap3 = 0;
context->vTrig3 = (info->v3 - 0.6 - OP_AMP_NORTON_VBE) * (info->r11 / (info->r10 + info->r11)); context->v_trig3 = (info->v3 - 0.6 - OP_AMP_NORTON_VBE) * (info->r11 / (info->r10 + info->r11));
context->exponent3[0] = -1.0 / (info->r11 * info->c3 * discrete_current_context->sample_rate); context->exponent3[0] = -1.0 / (info->r11 * info->c3 * discrete_current_context->sample_rate);
context->exponent3[0] = 1.0 - exp(context->exponent3[0]); context->exponent3[0] = 1.0 - exp(context->exponent3[0]);
context->exponent3[1] = -1.0 / ((1.0 / (1.0 / info->r10 + 1.0 / info->r11)) * info->c3 * discrete_current_context->sample_rate); context->exponent3[1] = -1.0 / ((1.0 / (1.0 / info->r10 + 1.0 / info->r11)) * info->c3 * discrete_current_context->sample_rate);

View File

@ -18,7 +18,7 @@
* DSS_SINEWAVE - Sinewave generator source code * DSS_SINEWAVE - Sinewave generator source code
* DSS_SQUAREWAVE - Squarewave generator source code * DSS_SQUAREWAVE - Squarewave generator source code
* DSS_SQUAREWFIX - Squarewave generator - fixed frequency * DSS_SQUAREWFIX - Squarewave generator - fixed frequency
* DSS_SQUAREWAVE2 - Squarewave generator - by tOn/tOff * DSS_SQUAREWAVE2 - Squarewave generator - by t_on/t_off
* DSS_TRIANGLEWAVE - Triangle waveform generator * DSS_TRIANGLEWAVE - Triangle waveform generator
* *
************************************************************************/ ************************************************************************/
@ -33,20 +33,19 @@ struct dss_counter_context
int clock_type; int clock_type;
int out_type; int out_type;
int is_7492; int is_7492;
int last; // Last clock state int last; /* Last clock state */
int count; // current count int count; /* current count */
double t_clock; // fixed counter clock in seconds double t_clock; /* fixed counter clock in seconds */
double t_left; // time unused during last sample in seconds double t_left; /* time unused during last sample in seconds */
}; };
struct dss_lfsr_context struct dss_lfsr_context
{ {
unsigned int lfsr_reg; unsigned int lfsr_reg;
int last; // Last clock state int last; /* Last clock state */
double t_clock; // fixed counter clock in seconds double t_clock; /* fixed counter clock in seconds */
double t_left; // time unused during last sample in seconds double t_left; /* time unused during last sample in seconds */
double sampleStep; double sample_step;
double shiftStep;
double t; double t;
UINT8 reset_on_high; UINT8 reset_on_high;
UINT8 invert_output; UINT8 invert_output;
@ -62,18 +61,18 @@ struct dss_note_context
{ {
int clock_type; int clock_type;
int out_type; int out_type;
int last; // Last clock state int last; /* Last clock state */
double t_clock; // fixed counter clock in seconds double t_clock; /* fixed counter clock in seconds */
double t_left; // time unused during last sample in seconds double t_left; /* time unused during last sample in seconds */
int max1; // Max 1 Count stored as int for easy use. int max1; /* Max 1 Count stored as int for easy use. */
int max2; // Max 2 Count stored as int for easy use. int max2; /* Max 2 Count stored as int for easy use. */
int count1; // current count1 int count1; /* current count1 */
int count2; // current count2 int count2; /* current count2 */
}; };
struct dss_op_amp_osc_context struct dss_op_amp_osc_context
{ {
const double *r1; // pointers to resistor values const double *r1; /* pointers to resistor values */
const double *r2; const double *r2;
const double *r3; const double *r3;
const double *r4; const double *r4;
@ -82,18 +81,18 @@ struct dss_op_amp_osc_context
const double *r7; const double *r7;
const double *r8; const double *r8;
int type; int type;
UINT8 flip_flop; // flip/flop output state UINT8 flip_flop; /* flip/flop output state */
UINT8 flip_flopXOR; // flip_flop ^ flip_flopXOR, 0 = discharge, 1 = charge UINT8 flip_flop_xor; /* flip_flop ^ flip_flop_xor, 0 = discharge, 1 = charge */
UINT8 is_squarewave; UINT8 is_squarewave;
double high_out_V; double v_out_high;
double thresholdLow; // falling threshold double threshold_low; /* falling threshold */
double thresholdHigh; // rising threshold double threshold_high; /* rising threshold */
double vCap; // current capacitor voltage double v_cap; /* current capacitor voltage */
double rTotal; // all input resistors in parallel double r_total; /* all input resistors in parallel */
double iFixed; // fixed current at the input double i_fixed; /* fixed current at the input */
double temp1; // Multi purpose double temp1; /* Multi purpose */
double temp2; // Multi purpose double temp2; /* Multi purpose */
double temp3; // Multi purpose double temp3; /* Multi purpose */
}; };
struct dss_sawtoothwave_context struct dss_sawtoothwave_context
@ -104,12 +103,12 @@ struct dss_sawtoothwave_context
struct dss_schmitt_osc_context struct dss_schmitt_osc_context
{ {
double ratioIn; // ratio of total charging voltage that comes from the input double ration_in; /* ratio of total charging voltage that comes from the input */
double ratioFeedback; // ratio of total charging voltage that comes from the feedback double ratio_feedback; /* ratio of total charging voltage that comes from the feedback */
double vCap; // current capacitor voltage double v_cap; /* current capacitor voltage */
double rc; // r*c double rc; /* r*c */
double exponent; double exponent;
int state; // state of the output int state; /* state of the output */
int enable_type; int enable_type;
UINT8 input_is_voltage; UINT8 input_is_voltage;
}; };
@ -128,10 +127,10 @@ struct dss_squarewave_context
struct dss_squarewfix_context struct dss_squarewfix_context
{ {
int flip_flop; int flip_flop;
double sampleStep; double sample_step;
double tLeft; double t_left;
double tOff; double t_off;
double tOn; double t_on;
}; };
struct dss_trianglewave_context struct dss_trianglewave_context
@ -145,17 +144,18 @@ struct dss_inverter_osc_context
{ {
double w; double w;
double wc; double wc;
double vCap; double v_cap;
double vG2_old; double v_g2_old;
double Rp; double rp;
double R1; double r1;
double R2; double r2;
double C; double c;
double tf_a; double tf_a;
double tf_b; double tf_b;
double tf_tab[DSS_INV_TAB_SIZE]; double tf_tab[DSS_INV_TAB_SIZE];
}; };
/************************************************************************ /************************************************************************
* *
* DSS_COUNTER - External clock Binary Counter * DSS_COUNTER - External clock Binary Counter
@ -177,6 +177,7 @@ struct dss_inverter_osc_context
#define DSS_COUNTER__DIR (*(node->input[4])) #define DSS_COUNTER__DIR (*(node->input[4]))
#define DSS_COUNTER__INIT (*(node->input[5])) #define DSS_COUNTER__INIT (*(node->input[5]))
#define DSS_COUNTER__CLOCK_TYPE (*(node->input[6])) #define DSS_COUNTER__CLOCK_TYPE (*(node->input[6]))
#define DSS_7492__CLOCK_TYPE DSS_COUNTER__MAX
static const int disc_7492_count[6] = {0x00, 0x01, 0x02, 0x04, 0x05, 0x06}; static const int disc_7492_count[6] = {0x00, 0x01, 0x02, 0x04, 0x05, 0x06};
@ -185,8 +186,13 @@ static void dss_counter_step(node_description *node)
struct dss_counter_context *context = node->context; struct dss_counter_context *context = node->context;
double cycles; double cycles;
int clock = 0, last_count, inc = 0; int clock = 0, last_count, inc = 0;
int max = DSS_COUNTER__MAX; int max;
double xTime = 0; double x_time = 0;
if (context->is_7492)
max = 5;
else
max = DSS_COUNTER__MAX;
if (context->clock_type == DISC_CLK_IS_FREQ) if (context->clock_type == DISC_CLK_IS_FREQ)
{ {
@ -194,20 +200,20 @@ static void dss_counter_step(node_description *node)
cycles = (context->t_left + discrete_current_context->sample_time) / context->t_clock; cycles = (context->t_left + discrete_current_context->sample_time) / context->t_clock;
inc = (int)cycles; inc = (int)cycles;
context->t_left = (cycles - inc) * context->t_clock; context->t_left = (cycles - inc) * context->t_clock;
if (inc) xTime = context->t_left / discrete_current_context->sample_time; if (inc) x_time = context->t_left / discrete_current_context->sample_time;
} }
else else
{ {
clock = (int)DSS_COUNTER__CLOCK; clock = (int)DSS_COUNTER__CLOCK;
xTime = DSS_COUNTER__CLOCK - clock; x_time = DSS_COUNTER__CLOCK - clock;
} }
/* If reset enabled then set output to the reset value. No xTime in reset. */ /* If reset enabled then set output to the reset value. No x_time in reset. */
if (DSS_COUNTER__RESET) if (DSS_COUNTER__RESET)
{ {
context->count = DSS_COUNTER__INIT; context->count = DSS_COUNTER__INIT;
node->output[0] = context->is_7492 ? 0 : context->count; node->output[0] = context->count;
return; return;
} }
@ -244,7 +250,7 @@ static void dss_counter_step(node_description *node)
for (clock = 0; clock < inc; clock++) for (clock = 0; clock < inc; clock++)
{ {
context->count += DSS_COUNTER__DIR ? 1 : -1; // up/down context->count += DSS_COUNTER__DIR ? 1 : -1; /* up/down */
if (context->count < 0) context->count = max; if (context->count < 0) context->count = max;
if (context->count > max) context->count = 0; if (context->count > max) context->count = 0;
} }
@ -253,15 +259,19 @@ static void dss_counter_step(node_description *node)
if (context->count != last_count) if (context->count != last_count)
{ {
/* the xTime is only output if the output changed. */ /* the x_time is only output if the output changed. */
switch (context->out_type) switch (context->out_type)
{ {
case DISC_OUT_IS_ENERGY: case DISC_OUT_IS_ENERGY:
if (xTime != 0) if (x_time == 0) x_time = 1.0;
node->output[0] = (context->count > last_count) ? (last_count + xTime) : (last_count - xTime); node->output[0] = last_count;
if (context->count > last_count)
node->output[0] += (context->count - last_count) * x_time;
else
node->output[0] -= (last_count - context->count) * x_time;
break; break;
case DISC_OUT_HAS_XTIME: case DISC_OUT_HAS_XTIME:
node->output[0] += xTime; node->output[0] += x_time;
break; break;
} }
} }
@ -274,19 +284,22 @@ static void dss_counter_reset(node_description *node)
{ {
struct dss_counter_context *context = node->context; struct dss_counter_context *context = node->context;
context->clock_type = (int)DSS_COUNTER__CLOCK_TYPE; if ((int)DSS_COUNTER__CLOCK_TYPE & DISC_COUNTER_IS_7492)
if (context->clock_type == DISC_COUNTER_IS_7492)
{ {
context->clock_type = DISC_CLK_ON_F_EDGE;
context->is_7492 = 1; context->is_7492 = 1;
context->clock_type = (int)DSS_7492__CLOCK_TYPE;
} }
else else
{
context->is_7492 = 0; context->is_7492 = 0;
if ((context->clock_type < DISC_CLK_ON_F_EDGE) || (context->clock_type > DISC_CLK_IS_FREQ)) context->clock_type = (int)DSS_COUNTER__CLOCK_TYPE;
discrete_log("Invalid clock type passed in NODE_%d\n", NODE_INDEX(node->node)); }
context->last = 0; context->out_type = context->clock_type & DISC_OUT_MASK;
if (context->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_COUNTER__CLOCK; context->clock_type &= DISC_CLK_MASK;
context->t_clock = 1.0 / DSS_COUNTER__CLOCK;
context->t_left = 0; context->t_left = 0;
context->last = 0;
context->count = DSS_COUNTER__INIT; /* count starts at reset value */ context->count = DSS_COUNTER__INIT; /* count starts at reset value */
node->output[0] = DSS_COUNTER__INIT; node->output[0] = DSS_COUNTER__INIT;
} }
@ -313,7 +326,7 @@ static void dss_counter_reset(node_description *node)
#define DSS_LFSR_NOISE__FEED (*(node->input[4])) #define DSS_LFSR_NOISE__FEED (*(node->input[4]))
#define DSS_LFSR_NOISE__BIAS (*(node->input[5])) #define DSS_LFSR_NOISE__BIAS (*(node->input[5]))
int dss_lfsr_function(int myfunc,int in0,int in1,int bitmask) static int dss_lfsr_function(int myfunc, int in0, int in1, int bitmask)
{ {
int retval; int retval;
@ -427,37 +440,37 @@ static void dss_lfsr_step(node_description *node)
for (clock = 0; clock < inc; clock++) for (clock = 0; clock < inc; clock++)
{ {
/* Fetch the last feedback result */ /* Fetch the last feedback result */
fbresult=((context->lfsr_reg)>>(lfsr_desc->bitlength))&0x01; fbresult = (context->lfsr_reg >> lfsr_desc->bitlength) & 0x01;
/* Stage 2 feedback combine fbresultNew with infeed bit */ /* Stage 2 feedback combine fbresultNew with infeed bit */
fbresult=dss_lfsr_function(lfsr_desc->feedback_function1,fbresult,((DSS_LFSR_NOISE__FEED)?0x01:0x00),0x01); fbresult = dss_lfsr_function(lfsr_desc->feedback_function1, fbresult, (DSS_LFSR_NOISE__FEED ? 0x01 : 0x00), 0x01);
/* Stage 3 first we setup where the bit is going to be shifted into */ /* Stage 3 first we setup where the bit is going to be shifted into */
fbresult = fbresult * lfsr_desc->feedback_function2_mask; fbresult = fbresult * lfsr_desc->feedback_function2_mask;
/* Then we left shift the register, */ /* Then we left shift the register, */
context->lfsr_reg=(context->lfsr_reg)<<1; context->lfsr_reg = context->lfsr_reg << 1;
/* Now move the fbresult into the shift register and mask it to the bitlength */ /* Now move the fbresult into the shift register and mask it to the bitlength */
context->lfsr_reg=dss_lfsr_function(lfsr_desc->feedback_function2,fbresult, (context->lfsr_reg), ((1<<(lfsr_desc->bitlength))-1)); context->lfsr_reg = dss_lfsr_function(lfsr_desc->feedback_function2, fbresult, context->lfsr_reg, (1 << lfsr_desc->bitlength) - 1 );
/* Now get and store the new feedback result */ /* Now get and store the new feedback result */
/* Fetch the feedback bits */ /* Fetch the feedback bits */
fb0=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel0))&0x01; fb0 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel0) & 0x01;
fb1=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel1))&0x01; fb1 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel1) & 0x01;
/* Now do the combo on them */ /* Now do the combo on them */
fbresult = dss_lfsr_function(lfsr_desc->feedback_function0, fb0, fb1, 0x01); fbresult = dss_lfsr_function(lfsr_desc->feedback_function0, fb0, fb1, 0x01);
context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,(context->lfsr_reg), fbresult<<(lfsr_desc->bitlength), ((2<<(lfsr_desc->bitlength))-1)); context->lfsr_reg = dss_lfsr_function(DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2 << lfsr_desc->bitlength) - 1);
/* Now select the output bit */ /* Now select the output bit */
if (context->out_is_f0) if (context->out_is_f0)
node->output[0] = fbresult & 0x01; node->output[0] = fbresult & 0x01;
else else
node->output[0]=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01; node->output[0] = (context->lfsr_reg >> lfsr_desc->output_bit) & 0x01;
/* Final inversion if required */ /* Final inversion if required */
if(context->invert_output) node->output[0]=(node->output[0])?0.0:1.0; if (context->invert_output) node->output[0] = node->output[0] ? 0 : 1;
/* Gain stage */ /* Gain stage */
node->output[0]=(node->output[0])?(DSS_LFSR_NOISE__AMP)/2:-(DSS_LFSR_NOISE__AMP)/2; node->output[0] = node->output[0] ? DSS_LFSR_NOISE__AMP / 2 : -DSS_LFSR_NOISE__AMP / 2;
/* Bias input as required */ /* Bias input as required */
node->output[0] = node->output[0] + DSS_LFSR_NOISE__BIAS; node->output[0] = node->output[0] + DSS_LFSR_NOISE__BIAS;
} }
@ -488,20 +501,20 @@ static void dss_lfsr_reset(node_description *node)
/* Now get and store the new feedback result */ /* Now get and store the new feedback result */
/* Fetch the feedback bits */ /* Fetch the feedback bits */
fb0=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel0))&0x01; fb0 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel0) & 0x01;
fb1=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel1))&0x01; fb1=(context->lfsr_reg >> lfsr_desc->feedback_bitsel1) & 0x01;
/* Now do the combo on them */ /* Now do the combo on them */
fbresult = dss_lfsr_function(lfsr_desc->feedback_function0, fb0, fb1, 0x01); fbresult = dss_lfsr_function(lfsr_desc->feedback_function0, fb0, fb1, 0x01);
context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,(context->lfsr_reg), fbresult<<(lfsr_desc->bitlength), ((2<<(lfsr_desc->bitlength))-1)); context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2<< lfsr_desc->bitlength ) - 1);
/* Now select and setup the output bit */ /* Now select and setup the output bit */
node->output[0]=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01; node->output[0] = (context->lfsr_reg >> lfsr_desc->output_bit) & 0x01;
/* Final inversion if required */ /* Final inversion if required */
if(lfsr_desc->flags&DISC_LFSR_FLAG_OUT_INVERT) node->output[0]=(node->output[0])?0.0:1.0; if(lfsr_desc->flags & DISC_LFSR_FLAG_OUT_INVERT) node->output[0] = node->output[0] ? 0 : 1;
/* Gain stage */ /* Gain stage */
node->output[0]=(node->output[0])?(DSS_LFSR_NOISE__AMP)/2:-(DSS_LFSR_NOISE__AMP)/2; node->output[0] = node->output[0] ? DSS_LFSR_NOISE__AMP / 2 : -DSS_LFSR_NOISE__AMP / 2;
/* Bias input as required */ /* Bias input as required */
node->output[0] = node->output[0] + DSS_LFSR_NOISE__BIAS; node->output[0] = node->output[0] + DSS_LFSR_NOISE__BIAS;
} }
@ -594,7 +607,7 @@ static void dss_note_step(node_description *node)
double cycles; double cycles;
int clock = 0, last_count2, inc = 0; int clock = 0, last_count2, inc = 0;
double xTime = 0; double x_time = 0;
if (context->clock_type == DISC_CLK_IS_FREQ) if (context->clock_type == DISC_CLK_IS_FREQ)
{ {
@ -602,13 +615,13 @@ static void dss_note_step(node_description *node)
cycles = (context->t_left + discrete_current_context->sample_time) / context->t_clock; cycles = (context->t_left + discrete_current_context->sample_time) / context->t_clock;
inc = (int)cycles; inc = (int)cycles;
context->t_left = (cycles - inc) * context->t_clock; context->t_left = (cycles - inc) * context->t_clock;
if (inc) xTime = context->t_left / discrete_current_context->sample_time; if (inc) x_time = context->t_left / discrete_current_context->sample_time;
} }
else else
{ {
/* Seperate clock info from xTime info. */ /* Seperate clock info from x_time info. */
clock = (int)DSS_NOTE__CLOCK; clock = (int)DSS_NOTE__CLOCK;
xTime = DSS_NOTE__CLOCK - clock; x_time = DSS_NOTE__CLOCK - clock;
} }
if (DSS_NOTE__ENABLE) if (DSS_NOTE__ENABLE)
@ -657,15 +670,19 @@ static void dss_note_step(node_description *node)
node->output[0] = context->count2; node->output[0] = context->count2;
if (context->count2 != last_count2) if (context->count2 != last_count2)
{ {
/* the xTime is only output if the output changed. */ /* the x_time is only output if the output changed. */
switch (context->out_type) switch (context->out_type)
{ {
case DISC_OUT_IS_ENERGY: case DISC_OUT_IS_ENERGY:
if (xTime != 0) if (x_time == 0) x_time = 1.0;
node->output[0] = (context->count2 > last_count2) ? (last_count2 + xTime) : (last_count2 - xTime); node->output[0] = last_count2;
if (context->count2 > last_count2)
node->output[0] += (context->count2 - last_count2) * x_time;
else
node->output[0] -= (last_count2 - context->count2) * x_time;
break; break;
case DISC_OUT_HAS_XTIME: case DISC_OUT_HAS_XTIME:
node->output[0] += xTime; node->output[0] += x_time;
break; break;
} }
} }
@ -680,9 +697,10 @@ static void dss_note_reset(node_description *node)
context->clock_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_CLK_MASK; context->clock_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_CLK_MASK;
context->out_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_OUT_MASK; context->out_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_OUT_MASK;
context->last = (DSS_NOTE__CLOCK != 0); context->last = (DSS_NOTE__CLOCK != 0);
if (context->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_NOTE__CLOCK;
context->t_left = 0; context->t_left = 0;
context->t_clock = 1.0 / DSS_NOTE__CLOCK;
context->count1 = (int)DSS_NOTE__DATA; context->count1 = (int)DSS_NOTE__DATA;
context->count2 = 0; context->count2 = 0;
@ -710,7 +728,7 @@ static void dss_note_reset(node_description *node)
/* The inputs on a norton op-amp are (info->vP - OP_AMP_NORTON_VBE) */ /* The inputs on a norton op-amp are (info->vP - OP_AMP_NORTON_VBE) */
/* which is the same as the output high voltage. We will define them */ /* which is the same as the output high voltage. We will define them */
/* the same to save a calculation step */ /* the same to save a calculation step */
#define DSS_OP_AMP_OSC_NORTON_VP_IN context->high_out_V #define DSS_OP_AMP_OSC_NORTON_VP_IN context->v_out_high
static void dss_op_amp_osc_step(node_description *node) static void dss_op_amp_osc_step(node_description *node)
{ {
@ -718,24 +736,25 @@ static void dss_op_amp_osc_step(node_description *node)
struct dss_op_amp_osc_context *context = node->context; struct dss_op_amp_osc_context *context = node->context;
double i; // Charging current created by vIn double i; /* Charging current created by vIn */
double v = 0; // all input voltages mixed double v = 0; /* all input voltages mixed */
double dt; // change in time double dt; /* change in time */
double vC; // Current voltage on capacitor, before dt double vC; /* Current voltage on capacitor, before dt */
double vCnext = 0; // Voltage on capacitor, after dt double vCnext = 0; /* Voltage on capacitor, after dt */
double iCharge[2] = {0}; double iCharge[2] = {0};
UINT8 force_charge = 0; UINT8 force_charge = 0;
UINT8 enable = DSS_OP_AMP_OSC__ENABLE; UINT8 enable = DSS_OP_AMP_OSC__ENABLE;
dt = discrete_current_context->sample_time; // Change in time dt = discrete_current_context->sample_time; /* Change in time */
vC = context->vCap; // Set to voltage before change vC = context->v_cap; /* Set to voltage before change */
/* work out the charge currents for the VCOs. */ /* work out the charge currents for the VCOs. */
switch (context->type) switch (context->type)
{ {
case DISC_OP_AMP_OSCILLATOR_VCO_1: case DISC_OP_AMP_OSCILLATOR_VCO_1:
/* Work out the charge rates. */ /* Work out the charge rates. */
i = DSS_OP_AMP_OSC__VMOD1 * context->temp1; // i is not a current. It is being used as a temp variable. /* i is not a current. It is being used as a temp variable. */
i = DSS_OP_AMP_OSC__VMOD1 * context->temp1;
iCharge[0] = (DSS_OP_AMP_OSC__VMOD1 - i) / info->r1; iCharge[0] = (DSS_OP_AMP_OSC__VMOD1 - i) / info->r1;
iCharge[1] = (i - (DSS_OP_AMP_OSC__VMOD1 * context->temp2)) / context->temp3; iCharge[1] = (i - (DSS_OP_AMP_OSC__VMOD1 * context->temp2)) / context->temp3;
break; break;
@ -746,13 +765,13 @@ static void dss_op_amp_osc_step(node_description *node)
double i1, i2; double i1, i2;
/* Work out the charge rates. */ /* Work out the charge rates. */
iCharge[0] = DSS_OP_AMP_OSC_NORTON_VP_IN / *context->r1; iCharge[0] = DSS_OP_AMP_OSC_NORTON_VP_IN / *context->r1;
iCharge[1] = (context->high_out_V - OP_AMP_NORTON_VBE) / *context->r2 - iCharge[0]; iCharge[1] = (context->v_out_high - OP_AMP_NORTON_VBE) / *context->r2 - iCharge[0];
/* Work out the Inverting Schmitt thresholds. */ /* Work out the Inverting Schmitt thresholds. */
i1 = DSS_OP_AMP_OSC_NORTON_VP_IN / *context->r5; i1 = DSS_OP_AMP_OSC_NORTON_VP_IN / *context->r5;
i2 = (0.0 - OP_AMP_NORTON_VBE) / *context->r4; i2 = (0.0 - OP_AMP_NORTON_VBE) / *context->r4;
context->thresholdLow = (i1 + i2) * *context->r3 + OP_AMP_NORTON_VBE; context->threshold_low = (i1 + i2) * *context->r3 + OP_AMP_NORTON_VBE;
i2 = (context->high_out_V - OP_AMP_NORTON_VBE) / *context->r4; i2 = (context->v_out_high - OP_AMP_NORTON_VBE) / *context->r4;
context->thresholdHigh = (i1 + i2) * *context->r3 + OP_AMP_NORTON_VBE; context->threshold_high = (i1 + i2) * *context->r3 + OP_AMP_NORTON_VBE;
break; break;
} }
@ -766,11 +785,11 @@ static void dss_op_amp_osc_step(node_description *node)
else else
{ {
/* we need to mix any bias and all modulation voltages together. */ /* we need to mix any bias and all modulation voltages together. */
i = context->iFixed; i = context->i_fixed;
i += DSS_OP_AMP_OSC__VMOD1 / info->r7; i += DSS_OP_AMP_OSC__VMOD1 / info->r7;
if (info->r8 != 0) if (info->r8 != 0)
i += DSS_OP_AMP_OSC__VMOD2 / info->r8; i += DSS_OP_AMP_OSC__VMOD2 / info->r8;
v = i * context->rTotal; v = i * context->r_total;
} }
/* Work out the charge rates. */ /* Work out the charge rates. */
@ -799,7 +818,7 @@ static void dss_op_amp_osc_step(node_description *node)
case DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON: case DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON:
/* we need to mix any bias and all modulation voltages together. */ /* we need to mix any bias and all modulation voltages together. */
iCharge[0] = context->iFixed; iCharge[0] = context->i_fixed;
v = DSS_OP_AMP_OSC__VMOD1 - OP_AMP_NORTON_VBE; v = DSS_OP_AMP_OSC__VMOD1 - OP_AMP_NORTON_VBE;
iCharge[0] += v / info->r1; iCharge[0] += v / info->r1;
if (info->r6 != 0) if (info->r6 != 0)
@ -817,7 +836,7 @@ static void dss_op_amp_osc_step(node_description *node)
/* Keep looping until all toggling in time sample is used up. */ /* Keep looping until all toggling in time sample is used up. */
do do
{ {
if ((context->flip_flop ^ context->flip_flopXOR) || force_charge) if ((context->flip_flop ^ context->flip_flop_xor) || force_charge)
{ {
/* Charging */ /* Charging */
/* iC=C*dv/dt works out to dv=iC*dt/C */ /* iC=C*dv/dt works out to dv=iC*dt/C */
@ -825,21 +844,21 @@ static void dss_op_amp_osc_step(node_description *node)
dt = 0; dt = 0;
/* has it charged past upper limit? */ /* has it charged past upper limit? */
if (vCnext > context->thresholdHigh) if (vCnext > context->threshold_high)
{ {
context->flip_flop = context->flip_flopXOR; context->flip_flop = context->flip_flop_xor;
toggled++; toggled++;
if (force_charge) if (force_charge)
{ {
/* we need to keep charging the cap to the max thereby disabling the circuit */ /* we need to keep charging the cap to the max thereby disabling the circuit */
if (vCnext > context->high_out_V) if (vCnext > context->v_out_high)
vCnext = context->high_out_V; vCnext = context->v_out_high;
} }
else else
{ {
/* calculate the overshoot time */ /* calculate the overshoot time */
dt = info->c * (vCnext - context->thresholdHigh) / iCharge[1]; dt = info->c * (vCnext - context->threshold_high) / iCharge[1];
vC = context->thresholdHigh; vC = context->threshold_high;
} }
} }
} }
@ -850,18 +869,18 @@ static void dss_op_amp_osc_step(node_description *node)
dt = 0; dt = 0;
/* has it discharged past lower limit? */ /* has it discharged past lower limit? */
if (vCnext < context->thresholdLow) if (vCnext < context->threshold_low)
{ {
context->flip_flop = !context->flip_flopXOR; context->flip_flop = !context->flip_flop_xor;
toggled++; toggled++;
/* calculate the overshoot time */ /* calculate the overshoot time */
dt = info->c * (context->thresholdLow - vCnext) / iCharge[0]; dt = info->c * (context->threshold_low - vCnext) / iCharge[0];
vC = context->thresholdLow; vC = context->threshold_low;
} }
} }
} while(dt); } while(dt);
context->vCap = vCnext; context->v_cap = vCnext;
if (context->is_squarewave) if (context->is_squarewave)
{ {
@ -870,12 +889,12 @@ static void dss_op_amp_osc_step(node_description *node)
/* squarewave to happen in the sample time causing it to be missed. */ /* squarewave to happen in the sample time causing it to be missed. */
/* If we toggle 2 states we force the missed output for 1 sample. */ /* If we toggle 2 states we force the missed output for 1 sample. */
/* If more then 2 states happen, there is no hope, the sample rate is just too low. */ /* If more then 2 states happen, there is no hope, the sample rate is just too low. */
node->output[0] = context->high_out_V * (context->flip_flop ? 0 : 1); node->output[0] = context->v_out_high * (context->flip_flop ? 0 : 1);
else else
node->output[0] = context->high_out_V * context->flip_flop; node->output[0] = context->v_out_high * context->flip_flop;
} }
else else
node->output[0] = context->vCap; node->output[0] = context->v_cap;
} }
else else
{ {
@ -893,8 +912,8 @@ static void dss_op_amp_osc_reset(node_description *node)
int loop; int loop;
node_description *r_node; node_description *r_node;
double i1 = 0; // inverting input current double i1 = 0; /* inverting input current */
double i2 = 0; // non-inverting input current double i2 = 0; /* non-inverting input current */
/* link to resistor static or node values */ /* link to resistor static or node values */
r_info_ptr = &info->r1; r_info_ptr = &info->r1;
@ -912,7 +931,7 @@ static void dss_op_amp_osc_reset(node_description *node)
r_context_ptr++; r_context_ptr++;
} }
context->is_squarewave = (info->type & DISC_OP_AMP_OSCILLATOR_OUT_SQW); context->is_squarewave = info->type & DISC_OP_AMP_OSCILLATOR_OUT_SQW;
context->type = info->type & DISC_OP_AMP_OSCILLATOR_TYPE_MASK; context->type = info->type & DISC_OP_AMP_OSCILLATOR_TYPE_MASK;
switch (context->type) switch (context->type)
@ -920,55 +939,55 @@ static void dss_op_amp_osc_reset(node_description *node)
case DISC_OP_AMP_OSCILLATOR_VCO_1: case DISC_OP_AMP_OSCILLATOR_VCO_1:
/* The charge rates vary depending on vMod so they are not precalculated. */ /* The charge rates vary depending on vMod so they are not precalculated. */
/* Charges while FlipFlop High */ /* Charges while FlipFlop High */
context->flip_flopXOR = 0; context->flip_flop_xor = 0;
/* Work out the Non-inverting Schmitt thresholds. */ /* Work out the Non-inverting Schmitt thresholds. */
context->temp1 = (info->vP / 2) / info->r4; context->temp1 = (info->vP / 2) / info->r4;
context->temp2 = (info->vP - OP_AMP_VP_RAIL_OFFSET) / info->r3; context->temp2 = (info->vP - OP_AMP_VP_RAIL_OFFSET) / info->r3;
context->temp3 = 1.0 / (1.0 / info->r3 + 1.0 / info->r4); context->temp3 = 1.0 / (1.0 / info->r3 + 1.0 / info->r4);
context->thresholdLow = context->temp1 * context->temp3; context->threshold_low = context->temp1 * context->temp3;
context->thresholdHigh = (context->temp1 + context->temp2) * context->temp3; context->threshold_high = (context->temp1 + context->temp2) * context->temp3;
/* There is no charge on the cap so the schmitt goes high at init. */ /* There is no charge on the cap so the schmitt goes high at init. */
context->flip_flop = 1; context->flip_flop = 1;
/* Setup some commonly used stuff */ /* Setup some commonly used stuff */
context->temp1 = info->r5 / (info->r2 + info->r5); // voltage ratio across r5 context->temp1 = info->r5 / (info->r2 + info->r5); /* voltage ratio across r5 */
context->temp2 = info->r6 / (info->r1 + info->r6); // voltage ratio across r6 context->temp2 = info->r6 / (info->r1 + info->r6); /* voltage ratio across r6 */
context->temp3 = 1.0 / (1.0 / info->r1 + 1.0 / info->r6); // input resistance when r6 switched in context->temp3 = 1.0 / (1.0 / info->r1 + 1.0 / info->r6); /* input resistance when r6 switched in */
break; break;
case DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON: case DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON:
/* Charges while FlipFlop High */ /* Charges while FlipFlop High */
context->flip_flopXOR = 0; context->flip_flop_xor = 0;
/* There is no charge on the cap so the schmitt inverter goes high at init. */ /* There is no charge on the cap so the schmitt inverter goes high at init. */
context->flip_flop = 1; context->flip_flop = 1;
break; break;
case DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON: case DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON:
/* Charges while FlipFlop Low */ /* Charges while FlipFlop Low */
context->flip_flopXOR = 1; context->flip_flop_xor = 1;
/* There is no charge on the cap so the schmitt goes low at init. */ /* There is no charge on the cap so the schmitt goes low at init. */
context->flip_flop = 0; context->flip_flop = 0;
/* The charge rates vary depending on vMod so they are not precalculated. */ /* The charge rates vary depending on vMod so they are not precalculated. */
/* But we can precalculate the fixed currents. */ /* But we can precalculate the fixed currents. */
context->iFixed = 0; context->i_fixed = 0;
if (info->r6 != 0) context->iFixed += info->vP / info->r6; if (info->r6 != 0) context->i_fixed += info->vP / info->r6;
context->iFixed += OP_AMP_NORTON_VBE / info->r1; context->i_fixed += OP_AMP_NORTON_VBE / info->r1;
context->iFixed += OP_AMP_NORTON_VBE / info->r2; context->i_fixed += OP_AMP_NORTON_VBE / info->r2;
/* Work out the input resistance to be used later to calculate the Millman voltage. */ /* Work out the input resistance to be used later to calculate the Millman voltage. */
context->rTotal = 1.0 / info->r1 + 1.0 / info->r2 + 1.0 / info->r7; context->r_total = 1.0 / info->r1 + 1.0 / info->r2 + 1.0 / info->r7;
if (info->r6) context->rTotal += 1.0 / info->r6; if (info->r6) context->r_total += 1.0 / info->r6;
if (info->r8) context->rTotal += 1.0 / info->r8; if (info->r8) context->r_total += 1.0 / info->r8;
context->rTotal = 1.0 / context->rTotal; context->r_total = 1.0 / context->r_total;
/* Work out the Non-inverting Schmitt thresholds. */ /* Work out the Non-inverting Schmitt thresholds. */
i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5; i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5;
i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4; i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4;
context->thresholdLow = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE; context->threshold_low = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE;
i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4; i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4;
context->thresholdHigh = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE; context->threshold_high = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE;
break; break;
case DISC_OP_AMP_OSCILLATOR_VCO_2 | DISC_OP_AMP_IS_NORTON: case DISC_OP_AMP_OSCILLATOR_VCO_2 | DISC_OP_AMP_IS_NORTON:
/* Charges while FlipFlop High */ /* Charges while FlipFlop High */
context->flip_flopXOR = 0; context->flip_flop_xor = 0;
/* There is no charge on the cap so the schmitt inverter goes high at init. */ /* There is no charge on the cap so the schmitt inverter goes high at init. */
context->flip_flop = 1; context->flip_flop = 1;
/* Work out the charge rates. */ /* Work out the charge rates. */
@ -977,32 +996,32 @@ static void dss_op_amp_osc_reset(node_description *node)
/* Work out the Inverting Schmitt thresholds. */ /* Work out the Inverting Schmitt thresholds. */
i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5; i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5;
i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4; i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4;
context->thresholdLow = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; context->threshold_low = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE;
i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4; i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4;
context->thresholdHigh = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; context->threshold_high = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE;
break; break;
case DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON: case DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON:
/* Charges while FlipFlop High */ /* Charges while FlipFlop High */
context->flip_flopXOR = 0; context->flip_flop_xor = 0;
/* There is no charge on the cap so the schmitt inverter goes high at init. */ /* There is no charge on the cap so the schmitt inverter goes high at init. */
context->flip_flop = 1; context->flip_flop = 1;
/* Work out the charge rates. */ /* Work out the charge rates. */
/* The charge rates vary depending on vMod so they are not precalculated. */ /* The charge rates vary depending on vMod so they are not precalculated. */
/* But we can precalculate the fixed currents. */ /* But we can precalculate the fixed currents. */
if (info->r7 != 0) context->iFixed = (info->vP - OP_AMP_NORTON_VBE) / info->r7; if (info->r7 != 0) context->i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r7;
context->temp1 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r2; context->temp1 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r2;
/* Work out the Inverting Schmitt thresholds. */ /* Work out the Inverting Schmitt thresholds. */
i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5; i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5;
i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4; i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4;
context->thresholdLow = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; context->threshold_low = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE;
i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4; i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4;
context->thresholdHigh = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; context->threshold_high = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE;
break; break;
} }
context->high_out_V = info->vP - ((context->type & DISC_OP_AMP_IS_NORTON) ? OP_AMP_NORTON_VBE : OP_AMP_VP_RAIL_OFFSET); context->v_out_high = info->vP - ((context->type & DISC_OP_AMP_IS_NORTON) ? OP_AMP_NORTON_VBE : OP_AMP_VP_RAIL_OFFSET);
context->vCap = 0; context->v_cap = 0;
dss_op_amp_osc_step(node); dss_op_amp_osc_step(node);
} }
@ -1092,10 +1111,10 @@ static void dss_schmitt_osc_step(node_description *node)
const discrete_schmitt_osc_desc *info = node->custom; const discrete_schmitt_osc_desc *info = node->custom;
struct dss_schmitt_osc_context *context = node->context; struct dss_schmitt_osc_context *context = node->context;
double supply, vCap, new_vCap, t, exponent; double supply, v_cap, new_vCap, t, exponent;
/* We will always oscillate. The enable just affects the output. */ /* We will always oscillate. The enable just affects the output. */
vCap = context->vCap; v_cap = context->v_cap;
exponent = context->exponent; exponent = context->exponent;
/* Keep looping until all toggling in time sample is used up. */ /* Keep looping until all toggling in time sample is used up. */
@ -1105,12 +1124,12 @@ static void dss_schmitt_osc_step(node_description *node)
/* The charging voltage to the cap is the sum of the input voltage and the gate /* The charging voltage to the cap is the sum of the input voltage and the gate
* output voltage in the ratios determined by their resistors in a divider network. * output voltage in the ratios determined by their resistors in a divider network.
* The input voltage is selectable as straight voltage in or logic level that will * The input voltage is selectable as straight voltage in or logic level that will
* use vGate as its voltage. Note that ratioIn is just the ratio of the total * use vGate as its voltage. Note that ration_in is just the ratio of the total
* voltage and needs to be multipled by the input voltage. ratioFeedback has * voltage and needs to be multipled by the input voltage. ratio_feedback has
* already been multiplied by vGate to save time because that voltage never changes. */ * already been multiplied by vGate to save time because that voltage never changes. */
supply = context->input_is_voltage ? context->ratioIn * DSS_SCHMITT_OSC__VIN : (DSS_SCHMITT_OSC__VIN ? context->ratioIn * info->vGate : 0); supply = context->input_is_voltage ? context->ration_in * DSS_SCHMITT_OSC__VIN : (DSS_SCHMITT_OSC__VIN ? context->ration_in * info->vGate : 0);
supply += (context->state ? context->ratioFeedback : 0); supply += (context->state ? context->ratio_feedback : 0);
new_vCap = vCap + ((supply - vCap) * exponent); new_vCap = v_cap + ((supply - v_cap) * exponent);
if (context->state) if (context->state)
{ {
/* Charging */ /* Charging */
@ -1118,10 +1137,10 @@ static void dss_schmitt_osc_step(node_description *node)
if (new_vCap > info->trshRise) if (new_vCap > info->trshRise)
{ {
/* calculate the overshoot time */ /* calculate the overshoot time */
t = context->rc * log(1.0 / (1.0 - ((new_vCap - info->trshRise) / (info->vGate - vCap)))); t = context->rc * log(1.0 / (1.0 - ((new_vCap - info->trshRise) / (info->vGate - v_cap))));
/* calculate new exponent because of reduced time */ /* calculate new exponent because of reduced time */
exponent = 1.0 - exp(-t / context->rc); exponent = 1.0 - exp(-t / context->rc);
vCap = new_vCap = info->trshRise; v_cap = new_vCap = info->trshRise;
context->state = 0; context->state = 0;
} }
} }
@ -1132,16 +1151,16 @@ static void dss_schmitt_osc_step(node_description *node)
if (new_vCap < info->trshFall) if (new_vCap < info->trshFall)
{ {
/* calculate the overshoot time */ /* calculate the overshoot time */
t = context->rc * log(1.0 / (1.0 - ((info->trshFall - new_vCap) / vCap))); t = context->rc * log(1.0 / (1.0 - ((info->trshFall - new_vCap) / v_cap)));
/* calculate new exponent because of reduced time */ /* calculate new exponent because of reduced time */
exponent = 1.0 - exp(-t / context->rc); exponent = 1.0 - exp(-t / context->rc);
vCap = new_vCap = info->trshFall; v_cap = new_vCap = info->trshFall;
context->state = 1; context->state = 1;
} }
} }
} while(t); } while(t);
context->vCap = new_vCap; context->v_cap = new_vCap;
switch (context->enable_type) switch (context->enable_type)
{ {
@ -1172,8 +1191,8 @@ static void dss_schmitt_osc_reset(node_description *node)
/* The 2 resistors make a voltage divider, so their ratios add together /* The 2 resistors make a voltage divider, so their ratios add together
* to make the charging voltage. */ * to make the charging voltage. */
context->ratioIn = info->rFeedback / (info->rIn + info->rFeedback); context->ration_in = info->rFeedback / (info->rIn + info->rFeedback);
context->ratioFeedback = info->rIn / (info->rIn + info->rFeedback) * info->vGate; context->ratio_feedback = info->rIn / (info->rIn + info->rFeedback) * info->vGate;
/* The voltage source resistance works out to the 2 resistors in parallel. /* The voltage source resistance works out to the 2 resistors in parallel.
* So use this for the RC charge constant. */ * So use this for the RC charge constant. */
@ -1183,7 +1202,7 @@ static void dss_schmitt_osc_reset(node_description *node)
context->exponent = 1.0 - exp(context->exponent); context->exponent = 1.0 - exp(context->exponent);
/* Cap is at 0V on power up. Causing output to be high. */ /* Cap is at 0V on power up. Causing output to be high. */
context->vCap = 0; context->v_cap = 0;
context->state = 1; context->state = 1;
node->output[0] = info->options ? 0 : DSS_SCHMITT_OSC__AMP; node->output[0] = info->options ? 0 : DSS_SCHMITT_OSC__AMP;
@ -1277,9 +1296,9 @@ static void dss_squarewave_step(node_description *node)
if(DSS_SQUAREWAVE__ENABLE) if(DSS_SQUAREWAVE__ENABLE)
{ {
if(context->phase>context->trigger) if(context->phase>context->trigger)
node->output[0]=(DSS_SQUAREWAVE__AMP/2.0); node->output[0] = DSS_SQUAREWAVE__AMP /2.0;
else else
node->output[0]=-(DSS_SQUAREWAVE__AMP/2.0); node->output[0] =- DSS_SQUAREWAVE__AMP / 2.0;
/* Add DC Bias component */ /* Add DC Bias component */
node->output[0] = node->output[0] + DSS_SQUAREWAVE__BIAS; node->output[0] = node->output[0] + DSS_SQUAREWAVE__BIAS;
@ -1296,7 +1315,7 @@ static void dss_squarewave_step(node_description *node)
/* boils out to */ /* boils out to */
/* phase step = (2Pi*output freq)/sample freq) */ /* phase step = (2Pi*output freq)/sample freq) */
/* Also keep the new phasor in the 2Pi range. */ /* Also keep the new phasor in the 2Pi range. */
context->phase=fmod((context->phase+((2.0*M_PI*DSS_SQUAREWAVE__FREQ)/discrete_current_context->sample_rate)),2.0*M_PI); context->phase=fmod(context->phase + ((2.0 * M_PI * DSS_SQUAREWAVE__FREQ) / discrete_current_context->sample_rate), 2.0 * M_PI);
} }
static void dss_squarewave_reset(node_description *node) static void dss_squarewave_reset(node_description *node)
@ -1336,22 +1355,22 @@ static void dss_squarewfix_step(node_description *node)
{ {
struct dss_squarewfix_context *context = node->context; struct dss_squarewfix_context *context = node->context;
context->tLeft -= context->sampleStep; context->t_left -= context->sample_step;
/* The enable input only curtails output, phase rotation still occurs */ /* The enable input only curtails output, phase rotation still occurs */
while (context->tLeft <= 0) while (context->t_left <= 0)
{ {
context->flip_flop = context->flip_flop ? 0 : 1; context->flip_flop = context->flip_flop ? 0 : 1;
context->tLeft += context->flip_flop ? context->tOn : context->tOff; context->t_left += context->flip_flop ? context->t_on : context->t_off;
} }
if(DSS_SQUAREWFIX__ENABLE) if(DSS_SQUAREWFIX__ENABLE)
{ {
/* Add gain and DC Bias component */ /* Add gain and DC Bias component */
context->tOff = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */ context->t_off = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */
context->tOn = context->tOff * (DSS_SQUAREWFIX__DUTY / 100.0); context->t_on = context->t_off * (DSS_SQUAREWFIX__DUTY / 100.0);
context->tOff -= context->tOn; context->t_off -= context->t_on;
node->output[0] = (context->flip_flop ? DSS_SQUAREWFIX__AMP / 2.0 : -(DSS_SQUAREWFIX__AMP / 2.0)) + DSS_SQUAREWFIX__BIAS; node->output[0] = (context->flip_flop ? DSS_SQUAREWFIX__AMP / 2.0 : -(DSS_SQUAREWFIX__AMP / 2.0)) + DSS_SQUAREWFIX__BIAS;
} }
@ -1365,25 +1384,25 @@ static void dss_squarewfix_reset(node_description *node)
{ {
struct dss_squarewfix_context *context = node->context; struct dss_squarewfix_context *context = node->context;
context->sampleStep = 1.0 / discrete_current_context->sample_rate; context->sample_step = 1.0 / discrete_current_context->sample_rate;
context->flip_flop = 1; context->flip_flop = 1;
/* Do the intial time shift and convert freq to off/on times */ /* Do the intial time shift and convert freq to off/on times */
context->tOff = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */ context->t_off = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */
context->tLeft = DSS_SQUAREWFIX__PHASE / 360.0; /* convert start phase to % */ context->t_left = DSS_SQUAREWFIX__PHASE / 360.0; /* convert start phase to % */
context->tLeft = context->tLeft - (int)context->tLeft; /* keep % between 0 & 1 */ context->t_left = context->t_left - (int)context->t_left; /* keep % between 0 & 1 */
context->tLeft = (context->tLeft < 0) ? 1.0 + context->tLeft : context->tLeft; /* if - then flip to + phase */ context->t_left = (context->t_left < 0) ? 1.0 + context->t_left : context->t_left; /* if - then flip to + phase */
context->tLeft *= context->tOff; context->t_left *= context->t_off;
context->tOn = context->tOff * (DSS_SQUAREWFIX__DUTY / 100.0); context->t_on = context->t_off * (DSS_SQUAREWFIX__DUTY / 100.0);
context->tOff -= context->tOn; context->t_off -= context->t_on;
context->tLeft = -context->tLeft; context->t_left = -context->t_left;
/* toggle output and work out intial time shift */ /* toggle output and work out intial time shift */
while (context->tLeft <= 0) while (context->t_left <= 0)
{ {
context->flip_flop = context->flip_flop ? 0 : 1; context->flip_flop = context->flip_flop ? 0 : 1;
context->tLeft += context->flip_flop ? context->tOn : context->tOff; context->t_left += context->flip_flop ? context->t_on : context->t_off;
} }
/* Step the output */ /* Step the output */
@ -1432,9 +1451,9 @@ static void dss_squarewave2_step(node_description *node)
context->phase = fmod(newphase, 2.0 * M_PI); context->phase = fmod(newphase, 2.0 * M_PI);
if(context->phase>context->trigger) if(context->phase>context->trigger)
node->output[0]=(DSS_SQUAREWAVE2__AMP/2.0); node->output[0] = DSS_SQUAREWAVE2__AMP / 2.0;
else else
node->output[0]=-(DSS_SQUAREWAVE2__AMP/2.0); node->output[0] = -DSS_SQUAREWAVE2__AMP / 2.0;
/* Add DC Bias component */ /* Add DC Bias component */
node->output[0] = node->output[0] + DSS_SQUAREWAVE2__BIAS; node->output[0] = node->output[0] + DSS_SQUAREWAVE2__BIAS;
@ -1497,6 +1516,7 @@ INLINE double dss_inverter_tf(node_description *node, double x)
{ {
const discrete_inverter_osc_desc *info = node->custom; const discrete_inverter_osc_desc *info = node->custom;
struct dss_inverter_osc_context *context = node->context; struct dss_inverter_osc_context *context = node->context;
if (x < 0.0) if (x < 0.0)
return info->vB; return info->vB;
else if (x <= info->vB) else if (x <= info->vB)
@ -1509,11 +1529,12 @@ static void dss_inverter_osc_step(node_description *node)
{ {
struct dss_inverter_osc_context *context = node->context; struct dss_inverter_osc_context *context = node->context;
const discrete_inverter_osc_desc *info = node->custom; const discrete_inverter_osc_desc *info = node->custom;
double diff, vG1, vG2, vG3, vI; double diff, vG1, vG2, vG3, vI;
double vMix, rMix; double vMix, rMix;
/* Get new state */ /* Get new state */
vI = context->vCap + context->vG2_old; vI = context->v_cap + context->v_g2_old;
switch (info->options & DISC_OSC_INVERTER_TYPE_MASK) switch (info->options & DISC_OSC_INVERTER_TYPE_MASK)
{ {
case DISC_OSC_INVERTER_IS_TYPE1: case DISC_OSC_INVERTER_IS_TYPE1:
@ -1551,14 +1572,14 @@ static void dss_inverter_osc_step(node_description *node)
{ {
vI = MAX(vI, (- info->clamp)); vI = MAX(vI, (- info->clamp));
vI = MIN(vI, info->vB + info->clamp); vI = MIN(vI, info->vB + info->clamp);
diff = vG3 * (context->Rp / (context->Rp + context->R1)) diff = vG3 * (context->rp / (context->rp + context->r1))
- (context->vCap + vG2) - (context->v_cap + vG2)
+ vI*(context->R1 / (context->Rp + context->R1)); + vI*(context->r1 / (context->rp + context->r1));
diff = diff - diff * context->wc; diff = diff - diff * context->wc;
} }
else else
{ {
diff = vG3 - (context->vCap + vG2); diff = vG3 - (context->v_cap + vG2);
diff = diff - diff * context->w; diff = diff - diff * context->w;
} }
break; break;
@ -1568,17 +1589,17 @@ static void dss_inverter_osc_step(node_description *node)
vI = MAX(vI, (- info->clamp)); vI = MAX(vI, (- info->clamp));
vI = MIN(vI, info->vB + info->clamp); vI = MIN(vI, info->vB + info->clamp);
} }
// FIXME handle R2 = 0 /* FIXME handle r2 = 0 */
rMix = (context->R1 * context->R2) / (context->R1 + context->R2); rMix = (context->r1 * context->r2) / (context->r1 + context->r2);
vMix = rMix* ((vG3-vG2) / context->R1 + (DSS_INVERTER_OSC__MOD-vG2) / context->R2); vMix = rMix* ((vG3 - vG2) / context->r1 + (DSS_INVERTER_OSC__MOD-vG2) / context->r2);
if (vMix < (vI-vG2-0.7)) if (vMix < (vI-vG2-0.7))
{ {
rMix = 1.0/rMix + 1.0/context->Rp; rMix = 1.0 / rMix + 1.0 / context->rp;
rMix = 1.0 / rMix; rMix = 1.0 / rMix;
vMix = rMix* ( (vG3-vG2) / context->R1 + (DSS_INVERTER_OSC__MOD-vG2) / context->R2 + (vI-0.7-vG2)/context->Rp); vMix = rMix* ( (vG3-vG2) / context->r1 + (DSS_INVERTER_OSC__MOD-vG2) / context->r2 + (vI-0.7-vG2)/context->rp);
} }
diff = vMix - context->vCap; diff = vMix - context->v_cap;
diff = diff - diff * exp(-discrete_current_context->sample_time/(context->C * rMix)); diff = diff - diff * exp(-discrete_current_context->sample_time / (context->c * rMix));
break; break;
case DISC_OSC_INVERTER_IS_TYPE5: case DISC_OSC_INVERTER_IS_TYPE5:
if ((info->clamp >= 0.0) && ((vI< - info->clamp) || (vI> info->vB+info->clamp))) if ((info->clamp >= 0.0) && ((vI< - info->clamp) || (vI> info->vB+info->clamp)))
@ -1586,23 +1607,23 @@ static void dss_inverter_osc_step(node_description *node)
vI = MAX(vI, (- info->clamp)); vI = MAX(vI, (- info->clamp));
vI = MIN(vI, info->vB + info->clamp); vI = MIN(vI, info->vB + info->clamp);
} }
// FIXME handle R2 = 0 /* FIXME handle r2 = 0 */
rMix = (context->R1 * context->R2) / (context->R1 + context->R2); rMix = (context->r1 * context->r2) / (context->r1 + context->r2);
vMix = rMix* ((vG3-vG2) / context->R1 + (DSS_INVERTER_OSC__MOD-vG2) / context->R2); vMix = rMix* ((vG3 - vG2) / context->r1 + (DSS_INVERTER_OSC__MOD-vG2) / context->r2);
if (vMix > (vI -vG2 +0.7)) if (vMix > (vI -vG2 +0.7))
{ {
rMix = 1.0/rMix + 1.0/context->Rp; rMix = 1.0 / rMix + 1.0/context->rp;
rMix = 1.0 / rMix; rMix = 1.0 / rMix;
vMix = rMix* ( (vG3-vG2) / context->R1 + (DSS_INVERTER_OSC__MOD-vG2) / context->R2 + (vI+0.7-vG2)/context->Rp); vMix = rMix* ( (vG3 - vG2) / context->r1 + (DSS_INVERTER_OSC__MOD-vG2) / context->r2 + (vI+0.7-vG2)/context->rp);
} }
diff = vMix - context->vCap; diff = vMix - context->v_cap;
diff = diff - diff * exp(-discrete_current_context->sample_time/(context->C * rMix)); diff = diff - diff * exp(-discrete_current_context->sample_time/(context->c * rMix));
break; break;
default: default:
fatalerror("DISCRETE_INVERTER_OSC - Wrong type on NODE_%02d", node->node - NODE_00); fatalerror("DISCRETE_INVERTER_OSC - Wrong type on NODE_%02d", node->node - NODE_00);
} }
context->vCap += diff; context->v_cap += diff;
context->vG2_old = vG2; context->v_g2_old = vG2;
if ((info->options & DISC_OSC_INVERTER_TYPE_MASK) == DISC_OSC_INVERTER_IS_TYPE3) if ((info->options & DISC_OSC_INVERTER_TYPE_MASK) == DISC_OSC_INVERTER_IS_TYPE3)
node->output[0] = vG1; node->output[0] = vG1;
else else
@ -1615,18 +1636,19 @@ static void dss_inverter_osc_reset(node_description *node)
{ {
struct dss_inverter_osc_context *context = node->context; struct dss_inverter_osc_context *context = node->context;
const discrete_inverter_osc_desc *info = node->custom; const discrete_inverter_osc_desc *info = node->custom;
int i; int i;
/* exponent */ /* exponent */
context->w = exp(-discrete_current_context->sample_time / (DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__C)); context->w = exp(-discrete_current_context->sample_time / (DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__C));
context->wc = exp(-discrete_current_context->sample_time / ((DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__RP) / (DSS_INVERTER_OSC__RP + DSS_INVERTER_OSC__RC) * DSS_INVERTER_OSC__C)); context->wc = exp(-discrete_current_context->sample_time / ((DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__RP) / (DSS_INVERTER_OSC__RP + DSS_INVERTER_OSC__RC) * DSS_INVERTER_OSC__C));
node->output[0] = 0; node->output[0] = 0;
context->vCap = 0; context->v_cap = 0;
context->vG2_old = 0; context->v_g2_old = 0;
context->Rp = DSS_INVERTER_OSC__RP; context->rp = DSS_INVERTER_OSC__RP;
context->R1 = DSS_INVERTER_OSC__RC; context->r1 = DSS_INVERTER_OSC__RC;
context->R2 = DSS_INVERTER_OSC__R2; context->r2 = DSS_INVERTER_OSC__R2;
context->C = DSS_INVERTER_OSC__C; context->c = DSS_INVERTER_OSC__C;
context->tf_b = (log(0.0 - log(info->vOutLow/info->vB)) - log(0.0 - log((info->vOutHigh/info->vB))) ) / log(info->vInRise / info->vInFall); context->tf_b = (log(0.0 - log(info->vOutLow/info->vB)) - log(0.0 - log((info->vOutHigh/info->vB))) ) / log(info->vInRise / info->vInFall);
context->tf_a = log(0.0 - log(info->vOutLow/info->vB)) - context->tf_b * log(info->vInRise/info->vB); context->tf_a = log(0.0 - log(info->vOutLow/info->vB)) - context->tf_b * log(info->vInRise/info->vB);
context->tf_a = exp(context->tf_a); context->tf_a = exp(context->tf_a);
@ -1709,7 +1731,7 @@ static void dss_trianglewave_reset(node_description *node)
static void dss_adsrenv_step(node_description *node) static void dss_adsrenv_step(node_description *node)
{ {
// struct dss_adsr_context *context = node->context; /* struct dss_adsr_context *context = node->context; */
if(DSS_ADSR__ENABLE) if(DSS_ADSR__ENABLE)
{ {

View File

@ -307,8 +307,10 @@ static void *discrete_start(const char *tag, int sndindex, int clock, const void
/* create the logfile */ /* create the logfile */
sprintf(name, "discrete%d.log", info->sndindex); sprintf(name, "discrete%d.log", info->sndindex);
if (DISCRETE_DEBUGLOG && !discrete_current_context->disclogfile) if (DISCRETE_DEBUGLOG && !info->disclogfile)
discrete_current_context->disclogfile = fopen(name, "w"); info->disclogfile = fopen(name, "w");
discrete_current_context = info;
/* first pass through the nodes: sanity check, fill in the indexed_nodes, and make a total count */ /* first pass through the nodes: sanity check, fill in the indexed_nodes, and make a total count */
discrete_log("discrete_start() - Doing node list sanity check"); discrete_log("discrete_start() - Doing node list sanity check");
@ -329,8 +331,6 @@ static void *discrete_start(const char *tag, int sndindex, int clock, const void
/* make sure this is a main node */ /* make sure this is a main node */
if (NODE_CHILD_NODE_NUM(intf[info->node_count].node) > 0) if (NODE_CHILD_NODE_NUM(intf[info->node_count].node) > 0)
fatalerror("discrete_start() - Child node number on NODE_%02d", NODE_INDEX(intf[info->node_count].node) ); fatalerror("discrete_start() - Child node number on NODE_%02d", NODE_INDEX(intf[info->node_count].node) );
} }
info->node_count++; info->node_count++;
discrete_log("discrete_start() - Sanity check counted %d nodes", info->node_count); discrete_log("discrete_start() - Sanity check counted %d nodes", info->node_count);
@ -357,6 +357,8 @@ static void *discrete_start(const char *tag, int sndindex, int clock, const void
setup_output_nodes(info); setup_output_nodes(info);
setup_disc_logs(info); setup_disc_logs(info);
discrete_current_context = NULL;
return info; return info;
} }
@ -414,9 +416,9 @@ static void discrete_stop(void *chip)
if (DISCRETE_DEBUGLOG) if (DISCRETE_DEBUGLOG)
{ {
/* close the debug log */ /* close the debug log */
if (discrete_current_context->disclogfile) if (info->disclogfile)
fclose(discrete_current_context->disclogfile); fclose(info->disclogfile);
discrete_current_context->disclogfile = NULL; info->disclogfile = NULL;
} }
} }
@ -703,8 +705,8 @@ static void find_input_nodes(discrete_info *info, discrete_sound_block *block_li
if (NODE_CHILD_NODE_NUM(inputnode) >= node_ref->module.num_output) if (NODE_CHILD_NODE_NUM(inputnode) >= node_ref->module.num_output)
fatalerror("discrete_start - Node NODE_%02d referenced non existent output %d on node NODE_%02d", NODE_INDEX(node->node), NODE_CHILD_NODE_NUM(inputnode), NODE_INDEX(inputnode)); fatalerror("discrete_start - Node NODE_%02d referenced non existent output %d on node NODE_%02d", NODE_INDEX(node->node), NODE_CHILD_NODE_NUM(inputnode), NODE_INDEX(inputnode));
node->input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); // Link referenced node out to input node->input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); /* Link referenced node out to input */
node->input_is_node |= 1 << inputnum; // Bit flag if input is node node->input_is_node |= 1 << inputnum; /* Bit flag if input is node */
} }
} }
} }

View File

@ -121,6 +121,59 @@
* *
*********************************************************************** ***********************************************************************
* *
* x_time - ANTI-ALSING features.
*
* Certain modules make use of x_time. This is a feature that passes
* infomation between modules about how long in the current sample, the
* switch in state happened. This is a decimal value of the % of the
* full sample period that it has been in the new state.
* 0 means it has been at the same state the whole sample.
*
* Example: Here is the output of a clock source with x_time on the
* output. The square wave is the real world waveform we
* want. The ^'s are the sample point. The numbers under
* the ^'s are the node output with the logic state left of
* the decimal and the x_time to the right. Under that is
* what the node's anti-aliased output energy would be.
* Note: the example is not 4x sampling so the energy
* does not provide an accurate representation of the
* original waveform. This is intentional so it fits
* in this header file.
* 1 ____ ____ ____ ____ ____ ____ ____ ____
* 0 ___ ____ ____ ____ ____ ____ ____ ____ __
* ^....^....^....^....^....^....^....^....^....^....^....^....^
* x_time 0.2 1.4 0.6 1.8 1.2 0.4 1.6 0.8 0.2 1.4 0.6
* energy 0.8 0.4 0.4 0.8 0.2 0.6 0.6 0.2 0.8 0.4 0.4
*
* Some modules will just pass the x_time onto another module.
*
* Modules that process x_time will keep track of the node's previous
* state so they can calculate the actual energy at the sample time.
*
* Example: Say we have a 555 module that outputs a clock with x_time
* that is connected to a counter. The output of the counter
* is connected to DAC_R1.
* In this case the counter module continues counting dependant
* on the integer portion of the 555 output. But it also
* passes the decimal portion as the x_time.
* The DAC_R1 then uses this info to anti-alias its output.
* Consider the following counter outputs vs DAC_R1
* calculations. The count changes from 9 to 10. It has
* been at the new state for 75% of the sample.
*
* counter binary x_time -- DAC_R1 bit energy --
* out count D3 D2 D1 D0
* 9.0 1001 0.0 1.0 0.0 0.0 1.0
* 10.75 1010 0.75 1.0 0.0 0.75 0.25
* 10.0 1010 0.0 1.0 0.0 1.0 0.0
*
* The DAC_R1 uses these energy calculations to scale the
* voltages created on each of its resistors. This
* anti-aliases the waveform no mater what the resistor
* weighting is.
*
***********************************************************************
*
* LIST OF CURRENTLY IMPLEMENTED DISCRETE BLOCKS * LIST OF CURRENTLY IMPLEMENTED DISCRETE BLOCKS
* --------------------------------------------- * ---------------------------------------------
* *
@ -142,7 +195,7 @@
* DISCRETE_INPUTX_STREAM(NODE,NUM, GAIN,OFFSET) * DISCRETE_INPUTX_STREAM(NODE,NUM, GAIN,OFFSET)
* *
* DISCRETE_COUNTER(NODE,ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE) * DISCRETE_COUNTER(NODE,ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE)
* DISCRETE_COUNTER_7492(NODE,ENAB,RESET,CLK) * DISCRETE_COUNTER_7492(NODE,ENAB,RESET,CLK,CLKTYPE)
* DISCRETE_LFSR_NOISE(NODE,ENAB,RESET,CLK,AMPL,FEED,BIAS,LFSRTB) * DISCRETE_LFSR_NOISE(NODE,ENAB,RESET,CLK,AMPL,FEED,BIAS,LFSRTB)
* DISCRETE_NOISE(NODE,ENAB,FREQ,AMP,BIAS) * DISCRETE_NOISE(NODE,ENAB,FREQ,AMP,BIAS)
* DISCRETE_NOTE(NODE,ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE) * DISCRETE_NOTE(NODE,ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE)
@ -386,7 +439,7 @@
* This counter counts up/down from 0 to MAX. When the enable is low, the output * This counter counts up/down from 0 to MAX. When the enable is low, the output
* is held at it's last value. When reset is high, the reset value is loaded * is held at it's last value. When reset is high, the reset value is loaded
* into the output. The counter can be clocked internally or externally. It also * into the output. The counter can be clocked internally or externally. It also
* supports xTime used by the clock modules to pass on anti-aliasing info. * supports x_time used by the clock modules to pass on anti-aliasing info.
* *
* Declaration syntax * Declaration syntax
* *
@ -399,6 +452,16 @@
* DISC_CLK_IS_FREQ - internally clock at this frequency. * DISC_CLK_IS_FREQ - internally clock at this frequency.
* Clock node must be static if * Clock node must be static if
* DISC_CLK_IS_FREQ is used. * DISC_CLK_IS_FREQ is used.
* x_time options: you can also | these x_time features to the basic
* types above if needed, or use seperately with 7492.
* DISC_OUT_IS_ENERGY - This will uses the x_time to
* anti-alias the count. Might be
* usefull if not connected to other
* modules.
* DISC_OUT_HAS_XTIME - This will generate x_time if
* being used with DISC_CLK_IS_FREQ.
* It will pass x_time for the
* other clock types.
* *
* DISCRETE_COUNTER(name of node, * DISCRETE_COUNTER(name of node,
* enable node or static value, * enable node or static value,
@ -413,10 +476,12 @@
* enable node or static value, * enable node or static value,
* reset node or static value, * reset node or static value,
* clock node or static value, * clock node or static value,
* max count static value) * clock type static value)
* *
* Note: A 7492 counter outputs a special bit pattern on its /6 stage. * Note: A 7492 counter outputs a special bit pattern on its /6 stage.
* A 7492 clocks on falling edge. This emulates the /6 stage only. * A 7492 clocks on the falling edge,
* so it is not recommended to use DISC_CLK_ON_R_EDGE for a 7492.
* This module emulates the /6 stage only.
* Use another DISCRETE_COUNTER for the /2 stage. * Use another DISCRETE_COUNTER for the /2 stage.
* *
* EXAMPLES: see Fire Truck, Monte Carlo, Super Bug, Polaris * EXAMPLES: see Fire Truck, Monte Carlo, Super Bug, Polaris
@ -1659,7 +1724,7 @@
* DISCRETE_DAC_R1(name of node, * DISCRETE_DAC_R1(name of node,
* enable node or static value, * enable node or static value,
* data node (static value is useless), * data node (static value is useless),
* vData node or static value (vON), * vData node or static value (voltage when a bit is on ),
* address of discrete_dac_r1_ladder structure) * address of discrete_dac_r1_ladder structure)
* *
* discrete_dac_r1_ladder = {ladderLength, r{}, vBias, rBias, rGnd, cFilter} * discrete_dac_r1_ladder = {ladderLength, r{}, vBias, rBias, rGnd, cFilter}
@ -1668,6 +1733,9 @@
* are out of circuit. So the bit selecting them will have no effect * are out of circuit. So the bit selecting them will have no effect
* on the DAC output voltage. * on the DAC output voltage.
* *
* x_time - this modules automatically handles any non-integer value
* on the data input as x_time.
*
* EXAMPLES: see Fire Truck, Monte Carlo, Super Bug, Polaris * EXAMPLES: see Fire Truck, Monte Carlo, Super Bug, Polaris
* *
*********************************************************************** ***********************************************************************
@ -1802,7 +1870,7 @@
* input 7 node, (if used) * input 7 node, (if used)
* address of discrete_mixer_info structure) * address of discrete_mixer_info structure)
* *
* discrete_mixer_desc = {type, r{}, rNode{}, c{}, rI, rF, cF, cAmp, vRef, gain} * discrete_mixer_desc = {type, r{}, r_node{}, c{}, rI, rF, cF, cAmp, vRef, gain}
* *
* Note: Set all unused components to 0. * Note: Set all unused components to 0.
* If an rNode is not used it should also be set to 0. * If an rNode is not used it should also be set to 0.
@ -2681,21 +2749,22 @@
* DISCRETE_555_ASTABLE - NE555 Chip simulation (astable mode). * DISCRETE_555_ASTABLE - NE555 Chip simulation (astable mode).
* DISCRETE_555_ASTABLE_CV - NE555 Chip simulation (astable mode) with CV control. * DISCRETE_555_ASTABLE_CV - NE555 Chip simulation (astable mode) with CV control.
* *
* v555 * v_charge v_pos
* | * V V
* .---------+ * | |
* | |
* | | * | |
* Z |8 * Z |8
* R1 Z .---------. * _FAST_CHARGE_DIODE R1 Z .---------.
* | 7| Vcc | * (optional) | 7| Vcc |
* +-----|Discharge| * +---------> +-----|Discharge|
* | | | * | | | |
* Z | 555 |3 * --- Z | 555 |3
* R2 Z | Out|---> Netlist Node * \ / R2 Z | Out|---> Netlist Node
* | 6| | * V | 6| |
* +-----|Threshold| * --- +-----|Threshold|
* | | | * | | | |
* +-----|Trigger | * +---------> +-----|Trigger |
* | 2| |---< Control Voltage * | 2| |---< Control Voltage
* | | Reset |5 * | | Reset |5
* | '---------' * | '---------'
@ -2723,27 +2792,27 @@
* *
* discrete_555_desc = * discrete_555_desc =
* { * {
* options, // bit mapped options * options, - bit mapped options
* v555, // B+ voltage of 555 * v_pos, - B+ voltage of 555
* v555high, // High output voltage of 555 (Usually v555 - 1.2V) * v_charge, - voltage to charge circuit (Defaults to v_pos)
* threshold555, // normally 2/3 of v555 * v_out_high, - High output voltage of 555 (Defaults to v_pos - 1.2V)
* trigger555 // normally 1/3 of v555
* } * }
* *
* The last 3 options of discrete_555_desc can use the following defaults * The last 2 options of discrete_555_desc can use the following defaults:
* unless otherwise needed. * DEFAULT_555_CHARGE - to connect v_charge to v_pos
* DEFAULT_555_HIGH, DEFAULT_555_THRESHOLD, DEFAULT_555_TRIGGER * DEFAULT_555_HIGH - to use the normal output voltage based on v_pos
* or all 3 combined as: * or combine both as:
* DEFAULT_555_VALUES * DEFAULT_555_VALUES
* *
* eg. {DISC_555_OUT_DC | DISC_555_OUT_SQW, 12, DEFAULT_555_VALUES} * eg. {DISC_555_OUT_SQW | DISC_555_OUT_DC, 12, DEFAULT_555_VALUES}
* *
* Output Types: * Output Types: (only needed with DISC_555_OUT_SQW, DISC_555_OUT_CAP
* and DISC_555_OUT_ENERGY)
* DISC_555_OUT_DC - Output is actual DC. (DEFAULT) * DISC_555_OUT_DC - Output is actual DC. (DEFAULT)
* DISC_555_OUT_AC - A cheat to make the waveform AC. * DISC_555_OUT_AC - A cheat to make the waveform AC.
* *
* Waveform Types: (ORed with output types) * Waveform Types: (ORed with output types)
* DISC_555_OUT_SQW - Output is Squarewave. 0 or v555high. (DEFAULT) * DISC_555_OUT_SQW - Output is Squarewave. 0 or v_out_high. (DEFAULT)
* When the state changes from low to high (or high to low) * When the state changes from low to high (or high to low)
* during a sample, the output will high (or low) for that * during a sample, the output will high (or low) for that
* sample. This can cause alaising effects. * sample. This can cause alaising effects.
@ -2763,7 +2832,7 @@
* through the sample, then the output will be 75% of the * through the sample, then the output will be 75% of the
* normal high value. * normal high value.
* DISC_555_OUT_LOGIC_X - This will output the 0/1 level of the flip-flop with * DISC_555_OUT_LOGIC_X - This will output the 0/1 level of the flip-flop with
* some eXtra info. This X info is in decimal remainder. * some eXtra info. This x_time is in decimal remainder.
* It lets you know the percent of sample time where the * It lets you know the percent of sample time where the
* flip-flop changed state. If 0, the change did not happen * flip-flop changed state. If 0, the change did not happen
* during the sample. 1.75 means the flip-flop is 1 and * during the sample. 1.75 means the flip-flop is 1 and
@ -2771,8 +2840,8 @@
* 0.2 means the flip-flop is 0 and switched over 4/5 of * 0.2 means the flip-flop is 0 and switched over 4/5 of
* the way through the sample. * the way through the sample.
* X modules can be used with counters to reduce alaising. * X modules can be used with counters to reduce alaising.
* DISC_555_OUT_COUNT_F_X - Same as DISC_555_OUT_COUNT_F but with X info. * DISC_555_OUT_COUNT_F_X - Same as DISC_555_OUT_COUNT_F but with x_time.
* DISC_555_OUT_COUNT_R_X - Same as DISC_555_OUT_COUNT_R but with X info. * DISC_555_OUT_COUNT_R_X - Same as DISC_555_OUT_COUNT_R but with x_time.
* *
* other options - DISCRETE_555_ASTABLE only: * other options - DISCRETE_555_ASTABLE only:
* DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE - diode used to bypass rDischarge * DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE - diode used to bypass rDischarge
@ -2785,9 +2854,10 @@
* DISCRETE_555_MSTABLE - NE555 Chip simulation (monostable mode) * DISCRETE_555_MSTABLE - NE555 Chip simulation (monostable mode)
* - Triggered on falling edge. * - Triggered on falling edge.
* *
* v555 * v_charge v_pos
* | * V V
* .---------+ * | |
* | |
* | | * | |
* Z | * Z |
* R Z .---------. * R Z .---------.
@ -2817,11 +2887,13 @@
* C node (or value) in farads, * C node (or value) in farads,
* address of discrete_555_desc structure) * address of discrete_555_desc structure)
* *
* discrete_555_desc = See DISCRETE_555_ASTABLE for description.
*
* Trigger Types * Trigger Types
* DISC_555_TRIGGER_IS_LOGIC - Input is (0 or !0) logic (DEFAULT) * DISC_555_TRIGGER_IS_LOGIC - Input is (0 or !0) logic (DEFAULT)
* DISC_555_TRIGGER_IS_VOLTAGE - Input is actual voltage. * DISC_555_TRIGGER_IS_VOLTAGE - Input is actual voltage.
* Voltage must drop below * Voltage must drop below
* trigger555 to activate. * trigger to activate.
* DISC_555_TRIGGER_DISCHARGES_CAP - some circuits connect an external * DISC_555_TRIGGER_DISCHARGES_CAP - some circuits connect an external
* device (transistor) to the cap to * device (transistor) to the cap to
* discharge it when the trigger is * discharge it when the trigger is
@ -2833,7 +2905,7 @@
* DISC_555_OUT_AC - A cheat to make the waveform AC. * DISC_555_OUT_AC - A cheat to make the waveform AC.
* *
* Waveform Types: (ORed with trigger types) * Waveform Types: (ORed with trigger types)
* DISC_555_OUT_SQW - Output is Squarewave. 0 or v555high. (DEFAULT) * DISC_555_OUT_SQW - Output is Squarewave. 0 or v_out_high. (DEFAULT)
* DISC_555_OUT_CAP - Output is Timing Capacitor 'C' voltage. * DISC_555_OUT_CAP - Output is Timing Capacitor 'C' voltage.
* *
* EXAMPLES: see Frogs * EXAMPLES: see Frogs
@ -2843,7 +2915,7 @@
* DISCRETE_555_CC - Constant Current Controlled 555 Oscillator * DISCRETE_555_CC - Constant Current Controlled 555 Oscillator
* Which works out to a VCO when R is fixed. * Which works out to a VCO when R is fixed.
* *
* vCCsource v555 * v_cc_source v_pos
* V V * V V
* | .----------------------+ * | .----------------------+
* | | | * | | |
@ -2896,15 +2968,20 @@
* *
* discrete_555_cc_desc = * discrete_555_cc_desc =
* { * {
* options, // bit mapped options * options; - bit mapped options
* v555, // B+ voltage of 555 * v_pos; - B+ voltage of 555
* v555high, // High output voltage of 555 (Usually v555 - 1.2V) * v_cc_source; - Voltage of the Constant Current source
* threshold555, // normally 2/3 of v555 * v_out_high; - High output voltage of 555 (Defaults to v_pos - 1.2V)
* trigger555, // normally 1/3 of v555 * v_cc_junction; - The voltage drop of the Constant Current source transitor
* vCCsource, // B+ voltage of the Constant Current source * (0 if Op Amp)
* vCCjunction // The voltage drop of the Constant Current source transitor (0 if Op Amp)
* } * }
* *
* The last 2 options of discrete_555_desc can use the following defaults:
* DEFAULT_555_CC_SOURCE - to connect v_cc_source to v_pos
* DEFAULT_555_HIGH - to use the normal output voltage based on v_pos
* or combine both as:
* DEFAULT_555_VALUES
*
* Output Types: * Output Types:
* See DISCRETE_555_ASTABLE for description. * See DISCRETE_555_ASTABLE for description.
* *
@ -2942,7 +3019,7 @@
* | En|<--------. | .---|Discharge | * | En|<--------. | .---|Discharge |
* '----' | gnd | '------------' * '----' | gnd | '------------'
* | | | * | | |
* gnd '-----------------------+---ZZZZ------> 5V * gnd '-----------------------+---ZZZZ------> v_charge (ignored)
* rX * rX
* *
* Declaration syntax * Declaration syntax
@ -2958,12 +3035,16 @@
* Vin2 (CV) node or static value, * Vin2 (CV) node or static value,
* address of discrete_555_vco1_desc structure) * address of discrete_555_vco1_desc structure)
* *
* discrete_555_vco1_desc = {options, // bit mapped options * discrete_555_vco1_desc =
* {
* options, - bit mapped options
* r1, r2, r3, r4, c, * r1, r2, r3, r4, c,
* v555, // B+ voltage of 555 * v_pos, - B+ voltage of 555
* v555high, // High output voltage of 555 (Usually v555 - 1.2V) * v_out_high, - High output voltage of 555 (Defaults to v_pos - 1.2V)
* threshold555, // normally 2/3 of v555 * }
* trigger555} // normally 1/3 of v555 *
* The last option of discrete_555_vco1_desc can use the following default:
* DEFAULT_555_HIGH - to use the normal output voltage based on v_pos
* *
* Notes: The value of resistor rX is not needed. It is just a pull-up * Notes: The value of resistor rX is not needed. It is just a pull-up
* for the discharge output. * for the discharge output.
@ -3543,15 +3624,15 @@ typedef struct _discrete_mixer_desc discrete_mixer_desc;
struct _discrete_mixer_desc struct _discrete_mixer_desc
{ {
int type; int type;
double r[DISC_MAX_MIXER_INPUTS]; // static input resistance values. These are in series with rNode, if used. double r[DISC_MAX_MIXER_INPUTS]; /* static input resistance values. These are in series with rNode, if used. */
int rNode[DISC_MAX_MIXER_INPUTS]; // variable resistance nodes, if needed. 0 if not used. int r_node[DISC_MAX_MIXER_INPUTS]; /* variable resistance nodes, if needed. 0 if not used. */
double c[DISC_MAX_MIXER_INPUTS]; double c[DISC_MAX_MIXER_INPUTS];
double rI; double rI;
double rF; double rF;
double cF; double cF;
double cAmp; double cAmp;
double vRef; double vRef;
double gain; // Scale value to get output close to +/- 32767 double gain; /* Scale value to get output close to +/- 32767 */
}; };
@ -3632,44 +3713,40 @@ struct _discrete_op_amp_filt_info
}; };
#define DEFAULT_555_CHARGE -1
#define DEFAULT_555_HIGH -1 #define DEFAULT_555_HIGH -1
#define DEFAULT_555_THRESHOLD -1 #define DEFAULT_555_VALUES DEFAULT_555_CHARGE, DEFAULT_555_HIGH
#define DEFAULT_555_TRIGGER -1
#define DEFAULT_555_VALUES DEFAULT_555_HIGH, DEFAULT_555_THRESHOLD, DEFAULT_555_TRIGGER
typedef struct _discrete_555_desc discrete_555_desc; typedef struct _discrete_555_desc discrete_555_desc;
struct _discrete_555_desc struct _discrete_555_desc
{ {
int options; // bit mapped options int options; /* bit mapped options */
double v555; // B+ voltage of 555 double v_pos; /* B+ voltage of 555 */
double v555high; // High output voltage of 555 (Usually v555 - 1.2V) double v_charge; /* voltage to charge circuit (Defaults to v_pos) */
double threshold555; // normally 2/3 of v555 double v_out_high; /* High output voltage of 555 (Defaults to v_pos - 1.2V) */
double trigger555; // normally 1/3 of v555
}; };
#define DEFAULT_555_CC_SOURCE DEFAULT_555_CHARGE
typedef struct _discrete_555_cc_desc discrete_555_cc_desc; typedef struct _discrete_555_cc_desc discrete_555_cc_desc;
struct _discrete_555_cc_desc struct _discrete_555_cc_desc
{ {
int options; // bit mapped options int options; /* bit mapped options */
double v555; // B+ voltage of 555 double v_pos; /* B+ voltage of 555 */
double v555high; // High output voltage of 555 (Usually v555 - 1.2V) double v_cc_source; /* Voltage of the Constant Current source */
double threshold555; // normally 2/3 of v555 double v_out_high; /* High output voltage of 555 (Defaults to v_pos - 1.2V) */
double trigger555; // normally 1/3 of v555 double v_cc_junction; /* The voltage drop of the Constant Current source transitor (0 if Op Amp) */
double vCCsource; // B+ voltage of the Constant Current source
double vCCjunction; // The voltage drop of the Constant Current source transitor (0 if Op Amp)
}; };
typedef struct _discrete_555_vco1_desc discrete_555_vco1_desc; typedef struct _discrete_555_vco1_desc discrete_555_vco1_desc;
struct _discrete_555_vco1_desc struct _discrete_555_vco1_desc
{ {
int options; // bit mapped options int options; /* bit mapped options */
double r1, r2, r3, r4, c; double r1, r2, r3, r4, c;
double v555; // B+ voltage of 555 double v_pos; /* B+ voltage of 555 */
double v555high; // High output voltage of 555 (Usually v555 - 1.2V) double v_charge; /* (ignored) */
double threshold555; // normally 2/3 of v555 double v_out_high; /* High output voltage of 555 (Defaults to v_pos - 1.2V) */
double trigger555; // normally 1/3 of v555
}; };
@ -3958,7 +4035,7 @@ enum
/* from disc_wav.c */ /* from disc_wav.c */
/* generic modules */ /* generic modules */
#define DISCRETE_COUNTER(NODE,ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE) { NODE, DSS_COUNTER , 7, { ENAB,RESET,CLK,NODE_NC,DIR,INIT0,NODE_NC }, { ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE }, NULL, "DISCRETE_COUNTER" }, #define DISCRETE_COUNTER(NODE,ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE) { NODE, DSS_COUNTER , 7, { ENAB,RESET,CLK,NODE_NC,DIR,INIT0,NODE_NC }, { ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE }, NULL, "DISCRETE_COUNTER" },
#define DISCRETE_COUNTER_7492(NODE,ENAB,RESET,CLK) { NODE, DSS_COUNTER , 7, { ENAB,RESET,CLK,NODE_NC,NODE_NC,NODE_NC,NODE_NC }, { ENAB,RESET,CLK,5,1,0,DISC_COUNTER_IS_7492 }, NULL, "DISCRETE_COUNTER_7492" }, #define DISCRETE_COUNTER_7492(NODE,ENAB,RESET,CLK,CLKTYPE) { NODE, DSS_COUNTER , 7, { ENAB,RESET,CLK,NODE_NC,NODE_NC,NODE_NC,NODE_NC }, { ENAB,RESET,CLK,CLKTYPE,1,0,DISC_COUNTER_IS_7492 }, NULL, "DISCRETE_COUNTER_7492" },
#define DISCRETE_LFSR_NOISE(NODE,ENAB,RESET,CLK,AMPL,FEED,BIAS,LFSRTB) { NODE, DSS_LFSR_NOISE , 6, { ENAB,RESET,CLK,AMPL,FEED,BIAS }, { ENAB,RESET,CLK,AMPL,FEED,BIAS }, LFSRTB, "LFSR Noise Source" }, #define DISCRETE_LFSR_NOISE(NODE,ENAB,RESET,CLK,AMPL,FEED,BIAS,LFSRTB) { NODE, DSS_LFSR_NOISE , 6, { ENAB,RESET,CLK,AMPL,FEED,BIAS }, { ENAB,RESET,CLK,AMPL,FEED,BIAS }, LFSRTB, "LFSR Noise Source" },
#define DISCRETE_NOISE(NODE,ENAB,FREQ,AMPL,BIAS) { NODE, DSS_NOISE , 4, { ENAB,FREQ,AMPL,BIAS }, { ENAB,FREQ,AMPL,BIAS }, NULL, "Noise Source" }, #define DISCRETE_NOISE(NODE,ENAB,FREQ,AMPL,BIAS) { NODE, DSS_NOISE , 4, { ENAB,FREQ,AMPL,BIAS }, { ENAB,FREQ,AMPL,BIAS }, NULL, "Noise Source" },
#define DISCRETE_NOTE(NODE,ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE) { NODE, DSS_NOTE , 6, { ENAB,CLK,DATA,NODE_NC,NODE_NC,NODE_NC }, { ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE }, NULL, "Note Generator" }, #define DISCRETE_NOTE(NODE,ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE) { NODE, DSS_NOTE , 6, { ENAB,CLK,DATA,NODE_NC,NODE_NC,NODE_NC }, { ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE }, NULL, "Note Generator" },
@ -4079,6 +4156,8 @@ enum
#define DISCRETE_555_VCO1_CV(NODE,RESET,VIN,CTRLV,OPTIONS) { NODE, DSD_555_VCO1 , 3, { RESET,VIN,CTRLV }, { RESET,VIN,CTRLV }, OPTIONS, "555 VCO1 with CV - Op-Amp type" }, #define DISCRETE_555_VCO1_CV(NODE,RESET,VIN,CTRLV,OPTIONS) { NODE, DSD_555_VCO1 , 3, { RESET,VIN,CTRLV }, { RESET,VIN,CTRLV }, OPTIONS, "555 VCO1 with CV - Op-Amp type" },
#define DISCRETE_566(NODE,ENAB,VMOD,R,C,OPTIONS) { NODE, DSD_566 , 4, { ENAB,VMOD,R,C }, { ENAB,VMOD,R,C }, OPTIONS, "566" }, #define DISCRETE_566(NODE,ENAB,VMOD,R,C,OPTIONS) { NODE, DSD_566 , 4, { ENAB,VMOD,R,C }, { ENAB,VMOD,R,C }, OPTIONS, "566" },
#define DISCRETE_74LS624(NODE,ENAB,VMOD,VRNG,C,OUTTYPE) { NODE, DSD_LS624 , 5, { ENAB,VMOD,VRNG,C,NODE_NC }, { ENAB,VMOD,VRNG,C, OUTTYPE }, NULL, "74LS624" }, #define DISCRETE_74LS624(NODE,ENAB,VMOD,VRNG,C,OUTTYPE) { NODE, DSD_LS624 , 5, { ENAB,VMOD,VRNG,C,NODE_NC }, { ENAB,VMOD,VRNG,C, OUTTYPE }, NULL, "74LS624" },
/* logging */
#define DISCRETE_CSVLOG1(NODE1) { NODE_SPECIAL, DSO_CSVLOG , 1, { NODE1 }, { NODE1 }, NULL, "CSV Log 1 Node" }, #define DISCRETE_CSVLOG1(NODE1) { NODE_SPECIAL, DSO_CSVLOG , 1, { NODE1 }, { NODE1 }, NULL, "CSV Log 1 Node" },
#define DISCRETE_CSVLOG2(NODE1,NODE2) { NODE_SPECIAL, DSO_CSVLOG , 2, { NODE1,NODE2 }, { NODE1,NODE2 }, NULL, "CSV Log 2 Nodes" }, #define DISCRETE_CSVLOG2(NODE1,NODE2) { NODE_SPECIAL, DSO_CSVLOG , 2, { NODE1,NODE2 }, { NODE1,NODE2 }, NULL, "CSV Log 2 Nodes" },
#define DISCRETE_CSVLOG3(NODE1,NODE2,NODE3) { NODE_SPECIAL, DSO_CSVLOG , 3, { NODE1,NODE2,NODE3 }, { NODE1,NODE2,NODE3 }, NULL, "CSV Log 3 Nodes" }, #define DISCRETE_CSVLOG3(NODE1,NODE2,NODE3) { NODE_SPECIAL, DSO_CSVLOG , 3, { NODE1,NODE2,NODE3 }, { NODE1,NODE2,NODE3 }, NULL, "CSV Log 3 Nodes" },
@ -4086,6 +4165,7 @@ enum
#define DISCRETE_CSVLOG5(NODE1,NODE2,NODE3,NODE4,NODE5) { NODE_SPECIAL, DSO_CSVLOG , 5, { NODE1,NODE2,NODE3,NODE4,NODE5 }, { NODE1,NODE2,NODE3,NODE4,NODE5 }, NULL, "CSV Log 5 Nodes" }, #define DISCRETE_CSVLOG5(NODE1,NODE2,NODE3,NODE4,NODE5) { NODE_SPECIAL, DSO_CSVLOG , 5, { NODE1,NODE2,NODE3,NODE4,NODE5 }, { NODE1,NODE2,NODE3,NODE4,NODE5 }, NULL, "CSV Log 5 Nodes" },
#define DISCRETE_WAVELOG1(NODE1,GAIN1) { NODE_SPECIAL, DSO_WAVELOG , 2, { NODE1,NODE_NC }, { NODE1,GAIN1 }, NULL, "Wave Log 1 Node" }, #define DISCRETE_WAVELOG1(NODE1,GAIN1) { NODE_SPECIAL, DSO_WAVELOG , 2, { NODE1,NODE_NC }, { NODE1,GAIN1 }, NULL, "Wave Log 1 Node" },
#define DISCRETE_WAVELOG2(NODE1,GAIN1,NODE2,GAIN2) { NODE_SPECIAL, DSO_WAVELOG , 4, { NODE1,NODE_NC,NODE2,NODE_NC }, { NODE1,GAIN1,NODE2,GAIN2 }, NULL, "Wave Log 2 Nodes" }, #define DISCRETE_WAVELOG2(NODE1,GAIN1,NODE2,GAIN2) { NODE_SPECIAL, DSO_WAVELOG , 4, { NODE1,NODE_NC,NODE2,NODE_NC }, { NODE1,GAIN1,NODE2,GAIN2 }, NULL, "Wave Log 2 Nodes" },
/* output */
#define DISCRETE_OUTPUT(OPNODE,GAIN) { NODE_SPECIAL, DSO_OUTPUT , 2, { OPNODE,NODE_NC }, { 0,GAIN }, NULL, "Output Node" }, #define DISCRETE_OUTPUT(OPNODE,GAIN) { NODE_SPECIAL, DSO_OUTPUT , 2, { OPNODE,NODE_NC }, { 0,GAIN }, NULL, "Output Node" },

View File

@ -44,7 +44,6 @@ static const discrete_555_cc_desc asteroid_thump_555cc =
DISC_555_OUT_SQW | DISC_555_OUT_AC | DISCRETE_555_CC_TO_CAP, DISC_555_OUT_SQW | DISC_555_OUT_AC | DISCRETE_555_CC_TO_CAP,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.8 // VBE 2N3906 (Si) 0.8 // VBE 2N3906 (Si)
}; };

View File

@ -95,14 +95,14 @@ static const discrete_mixer_desc crash_mixer =
static const discrete_555_desc crash_beeper_555m = static const discrete_555_desc crash_beeper_555m =
{ {
DISC_555_TRIGGER_IS_LOGIC | DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_SQW | DISC_555_OUT_DC | DISC_555_TRIGGER_IS_LOGIC,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES DEFAULT_555_VALUES
}; };
static const discrete_555_desc crash_beeper_555a = static const discrete_555_desc crash_beeper_555a =
{ {
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_SQW | DISC_555_OUT_DC,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES DEFAULT_555_VALUES
}; };

View File

@ -201,27 +201,32 @@ static const discrete_lfsr_desc dkong_lfsr =
}; };
static const discrete_mixer_desc dkong_rc_jump_desc = static const discrete_mixer_desc dkong_rc_jump_desc =
{DISC_MIXER_IS_RESISTOR, {
DISC_MIXER_IS_RESISTOR,
{1, DK_R49+DK_R51,NE555_INTERNAL_R,2*NE555_INTERNAL_R}, {1, DK_R49+DK_R51,NE555_INTERNAL_R,2*NE555_INTERNAL_R},
{NODE_26,0,0,0}, {NODE_26,0,0,0},
{0,0,0,0}, // no node capacitors {0,0,0,0}, // no node capacitors
0, 0, 0, 0,
DK_C24, DK_C24,
0, 0,
0, 1}; 0, 1
};
static const discrete_mixer_desc dkong_rc_walk_desc = static const discrete_mixer_desc dkong_rc_walk_desc =
{DISC_MIXER_IS_RESISTOR, {
DISC_MIXER_IS_RESISTOR,
{1, DK_R45+DK_R44,NE555_INTERNAL_R,2*NE555_INTERNAL_R}, {1, DK_R45+DK_R44,NE555_INTERNAL_R,2*NE555_INTERNAL_R},
{NODE_52,0,0,0}, {NODE_52,0,0,0},
{0,0,0,0}, // no node capacitors {0,0,0,0}, // no node capacitors
0, 0, 0, 0,
DK_C29, DK_C29,
0, 0,
0, 1}; 0, 1
};
static const discrete_mixer_desc dkong_mixer_desc = static const discrete_mixer_desc dkong_mixer_desc =
{DISC_MIXER_IS_RESISTOR, {
DISC_MIXER_IS_RESISTOR,
{DK_R2, DK_R24, DK_R1, DK_R14}, {DK_R2, DK_R24, DK_R1, DK_R14},
{0,0,0}, // no variable resistors {0,0,0}, // no variable resistors
{0,0,0}, // no node capacitors {0,0,0}, // no node capacitors
@ -232,29 +237,35 @@ static const discrete_mixer_desc dkong_mixer_desc =
#endif #endif
DK_C159, DK_C159,
DK_C12, DK_C12,
0, 1}; 0, 1
};
/* There is no load on the output for the jump circuit /* There is no load on the output for the jump circuit
* For the walk circuit, the voltage does not matter */ * For the walk circuit, the voltage does not matter */
static const discrete_555_desc dkong_555_vco_desc = static const discrete_555_desc dkong_555_vco_desc =
{DISC_555_OUT_DC | DISC_555_OUT_ENERGY, {
DISC_555_OUT_ENERGY | DISC_555_OUT_DC,
DK_SUP_V, DK_SUP_V,
DK_SUP_V-0.5,DK_SUP_V*0.66,DK_SUP_V*0.33 DEFAULT_555_CHARGE,
DK_SUP_V - 0.5
}; };
static const discrete_inverter_osc_desc dkong_inverter_osc_desc_jump = static const discrete_inverter_osc_desc dkong_inverter_osc_desc_jump =
{DEFAULT_CD40XX_VALUES(DK_SUP_V), {
DEFAULT_CD40XX_VALUES(DK_SUP_V),
DISC_OSC_INVERTER_IS_TYPE1 DISC_OSC_INVERTER_IS_TYPE1
}; };
static const discrete_inverter_osc_desc dkong_inverter_osc_desc_walk = static const discrete_inverter_osc_desc dkong_inverter_osc_desc_walk =
{DEFAULT_CD40XX_VALUES(DK_SUP_V), {
DEFAULT_CD40XX_VALUES(DK_SUP_V),
DISC_OSC_INVERTER_IS_TYPE2 DISC_OSC_INVERTER_IS_TYPE2
}; };
static const discrete_op_amp_filt_info dkong_sallen_key_info = static const discrete_op_amp_filt_info dkong_sallen_key_info =
{ RES_K(5.6), RES_K(5.6), 0, 0, 0, {
RES_K(5.6), RES_K(5.6), 0, 0, 0,
CAP_N(22), CAP_N(10), 0 CAP_N(22), CAP_N(10), 0
}; };
@ -502,11 +513,7 @@ static const discrete_mixer_desc radarscp_mixer_desc_7 =
/* There is no load on the output for the jump circuit /* There is no load on the output for the jump circuit
* For the walk circuit, the voltage does not matter */ * For the walk circuit, the voltage does not matter */
static const discrete_555_desc radarscp_555_vco_desc = #define radarscp_555_vco_desc dkong_555_vco_desc
{DISC_555_OUT_DC | DISC_555_OUT_ENERGY,
DK_SUP_V,
DK_SUP_V-0.5,DK_SUP_V*0.66,DK_SUP_V*0.33
};
static const discrete_inverter_osc_desc radarscp_inverter_osc_desc_0 = static const discrete_inverter_osc_desc radarscp_inverter_osc_desc_0 =
{DEFAULT_CD40XX_VALUES(DK_SUP_V), {DEFAULT_CD40XX_VALUES(DK_SUP_V),

View File

@ -110,7 +110,6 @@ static const discrete_555_cc_desc firetrk_motor_vco =
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_DC | DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // Q2 junction voltage 0.7 // Q2 junction voltage
}; };
@ -222,7 +221,7 @@ DISCRETE_SOUND_START(firetrk)
RES_M(1), 0, 0, // R28, no rGnd, no rDis RES_M(1), 0, 0, // R28, no rGnd, no rDis
&firetrk_motor_vco) &firetrk_motor_vco)
DISCRETE_COUNTER_7492(NODE_23, 1, FIRETRUCK_ATTRACT_EN, // IC A9, QB-QD DISCRETE_COUNTER_7492(NODE_23, 1, FIRETRUCK_ATTRACT_EN, // IC A9, QB-QD
NODE_22) // from IC B9, pin 3 NODE_22, DISC_CLK_ON_F_EDGE) // from IC B9, pin 3
DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 0x04, "01&") // IC A9, pin 8 DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 0x04, "01&") // IC A9, pin 8
DISCRETE_COUNTER(NODE_25, 1, FIRETRUCK_ATTRACT_EN, // IC A9, pin 12 DISCRETE_COUNTER(NODE_25, 1, FIRETRUCK_ATTRACT_EN, // IC A9, pin 12
NODE_24, // from IC A9, pin 8 NODE_24, // from IC A9, pin 8
@ -337,7 +336,6 @@ static const discrete_555_cc_desc superbug_motor_vco =
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_DC | DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // Q1 junction voltage 0.7 // Q1 junction voltage
}; };
@ -426,7 +424,7 @@ DISCRETE_SOUND_START(superbug)
RES_M(3.3), 0, 0, // R11, no rGnd, no rDis RES_M(3.3), 0, 0, // R11, no rGnd, no rDis
&superbug_motor_vco) &superbug_motor_vco)
DISCRETE_COUNTER_7492(NODE_23, 1, SUPERBUG_ATTRACT_EN, // IC A7, QB-QD DISCRETE_COUNTER_7492(NODE_23, 1, SUPERBUG_ATTRACT_EN, // IC A7, QB-QD
NODE_22) // from IC A6, pin 3 NODE_22, DISC_CLK_ON_F_EDGE) // from IC A6, pin 3
DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 0x04, "01&") // IC A7, pin 8-QD DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 0x04, "01&") // IC A7, pin 8-QD
DISCRETE_TRANSFORM2(NODE_25, 1, NODE_23, 0x01, "01&") // IC A7, pin 11-QB DISCRETE_TRANSFORM2(NODE_25, 1, NODE_23, 0x01, "01&") // IC A7, pin 11-QB
DISCRETE_LOGIC_XOR(NODE_26, 1, NODE_24, NODE_25) // Gate A9, pin 8 DISCRETE_LOGIC_XOR(NODE_26, 1, NODE_24, NODE_25) // Gate A9, pin 8
@ -498,7 +496,6 @@ static const discrete_555_cc_desc montecar_motor_vco =
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_DC | DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // Q1 junction voltage 0.7 // Q1 junction voltage
}; };
@ -611,7 +608,7 @@ DISCRETE_SOUND_START(montecar)
RES_M(1), 0, 0, // R86, no rGnd, no rDis RES_M(1), 0, 0, // R86, no rGnd, no rDis
&montecar_motor_vco) &montecar_motor_vco)
DISCRETE_COUNTER_7492(NODE_23, 1, MONTECAR_ATTRACT_EN, // IC B/C9, QB-QD DISCRETE_COUNTER_7492(NODE_23, 1, MONTECAR_ATTRACT_EN, // IC B/C9, QB-QD
NODE_22) // from IC C9, pin 9 NODE_22, DISC_CLK_ON_F_EDGE) // from IC C9, pin 9
DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 0x04, "01&") // IC B/C9, pin 8-QD DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 0x04, "01&") // IC B/C9, pin 8-QD
DISCRETE_TRANSFORM2(NODE_25, 1, NODE_23, 0x01, "01&") // IC B/C9, pin 11-QB DISCRETE_TRANSFORM2(NODE_25, 1, NODE_23, 0x01, "01&") // IC B/C9, pin 11-QB
DISCRETE_LOGIC_XOR(NODE_26, 1, NODE_24, NODE_25) // Gate A9, pin 11 DISCRETE_LOGIC_XOR(NODE_26, 1, NODE_24, NODE_25) // Gate A9, pin 11
@ -646,7 +643,7 @@ DISCRETE_SOUND_START(montecar)
RES_M(1), 0, 0, // R81, no rGnd, no rDis RES_M(1), 0, 0, // R81, no rGnd, no rDis
&montecar_motor_vco) &montecar_motor_vco)
DISCRETE_COUNTER_7492(NODE_43, 1, MONTECAR_ATTRACT_EN, // IC A/B9, QB-QD DISCRETE_COUNTER_7492(NODE_43, 1, MONTECAR_ATTRACT_EN, // IC A/B9, QB-QD
NODE_42) // from IC C9, pin 5 NODE_42, DISC_CLK_ON_F_EDGE) // from IC C9, pin 5
DISCRETE_TRANSFORM2(NODE_44, 1, NODE_43, 0x04, "01&") // IC A/B9, pin 8-QD DISCRETE_TRANSFORM2(NODE_44, 1, NODE_43, 0x04, "01&") // IC A/B9, pin 8-QD
DISCRETE_TRANSFORM2(NODE_45, 1, NODE_43, 0x01, "01&") // IC A/B9, pin 11-QB DISCRETE_TRANSFORM2(NODE_45, 1, NODE_43, 0x01, "01&") // IC A/B9, pin 11-QB
DISCRETE_LOGIC_XOR(NODE_46, 1, NODE_44, NODE_45) // Gate A9, pin 6 DISCRETE_LOGIC_XOR(NODE_46, 1, NODE_44, NODE_45) // Gate A9, pin 6

View File

@ -3151,10 +3151,9 @@ static const discrete_comp_adder_table invaders_thump_resistors =
static const discrete_555_desc invaders_thump_555 = static const discrete_555_desc invaders_thump_555 =
{ {
DISC_555_OUT_ENERGY | DISC_555_OUT_DC, DISC_555_OUT_ENERGY | DISC_555_OUT_DC,
5,
5.0 - 0.6, /* 5V - diode drop */ 5.0 - 0.6, /* 5V - diode drop */
DEFAULT_TTL_V_LOGIC_1, /* Output of F3 7411 buffer */ DEFAULT_TTL_V_LOGIC_1 /* Output of F3 7411 buffer */
DEFAULT_555_THRESHOLD,
DEFAULT_555_TRIGGER
}; };
@ -3708,8 +3707,8 @@ static const discrete_555_desc blueshrk_555_H1B =
{ {
DISC_555_OUT_ENERGY | DISC_555_OUT_DC, DISC_555_OUT_ENERGY | DISC_555_OUT_DC,
5, /* B+ voltage of 555 */ 5, /* B+ voltage of 555 */
12, /* the OC buffer H2 converts the output voltage to 12V. */ DEFAULT_555_CHARGE,
DEFAULT_555_THRESHOLD, DEFAULT_555_TRIGGER 12 /* the OC buffer H2 converts the output voltage to 12V. */
}; };

View File

@ -238,7 +238,8 @@ static const discrete_555_desc phoenix_effect2_555 =
{ {
DISC_555_OUT_ENERGY, DISC_555_OUT_ENERGY,
5, // B+ voltage of 555 5, // B+ voltage of 555
4.0, DEFAULT_555_THRESHOLD, DEFAULT_555_TRIGGER DEFAULT_555_CHARGE,
4.0 // loaded output voltage
}; };
static const discrete_comp_adder_table phoenix_effect2_cap_sel = static const discrete_comp_adder_table phoenix_effect2_cap_sel =
@ -335,52 +336,145 @@ DISCRETE_SOUND_START(phoenix)
/* - level 5 spaceship */ /* - level 5 spaceship */
/************************************************/ /************************************************/
/* R22 has been confirmed on real boards as 470 ohm, not 47k in schematics */ /* R22 has been confirmed on real boards as 470 ohm, not 47k in schematics */
DISCRETE_RCDISC4(NODE_20, 1, PHOENIX_EFFECT_1_FREQ, 470, RES_K(100), RES_K(33), CAP_U(6.8), 12, 1) // R22, R23, R24, C7 DISCRETE_RCDISC4(NODE_20, /* IC52 output pin 7 */
DISCRETE_555_ASTABLE_CV(NODE_21, 1, RES_K(47), RES_K(47), CAP_U(.001), NODE_20, &phoenix_effect1_555) // R25, R26, C8 1, /* ENAB */
PHOENIX_EFFECT_1_FREQ, /* Input to O.C. inverter */
470, /* R22 */
RES_K(100), /* R23 */
RES_K(33), /* R24 */
CAP_U(6.8), /* C7 */
12, /* 12V supply */
1) /* Circuit type 1 */
DISCRETE_555_ASTABLE_CV(NODE_21, /* IC20 pin 6 */
1, /* ENAB */
RES_K(47), /* R25 */
RES_K(47), /* R26 */
CAP_U(.001), /* C8 */
NODE_20, /* IC48 pin 5 input */
&phoenix_effect1_555)
/* LS163 counts rising edge, but the LS14 inverts that */ /* LS163 counts rising edge, but the LS14 inverts that */
DISCRETE_NOTE(NODE_22, 1, NODE_21, PHOENIX_EFFECT_1_DATA, 0x0f, 1, DISC_CLK_BY_COUNT | DISC_OUT_IS_ENERGY) DISCRETE_NOTE(NODE_22, /* IC21 pin 5 output */
1, /* ENAB */
NODE_21, /* IC13 pin 2 clock input */
PHOENIX_EFFECT_1_DATA, /* Pre-load data */
0x0f, /* Maximum count of first counter 0-15 (IC13) */
1, /* Maximum count of second counter 0-1 (IC21) */
DISC_CLK_BY_COUNT | DISC_OUT_IS_ENERGY) /* Module is clocked externally and we anti-alias output */
/* When FILT is enabled, the effect is filtered. /* When FILT is enabled, the effect is filtered.
* While the R20 does decrease the amplitude a little, its main purpose * While the R20 does decrease the amplitude a little, its main purpose
* is to discharge C5 when the filter is disabled. */ * is to discharge C5 when the filter is disabled. */
DISCRETE_SWITCH(NODE_23, 1, PHOENIX_EFFECT_1_FILT, DEFAULT_TTL_V_LOGIC_1, DEFAULT_TTL_V_LOGIC_1 * RES_K(100) / (RES_K(10) + RES_K(100))) // R20, R19 DISCRETE_SWITCH(NODE_23,
DISCRETE_MULTIPLY(NODE_24, 1, NODE_22, NODE_23) 1, /* ENAB */
DISCRETE_RCFILTER(NODE_25, 1, NODE_24, 1.0/(1.0/RES_K(10) + 1.0/RES_K(100)), CAP_U(.047)) // R19, R20, C5 PHOENIX_EFFECT_1_FILT,
DISCRETE_SWITCH(PHOENIX_EFFECT_1_SND, 1, PHOENIX_EFFECT_1_FILT, NODE_24, NODE_25) DEFAULT_TTL_V_LOGIC_1,
DEFAULT_TTL_V_LOGIC_1 * RES_K(100) / (RES_K(10) + RES_K(100))) /* R20, R19 */
DISCRETE_MULTIPLY(NODE_24,
1, /* ENAB */
NODE_22,
NODE_23)
DISCRETE_RCFILTER(NODE_25,
1,
NODE_24,
1.0/(1.0/RES_K(10) + 1.0/RES_K(100)), /* R19, R20 */
CAP_U(.047)) /* C5 */
DISCRETE_SWITCH(PHOENIX_EFFECT_1_SND,
1, /* ENAB */
PHOENIX_EFFECT_1_FILT,
NODE_24, /* non-filtered */
NODE_25) /* filtered */
/************************************************/ /************************************************/
/* Effect 2 */ /* Effect 2 */
/* - bird flying, bird/phoenix/spaceship hit */ /* - bird flying, bird/phoenix/spaceship hit */
/* - phoenix wing hit */ /* - phoenix wing hit */
/************************************************/ /************************************************/
DISCRETE_COMP_ADDER(NODE_30, 1, PHOENIX_EFFECT_2_FREQ, &phoenix_effect2_cap_sel) DISCRETE_COMP_ADDER(NODE_30, /* total capacitance of selected capacitors */
1, /* ENAB */
PHOENIX_EFFECT_2_FREQ, /* passed selection bits */
&phoenix_effect2_cap_sel)
/* Part of the frequency select also effects the gain */ /* Part of the frequency select also effects the gain */
DISCRETE_TRANSFORM2(NODE_31, 1, PHOENIX_EFFECT_2_FREQ, 2, "01&1/") // get bit 0x02 DISCRETE_TRANSFORM2(NODE_31, /* 0/1 state of PHOENIX_EFFECT_2_FREQ high bit */
DISCRETE_SWITCH(NODE_32, 1, NODE_31, DEFAULT_TTL_V_LOGIC_1, DEFAULT_TTL_V_LOGIC_1/2) 1, /* ENAB */
DISCRETE_555_ASTABLE(NODE_33, 1, RES_K(47), RES_K(100), NODE_30, &phoenix_effect2_555) // R40, R41 PHOENIX_EFFECT_2_FREQ, 2, "01&1/") // get bit 0x02
DISCRETE_SWITCH(NODE_32, /* voltage level */
1, /* ENAB */
NODE_31, /* PHOENIX_EFFECT_2_FREQ high bit determines voltage level */
DEFAULT_TTL_V_LOGIC_1,
DEFAULT_TTL_V_LOGIC_1 / 2)
DISCRETE_555_ASTABLE(NODE_33, /* pin 3 output of IC44 */
1, /* ENAB */
RES_K(47), /* R40 */
RES_K(100), /* R41 */
NODE_30, /* C16, C17, C18 combined */
&phoenix_effect2_555)
/* C20 has been confirmed on real boards as 1uF, not 10uF in schematics */ /* C20 has been confirmed on real boards as 1uF, not 10uF in schematics */
DISCRETE_555_ASTABLE(NODE_34, 1, RES_K(510), RES_K(510), CAP_U(1), &phoenix_effect2_555) // R23, R24, C20 DISCRETE_555_ASTABLE(NODE_34, /* pin 3 output of IC51 */
1, /* ENAB */
RES_K(510), /* R23 */
RES_K(510), /* R24 */
CAP_U(1), /* C20 */
&phoenix_effect2_555)
/* R45 & R46 have been confirmed on real boards as 5.1k, not 51k in schematics */ /* R45 & R46 have been confirmed on real boards as 5.1k, not 51k in schematics */
/* We need to work backwards here and calculate the voltage at the junction of R42 & R46 */ /* We need to work backwards here and calculate the voltage at the junction of R42 & R46 */
/* If you remove C22 from the real PCB, you can WAVELOG NODE_35 with a gain of 1000 and compare /* If you remove C22 from the real PCB, you can WAVELOG NODE_35 with a gain of 1000 and compare
* it against the junction of R42 & R46 on a real PCB. */ * it against the junction of R42 & R46 on a real PCB. */
DISCRETE_MIXER3(NODE_35, 1, NODE_33, NODE_34, 5, &phoenix_effect2_mixer1) DISCRETE_MIXER3(NODE_35, /* Voltage at junction of R42 & R46 with C22 removed */
1, /* ENAB */
NODE_33, /* output from IC44 */
NODE_34, /* output from IC51 */
5, /* B+ connected internally to pin 5 of 555 */
&phoenix_effect2_mixer1)
/* Then calculate the voltage going to C22 */ /* Then calculate the voltage going to C22 */
/* If you remove C22 from the real PCB, you can WAVELOG NODE_36 with a gain of 1000 and compare /* If you remove C22 from the real PCB, you can WAVELOG NODE_36 with a gain of 1000 and compare
* it against the junction of R45 & R46 on a real PCB. */ * it against the junction of R45 & R46 on a real PCB. */
DISCRETE_MIXER2(NODE_36, 1, NODE_34, NODE_35, &phoenix_effect2_mixer2) DISCRETE_MIXER2(NODE_36, /* Voltage at junction of R45 & R46 with C22 removed */
1, /* ENAB */
NODE_34, /* pin 3 output of IC51 */
NODE_35, /* Voltage at junction of R42 & R46 with C22 removed */
&phoenix_effect2_mixer2)
/* C22 charging is R45 in parallel with R46, R42 and the 555 CV internal resistance */ /* C22 charging is R45 in parallel with R46, R42 and the 555 CV internal resistance */
DISCRETE_RCFILTER(NODE_37, 1, NODE_36, 1.0/ (1.0/RES_K(5.1) + (1.0/(RES_K(5.1) + 1.0/(1.0/RES_K(10) + 1.0/RES_K(5) + 1.0/RES_K(10)) ))), CAP_U(100)) // R45, R46, R42, internal 555 Rs, C22 DISCRETE_RCFILTER(NODE_37,
1, /* ENAB */
NODE_36,
1.0/ (1.0/RES_K(5.1) + (1.0/(RES_K(5.1) + 1.0/(1.0/RES_K(10) + 1.0/RES_K(5) + 1.0/RES_K(10)) ))),
CAP_U(100)) /* R45, R46, R42, internal 555 Rs, C22 */
/* Now mix from C22 on */ /* Now mix from C22 on */
/* You can WAVELOG NODE_38 with a gain of 1000 and compare it against IC50 pin 5 on a real PCB. */ /* You can WAVELOG NODE_38 with a gain of 1000 and compare it against IC50 pin 5 on a real PCB. */
DISCRETE_MIXER3(NODE_38, 1, NODE_33, NODE_37, 5, &phoenix_effect2_mixer3) DISCRETE_MIXER3(NODE_38, /* control voltage to pin 5 of IC50 */
DISCRETE_555_ASTABLE_CV(NODE_39, 1, RES_K(20), RES_K(20), CAP_U(0.001), NODE_38, &phoenix_effect1_555) // R47, R48, C23 1, /* ENAB */
DISCRETE_NOTE(NODE_40, 1, NODE_39, PHOENIX_EFFECT_2_DATA, 0x0f, 1, DISC_CLK_BY_COUNT | DISC_OUT_IS_ENERGY) NODE_33, /* pin 3 output of IC44 */
DISCRETE_MULTIPLY(PHOENIX_EFFECT_2_SND, 1, NODE_40, NODE_32) NODE_37, /* voltage on C22 */
5, /* IC50 internally connected to B+ */
&phoenix_effect2_mixer3)
DISCRETE_555_ASTABLE_CV(NODE_39, /* IC20 pin 8 output */
1, /* ENAB */
RES_K(20), /* R47 */
RES_K(20), /* R48 */
CAP_U(0.001), /* C23 */
NODE_38, /* IC50 pin 5 input */
&phoenix_effect1_555)
DISCRETE_NOTE(NODE_40, /* IC21 pin 9 output */
1, /* ENAB */
NODE_39, /* IC14 pin 2 clock input */
PHOENIX_EFFECT_2_DATA, /* Pre-load data */
0x0f, /* Maximum count of first counter 0-15 (IC14) */
1, /* Maximum count of second counter 0-1 (IC21) */
DISC_CLK_BY_COUNT | DISC_OUT_IS_ENERGY)
DISCRETE_MULTIPLY(PHOENIX_EFFECT_2_SND,
1, /* ENAB */
NODE_40, /* IC21 pin 9 output */
NODE_32) /* voltage level selected by high bit of PHOENIX_EFFECT_2_FREQ */
/************************************************/ /************************************************/
/* Combine all sound sources. */ /* Combine all sound sources. */
/************************************************/ /************************************************/
DISCRETE_MIXER4(NODE_90, 1, PHOENIX_EFFECT_1_SND, PHOENIX_EFFECT_2_SND, PHOENIX_EFFECT_3_SND, PHOENIX_EFFECT_4_SND,&phoenix_mixer) DISCRETE_MIXER4(NODE_90,
1, /* ENAB */
PHOENIX_EFFECT_1_SND,
PHOENIX_EFFECT_2_SND,
PHOENIX_EFFECT_3_SND,
PHOENIX_EFFECT_4_SND,
&phoenix_mixer)
DISCRETE_OUTPUT(NODE_90, 1) DISCRETE_OUTPUT(NODE_90, 1)
DISCRETE_SOUND_END DISCRETE_SOUND_END
@ -389,9 +483,11 @@ WRITE8_HANDLER( phoenix_sound_control_a_w )
{ {
discrete_sound_w(machine, PHOENIX_EFFECT_2_DATA, data & 0x0f); discrete_sound_w(machine, PHOENIX_EFFECT_2_DATA, data & 0x0f);
discrete_sound_w(machine, PHOENIX_EFFECT_2_FREQ, (data & 0x30) >> 4); discrete_sound_w(machine, PHOENIX_EFFECT_2_FREQ, (data & 0x30) >> 4);
// discrete_sound_w(PHOENIX_EFFECT_3_EN , data & 0x40); #if 0
// discrete_sound_w(PHOENIX_EFFECT_4_EN , data & 0x80); /* future handling of noise sounds */
discrete_sound_w(PHOENIX_EFFECT_3_EN , data & 0x40);
discrete_sound_w(PHOENIX_EFFECT_4_EN , data & 0x80);
#endif
stream_update(channel); stream_update(channel);
sound_latch_a = data; sound_latch_a = data;
} }

View File

@ -26,7 +26,6 @@ static const discrete_555_cc_desc poolshrk_score_vco =
DISC_555_OUT_SQW, DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // Q3 junction voltage 0.7 // Q3 junction voltage
}; };

View File

@ -88,7 +88,7 @@ static const discrete_555_desc spiders_fire_555a =
static const discrete_555_desc spiders_super_web_555a = static const discrete_555_desc spiders_super_web_555a =
{ {
DISC_555_OUT_DC | DISC_555_OUT_CAP, DISC_555_OUT_CAP | DISC_555_OUT_DC,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES DEFAULT_555_VALUES
}; };

View File

@ -42,7 +42,6 @@ static const discrete_555_cc_desc sprint2_motor_vco =
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_DC | DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // VBE 2N3644 (Si) 0.7 // VBE 2N3644 (Si)
}; };
@ -140,7 +139,7 @@ DISCRETE_SOUND_START(sprint2)
&sprint2_motor_vco) &sprint2_motor_vco)
/* QB-D of 7492 */ /* QB-D of 7492 */
DISCRETE_COUNTER_7492(NODE_23, 1, SPRINT2_ATTRACT_EN, NODE_22) DISCRETE_COUNTER_7492(NODE_23, 1, SPRINT2_ATTRACT_EN, NODE_22, DISC_CLK_ON_F_EDGE)
/* Mask the bits and XOR for clock input */ /* Mask the bits and XOR for clock input */
DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 1, "01&") DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 1, "01&")
@ -178,7 +177,7 @@ DISCRETE_SOUND_START(sprint2)
&sprint2_motor_vco) &sprint2_motor_vco)
/* QB-D of 7492 */ /* QB-D of 7492 */
DISCRETE_COUNTER_7492(NODE_43, 1, SPRINT2_ATTRACT_EN, NODE_42) DISCRETE_COUNTER_7492(NODE_43, 1, SPRINT2_ATTRACT_EN, NODE_42, DISC_CLK_ON_F_EDGE)
/* Mask the bits and XOR for clock input */ /* Mask the bits and XOR for clock input */
DISCRETE_TRANSFORM2(NODE_44, 1, NODE_43, 1, "01&") DISCRETE_TRANSFORM2(NODE_44, 1, NODE_43, 1, "01&")
@ -263,7 +262,7 @@ DISCRETE_SOUND_START(sprint1)
&sprint2_motor_vco) &sprint2_motor_vco)
/* QB-D of 7492 */ /* QB-D of 7492 */
DISCRETE_COUNTER_7492(NODE_23, 1, SPRINT2_ATTRACT_EN, NODE_22) DISCRETE_COUNTER_7492(NODE_23, 1, SPRINT2_ATTRACT_EN, NODE_22, DISC_CLK_ON_F_EDGE)
/* Mask the bits and XOR for clock input */ /* Mask the bits and XOR for clock input */
DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 1, "01&") DISCRETE_TRANSFORM2(NODE_24, 1, NODE_23, 1, "01&")
@ -329,7 +328,6 @@ static const discrete_555_cc_desc dominos_tone_vco =
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_DC | DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // Q1 junction voltage 0.7 // Q1 junction voltage
}; };
@ -381,7 +379,7 @@ DISCRETE_SOUND_START(dominos)
DISCRETE_DAC_R1(NODE_20, 1, DOMINOS_FREQ_DATA, DEFAULT_TTL_V_LOGIC_1, &dominos_tone_vco_dac) DISCRETE_DAC_R1(NODE_20, 1, DOMINOS_FREQ_DATA, DEFAULT_TTL_V_LOGIC_1, &dominos_tone_vco_dac)
DISCRETE_555_CC(NODE_21, 1, NODE_20, DOMINOS_R23, CAP_U(.01), 0, 0, 0, &dominos_tone_vco) DISCRETE_555_CC(NODE_21, 1, NODE_20, DOMINOS_R23, CAP_U(.01), 0, 0, 0, &dominos_tone_vco)
DISCRETE_COUNTER_7492(NODE_22, 1, DOMINOS_ATTRACT_EN, // IC D8, QB-QD DISCRETE_COUNTER_7492(NODE_22, 1, DOMINOS_ATTRACT_EN, // IC D8, QB-QD
NODE_21) // from IC D7/8, pin 3 NODE_21, DISC_CLK_ON_F_EDGE) // from IC D7/8, pin 3
DISCRETE_TRANSFORM2(NODE_23, 1, NODE_22, 0x01, "01&") // IC D8, pin 11-QB DISCRETE_TRANSFORM2(NODE_23, 1, NODE_22, 0x01, "01&") // IC D8, pin 11-QB
DISCRETE_SWITCH(NODE_24, 1, NODE_23, 0, // Enable gate C5 DISCRETE_SWITCH(NODE_24, 1, NODE_23, 0, // Enable gate C5
DOMINOS_AMP_DATA) // IC C4 DOMINOS_AMP_DATA) // IC C4

View File

@ -83,7 +83,6 @@ static const discrete_555_cc_desc sprint4_motor_vco =
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_DC | DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // Q1 junction voltage 0.7 // Q1 junction voltage
}; };
@ -191,7 +190,8 @@ static const discrete_mixer_desc sprint4_mixer =
DISCRETE_COUNTER_7492(SPRINT4_PLAYER_MOTOR_NODE(4, _plr), /* IC D9, pins 11,9,8 */ \ DISCRETE_COUNTER_7492(SPRINT4_PLAYER_MOTOR_NODE(4, _plr), /* IC D9, pins 11,9,8 */ \
1, /* ENAB */ \ 1, /* ENAB */ \
SPRINT4_ATTRACT_EN, /* RESET */ \ SPRINT4_ATTRACT_EN, /* RESET */ \
SPRINT4_PLAYER_MOTOR_NODE(3, _plr)) /* CLK */ \ SPRINT4_PLAYER_MOTOR_NODE(3, _plr), /* CLK */ \
DISC_CLK_ON_F_EDGE) \
DISCRETE_TRANSFORM3(SPRINT4_PLAYER_MOTOR_NODE(5, _plr), /* IC B10, pin 3 */ \ DISCRETE_TRANSFORM3(SPRINT4_PLAYER_MOTOR_NODE(5, _plr), /* IC B10, pin 3 */ \
1, /* ENAB */ \ 1, /* ENAB */ \
SPRINT4_PLAYER_MOTOR_NODE(4, _plr), /* INP0 */ \ SPRINT4_PLAYER_MOTOR_NODE(4, _plr), /* INP0 */ \

View File

@ -65,7 +65,7 @@ static const discrete_555_desc tank8_555_a =
static const discrete_555_desc tank8_555_m = static const discrete_555_desc tank8_555_m =
{ {
DISC_555_TRIGGER_IS_VOLTAGE | DISC_555_OUT_SQW | DISC_555_OUT_DC, DISC_555_OUT_SQW | DISC_555_OUT_DC | DISC_555_TRIGGER_IS_VOLTAGE,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES DEFAULT_555_VALUES
}; };

View File

@ -77,7 +77,6 @@ static const discrete_555_cc_desc triplhnt_bear_roar_vco =
DISC_555_OUT_DC | DISC_555_OUT_SQW, DISC_555_OUT_DC | DISC_555_OUT_SQW,
5, // B+ voltage of 555 5, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
5, // B+ voltage of the Constant Current source
0.7 // Q2 junction voltage 0.7 // Q2 junction voltage
}; };

View File

@ -38,7 +38,7 @@ static emu_timer *frogs_croak_timer;
static const discrete_555_desc frogsZip555m = static const discrete_555_desc frogsZip555m =
{ {
DISC_555_TRIGGER_IS_LOGIC | DISC_555_OUT_DC | DISC_555_OUT_CAP, DISC_555_OUT_CAP | DISC_555_OUT_DC | DISC_555_TRIGGER_IS_LOGIC,
12, // B+ voltage of 555 12, // B+ voltage of 555
DEFAULT_555_VALUES DEFAULT_555_VALUES
}; };
@ -48,7 +48,6 @@ static const discrete_555_cc_desc frogsZip555cc =
DISC_555_OUT_CAP | DISC_555_OUT_DC, DISC_555_OUT_CAP | DISC_555_OUT_DC,
12, // B+ voltage of 555 12, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
12, // B+ voltage of the Constant Current source
0.6 // Q13 Vbe 0.6 // Q13 Vbe
}; };
@ -220,53 +219,62 @@ WRITE8_HANDLER( frogs_audio_w )
static const discrete_mixer_desc headon_mixer = static const discrete_mixer_desc headon_mixer =
{DISC_MIXER_IS_RESISTOR, {
DISC_MIXER_IS_RESISTOR,
{RES_K(130), RES_K(130), RES_K(100), RES_K(100), RES_K(100), RES_K(10)}, // 130 = 390/3, Bonus Res is dummy {RES_K(130), RES_K(130), RES_K(100), RES_K(100), RES_K(100), RES_K(10)}, // 130 = 390/3, Bonus Res is dummy
{0,0,0,0,0}, // no variable resistors {0,0,0,0,0}, // no variable resistors
{0,0,0,0,CAP_N(470),0}, {0,0,0,0,CAP_N(470),0},
0, RES_K(100), 0, RES_K(100),
0, 0,
CAP_U(1), // not in schematics, used to suppress DC CAP_U(1), // not in schematics, used to suppress DC
0, 1}; 0, 1
};
static const discrete_mixer_desc headon_crash_mixer = static const discrete_mixer_desc headon_crash_mixer =
{DISC_MIXER_IS_OP_AMP, {
DISC_MIXER_IS_OP_AMP,
{RES_K(50), RES_K(10)}, // Resistors, in fact variable resistors (100k) {RES_K(50), RES_K(10)}, // Resistors, in fact variable resistors (100k)
{0,0,0,0,0}, // no variable resistors {0,0,0,0,0}, // no variable resistors
{CAP_N(100),CAP_U(1)}, {CAP_N(100),CAP_U(1)},
0, RES_K(100), 0, RES_K(100),
0, 0,
CAP_U(1)*0, // not in schematics, used to suppress DC CAP_U(1)*0, // not in schematics, used to suppress DC
0, 1}; 0, 1
};
static const discrete_inverter_osc_desc headon_inverter_osc_1 = static const discrete_inverter_osc_desc headon_inverter_osc_1 =
{DEFAULT_CD40XX_VALUES(12), {
DEFAULT_CD40XX_VALUES(12),
DISC_OSC_INVERTER_IS_TYPE4 DISC_OSC_INVERTER_IS_TYPE4
}; };
static const discrete_inverter_osc_desc headon_inverter_osc_2 = static const discrete_inverter_osc_desc headon_inverter_osc_2 =
{DEFAULT_CD40XX_VALUES(12), {
DEFAULT_CD40XX_VALUES(12),
DISC_OSC_INVERTER_IS_TYPE5 | DISC_OSC_INVERTER_OUT_IS_LOGIC DISC_OSC_INVERTER_IS_TYPE5 | DISC_OSC_INVERTER_OUT_IS_LOGIC
}; };
static const discrete_555_desc headon_555_bonus = static const discrete_555_desc headon_555_bonus =
{DISC_555_OUT_DC | DISC_555_OUT_ENERGY, {
DISC_555_OUT_ENERGY | DISC_555_OUT_DC,
12, 12,
12-0.5,12*0.66,12*0.33 DEFAULT_555_CHARGE,
12.0-0.5
}; };
static const discrete_555_desc headon_555_crash = static const discrete_555_desc headon_555_crash =
{DISC_555_OUT_DC | DISC_555_TRIGGER_IS_LOGIC, {
DISC_555_OUT_SQW | DISC_555_OUT_DC | DISC_555_TRIGGER_IS_LOGIC,
12, 12,
12-0.5,12*0.66,12*0.33 DEFAULT_555_CHARGE,
12.0-0.5
}; };
static const discrete_555_cc_desc headon_555cc = static const discrete_555_cc_desc headon_555cc =
{ {
DISC_555_OUT_DC, DISC_555_OUT_SQW | DISC_555_OUT_DC,
12, // B+ voltage of 555 12, // B+ voltage of 555
DEFAULT_555_VALUES, DEFAULT_555_VALUES,
12, // B+ voltage of the Constant Current source
0.6 // Q16, Q10 Vbe 0.6 // Q16, Q10 Vbe
}; };
@ -274,15 +282,15 @@ static const discrete_555_cc_desc headon_555cc =
/* /*
* From : http://www.vego.nl/8/08/03/08_08_03.htm * From : http://www.vego.nl/8/08/03/08_08_03.htm
* *
* - voeding: -7 V, clock-frequentie: 2.267 Hz *- voeding: -7 V, clock-frequency: 2.267 Hz
*- voeding: -8 V, clock-frequentie: 8.731 Hz *- voeding: -8 V, clock-frequency: 8.731 Hz
*- voeding: -9 V, clock-frequentie: 16,38 kHz *- voeding: -9 V, clock-frequency: 16,38 kHz
*- voeding: -10 V, clock-frequentie: 23,53 kHz *- voeding: -10 V, clock-frequency: 23,53 kHz
*- voeding: -11 V, clock-frequentie: 32,56 kHz *- voeding: -11 V, clock-frequency: 32,56 kHz
*- voeding: -12 V, clock-frequentie: 38,34 kHz *- voeding: -12 V, clock-frequency: 38,34 kHz
*- voeding: -13 V, clock-frequentie: 40,00 kHz *- voeding: -13 V, clock-frequency: 40,00 kHz
*- voeding: -14 V, clock-frequentie: 37,80 kHz *- voeding: -14 V, clock-frequency: 37,80 kHz
*- voeding: -15 V, clock-frequentie: 33,17 kHz *- voeding: -15 V, clock-frequency: 33,17 kHz
* *
* However all other mame sources say 100kHz. * However all other mame sources say 100kHz.
*/ */
@ -305,7 +313,8 @@ static const discrete_lfsr_desc mm5837_lfsr =
}; };
static const discrete_op_amp_filt_info headon_sallen_key_info = static const discrete_op_amp_filt_info headon_sallen_key_info =
{ RES_K(15), RES_K(15), 0, 0, 0, {
RES_K(15), RES_K(15), 0, 0, 0,
CAP_N(470), CAP_N(47), 0 CAP_N(470), CAP_N(47), 0
}; };