Discrete work - this one needs a full recompile

- change the way custom modules are handled
- updated drivers mario and dkong accordingly
- minor change to stream input handling
- no more linear lists for nodes. All node processing switched to linked lists.
- module step and reset now only get a node pointer passed
- Added discrete_info * pointer to node
- Only nodes with a step routine actually get processed.
- Fixed a bug: discrete logs did not work since some time
- preliminary parallel task constants; depending on results these may vanish again.
- Overall slight performance increase. dkong 940% to 960%, galaxian 740% to 790%
This commit is contained in:
Couriersud 2009-08-23 19:04:41 +00:00
parent dc0df4572e
commit 20caff1c3b
9 changed files with 374 additions and 274 deletions

View File

@ -234,7 +234,7 @@ static DISCRETE_STEP(dsd_555_astbl)
* dt = R*C(log(1/(1-(Vc/Vr)))) * dt = R*C(log(1/(1-(Vc/Vr))))
*/ */
dt = disc_info->sample_time; dt = node->info->sample_time;
/* Sometimes a switching network is used to setup the capacitance. /* Sometimes a switching network is used to setup the capacitance.
* These may select no capacitor, causing oscillation to stop. * These may select no capacitor, causing oscillation to stop.
@ -338,7 +338,7 @@ static DISCRETE_STEP(dsd_555_astbl)
} }
/* Convert last switch time to a ratio */ /* Convert last switch time to a ratio */
x_time = x_time / disc_info->sample_time; x_time = x_time / node->info->sample_time;
switch (context->output_type) switch (context->output_type)
{ {
@ -387,7 +387,7 @@ static DISCRETE_RESET(dsd_555_astbl)
context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
/* setup v_charge or node */ /* setup v_charge or node */
v_charge_node = discrete_find_node(disc_info, info->v_charge); v_charge_node = discrete_find_node(node->info, info->v_charge);
if (v_charge_node) if (v_charge_node)
context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]); context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]);
else else
@ -548,7 +548,7 @@ static DISCRETE_RESET(dsd_555_mstbl)
context->output_type = info->options & DISC_555_OUT_MASK; context->output_type = info->options & DISC_555_OUT_MASK;
if ((context->output_type == DISC_555_OUT_COUNT_F) || (context->output_type == DISC_555_OUT_COUNT_R)) if ((context->output_type == DISC_555_OUT_COUNT_F) || (context->output_type == DISC_555_OUT_COUNT_R))
{ {
discrete_log(disc_info, "Invalid Output type in NODE_%d.\n", node->node - NODE_00); discrete_log(node->info, "Invalid Output type in NODE_%d.\n", node->node - NODE_00);
context->output_type = DISC_555_OUT_SQW; context->output_type = DISC_555_OUT_SQW;
} }
@ -642,7 +642,7 @@ static DISCRETE_STEP(dsd_555_cc)
return; return;
} }
dt = disc_info->sample_time; /* Change in time */ dt = node->info->sample_time; /* Change in time */
v_cap = context->cap_voltage; /* Set to voltage before change */ v_cap = context->cap_voltage; /* Set to voltage before change */
v_vcharge_limit = DSD_555_CC__VIN + info->v_cc_junction; /* the max v_cap can be and still be charged by i */ v_vcharge_limit = DSD_555_CC__VIN + info->v_cc_junction; /* the max v_cap can be and still be charged by i */
/* Calculate charging current */ /* Calculate charging current */
@ -888,7 +888,7 @@ static DISCRETE_STEP(dsd_555_cc)
context->cap_voltage = v_cap_next; context->cap_voltage = v_cap_next;
/* Convert last switch time to a ratio */ /* Convert last switch time to a ratio */
x_time = x_time / disc_info->sample_time; x_time = x_time / node->info->sample_time;
switch (context->output_type) switch (context->output_type)
{ {
@ -1171,7 +1171,7 @@ static DISCRETE_STEP(dsd_555_vco1)
double v_cap; /* Current voltage on capacitor, before dt */ double v_cap; /* Current voltage on capacitor, before dt */
double v_cap_next = 0; /* Voltage on capacitor, after dt */ double v_cap_next = 0; /* Voltage on capacitor, after dt */
dt = disc_info->sample_time; /* Change in time */ dt = node->info->sample_time; /* Change in time */
v_cap = context->cap_voltage; v_cap = context->cap_voltage;
/* Check: if the Control Voltage node is connected. */ /* Check: if the Control Voltage node is connected. */
@ -1275,7 +1275,7 @@ static DISCRETE_STEP(dsd_555_vco1)
context->cap_voltage = v_cap_next; context->cap_voltage = v_cap_next;
/* Convert last switch time to a ratio. No x_time in reset. */ /* Convert last switch time to a ratio. No x_time in reset. */
x_time = x_time / disc_info->sample_time; x_time = x_time / node->info->sample_time;
if (!DSD_555_VCO1__RESET) x_time = 0; if (!DSD_555_VCO1__RESET) x_time = 0;
switch (context->output_type) switch (context->output_type)
@ -1403,7 +1403,7 @@ static DISCRETE_STEP(dsd_566)
if (DSD_566__ENABLE && !context->error) if (DSD_566__ENABLE && !context->error)
{ {
dt = disc_info->sample_time; /* Change in time */ dt = node->info->sample_time; /* Change in time */
v_cap = context->cap_voltage; /* Set to voltage before change */ v_cap = context->cap_voltage; /* Set to voltage before change */
/* get the v_charge and update each step if it is a node */ /* get the v_charge and update each step if it is a node */
@ -1528,7 +1528,7 @@ static DISCRETE_RESET(dsd_566)
} }
/* setup v_charge or node */ /* setup v_charge or node */
v_charge_node = discrete_find_node(disc_info, info->v_charge); v_charge_node = discrete_find_node(node->info, info->v_charge);
if (v_charge_node) if (v_charge_node)
context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]); context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]);
else else
@ -1608,7 +1608,7 @@ static DISCRETE_STEP(dsd_ls624)
double en = 0.0f; double en = 0.0f;
int cntf = 0, cntr = 0; int cntf = 0, cntr = 0;
sample_t = disc_info->sample_time; /* Change in time */ sample_t = node->info->sample_time; /* Change in time */
//dt = LS624_T(DSD_LS624__C, DSD_LS624__VRNG, DSD_LS624__VMOD) / 2.0; //dt = LS624_T(DSD_LS624__C, DSD_LS624__VRNG, DSD_LS624__VMOD) / 2.0;
dt = 1.0f / (2.0f * LS624_F(DSD_LS624__C, DSD_LS624__VMOD, DSD_LS624__VRNG)); dt = 1.0f / (2.0f * LS624_F(DSD_LS624__C, DSD_LS624__VMOD, DSD_LS624__VRNG));
t = context->remain; t = context->remain;

View File

@ -229,7 +229,7 @@ static DISCRETE_RESET(dst_filter1)
{ {
struct dss_filter1_context *context = (struct dss_filter1_context *)node->context; struct dss_filter1_context *context = (struct dss_filter1_context *)node->context;
calculate_filter1_coefficients(disc_info, DST_FILTER1__FREQ, DST_FILTER1__TYPE, &context->a1, &context->b0, &context->b1); calculate_filter1_coefficients(node->info, DST_FILTER1__FREQ, DST_FILTER1__TYPE, &context->a1, &context->b0, &context->b1);
node->output[0] = 0; node->output[0] = 0;
} }
@ -259,7 +259,7 @@ static void calculate_filter2_coefficients(const discrete_info *disc_info,
double w; /* cutoff freq, in radians/sec */ double w; /* cutoff freq, in radians/sec */
double w_squared; double w_squared;
double den; /* temp variable */ double den; /* temp variable */
double two_over_T = 2*disc_info->sample_rate; double two_over_T = 2 * disc_info->sample_rate;
double two_over_T_squared = two_over_T * two_over_T; double two_over_T_squared = two_over_T * two_over_T;
/* calculate digital filter coefficents */ /* calculate digital filter coefficents */
@ -318,7 +318,7 @@ static DISCRETE_RESET(dst_filter2)
{ {
struct dss_filter2_context *context = (struct dss_filter2_context *)node->context; struct dss_filter2_context *context = (struct dss_filter2_context *)node->context;
calculate_filter2_coefficients(disc_info, DST_FILTER2__FREQ, DST_FILTER2__DAMP, DST_FILTER2__TYPE, calculate_filter2_coefficients(node->info, DST_FILTER2__FREQ, DST_FILTER2__DAMP, DST_FILTER2__TYPE,
&context->a1, &context->a2, &context->a1, &context->a2,
&context->b0, &context->b1, &context->b2); &context->b0, &context->b1, &context->b2);
node->output[0] = 0; node->output[0] = 0;
@ -508,7 +508,7 @@ static DISCRETE_RESET(dst_op_amp_filt)
double d = (info->c1 + info->c2) / sqrt(info->rF / context->rTotal * info->c1 * info->c2); double d = (info->c1 + info->c2) / sqrt(info->rF / context->rTotal * info->c1 * info->c2);
double gain = -info->rF / context->rTotal * info->c2 / (info->c1 + info->c2); double gain = -info->rF / context->rTotal * info->c2 / (info->c1 + info->c2);
calculate_filter2_coefficients(disc_info, fc, d, DISC_FILTER_BANDPASS, calculate_filter2_coefficients(node->info, fc, d, DISC_FILTER_BANDPASS,
&context->a1, &context->a2, &context->a1, &context->a2,
&context->b0, &context->b1, &context->b2); &context->b0, &context->b1, &context->b2);
context->b0 *= gain; context->b0 *= gain;
@ -577,7 +577,7 @@ static DISCRETE_STEP(dst_rcdisc)
if (DST_RCDISC__ENABLE) if (DST_RCDISC__ENABLE)
{ {
node->output[0] = DST_RCDISC__IN * exp(context->t / context->exponent0); node->output[0] = DST_RCDISC__IN * exp(context->t / context->exponent0);
context->t += disc_info->sample_time; context->t += node->info->sample_time;
} else } else
{ {
context->state = 0; context->state = 0;
@ -780,17 +780,17 @@ static DISCRETE_RESET( dst_rcdisc4)
/* some error checking. */ /* some error checking. */
if (DST_RCDISC4__R1 <= 0 || DST_RCDISC4__R2 <= 0 || DST_RCDISC4__C1 <= 0 || (DST_RCDISC4__R3 <= 0 && context->type == 1)) if (DST_RCDISC4__R1 <= 0 || DST_RCDISC4__R2 <= 0 || DST_RCDISC4__C1 <= 0 || (DST_RCDISC4__R3 <= 0 && context->type == 1))
{ {
discrete_log(disc_info, "Invalid component values in NODE_%d.\n", node->node - NODE_00); discrete_log(node->info, "Invalid component values in NODE_%d.\n", node->node - NODE_00);
return; return;
} }
if (DST_RCDISC4__VP < 3) if (DST_RCDISC4__VP < 3)
{ {
discrete_log(disc_info, "vP must be >= 3V in NODE_%d.\n", node->node - NODE_00); discrete_log(node->info, "vP must be >= 3V in NODE_%d.\n", node->node - NODE_00);
return; return;
} }
if (DST_RCDISC4__TYPE < 1 || DST_RCDISC4__TYPE > 3) if (DST_RCDISC4__TYPE < 1 || DST_RCDISC4__TYPE > 3)
{ {
discrete_log(disc_info, "Invalid circuit type in NODE_%d.\n", node->node - NODE_00); discrete_log(node->info, "Invalid circuit type in NODE_%d.\n", node->node - NODE_00);
return; return;
} }
@ -1236,7 +1236,7 @@ static DISCRETE_RESET(dst_rcintegrate)
struct dst_rcintegrate_context *context = (struct dst_rcintegrate_context *)node->context; struct dst_rcintegrate_context *context = (struct dst_rcintegrate_context *)node->context;
double r; double r;
double dt = disc_info->sample_time; double dt = node->info->sample_time;
context->type = DST_RCINTEGRATE__TYPE; context->type = DST_RCINTEGRATE__TYPE;
@ -1312,7 +1312,7 @@ static DISCRETE_RESET(dst_sallen_key)
fatalerror("Unknown sallen key filter type"); fatalerror("Unknown sallen key filter type");
} }
calculate_filter2_coefficients(disc_info, freq, 1.0 / q, DISC_FILTER_LOWPASS, calculate_filter2_coefficients(node->info, freq, 1.0 / q, DISC_FILTER_LOWPASS,
&context->a1, &context->a2, &context->a1, &context->a2,
&context->b0, &context->b1, &context->b2); &context->b0, &context->b1, &context->b2);
node->output[0] = 0; node->output[0] = 0;
@ -1460,8 +1460,8 @@ static DISCRETE_RESET(dst_rcdisc2N)
f1 = 1.0 / (2 * M_PI * DST_RCDISC2N__R0 * DST_RCDISC2N__C); f1 = 1.0 / (2 * M_PI * DST_RCDISC2N__R0 * DST_RCDISC2N__C);
f2 = 1.0 / (2 * M_PI * DST_RCDISC2N__R1 * DST_RCDISC2N__C); f2 = 1.0 / (2 * M_PI * DST_RCDISC2N__R1 * DST_RCDISC2N__C);
calculate_filter1_coefficients(disc_info, f1, DISC_FILTER_LOWPASS, &context->a1_0, &context->b0_0, &context->b1_0); calculate_filter1_coefficients(node->info, f1, DISC_FILTER_LOWPASS, &context->a1_0, &context->b0_0, &context->b1_0);
calculate_filter1_coefficients(disc_info, f2, DISC_FILTER_LOWPASS, &context->a1_1, &context->b0_1, &context->b1_1); calculate_filter1_coefficients(node->info, f2, DISC_FILTER_LOWPASS, &context->a1_1, &context->b0_1, &context->b1_1);
/* Initialize the object */ /* Initialize the object */
node->output[0] = 0; node->output[0] = 0;

View File

@ -15,6 +15,8 @@
* *
************************************************************************/ ************************************************************************/
#define EXPERIMENTAL_STREAM_PARALLEL (0)
#define DSS_INPUT__GAIN (*(node->input[0])) #define DSS_INPUT__GAIN (*(node->input[0]))
#define DSS_INPUT__OFFSET (*(node->input[1])) #define DSS_INPUT__OFFSET (*(node->input[1]))
#define DSS_INPUT__INIT (*(node->input[2])) #define DSS_INPUT__INIT (*(node->input[2]))
@ -54,7 +56,7 @@ READ8_DEVICE_HANDLER(discrete_sound_r)
/* Bring the system up to now */ /* Bring the system up to now */
stream_update(info->discrete_stream); stream_update(info->discrete_stream);
if ((node->module.type >= DSS_INPUT_DATA) && (node->module.type <= DSS_INPUT_PULSE)) if ((node->module->type >= DSS_INPUT_DATA) && (node->module->type <= DSS_INPUT_PULSE))
{ {
data = *node_data; data = *node_data;
} }
@ -65,7 +67,7 @@ READ8_DEVICE_HANDLER(discrete_sound_r)
return data; return data;
} }
#if 0 #if EXPERIMENTAL_STREAM_PARALLEL
static STREAM_BACKGROUND_CALLBACK( disc_cb ) static STREAM_BACKGROUND_CALLBACK( disc_cb )
{ {
node_description *node = (node_description *) ptr; node_description *node = (node_description *) ptr;
@ -86,7 +88,7 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
UINT8 last_data = *node_data; UINT8 last_data = *node_data;
UINT8 new_data = 0; UINT8 new_data = 0;
switch (node->module.type) switch (node->module->type)
{ {
case DSS_INPUT_DATA: case DSS_INPUT_DATA:
new_data = data; new_data = data;
@ -102,7 +104,7 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
if (last_data != new_data) if (last_data != new_data)
{ {
#if 1 #if !EXPERIMENTAL_STREAM_PARALLEL
/* Bring the system up to now */ /* Bring the system up to now */
stream_update(info->discrete_stream); stream_update(info->discrete_stream);
@ -172,12 +174,12 @@ static DISCRETE_RESET(dss_adjustment)
if (node->custom) if (node->custom)
{ {
context->port = input_port_by_tag(disc_info->device->machine->portconfig, (const char *)node->custom); context->port = input_port_by_tag(node->info->device->machine->portconfig, (const char *)node->custom);
if (context->port == NULL) if (context->port == NULL)
fatalerror("DISCRETE_ADJUSTMENT_TAG - NODE_%d has invalid tag", node->node-NODE_00); fatalerror("DISCRETE_ADJUSTMENT_TAG - NODE_%d has invalid tag", node->node-NODE_00);
} }
else else
context->port = input_port_by_index(disc_info->device->machine->portconfig, DSS_ADJUSTMENT__PORT); context->port = input_port_by_index(node->info->device->machine->portconfig, DSS_ADJUSTMENT__PORT);
context->lastpval = 0x7fffffff; context->lastpval = 0x7fffffff;
context->pmin = DSS_ADJUSTMENT__PMIN; context->pmin = DSS_ADJUSTMENT__PMIN;
@ -233,7 +235,7 @@ static DISCRETE_RESET(dss_input)
{ {
UINT8 *node_data = (UINT8 *)node->context; UINT8 *node_data = (UINT8 *)node->context;
switch (node->module.type) switch (node->module->type)
{ {
case DSS_INPUT_DATA: case DSS_INPUT_DATA:
*node_data = DSS_INPUT__INIT; *node_data = DSS_INPUT__INIT;
@ -280,13 +282,19 @@ static DISCRETE_STEP(dss_input_stream)
stream_sample_t **ptr = (stream_sample_t **)node->context; stream_sample_t **ptr = (stream_sample_t **)node->context;
stream_sample_t *data = *ptr; stream_sample_t *data = *ptr;
node->output[0] = data ? (*data) * DSS_INPUT_STREAM__GAIN + DSS_INPUT_STREAM__OFFSET : 0; if (data)
{
node->output[0] = (*data) * DSS_INPUT_STREAM__GAIN + DSS_INPUT_STREAM__OFFSET;
(*ptr)++;
}
else
node->output[0] = 0;
} }
static DISCRETE_RESET(dss_input_stream) static DISCRETE_RESET(dss_input_stream)
{ {
int istream = DSS_INPUT_STREAM__STREAM; int istream = DSS_INPUT_STREAM__STREAM;
/* we will use the node's context pointer to point to the input stream data */ /* we will use the node's context pointer to point to the input stream data */
assert(istream < disc_info->discrete_input_streams); assert(istream < node->info->discrete_input_streams);
node->context = (discrete_info *) &disc_info->input_stream_data[istream]; node->context = (discrete_info *) &node->info->input_stream_data[istream];
} }

View File

@ -384,11 +384,11 @@ static DISCRETE_RESET(dst_dac_r1)
if (info->ladderLength < 2) if (info->ladderLength < 2)
{ {
/* You need at least 2 resistors for a ladder */ /* You need at least 2 resistors for a ladder */
discrete_log(disc_info, "dst_dac_r1_reset - Ladder length too small"); discrete_log(node->info, "dst_dac_r1_reset - Ladder length too small");
} }
if (info->ladderLength > DISC_LADDER_MAXRES ) if (info->ladderLength > DISC_LADDER_MAXRES )
{ {
discrete_log(disc_info, "dst_dac_r1_reset - Ladder length exceeds DISC_LADDER_MAXRES"); discrete_log(node->info, "dst_dac_r1_reset - Ladder length exceeds DISC_LADDER_MAXRES");
} }
/* /*
@ -491,7 +491,7 @@ static DISCRETE_STEP(dst_divide)
if(DST_DIVIDE__DIV == 0) if(DST_DIVIDE__DIV == 0)
{ {
node->output[0 ]= DBL_MAX; /* Max out but don't break */ node->output[0 ]= DBL_MAX; /* Max out but don't break */
discrete_log(disc_info, "dst_divider_step() - Divide by Zero attempted in NODE_%02d.\n",NODE_INDEX(node->node)); discrete_log(node->info, "dst_divider_step() - Divide by Zero attempted in NODE_%02d.\n",NODE_INDEX(node->node));
} }
else else
{ {
@ -609,7 +609,7 @@ static DISCRETE_STEP(dst_integrate)
i_neg = context->v_max_in / info->r1; i_neg = context->v_max_in / info->r1;
i_pos = (DST_INTEGRATE__TRG0 - OP_AMP_NORTON_VBE) / info->r2; i_pos = (DST_INTEGRATE__TRG0 - OP_AMP_NORTON_VBE) / info->r2;
if (i_pos < 0) i_pos = 0; if (i_pos < 0) i_pos = 0;
node->output[0] += (i_pos - i_neg) / disc_info->sample_rate / info->c; node->output[0] += (i_pos - i_neg) / node->info->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:
@ -618,7 +618,7 @@ static DISCRETE_STEP(dst_integrate)
i_neg = dst_trigger_function(trig0, trig1, 0, info->f0) ? context->v_max_in_d / info->r1 : 0; i_neg = dst_trigger_function(trig0, trig1, 0, info->f0) ? context->v_max_in_d / info->r1 : 0;
i_pos = dst_trigger_function(trig0, trig1, 0, info->f1) ? context->v_max_in / info->r2 : 0; i_pos = dst_trigger_function(trig0, trig1, 0, info->f1) ? context->v_max_in / info->r2 : 0;
i_pos += dst_trigger_function(trig0, trig1, 0, info->f2) ? context->v_max_in_d / info->r3 : 0; i_pos += dst_trigger_function(trig0, trig1, 0, info->f2) ? context->v_max_in_d / info->r3 : 0;
node->output[0] += (i_pos - i_neg) / disc_info->sample_rate / info->c; node->output[0] += (i_pos - i_neg) / node->info->sample_rate / info->c;
break; break;
} }
@ -646,7 +646,7 @@ static DISCRETE_RESET(dst_integrate)
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 */
i = v / info->r1; i = v / info->r1;
context->change = i / disc_info->sample_rate / info->c; context->change = i / node->info->sample_rate / info->c;
} }
node->output[0] = 0; node->output[0] = 0;
} }
@ -1227,7 +1227,7 @@ static DISCRETE_RESET(dst_mixer)
context->r_node_bit_flag = 0; context->r_node_bit_flag = 0;
for (bit = 0; bit < 8; bit++) for (bit = 0; bit < 8; bit++)
{ {
r_node = discrete_find_node(disc_info, info->r_node[bit]); r_node = discrete_find_node(node->info, info->r_node[bit]);
if (r_node != NULL) if (r_node != NULL)
{ {
context->r_node[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->r_node[bit])]); context->r_node[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->r_node[bit])]);
@ -1354,7 +1354,7 @@ static DISCRETE_STEP(dst_multiplex)
else else
{ {
/* Bad address. We will leave the output alone. */ /* Bad address. We will leave the output alone. */
discrete_log(disc_info, "NODE_%02d - Address = %d. Out of bounds\n", node->node-NODE_00, addr); discrete_log(node->info, "NODE_%02d - Address = %d. Out of bounds\n", node->node-NODE_00, addr);
} }
} }
else else
@ -1439,7 +1439,7 @@ static DISCRETE_STEP(dst_oneshot)
if (do_count) if (do_count)
{ {
context->countdown -= disc_info->sample_time; context->countdown -= node->info->sample_time;
if(context->countdown <= 0.0) if(context->countdown <= 0.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;
@ -1514,7 +1514,7 @@ static DISCRETE_RESET(dst_ramp)
struct dss_ramp_context *context = (struct dss_ramp_context *)node->context; struct dss_ramp_context *context = (struct dss_ramp_context *)node->context;
node->output[0] = DST_RAMP__CLAMP; node->output[0] = DST_RAMP__CLAMP;
context->step = DST_RAMP__GRAD / disc_info->sample_rate; context->step = DST_RAMP__GRAD / node->info->sample_rate;
context->dir = ((DST_RAMP__END - DST_RAMP__START) == abs(DST_RAMP__END - DST_RAMP__START)); context->dir = ((DST_RAMP__END - DST_RAMP__START) == abs(DST_RAMP__END - DST_RAMP__START));
context->last_en = 0; context->last_en = 0;
} }
@ -1560,7 +1560,7 @@ static DISCRETE_STEP(dst_samphold)
if (DST_SAMPHOLD__CLOCK == 0) node->output[0] = DST_SAMPHOLD__IN0; if (DST_SAMPHOLD__CLOCK == 0) node->output[0] = DST_SAMPHOLD__IN0;
break; break;
default: default:
discrete_log(disc_info, "dst_samphold_step - Invalid clocktype passed"); discrete_log(node->info, "dst_samphold_step - Invalid clocktype passed");
break; break;
} }
} }
@ -1762,7 +1762,7 @@ static DISCRETE_STEP(dst_transform)
top = (int)number1 ^ (int)top; top = (int)number1 ^ (int)top;
break; break;
default: default:
discrete_log(disc_info, "dst_transform_step - Invalid function type/variable passed"); discrete_log(node->info, "dst_transform_step - Invalid function type/variable passed");
node->output[0] = 0; node->output[0] = 0;
break; break;
} }
@ -1869,7 +1869,7 @@ static DISCRETE_RESET(dst_op_amp)
} }
else else
/* linear charge */ /* linear charge */
context->exponent = disc_info->sample_rate * info->c; context->exponent = node->info->sample_rate * info->c;
} }
if (info->r3 > 0) if (info->r3 > 0)

View File

@ -199,10 +199,10 @@ static DISCRETE_STEP(dss_counter)
if (context->clock_type == DISC_CLK_IS_FREQ) if (context->clock_type == DISC_CLK_IS_FREQ)
{ {
/* We need to keep clocking the internal clock even if disabled. */ /* We need to keep clocking the internal clock even if disabled. */
cycles = (context->t_left + disc_info->sample_time) * ds_clock; cycles = (context->t_left + node->info->sample_time) * ds_clock;
inc = (int)cycles; inc = (int)cycles;
context->t_left = (cycles - inc) / ds_clock; context->t_left = (cycles - inc) / ds_clock;
if (inc) x_time = context->t_left / disc_info->sample_time; if (inc) x_time = context->t_left / node->info->sample_time;
} }
else else
{ {
@ -401,7 +401,7 @@ static DISCRETE_STEP(dss_lfsr)
if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ)
{ {
/* We need to keep clocking the internal clock even if disabled. */ /* We need to keep clocking the internal clock even if disabled. */
cycles = (context->t_left + disc_info->sample_time) / context->t_clock; cycles = (context->t_left + node->info->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;
} }
@ -445,22 +445,22 @@ static DISCRETE_STEP(dss_lfsr)
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(disc_info, lfsr_desc->feedback_function1, fbresult, noise_feed, 0x01); fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function1, fbresult, noise_feed, 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(disc_info, lfsr_desc->feedback_function2, fbresult, context->lfsr_reg, (1 << lfsr_desc->bitlength) - 1 ); context->lfsr_reg = dss_lfsr_function(node->info, 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(disc_info, lfsr_desc->feedback_function0, fb0, fb1, 0x01); fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function0, fb0, fb1, 0x01);
context->lfsr_reg = dss_lfsr_function(disc_info, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2 << lfsr_desc->bitlength) - 1); context->lfsr_reg = dss_lfsr_function(node->info, 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 */
@ -500,7 +500,7 @@ static DISCRETE_RESET(dss_lfsr)
context->out_lfsr_reg = (lfsr_desc->flags & DISC_LFSR_FLAG_OUTPUT_SR_SN1) ? 1 : 0; context->out_lfsr_reg = (lfsr_desc->flags & DISC_LFSR_FLAG_OUTPUT_SR_SN1) ? 1 : 0;
if ((lfsr_desc->clock_type < DISC_CLK_ON_F_EDGE) || (lfsr_desc->clock_type > DISC_CLK_IS_FREQ)) if ((lfsr_desc->clock_type < DISC_CLK_ON_F_EDGE) || (lfsr_desc->clock_type > DISC_CLK_IS_FREQ))
discrete_log(disc_info, "Invalid clock type passed in NODE_%d\n", NODE_INDEX(node->node)); discrete_log(node->info, "Invalid clock type passed in NODE_%d\n", NODE_INDEX(node->node));
context->last = (DSS_COUNTER__CLOCK != 0); context->last = (DSS_COUNTER__CLOCK != 0);
if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK; if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK;
@ -513,8 +513,8 @@ static DISCRETE_RESET(dss_lfsr)
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(disc_info, lfsr_desc->feedback_function0, fb0, fb1, 0x01); fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function0, fb0, fb1, 0x01);
context->lfsr_reg=dss_lfsr_function(disc_info, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2<< lfsr_desc->bitlength ) - 1); context->lfsr_reg=dss_lfsr_function(node->info, 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;
@ -554,7 +554,7 @@ static DISCRETE_STEP(dss_noise)
if(context->phase > (2.0 * M_PI)) if(context->phase > (2.0 * M_PI))
{ {
/* GCC's rand returns a RAND_MAX value of 0x7fff */ /* GCC's rand returns a RAND_MAX value of 0x7fff */
int newval = (mame_rand(disc_info->device->machine) & 0x7fff) - 16384; int newval = (mame_rand(node->info->device->machine) & 0x7fff) - 16384;
/* make sure the peak to peak values are the amplitude */ /* make sure the peak to peak values are the amplitude */
node->output[0] = DSS_NOISE__AMP / 2; node->output[0] = DSS_NOISE__AMP / 2;
@ -577,7 +577,7 @@ static DISCRETE_STEP(dss_noise)
/* The enable input only curtails output, phase rotation still occurs. */ /* The enable input only curtails output, phase rotation still occurs. */
/* We allow the phase to exceed 2Pi here, so we can tell when to sample the noise. */ /* We allow the phase to exceed 2Pi here, so we can tell when to sample the noise. */
context->phase += ((2.0 * M_PI * DSS_NOISE__FREQ) / disc_info->sample_rate); context->phase += ((2.0 * M_PI * DSS_NOISE__FREQ) / node->info->sample_rate);
} }
@ -621,10 +621,10 @@ static DISCRETE_STEP(dss_note)
if (context->clock_type == DISC_CLK_IS_FREQ) if (context->clock_type == DISC_CLK_IS_FREQ)
{ {
/* We need to keep clocking the internal clock even if disabled. */ /* We need to keep clocking the internal clock even if disabled. */
cycles = (context->t_left + disc_info->sample_time) / context->t_clock; cycles = (context->t_left + node->info->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) x_time = context->t_left / disc_info->sample_time; if (inc) x_time = context->t_left / node->info->sample_time;
} }
else else
{ {
@ -754,7 +754,7 @@ static DISCRETE_STEP(dss_op_amp_osc)
UINT8 force_charge = 0; UINT8 force_charge = 0;
UINT8 enable = DSS_OP_AMP_OSC__ENABLE; UINT8 enable = DSS_OP_AMP_OSC__ENABLE;
dt = disc_info->sample_time; /* Change in time */ dt = node->info->sample_time; /* Change in time */
vC = context->v_cap; /* 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. */
@ -931,7 +931,7 @@ static DISCRETE_RESET(dss_op_amp_osc)
{ {
if IS_VALUE_A_NODE(*r_info_ptr) if IS_VALUE_A_NODE(*r_info_ptr)
{ {
r_node = discrete_find_node(disc_info, *r_info_ptr); r_node = discrete_find_node(node->info, *r_info_ptr);
*r_context_ptr = &(r_node->output[NODE_CHILD_NODE_NUM((int)*r_info_ptr)]); *r_context_ptr = &(r_node->output[NODE_CHILD_NODE_NUM((int)*r_info_ptr)]);
} }
else else
@ -1078,7 +1078,7 @@ static DISCRETE_STEP(dss_sawtoothwave)
/* 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_SAWTOOTHWAVE__FREQ) / disc_info->sample_rate)), 2.0 * M_PI); context->phase = fmod((context->phase + ((2.0 * M_PI * DSS_SAWTOOTHWAVE__FREQ) / node->info->sample_rate)), 2.0 * M_PI);
} }
static DISCRETE_RESET(dss_sawtoothwave) static DISCRETE_RESET(dss_sawtoothwave)
@ -1257,7 +1257,7 @@ static DISCRETE_STEP(dss_sinewave)
/* 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_SINEWAVE__FREQ) / disc_info->sample_rate)), 2.0 * M_PI); context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_SINEWAVE__FREQ) / node->info->sample_rate)), 2.0 * M_PI);
} }
static DISCRETE_RESET(dss_sinewave) static DISCRETE_RESET(dss_sinewave)
@ -1323,7 +1323,7 @@ static DISCRETE_STEP(dss_squarewave)
/* 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) / disc_info->sample_rate), 2.0 * M_PI); context->phase=fmod(context->phase + ((2.0 * M_PI * DSS_SQUAREWAVE__FREQ) / node->info->sample_rate), 2.0 * M_PI);
} }
static DISCRETE_RESET(dss_squarewave) static DISCRETE_RESET(dss_squarewave)
@ -1392,7 +1392,7 @@ static DISCRETE_RESET(dss_squarewfix)
{ {
struct dss_squarewfix_context *context = (struct dss_squarewfix_context *)node->context; struct dss_squarewfix_context *context = (struct dss_squarewfix_context *)node->context;
context->sample_step = 1.0 / disc_info->sample_rate; context->sample_step = 1.0 / node->info->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 */
@ -1454,7 +1454,7 @@ static DISCRETE_STEP(dss_squarewave2)
/* phase step = 2Pi/(output period/sample period) */ /* phase step = 2Pi/(output period/sample period) */
/* boils out to */ /* boils out to */
/* phase step = 2Pi/(output period*sample freq) */ /* phase step = 2Pi/(output period*sample freq) */
newphase = context->phase + ((2.0 * M_PI) / ((DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON) * disc_info->sample_rate)); newphase = context->phase + ((2.0 * M_PI) / ((DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON) * node->info->sample_rate));
/* Keep the new phasor in the 2Pi range.*/ /* Keep the new phasor in the 2Pi range.*/
context->phase = fmod(newphase, 2.0 * M_PI); context->phase = fmod(newphase, 2.0 * M_PI);
@ -1607,7 +1607,7 @@ static DISCRETE_STEP(dss_inverter_osc)
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->v_cap; diff = vMix - context->v_cap;
diff = diff - diff * exp(-disc_info->sample_time / (context->c * rMix)); diff = diff - diff * exp(-node->info->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)))
@ -1625,7 +1625,7 @@ static DISCRETE_STEP(dss_inverter_osc)
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->v_cap; diff = vMix - context->v_cap;
diff = diff - diff * exp(-disc_info->sample_time/(context->c * rMix)); diff = diff - diff * exp(-node->info->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);
@ -1648,8 +1648,8 @@ static DISCRETE_RESET(dss_inverter_osc)
int i; int i;
/* exponent */ /* exponent */
context->w = exp(-disc_info->sample_time / (DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__C)); context->w = exp(-node->info->sample_time / (DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__C));
context->wc = exp(-disc_info->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(-node->info->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->v_cap = 0; context->v_cap = 0;
context->v_g2_old = 0; context->v_g2_old = 0;
@ -1708,7 +1708,7 @@ static DISCRETE_STEP(dss_trianglewave)
/* 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_TRIANGLEWAVE__FREQ) / disc_info->sample_rate)), 2.0 * M_PI); context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_TRIANGLEWAVE__FREQ) / node->info->sample_rate)), 2.0 * M_PI);
} }
static DISCRETE_RESET(dss_trianglewave) static DISCRETE_RESET(dss_trianglewave)

View File

@ -57,16 +57,14 @@
#define DISCRETE_PROFILING (0) #define DISCRETE_PROFILING (0)
/************************************* /*************************************
* *
* Prototypes * Prototypes
* *
*************************************/ *************************************/
static void init_nodes(discrete_info *info, discrete_sound_block *block_list, const device_config *device); static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device);
static void find_input_nodes(discrete_info *info, discrete_sound_block *block_list); static void find_input_nodes(discrete_info *info);
static void setup_output_nodes(const device_config *device, discrete_info *info); static void setup_output_nodes(const device_config *device, discrete_info *info);
static void setup_disc_logs(discrete_info *info); static void setup_disc_logs(discrete_info *info);
static node_description *discrete_find_node(const discrete_info *info, int node); static node_description *discrete_find_node(const discrete_info *info, int node);
@ -229,7 +227,19 @@ static const discrete_module module_list[] =
{ DSS_NULL ,"DSS_NULL" , 0 ,0 ,NULL ,NULL } { DSS_NULL ,"DSS_NULL" , 0 ,0 ,NULL ,NULL }
}; };
/*************************************
*
* Add an entry to a list
*
*************************************/
static void add_list(discrete_info *info, linked_list_entry ***list, void *ptr)
{
**list = auto_alloc(info->device->machine, linked_list_entry);
(**list)->ptr = ptr;
(**list)->next = NULL;
*list = &((**list)->next);
}
/************************************* /*************************************
* *
@ -249,7 +259,7 @@ static node_description *discrete_find_node(const discrete_info *info, int node)
* *
*************************************/ *************************************/
static int discrete_build_list(discrete_info *info, discrete_sound_block *intf, discrete_sound_block *out, int offset) static void discrete_build_list(discrete_info *info, discrete_sound_block *intf, linked_list_entry ***current)
{ {
int node_count = 0; int node_count = 0;
@ -258,56 +268,103 @@ static int discrete_build_list(discrete_info *info, discrete_sound_block *intf,
/* scan imported */ /* scan imported */
if (intf[node_count].type == DSO_IMPORT) if (intf[node_count].type == DSO_IMPORT)
{ {
offset = discrete_build_list(info, (discrete_sound_block *) intf[node_count].custom, out, offset); discrete_log(info, "discrete_build_list() - DISCRETE_IMPORT @ NODE_%02d", NODE_INDEX(intf[node_count].node) );
discrete_build_list(info, (discrete_sound_block *) intf[node_count].custom, current);
} }
else if (intf[node_count].type == DSO_REPLACE) else if (intf[node_count].type == DSO_REPLACE)
{ {
int i; linked_list_entry *entry;
node_count++; node_count++;
if (intf[node_count].type == DSS_NULL) if (intf[node_count].type == DSS_NULL)
fatalerror("discrete_build_list: DISCRETE_REPLACE at end of node_list"); fatalerror("discrete_build_list: DISCRETE_REPLACE at end of node_list");
for (i = 0; i < offset; i++) for (entry = info->block_list; entry != NULL; entry = entry->next)
if (out[i].type != NODE_SPECIAL ) {
if (out[i].node == intf[node_count].node) discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
if (block->type != NODE_SPECIAL )
if (block->node == intf[node_count].node)
{ {
out[i] = intf[node_count]; entry->ptr = (void *) &intf[node_count];
discrete_log(info, "discrete_build_list() - DISCRETE_REPLACE @ NODE_%02d", NODE_INDEX(intf[node_count].node) );
break; break;
} }
}
if (i >= offset) if (entry == NULL)
fatalerror("discrete_build_list: DISCRETE_REPLACE did not found node %d", NODE_INDEX(intf[node_count].node)); fatalerror("discrete_build_list: DISCRETE_REPLACE did not found node %d", NODE_INDEX(intf[node_count].node));
} }
else if (intf[node_count].type == DSO_DELETE) else if (intf[node_count].type == DSO_DELETE)
{ {
int i,p,deleted; int p,deleted;
linked_list_entry *entry, *last;
p = 0; p = 0;
deleted = 0; deleted = 0;
for (i = 0; i < offset; i++) last = NULL;
for (entry = info->block_list; entry != NULL; last = entry, entry = entry->next)
{ {
if ((out[i].node >= intf[node_count].input_node[0]) && discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
(out[i].node <= intf[node_count].input_node[1]))
if ((block->node >= intf[node_count].input_node[0]) &&
(block->node <= intf[node_count].input_node[1]))
{ {
discrete_log(info, "discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(out[i].node) ); discrete_log(info, "discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(block->node) );
deleted++; if (last != NULL)
} last->next = entry->next;
else else
{ info->block_list = entry->next;
out[p++] = out[i];
} }
} }
offset -= deleted;
} }
else else
out[offset++] = intf[node_count]; {
discrete_log(info, "discrete_build_list() - adding node %d (*current %p)\n", node_count, *current);
add_list(info, current, &intf[node_count]);
}
node_count++; node_count++;
} }
out[offset] = intf[node_count]; }
return offset;
/*************************************
*
* Sanity check list
*
*************************************/
static void discrete_sanity_check(discrete_info *info)
{
linked_list_entry *entry;
int node_count = 0;
discrete_log(info, "discrete_start() - Doing node list sanity check");
for (entry = info->block_list; entry != NULL; entry = entry->next)
{
discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
/* make sure we don't have too many nodes overall */
if (node_count > DISCRETE_MAX_NODES)
fatalerror("discrete_start() - Upper limit of %d nodes exceeded, have you terminated the interface block?", DISCRETE_MAX_NODES);
/* make sure the node number is in range */
if (block->node < NODE_START || block->node > NODE_END)
fatalerror("discrete_start() - Invalid node number on node %02d descriptor", block->node);
/* make sure the node type is valid */
if (block->type > DSO_OUTPUT)
fatalerror("discrete_start() - Invalid function type on NODE_%02d", NODE_INDEX(block->node) );
/* make sure this is a main node */
if (NODE_CHILD_NODE_NUM(block->node) > 0)
fatalerror("discrete_start() - Child node number on NODE_%02d", NODE_INDEX(block->node) );
node_count++;
}
discrete_log(info, "discrete_start() - Sanity check counted %d nodes", node_count);
} }
/************************************* /*************************************
@ -318,7 +375,7 @@ static int discrete_build_list(discrete_info *info, discrete_sound_block *intf,
static DEVICE_START( discrete ) static DEVICE_START( discrete )
{ {
discrete_sound_block *intf; linked_list_entry **intf;
discrete_sound_block *intf_start = (discrete_sound_block *)device->static_config; discrete_sound_block *intf_start = (discrete_sound_block *)device->static_config;
discrete_info *info = get_safe_token(device); discrete_info *info = get_safe_token(device);
char name[32]; char name[32];
@ -337,50 +394,29 @@ static DEVICE_START( discrete )
/* create the logfile */ /* create the logfile */
sprintf(name, "discrete%s.log", device->tag); sprintf(name, "discrete%s.log", device->tag);
if (DISCRETE_DEBUGLOG && !info->disclogfile) if (DISCRETE_DEBUGLOG)
info->disclogfile = fopen(name, "w"); info->disclogfile = fopen(name, "w");
/* Build the final block list */ /* Build the final block list */
intf = auto_alloc_array_clear(device->machine, discrete_sound_block, DISCRETE_MAX_NODES); info->block_list = NULL;
discrete_build_list(info, intf_start, intf, 0); intf = &info->block_list;
discrete_build_list(info, intf_start, &intf);
/* 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(info, "discrete_start() - Doing node list sanity check"); discrete_sanity_check(info);
for (info->node_count = 0; intf[info->node_count].type != DSS_NULL; info->node_count++)
{ /* Start with empty lists */
/* make sure we don't have too many nodes overall */ info->node_list = NULL;
if (info->node_count > DISCRETE_MAX_NODES) info->step_list = NULL;
fatalerror("discrete_start() - Upper limit of %d nodes exceeded, have you terminated the interface block?", DISCRETE_MAX_NODES);
/* make sure the node number is in range */
if (intf[info->node_count].node < NODE_START || intf[info->node_count].node > NODE_END)
fatalerror("discrete_start() - Invalid node number on node %02d descriptor", info->node_count);
/* make sure the node type is valid */
if (intf[info->node_count].type > DSO_OUTPUT)
fatalerror("discrete_start() - Invalid function type on NODE_%02d", NODE_INDEX(intf[info->node_count].node) );
/* make sure this is a main node */
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) );
}
info->node_count++;
discrete_log(info, "discrete_start() - Sanity check counted %d nodes", info->node_count);
/* allocate memory for the array of actual nodes */
info->node_list = auto_alloc_array_clear(device->machine, node_description, info->node_count);
/* allocate memory for the node execution order array */
info->running_order = auto_alloc_array_clear(device->machine, node_description *, info->node_count);
/* allocate memory to hold pointers to nodes by index */ /* allocate memory to hold pointers to nodes by index */
info->indexed_node = auto_alloc_array_clear(device->machine, node_description *, DISCRETE_MAX_NODES); info->indexed_node = auto_alloc_array_clear(device->machine, node_description *, DISCRETE_MAX_NODES);
/* initialize the node data */ /* initialize the node data */
init_nodes(info, intf, device); init_nodes(info, info->block_list, device);
/* now go back and find pointers to all input nodes */ /* now go back and find pointers to all input nodes */
find_input_nodes(info, intf); find_input_nodes(info);
/* then set up the output nodes */ /* then set up the output nodes */
setup_output_nodes(device, info); setup_output_nodes(device, info);
@ -403,27 +439,29 @@ static DEVICE_STOP( discrete )
if (DISCRETE_PROFILING) if (DISCRETE_PROFILING)
{ {
int nodenum; int count = 0;
linked_list_entry *entry;
osd_ticks_t total = 0; osd_ticks_t total = 0;
osd_ticks_t tresh; osd_ticks_t tresh;
printf("Total Samples: %d\n", info->total_samples);
/* calculate total time */ /* calculate total time */
for (nodenum = 0; nodenum < info->node_count; nodenum++) for (entry = info->step_list; entry != NULL; entry = entry->next)
{ {
node_description *node = info->running_order[nodenum]; node_description *node = (node_description *) entry->ptr;
/* Now step the node */ /* Now step the node */
total += node->run_time; total += node->run_time;
count++;
} }
/* print statistics */ /* print statistics */
tresh = total / info->node_count; printf("Total Samples: %d\n", info->total_samples);
for (nodenum = 0; nodenum < info->node_count; nodenum++) tresh = total / count;
for (entry = info->step_list; entry != NULL; entry = entry->next)
{ {
node_description *node = info->running_order[nodenum]; node_description *node = (node_description *) entry->ptr;
if (node->run_time > tresh) if (node->run_time > tresh)
printf("%3d: %20s %8.2f %10d\n", NODE_INDEX(node->node), node->module.name, (float) node->run_time / (float) total * 100.0, ((int) node->run_time) / info->total_samples); printf("%3d: %20s %8.2f %10d\n", NODE_INDEX(node->node), node->module->name, (float) node->run_time / (float) total * 100.0, ((int) node->run_time) / info->total_samples);
} }
} }
@ -457,22 +495,22 @@ static DEVICE_STOP( discrete )
static DEVICE_RESET( discrete ) static DEVICE_RESET( discrete )
{ {
discrete_info *info = get_safe_token(device); discrete_info *info = get_safe_token(device);
int nodenum; linked_list_entry *entry;
/* loop over all nodes */ /* loop over all nodes */
for (nodenum = 0; nodenum < info->node_count; nodenum++) for (entry = info->node_list; entry != 0; entry = entry->next)
{ {
node_description *node = info->running_order[nodenum]; node_description *node = (node_description *) entry->ptr;
node->output[0] = 0; node->output[0] = 0;
/* if the node has a reset function, call it */ /* if the node has a reset function, call it */
if (node->module.reset) if (node->module->reset)
(*node->module.reset)(info, node); (*node->module->reset)(node);
/* otherwise, just step it */ /* otherwise, just step it */
else if (node->module.step) else if (node->module->step)
(*node->module.step)(info, node); (*node->module->step)(node);
} }
} }
@ -562,87 +600,120 @@ INLINE void bigselect(const device_config *device, node_description *node)
* *
*************************************/ *************************************/
static STREAM_UPDATE( discrete_stream_update ) INLINE void discrete_stream_update_csv(discrete_info *info)
{ {
discrete_info *info = (discrete_info *)param; int nodenum, outputnum;
int samplenum, nodenum, outputnum;
/* Dump any csv logs */
for (outputnum = 0; outputnum < info->num_csvlogs; outputnum++)
{
fprintf(info->disc_csv_file[outputnum], "%" I64FMT "d", ++info->sample_num);
for (nodenum = 0; nodenum < info->csvlog_node[outputnum]->active_inputs; nodenum++)
{
fprintf(info->disc_csv_file[outputnum], ", %f", *info->csvlog_node[outputnum]->input[nodenum]);
}
fprintf(info->disc_csv_file[outputnum], "\n");
}
}
INLINE void discrete_stream_update_wave(discrete_info *info)
{
int outputnum;
double val; double val;
INT16 wave_data_l, wave_data_r; INT16 wave_data_l, wave_data_r;
/* Dump any wave logs */
for (outputnum = 0; outputnum < info->num_wavelogs; outputnum++)
{
/* get nodes to be logged and apply gain, then clip to 16 bit */
val = (*info->wavelog_node[outputnum]->input[0]) * (*info->wavelog_node[outputnum]->input[1]);
val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val;
wave_data_l = (INT16)val;
if (info->wavelog_node[outputnum]->active_inputs == 2)
{
/* DISCRETE_WAVELOG1 */
wav_add_data_16(info->disc_wav_file[outputnum], &wave_data_l, 1);
}
else
{
/* DISCRETE_WAVELOG2 */
val = (*info->wavelog_node[outputnum]->input[2]) * (*info->wavelog_node[outputnum]->input[3]);
val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val;
wave_data_r = (INT16)val;
wav_add_data_16lr(info->disc_wav_file[outputnum], &wave_data_l, &wave_data_r, 1);
}
}
}
INLINE void discrete_stream_update_nodes(discrete_info *info, stream_sample_t **outputs)
{
int outputnum;
double val;
linked_list_entry *entry;
if (DISCRETE_PROFILING)
info->total_samples++;
/* loop over all nodes */
for (entry = info->step_list; entry != NULL; entry = entry->next)
{
node_description *node = (node_description *) entry->ptr;
/* Now step the node */
if (DISCRETE_PROFILING)
node->run_time -= osd_profiling_ticks();
(*node->module->step)(node);
//bigselect(info->device, node);
if (DISCRETE_PROFILING)
node->run_time += osd_profiling_ticks();
}
/* Add gain to the output and put into the buffers */
/* Clipping will be handled by the main sound system */
for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++)
{
val = (*info->output_node[outputnum]->input[0]) * (*info->output_node[outputnum]->input[1]);
*(outputs[outputnum]++) = val;
}
}
static STREAM_UPDATE( discrete_stream_update )
{
discrete_info *info = (discrete_info *)param;
stream_sample_t *outptr[DISCRETE_MAX_OUTPUTS];
int samplenum, nodenum, outputnum;
/* Setup any output streams */
for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++)
outptr[outputnum] = outputs[outputnum];
/* Setup any input streams */ /* Setup any input streams */
for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++) for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++)
{ {
info->input_stream_data[nodenum] = inputs[nodenum]; info->input_stream_data[nodenum] = inputs[nodenum];
} }
/* Now we must do samples iterations of the node list, one output for each step */ if ((info->num_csvlogs > 0) || (info->num_wavelogs > 0))
for (samplenum = 0; samplenum < samples; samplenum++)
{ {
info->total_samples++; /* Now we must do samples iterations of the node list, one output for each step */
/* loop over all nodes */ for (samplenum = 0; samplenum < samples; samplenum++)
for (nodenum = 0; nodenum < info->node_count; nodenum++)
{ {
node_description *node = info->running_order[nodenum]; discrete_stream_update_nodes(info, outptr);
/* Now step the node */
if (DISCRETE_PROFILING)
node->run_time -= osd_profiling_ticks();
if (node->module.step)
(*node->module.step)(info, node);
//bigselect(info->device, node);
if (DISCRETE_PROFILING)
node->run_time += osd_profiling_ticks();
} }
}
/* Add gain to the output and put into the buffers */ else
/* Clipping will be handled by the main sound system */ {
for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++) /* Now we must do samples iterations of the node list, one output for each step */
for (samplenum = 0; samplenum < samples; samplenum++)
{ {
val = (*info->output_node[outputnum]->input[0]) * (*info->output_node[outputnum]->input[1]); discrete_stream_update_nodes(info, outptr);
outputs[outputnum][samplenum] = val; discrete_stream_update_csv(info);
} discrete_stream_update_wave(info);
/* Dump any csv logs */
for (outputnum = 0; outputnum < info->num_csvlogs; outputnum++)
{
fprintf(info->disc_csv_file[outputnum], "%" I64FMT "d", ++info->sample_num);
for (nodenum = 0; nodenum < info->csvlog_node[outputnum]->active_inputs; nodenum++)
{
fprintf(info->disc_csv_file[outputnum], ", %f", *info->csvlog_node[outputnum]->input[nodenum]);
}
fprintf(info->disc_csv_file[outputnum], "\n");
}
/* Dump any wave logs */
for (outputnum = 0; outputnum < info->num_wavelogs; outputnum++)
{
/* get nodes to be logged and apply gain, then clip to 16 bit */
val = (*info->wavelog_node[outputnum]->input[0]) * (*info->wavelog_node[outputnum]->input[1]);
val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val;
wave_data_l = (INT16)val;
if (info->wavelog_node[outputnum]->active_inputs == 2)
{
/* DISCRETE_WAVELOG1 */
wav_add_data_16(info->disc_wav_file[outputnum], &wave_data_l, 1);
}
else
{
/* DISCRETE_WAVELOG2 */
val = (*info->wavelog_node[outputnum]->input[2]) * (*info->wavelog_node[outputnum]->input[3]);
val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val;
wave_data_r = (INT16)val;
wav_add_data_16lr(info->disc_wav_file[outputnum], &wave_data_l, &wave_data_r, 1);
}
}
/* advance input streams */
for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++)
{
info->input_stream_data[nodenum]++;
} }
} }
@ -656,24 +727,24 @@ static STREAM_UPDATE( discrete_stream_update )
* *
*************************************/ *************************************/
static void init_nodes(discrete_info *info, discrete_sound_block *block_list, const device_config *device)
static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device)
{ {
int nodenum; linked_list_entry **step_list = &info->step_list;
linked_list_entry **node_list = &info->node_list;
linked_list_entry *entry;
/* start with no outputs or input streams */ /* start with no outputs or input streams */
info->discrete_outputs = 0; info->discrete_outputs = 0;
info->discrete_input_streams = 0; info->discrete_input_streams = 0;
/* loop over all nodes */ /* loop over all nodes */
for (nodenum = 0; nodenum < info->node_count; nodenum++) for (entry = block_list; entry != NULL; entry = entry->next)
{ {
discrete_sound_block *block = &block_list[nodenum]; discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
node_description *node = &info->node_list[nodenum]; node_description *node = auto_alloc_clear(info->device->machine, node_description);
int inputnum, modulenum; int inputnum, modulenum;
/* our running order just follows the order specified */
info->running_order[nodenum] = node;
/* keep track of special nodes */ /* keep track of special nodes */
if (block->node == NODE_SPECIAL) if (block->node == NODE_SPECIAL)
{ {
@ -721,8 +792,9 @@ static void init_nodes(discrete_info *info, discrete_sound_block *block_list, co
fatalerror("init_nodes() - Unable to find discrete module type %d for NODE_%02d", block->type, NODE_INDEX(block->node)); fatalerror("init_nodes() - Unable to find discrete module type %d for NODE_%02d", block->type, NODE_INDEX(block->node));
/* static inits */ /* static inits */
node->info = info;
node->node = block->node; node->node = block->node;
node->module = module_list[modulenum]; node->module = &module_list[modulenum];
node->output[0] = 0.0; node->output[0] = 0.0;
node->block = block; node->block = block;
@ -733,36 +805,40 @@ static void init_nodes(discrete_info *info, discrete_sound_block *block_list, co
} }
node->context = NULL; node->context = NULL;
node->name = block->name;
node->custom = block->custom; node->custom = block->custom;
/* setup module if custom */ /* setup module if custom */
if (block->type == DST_CUSTOM) if (block->type == DST_CUSTOM)
{ {
const discrete_custom_info *custom = (const discrete_custom_info *)node->custom; const discrete_custom_info *custom = (const discrete_custom_info *)node->custom;
node->module.reset = custom->reset; node->module = &custom->module;
node->module.step = custom->step;
node->module.contextsize = custom->contextsize;
node->custom = custom->custom; node->custom = custom->custom;
} }
/* allocate memory if necessary */ /* allocate memory if necessary */
if (node->module.contextsize) if (node->module->contextsize)
node->context = auto_alloc_array_clear(device->machine, UINT8, node->module.contextsize); node->context = auto_alloc_array_clear(device->machine, UINT8, node->module->contextsize);
/* if we are an stream input node, track that */ /* if we are an stream input node, track that */
if (block->type == DSS_INPUT_STREAM) if (block->type == DSS_INPUT_STREAM)
{ {
if (info->discrete_input_streams == DISCRETE_MAX_OUTPUTS) if (info->discrete_input_streams == DISCRETE_MAX_OUTPUTS)
fatalerror("init_nodes() - There can not be more then %d input stream nodes", DISCRETE_MAX_OUTPUTS); fatalerror("init_nodes() - There can not be more then %d input stream nodes", DISCRETE_MAX_OUTPUTS);
/* we will use the node's context pointer to point to the input stream data */
//node->context = &info->input_stream_data[info->discrete_input_streams++];
node->context = NULL; node->context = NULL;
info->discrete_input_streams++; info->discrete_input_streams++;
} }
/* add to node list */
add_list(info, &node_list, node);
/* our running order just follows the order specified */
/* does the node step ? */
if (node->module->step != NULL)
add_list(info, &step_list, node);
/* and register save state */ /* and register save state */
state_save_register_device_item_array(device, nodenum, node->output); state_save_register_device_item_array(device, node->node, node->output);
} }
/* if no outputs, give an error */ /* if no outputs, give an error */
@ -778,15 +854,16 @@ static void init_nodes(discrete_info *info, discrete_sound_block *block_list, co
* *
*************************************/ *************************************/
static void find_input_nodes(discrete_info *info, discrete_sound_block *block_list) static void find_input_nodes(discrete_info *info)
{ {
int nodenum, inputnum; int inputnum;
linked_list_entry *entry;
/* loop over all nodes */ /* loop over all nodes */
for (nodenum = 0; nodenum < info->node_count; nodenum++) for (entry = info->node_list; entry != NULL; entry = entry->next)
{ {
node_description *node = &info->node_list[nodenum]; node_description *node = (node_description *) entry->ptr;
discrete_sound_block *block = &block_list[nodenum]; const discrete_sound_block *block = node->block;
/* loop over all active inputs */ /* loop over all active inputs */
for (inputnum = 0; inputnum < node->active_inputs; inputnum++) for (inputnum = 0; inputnum < node->active_inputs; inputnum++)
@ -800,7 +877,7 @@ static void find_input_nodes(discrete_info *info, discrete_sound_block *block_li
if (!node_ref) if (!node_ref)
fatalerror("discrete_start - NODE_%02d referenced a non existent node NODE_%02d", NODE_INDEX(node->node), NODE_INDEX(inputnode)); fatalerror("discrete_start - NODE_%02d referenced a non existent node NODE_%02d", NODE_INDEX(node->node), NODE_INDEX(inputnode));
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_%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_%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 */

View File

@ -3228,13 +3228,18 @@
* DISCRETE_CUSTOMx(name of node, * DISCRETE_CUSTOMx(name of node,
* input 0 node or static value, ...) * input 0 node or static value, ...)
* *
* discrete_custom_info = {reset, step, contextsize, custom} * discrete_custom_info = {discrete_module, custom}
* reset = address called to reset a node after creation or system reset * discrete_module = discrete module definition
* step = address called to execute one time delta of output update
* contextsize = size of context to create
* custom = address of specific initialization data * custom = address of specific initialization data
* *
* EXAMPLES: see Donkey Kong * In most case, you should be able to use
*
* discrete_custom_info = {DISCRETE_CUSTOM_MODULE(basename, context type), custom}
*
* if you have used DISCRETE_STEP(basename) and DISCRETE_RESET(basename) to define
* the step/reset procedures.
*
* EXAMPLES: see Donkey Kong, Mario Bros.
* *
*********************************************************************** ***********************************************************************
======================================================================= =======================================================================
@ -3329,13 +3334,13 @@
*************************************/ *************************************/
/* calculate charge exponent using discrete sample time */ /* calculate charge exponent using discrete sample time */
#define RC_CHARGE_EXP(rc) (1.0 - exp(disc_info->neg_sample_time / (rc))) #define RC_CHARGE_EXP(rc) (1.0 - exp(node->info->neg_sample_time / (rc)))
/* calculate charge exponent using given sample time */ /* calculate charge exponent using given sample time */
#define RC_CHARGE_EXP_DT(rc, dt) (1.0 - exp(-(dt) / (rc))) #define RC_CHARGE_EXP_DT(rc, dt) (1.0 - exp(-(dt) / (rc)))
#define RC_CHARGE_NEG_EXP_DT(rc, dt) (1.0 - exp((dt) / (rc))) #define RC_CHARGE_NEG_EXP_DT(rc, dt) (1.0 - exp((dt) / (rc)))
/* calculate discharge exponent using discrete sample time */ /* calculate discharge exponent using discrete sample time */
#define RC_DISCHARGE_EXP(rc) (exp(disc_info->neg_sample_time / (rc))) #define RC_DISCHARGE_EXP(rc) (exp(node->info->neg_sample_time / (rc)))
/* calculate discharge exponent using given sample time */ /* calculate discharge exponent using given sample time */
#define RC_DISCHARGE_EXP_DT(rc, dt) (exp(-(dt) / (rc))) #define RC_DISCHARGE_EXP_DT(rc, dt) (exp(-(dt) / (rc)))
#define RC_DISCHARGE_NEG_EXP_DT(rc, dt) (exp((dt) / (rc))) #define RC_DISCHARGE_NEG_EXP_DT(rc, dt) (exp((dt) / (rc)))
@ -3349,19 +3354,14 @@
#define DISCRETE_STEP_NAME( _func ) _func ## _step #define DISCRETE_STEP_NAME( _func ) _func ## _step
#define DISCRETE_RESET_NAME( _func ) _func ## _reset #define DISCRETE_RESET_NAME( _func ) _func ## _reset
#define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (const discrete_info *disc_info, node_description *node) #define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (node_description *node)
#define DISCRETE_RESET(_func) void DISCRETE_RESET_NAME(_func) (const discrete_info *disc_info, node_description *node) #define DISCRETE_RESET(_func) void DISCRETE_RESET_NAME(_func) (node_description *node)
#define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (disc_info, node) #define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (node)
#define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (disc_info, node) #define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (node)
#if 0 #define DISCRETE_CUSTOM_MODULE(_basename, _context_type) \
#define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (const device_config *device, node_description *node) { DST_CUSTOM, "CUSTOM", 1, sizeof(_context_type), DISCRETE_RESET_NAME(_basename), DISCRETE_STEP_NAME(_basename) }
#define DISCRETE_RESET(_func) void DISCRETE_RESET_NAME(_func) (const device_config *device, node_description *node)
#define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (device, node)
#define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (device, node)
#endif
/************************************* /*************************************
* *
@ -3611,8 +3611,8 @@ struct _discrete_module
const char * name; const char * name;
int num_output; /* Total number of output nodes, i.e. Master node + 1 */ int num_output; /* Total number of output nodes, i.e. Master node + 1 */
size_t contextsize; size_t contextsize;
void (*reset)(const discrete_info *disc_info, node_description *node); /* Called to reset a node after creation or system reset */ void (*reset)(node_description *node); /* Called to reset a node after creation or system reset */
void (*step)(const discrete_info *disc_info, node_description *node); /* Called to execute one time delta of output update */ void (*step)(node_description *node); /* Called to execute one time delta of output update */
}; };
@ -3631,15 +3631,17 @@ struct _node_description
int input_is_node; /* Bit Flags. 1 in bit location means input_is_node */ int input_is_node; /* Bit Flags. 1 in bit location means input_is_node */
const double * input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */ const double * input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */
discrete_module module; /* Copy of the node's module info */
const discrete_sound_block *block; /* Points to the node's setup block. */
void * context; /* Contextual information specific to this node type */ void * context; /* Contextual information specific to this node type */
const char * name; /* Text name string for identification/debug */
const void * custom; /* Custom function specific initialisation data */ const void * custom; /* Custom function specific initialisation data */
const discrete_module *module; /* Node's module info */
const discrete_sound_block *block; /* Points to the node's setup block. */
const discrete_info *info; /* Points to the parent */
osd_ticks_t run_time; osd_ticks_t run_time;
}; };
/************************************* /*************************************
* *
* Core runtime info * Core runtime info
@ -3650,6 +3652,13 @@ struct _node_description
* *
*************************************/ *************************************/
typedef struct _linked_list_entry linked_list_entry;
struct _linked_list_entry
{
void *ptr;
linked_list_entry *next;
};
struct _discrete_info struct _discrete_info
{ {
const device_config *device; const device_config *device;
@ -3660,10 +3669,16 @@ struct _discrete_info
double neg_sample_time; double neg_sample_time;
/* internal node tracking */ /* internal node tracking */
int node_count;
node_description **running_order;
node_description **indexed_node; node_description **indexed_node;
node_description *node_list;
/* list of all nodes */
linked_list_entry *node_list; /* node_description * */
/* list of nodes which step */
linked_list_entry *step_list; /* node_description * */
/* list of discrete blocks after prescan (IMPORT, DELETE, REPLACE) */
linked_list_entry *block_list; /* discrete_sound_block * */
/* the input streams */ /* the input streams */
int discrete_input_streams; int discrete_input_streams;
@ -3953,9 +3968,7 @@ struct _discrete_adsr
typedef struct _discrete_custom_info discrete_custom_info; typedef struct _discrete_custom_info discrete_custom_info;
struct _discrete_custom_info struct _discrete_custom_info
{ {
void (*reset)(const discrete_info *disc_info, node_description *node); /* Called to reset a node after creation or system reset */ const discrete_module module;
void (*step)(const discrete_info *disc_info, node_description *node); /* Called to execute one time delta of output update */
size_t contextsize;
const void *custom; /* Custom function specific initialisation data */ const void *custom; /* Custom function specific initialisation data */
}; };
@ -4184,6 +4197,12 @@ enum
DSO_IMPORT, /* import from another discrete block */ DSO_IMPORT, /* import from another discrete block */
DSO_REPLACE, /* replace next node */ DSO_REPLACE, /* replace next node */
DSO_DELETE, /* delete nodes */ DSO_DELETE, /* delete nodes */
/* Parallel execution */
DSO_TASK_START, /* start of parallel task */
DSO_TASK_END, /* end of parallel task */
DSO_TASK_SYNC, /* wait for all parallel tasks to finish */
/* Marks end of this enum -- must be last entry ! */ /* Marks end of this enum -- must be last entry ! */
DSO_LAST DSO_LAST

View File

@ -343,9 +343,7 @@ static DISCRETE_RESET( dkong_custom_mixer )
static const discrete_custom_info dkong_custom_mixer_info = static const discrete_custom_info dkong_custom_mixer_info =
{ {
DISCRETE_RESET_NAME( dkong_custom_mixer ), DISCRETE_CUSTOM_MODULE( dkong_custom_mixer, struct dkong_custom_mixer_context),
DISCRETE_STEP_NAME( dkong_custom_mixer ),
sizeof(struct dkong_custom_mixer_context),
NULL NULL
}; };
#endif #endif

View File

@ -192,7 +192,7 @@ static DISCRETE_STEP( mario_custom_run )
double t1 = 0.5 / LS624_F(MARIO_CUSTOM_C1, MARIO_CUSTOM_IN1, RUN_VCO_VOLTAGE); double t1 = 0.5 / LS624_F(MARIO_CUSTOM_C1, MARIO_CUSTOM_IN1, RUN_VCO_VOLTAGE);
double t2 = 0.5 / LS624_F(MARIO_CUSTOM_C2, MARIO_CUSTOM_IN2, RUN_VCO_VOLTAGE); double t2 = 0.5 / LS624_F(MARIO_CUSTOM_C2, MARIO_CUSTOM_IN2, RUN_VCO_VOLTAGE);
double sample_t = disc_info->sample_time; double sample_t = node->info->sample_time;
double vn, t; double vn, t;
//if (MARIO_CUSTOM_VOUT) //if (MARIO_CUSTOM_VOUT)
@ -258,9 +258,7 @@ static DISCRETE_RESET( mario_custom_run )
static const discrete_custom_info mario_custom_run_info = static const discrete_custom_info mario_custom_run_info =
{ {
DISCRETE_RESET_NAME( mario_custom_run ), DISCRETE_CUSTOM_MODULE( mario_custom_run, struct mario_custom_run_context),
DISCRETE_STEP_NAME( mario_custom_run ),
sizeof(struct mario_custom_run_context),
NULL NULL
}; };