diff options
author | Derrick Renaud <derrickr@mamedev.org> | 2008-10-29 01:59:44 +0000 |
---|---|---|
committer | Derrick Renaud <derrickr@mamedev.org> | 2008-10-29 01:59:44 +0000 |
commit | 65d187ecf29fdbfa1bc006d61fb24817c0644f43 (patch) | |
tree | 84a6b2f8b85f4e64796d0eddf9b5ee3659b785d0 | |
parent | 0a82f626442845d3ac98b5c0dafc447ccbd5d87c (diff) |
More Discrete module optimizations.
Added optimized custom mixer to Donkey Kong.
-rw-r--r-- | src/emu/sound/disc_dev.c | 113 | ||||
-rw-r--r-- | src/emu/sound/disc_flt.c | 218 | ||||
-rw-r--r-- | src/emu/sound/disc_mth.c | 194 | ||||
-rw-r--r-- | src/emu/sound/disc_wav.c | 41 | ||||
-rw-r--r-- | src/emu/sound/discrete.c | 47 | ||||
-rw-r--r-- | src/emu/sound/discrete.h | 156 | ||||
-rw-r--r-- | src/mame/audio/dkong.c | 377 | ||||
-rw-r--r-- | src/mame/audio/firetrk.c | 2 | ||||
-rw-r--r-- | src/mame/audio/hitme.c | 2 | ||||
-rw-r--r-- | src/mame/audio/madalien.c | 4 | ||||
-rw-r--r-- | src/mame/audio/mw8080bw.c | 5 | ||||
-rw-r--r-- | src/mame/audio/phoenix.c | 1 | ||||
-rw-r--r-- | src/mame/audio/qix.c | 4 |
13 files changed, 661 insertions, 503 deletions
diff --git a/src/emu/sound/disc_dev.c b/src/emu/sound/disc_dev.c index ba35bcb6cd5..7ad1fcdf940 100644 --- a/src/emu/sound/disc_dev.c +++ b/src/emu/sound/disc_dev.c @@ -23,7 +23,7 @@ * ************************************************************************/ -#define DEFAULT_555_CAP_BLEED RES_M(10) +#define DEFAULT_555_BLEED_R RES_M(10) struct dsd_555_astbl_context { @@ -42,8 +42,12 @@ struct dsd_555_astbl_context double exp_bleed; double exp_charge; double exp_discharge; + double t_rc_bleed; double t_rc_charge; double t_rc_discharge; + double last_r1; + double last_r2; + double last_c; }; struct dsd_555_mstbl_context @@ -147,7 +151,7 @@ struct dsd_ls624_context #define DSD_555_ASTBL_RC_MASK 0x0e /* charge/discharge constants */ -#define DSD_555_ASTBL_T_RC_BLEED (DEFAULT_555_CAP_BLEED * DSD_555_ASTBL__C) +#define DSD_555_ASTBL_T_RC_BLEED (DEFAULT_555_BLEED_R * DSD_555_ASTBL__C) /* Use quick charge if specified. */ #define DSD_555_ASTBL_T_RC_CHARGE ((DSD_555_ASTBL__R1 + ((info->options & DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE) ? 0 : DSD_555_ASTBL__R2)) * DSD_555_ASTBL__C) #define DSD_555_ASTBL_T_RC_DISCHARGE (DSD_555_ASTBL__R2 * DSD_555_ASTBL__C) @@ -161,11 +165,10 @@ static void dsd_555_astbl_step(node_description *node) int count_r = 0; double dt; /* change in time */ double x_time = 0; /* time since change happened */ - double t_rc = 0; /* RC time constant */ double v_cap = context->cap_voltage; /* Current voltage on capacitor, before dt */ double v_cap_next = 0; /* Voltage on capacitor, after dt */ - double v_charge, exponent; - int update_exponent, update_t_rc; + double v_charge, exponent = 0; + int update_exponent = 0; /* put commonly used stuff in local variables for speed */ double threshold = context->threshold; @@ -246,9 +249,20 @@ static void dsd_555_astbl_step(node_description *node) } else { + /* Update charge contstants and exponents if nodes changed */ + if (context->has_rc_nodes && (DSD_555_ASTBL__R1 != context->last_r1 || DSD_555_ASTBL__C != context->last_c || DSD_555_ASTBL__R2 != context->last_r2)) + { + context->t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED; + context->t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE; + context->t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE; + context->exp_bleed = RC_CHARGE_EXP(context->t_rc_bleed); + context->exp_charge = RC_CHARGE_EXP(context->t_rc_charge); + context->exp_discharge = RC_CHARGE_EXP(context->t_rc_discharge); + context->last_r1 = DSD_555_ASTBL__R1; + context->last_r2 = DSD_555_ASTBL__R2; + context->last_c = DSD_555_ASTBL__C; + } /* Keep looping until all toggling in time sample is used up. */ - update_t_rc = context->has_rc_nodes; - update_exponent = update_t_rc; do { if (context->flip_flop) @@ -258,10 +272,7 @@ static void dsd_555_astbl_step(node_description *node) /* Oscillation disabled because there is no longer any charge resistor. */ /* Bleed the cap due to circuit losses. */ if (update_exponent) - { - t_rc = DSD_555_ASTBL_T_RC_BLEED; - exponent = 1.0 - exp(-(dt / t_rc)); - } + exponent = RC_CHARGE_EXP_DT(context->t_rc_bleed, dt); else exponent = context->exp_bleed; v_cap_next = v_cap - (v_cap * exponent); @@ -270,12 +281,8 @@ static void dsd_555_astbl_step(node_description *node) else { /* Charging */ - if (update_t_rc) - t_rc = DSD_555_ASTBL_T_RC_CHARGE; - else - t_rc = context->t_rc_charge; if (update_exponent) - exponent = 1.0 - exp(-(dt / t_rc )); + exponent = RC_CHARGE_EXP_DT(context->t_rc_charge, dt); else exponent = context->exp_charge; v_cap_next = v_cap + ((v_charge - v_cap) * exponent); @@ -285,7 +292,7 @@ static void dsd_555_astbl_step(node_description *node) if (v_cap_next >= threshold) { /* calculate the overshoot time */ - dt = t_rc * log(1.0 / (1.0 - ((v_cap_next - threshold) / (v_charge - v_cap)))); + dt = context->t_rc_charge * log(1.0 / (1.0 - ((v_cap_next - threshold) / (v_charge - v_cap)))); x_time = dt; v_cap = threshold; context->flip_flop = 0; @@ -299,12 +306,8 @@ static void dsd_555_astbl_step(node_description *node) /* Discharging */ if(DSD_555_ASTBL__R2 != 0) { - if (update_t_rc) - t_rc = DSD_555_ASTBL_T_RC_DISCHARGE; - else - t_rc = context->t_rc_discharge; if (update_exponent) - exponent = 1.0 - exp(-(dt / t_rc )); + exponent = RC_CHARGE_EXP_DT(context->t_rc_discharge, dt); else exponent = context->exp_discharge; v_cap_next = v_cap - (v_cap * exponent); @@ -320,7 +323,8 @@ static void dsd_555_astbl_step(node_description *node) if (v_cap_next <= trigger) { /* calculate the overshoot time */ - dt = t_rc * log(1.0 / (1.0 - ((trigger - v_cap_next) / v_cap))); + if (v_cap_next < trigger) + dt = context->t_rc_discharge * log(1.0 / (1.0 - ((trigger - v_cap_next) / v_cap))); x_time = dt; v_cap = trigger; context->flip_flop = 1; @@ -376,9 +380,6 @@ static void dsd_555_astbl_reset(node_description *node) struct dsd_555_astbl_context *context = node->context; node_description *v_charge_node; - double neg_dt = 0.0 - discrete_current_context->sample_time; - double t_rc; - context->use_ctrlv = (node->input_is_node >> 4) & 1; context->output_type = info->options & DISC_555_OUT_MASK; @@ -416,14 +417,12 @@ static void dsd_555_astbl_reset(node_description *node) context->has_rc_nodes = 1; else { - t_rc = DSD_555_ASTBL_T_RC_BLEED; - context->exp_bleed = 1.0 - exp(neg_dt / t_rc); - t_rc = DSD_555_ASTBL_T_RC_CHARGE; - context->exp_charge = 1.0 - exp(neg_dt / t_rc); - context->t_rc_charge = t_rc; - t_rc = DSD_555_ASTBL_T_RC_DISCHARGE; - context->exp_discharge = 1.0 - exp(neg_dt / t_rc); - context->t_rc_discharge = t_rc; + context->t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED; + context->exp_bleed = RC_CHARGE_EXP(context->t_rc_bleed); + context->t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE; + context->exp_charge = RC_CHARGE_EXP(context->t_rc_charge); + context->t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE; + context->exp_discharge = RC_CHARGE_EXP(context->t_rc_discharge); } context->output_is_ac = info->options & DISC_555_OUT_AC; @@ -507,7 +506,7 @@ static void dsd_555_mstbl_step(node_description *node) else { /* Charging */ - v_cap_next = v_cap + ((info->v_pos - v_cap) * (1.0 - exp(-(discrete_current_context->sample_time / (DSD_555_MSTBL__R * DSD_555_MSTBL__C))))); + v_cap_next = v_cap + ((info->v_pos - v_cap) * RC_CHARGE_EXP(DSD_555_MSTBL__R * DSD_555_MSTBL__C)); /* Has it charged past upper limit? */ /* If trigger is still enabled, then we keep charging, @@ -603,7 +602,7 @@ static void dsd_555_mstbl_reset(node_description *node) #define DSD_555_CC_RC_MASK 0x78 /* charge/discharge constants */ -#define DSD_555_CC_T_RC_BLEED (DEFAULT_555_CAP_BLEED * DSD_555_CC__C) +#define DSD_555_CC_T_RC_BLEED (DEFAULT_555_BLEED_R * DSD_555_CC__C) #define DSD_555_CC_T_RC_DISCHARGE_01 (DSD_555_CC__RDIS * DSD_555_CC__C) #define DSD_555_CC_T_RC_DISCHARGE_NO_I (DSD_555_CC__RGND * DSD_555_CC__C) #define DSD_555_CC_T_RC_CHARGE (r_charge * DSD_555_CC__C) @@ -714,7 +713,7 @@ static void dsd_555_cc_step(node_description *node) if (update_exponent) { t_rc = DSD_555_CC_T_RC_BLEED; - exponent = 1.0 - exp(-(dt / t_rc)); + exponent = RC_CHARGE_EXP_DT(t_rc, dt); } else exponent = context->exp_bleed; @@ -755,7 +754,7 @@ static void dsd_555_cc_step(node_description *node) else t_rc = context->t_rc_discharge_01; if (update_exponent) - exponent = 1.0 - exp(-(dt / t_rc)); + exponent = RC_CHARGE_EXP_DT(t_rc, dt); else exponent = context->exp_discharge_01; @@ -808,7 +807,7 @@ static void dsd_555_cc_step(node_description *node) else t_rc = context->t_rc_discharge_no_i; if (update_exponent) - exponent = 1.0 - exp(-(dt / t_rc)); + exponent = RC_CHARGE_EXP_DT(t_rc, dt); else exponent = context->exp_discharge_no_i; @@ -829,7 +828,7 @@ static void dsd_555_cc_step(node_description *node) else t_rc = context->t_rc_charge; if (update_exponent) - exponent = 1.0 - exp(-(dt / t_rc)); + exponent = RC_CHARGE_EXP_DT(t_rc, dt); else exponent = context->exp_charge; @@ -857,7 +856,7 @@ static void dsd_555_cc_step(node_description *node) else t_rc = context->t_rc_discharge; if (update_exponent) - exponent = 1.0 - exp(-(dt / t_rc)); + exponent = RC_CHARGE_EXP_DT(t_rc, dt); else exponent = context->exp_discharge; @@ -935,8 +934,7 @@ static void dsd_555_cc_reset(node_description *node) const discrete_555_cc_desc *info = node->custom; struct dsd_555_cc_context *context = node->context; - double neg_dt = 0.0 - discrete_current_context->sample_time; - double r_temp, r_discharge = 0, r_charge = 0, t_rc; + double r_temp, r_discharge = 0, r_charge = 0; context->flip_flop = 1; context->cap_voltage = 0; @@ -996,20 +994,15 @@ static void dsd_555_cc_reset(node_description *node) break; } - t_rc = DSD_555_CC_T_RC_BLEED; - context->exp_bleed = 1.0 - exp(neg_dt / t_rc); - t_rc = DSD_555_CC_T_RC_DISCHARGE_01; - context->exp_discharge_01 = 1.0 - exp(neg_dt / t_rc); - context->t_rc_discharge_01 = t_rc; - t_rc = DSD_555_CC_T_RC_DISCHARGE_NO_I; - context->exp_discharge_no_i = 1.0 - exp(neg_dt / t_rc); - context->t_rc_discharge_no_i = t_rc; - t_rc = DSD_555_CC_T_RC_CHARGE; - context->exp_charge = 1.0 - exp(neg_dt / t_rc); - context->t_rc_charge = t_rc; - t_rc = DSD_555_CC_T_RC_DISCHARGE; - context->exp_discharge = 1.0 - exp(neg_dt / t_rc); - context->t_rc_discharge = t_rc; + context->exp_bleed = RC_CHARGE_EXP(DSD_555_CC_T_RC_BLEED); + context->t_rc_discharge_01 = DSD_555_CC_T_RC_DISCHARGE_01; + context->exp_discharge_01 = RC_CHARGE_EXP(context->t_rc_discharge_01); + context->t_rc_discharge_no_i = DSD_555_CC_T_RC_DISCHARGE_NO_I; + context->exp_discharge_no_i = RC_CHARGE_EXP(context->t_rc_discharge_no_i); + context->t_rc_charge = DSD_555_CC_T_RC_CHARGE; + context->exp_charge = RC_CHARGE_EXP(context->t_rc_charge); + context->t_rc_discharge = DSD_555_CC_T_RC_DISCHARGE; + context->exp_discharge = RC_CHARGE_EXP(context->t_rc_discharge); } /* Step to set the output */ @@ -1606,7 +1599,7 @@ static void dsd_ls624_step(node_description *node) double dt; /* change in time */ double sample_t; double t; - int lst, cntf=0, cntr=0; + int lst, cntf = 0, cntr = 0; sample_t = discrete_current_context->sample_time; /* Change in time */ dt = LS624_T(DSD_LS624__C, DSD_LS624__VRNG, DSD_LS624__VMOD); @@ -1615,7 +1608,7 @@ static void dsd_ls624_step(node_description *node) lst = context->state; while (t + dt < sample_t) { - context->state = (1-context->state); + context->state = (1 - context->state); if (context->state) cntr++; else @@ -1627,7 +1620,7 @@ static void dsd_ls624_step(node_description *node) switch (context->out_type) { case DISC_LS624_OUT_ENERGY: - node->output[0] = ((double) lst) * (1.0+context->remain/sample_t) - ((double) context->state) * context->remain/sample_t; + node->output[0] = ((double)lst) * (1.0 + context->remain / sample_t) - ((double)context->state) * context->remain / sample_t; break; case DISC_LS624_OUT_LOGIC: node->output[0] = context->state; diff --git a/src/emu/sound/disc_flt.c b/src/emu/sound/disc_flt.c index 9f565c97636..e8a233d68f4 100644 --- a/src/emu/sound/disc_flt.c +++ b/src/emu/sound/disc_flt.c @@ -19,8 +19,10 @@ * DST_RCDISC5 - Diode in series with R//C * DST_RCDISC_MOD - RC triggered by logic and modulated * DST_RCFILTER - Simple RC filter & also lowpass filter + * DST_RCFILTER_SW - Usage of node_description values for switchable RC filter * DST_RCINTEGRATE - Two diode inputs, transistor and a R/C charge * discharge network + * DST_SALLEN_KEY - Sallen-Key filter circuit * ************************************************************************/ @@ -99,6 +101,7 @@ struct dst_rcfilter_context struct dst_rcfilter_sw_context { double vCap[4]; + double exp[4]; }; struct dst_rcintegrate_context @@ -152,8 +155,7 @@ static void dst_crfilter_reset(node_description *node) { struct dst_rcfilter_context *context = node->context; - context->exponent = -1.0 / (DST_CRFILTER__R * DST_CRFILTER__C * discrete_current_context->sample_rate); - context->exponent = 1.0 - exp(context->exponent); + context->exponent = RC_CHARGE_EXP(DST_CRFILTER__R * DST_CRFILTER__C); context->vCap = 0; node->output[0] = DST_CRFILTER__IN; } @@ -316,64 +318,6 @@ static void dst_filter2_reset(node_description *node) node->output[0] = 0; } -/************************************************************************ - * - * DST_SALLEN_KEY - Sallen-Key filter circuit - * - * input[0] - Enable input value - * input[1] - IN0 node - * input[3] - Filter Type - * - * also passed discrete_op_amp_filt_info structure - * - * 2008, couriersud - ************************************************************************/ -#define DST_SALLEN_KEY__ENABLE (*(node->input[0])) -#define DST_SALLEN_KEY__INP0 (*(node->input[1])) -#define DST_SALLEN_KEY__TYPE (*(node->input[2])) - -static void dst_sallen_key_step(node_description *node) -{ - struct dss_filter2_context *context = node->context; - - double gain = 1.0; - - if (DST_SALLEN_KEY__ENABLE == 0.0) - { - gain = 0.0; - } - - node->output[0] = -context->a1 * context->y1 - context->a2 * context->y2 + - context->b0 * gain * DST_SALLEN_KEY__INP0 + context->b1 * context->x1 + context->b2 * context->x2; - - context->x2 = context->x1; - context->x1 = gain * DST_SALLEN_KEY__INP0; - context->y2 = context->y1; - context->y1 = node->output[0]; -} - -static void dst_sallen_key_reset(node_description *node) -{ - struct dss_filter2_context *context = node->context; - const discrete_op_amp_filt_info *info = node->custom; - - double freq, q; - - switch ((int) DST_SALLEN_KEY__TYPE) - { - case DISC_SALLEN_KEY_LOW_PASS: - freq = 1.0 / ( 2.0 * M_PI * sqrt(info->c1 * info->c2 * info->r1 * info->r2)); - q = sqrt(info->c1 * info->c2 * info->r1 * info->r2) / (info->c2 * (info->r1 + info->r2)); - break; - default: - fatalerror("Unknown sallen key filter type"); - } - - calculate_filter2_coefficients(freq, 1.0 / q, DISC_FILTER_LOWPASS, - &context->a1, &context->a2, - &context->b0, &context->b1, &context->b2); - node->output[0] = 0; -} /************************************************************************ * @@ -521,20 +465,16 @@ static void dst_op_amp_filt_reset(node_description *node) switch (context->type) { case DISC_OP_AMP_FILTER_IS_LOW_PASS_1: - context->exponentC1 = -1.0 / (info->rF * info->c1 * discrete_current_context->sample_rate); - context->exponentC1 = 1.0 - exp(context->exponentC1); + context->exponentC1 = RC_CHARGE_EXP(info->rF * info->c1); context->exponentC2 = 0; break; case DISC_OP_AMP_FILTER_IS_HIGH_PASS_1: - context->exponentC1 = -1.0 / (context->rTotal * info->c1 * discrete_current_context->sample_rate); - context->exponentC1 = 1.0 - exp(context->exponentC1); + context->exponentC1 = RC_CHARGE_EXP(context->rTotal * info->c1); context->exponentC2 = 0; break; case DISC_OP_AMP_FILTER_IS_BAND_PASS_1: - context->exponentC1 = -1.0 / (info->rF * info->c1 * discrete_current_context->sample_rate); - context->exponentC1 = 1.0 - exp(context->exponentC1); - context->exponentC2 = -1.0 / (context->rTotal * info->c2 * discrete_current_context->sample_rate); - context->exponentC2 = 1.0 - exp(context->exponentC2); + context->exponentC1 = RC_CHARGE_EXP(info->rF * info->c1); + context->exponentC2 = RC_CHARGE_EXP(context->rTotal * info->c2); break; case DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON: context->rTotal = 1.0 / (1.0 / info->r1 + 1.0 / info->r2); @@ -559,16 +499,12 @@ static void dst_op_amp_filt_reset(node_description *node) break; } case DISC_OP_AMP_FILTER_IS_BAND_PASS_0 | DISC_OP_AMP_IS_NORTON: - context->exponentC1 = -1.0 / ((1.0 / (1.0 / info->r1 + 1.0 / (info->r2 + info->r3 + info->r4))) * info->c1 * discrete_current_context->sample_rate); - context->exponentC1 = 1.0 - exp(context->exponentC1); - context->exponentC2 = -1.0 / ((1.0 / (1.0 / (info->r1 + info->r2) + 1.0 / (info->r3 + info->r4))) * info->c2 * discrete_current_context->sample_rate); - context->exponentC2 = 1.0 - exp(context->exponentC2); - context->exponentC3 = -1.0 / ((info->r1 + info->r2 + info->r3 + info->r4) * info->c3 * discrete_current_context->sample_rate); - context->exponentC3 = 1.0 - exp(context->exponentC3); + context->exponentC1 = RC_CHARGE_EXP(RES_2_PARALLEL(info->r1, info->r2 + info->r3 + info->r4) * info->c1); + context->exponentC2 = RC_CHARGE_EXP(RES_2_PARALLEL(info->r1 + info->r2, info->r3 + info->r4) * info->c2); + context->exponentC3 = RC_CHARGE_EXP((info->r1 + info->r2 + info->r3 + info->r4) * info->c3); break; case DISC_OP_AMP_FILTER_IS_HIGH_PASS_0 | DISC_OP_AMP_IS_NORTON: - context->exponentC1 = -1.0 / (info->r1 * info->c1 * discrete_current_context->sample_rate); - context->exponentC1 = 1.0 - exp(context->exponentC1); + context->exponentC1 = RC_CHARGE_EXP(info->r1 * info->c1); break; } @@ -679,10 +615,8 @@ static void dst_rcdisc2_reset(node_description *node) context->state = 0; context->t = 0; - context->exponent0 = -1.0 * DST_RCDISC2__R0 * DST_RCDISC2__C; - context->exponent1 = -1.0 * DST_RCDISC2__R1 * DST_RCDISC2__C; - context->exponent0 = exp(discrete_current_context->sample_time/context->exponent0); - context->exponent1 = exp(discrete_current_context->sample_time/context->exponent1); + context->exponent0 = RC_DISCHARGE_EXP(DST_RCDISC2__R0 * DST_RCDISC2__C); + context->exponent1 = RC_DISCHARGE_EXP(DST_RCDISC2__R1 * DST_RCDISC2__C); } /************************************************************************ @@ -716,13 +650,13 @@ static void dst_rcdisc3_step(node_description *node) diff = DST_RCDISC3__IN - node->output[0]; if( diff > 0 ) { - diff = diff - (diff * exp(discrete_current_context->sample_time / context->exponent0)); + diff = diff - (diff * context->exponent0); } else if( diff < 0) { if(diff < -0.5) - diff = diff - (diff * exp(discrete_current_context->sample_time / context->exponent1)); + diff = diff - (diff * context->exponent1); else - diff = diff - (diff * exp(discrete_current_context->sample_time / context->exponent0)); + diff = diff - (diff * context->exponent0); } node->output[0] += diff; } @@ -740,8 +674,8 @@ static void dst_rcdisc3_reset(node_description *node) context->state = 0; context->t = 0; - context->exponent0 = -1.0 * DST_RCDISC3__R1 * DST_RCDISC3__C; - context->exponent1 = -1.0 *(DST_RCDISC3__R1 * DST_RCDISC3__R2)/( DST_RCDISC3__R1 + DST_RCDISC3__R2)* DST_RCDISC3__C; + context->exponent0 = RC_CHARGE_EXP(DST_RCDISC3__R1 * DST_RCDISC3__C); + context->exponent1 = RC_CHARGE_EXP(RES_2_PARALLEL(DST_RCDISC3__R1, DST_RCDISC3__R2) * DST_RCDISC3__C); } @@ -832,21 +766,19 @@ static void dst_rcdisc4_reset(node_description *node) v = DST_RCDISC4__VP - .5; /* diode drop */ /* When the input is 1, both R1 & R3 are basically in parallel. */ - r = 1.0 / (1.0 / DST_RCDISC4__R1 + 1.0 / DST_RCDISC4__R3); + r = RES_2_PARALLEL(DST_RCDISC4__R1, DST_RCDISC4__R3); rT = DST_RCDISC4__R2 + r; i = v / rT; context->v[1] = i * r + .5; - rT = 1.0 / (1.0 / DST_RCDISC4__R2 + 1.0 / r); - context->exp[1] = -1.0 / (rT * DST_RCDISC4__C1 * discrete_current_context->sample_rate); - context->exp[1] = 1.0 - exp(context->exp[1]); + rT = RES_2_PARALLEL(DST_RCDISC4__R2, r); + context->exp[1] = RC_CHARGE_EXP(rT * DST_RCDISC4__C1); /* When the input is 0, R1 is out of circuit. */ rT = DST_RCDISC4__R2 + DST_RCDISC4__R3; i = v / rT; context->v[0] = i * DST_RCDISC4__R3 + .5; - rT = 1.0 / (1.0 / DST_RCDISC4__R2 + 1.0 / DST_RCDISC4__R3); - context->exp[0] = -1.0 / (rT * DST_RCDISC4__C1 * discrete_current_context->sample_rate); - context->exp[0] = 1.0 - exp(context->exp[0]); + rT = RES_2_PARALLEL(DST_RCDISC4__R2, DST_RCDISC4__R3); + context->exp[0] = RC_CHARGE_EXP(rT * DST_RCDISC4__C1); break; case 3: @@ -855,15 +787,13 @@ static void dst_rcdisc4_reset(node_description *node) * resistance, so we will just use .5k in series with R1. */ r = 500.0 + DST_RCDISC4__R1; - context->v[1] = DST_RCDISC4__R2 / (r + DST_RCDISC4__R2) * (5.0 - 0.5); - rT = 1.0 / ( 1.0 / r + 1.0 / DST_RCDISC4__R2); - context->exp[1] = -1.0 / (rT * DST_RCDISC4__C1 * discrete_current_context->sample_rate); - context->exp[1] = 1.0 - exp(context->exp[1]); + context->v[1] = RES_VOLTAGE_DIVIDER(r, DST_RCDISC4__R2) * (5.0 - 0.5); + rT = RES_2_PARALLEL(r, DST_RCDISC4__R2); + context->exp[1] = RC_CHARGE_EXP(rT * DST_RCDISC4__C1); /* When the input is 0, R1 is out of circuit. */ context->v[0] = 0; - context->exp[0] = -1.0 / (DST_RCDISC4__R2 * DST_RCDISC4__C1 * discrete_current_context->sample_rate); - context->exp[0] = 1.0 - exp(context->exp[0]); + context->exp[0] = RC_CHARGE_EXP(DST_RCDISC4__R2 * DST_RCDISC4__C1); break; } } @@ -901,7 +831,7 @@ static void dst_rcdisc5_step(node_description *node) if(diff < 0) //diff = diff - (diff * exp(discrete_current_context->sample_time / context->exponent0)); - diff = -node->output[0] + (node->output[0] * exp(discrete_current_context->sample_time / context->exponent0)); + diff = -node->output[0] + (node->output[0] * context->exponent0); node->output[0] += diff; } else @@ -918,7 +848,7 @@ static void dst_rcdisc5_reset(node_description *node) context->state = 0; context->t = 0; - context->exponent0 = -1.0 * DST_RCDISC5__R * DST_RCDISC5__C; + context->exponent0 = RC_CHARGE_EXP(DST_RCDISC5__R * DST_RCDISC5__C); } @@ -986,34 +916,33 @@ static void dst_rcdisc_mod_reset(node_description *node) struct dst_rcdisc_mod_context *context = node->context; double rc[2], rc2[2]; - double neg_dt = 0.0 - discrete_current_context->sample_time; /* pre-calculate fixed values */ /* DST_RCDISC_MOD__IN1 <= 0.5 */ rc[0] = DST_RCDISC_MOD__R1 + DST_RCDISC_MOD__R2; if (rc[0] < 1) rc[0] = 1; - context->exp_low[0] = exp(neg_dt / (DST_RCDISC_MOD__C * rc[0])); + context->exp_low[0] = RC_DISCHARGE_EXP(DST_RCDISC_MOD__C * rc[0]); context->gain[0] = RES_VOLTAGE_DIVIDER(rc[0], DST_RCDISC_MOD__R4); /* DST_RCDISC_MOD__IN1 > 0.5 */ rc[1] = DST_RCDISC_MOD__R2; if (rc[1] < 1) rc[1] = 1; - context->exp_low[1] = exp(neg_dt / (DST_RCDISC_MOD__C * rc[1])); + context->exp_low[1] = RC_DISCHARGE_EXP(DST_RCDISC_MOD__C * rc[1]); context->gain[1] = RES_VOLTAGE_DIVIDER(rc[1], DST_RCDISC_MOD__R4); /* DST_RCDISC_MOD__IN2 <= 0.6 */ rc2[0] = DST_RCDISC_MOD__R4; /* DST_RCDISC_MOD__IN2 > 0.6 */ - rc2[1] = DST_RCDISC_MOD__R3 * DST_RCDISC_MOD__R4 / (DST_RCDISC_MOD__R3 + DST_RCDISC_MOD__R4); + rc2[1] = RES_2_PARALLEL(DST_RCDISC_MOD__R3, DST_RCDISC_MOD__R4); /* DST_RCDISC_MOD__IN1 <= 0.5 && DST_RCDISC_MOD__IN2 <= 0.6 */ - context->exp_high[0] = exp(neg_dt / (DST_RCDISC_MOD__C * (rc[0] + rc2[0]))); + context->exp_high[0] = RC_DISCHARGE_EXP(DST_RCDISC_MOD__C * (rc[0] + rc2[0])); context->vd_gain[0] = RES_VOLTAGE_DIVIDER(rc[0], rc2[0]); /* DST_RCDISC_MOD__IN1 > 0.5 && DST_RCDISC_MOD__IN2 <= 0.6 */ - context->exp_high[1] = exp(neg_dt / (DST_RCDISC_MOD__C * (rc[1] + rc2[0]))); + context->exp_high[1] = RC_DISCHARGE_EXP(DST_RCDISC_MOD__C * (rc[1] + rc2[0])); context->vd_gain[1] = RES_VOLTAGE_DIVIDER(rc[1], rc2[0]); /* DST_RCDISC_MOD__IN1 <= 0.5 && DST_RCDISC_MOD__IN2 > 0.6 */ - context->exp_high[2] = exp(neg_dt / (DST_RCDISC_MOD__C * (rc[0] + rc2[1]))); + context->exp_high[2] = RC_DISCHARGE_EXP(DST_RCDISC_MOD__C * (rc[0] + rc2[1])); context->vd_gain[2] = RES_VOLTAGE_DIVIDER(rc[0], rc2[1]); /* DST_RCDISC_MOD__IN1 > 0.5 && DST_RCDISC_MOD__IN2 > 0.6 */ - context->exp_high[3] = exp(neg_dt / (DST_RCDISC_MOD__C * (rc[1] + rc2[1]))); + context->exp_high[3] = RC_DISCHARGE_EXP(DST_RCDISC_MOD__C * (rc[1] + rc2[1])); context->vd_gain[3] = RES_VOLTAGE_DIVIDER(rc[1], rc2[1]); context->v_cap = 0; @@ -1060,8 +989,7 @@ static void dst_rcfilter_reset(node_description *node) { struct dst_rcfilter_context *context = node->context; - context->exponent = -1.0 / (DST_RCFILTER__R * DST_RCFILTER__C * discrete_current_context->sample_rate); - context->exponent = 1.0 - exp(context->exponent); + context->exponent = RC_CHARGE_EXP(DST_RCFILTER__R * DST_RCFILTER__C); context->vCap = 0; node->output[0] = 0; } @@ -1090,7 +1018,6 @@ static void dst_rcfilter_sw_step(node_description *node) struct dst_rcfilter_sw_context *context = node->context; int i; - double rcexp; int bits = (int)DST_RCFILTER_SW__SWITCH; double us = 0, rs = 0; @@ -1104,13 +1031,12 @@ static void dst_rcfilter_sw_step(node_description *node) rs += DST_RCFILTER_SW__R; } } - node->output[0] = CD4066_ON_RES / ( CD4066_ON_RES + rs) * DST_RCFILTER_SW__VIN + DST_RCFILTER_SW__R / (CD4066_ON_RES + rs) * us; + node->output[0] = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES) * DST_RCFILTER_SW__VIN + DST_RCFILTER_SW__R / (CD4066_ON_RES + rs) * us; for (i = 0; i < 4; i++) { if (( bits & (1 << i)) != 0) { - rcexp = 1.0 - exp(-1.0 / ( CD4066_ON_RES * DST_RCFILTER_SW__C(i)) * discrete_current_context->sample_rate); - context->vCap[i] += ((node->output[0] - context->vCap[i]) * rcexp); + context->vCap[i] += (node->output[0] - context->vCap[i]) * context->exp[i]; } } } @@ -1128,6 +1054,7 @@ static void dst_rcfilter_sw_reset(node_description *node) for (i = 0; i < 4; i++) context->vCap[i] = 0; + context->exp[i] = RC_CHARGE_EXP(CD4066_ON_RES * DST_RCFILTER_SW__C(i)); node->output[0] = 0; } @@ -1183,12 +1110,12 @@ static void dst_rcintegrate_step(node_description *node) { /* discharge .... */ diff = 0.0 - context->vCap; - iC = 0.0 - context->c_exp1 * diff; /* iC */ + iC = context->c_exp1 * diff; /* iC */ diff -= diff * context->exp_exponent1; context->vCap += diff; iQ = 0; vE = context->vCap * context->gain_r1_r2; - RG = vE / (-iC); + RG = vE / iC; } else { @@ -1258,6 +1185,65 @@ static void dst_rcintegrate_reset(node_description *node) node->output[0] = 0; } +/************************************************************************ + * + * DST_SALLEN_KEY - Sallen-Key filter circuit + * + * input[0] - Enable input value + * input[1] - IN0 node + * input[3] - Filter Type + * + * also passed discrete_op_amp_filt_info structure + * + * 2008, couriersud + ************************************************************************/ +#define DST_SALLEN_KEY__ENABLE (*(node->input[0])) +#define DST_SALLEN_KEY__INP0 (*(node->input[1])) +#define DST_SALLEN_KEY__TYPE (*(node->input[2])) + +static void dst_sallen_key_step(node_description *node) +{ + struct dss_filter2_context *context = node->context; + + double gain = 1.0; + + if (DST_SALLEN_KEY__ENABLE == 0.0) + { + gain = 0.0; + } + + node->output[0] = -context->a1 * context->y1 - context->a2 * context->y2 + + context->b0 * gain * DST_SALLEN_KEY__INP0 + context->b1 * context->x1 + context->b2 * context->x2; + + context->x2 = context->x1; + context->x1 = gain * DST_SALLEN_KEY__INP0; + context->y2 = context->y1; + context->y1 = node->output[0]; +} + +static void dst_sallen_key_reset(node_description *node) +{ + struct dss_filter2_context *context = node->context; + const discrete_op_amp_filt_info *info = node->custom; + + double freq, q; + + switch ((int) DST_SALLEN_KEY__TYPE) + { + case DISC_SALLEN_KEY_LOW_PASS: + freq = 1.0 / ( 2.0 * M_PI * sqrt(info->c1 * info->c2 * info->r1 * info->r2)); + q = sqrt(info->c1 * info->c2 * info->r1 * info->r2) / (info->c2 * (info->r1 + info->r2)); + break; + default: + fatalerror("Unknown sallen key filter type"); + } + + calculate_filter2_coefficients(freq, 1.0 / q, DISC_FILTER_LOWPASS, + &context->a1, &context->a2, + &context->b0, &context->b1, &context->b2); + node->output[0] = 0; +} + /* !!!!!!!!!!! NEW FILTERS for testing !!!!!!!!!!!!!!!!!!!!! */ diff --git a/src/emu/sound/disc_mth.c b/src/emu/sound/disc_mth.c index 1c6314152d6..ab8d854a0c9 100644 --- a/src/emu/sound/disc_mth.c +++ b/src/emu/sound/disc_mth.c @@ -43,6 +43,11 @@ #include <float.h> +struct dst_comp_adder_context +{ + double total[256]; +}; + struct dst_dac_r1_context { double i_bias; /* current of the bias circuit */ @@ -51,6 +56,12 @@ struct dst_dac_r1_context int last_data; }; +struct dst_diode_mix__context +{ + int size; + double v_junction[8]; +}; + struct dst_flipflop_context { int last_clk; @@ -71,8 +82,10 @@ struct dst_mixer_context int type; int size; int r_node_bit_flag; + int c_bit_flag; double r_total; double *r_node[DISC_MIXER_MAX_INPS]; /* Either pointer to resistance node output OR NULL */ + double r_last[DISC_MIXER_MAX_INPS]; double exponent_rc[DISC_MIXER_MAX_INPS]; /* For high pass filtering cause by cIn */ double v_cap[DISC_MIXER_MAX_INPS]; /* cap voltage of each input */ double exponent_c_f; /* Low pass on mixed inputs */ @@ -182,49 +195,59 @@ static void dst_adder_step(node_description *node) * * DST_COMP_ADDER - Selectable parallel component adder * - * input[0] - Enable input value - * input[1] - Bit Select + * input[0] - Bit Select * * Also passed discrete_comp_adder_table structure * * Mar 2004, D Renaud. ************************************************************************/ -#define DST_COMP_ADDER__ENABLE (*(node->input[0])) -#define DST_COMP_ADDER__SELECT (int)(*(node->input[1])) +#define DST_COMP_ADDER__SELECT (*(node->input[0])) static void dst_comp_adder_step(node_description *node) { - const discrete_comp_adder_table *info = node->custom; - int bit; + struct dst_comp_adder_context *context = node->context; + int select; + + select = (int)DST_COMP_ADDER__SELECT; + assert(select < 256); + node->output[0] = context->total[select]; +} + +static void dst_comp_adder_reset(node_description *node) +{ + const discrete_comp_adder_table *info = node->custom; + struct dst_comp_adder_context *context = node->context; + + int i, bit; + int length = 1 << info->length; + + assert(length <= 256); - if(DST_COMP_ADDER__ENABLE) + /* pre-calculate all possible values to speed up step rooutine */ + for(i = 0; i < length; i++) { switch (info->type) { case DISC_COMP_P_CAPACITOR: - node->output[0] = info->cDefault; - for(bit=0; bit < info->length; bit++) + context->total[i] = info->cDefault; + for(bit = 0; bit < info->length; bit++) { - if (DST_COMP_ADDER__SELECT & (1 << bit)) node->output[0] += info->c[bit]; + if (i & (1 << bit)) context->total[i] += info->c[bit]; } break; case DISC_COMP_P_RESISTOR: - node->output[0] = info->cDefault ? 1.0 / info->cDefault : 0; - for(bit=0; bit < info->length; bit++) + context->total[i] = (info->cDefault != 0) ? 1.0 / info->cDefault : 0; + for(bit = 0; bit < info->length; bit++) { - if (DST_COMP_ADDER__SELECT & (1 << bit)) node->output[0] += 1.0 / info->c[bit]; + if ((i & (1 << bit)) && (info->c[bit] != 0)) context->total[i] += 1.0 / info->c[bit]; } - if (node->output[0] != 0) node->output[0] = 1.0 / node->output[0]; + if (context->total[i] != 0) context->total[i] = 1.0 / context->total[i]; break; } } - else - { - node->output[0] = 0; - } + node->output[0] = context->total[0]; } - /************************************************************************ * * DST_CLAMP - Simple signal clamping circuit @@ -378,8 +401,7 @@ static void dst_dac_r1_reset(node_description *node) if (info->cFilter) { /* Setup filter constants */ - context->exponent = -1.0 / (context->r_total * info->cFilter * discrete_current_context->sample_rate); - context->exponent = 1.0 - exp(context->exponent); + context->exponent = RC_CHARGE_EXP(context->r_total * info->cFilter); } } @@ -388,38 +410,53 @@ static void dst_dac_r1_reset(node_description *node) * * DST_DIODE_MIX - Diode Mixer * - * input[0] - Enable input value - * input[1] - Diode junction voltage drop - * input[2] - Input 0 + * input[0] - Input 0 * ..... * * Dec 2004, D Renaud. ************************************************************************/ -#define DST_DIODE_MIX__VJUNC (*(node->input[0])) -#define DST_DIODE_MIX_INP_OFFSET 1 +#define DST_DIODE_MIX_INP_OFFSET 0 #define DST_DIODE_MIX__INP(addr) (*(node->input[DST_DIODE_MIX_INP_OFFSET + addr])) static void dst_diode_mix_step(node_description *node) { - struct dst_size_context *context = node->context; + struct dst_diode_mix__context *context = node->context; - double max = 0; + double val, max = 0; int addr; for (addr = 0; addr < context->size; addr++) { - if (DST_DIODE_MIX__INP(addr) > max) max = DST_DIODE_MIX__INP(addr); + val = DST_DIODE_MIX__INP(addr) - context->v_junction[addr]; + if (val > max) max = val; } - node->output[0] = max - DST_DIODE_MIX__VJUNC; - if (node->output[0] < 0) node->output[0] = 0; + if (max < 0) max = 0; + node->output[0] = max; } static void dst_diode_mix_reset(node_description *node) { - struct dst_size_context *context = node->context; + const double *info = node->custom; + struct dst_diode_mix__context *context = node->context; + + int addr; context->size = node->active_inputs - DST_DIODE_MIX_INP_OFFSET; + assert(context->size <= 8); + for (addr = 0; addr < context->size; addr++) + { + if (info == NULL) + { + /* setup default junction voltage */ + context->v_junction[addr] = 0.5; + } + else + { + /* use supplied junction voltage */ + context->v_junction[addr] = *info++; + } + } dst_diode_mix_step(node); } @@ -932,6 +969,7 @@ static void dst_lookup_table_step(node_description *node) node->output[0] = table[addr]; } + /************************************************************************ * * DST_MIXER - Mixer/Gain stage @@ -995,9 +1033,9 @@ static void dst_mixer_step(node_description *node) int bit, connected; /* put commonly used stuff in local variables for speed */ - double value; - double dt = discrete_current_context->sample_rate; int r_node_bit_flag = context->r_node_bit_flag; + int c_bit_flag = context->c_bit_flag; + int bit_mask = 1; int has_rF = (info->rF != 0); int type = context->type; double v_ref = info->vRef; @@ -1018,19 +1056,19 @@ static void dst_mixer_step(node_description *node) connected = 1; vTemp = DST_MIXER__IN(bit); - if (r_node_bit_flag & (1 << bit)) + /* is there a resistor? */ + if (r_node_bit_flag & bit_mask) { /* a node has the possibility of being disconnected from the circuit. */ - value = *context->r_node[bit]; - if (value == 0) + if (*context->r_node[bit] == 0) connected = 0; else { /* value currently holds resistance */ - rTemp += value; + rTemp += *context->r_node[bit]; r_total += 1.0 / rTemp; - value = info->c[bit]; - if (value != 0) + /* is there a capacitor? */ + if (c_bit_flag & bit_mask) { switch (type) { @@ -1049,16 +1087,20 @@ static void dst_mixer_step(node_description *node) rTemp2 = rTemp + rI; break; } - /* Re-calculate exponent if resistor is a node */ - /* value currently holds capacitance */ - context->exponent_rc[bit] = 1.0 - exp(-1.0 / (rTemp2 * value * dt)); + /* Re-calculate exponent if resistor is a node and has changed value */ + if (*context->r_node[bit] != context->r_last[bit]) + { + context->exponent_rc[bit] = RC_CHARGE_EXP(rTemp2 * info->c[bit]); + context->r_last[bit] = *context->r_node[bit]; + } } } } if (connected) { - if (info->c[bit] != 0) + /* is there a capacitor? */ + if (c_bit_flag & bit_mask) { /* do input high pass filtering if needed. */ context->v_cap[bit] += (vTemp - v_ref - context->v_cap[bit]) * context->exponent_rc[bit]; @@ -1066,6 +1108,7 @@ static void dst_mixer_step(node_description *node) } i += ((type == DISC_MIXER_IS_OP_AMP) ? v_ref - vTemp : vTemp) / rTemp; } + bit_mask = bit_mask << 1; } } else @@ -1075,7 +1118,7 @@ static void dst_mixer_step(node_description *node) { vTemp = DST_MIXER__IN(bit); - if (info->c[bit] != 0) + if (c_bit_flag & (1 << bit)) { /* do input high pass filtering if needed. */ context->v_cap[bit] += (vTemp - v_ref - context->v_cap[bit]) * context->exponent_rc[bit]; @@ -1103,7 +1146,7 @@ static void dst_mixer_step(node_description *node) if (r_node_bit_flag != 0) { /* Re-calculate exponent if resistor nodes are used */ - context->exponent_c_f = 1.0 - exp(-1.0 / (r_total * info->cF * dt)); + context->exponent_c_f = RC_CHARGE_EXP(r_total * info->cF); } context->v_cap_f += (v - v_ref - context->v_cap_f) * context->exponent_c_f; v = context->v_cap_f; @@ -1144,6 +1187,10 @@ static void dst_mixer_reset(node_description *node) } else context->r_node[bit] = NULL; + + /* flag any caps */ + if (info->c[bit] != 0) + context->c_bit_flag |= 1 << bit; } context->size = node->active_inputs - 1; @@ -1193,8 +1240,7 @@ static void dst_mixer_reset(node_description *node) break; } /* Setup filter constants */ - context->exponent_rc[bit] = -1.0 / (rTemp * info->c[bit] * discrete_current_context->sample_rate); - context->exponent_rc[bit] = 1.0 - exp(context->exponent_rc[bit]); + context->exponent_rc[bit] = RC_CHARGE_EXP(rTemp * info->c[bit]); } } @@ -1209,8 +1255,7 @@ static void dst_mixer_reset(node_description *node) if (info->cF != 0) { /* Setup filter constants */ - context->exponent_c_f = -1.0 / (((info->type == DISC_MIXER_IS_OP_AMP) ? info->rF : (1.0 / context->r_total))* info->cF * discrete_current_context->sample_rate); - context->exponent_c_f = 1.0 - exp(context->exponent_c_f); + context->exponent_c_f = RC_CHARGE_EXP(((info->type == DISC_MIXER_IS_OP_AMP) ? info->rF : (1.0 / context->r_total)) * info->cF); } context->v_cap_amp = 0; @@ -1218,10 +1263,9 @@ static void dst_mixer_reset(node_description *node) if (info->cAmp != 0) { /* Setup filter constants */ - /* We will use 100000 ohms as an average final stage impedance. */ + /* We will use 100k ohms as an average final stage impedance. */ /* Your amp/speaker system will have more effect on incorrect filtering then any value used here. */ - context->exponent_c_amp = -1.0 / (100000 * info->cAmp * discrete_current_context->sample_rate); - context->exponent_c_amp = 1.0 - exp(context->exponent_c_amp); + context->exponent_c_amp = RC_CHARGE_EXP(RES_K(100) * info->cAmp); } if (context->type == DISC_MIXER_IS_OP_AMP_WITH_RI) context->gain = info->rF / info->rI; @@ -1770,8 +1814,7 @@ static void dst_op_amp_reset(node_description *node) if (context->has_r4) { /* exponential charge */ - context->exponent = -1.0 / (info->r4 * info->c * discrete_current_context->sample_rate); - context->exponent = 1.0 - exp(context->exponent); + context->exponent = RC_CHARGE_EXP(info->r4 * info->c); } else /* linear charge */ @@ -1840,12 +1883,9 @@ static void dst_op_amp_1sht_reset(node_description *node) const discrete_op_amp_1sht_info *info = node->custom; struct dst_op_amp_1sht_context *context = node->context; - context->exponent1c = -1.0 / ((1.0 / (1.0 / info->r3 + 1.0 / info->r4)) * info->c1 * discrete_current_context->sample_rate); - context->exponent1c = 1.0 - exp(context->exponent1c); - context->exponent1d = -1.0 / (info->r4 * info->c1 * discrete_current_context->sample_rate); - context->exponent1d = 1.0 - exp(context->exponent1d); - context->exponent2 = -1.0 / (info->r2 * info->c2 * discrete_current_context->sample_rate); - context->exponent2 = 1.0 - exp(context->exponent2); + context->exponent1c = RC_CHARGE_EXP(RES_2_PARALLEL(info->r3, info->r4) * info->c1); + context->exponent1d = RC_CHARGE_EXP(info->r4 * info->c1); + context->exponent2 = RC_CHARGE_EXP(info->r2 * info->c2); context->i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r1; context->v_cap1 = context->v_cap2 = 0; context->v_max = info->vP - OP_AMP_NORTON_VBE; @@ -1963,38 +2003,30 @@ static void dst_tvca_op_amp_reset(node_description *node) context->v_out_max = info->vP - OP_AMP_NORTON_VBE; /* This is probably overkill because R5 is usually much lower then r6 or r7, * but it is better to play it safe. */ - context->v_trig[0] = (info->v1 - 0.6) * (info->r6 / (info->r6 + info->r5)); - context->v_trig[1] = (info->v1 - 0.6 - OP_AMP_NORTON_VBE) * (context->r67 / (context->r67 + info->r5)) + OP_AMP_NORTON_VBE; + context->v_trig[0] = (info->v1 - 0.6) * RES_VOLTAGE_DIVIDER(info->r5, info->r6); + context->v_trig[1] = (info->v1 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r5, context->r67) + OP_AMP_NORTON_VBE; context->i_fixed = context->v_out_max / info->r1; context->v_cap1 = 0; /* Charge rate thru r5 */ /* There can be a different charge rates depending on function F3. */ - context->exponent_c[0] = -1.0 / ((1.0 / (1.0 / info->r5 + 1.0 / info->r6)) * info->c1 * discrete_current_context->sample_rate); - context->exponent_c[0] = 1.0 - exp(context->exponent_c[0]); - context->exponent_c[1] = -1.0 / ((1.0 / (1.0 / info->r5 + 1.0 / context->r67)) * info->c1 * discrete_current_context->sample_rate); - context->exponent_c[1] = 1.0 - exp(context->exponent_c[1]); + context->exponent_c[0] = RC_CHARGE_EXP(RES_2_PARALLEL(info->r5, info->r6) * info->c1); + context->exponent_c[1] = RC_CHARGE_EXP(RES_2_PARALLEL(info->r5, context->r67) * info->c1); /* Discharge rate thru r6 + r7 */ - context->exponent_d[1] = -1.0 / (context->r67 * info->c1 * discrete_current_context->sample_rate); - context->exponent_d[1] = 1.0 - exp(context->exponent_d[1]); + context->exponent_d[1] = RC_CHARGE_EXP(context->r67 * info->c1); /* Discharge rate thru r6 */ if (info->r6 != 0) { - context->exponent_d[0] = -1.0 / (info->r6 * info->c1 * discrete_current_context->sample_rate); - context->exponent_d[0] = 1.0 - exp(context->exponent_d[0]); + context->exponent_d[0] = RC_CHARGE_EXP(info->r6 * info->c1); } context->v_cap2 = 0; - context->v_trig2 = (info->v2 - 0.6 - OP_AMP_NORTON_VBE) * (info->r9 / (info->r8 + info->r9)); - context->exponent2[0] = -1.0 / (info->r9 * info->c2 * discrete_current_context->sample_rate); - context->exponent2[0] = 1.0 - exp(context->exponent2[0]); - context->exponent2[1] = -1.0 / ((1.0 / (1.0 / info->r8 + 1.0 / info->r9)) * info->c2 * discrete_current_context->sample_rate); - context->exponent2[1] = 1.0 - exp(context->exponent2[1]); + context->v_trig2 = (info->v2 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r8, info->r9); + context->exponent2[0] = RC_CHARGE_EXP(info->r9 * info->c2); + context->exponent2[1] = RC_CHARGE_EXP(RES_2_PARALLEL(info->r8, info->r9) * info->c2); context->v_cap3 = 0; - context->v_trig3 = (info->v3 - 0.6 - OP_AMP_NORTON_VBE) * (info->r11 / (info->r10 + info->r11)); - context->exponent3[0] = -1.0 / (info->r11 * info->c3 * discrete_current_context->sample_rate); - context->exponent3[0] = 1.0 - exp(context->exponent3[0]); - context->exponent3[1] = -1.0 / ((1.0 / (1.0 / info->r10 + 1.0 / info->r11)) * info->c3 * discrete_current_context->sample_rate); - context->exponent3[1] = 1.0 - exp(context->exponent3[1]); + context->v_trig3 = (info->v3 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r10, info->r11); + context->exponent3[0] = RC_CHARGE_EXP(info->r11 * info->c3); + context->exponent3[1] = RC_CHARGE_EXP(RES_2_PARALLEL(info->r10, info->r11) * info->c3); dst_tvca_op_amp_step(node); } diff --git a/src/emu/sound/disc_wav.c b/src/emu/sound/disc_wav.c index b5f3c05dc8d..3b13f6f04ec 100644 --- a/src/emu/sound/disc_wav.c +++ b/src/emu/sound/disc_wav.c @@ -39,6 +39,23 @@ struct dss_counter_context double t_left; /* time unused during last sample in seconds */ }; +#define DSS_INV_TAB_SIZE 500 + +struct dss_inverter_osc_context +{ + double w; + double wc; + double v_cap; + double v_g2_old; + double rp; + double r1; + double r2; + double c; + double tf_a; + double tf_b; + double tf_tab[DSS_INV_TAB_SIZE]; +}; + struct dss_lfsr_context { unsigned int lfsr_reg; @@ -138,23 +155,6 @@ struct dss_trianglewave_context double phase; }; -#define DSS_INV_TAB_SIZE 500 - -struct dss_inverter_osc_context -{ - double w; - double wc; - double v_cap; - double v_g2_old; - double rp; - double r1; - double r2; - double c; - double tf_a; - double tf_b; - double tf_tab[DSS_INV_TAB_SIZE]; -}; - /************************************************************************ * @@ -1139,7 +1139,7 @@ static void dss_schmitt_osc_step(node_description *node) /* calculate the overshoot time */ t = context->rc * log(1.0 / (1.0 - ((new_vCap - info->trshRise) / (info->vGate - v_cap)))); /* calculate new exponent because of reduced time */ - exponent = 1.0 - exp(-t / context->rc); + exponent = RC_CHARGE_EXP_DT(context->rc, t); v_cap = new_vCap = info->trshRise; context->state = 0; } @@ -1153,7 +1153,7 @@ static void dss_schmitt_osc_step(node_description *node) /* calculate the overshoot time */ t = context->rc * log(1.0 / (1.0 - ((info->trshFall - new_vCap) / v_cap))); /* calculate new exponent because of reduced time */ - exponent = 1.0 - exp(-t / context->rc); + exponent = RC_CHARGE_EXP_DT(context->rc, t); v_cap = new_vCap = info->trshFall; context->state = 1; } @@ -1198,8 +1198,7 @@ static void dss_schmitt_osc_reset(node_description *node) * So use this for the RC charge constant. */ rSource = 1.0 / ((1.0 / info->rIn) + (1.0 / info->rFeedback)); context->rc = rSource * info->c; - context->exponent = -1.0 / (context->rc * discrete_current_context->sample_rate); - context->exponent = 1.0 - exp(context->exponent); + context->exponent = RC_CHARGE_EXP(context->rc); /* Cap is at 0V on power up. Causing output to be high. */ context->v_cap = 0; diff --git a/src/emu/sound/discrete.c b/src/emu/sound/discrete.c index 58aea8e1a4d..37dee6aac13 100644 --- a/src/emu/sound/discrete.c +++ b/src/emu/sound/discrete.c @@ -57,47 +57,7 @@ * *************************************/ -struct _discrete_info -{ - /* emulation info */ - int sndindex; - int sample_rate; - double sample_time; - - /* internal node tracking */ - int node_count; - node_description **running_order; - node_description **indexed_node; - node_description *node_list; - - /* the input streams */ - int discrete_input_streams; - stream_sample_t *input_stream_data[DISCRETE_MAX_OUTPUTS]; - - /* output node tracking */ - int discrete_outputs; - node_description *output_node[DISCRETE_MAX_OUTPUTS]; - - /* the output stream */ - sound_stream *discrete_stream; - - /* debugging statics */ - FILE *disclogfile; - - /* csvlog tracking */ - int num_csvlogs; - FILE *disc_csv_file[DISCRETE_MAX_CSVLOGS]; - node_description *csvlog_node[DISCRETE_MAX_CSVLOGS]; - INT64 sample_num; - - /* wavelog tracking */ - int num_wavelogs; - wav_file *disc_wav_file[DISCRETE_MAX_WAVELOGS]; - node_description *wavelog_node[DISCRETE_MAX_WAVELOGS]; -}; -typedef struct _discrete_info discrete_info; - -static discrete_info *discrete_current_context; +discrete_info *discrete_current_context = NULL; @@ -218,9 +178,9 @@ static const discrete_module module_list[] = { DST_ASWITCH ,"DST_ASWITCH" , 1 ,0 ,NULL ,dst_aswitch_step }, { DST_TRANSFORM ,"DST_TRANSFORM" , 1 ,0 ,NULL ,dst_transform_step }, /* Component specific */ - { DST_COMP_ADDER ,"DST_COMP_ADDER" , 1 ,0 ,NULL ,dst_comp_adder_step }, + { DST_COMP_ADDER ,"DST_COMP_ADDER" , 1 ,sizeof(struct dst_comp_adder_context) ,dst_comp_adder_reset ,dst_comp_adder_step }, { DST_DAC_R1 ,"DST_DAC_R1" , 1 ,sizeof(struct dst_dac_r1_context) ,dst_dac_r1_reset ,dst_dac_r1_step }, - { DST_DIODE_MIX ,"DST_DIODE_MIX" , 1 ,sizeof(struct dst_size_context) ,dst_diode_mix_reset ,dst_diode_mix_step }, + { DST_DIODE_MIX ,"DST_DIODE_MIX" , 1 ,sizeof(struct dst_diode_mix__context) ,dst_diode_mix_reset ,dst_diode_mix_step }, { DST_INTEGRATE ,"DST_INTEGRATE" , 1 ,sizeof(struct dst_integrate_context) ,dst_integrate_reset ,dst_integrate_step }, { DST_MIXER ,"DST_MIXER" , 1 ,sizeof(struct dst_mixer_context) ,dst_mixer_reset ,dst_mixer_step }, { DST_OP_AMP ,"DST_OP_AMP" , 1 ,sizeof(struct dst_op_amp_context) ,dst_op_amp_reset ,dst_op_amp_step }, @@ -304,6 +264,7 @@ static void *discrete_start(const char *tag, int sndindex, int clock, const void else info->sample_rate = Machine->sample_rate; info->sample_time = 1.0 / info->sample_rate; + info->neg_sample_time = - info->sample_time; /* create the logfile */ sprintf(name, "discrete%d.log", info->sndindex); diff --git a/src/emu/sound/discrete.h b/src/emu/sound/discrete.h index 7fe1c83abe1..236cf70b55e 100644 --- a/src/emu/sound/discrete.h +++ b/src/emu/sound/discrete.h @@ -238,11 +238,11 @@ * DISCRETE_TRANSFORM4(NODE,INP0,INP1,INP2,INP3,FUNCT) * DISCRETE_TRANSFORM5(NODE,INP0,INP1,INP2,INP3,INP4,FUNCT) * - * DISCRETE_COMP_ADDER(NODE,ENAB,DATA,TABLE) + * DISCRETE_COMP_ADDER(NODE,DATA,TABLE) * DISCRETE_DAC_R1(NODE,ENAB,DATA,VDATA,LADDER) - * DISCRETE_DIODE_MIXER2(NODE,VJUNC,IN0,IN1) - * DISCRETE_DIODE_MIXER3(NODE,VJUNC,IN0,IN1,IN2) - * DISCRETE_DIODE_MIXER4(NODE,VJUNC,IN0,IN1,IN2,IN3) + * DISCRETE_DIODE_MIXER2(NODE,IN0,IN1,TABLE) + * DISCRETE_DIODE_MIXER3(NODE,IN0,IN1,IN2,TABLE) + * DISCRETE_DIODE_MIXER4(NODE,IN0,IN1,IN2,IN3,TABLE) * DISCRETE_INTEGRATE(NODE,TRG0,TRG1,INFO) * DISCRETE_MIXER2(NODE,ENAB,IN0,IN1,INFO) * DISCRETE_MIXER3(NODE,ENAB,IN0,IN1,IN2,INFO) @@ -300,11 +300,15 @@ * DISCRETE_555_VCO1_CV(NODE,RESET,VIN,CTRLV,OPTIONS) * DISCRETE_566(NODE,ENAB,VMOD,R,C,OPTIONS) * - * DISCRETE_CUSTOM1(NODE,ENAB,IN0,INFO) - * DISCRETE_CUSTOM2(NODE,ENAB,IN0,IN1,INFO) - * DISCRETE_CUSTOM3(NODE,ENAB,IN0,IN1,IN2,INFO) - * DISCRETE_CUSTOM4(NODE,ENAB,IN0,IN1,IN2,IN3,INFO) - * DISCRETE_CUSTOM5(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,INFO) + * DISCRETE_CUSTOM1(NODE,IN0,INFO) + * DISCRETE_CUSTOM2(NODE,IN0,IN1,INFO) + * DISCRETE_CUSTOM3(NODE,IN0,IN1,IN2,INFO) + * DISCRETE_CUSTOM4(NODE,IN0,IN1,IN2,IN3,INFO) + * DISCRETE_CUSTOM5(NODE,IN0,IN1,IN2,IN3,IN4,INFO) + * DISCRETE_CUSTOM6(NODE,IN0,IN1,IN2,IN3,IN4,IN5,INFO) + * DISCRETE_CUSTOM7(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,INFO) + * DISCRETE_CUSTOM8(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,INFO) + * DISCRETE_CUSTOM9(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,INFO) * * DISCRETE_CSVLOG1(NODE1) * DISCRETE_CSVLOG2(NODE1,NODE2) @@ -1683,11 +1687,11 @@ * Declaration syntax * * DISCRETE_COMP_ADDER(name of node, - * enable node or static value, * data node (static value is useless), * address of discrete_comp_adder_table structure) * * discrete_comp_adder_table = {type, cDefault, length, c{}} + * note: length can be a maximum of 8 * * Circuit Types: * DISC_COMP_P_CAPACITOR - parallel capacitors @@ -1760,10 +1764,14 @@ * Declaration syntax * * DISCRETE_DIODE_MIXERx(name of node, - * (x = 2/3/4) voltage drop of the diode junction (static value), - * input 0 node, + * (x = 2/3/4) input 0 node, * input 1 node, - * ...) + * ..., + * address of v_junction table) + * + * v_junction table can be set to NULL if you want all diodes to + * default to a 0.5V drop. Otherwise use a + * table of doubles to specify juntion voltages. * * EXAMPLES: see dkong * @@ -2681,11 +2689,11 @@ * enable, * input node (or value), * switch node (or value), - * R in Ohms, - * C1 in Farads, - * C2 in Farads, - * C3 in Farads, - * C4 in Farads) + * R in Ohms (static value), + * C1 in Farads (static value), + * C2 in Farads (static value), + * C3 in Farads (static value), + * C4 in Farads (static value)) * * This is a typical filter circuit in circusc or scramble. * Switches are usually CD4066 with a "open" resistance of @@ -3095,6 +3103,8 @@ * DISC_566_OUT_TRIANGLE - Pin 4 Triangle Wave Output * DISC_566_OUT_LOGIC - Internal Flip/Flop Output * + * EXAMPLES: see Starship 1 + * *********************************************************************** * * DISCRETE_74LS624 - VCO. @@ -3142,19 +3152,20 @@ *********************************************************************** * * DISCRETE_CUSTOMx - Link to custom code - * where x = 1 to 5 + * where x = 1 to 9 * * Declaration syntax * * DISCRETE_CUSTOMx(name of node, - * enable node or static value, * 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 - * custom = address of specific initialisation data + * custom = address of specific initialization data + * + * EXAMPLES: see Donkey Kong * *********************************************************************** ======================================================================= @@ -3236,6 +3247,30 @@ * ************************************************************************/ +#include "streams.h" +#include "wavwrite.h" + + + +/************************************* + * + * macros + * see also: emu\machine\rescap.h + * + *************************************/ + +/* calculate charge exponent using discrete sample time */ +#define RC_CHARGE_EXP(rc) (1.0 - exp(discrete_current_context->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(discrete_current_context->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))) + /************************************* * @@ -3521,6 +3556,57 @@ struct _node_description }; +/************************************* + * + * Core runtime info + * + * this structure is exposed mainly + * to read the sample rate info + * and possibly context info + * + *************************************/ + +typedef struct _discrete_info discrete_info; +struct _discrete_info +{ + /* emulation info */ + int sndindex; + int sample_rate; + double sample_time; + double neg_sample_time; + + /* internal node tracking */ + int node_count; + node_description **running_order; + node_description **indexed_node; + node_description *node_list; + + /* the input streams */ + int discrete_input_streams; + stream_sample_t *input_stream_data[DISCRETE_MAX_OUTPUTS]; + + /* output node tracking */ + int discrete_outputs; + node_description *output_node[DISCRETE_MAX_OUTPUTS]; + + /* the output stream */ + sound_stream *discrete_stream; + + /* debugging statics */ + FILE *disclogfile; + + /* csvlog tracking */ + int num_csvlogs; + FILE *disc_csv_file[DISCRETE_MAX_CSVLOGS]; + node_description *csvlog_node[DISCRETE_MAX_CSVLOGS]; + INT64 sample_num; + + /* wavelog tracking */ + int num_wavelogs; + wav_file *disc_wav_file[DISCRETE_MAX_WAVELOGS]; + node_description *wavelog_node[DISCRETE_MAX_WAVELOGS]; +}; + /************************************* * @@ -4102,11 +4188,11 @@ enum #define DISCRETE_TRANSFORM4(NODE,INP0,INP1,INP2,INP3,FUNCT) { NODE, DST_TRANSFORM , 4, { INP0,INP1,INP2,INP3 }, { INP0,INP1,INP2,INP3 }, FUNCT, "DISCRETE_TRANSFORM4" }, #define DISCRETE_TRANSFORM5(NODE,INP0,INP1,INP2,INP3,INP4,FUNCT) { NODE, DST_TRANSFORM , 5, { INP0,INP1,INP2,INP3,INP4 }, { INP0,INP1,INP2,INP3,INP4 }, FUNCT, "DISCRETE_TRANSFORM5" }, /* Component specific */ -#define DISCRETE_COMP_ADDER(NODE,ENAB,DATA,TABLE) { NODE, DST_COMP_ADDER , 2, { ENAB,DATA }, { ENAB,DATA }, TABLE, "DISCRETE_COMP_ADDER" }, +#define DISCRETE_COMP_ADDER(NODE,DATA,TABLE) { NODE, DST_COMP_ADDER , 1, { DATA }, { DATA }, TABLE, "DISCRETE_COMP_ADDER" }, #define DISCRETE_DAC_R1(NODE,ENAB,DATA,VDATA,LADDER) { NODE, DST_DAC_R1 , 3, { ENAB,DATA,VDATA }, { ENAB,DATA,VDATA }, LADDER, "DISCRETE_DAC_R1" }, -#define DISCRETE_DIODE_MIXER2(NODE,VJUNC,IN0,IN1) { NODE, DST_DIODE_MIX , 3, { NODE_NC,IN0,IN1 }, { VJUNC,IN0,IN1 }, NULL, "DISCRETE_DIODE_MIXER2" }, -#define DISCRETE_DIODE_MIXER3(NODE,VJUNC,IN0,IN1,IN2) { NODE, DST_DIODE_MIX , 4, { NODE_NC,IN0,IN1,IN2 }, { VJUNC,IN0,IN1,IN2 }, INFO, "DISCRETE_DIODE_MIXER3" }, -#define DISCRETE_DIODE_MIXER4(NODE,VJUNC,IN0,IN1,IN2,IN3) { NODE, DST_DIODE_MIX , 5, { NODE_NC,IN0,IN1,IN2,IN3 }, { VJUNC,IN0,IN1,IN2,IN3 }, INFO, "DISCRETE_DIODE_MIXER4" }, +#define DISCRETE_DIODE_MIXER2(NODE,IN0,IN1,TABLE) { NODE, DST_DIODE_MIX , 3, { IN0,IN1 }, { IN0,IN1 }, TABLE, "DISCRETE_DIODE_MIXER2" }, +#define DISCRETE_DIODE_MIXER3(NODE,IN0,IN1,IN2,TABLE) { NODE, DST_DIODE_MIX , 4, { IN0,IN1,IN2 }, { IN0,IN1,IN2 }, TABLE, "DISCRETE_DIODE_MIXER3" }, +#define DISCRETE_DIODE_MIXER4(NODE,IN0,IN1,IN2,IN3,TABLE) { NODE, DST_DIODE_MIX , 5, { IN0,IN1,IN2,IN3 }, { IN0,IN1,IN2,IN3 }, TABLE, "DISCRETE_DIODE_MIXER4" }, #define DISCRETE_INTEGRATE(NODE,TRG0,TRG1,INFO) { NODE, DST_INTEGRATE , 2, { TRG0,TRG1 }, { TRG0,TRG1 }, INFO, "DISCRETE_INTEGRATE" }, #define DISCRETE_MIXER2(NODE,ENAB,IN0,IN1,INFO) { NODE, DST_MIXER , 3, { ENAB,IN0,IN1 }, { ENAB,IN0,IN1 }, INFO, "DISCRETE_MIXER2" }, #define DISCRETE_MIXER3(NODE,ENAB,IN0,IN1,IN2,INFO) { NODE, DST_MIXER , 4, { ENAB,IN0,IN1,IN2 }, { ENAB,IN0,IN1,IN2 }, INFO, "DISCRETE_MIXER3" }, @@ -4136,7 +4222,7 @@ enum #define DISCRETE_RCDISC5(NODE,ENAB,INP0,RVAL,CVAL) { NODE, DST_RCDISC5 , 4, { ENAB,INP0,NODE_NC,NODE_NC }, { ENAB,INP0,RVAL,CVAL }, NULL, "DISCRETE_RCDISC5" }, #define DISCRETE_RCDISC_MODULATED(NODE,INP0,INP1,RVAL0,RVAL1,RVAL2,RVAL3,CVAL,VP) { NODE, DST_RCDISC_MOD, 8, { INP0,INP1,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC }, { INP0,INP1,RVAL0,RVAL1,RVAL2,RVAL3,CVAL,VP }, NULL, "DISCRETE_RCDISC_MODULATED" }, #define DISCRETE_RCFILTER(NODE,ENAB,INP0,RVAL,CVAL) { NODE, DST_RCFILTER , 4, { ENAB,INP0,NODE_NC,NODE_NC }, { ENAB,INP0,RVAL,CVAL }, NULL, "DISCRETE_RCFILTER" }, -#define DISCRETE_RCFILTER_SW(NODE,ENAB,INP0,SW,RVAL,CVAL1,CVAL2,CVAL3,CVAL4) { NODE, DST_RCFILTER_SW, 8, { ENAB,INP0,SW,RVAL,CVAL1,CVAL2,CVAL3,CVAL4 }, { ENAB,INP0,SW,RVAL,CVAL1,CVAL2,CVAL3,CVAL4 }, NULL, "DISCRETE_RCFILTER_SW" }, +#define DISCRETE_RCFILTER_SW(NODE,ENAB,INP0,SW,RVAL,CVAL1,CVAL2,CVAL3,CVAL4) { NODE, DST_RCFILTER_SW, 8, { ENAB,INP0,SW,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC }, { ENAB,INP0,SW,RVAL,CVAL1,CVAL2,CVAL3,CVAL4 }, NULL, "DISCRETE_RCFILTER_SW" }, #define DISCRETE_RCFILTER_VREF(NODE,ENAB,INP0,RVAL,CVAL,VREF) { NODE, DST_RCFILTER , 5, { ENAB,INP0,NODE_NC,NODE_NC,NODE_NC }, { ENAB,INP0,RVAL,CVAL,VREF }, NULL, "DISCRETE_RCFILTER_VREF" }, #define DISCRETE_RCINTEGRATE(NODE,INP0,RVAL0,RVAL1,RVAL2,CVAL,vP,TYPE) { NODE, DST_RCINTEGRATE , 7, { INP0,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC }, { INP0,RVAL0,RVAL1,RVAL2,CVAL,vP,TYPE }, NULL, "DISCRETE_RCINTEGRATE" }, /* For testing - seem to be buggered. Use versions not ending in N. */ @@ -4146,11 +4232,15 @@ enum /* from disc_dev.c */ /* generic modules */ -#define DISCRETE_CUSTOM1(NODE,ENAB,IN0,INFO) { NODE, DST_CUSTOM , 2, { ENAB,IN0 }, { ENAB,IN0 }, INFO, "DISCRETE_CUSTOM1" }, -#define DISCRETE_CUSTOM2(NODE,ENAB,IN0,IN1,INFO) { NODE, DST_CUSTOM , 3, { ENAB,IN0,IN1 }, { ENAB,IN0,IN1 }, INFO, "DISCRETE_CUSTOM2" }, -#define DISCRETE_CUSTOM3(NODE,ENAB,IN0,IN1,IN2,INFO) { NODE, DST_CUSTOM , 4, { ENAB,IN0,IN1,IN2 }, { ENAB,IN0,IN1,IN2 }, INFO, "DISCRETE_CUSTOM3" }, -#define DISCRETE_CUSTOM4(NODE,ENAB,IN0,IN1,IN2,IN3,INFO) { NODE, DST_CUSTOM , 5, { ENAB,IN0,IN1,IN2,IN3 }, { ENAB,IN0,IN1,IN2,IN3 }, INFO, "DISCRETE_CUSTOM4" }, -#define DISCRETE_CUSTOM5(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,INFO) { NODE, DST_CUSTOM , 6, { ENAB,IN0,IN1,IN2,IN3,IN4 }, { ENAB,IN0,IN1,IN2,IN3,IN4 }, INFO, "DISCRETE_CUSTOM5" }, +#define DISCRETE_CUSTOM1(NODE,IN0,INFO) { NODE, DST_CUSTOM , 1, { IN0 }, { IN0 }, INFO, "DISCRETE_CUSTOM1" }, +#define DISCRETE_CUSTOM2(NODE,IN0,IN1,INFO) { NODE, DST_CUSTOM , 2, { IN0,IN1 }, { IN0,IN1 }, INFO, "DISCRETE_CUSTOM2" }, +#define DISCRETE_CUSTOM3(NODE,IN0,IN1,IN2,INFO) { NODE, DST_CUSTOM , 3, { IN0,IN1,IN2 }, { IN0,IN1,IN2 }, INFO, "DISCRETE_CUSTOM3" }, +#define DISCRETE_CUSTOM4(NODE,IN0,IN1,IN2,IN3,INFO) { NODE, DST_CUSTOM , 4, { IN0,IN1,IN2,IN3 }, { IN0,IN1,IN2,IN3 }, INFO, "DISCRETE_CUSTOM4" }, +#define DISCRETE_CUSTOM5(NODE,IN0,IN1,IN2,IN3,IN4,INFO) { NODE, DST_CUSTOM , 5, { IN0,IN1,IN2,IN3,IN4 }, { IN0,IN1,IN2,IN3,IN4 }, INFO, "DISCRETE_CUSTOM5" }, +#define DISCRETE_CUSTOM6(NODE,IN0,IN1,IN2,IN3,IN4,IN5,INFO) { NODE, DST_CUSTOM , 6, { IN0,IN1,IN2,IN3,IN4,IN5 }, { IN0,IN1,IN2,IN3,IN4,IN5 }, INFO, "DISCRETE_CUSTOM6" }, +#define DISCRETE_CUSTOM7(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,INFO) { NODE, DST_CUSTOM , 7, { IN0,IN1,IN2,IN3,IN4,IN5,IN6 }, { IN0,IN1,IN2,IN3,IN4,IN5,IN6 }, INFO, "DISCRETE_CUSTOM7" }, +#define DISCRETE_CUSTOM8(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,INFO) { NODE, DST_CUSTOM , 8, { IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7 }, { IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7 }, INFO, "DISCRETE_CUSTOM8" }, +#define DISCRETE_CUSTOM9(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,INFO) { NODE, DST_CUSTOM , 9, { IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8 }, { IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8 }, INFO, "DISCRETE_CUSTOM9" }, /* Component specific */ #define DISCRETE_555_ASTABLE(NODE,RESET,R1,R2,C,OPTIONS) { NODE, DSD_555_ASTBL , 5, { RESET,R1,R2,C,NODE_NC }, { RESET,R1,R2,C,-1 }, OPTIONS, "DISCRETE_555_ASTABLE" }, #define DISCRETE_555_ASTABLE_CV(NODE,RESET,R1,R2,C,CTRLV,OPTIONS) { NODE, DSD_555_ASTBL , 5, { RESET,R1,R2,C,CTRLV }, { RESET,R1,R2,C,CTRLV }, OPTIONS, "DISCRETE_555_ASTABLE_CV" }, @@ -4182,9 +4272,11 @@ enum * *************************************/ +extern discrete_info *discrete_current_context; + node_description *discrete_find_node(void *chip, int node); WRITE8_HANDLER(discrete_sound_w); -READ8_HANDLER(discrete_sound_r); +READ8_HANDLER( discrete_sound_r); #endif /* __DISCRETE_H__ */ diff --git a/src/mame/audio/dkong.c b/src/mame/audio/dkong.c index 0becac0ce0a..157940e7f87 100644 --- a/src/mame/audio/dkong.c +++ b/src/mame/audio/dkong.c @@ -18,6 +18,8 @@ /* Set to 1 to disable DAC and post-mixer filters */ #define DK_NO_FILTERS (0) +/* Set to 1 to use faster custom mixer */ +#define DK_USE_CUSTOM (1) /* Issue surrounded by this define need to be analyzed and * reviewed at a lator time. @@ -50,10 +52,9 @@ #define DS_SOUND0 NODE_208 #define DS_SOUND1 NODE_209 -#define DS_SOUND2 NODE_210 -#define DS_SOUND6 NODE_211 -#define DS_SOUND7 NODE_212 -#define DS_SOUND9 NODE_213 +#define DS_SOUND6 NODE_210 +#define DS_SOUND7 NODE_211 +#define DS_SOUND9 NODE_212 #define DS_ADJ_DAC NODE_240 @@ -183,6 +184,8 @@ static const discrete_lfsr_desc dkong_lfsr = 0 /* Output bit */ }; +static const double dkong_diode_mix_table[2] = {DK_1N5553_V, DK_1N5553_V * 2}; + static const discrete_mixer_desc dkong_rc_jump_desc = { DISC_MIXER_IS_RESISTOR, @@ -252,6 +255,102 @@ static const discrete_op_amp_filt_info dkong_sallen_key_info = CAP_N(22), CAP_N(10), 0 }; +#if DK_USE_CUSTOM +/************************************************************************ + * + * Custom dkong mixer + * + * input[0] - In1 (Logic) + * input[1] - In2 + * input[2] - R1 + * input[3] - R2 + * input[4] - R3 + * input[5] - R4 + * input[6] - C + * input[7] - B+ + * + * V (B+) V (B+) + * v v + * | Node Output <----. .-- | ----- + * Z | | Z + * Z R1 | | Z 5k + * Z | | Z 555 + * |\ | R2 R4 | | internal + * In1 >---| >o--+---/\/\/\--+---/\/\/\---+-----------+ CV + * |/ | | | + * | --- | Z + * R3 | --- C | Z 10k + * In2 >----/\/\/\-----------' | | Z + * | '-- | ----- + * Gnd Gnd + * + ************************************************************************/ +#define DKONG_CUSTOM_IN1 (*(node->input[0])) +#define DKONG_CUSTOM_IN2 (*(node->input[1])) +#define DKONG_CUSTOM_R1 (*(node->input[2])) +#define DKONG_CUSTOM_R2 (*(node->input[3])) +#define DKONG_CUSTOM_R3 (*(node->input[4])) +#define DKONG_CUSTOM_R4 (*(node->input[5])) +#define DKONG_CUSTOM_C (*(node->input[6])) +#define DKONG_CUSTOM_V (*(node->input[7])) + +struct dkong_custom_mixer_context +{ + double i_in1[2]; + double r_in[2]; + double r_total[2]; + double exp[2]; +}; + +static void dkong_custom_mixer_step(node_description *node) +{ + struct dkong_custom_mixer_context *context = node->context; + + int in_1 = (int)DKONG_CUSTOM_IN1; + + /* start of with 555 current */ + double i_total = DKONG_CUSTOM_V / RES_K(5); + /* add in current from In1 */ + i_total += context->i_in1[in_1]; + /* add in current from In2 */ + i_total += DKONG_CUSTOM_IN2 / DKONG_CUSTOM_R3; + /* charge cap */ + /* node->output is cap voltage, (i_total * context->r_total[in_1]) is current charge voltage */ + node->output[0] += (i_total * context->r_total[in_1] - node->output[0]) * context->exp[in_1]; +} + +#define NE555_CV_R RES_2_PARALLEL(RES_K(5), RES_K(10)) + +static void dkong_custom_mixer_reset(node_description *node) +{ + struct dkong_custom_mixer_context *context = node->context; + + /* everything is based on the input to the O.C. inverter */ + /* precalculate current from In1 */ + context->i_in1[0] = DKONG_CUSTOM_V / (DKONG_CUSTOM_R1 + DKONG_CUSTOM_R2); + context->i_in1[1] = 0; + /* precalculate total resistance for input circuit */ + context->r_in[0] = RES_2_PARALLEL((DKONG_CUSTOM_R1 + DKONG_CUSTOM_R2), DKONG_CUSTOM_R3); + context->r_in[1] = RES_2_PARALLEL(DKONG_CUSTOM_R2, DKONG_CUSTOM_R3); + /* precalculate total charging resistance */ + context->r_total[0] = RES_2_PARALLEL(context->r_in[0] + DKONG_CUSTOM_R4, NE555_CV_R); + context->r_total[1] = RES_2_PARALLEL((context->r_in[1] + DKONG_CUSTOM_R4), NE555_CV_R); + /* precalculate charging exponents */ + context->exp[0] = RC_CHARGE_EXP(context->r_total[0] * DKONG_CUSTOM_C); + context->exp[1] = RC_CHARGE_EXP(context->r_total[1] * DKONG_CUSTOM_C); + + node->output[0] = 0; +} + +static const discrete_custom_info dkong_custom_mixer_info = +{ + &dkong_custom_mixer_reset, + &dkong_custom_mixer_step, + sizeof(struct dkong_custom_mixer_context), + NULL +}; +#endif + static DISCRETE_SOUND_START(dkong2b) /************************************************/ @@ -259,23 +358,15 @@ static DISCRETE_SOUND_START(dkong2b) /************************************************/ /* DISCRETE_INPUT_DATA */ - DISCRETE_INPUT_NOT(DS_SOUND2_INV) - DISCRETE_INPUT_NOT(DS_SOUND1_INV) - DISCRETE_INPUT_NOT(DS_SOUND0_INV) - DISCRETE_INPUT_NOT(DS_DISCHARGE_INV) - DISCRETE_INPUT_DATA(DS_DAC) + DISCRETE_INPUT_NOT(DS_SOUND2_INV) + DISCRETE_INPUT_NOT(DS_SOUND1_INV) /* IC 6J, pin 12 */ + DISCRETE_INPUT_NOT(DS_SOUND0_INV) /* IC 6J, pin 2 */ + DISCRETE_INPUT_NOT(DS_DISCHARGE_INV) + DISCRETE_INPUT_DATA(DS_DAC) /* Mixing - DAC */ DISCRETE_ADJUSTMENT_TAG(DS_ADJ_DAC, 0, 1, DISC_LINADJ, "VR2") /************************************************/ - /* SIGNALS */ - /************************************************/ - - DISCRETE_LOGIC_INVERT(DS_SOUND0,1,DS_SOUND0_INV) - DISCRETE_LOGIC_INVERT(DS_SOUND1,1,DS_SOUND1_INV) - DISCRETE_LOGIC_INVERT(DS_SOUND2,1,DS_SOUND2_INV) - - /************************************************/ /* Stomp */ /************************************************/ /* Noise */ @@ -287,52 +378,64 @@ static DISCRETE_SOUND_START(dkong2b) /* C21 is discharged via Q5 BE */ DISCRETE_RCDISC_MODULATED(NODE_15,DS_SOUND2_INV,0,DK_R10,0,0,DK_R9,DK_C21,DK_SUP_V) /* Q5 */ - DISCRETE_TRANSFORM2(NODE_16, NODE_15, 0.6, "01>") - DISCRETE_RCDISC2(NODE_17,NODE_16,DK_SUP_V,DK_R8+DK_R7,0.0,DK_R7,DK_C20) + DISCRETE_TRANSFORM2(NODE_16, NODE_15, 0.6, "01>") + DISCRETE_RCDISC2(NODE_17,NODE_16,DK_SUP_V,DK_R8+DK_R7,0.0,DK_R7,DK_C20) - DISCRETE_DIODE_MIXER2(NODE_18, DK_1N5553_V, NODE_13, NODE_13) /* D3 */ - DISCRETE_DIODE_MIXER2(NODE_20, DK_1N5553_V, NODE_17, NODE_18) /* D1, D2 */ + DISCRETE_DIODE_MIXER2(NODE_20, NODE_17, NODE_13, &dkong_diode_mix_table) /* D1, D2 + D3 */ - DISCRETE_RCINTEGRATE(NODE_22,NODE_20,DK_R5, RES_2_PARALLEL(DK_R4+DK_R3,DK_R6),0,DK_C19,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) - DISCRETE_MULTIPLY(DS_OUT_SOUND0,1,NODE_22,DK_R3/R_SERIES(DK_R3,DK_R4)) + DISCRETE_RCINTEGRATE(NODE_22,NODE_20,DK_R5, RES_2_PARALLEL(DK_R4+DK_R3,DK_R6),0,DK_C19,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) + DISCRETE_MULTIPLY(DS_OUT_SOUND0,1,NODE_22,DK_R3/R_SERIES(DK_R3,DK_R4)) /************************************************/ /* Jump */ /************************************************/ /* tt */ - DISCRETE_MULTIPLY(NODE_24,1,DS_SOUND1,DK_SUP_V) /* 4049B Inverter Oscillator build from 3 inverters */ DISCRETE_INVERTER_OSC(NODE_25,1,0,DK_R38,DK_R39,DK_C26,0,&dkong_inverter_osc_desc_jump) +#if DK_USE_CUSTOM + /* custom mixer for 555 CV voltage */ + DISCRETE_CUSTOM8(NODE_28, DS_SOUND1_INV, NODE_25, + DK_R32, DK_R50, DK_R51, DK_R49, DK_C24, DK_SUP_V, &dkong_custom_mixer_info) +#else + DISCRETE_LOGIC_INVERT(DS_SOUND1,1,DS_SOUND1_INV) + DISCRETE_MULTIPLY(NODE_24,1,DS_SOUND1,DK_SUP_V) DISCRETE_TRANSFORM3(NODE_26,DS_SOUND1,DK_R32,DK_R49+DK_R50,"01*2+") DISCRETE_MIXER4(NODE_28, 1, NODE_24, NODE_25, DK_SUP_V, 0,&dkong_rc_jump_desc) - /* 555 Voltage controlled */ - DISCRETE_555_ASTABLE_CV(NODE_29, 1, RES_K(47), RES_K(27), CAP_N(47), NODE_28, - &dkong_555_vco_desc) +#endif + /* 555 Voltage controlled */ + DISCRETE_555_ASTABLE_CV(NODE_29, 1, RES_K(47), RES_K(27), CAP_N(47), NODE_28, + &dkong_555_vco_desc) /* Jump trigger */ DISCRETE_RCDISC_MODULATED(NODE_33,DS_SOUND1_INV,0,DK_R32,0,0,DK_R31,DK_C18,DK_SUP_V) - DISCRETE_TRANSFORM2(NODE_34, NODE_33, 0.6, "01>") - DISCRETE_RCDISC2(NODE_35, NODE_34,DK_SUP_V,R_SERIES(DK_R30,DK_R29),0.0,DK_R29,DK_C17) + DISCRETE_TRANSFORM2(NODE_34, NODE_33, 0.6, "01>") + DISCRETE_RCDISC2(NODE_35, NODE_34,DK_SUP_V,R_SERIES(DK_R30,DK_R29),0.0,DK_R29,DK_C17) - DISCRETE_DIODE_MIXER2(NODE_36, DK_1N5553_V, NODE_29, NODE_29) - DISCRETE_DIODE_MIXER2(NODE_38, DK_1N5553_V, NODE_36, NODE_35) + DISCRETE_DIODE_MIXER2(NODE_38, NODE_35, NODE_29, &dkong_diode_mix_table) - DISCRETE_RCINTEGRATE(NODE_39,NODE_38,DK_R27, RES_2_PARALLEL(DK_R28,DK_R26+DK_R25),0,DK_C16,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) - DISCRETE_MULTIPLY(DS_OUT_SOUND1,1,NODE_39,DK_R25/(DK_R26+DK_R25)) + DISCRETE_RCINTEGRATE(NODE_39,NODE_38,DK_R27, RES_2_PARALLEL(DK_R28,DK_R26+DK_R25),0,DK_C16,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) + DISCRETE_MULTIPLY(DS_OUT_SOUND1,1,NODE_39,DK_R25/(DK_R26+DK_R25)) /************************************************/ /* Walk */ /************************************************/ - DISCRETE_MULTIPLY(NODE_50,1,DS_SOUND0,DK_SUP_V) DISCRETE_INVERTER_OSC(NODE_51,1,0,DK_R47,DK_R48,DK_C30,0,&dkong_inverter_osc_desc_walk) +#if DK_USE_CUSTOM + /* custom mixer for 555 CV voltage */ + DISCRETE_CUSTOM8(NODE_54, DS_SOUND0_INV, NODE_51, + DK_R36, DK_R45, DK_R46, DK_R44, DK_C29, DK_SUP_V, &dkong_custom_mixer_info) +#else + DISCRETE_LOGIC_INVERT(DS_SOUND0,1,DS_SOUND0_INV) + DISCRETE_MULTIPLY(NODE_50,1,DS_SOUND0,DK_SUP_V) DISCRETE_TRANSFORM3(NODE_52,DS_SOUND0,DK_R46,R_SERIES(DK_R44,DK_R45),"01*2+") DISCRETE_MIXER4(NODE_54, 1, NODE_50, NODE_51, DK_SUP_V, 0,&dkong_rc_walk_desc) +#endif - /* 555 Voltage controlled */ - DISCRETE_555_ASTABLE_CV(NODE_55, 1, RES_K(47), RES_K(27), CAP_N(33), NODE_54, &dkong_555_vco_desc) + /* 555 Voltage controlled */ + DISCRETE_555_ASTABLE_CV(NODE_55, 1, RES_K(47), RES_K(27), CAP_N(33), NODE_54, &dkong_555_vco_desc) /* Trigger */ DISCRETE_RCDISC_MODULATED(NODE_60,DS_SOUND0_INV,NODE_55,DK_R36,DK_R18,DK_R35,DK_R17,DK_C25,DK_SUP_V) /* Filter and divide - omitted C22 */ @@ -348,13 +451,13 @@ static DISCRETE_SOUND_START(dkong2b) DISCRETE_TRANSFORM4(NODE_71, DS_DAC, DK_SUP_V/256.0, NODE_70, DS_DISCHARGE_INV, "01*3!2+*") /* following the DAC are two opamps. The first is a current-to-voltage changer - * for the DAC08 which delivers a variable output current. - * - * The second one is a Sallen Key filter ... - * http://www.t-linespeakers.org/tech/filters/Sallen-Key.html - * f = w / 2 / pi = 1 / ( 2 * pi * 5.6k*sqrt(22n*10n)) = 1916 Hz - * Q = 1/2 * sqrt(22n/10n)= 0.74 - */ + * for the DAC08 which delivers a variable output current. + * + * The second one is a Sallen Key filter ... + * http://www.t-linespeakers.org/tech/filters/Sallen-Key.html + * f = w / 2 / pi = 1 / ( 2 * pi * 5.6k*sqrt(22n*10n)) = 1916 Hz + * Q = 1/2 * sqrt(22n/10n)= 0.74 + */ DISCRETE_SALLEN_KEY_FILTER(NODE_73, 1, NODE_71, DISC_SALLEN_KEY_LOW_PASS, &dkong_sallen_key_info) /* Adjustment VR2 */ @@ -372,8 +475,8 @@ static DISCRETE_SOUND_START(dkong2b) /* Amplifier: internal amplifier */ DISCRETE_ADDER2(NODE_289,1,NODE_288,5.0*43.0/(100.0+43.0)) - DISCRETE_RCINTEGRATE(NODE_294,NODE_289,0,150,1000, CAP_U(33),DK_SUP_V,DISC_RC_INTEGRATE_TYPE3) - DISCRETE_CRFILTER(NODE_295,1,NODE_294, RES_K(50), DK_C13) + DISCRETE_RCINTEGRATE(NODE_294,NODE_289,0,150,1000, CAP_U(33),DK_SUP_V,DISC_RC_INTEGRATE_TYPE3) + DISCRETE_CRFILTER(NODE_295,1,NODE_294, RES_K(50), DK_C13) /*DISCRETE_CRFILTER(NODE_295,1,NODE_294, 1000, DK_C13) */ /* EZV20 equivalent filter circuit ... */ DISCRETE_CRFILTER(NODE_296,1,NODE_295, RES_K(1), CAP_U(4.7)) @@ -515,13 +618,13 @@ static DISCRETE_SOUND_START(radarscp) /************************************************/ /* DISCRETE_INPUT_DATA */ - DISCRETE_INPUT_NOT(DS_SOUND0_INV) - DISCRETE_INPUT_NOT(DS_SOUND1_INV) - DISCRETE_INPUT_NOT(DS_SOUND2_INV) - DISCRETE_INPUT_NOT(DS_SOUND6_INV) - DISCRETE_INPUT_NOT(DS_SOUND7_INV) - DISCRETE_INPUT_NOT(DS_DISCHARGE_INV) - DISCRETE_INPUT_DATA(DS_DAC) + DISCRETE_INPUT_NOT(DS_SOUND0_INV) + DISCRETE_INPUT_NOT(DS_SOUND1_INV) + DISCRETE_INPUT_NOT(DS_SOUND2_INV) + DISCRETE_INPUT_NOT(DS_SOUND6_INV) + DISCRETE_INPUT_NOT(DS_SOUND7_INV) + DISCRETE_INPUT_NOT(DS_DISCHARGE_INV) + DISCRETE_INPUT_DATA(DS_DAC) /* Mixing - DAC */ DISCRETE_ADJUSTMENT_TAG(DS_ADJ_DAC, 0, 1, DISC_LINADJ, "VR2") @@ -550,14 +653,13 @@ static DISCRETE_SOUND_START(radarscp) /* C21 is discharged via Q5 BE */ DISCRETE_RCDISC_MODULATED(NODE_16,DS_SOUND2_INV,0,RS_R_NN01,0,0,RS_R9*2,RS_C20,DK_SUP_V) - DISCRETE_TRANSFORM2(NODE_17, NODE_16, 0.6, "01>") /* TR2 */ - DISCRETE_RCDISC2(NODE_18,NODE_17,DK_SUP_V,RS_R8+RS_R7,0.0,RS_R7,RS_C19) + DISCRETE_TRANSFORM2(NODE_17, NODE_16, 0.6, "01>") /* TR2 */ + DISCRETE_RCDISC2(NODE_18,NODE_17,DK_SUP_V,RS_R8+RS_R7,0.0,RS_R7,RS_C19) - DISCRETE_DIODE_MIXER2(NODE_19, DK_1N5553_V, NODE_13, NODE_13) /* D3 */ - DISCRETE_DIODE_MIXER2(NODE_20, DK_1N5553_V, NODE_18, NODE_19) /* D1, D2 */ + DISCRETE_DIODE_MIXER2(NODE_20, NODE_18, NODE_13, &dkong_diode_mix_table) /* D1, D2 + D3 */ - DISCRETE_RCINTEGRATE(NODE_22,NODE_20,RS_R5, RES_2_PARALLEL(RS_R4+RS_R3,RS_R6),0,RS_C18,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) - DISCRETE_MULTIPLY(DS_OUT_SOUND2,1,NODE_22,RS_R3/R_SERIES(RS_R3,RS_R4)) + DISCRETE_RCINTEGRATE(NODE_22,NODE_20,RS_R5, RES_2_PARALLEL(RS_R4+RS_R3,RS_R6),0,RS_C18,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) + DISCRETE_MULTIPLY(DS_OUT_SOUND2,1,NODE_22,RS_R3/R_SERIES(RS_R3,RS_R4)) /************************************************/ /* SOUND1 */ @@ -566,14 +668,13 @@ static DISCRETE_SOUND_START(radarscp) /* C21 is discharged via Q5 BE */ DISCRETE_RCDISC_MODULATED(NODE_26,DS_SOUND1_INV,0,RS_R_NN02,0,0,RS_R32,RS_C31,DK_SUP_V) - DISCRETE_TRANSFORM2(NODE_27, NODE_26, 0.6, "01>") /* TR5 */ - DISCRETE_RCDISC2(NODE_28,NODE_27,DK_SUP_V,RS_R31+RS_R30,0.0,RS_R30,RS_C30) + DISCRETE_TRANSFORM2(NODE_27, NODE_26, 0.6, "01>") /* TR5 */ + DISCRETE_RCDISC2(NODE_28,NODE_27,DK_SUP_V,RS_R31+RS_R30,0.0,RS_R30,RS_C30) - DISCRETE_DIODE_MIXER2(NODE_29, DK_1N5553_V, NODE_14, NODE_14) /* D3 */ - DISCRETE_DIODE_MIXER2(NODE_30, DK_1N5553_V, NODE_28, NODE_29) /* D1, D2 */ + DISCRETE_DIODE_MIXER2(NODE_30, NODE_28, NODE_14, &dkong_diode_mix_table) /* D1, D2 + D3 */ - DISCRETE_RCINTEGRATE(NODE_31,NODE_30,RS_R28, RES_2_PARALLEL(RS_R27+RS_R26,RS_R29),0,RS_C29,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) - DISCRETE_MULTIPLY(DS_OUT_SOUND1,1,NODE_31,RS_R26/R_SERIES(RS_R26,RS_R27)) + DISCRETE_RCINTEGRATE(NODE_31,NODE_30,RS_R28, RES_2_PARALLEL(RS_R27+RS_R26,RS_R29),0,RS_C29,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) + DISCRETE_MULTIPLY(DS_OUT_SOUND1,1,NODE_31,RS_R26/R_SERIES(RS_R26,RS_R27)) /************************************************/ /* SOUND0 */ @@ -582,8 +683,8 @@ static DISCRETE_SOUND_START(radarscp) DISCRETE_INVERTER_OSC(NODE_41,1,0,RS_R57,RS_R58,RS_C53,0,&radarscp_inverter_osc_desc_0) DISCRETE_MIXER3(NODE_42, 1, NODE_41, DK_SUP_V, 0,&radarscp_mixer_desc_0) - /* 555 Voltage controlled */ - DISCRETE_555_ASTABLE_CV(NODE_43, DS_SOUND6, RES_K(47), RES_K(27), RS_C49, NODE_42, &radarscp_555_vco_desc) + /* 555 Voltage controlled */ + DISCRETE_555_ASTABLE_CV(NODE_43, DS_SOUND6, RES_K(47), RES_K(27), RS_C49, NODE_42, &radarscp_555_vco_desc) DISCRETE_RCDISC_MODULATED(NODE_44,DS_SOUND0_INV,NODE_43,RS_R39,RS_R18,RS_R37,RS_R38,RS_C22,DK_SUP_V) DISCRETE_CRFILTER(NODE_45, 1, NODE_44, RS_R15+RS_R16, RS_C33) @@ -598,11 +699,11 @@ static DISCRETE_SOUND_START(radarscp) DISCRETE_INVERTER_OSC(NODE_52,1,0,RS_R48,RS_R49,RS_C47,0,&radarscp_inverter_osc_desc_7) DISCRETE_MIXER3(NODE_53, 1, NODE_51, DK_SUP_V, 0,&radarscp_mixer_desc_7) - /* 555 Voltage controlled */ - DISCRETE_555_ASTABLE_CV(NODE_54, DS_SOUND7, RES_K(47), RES_K(27), RS_C48, NODE_53, &radarscp_555_vco_desc) + /* 555 Voltage controlled */ + DISCRETE_555_ASTABLE_CV(NODE_54, DS_SOUND7, RES_K(47), RES_K(27), RS_C48, NODE_53, &radarscp_555_vco_desc) - DISCRETE_RCINTEGRATE(NODE_55,NODE_52,RS_R46, RS_R46,0,RS_C45,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) - DISCRETE_TRANSFORM4(NODE_56, NODE_55, DS_SOUND7,NODE_54,2.5, "01*23<*") + DISCRETE_RCINTEGRATE(NODE_55,NODE_52,RS_R46, RS_R46,0,RS_C45,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1) + DISCRETE_TRANSFORM4(NODE_56, NODE_55, DS_SOUND7,NODE_54,2.5, "01*23<*") DISCRETE_CRFILTER(NODE_57, 1, NODE_56, RS_R43+RS_R44, RS_C46) DISCRETE_MULTIPLY(DS_OUT_SOUND7, 1, NODE_57, RS_R44/(RS_R43+RS_R44)) @@ -614,13 +715,13 @@ static DISCRETE_SOUND_START(radarscp) DISCRETE_TRANSFORM4(NODE_171, DS_DAC, DK_SUP_V/256.0, NODE_170, DS_DISCHARGE_INV, "01*3!2+*") /* following the DAC are two opamps. The first is a current-to-voltage changer - * for the DAC08 which delivers a variable output current. - * - * The second one is a Sallen Key filter ... - * http://www.t-linespeakers.org/tech/filters/Sallen-Key.html - * f = w / 2 / pi = 1 / ( 2 * pi * 5.6k*sqrt(22n*10n)) = 1916 Hz - * Q = 1/2 * sqrt(22n/10n)= 0.74 - */ + * for the DAC08 which delivers a variable output current. + * + * The second one is a Sallen Key filter ... + * http://www.t-linespeakers.org/tech/filters/Sallen-Key.html + * f = w / 2 / pi = 1 / ( 2 * pi * 5.6k*sqrt(22n*10n)) = 1916 Hz + * Q = 1/2 * sqrt(22n/10n)= 0.74 + */ DISCRETE_SALLEN_KEY_FILTER(NODE_173, 1, NODE_171, DISC_SALLEN_KEY_LOW_PASS, &dkong_sallen_key_info) /* Adjustment VR3 */ @@ -634,7 +735,7 @@ static DISCRETE_SOUND_START(radarscp) /* Amplifier: internal amplifier */ DISCRETE_ADDER2(NODE_289,1,NODE_288,5.0*43.0/(100.0+43.0)) - DISCRETE_RCINTEGRATE(NODE_294,NODE_289,0,150,1000, CAP_U(33),DK_SUP_V,DISC_RC_INTEGRATE_TYPE3) + DISCRETE_RCINTEGRATE(NODE_294,NODE_289,0,150,1000, CAP_U(33),DK_SUP_V,DISC_RC_INTEGRATE_TYPE3) DISCRETE_CRFILTER(NODE_295,1,NODE_294, 1000, DK_C13) DISCRETE_OUTPUT(NODE_295, 32767.0/5.0 * 3) @@ -748,20 +849,20 @@ static DISCRETE_SOUND_START(dkongjr) /************************************************/ /* DISCRETE_INPUT_DATA */ - DISCRETE_INPUT_NOT(DS_SOUND0_INV) - DISCRETE_INPUT_NOT(DS_SOUND1_INV) - DISCRETE_INPUT_NOT(DS_SOUND2_INV) - DISCRETE_INPUT_NOT(DS_SOUND6_INV) - DISCRETE_INPUT_NOT(DS_SOUND7_INV) - DISCRETE_INPUT_NOT(DS_SOUND9_INV) - DISCRETE_INPUT_NOT(DS_DISCHARGE_INV) - DISCRETE_INPUT_DATA(DS_DAC) + DISCRETE_INPUT_NOT(DS_SOUND0_INV) + DISCRETE_INPUT_NOT(DS_SOUND1_INV) + DISCRETE_INPUT_NOT(DS_SOUND2_INV) + DISCRETE_INPUT_NOT(DS_SOUND6_INV) + DISCRETE_INPUT_NOT(DS_SOUND7_INV) + DISCRETE_INPUT_NOT(DS_SOUND9_INV) + DISCRETE_INPUT_NOT(DS_DISCHARGE_INV) + DISCRETE_INPUT_DATA(DS_DAC) /************************************************/ /* SIGNALS */ /************************************************/ - DISCRETE_LOGIC_INVERT(DS_SOUND7,1,DS_SOUND7_INV) + DISCRETE_LOGIC_INVERT(DS_SOUND7,1,DS_SOUND7_INV) DISCRETE_LOGIC_INVERT(DS_SOUND9,1,DS_SOUND9_INV) /************************************************/ @@ -775,8 +876,8 @@ static DISCRETE_SOUND_START(dkongjr) DISCRETE_74LS624( NODE_14, 1, NODE_13, 0.98*DK_SUP_V, JR_C22, DISC_LS624_OUT_ENERGY) DISCRETE_RCDISC_MODULATED(NODE_15, NODE_12, NODE_14, 120, JR_R27, RES_K(0.001), JR_R28, JR_C28, DK_SUP_V) /* The following circuit does not match 100%, however works. - * To be exact, we need a C-R-C-R circuit, we actually do not have. - */ + * To be exact, we need a C-R-C-R circuit, we actually do not have. + */ DISCRETE_CRFILTER_VREF(NODE_16, 1, NODE_15, JR_R4, JR_C23, 2.5) DISCRETE_RCFILTER(DS_OUT_SOUND1, 1, NODE_16, JR_R19, JR_C21) @@ -789,8 +890,8 @@ static DISCRETE_SOUND_START(dkongjr) DISCRETE_LS123_INV(NODE_25, DS_SOUND2_INV, JR_R17, JR_C27) DISCRETE_RCDISC_MODULATED(NODE_26, NODE_25, NODE_21, 120, JR_R24, RES_K(0.001), JR_R18, JR_C29, DK_SUP_V) /* The following circuit does not match 100%, however works. - * To be exact, we need a C-R-C-R circuit, we actually do not have. - */ + * To be exact, we need a C-R-C-R circuit, we actually do not have. + */ DISCRETE_CRFILTER_VREF(NODE_27, 1, NODE_26, JR_R6, JR_C30, 2.5) DISCRETE_RCFILTER(DS_OUT_SOUND2, 1, NODE_27, JR_R2, JR_C25) @@ -842,13 +943,13 @@ static DISCRETE_SOUND_START(dkongjr) DISCRETE_TRANSFORM4(NODE_171, DS_DAC, DK_SUP_V/256.0, NODE_170, DS_DISCHARGE_INV, "01*3!2+*") /* following the DAC are two opamps. The first is a current-to-voltage changer - * for the DAC08 which delivers a variable output current. - * - * The second one is a Sallen Key filter ... - * http://www.t-linespeakers.org/tech/filters/Sallen-Key.html - * f = w / 2 / pi = 1 / ( 2 * pi * 5.6k*sqrt(22n*10n)) = 1916 Hz - * Q = 1/2 * sqrt(22n/10n)= 0.74 - */ + * for the DAC08 which delivers a variable output current. + * + * The second one is a Sallen Key filter ... + * http://www.t-linespeakers.org/tech/filters/Sallen-Key.html + * f = w / 2 / pi = 1 / ( 2 * pi * 5.6k*sqrt(22n*10n)) = 1916 Hz + * Q = 1/2 * sqrt(22n/10n)= 0.74 + */ DISCRETE_SALLEN_KEY_FILTER(DS_OUT_DAC, 1, NODE_171, DISC_SALLEN_KEY_LOW_PASS, &dkong_sallen_key_info) @@ -859,8 +960,8 @@ static DISCRETE_SOUND_START(dkongjr) DISCRETE_MIXER5(NODE_288, 1, DS_OUT_SOUND9, DS_OUT_SOUND0, DS_OUT_SOUND2, DS_OUT_SOUND1, DS_OUT_DAC, &dkongjr_mixer_desc) /* Amplifier: internal amplifier - * Just a 1:n amplifier without filters - just the output filter - */ + * Just a 1:n amplifier without filters - just the output filter + */ DISCRETE_CRFILTER(NODE_295,1,NODE_288, 1000, JR_C13) DISCRETE_OUTPUT(NODE_295, 32767.0/5.0 * 10) @@ -944,32 +1045,32 @@ Addresses found at @0x510, cpu2 18 C1 (5100: NC) 3 CLK (5100: ROM-CK) - For documentation purposes: - - Addresses - { 0x0000, 0x007a, 0x018b, 0x0320, 0x036c, 0x03c4, 0x041c, 0x0520, 0x063e } - and related samples interface - - static const char *const radarsc1_sample_names[] = - { - "*radarsc1", - "10.wav", - "12.wav", - "14.wav", - "16.wav", - "18.wav", - "1A.wav", - "1C.wav", - "1E.wav", - "20.wav", - 0 - }; - - static const samples_interface radarsc1_samples_interface = - { - 8, - radarsc1_sample_names - }; + For documentation purposes: + + Addresses + { 0x0000, 0x007a, 0x018b, 0x0320, 0x036c, 0x03c4, 0x041c, 0x0520, 0x063e } + and related samples interface + + static const char *const radarsc1_sample_names[] = + { + "*radarsc1", + "10.wav", + "12.wav", + "14.wav", + "16.wav", + "18.wav", + "1A.wav", + "1C.wav", + "1E.wav", + "20.wav", + 0 + }; + + static const samples_interface radarsc1_samples_interface = + { + 8, + radarsc1_sample_names + }; */ @@ -990,16 +1091,16 @@ static WRITE8_HANDLER( M58817_command_w ) static WRITE8_HANDLER( dkong_voice_w ) { /* only provided for documentation purposes - * not actually used - */ + * not actually used + */ logerror("dkong_speech_w: 0x%02x\n", data); } static READ8_HANDLER( dkong_voice_status_r ) { /* only provided for documentation purposes - * not actually used - */ + * not actually used + */ return 0; } @@ -1052,9 +1153,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( dkong_sound_io_map, ADDRESS_SPACE_IO, 8 ) AM_RANGE(0x00, 0xFF) AM_DEVREAD(LATCH8, "ls175.3d", dkong_tune_r) - AM_WRITE(dkong_voice_w) + AM_WRITE(dkong_voice_w) AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_DEVREAD(LATCH8, "ls175.3d", dkong_tune_r) - AM_WRITE(dkong_voice_w) + AM_WRITE(dkong_voice_w) AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(dkong_p1_w) /* only write to dac */ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_LATCH8_READWRITE("virtual_p2") AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_LATCH8_READBIT("ls259.6h", 5) @@ -1073,7 +1174,7 @@ static ADDRESS_MAP_START( radarsc1_sound_io_map, ADDRESS_SPACE_IO, 8 ) AM_RANGE(0x00, 0x00) AM_MIRROR(0xff) AM_DEVREAD(LATCH8, "ls175.3d", latch8_r) AM_RANGE(0x00, 0xff) AM_WRITE(dkong_p1_w) /* DAC here */ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_LATCH8_READ("virtual_p1") - AM_WRITE(M58817_command_w) + AM_WRITE(M58817_command_w) AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_LATCH8_WRITE("virtual_p2") AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_LATCH8_READBIT("ls259.6h", 5) AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_LATCH8_READBIT("ls259.6h", 4) @@ -1130,11 +1231,11 @@ MACHINE_DRIVER_START( dkong2b_audio ) MDRV_LATCH8_DISCRETE_NODE(7, DS_SOUND7_INP) /* If P2.Bit7 -> is apparently an external signal decay or other output control - * If P2.Bit6 -> activates the external compressed sample ROM (not radarsc1) - * If P2.Bit5 -> Signal ANSN ==> Grid enable (radarsc1) - * If P2.Bit4 -> status code to main cpu - * P2.Bit2-0 -> select the 256 byte bank for external ROM - */ + * If P2.Bit6 -> activates the external compressed sample ROM (not radarsc1) + * If P2.Bit5 -> Signal ANSN ==> Grid enable (radarsc1) + * If P2.Bit4 -> status code to main cpu + * P2.Bit2-0 -> select the 256 byte bank for external ROM + */ MDRV_LATCH8_ADD( "virtual_p2" ) /* virtual latch for port B */ MDRV_LATCH8_INVERT( 0x20 ) /* signal is inverted */ diff --git a/src/mame/audio/firetrk.c b/src/mame/audio/firetrk.c index bd7363bdb10..744a525d1b8 100644 --- a/src/mame/audio/firetrk.c +++ b/src/mame/audio/firetrk.c @@ -626,7 +626,7 @@ DISCRETE_SOUND_START(montecar) /* Also I shifted the frequencies up for it to */ /* sound different from the player's car. */ /************************************************/ - DISCRETE_COMP_ADDER(NODE_30, 1, MONTECAR_DRONE_LOUD_DATA, &montecar_drone_vol_res) // make sure to change the node value in the mixer table if you change this node number + DISCRETE_COMP_ADDER(NODE_30, MONTECAR_DRONE_LOUD_DATA, &montecar_drone_vol_res) // make sure to change the node value in the mixer table if you change this node number DISCRETE_ADJUSTMENT_TAG(NODE_40, RES_K(260), // R85 + R88 @ max diff --git a/src/mame/audio/hitme.c b/src/mame/audio/hitme.c index a1843c934dc..a2bf4633de0 100644 --- a/src/mame/audio/hitme.c +++ b/src/mame/audio/hitme.c @@ -67,7 +67,7 @@ DISCRETE_SOUND_START(hitme) DISCRETE_LOGIC_DFLIPFLOP(NODE_22,1,NODE_21,1,HITME_OUT1,HITME_ENABLE_VAL) /* The output of the latch goes through a series of various capacitors in parallel. */ - DISCRETE_COMP_ADDER(NODE_23,1,NODE_22,&desc_hitme_adder) + DISCRETE_COMP_ADDER(NODE_23,NODE_22,&desc_hitme_adder) /* The combined capacitance is input to a 555 timer in astable mode. */ DISCRETE_555_ASTABLE(NODE_24,1,22e3,39e3,NODE_23,&desc_hitme_555) diff --git a/src/mame/audio/madalien.c b/src/mame/audio/madalien.c index 4066c2b30f7..9976a4783e0 100644 --- a/src/mame/audio/madalien.c +++ b/src/mame/audio/madalien.c @@ -205,7 +205,7 @@ DISCRETE_SOUND_START( madalien ) &madalien_555_1l) // The speed frequencies seem strange but the components have been GuruVerified // There is not much change in selected frequency. 99Hz, 110.6Hz, 124Hz - DISCRETE_COMP_ADDER(NODE_51, 1, MADALIEN_8910_PORTB_45, &madalien_555_1f_r_select) + DISCRETE_COMP_ADDER(NODE_51, MADALIEN_8910_PORTB_45, &madalien_555_1f_r_select) DISCRETE_555_ASTABLE_CV(NODE_52, // IC 1F pin 3 out MADALIEN_8910_PORTB_45, // enabled by gate O2 pin 13 NODE_51, @@ -222,7 +222,7 @@ DISCRETE_SOUND_START( madalien ) DISCRETE_DAC_R1(NODE_55, 1, NODE_54, DEFAULT_TTL_V_LOGIC_1, &madalien_effect1a_dac) DISCRETE_DAC_R1(NODE_56, 1, NODE_54, DEFAULT_TTL_V_LOGIC_1, &madalien_effect1b_dac) DISCRETE_RCFILTER(NODE_57, 1, NODE_56, RES_K(22)/2 + RES_K(22), CAP_U(.033)) - DISCRETE_COMP_ADDER(NODE_59, 1, MADALIEN_8910_PORTB_23, &madalien_effect_1b_vol_r) + DISCRETE_COMP_ADDER(NODE_59, MADALIEN_8910_PORTB_23, &madalien_effect_1b_vol_r) /************************************************ * Enemy motor diff --git a/src/mame/audio/mw8080bw.c b/src/mame/audio/mw8080bw.c index 7cf2fb354f2..be0bf8f4456 100644 --- a/src/mame/audio/mw8080bw.c +++ b/src/mame/audio/mw8080bw.c @@ -516,11 +516,9 @@ static DISCRETE_SOUND_START(maze) 16, /* SIZE */ &maze_74147_table) DISCRETE_COMP_ADDER(MAZE_R305_306_308, /* value of selected parallel circuit R305, R306, R308 */ - 1, /* ENAB */ NODE_32, /* DATA */ &maze_r305_306_308) DISCRETE_COMP_ADDER(MAZE_R303_309, /* value of selected parallel circuit R303, R309 */ - 1, /* ENAB */ MAZE_PLAYER_SEL, /* DATA */ &maze_r303_309) DISCRETE_OP_AMP_OSCILLATOR(NODE_36, /* IC J1, pin 4 */ @@ -985,11 +983,9 @@ static DISCRETE_SOUND_START(checkmat) * Tone generator ************************************************/ DISCRETE_COMP_ADDER(CHECKMAT_R401_402_400, /* value of selected parallel circuit R401, R402, R400 */ - 1, /* ENAB */ CHECKMAT_TONE_DATA_45, /* DATA */ &checkmat_r401_402_400) DISCRETE_COMP_ADDER(CHECKMAT_R407_406_410, /* value of selected parallel circuit R407, R406, R410 */ - 1, /* ENAB */ CHECKMAT_TONE_DATA_67, /* DATA */ &checkmat_r407_406_410) DISCRETE_OP_AMP_OSCILLATOR(NODE_30, /* IC N3/4, pin 4 */ @@ -3441,7 +3437,6 @@ static const discrete_mixer_desc invaders_mixer = #define INVADERS_FLEET(_board) \ DISCRETE_INPUT_DATA (INVADERS_NODE(INVADERS_FLEET_DATA, _board)) \ DISCRETE_COMP_ADDER(INVADERS_NODE(30, _board), \ - 1, /* ENAB */ \ INVADERS_NODE(INVADERS_FLEET_DATA, _board), /* DATA */ \ &invaders_thump_resistors) \ DISCRETE_555_ASTABLE(INVADERS_NODE(31, _board), /* IC F3, pin 6 */ \ diff --git a/src/mame/audio/phoenix.c b/src/mame/audio/phoenix.c index 2e31bf1ad84..b00e8378ec2 100644 --- a/src/mame/audio/phoenix.c +++ b/src/mame/audio/phoenix.c @@ -389,7 +389,6 @@ DISCRETE_SOUND_START(phoenix) /* - phoenix wing hit */ /************************************************/ DISCRETE_COMP_ADDER(NODE_30, /* total capacitance of selected capacitors */ - 1, /* ENAB */ PHOENIX_EFFECT_2_FREQ, /* passed selection bits */ &phoenix_effect2_cap_sel) /* Part of the frequency select also effects the gain */ diff --git a/src/mame/audio/qix.c b/src/mame/audio/qix.c index f5019693740..cd76bce53a5 100644 --- a/src/mame/audio/qix.c +++ b/src/mame/audio/qix.c @@ -60,8 +60,8 @@ static DISCRETE_SOUND_START(qix) DISCRETE_TRANSFORM2(QIX_VOL_DATA_R, QIX_VOL_DATA, 0x0f, "01&") /* Work out the parallel resistance of the selected resistors. */ - DISCRETE_COMP_ADDER(NODE_10, 1, QIX_VOL_DATA_L, &qix_attn_table) - DISCRETE_COMP_ADDER(NODE_20, 1, QIX_VOL_DATA_R, &qix_attn_table) + DISCRETE_COMP_ADDER(NODE_10, QIX_VOL_DATA_L, &qix_attn_table) + DISCRETE_COMP_ADDER(NODE_20, QIX_VOL_DATA_R, &qix_attn_table) /* Then use it for the resistor divider network. */ DISCRETE_TRANSFORM3(NODE_11, NODE_10, RES_K(10), QIX_DAC_DATA, "001+/2*") |