mirror of
https://github.com/holub/mame
synced 2025-05-22 13:48:55 +03:00
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:
parent
dc0df4572e
commit
20caff1c3b
@ -234,7 +234,7 @@ static DISCRETE_STEP(dsd_555_astbl)
|
||||
* 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.
|
||||
* 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 */
|
||||
x_time = x_time / disc_info->sample_time;
|
||||
x_time = x_time / node->info->sample_time;
|
||||
|
||||
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;
|
||||
|
||||
/* 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)
|
||||
context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]);
|
||||
else
|
||||
@ -548,7 +548,7 @@ static DISCRETE_RESET(dsd_555_mstbl)
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -642,7 +642,7 @@ static DISCRETE_STEP(dsd_555_cc)
|
||||
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_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 */
|
||||
@ -888,7 +888,7 @@ static DISCRETE_STEP(dsd_555_cc)
|
||||
context->cap_voltage = v_cap_next;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
@ -1171,7 +1171,7 @@ static DISCRETE_STEP(dsd_555_vco1)
|
||||
double v_cap; /* Current voltage on capacitor, before 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;
|
||||
|
||||
/* Check: if the Control Voltage node is connected. */
|
||||
@ -1275,7 +1275,7 @@ static DISCRETE_STEP(dsd_555_vco1)
|
||||
context->cap_voltage = v_cap_next;
|
||||
|
||||
/* 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;
|
||||
|
||||
switch (context->output_type)
|
||||
@ -1403,7 +1403,7 @@ static DISCRETE_STEP(dsd_566)
|
||||
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
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)
|
||||
context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]);
|
||||
else
|
||||
@ -1608,7 +1608,7 @@ static DISCRETE_STEP(dsd_ls624)
|
||||
double en = 0.0f;
|
||||
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 = 1.0f / (2.0f * LS624_F(DSD_LS624__C, DSD_LS624__VMOD, DSD_LS624__VRNG));
|
||||
t = context->remain;
|
||||
|
@ -229,7 +229,7 @@ static DISCRETE_RESET(dst_filter1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -259,7 +259,7 @@ static void calculate_filter2_coefficients(const discrete_info *disc_info,
|
||||
double w; /* cutoff freq, in radians/sec */
|
||||
double w_squared;
|
||||
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;
|
||||
|
||||
/* calculate digital filter coefficents */
|
||||
@ -318,7 +318,7 @@ static DISCRETE_RESET(dst_filter2)
|
||||
{
|
||||
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->b0, &context->b1, &context->b2);
|
||||
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 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->b0, &context->b1, &context->b2);
|
||||
context->b0 *= gain;
|
||||
@ -577,7 +577,7 @@ static DISCRETE_STEP(dst_rcdisc)
|
||||
if (DST_RCDISC__ENABLE)
|
||||
{
|
||||
node->output[0] = DST_RCDISC__IN * exp(context->t / context->exponent0);
|
||||
context->t += disc_info->sample_time;
|
||||
context->t += node->info->sample_time;
|
||||
} else
|
||||
{
|
||||
context->state = 0;
|
||||
@ -780,17 +780,17 @@ static DISCRETE_RESET( dst_rcdisc4)
|
||||
/* some error checking. */
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1236,7 +1236,7 @@ static DISCRETE_RESET(dst_rcintegrate)
|
||||
struct dst_rcintegrate_context *context = (struct dst_rcintegrate_context *)node->context;
|
||||
|
||||
double r;
|
||||
double dt = disc_info->sample_time;
|
||||
double dt = node->info->sample_time;
|
||||
|
||||
context->type = DST_RCINTEGRATE__TYPE;
|
||||
|
||||
@ -1312,7 +1312,7 @@ static DISCRETE_RESET(dst_sallen_key)
|
||||
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->b0, &context->b1, &context->b2);
|
||||
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);
|
||||
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(disc_info, f2, DISC_FILTER_LOWPASS, &context->a1_1, &context->b0_1, &context->b1_1);
|
||||
calculate_filter1_coefficients(node->info, f1, DISC_FILTER_LOWPASS, &context->a1_0, &context->b0_0, &context->b1_0);
|
||||
calculate_filter1_coefficients(node->info, f2, DISC_FILTER_LOWPASS, &context->a1_1, &context->b0_1, &context->b1_1);
|
||||
|
||||
/* Initialize the object */
|
||||
node->output[0] = 0;
|
||||
|
@ -15,6 +15,8 @@
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#define EXPERIMENTAL_STREAM_PARALLEL (0)
|
||||
|
||||
#define DSS_INPUT__GAIN (*(node->input[0]))
|
||||
#define DSS_INPUT__OFFSET (*(node->input[1]))
|
||||
#define DSS_INPUT__INIT (*(node->input[2]))
|
||||
@ -54,7 +56,7 @@ READ8_DEVICE_HANDLER(discrete_sound_r)
|
||||
/* Bring the system up to now */
|
||||
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;
|
||||
}
|
||||
@ -65,7 +67,7 @@ READ8_DEVICE_HANDLER(discrete_sound_r)
|
||||
return data;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if EXPERIMENTAL_STREAM_PARALLEL
|
||||
static STREAM_BACKGROUND_CALLBACK( disc_cb )
|
||||
{
|
||||
node_description *node = (node_description *) ptr;
|
||||
@ -86,7 +88,7 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
|
||||
UINT8 last_data = *node_data;
|
||||
UINT8 new_data = 0;
|
||||
|
||||
switch (node->module.type)
|
||||
switch (node->module->type)
|
||||
{
|
||||
case DSS_INPUT_DATA:
|
||||
new_data = data;
|
||||
@ -102,7 +104,7 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
|
||||
|
||||
if (last_data != new_data)
|
||||
{
|
||||
#if 1
|
||||
#if !EXPERIMENTAL_STREAM_PARALLEL
|
||||
/* Bring the system up to now */
|
||||
stream_update(info->discrete_stream);
|
||||
|
||||
@ -172,12 +174,12 @@ static DISCRETE_RESET(dss_adjustment)
|
||||
|
||||
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)
|
||||
fatalerror("DISCRETE_ADJUSTMENT_TAG - NODE_%d has invalid tag", node->node-NODE_00);
|
||||
}
|
||||
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->pmin = DSS_ADJUSTMENT__PMIN;
|
||||
@ -233,7 +235,7 @@ static DISCRETE_RESET(dss_input)
|
||||
{
|
||||
UINT8 *node_data = (UINT8 *)node->context;
|
||||
|
||||
switch (node->module.type)
|
||||
switch (node->module->type)
|
||||
{
|
||||
case DSS_INPUT_DATA:
|
||||
*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 *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)
|
||||
{
|
||||
int istream = DSS_INPUT_STREAM__STREAM;
|
||||
/* we will use the node's context pointer to point to the input stream data */
|
||||
assert(istream < disc_info->discrete_input_streams);
|
||||
node->context = (discrete_info *) &disc_info->input_stream_data[istream];
|
||||
assert(istream < node->info->discrete_input_streams);
|
||||
node->context = (discrete_info *) &node->info->input_stream_data[istream];
|
||||
}
|
||||
|
@ -384,11 +384,11 @@ static DISCRETE_RESET(dst_dac_r1)
|
||||
if (info->ladderLength < 2)
|
||||
{
|
||||
/* 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 )
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -609,7 +609,7 @@ static DISCRETE_STEP(dst_integrate)
|
||||
i_neg = context->v_max_in / info->r1;
|
||||
i_pos = (DST_INTEGRATE__TRG0 - OP_AMP_NORTON_VBE) / info->r2;
|
||||
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;
|
||||
|
||||
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_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;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -646,7 +646,7 @@ static DISCRETE_RESET(dst_integrate)
|
||||
v = info->v1 * info->r3 / (info->r2 + info->r3); /* vRef */
|
||||
v = info->v1 - v; /* actual charging voltage */
|
||||
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;
|
||||
}
|
||||
@ -1227,7 +1227,7 @@ static DISCRETE_RESET(dst_mixer)
|
||||
context->r_node_bit_flag = 0;
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
/* 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
|
||||
@ -1439,7 +1439,7 @@ static DISCRETE_STEP(dst_oneshot)
|
||||
|
||||
if (do_count)
|
||||
{
|
||||
context->countdown -= disc_info->sample_time;
|
||||
context->countdown -= node->info->sample_time;
|
||||
if(context->countdown <= 0.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;
|
||||
|
||||
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->last_en = 0;
|
||||
}
|
||||
@ -1560,7 +1560,7 @@ static DISCRETE_STEP(dst_samphold)
|
||||
if (DST_SAMPHOLD__CLOCK == 0) node->output[0] = DST_SAMPHOLD__IN0;
|
||||
break;
|
||||
default:
|
||||
discrete_log(disc_info, "dst_samphold_step - Invalid clocktype passed");
|
||||
discrete_log(node->info, "dst_samphold_step - Invalid clocktype passed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1762,7 +1762,7 @@ static DISCRETE_STEP(dst_transform)
|
||||
top = (int)number1 ^ (int)top;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@ -1869,7 +1869,7 @@ static DISCRETE_RESET(dst_op_amp)
|
||||
}
|
||||
else
|
||||
/* linear charge */
|
||||
context->exponent = disc_info->sample_rate * info->c;
|
||||
context->exponent = node->info->sample_rate * info->c;
|
||||
}
|
||||
|
||||
if (info->r3 > 0)
|
||||
|
@ -199,10 +199,10 @@ static DISCRETE_STEP(dss_counter)
|
||||
if (context->clock_type == DISC_CLK_IS_FREQ)
|
||||
{
|
||||
/* 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;
|
||||
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
|
||||
{
|
||||
@ -401,7 +401,7 @@ static DISCRETE_STEP(dss_lfsr)
|
||||
if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ)
|
||||
{
|
||||
/* 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;
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
fbresult = fbresult * lfsr_desc->feedback_function2_mask;
|
||||
/* Then we left shift the register, */
|
||||
context->lfsr_reg = context->lfsr_reg << 1;
|
||||
/* 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 */
|
||||
/* Fetch the feedback bits */
|
||||
fb0 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel0) & 0x01;
|
||||
fb1 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel1) & 0x01;
|
||||
/* Now do the combo on them */
|
||||
fbresult = dss_lfsr_function(disc_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);
|
||||
fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function0, fb0, fb1, 0x01);
|
||||
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 */
|
||||
@ -500,7 +500,7 @@ static DISCRETE_RESET(dss_lfsr)
|
||||
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))
|
||||
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);
|
||||
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;
|
||||
fb1=(context->lfsr_reg >> lfsr_desc->feedback_bitsel1) & 0x01;
|
||||
/* Now do the combo on them */
|
||||
fbresult = dss_lfsr_function(disc_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);
|
||||
fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function0, fb0, fb1, 0x01);
|
||||
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 */
|
||||
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))
|
||||
{
|
||||
/* 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 */
|
||||
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. */
|
||||
/* 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)
|
||||
{
|
||||
/* 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;
|
||||
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
|
||||
{
|
||||
@ -754,7 +754,7 @@ static DISCRETE_STEP(dss_op_amp_osc)
|
||||
UINT8 force_charge = 0;
|
||||
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 */
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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)]);
|
||||
}
|
||||
else
|
||||
@ -1078,7 +1078,7 @@ static DISCRETE_STEP(dss_sawtoothwave)
|
||||
/* boils out to */
|
||||
/* phase step = (2Pi*output freq)/sample freq) */
|
||||
/* 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)
|
||||
@ -1257,7 +1257,7 @@ static DISCRETE_STEP(dss_sinewave)
|
||||
/* boils out to */
|
||||
/* phase step = (2Pi*output freq)/sample freq) */
|
||||
/* 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)
|
||||
@ -1323,7 +1323,7 @@ static DISCRETE_STEP(dss_squarewave)
|
||||
/* boils out to */
|
||||
/* phase step = (2Pi*output freq)/sample freq) */
|
||||
/* 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)
|
||||
@ -1392,7 +1392,7 @@ static DISCRETE_RESET(dss_squarewfix)
|
||||
{
|
||||
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;
|
||||
|
||||
/* 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) */
|
||||
/* boils out to */
|
||||
/* 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.*/
|
||||
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);
|
||||
}
|
||||
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;
|
||||
case DISC_OSC_INVERTER_IS_TYPE5:
|
||||
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);
|
||||
}
|
||||
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;
|
||||
default:
|
||||
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;
|
||||
|
||||
/* exponent */
|
||||
context->w = exp(-disc_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->w = exp(-node->info->sample_time / (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;
|
||||
context->v_cap = 0;
|
||||
context->v_g2_old = 0;
|
||||
@ -1708,7 +1708,7 @@ static DISCRETE_STEP(dss_trianglewave)
|
||||
/* boils out to */
|
||||
/* phase step = (2Pi*output freq)/sample freq) */
|
||||
/* 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)
|
||||
|
@ -57,16 +57,14 @@
|
||||
|
||||
#define DISCRETE_PROFILING (0)
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Prototypes
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void init_nodes(discrete_info *info, discrete_sound_block *block_list, const device_config *device);
|
||||
static void find_input_nodes(discrete_info *info, discrete_sound_block *block_list);
|
||||
static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device);
|
||||
static void find_input_nodes(discrete_info *info);
|
||||
static void setup_output_nodes(const device_config *device, discrete_info *info);
|
||||
static void setup_disc_logs(discrete_info *info);
|
||||
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 }
|
||||
};
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* 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;
|
||||
|
||||
@ -258,56 +268,103 @@ static int discrete_build_list(discrete_info *info, discrete_sound_block *intf,
|
||||
/* scan imported */
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
linked_list_entry *entry;
|
||||
|
||||
node_count++;
|
||||
if (intf[node_count].type == DSS_NULL)
|
||||
fatalerror("discrete_build_list: DISCRETE_REPLACE at end of node_list");
|
||||
|
||||
for (i = 0; i < offset; i++)
|
||||
if (out[i].type != NODE_SPECIAL )
|
||||
if (out[i].node == intf[node_count].node)
|
||||
for (entry = info->block_list; entry != NULL; entry = entry->next)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= offset)
|
||||
if (entry == NULL)
|
||||
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)
|
||||
{
|
||||
int i,p,deleted;
|
||||
int p,deleted;
|
||||
linked_list_entry *entry, *last;
|
||||
|
||||
p = 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]) &&
|
||||
(out[i].node <= intf[node_count].input_node[1]))
|
||||
discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
|
||||
|
||||
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) );
|
||||
deleted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
out[p++] = out[i];
|
||||
discrete_log(info, "discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(block->node) );
|
||||
if (last != NULL)
|
||||
last->next = entry->next;
|
||||
else
|
||||
info->block_list = entry->next;
|
||||
}
|
||||
}
|
||||
offset -= deleted;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
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 )
|
||||
{
|
||||
discrete_sound_block *intf;
|
||||
linked_list_entry **intf;
|
||||
discrete_sound_block *intf_start = (discrete_sound_block *)device->static_config;
|
||||
discrete_info *info = get_safe_token(device);
|
||||
char name[32];
|
||||
@ -337,50 +394,29 @@ static DEVICE_START( discrete )
|
||||
|
||||
/* create the logfile */
|
||||
sprintf(name, "discrete%s.log", device->tag);
|
||||
if (DISCRETE_DEBUGLOG && !info->disclogfile)
|
||||
if (DISCRETE_DEBUGLOG)
|
||||
info->disclogfile = fopen(name, "w");
|
||||
|
||||
/* Build the final block list */
|
||||
intf = auto_alloc_array_clear(device->machine, discrete_sound_block, DISCRETE_MAX_NODES);
|
||||
discrete_build_list(info, intf_start, intf, 0);
|
||||
info->block_list = NULL;
|
||||
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 */
|
||||
discrete_log(info, "discrete_start() - Doing node list sanity check");
|
||||
for (info->node_count = 0; intf[info->node_count].type != DSS_NULL; info->node_count++)
|
||||
{
|
||||
/* make sure we don't have too many nodes overall */
|
||||
if (info->node_count > DISCRETE_MAX_NODES)
|
||||
fatalerror("discrete_start() - Upper limit of %d nodes exceeded, have you terminated the interface block?", DISCRETE_MAX_NODES);
|
||||
discrete_sanity_check(info);
|
||||
|
||||
/* 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);
|
||||
/* Start with empty lists */
|
||||
info->node_list = NULL;
|
||||
info->step_list = NULL;
|
||||
|
||||
/* allocate memory to hold pointers to nodes by index */
|
||||
info->indexed_node = auto_alloc_array_clear(device->machine, node_description *, DISCRETE_MAX_NODES);
|
||||
|
||||
/* 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 */
|
||||
find_input_nodes(info, intf);
|
||||
find_input_nodes(info);
|
||||
|
||||
/* then set up the output nodes */
|
||||
setup_output_nodes(device, info);
|
||||
@ -403,27 +439,29 @@ static DEVICE_STOP( discrete )
|
||||
|
||||
if (DISCRETE_PROFILING)
|
||||
{
|
||||
int nodenum;
|
||||
int count = 0;
|
||||
linked_list_entry *entry;
|
||||
osd_ticks_t total = 0;
|
||||
osd_ticks_t tresh;
|
||||
|
||||
printf("Total Samples: %d\n", info->total_samples);
|
||||
/* 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 */
|
||||
total += node->run_time;
|
||||
count++;
|
||||
}
|
||||
/* print statistics */
|
||||
tresh = total / info->node_count;
|
||||
for (nodenum = 0; nodenum < info->node_count; nodenum++)
|
||||
printf("Total Samples: %d\n", info->total_samples);
|
||||
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)
|
||||
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 )
|
||||
{
|
||||
discrete_info *info = get_safe_token(device);
|
||||
int nodenum;
|
||||
linked_list_entry *entry;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* if the node has a reset function, call it */
|
||||
if (node->module.reset)
|
||||
(*node->module.reset)(info, node);
|
||||
if (node->module->reset)
|
||||
(*node->module->reset)(node);
|
||||
|
||||
/* otherwise, just step it */
|
||||
else if (node->module.step)
|
||||
(*node->module.step)(info, node);
|
||||
else if (node->module->step)
|
||||
(*node->module->step)(node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -562,12 +600,96 @@ INLINE void bigselect(const device_config *device, node_description *node)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
INLINE void discrete_stream_update_csv(discrete_info *info)
|
||||
{
|
||||
int 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;
|
||||
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;
|
||||
double val;
|
||||
INT16 wave_data_l, wave_data_r;
|
||||
|
||||
/* Setup any output streams */
|
||||
for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++)
|
||||
outptr[outputnum] = outputs[outputnum];
|
||||
|
||||
/* Setup any input streams */
|
||||
for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++)
|
||||
@ -575,74 +697,23 @@ static STREAM_UPDATE( discrete_stream_update )
|
||||
info->input_stream_data[nodenum] = inputs[nodenum];
|
||||
}
|
||||
|
||||
/* Now we must do samples iterations of the node list, one output for each step */
|
||||
for (samplenum = 0; samplenum < samples; samplenum++)
|
||||
if ((info->num_csvlogs > 0) || (info->num_wavelogs > 0))
|
||||
{
|
||||
info->total_samples++;
|
||||
/* loop over all nodes */
|
||||
for (nodenum = 0; nodenum < info->node_count; nodenum++)
|
||||
/* Now we must do samples iterations of the node list, one output for each step */
|
||||
for (samplenum = 0; samplenum < samples; samplenum++)
|
||||
{
|
||||
node_description *node = info->running_order[nodenum];
|
||||
|
||||
/* 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();
|
||||
|
||||
discrete_stream_update_nodes(info, outptr);
|
||||
}
|
||||
|
||||
/* 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++)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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]);
|
||||
outputs[outputnum][samplenum] = val;
|
||||
}
|
||||
discrete_stream_update_nodes(info, outptr);
|
||||
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 */
|
||||
info->discrete_outputs = 0;
|
||||
info->discrete_input_streams = 0;
|
||||
|
||||
/* 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];
|
||||
node_description *node = &info->node_list[nodenum];
|
||||
discrete_sound_block *block = (discrete_sound_block *) entry->ptr;
|
||||
node_description *node = auto_alloc_clear(info->device->machine, node_description);
|
||||
int inputnum, modulenum;
|
||||
|
||||
/* our running order just follows the order specified */
|
||||
info->running_order[nodenum] = node;
|
||||
|
||||
/* keep track of special nodes */
|
||||
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));
|
||||
|
||||
/* static inits */
|
||||
node->info = info;
|
||||
node->node = block->node;
|
||||
node->module = module_list[modulenum];
|
||||
node->module = &module_list[modulenum];
|
||||
node->output[0] = 0.0;
|
||||
node->block = block;
|
||||
|
||||
@ -733,36 +805,40 @@ static void init_nodes(discrete_info *info, discrete_sound_block *block_list, co
|
||||
}
|
||||
|
||||
node->context = NULL;
|
||||
node->name = block->name;
|
||||
node->custom = block->custom;
|
||||
|
||||
/* setup module if custom */
|
||||
if (block->type == DST_CUSTOM)
|
||||
{
|
||||
const discrete_custom_info *custom = (const discrete_custom_info *)node->custom;
|
||||
node->module.reset = custom->reset;
|
||||
node->module.step = custom->step;
|
||||
node->module.contextsize = custom->contextsize;
|
||||
node->module = &custom->module;
|
||||
node->custom = custom->custom;
|
||||
}
|
||||
|
||||
/* allocate memory if necessary */
|
||||
if (node->module.contextsize)
|
||||
node->context = auto_alloc_array_clear(device->machine, UINT8, node->module.contextsize);
|
||||
if (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 (block->type == DSS_INPUT_STREAM)
|
||||
{
|
||||
if (info->discrete_input_streams == 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;
|
||||
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 */
|
||||
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 */
|
||||
@ -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 */
|
||||
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];
|
||||
discrete_sound_block *block = &block_list[nodenum];
|
||||
node_description *node = (node_description *) entry->ptr;
|
||||
const discrete_sound_block *block = node->block;
|
||||
|
||||
/* loop over all active inputs */
|
||||
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)
|
||||
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));
|
||||
|
||||
node->input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); /* Link referenced node out to input */
|
||||
|
@ -3228,13 +3228,18 @@
|
||||
* DISCRETE_CUSTOMx(name of node,
|
||||
* input 0 node or static value, ...)
|
||||
*
|
||||
* discrete_custom_info = {reset, step, contextsize, custom}
|
||||
* reset = address called to reset a node after creation or system reset
|
||||
* step = address called to execute one time delta of output update
|
||||
* contextsize = size of context to create
|
||||
* discrete_custom_info = {discrete_module, custom}
|
||||
* discrete_module = discrete module definition
|
||||
* 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 */
|
||||
#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 */
|
||||
#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)))
|
||||
|
||||
/* 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 */
|
||||
#define RC_DISCHARGE_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_RESET_NAME( _func ) _func ## _reset
|
||||
|
||||
#define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (const discrete_info *disc_info, node_description *node)
|
||||
#define DISCRETE_RESET(_func) void DISCRETE_RESET_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) (node_description *node)
|
||||
|
||||
#define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (disc_info, node)
|
||||
#define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (disc_info, node)
|
||||
#define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (node)
|
||||
#define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (node)
|
||||
|
||||
#if 0
|
||||
#define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (const device_config *device, node_description *node)
|
||||
#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
|
||||
#define DISCRETE_CUSTOM_MODULE(_basename, _context_type) \
|
||||
{ DST_CUSTOM, "CUSTOM", 1, sizeof(_context_type), DISCRETE_RESET_NAME(_basename), DISCRETE_STEP_NAME(_basename) }
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -3611,8 +3611,8 @@ struct _discrete_module
|
||||
const char * name;
|
||||
int num_output; /* Total number of output nodes, i.e. Master node + 1 */
|
||||
size_t contextsize;
|
||||
void (*reset)(const discrete_info *disc_info, 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 (*reset)(node_description *node); /* Called to reset a node after creation or system reset */
|
||||
void (*step)(node_description *node); /* Called to execute one time delta of output update */
|
||||
};
|
||||
|
||||
|
||||
@ -3631,11 +3631,13 @@ struct _node_description
|
||||
int input_is_node; /* Bit Flags. 1 in bit location means input_is_node */
|
||||
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 */
|
||||
const char * name; /* Text name string for identification/debug */
|
||||
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;
|
||||
};
|
||||
|
||||
@ -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
|
||||
{
|
||||
const device_config *device;
|
||||
@ -3660,10 +3669,16 @@ struct _discrete_info
|
||||
double neg_sample_time;
|
||||
|
||||
/* internal node tracking */
|
||||
int node_count;
|
||||
node_description **running_order;
|
||||
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 */
|
||||
int discrete_input_streams;
|
||||
@ -3953,9 +3968,7 @@ struct _discrete_adsr
|
||||
typedef struct _discrete_custom_info 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 */
|
||||
void (*step)(const discrete_info *disc_info, node_description *node); /* Called to execute one time delta of output update */
|
||||
size_t contextsize;
|
||||
const discrete_module module;
|
||||
const void *custom; /* Custom function specific initialisation data */
|
||||
};
|
||||
|
||||
@ -4185,6 +4198,12 @@ enum
|
||||
DSO_REPLACE, /* replace next node */
|
||||
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 ! */
|
||||
DSO_LAST
|
||||
};
|
||||
|
@ -343,9 +343,7 @@ static DISCRETE_RESET( dkong_custom_mixer )
|
||||
|
||||
static const discrete_custom_info dkong_custom_mixer_info =
|
||||
{
|
||||
DISCRETE_RESET_NAME( dkong_custom_mixer ),
|
||||
DISCRETE_STEP_NAME( dkong_custom_mixer ),
|
||||
sizeof(struct dkong_custom_mixer_context),
|
||||
DISCRETE_CUSTOM_MODULE( dkong_custom_mixer, struct dkong_custom_mixer_context),
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
@ -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 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;
|
||||
|
||||
//if (MARIO_CUSTOM_VOUT)
|
||||
@ -258,9 +258,7 @@ static DISCRETE_RESET( mario_custom_run )
|
||||
|
||||
static const discrete_custom_info mario_custom_run_info =
|
||||
{
|
||||
DISCRETE_RESET_NAME( mario_custom_run ),
|
||||
DISCRETE_STEP_NAME( mario_custom_run ),
|
||||
sizeof(struct mario_custom_run_context),
|
||||
DISCRETE_CUSTOM_MODULE( mario_custom_run, struct mario_custom_run_context),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user