mirror of
https://github.com/holub/mame
synced 2025-07-03 17:08:39 +03:00
Discrete cleanups and fixed discrete logging.
This commit is contained in:
parent
39ea677641
commit
384422ee09
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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" },
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
|
@ -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. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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 */ \
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user