diff options
Diffstat (limited to 'src/emu/sound/disc_dev.c')
-rw-r--r-- | src/emu/sound/disc_dev.c | 632 |
1 files changed, 316 insertions, 316 deletions
diff --git a/src/emu/sound/disc_dev.c b/src/emu/sound/disc_dev.c index a2bdb054889..4276e3cfd64 100644 --- a/src/emu/sound/disc_dev.c +++ b/src/emu/sound/disc_dev.c @@ -24,7 +24,7 @@ * ************************************************************************/ -#define DEFAULT_555_BLEED_R RES_M(10) +#define DEFAULT_555_BLEED_R RES_M(10) /************************************************************************ * @@ -40,39 +40,39 @@ * * Jan 2004, D Renaud. ************************************************************************/ -#define DSD_555_ASTBL__RESET (! DISCRETE_INPUT(0)) -#define DSD_555_ASTBL__R1 DISCRETE_INPUT(1) -#define DSD_555_ASTBL__R2 DISCRETE_INPUT(2) -#define DSD_555_ASTBL__C DISCRETE_INPUT(3) -#define DSD_555_ASTBL__CTRLV DISCRETE_INPUT(4) +#define DSD_555_ASTBL__RESET (! DISCRETE_INPUT(0)) +#define DSD_555_ASTBL__R1 DISCRETE_INPUT(1) +#define DSD_555_ASTBL__R2 DISCRETE_INPUT(2) +#define DSD_555_ASTBL__C DISCRETE_INPUT(3) +#define DSD_555_ASTBL__CTRLV DISCRETE_INPUT(4) /* bit mask of the above RC inputs */ -#define DSD_555_ASTBL_RC_MASK 0x0e +#define DSD_555_ASTBL_RC_MASK 0x0e /* charge/discharge constants */ -#define DSD_555_ASTBL_T_RC_BLEED (DEFAULT_555_BLEED_R * 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) +#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) DISCRETE_STEP(dsd_555_astbl) { DISCRETE_DECLARE_INFO(discrete_555_desc) - int count_f = 0; - int count_r = 0; - double dt; /* change in time */ - double x_time = 0; /* time since change happened */ - double v_cap = m_cap_voltage; /* Current voltage on capacitor, before dt */ - double v_cap_next = 0; /* Voltage on capacitor, after dt */ - double v_charge, exponent = 0; - UINT8 flip_flop = m_flip_flop; - UINT8 update_exponent = 0; - double v_out = 0.0; + int count_f = 0; + int count_r = 0; + double dt; /* change in time */ + double x_time = 0; /* time since change happened */ + double v_cap = m_cap_voltage; /* Current voltage on capacitor, before dt */ + double v_cap_next = 0; /* Voltage on capacitor, after dt */ + double v_charge, exponent = 0; + UINT8 flip_flop = m_flip_flop; + UINT8 update_exponent = 0; + double v_out = 0.0; /* put commonly used stuff in local variables for speed */ - double threshold = m_threshold; - double trigger = m_trigger; + double threshold = m_threshold; + double trigger = m_trigger; if(DSD_555_ASTBL__RESET) { @@ -87,7 +87,7 @@ DISCRETE_STEP(dsd_555_astbl) if (m_use_ctrlv) { /* If CV is less then .25V, the circuit will oscillate way out of range. - * So we will just ignore it when it happens. */ + * So we will just ignore it when it happens. */ if (DSD_555_ASTBL__CTRLV < .25) return; /* If it is a node then calculate thresholds based on Control Voltage */ threshold = DSD_555_ASTBL__CTRLV; @@ -117,28 +117,28 @@ DISCRETE_STEP(dsd_555_astbl) /* Calculate future capacitor voltage. - * ref@ http://www.physics.rutgers.edu/ugrad/205/capacitance.html - * The formulas from the ref pages have been modified to reflect that we are stepping the change. - * dt = time of sample (1/sample frequency) - * VC = Voltage across capacitor - * VC' = Future voltage across capacitor - * Vc = Voltage change - * Vr = is the voltage across the resistor. For charging it is Vcc - VC. Discharging it is VC - 0. - * R = R1+R2 (for charging) R = R2 for discharging. - * Vc = Vr*(1-exp(-dt/(R*C))) - * VC' = VC + Vc (for charging) VC' = VC - Vc for discharging. - * - * We will also need to calculate the amount of time we overshoot the thresholds - * dt = amount of time we overshot - * Vc = voltage change overshoot - * dt = R*C(log(1/(1-(Vc/Vr)))) - */ + * ref@ http://www.physics.rutgers.edu/ugrad/205/capacitance.html + * The formulas from the ref pages have been modified to reflect that we are stepping the change. + * dt = time of sample (1/sample frequency) + * VC = Voltage across capacitor + * VC' = Future voltage across capacitor + * Vc = Voltage change + * Vr = is the voltage across the resistor. For charging it is Vcc - VC. Discharging it is VC - 0. + * R = R1+R2 (for charging) R = R2 for discharging. + * Vc = Vr*(1-exp(-dt/(R*C))) + * VC' = VC + Vc (for charging) VC' = VC - Vc for discharging. + * + * We will also need to calculate the amount of time we overshoot the thresholds + * dt = amount of time we overshot + * Vc = voltage change overshoot + * dt = R*C(log(1/(1-(Vc/Vr)))) + */ dt = this->sample_time(); /* Sometimes a switching network is used to setup the capacitance. - * These may select no capacitor, causing oscillation to stop. - */ + * These may select no capacitor, causing oscillation to stop. + */ if (DSD_555_ASTBL__C == 0) { flip_flop = 1; @@ -353,20 +353,20 @@ DISCRETE_RESET(dsd_555_astbl) * * Oct 2004, D Renaud. ************************************************************************/ -#define DSD_555_MSTBL__RESET (! DISCRETE_INPUT(0)) -#define DSD_555_MSTBL__TRIGGER DISCRETE_INPUT(1) -#define DSD_555_MSTBL__R DISCRETE_INPUT(2) -#define DSD_555_MSTBL__C DISCRETE_INPUT(3) +#define DSD_555_MSTBL__RESET (! DISCRETE_INPUT(0)) +#define DSD_555_MSTBL__TRIGGER DISCRETE_INPUT(1) +#define DSD_555_MSTBL__R DISCRETE_INPUT(2) +#define DSD_555_MSTBL__C DISCRETE_INPUT(3) /* bit mask of the above RC inputs */ -#define DSD_555_MSTBL_RC_MASK 0x0c +#define DSD_555_MSTBL_RC_MASK 0x0c DISCRETE_STEP(dsd_555_mstbl) { DISCRETE_DECLARE_INFO(discrete_555_desc) - double v_cap; /* Current voltage on capacitor, before dt */ - double x_time = 0; /* time since change happened */ + double v_cap; /* Current voltage on capacitor, before dt */ + double x_time = 0; /* time since change happened */ double dt, exponent; double out = 0; int trigger = 0; @@ -426,13 +426,13 @@ DISCRETE_STEP(dsd_555_mstbl) if (flip_flop) { /* Sometimes a switching network is used to setup the capacitance. - * These may select 'no' capacitor, causing oscillation to stop. - */ + * These may select 'no' capacitor, causing oscillation to stop. + */ if (UNEXPECTED(DSD_555_MSTBL__C == 0)) { /* The trigger voltage goes high because the cap circuit is open. - * and the cap discharges */ - v_cap = info->v_pos; /* needed for cap output type */ + * and the cap discharges */ + v_cap = info->v_pos; /* needed for cap output type */ m_cap_voltage = 0; if (!trigger) @@ -454,7 +454,7 @@ DISCRETE_STEP(dsd_555_mstbl) /* Has it charged past upper limit? */ /* If trigger is still enabled, then we keep charging, - * regardless of threshold. */ + * regardless of threshold. */ if (UNEXPECTED((v_cap >= m_threshold) && !trigger)) { dt = DSD_555_MSTBL__R * DSD_555_MSTBL__C * log(1.0 / (1.0 - ((v_cap - m_threshold) / v_diff))); @@ -557,47 +557,47 @@ DISCRETE_RESET(dsd_555_mstbl) * * Mar 2004, D Renaud. ************************************************************************/ -#define DSD_555_CC__RESET (! DISCRETE_INPUT(0)) -#define DSD_555_CC__VIN DISCRETE_INPUT(1) -#define DSD_555_CC__R DISCRETE_INPUT(2) -#define DSD_555_CC__C DISCRETE_INPUT(3) -#define DSD_555_CC__RBIAS DISCRETE_INPUT(4) -#define DSD_555_CC__RGND DISCRETE_INPUT(5) -#define DSD_555_CC__RDIS DISCRETE_INPUT(6) +#define DSD_555_CC__RESET (! DISCRETE_INPUT(0)) +#define DSD_555_CC__VIN DISCRETE_INPUT(1) +#define DSD_555_CC__R DISCRETE_INPUT(2) +#define DSD_555_CC__C DISCRETE_INPUT(3) +#define DSD_555_CC__RBIAS DISCRETE_INPUT(4) +#define DSD_555_CC__RGND DISCRETE_INPUT(5) +#define DSD_555_CC__RDIS DISCRETE_INPUT(6) /* bit mask of the above RC inputs not including DSD_555_CC__R */ -#define DSD_555_CC_RC_MASK 0x78 +#define DSD_555_CC_RC_MASK 0x78 /* charge/discharge constants */ -#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) -#define DSD_555_CC_T_RC_DISCHARGE (r_discharge * 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) +#define DSD_555_CC_T_RC_DISCHARGE (r_discharge * DSD_555_CC__C) DISCRETE_STEP(dsd_555_cc) { DISCRETE_DECLARE_INFO(discrete_555_cc_desc) - int count_f = 0; - int count_r = 0; - double i; /* Charging current created by vIn */ - double r_charge = 0; /* Equivalent charging resistor */ - double r_discharge = 0; /* Equivalent discharging resistor */ - double vi = 0; /* Equivalent voltage from current source */ - double v_bias = 0; /* Equivalent voltage from bias voltage */ - double v = 0; /* Equivalent voltage total from current source and bias circuit if used */ - double dt; /* change in time */ - double x_time = 0; /* time since change happened */ - double t_rc ; /* RC time constant */ - double v_cap; /* Current voltage on capacitor, before dt */ - double v_cap_next = 0; /* Voltage on capacitor, after dt */ - double v_vcharge_limit; /* vIn and the junction voltage limit the max charging voltage from i */ - double r_temp; /* play thing */ - double exponent; - UINT8 update_exponent, update_t_rc; - UINT8 flip_flop = m_flip_flop; + int count_f = 0; + int count_r = 0; + double i; /* Charging current created by vIn */ + double r_charge = 0; /* Equivalent charging resistor */ + double r_discharge = 0; /* Equivalent discharging resistor */ + double vi = 0; /* Equivalent voltage from current source */ + double v_bias = 0; /* Equivalent voltage from bias voltage */ + double v = 0; /* Equivalent voltage total from current source and bias circuit if used */ + double dt; /* change in time */ + double x_time = 0; /* time since change happened */ + double t_rc ; /* RC time constant */ + double v_cap; /* Current voltage on capacitor, before dt */ + double v_cap_next = 0; /* Voltage on capacitor, after dt */ + double v_vcharge_limit; /* vIn and the junction voltage limit the max charging voltage from i */ + double r_temp; /* play thing */ + double exponent; + UINT8 update_exponent, update_t_rc; + UINT8 flip_flop = m_flip_flop; double v_out = 0; @@ -611,9 +611,9 @@ DISCRETE_STEP(dsd_555_cc) return; } - dt = this->sample_time(); /* Change in time */ - v_cap = m_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 */ + dt = this->sample_time(); /* Change in time */ + v_cap = m_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 */ i = (m_v_cc_source - v_vcharge_limit) / DSD_555_CC__R; if ( i < 0) i = 0; @@ -624,7 +624,7 @@ DISCRETE_STEP(dsd_555_cc) } else { - switch (m_type) /* see dsd_555_cc_reset for descriptions */ + switch (m_type) /* see dsd_555_cc_reset for descriptions */ { case 1: r_discharge = DSD_555_CC__RDIS; @@ -656,7 +656,7 @@ DISCRETE_STEP(dsd_555_cc) r_temp = DSD_555_CC__RBIAS + DSD_555_CC__RDIS; r_charge = RES_2_PARALLEL(r_temp, DSD_555_CC__RGND); r_temp += DSD_555_CC__RGND; - r_temp = DSD_555_CC__RGND / r_temp; /* now has voltage divider ratio, not resistance */ + r_temp = DSD_555_CC__RGND / r_temp; /* now has voltage divider ratio, not resistance */ vi = i * DSD_555_CC__RBIAS * r_temp; v_bias = info->v_pos * r_temp; r_discharge = RES_2_PARALLEL(DSD_555_CC__RGND, DSD_555_CC__RDIS); @@ -677,8 +677,8 @@ DISCRETE_STEP(dsd_555_cc) if (i == 0) { /* No charging current, so we have to discharge the cap - * due to cap and circuit losses. - */ + * due to cap and circuit losses. + */ if (update_exponent) { t_rc = DSD_555_CC_T_RC_BLEED; @@ -695,10 +695,10 @@ DISCRETE_STEP(dsd_555_cc) /* iC=C*dv/dt works out to dv=iC*dt/C */ v_cap_next = v_cap + (i * dt / DSD_555_CC__C); /* Yes, if the cap voltage has reached the max voltage it can, - * and the 555 threshold has not been reached, then oscillation stops. - * This is the way the actual electronics works. - * This is why you never play with the pots after being factory adjusted - * to work in the proper range. */ + * and the 555 threshold has not been reached, then oscillation stops. + * This is the way the actual electronics works. + * This is why you never play with the pots after being factory adjusted + * to work in the proper range. */ if (v_cap_next > v_vcharge_limit) v_cap_next = v_vcharge_limit; dt = 0; @@ -732,7 +732,7 @@ DISCRETE_STEP(dsd_555_cc) /* Asteroids - Special Case */ /* Charging in discharge mode */ /* If the cap voltage is past the current source charging limit - * then only the bias voltage will charge the cap. */ + * then only the bias voltage will charge the cap. */ v = (v_cap < v_vcharge_limit) ? vi : v_vcharge_limit; v_cap_next = v_cap + ((v - v_cap) * exponent); } @@ -753,7 +753,7 @@ DISCRETE_STEP(dsd_555_cc) update_exponent = 1; } } - else /* Immediate discharge. No change in dt. */ + else /* Immediate discharge. No change in dt. */ { x_time = dt; v_cap_next = m_trigger; @@ -769,8 +769,8 @@ DISCRETE_STEP(dsd_555_cc) if ((i == 0) && (DSD_555_CC__RBIAS == 0)) { /* No charging current, so we have to discharge the cap - * due to rGnd. - */ + * due to rGnd. + */ if (update_t_rc) t_rc = DSD_555_CC_T_RC_DISCHARGE_NO_I; else @@ -787,7 +787,7 @@ DISCRETE_STEP(dsd_555_cc) { /* Charging */ /* If the cap voltage is past the current source charging limit - * then only the bias voltage will charge the cap. */ + * then only the bias voltage will charge the cap. */ v = v_bias; if (v_cap < v_vcharge_limit) v += vi; else if (m_type <= 3) v = v_vcharge_limit; @@ -844,7 +844,7 @@ DISCRETE_STEP(dsd_555_cc) update_exponent = 1; } } - else /* Immediate discharge. No change in dt. */ + else /* Immediate discharge. No change in dt. */ { x_time = dt; v_cap_next = m_trigger; @@ -903,7 +903,7 @@ DISCRETE_RESET(dsd_555_cc) { DISCRETE_DECLARE_INFO(discrete_555_cc_desc) - double r_temp, r_discharge = 0, r_charge = 0; + double r_temp, r_discharge = 0, r_charge = 0; m_flip_flop = 1; m_cap_voltage = 0; @@ -923,10 +923,10 @@ DISCRETE_RESET(dsd_555_cc) m_ac_shift = m_output_is_ac ? -m_v_out_high / 2.0 : 0; /* There are 8 different types of basic oscillators - * depending on the resistors used. We will determine - * the type of circuit at reset, because the ciruit type - * is constant. See Below. - */ + * depending on the resistors used. We will determine + * the type of circuit at reset, because the ciruit type + * is constant. See Below. + */ m_type = (DSD_555_CC__RDIS > 0) | ((DSD_555_CC__RGND > 0) << 1) | ((DSD_555_CC__RBIAS > 0) << 2); /* optimization if none of the values are nodes */ @@ -935,7 +935,7 @@ DISCRETE_RESET(dsd_555_cc) m_has_rc_nodes = 1; else { - switch (m_type) /* see dsd_555_cc_reset for descriptions */ + switch (m_type) /* see dsd_555_cc_reset for descriptions */ { case 1: r_discharge = DSD_555_CC__RDIS; @@ -978,137 +978,137 @@ DISCRETE_RESET(dsd_555_cc) this->step(); /* - * TYPES: - * Note: These are equivalent circuits shown without the 555 circuitry. - * See the schematic in src\sound\discrete.h for full hookup info. - * - * DISCRETE_555_CC_TO_DISCHARGE_PIN - * When the CC source is connected to the discharge pin, it allows the - * circuit to charge when the 555 is in charge mode. But when in discharge - * mode, the CC source is grounded, disabling it's effect. - * - * [0] - * No resistors. Straight constant current charge of capacitor. - * When there is not any charge current, the cap will bleed off. - * Once the lower threshold(trigger) is reached, the output will - * go high but the cap will continue to discharge due to losses. - * .------+---> cap_voltage CHARGING: - * | | dv (change in voltage) compared to dt (change in time in seconds). - * .---. --- dv = i * dt / C; where i is current in amps and C is capacitance in farads. - * | i | --- C cap_voltage = cap_voltage + dv - * '---' | - * | | DISCHARGING: - * gnd gnd instantaneous - * - * [1] - * Same as type 1 but with rDischarge. rDischarge has no effect on the charge rate because - * of the constant current source i. - * When there is not any charge current, the cap will bleed off. - * Once the lower threshold(trigger) is reached, the output will - * go high but the cap will continue to discharge due to losses. - * .----ZZZ-----+---> cap_voltage CHARGING: - * | rDischarge | dv (change in voltage) compared to dt (change in time in seconds). - * .---. --- dv = i * dt / C; where i is current in amps and C is capacitance in farads. - * | i | --- C cap_voltage = cap_voltage + dv - * '---' | - * | | DISCHARGING: - * gnd gnd through rDischarge - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! IMPORTANT NOTE ABOUT TYPES 3 - 7 !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * From here on in all the circuits have either an rBias or rGnd resistor. - * This converts the constant current into a voltage source. - * So all the remaining circuit types will be converted to this circuit. - * When discharging, rBias is out of the equation because the 555 is grounding the circuit - * after that point. - * - * .------------. Rc Rc is the equivilent circuit resistance. - * | v |----ZZZZ---+---> cap_voltage v is the equivilent circuit voltage. - * | | | - * '------------' --- Then the standard RC charging formula applies. - * | --- C - * | | NOTE: All the following types are converted to Rc and v values. - * gnd gnd - * - * [2] - * When there is not any charge current, the cap will bleed off. - * Once the lower threshold(trigger) is reached, the output will - * go high but the cap will continue to discharge due to rGnd. - * .-------+------+------> cap_voltage CHARGING: - * | | | v = vi = i * rGnd - * .---. --- Z Rc = rGnd - * | i | --- C Z rGnd - * '---' | | DISCHARGING: - * | | | instantaneous - * gnd gnd gnd - * - * [3] - * When there is not any charge current, the cap will bleed off. - * Once the lower threshold(trigger) is reached, the output will - * go high but the cap will continue to discharge due to rGnd. - * .----ZZZ-----+------+------> cap_voltage CHARGING: - * | rDischarge | | v = vi = i * rGnd - * .---. --- Z Rc = rGnd - * | i | --- C Z rGnd - * '---' | | DISCHARGING: - * | | | through rDischarge || rGnd ( || means in parallel) - * gnd gnd gnd - * - * [4] - * .---ZZZ---+------------+-------------> cap_voltage CHARGING: - * | rBias | | Rc = rBias - * .-------. .---. --- vi = i * rBias - * | vBias | | i | --- C v = vBias + vi - * '-------' '---' | - * | | | DISCHARGING: - * gnd gnd gnd instantaneous - * - * [5] - * .---ZZZ---+----ZZZ-----+-------------> cap_voltage CHARGING: - * | rBias | rDischarge | Rc = rBias + rDischarge - * .-------. .---. --- vi = i * rBias - * | vBias | | i | --- C v = vBias + vi - * '-------' '---' | - * | | | DISCHARGING: - * gnd gnd gnd through rDischarge - * - * [6] - * .---ZZZ---+------------+------+------> cap_voltage CHARGING: - * | rBias | | | Rc = rBias || rGnd - * .-------. .---. --- Z vi = i * Rc - * | vBias | | i | --- C Z rGnd v = vBias * (rGnd / (rBias + rGnd)) + vi - * '-------' '---' | | - * | | | | DISCHARGING: - * gnd gnd gnd gnd instantaneous - * - * [7] - * .---ZZZ---+----ZZZ-----+------+------> cap_voltage CHARGING: - * | rBias | rDischarge | | Rc = (rBias + rDischarge) || rGnd - * .-------. .---. --- Z vi = i * rBias * (rGnd / (rBias + rDischarge + rGnd)) - * | vBias | | i | --- C Z rGnd v = vBias * (rGnd / (rBias + rDischarge + rGnd)) + vi - * '-------' '---' | | - * | | | | DISCHARGING: - * gnd gnd gnd gnd through rDischarge || rGnd - */ - - /* - * DISCRETE_555_CC_TO_CAP - * - * When the CC source is connected to the capacitor, it allows the - * current to charge the cap while it is in discharge mode, slowing the - * discharge. So in charge mode it charges linearly from the constant - * current cource. But when in discharge mode it behaves like circuit - * type 2 above. - * .-------+------+------> cap_voltage CHARGING: - * | | | dv = i * dt / C - * .---. --- Z cap_voltage = cap_voltage + dv - * | i | --- C Z rDischarge - * '---' | | DISCHARGING: - * | | | v = vi = i * rGnd - * gnd gnd discharge Rc = rDischarge - */ + * TYPES: + * Note: These are equivalent circuits shown without the 555 circuitry. + * See the schematic in src\sound\discrete.h for full hookup info. + * + * DISCRETE_555_CC_TO_DISCHARGE_PIN + * When the CC source is connected to the discharge pin, it allows the + * circuit to charge when the 555 is in charge mode. But when in discharge + * mode, the CC source is grounded, disabling it's effect. + * + * [0] + * No resistors. Straight constant current charge of capacitor. + * When there is not any charge current, the cap will bleed off. + * Once the lower threshold(trigger) is reached, the output will + * go high but the cap will continue to discharge due to losses. + * .------+---> cap_voltage CHARGING: + * | | dv (change in voltage) compared to dt (change in time in seconds). + * .---. --- dv = i * dt / C; where i is current in amps and C is capacitance in farads. + * | i | --- C cap_voltage = cap_voltage + dv + * '---' | + * | | DISCHARGING: + * gnd gnd instantaneous + * + * [1] + * Same as type 1 but with rDischarge. rDischarge has no effect on the charge rate because + * of the constant current source i. + * When there is not any charge current, the cap will bleed off. + * Once the lower threshold(trigger) is reached, the output will + * go high but the cap will continue to discharge due to losses. + * .----ZZZ-----+---> cap_voltage CHARGING: + * | rDischarge | dv (change in voltage) compared to dt (change in time in seconds). + * .---. --- dv = i * dt / C; where i is current in amps and C is capacitance in farads. + * | i | --- C cap_voltage = cap_voltage + dv + * '---' | + * | | DISCHARGING: + * gnd gnd through rDischarge + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !!!!! IMPORTANT NOTE ABOUT TYPES 3 - 7 !!!!! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * From here on in all the circuits have either an rBias or rGnd resistor. + * This converts the constant current into a voltage source. + * So all the remaining circuit types will be converted to this circuit. + * When discharging, rBias is out of the equation because the 555 is grounding the circuit + * after that point. + * + * .------------. Rc Rc is the equivilent circuit resistance. + * | v |----ZZZZ---+---> cap_voltage v is the equivilent circuit voltage. + * | | | + * '------------' --- Then the standard RC charging formula applies. + * | --- C + * | | NOTE: All the following types are converted to Rc and v values. + * gnd gnd + * + * [2] + * When there is not any charge current, the cap will bleed off. + * Once the lower threshold(trigger) is reached, the output will + * go high but the cap will continue to discharge due to rGnd. + * .-------+------+------> cap_voltage CHARGING: + * | | | v = vi = i * rGnd + * .---. --- Z Rc = rGnd + * | i | --- C Z rGnd + * '---' | | DISCHARGING: + * | | | instantaneous + * gnd gnd gnd + * + * [3] + * When there is not any charge current, the cap will bleed off. + * Once the lower threshold(trigger) is reached, the output will + * go high but the cap will continue to discharge due to rGnd. + * .----ZZZ-----+------+------> cap_voltage CHARGING: + * | rDischarge | | v = vi = i * rGnd + * .---. --- Z Rc = rGnd + * | i | --- C Z rGnd + * '---' | | DISCHARGING: + * | | | through rDischarge || rGnd ( || means in parallel) + * gnd gnd gnd + * + * [4] + * .---ZZZ---+------------+-------------> cap_voltage CHARGING: + * | rBias | | Rc = rBias + * .-------. .---. --- vi = i * rBias + * | vBias | | i | --- C v = vBias + vi + * '-------' '---' | + * | | | DISCHARGING: + * gnd gnd gnd instantaneous + * + * [5] + * .---ZZZ---+----ZZZ-----+-------------> cap_voltage CHARGING: + * | rBias | rDischarge | Rc = rBias + rDischarge + * .-------. .---. --- vi = i * rBias + * | vBias | | i | --- C v = vBias + vi + * '-------' '---' | + * | | | DISCHARGING: + * gnd gnd gnd through rDischarge + * + * [6] + * .---ZZZ---+------------+------+------> cap_voltage CHARGING: + * | rBias | | | Rc = rBias || rGnd + * .-------. .---. --- Z vi = i * Rc + * | vBias | | i | --- C Z rGnd v = vBias * (rGnd / (rBias + rGnd)) + vi + * '-------' '---' | | + * | | | | DISCHARGING: + * gnd gnd gnd gnd instantaneous + * + * [7] + * .---ZZZ---+----ZZZ-----+------+------> cap_voltage CHARGING: + * | rBias | rDischarge | | Rc = (rBias + rDischarge) || rGnd + * .-------. .---. --- Z vi = i * rBias * (rGnd / (rBias + rDischarge + rGnd)) + * | vBias | | i | --- C Z rGnd v = vBias * (rGnd / (rBias + rDischarge + rGnd)) + vi + * '-------' '---' | | + * | | | | DISCHARGING: + * gnd gnd gnd gnd through rDischarge || rGnd + */ + + /* + * DISCRETE_555_CC_TO_CAP + * + * When the CC source is connected to the capacitor, it allows the + * current to charge the cap while it is in discharge mode, slowing the + * discharge. So in charge mode it charges linearly from the constant + * current cource. But when in discharge mode it behaves like circuit + * type 2 above. + * .-------+------+------> cap_voltage CHARGING: + * | | | dv = i * dt / C + * .---. --- Z cap_voltage = cap_voltage + dv + * | i | --- C Z rDischarge + * '---' | | DISCHARGING: + * | | | v = vi = i * rGnd + * gnd gnd discharge Rc = rDischarge + */ } @@ -1124,31 +1124,31 @@ DISCRETE_RESET(dsd_555_cc) * * Apr 2006, D Renaud. ************************************************************************/ -#define DSD_555_VCO1__RESET DISCRETE_INPUT(0) /* reset active low */ -#define DSD_555_VCO1__VIN1 DISCRETE_INPUT(1) -#define DSD_555_VCO1__VIN2 DISCRETE_INPUT(2) +#define DSD_555_VCO1__RESET DISCRETE_INPUT(0) /* reset active low */ +#define DSD_555_VCO1__VIN1 DISCRETE_INPUT(1) +#define DSD_555_VCO1__VIN2 DISCRETE_INPUT(2) DISCRETE_STEP(dsd_555_vco1) { DISCRETE_DECLARE_INFO(discrete_555_vco1_desc) - int count_f = 0; - int count_r = 0; - double dt; /* change in time */ - double x_time = 0; /* time since change happened */ - double v_cap; /* Current voltage on capacitor, before dt */ - double v_cap_next = 0; /* Voltage on capacitor, after dt */ + int count_f = 0; + int count_r = 0; + double dt; /* change in time */ + double x_time = 0; /* time since change happened */ + double v_cap; /* Current voltage on capacitor, before dt */ + double v_cap_next = 0; /* Voltage on capacitor, after dt */ - double v_out = 0; + double v_out = 0; - dt = this->sample_time(); /* Change in time */ + dt = this->sample_time(); /* Change in time */ v_cap = m_cap_voltage; /* Check: if the Control Voltage node is connected. */ - if (m_ctrlv_is_node && DSD_555_VCO1__RESET) /* reset active low */ + if (m_ctrlv_is_node && DSD_555_VCO1__RESET) /* reset active low */ { /* If CV is less then .25V, the circuit will oscillate way out of range. - * So we will just ignore it when it happens. */ + * So we will just ignore it when it happens. */ if (DSD_555_VCO1__VIN2 < .25) return; /* If it is a node then calculate thresholds based on Control Voltage */ m_threshold = DSD_555_VCO1__VIN2; @@ -1175,7 +1175,7 @@ DISCRETE_STEP(dsd_555_vco1) if (m_flip_flop) { /* if we are in reset then toggle f/f and discharge */ - if (!DSD_555_VCO1__RESET) /* reset active low */ + if (!DSD_555_VCO1__RESET) /* reset active low */ { m_flip_flop = 0; count_f++; @@ -1206,7 +1206,7 @@ DISCRETE_STEP(dsd_555_vco1) v_cap_next = v_cap - (m_i_discharge * dt / info->c); /* if we are in reset, then the cap can discharge to 0 */ - if (!DSD_555_VCO1__RESET) /* reset active low */ + if (!DSD_555_VCO1__RESET) /* reset active low */ { if (v_cap_next < 0) v_cap_next = 0; dt = 0; @@ -1214,7 +1214,7 @@ DISCRETE_STEP(dsd_555_vco1) else { /* if we are out of reset and the cap voltage is less then - * the lower threshold, toggle f/f and start charging */ + * the lower threshold, toggle f/f and start charging */ if (v_cap <= m_trigger) { if (m_flip_flop == 0) @@ -1295,19 +1295,19 @@ DISCRETE_RESET(dsd_555_vco1) /* Setup op-amp parameters */ /* The voltage at op-amp +in is always a fixed ratio of the modulation voltage. */ - v_ratio_r3 = info->r3 / (info->r2 + info->r3); /* +in voltage */ + v_ratio_r3 = info->r3 / (info->r2 + info->r3); /* +in voltage */ /* The voltage at op-amp -in is 1 of 2 fixed ratios of the modulation voltage, - * based on the 555 Flip-Flop state. */ + * based on the 555 Flip-Flop state. */ /* If the FF is 0, then only R1 is connected allowing the full modulation volatge to pass. */ /* v_ratio_r4_0 = 1 */ /* If the FF is 1, then R1 & R4 make a voltage divider similar to R2 & R3 */ - v_ratio_r4_1 = info->r4 / (info->r1 + info->r4); /* -in voltage */ + v_ratio_r4_1 = info->r4 / (info->r1 + info->r4); /* -in voltage */ /* the input resistance to the op amp depends on the FF state */ /* r_in_0 = info->r1 when FF = 0 */ - r_in_1 = 1.0 / (1.0 / info->r1 + 1.0 / info->r4); /* input resistance when r4 switched in */ + r_in_1 = 1.0 / (1.0 / info->r1 + 1.0 / info->r4); /* input resistance when r4 switched in */ /* Now that we know the voltages entering the op amp and the resistance for the - * FF states, we can predetermine the ratios for the charge/discharge currents. */ + * FF states, we can predetermine the ratios for the charge/discharge currents. */ m_i_discharge = (1 - v_ratio_r3) / info->r1; m_i_charge = (v_ratio_r3 - v_ratio_r4_1) / r_in_1; @@ -1322,9 +1322,9 @@ DISCRETE_RESET(dsd_555_vco1) m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; /* Calculate 555 thresholds. - * If the Control Voltage is a node, then the thresholds will be calculated each step. - * If the Control Voltage is a fixed voltage, then the thresholds will be calculated - * from that. Otherwise we will use thresholds based on v_pos. */ + * If the Control Voltage is a node, then the thresholds will be calculated each step. + * If the Control Voltage is a fixed voltage, then the thresholds will be calculated + * from that. Otherwise we will use thresholds based on v_pos. */ if (!m_ctrlv_is_node && (DSD_555_VCO1__VIN2 != -1)) { /* Setup based on supplied Control Voltage static value */ @@ -1394,45 +1394,45 @@ DISCRETE_RESET(dsd_555_vco1) * in frequency. * ************************************************************************/ -#define DSD_566__VMOD DISCRETE_INPUT(0) -#define DSD_566__R DISCRETE_INPUT(1) -#define DSD_566__C DISCRETE_INPUT(2) -#define DSD_566__VPOS DISCRETE_INPUT(3) -#define DSD_566__VNEG DISCRETE_INPUT(4) -#define DSD_566__VCHARGE DISCRETE_INPUT(5) -#define DSD_566__OPTIONS DISCRETE_INPUT(6) +#define DSD_566__VMOD DISCRETE_INPUT(0) +#define DSD_566__R DISCRETE_INPUT(1) +#define DSD_566__C DISCRETE_INPUT(2) +#define DSD_566__VPOS DISCRETE_INPUT(3) +#define DSD_566__VNEG DISCRETE_INPUT(4) +#define DSD_566__VCHARGE DISCRETE_INPUT(5) +#define DSD_566__OPTIONS DISCRETE_INPUT(6) static const struct { - double c_high[6]; - double c_low[6]; - double sqr_low[6]; - double osc_stable[6]; - double osc_stop[6]; + double c_high[6]; + double c_low[6]; + double sqr_low[6]; + double osc_stable[6]; + double osc_stop[6]; } ne566 = { /* 10 10.5 11 11.5 12 13 14 15 B+ */ - {3.364, /*3.784,*/ 4.259, /*4.552,*/ 4.888, 5.384, 5.896, 6.416}, /* c_high */ - {1.940, /*2.100,*/ 2.276, /*2.404,*/ 2.580, 2.880, 3.180, 3.488}, /* c_low */ - {4.352, /*4.144,*/ 4.080, /*4.260,*/ 4.500, 4.960, 5.456, 5.940}, /* sqr_low */ - {4.885, /*5.316,*/ 5.772, /*6.075,*/ 6.335, 6.912, 7.492, 7.945}, /* osc_stable */ - {4.495, /*4.895,*/ 5.343, /*5.703,*/ 5.997, 6.507, 7.016, 7.518} /* osc_stop */ + {3.364, /*3.784,*/ 4.259, /*4.552,*/ 4.888, 5.384, 5.896, 6.416}, /* c_high */ + {1.940, /*2.100,*/ 2.276, /*2.404,*/ 2.580, 2.880, 3.180, 3.488}, /* c_low */ + {4.352, /*4.144,*/ 4.080, /*4.260,*/ 4.500, 4.960, 5.456, 5.940}, /* sqr_low */ + {4.885, /*5.316,*/ 5.772, /*6.075,*/ 6.335, 6.912, 7.492, 7.945}, /* osc_stable */ + {4.495, /*4.895,*/ 5.343, /*5.703,*/ 5.997, 6.507, 7.016, 7.518} /* osc_stop */ }; DISCRETE_STEP(dsd_566) { - double i = 0; /* Charging current created by vIn */ - double i_rise; /* non-linear rise charge current */ - double dt; /* change in time */ - double x_time = 0; - double v_cap; /* Current voltage on capacitor, before dt */ - int count_f = 0, count_r = 0; + double i = 0; /* Charging current created by vIn */ + double i_rise; /* non-linear rise charge current */ + double dt; /* change in time */ + double x_time = 0; + double v_cap; /* Current voltage on capacitor, before dt */ + int count_f = 0, count_r = 0; - double v_out = 0.0; + double v_out = 0.0; - dt = this->sample_time(); /* Change in time */ - v_cap = m_cap_voltage; /* Set to voltage before change */ + dt = this->sample_time(); /* Change in time */ + v_cap = m_cap_voltage; /* Set to voltage before change */ /* Calculate charging current if it is in range */ if (EXPECTED(DSD_566__VMOD > m_v_osc_stop)) @@ -1482,10 +1482,10 @@ DISCRETE_STEP(dsd_566) v_cap += i_rise * dt / DSD_566__C; dt = 0; /* Yes, if the cap voltage has reached the max voltage it can, - * and the 566 threshold has not been reached, then oscillation stops. - * This is the way the actual electronics works. - * This is why you never play with the pots after being factory adjusted - * to work in the proper range. */ + * and the 566 threshold has not been reached, then oscillation stops. + * This is the way the actual electronics works. + * This is why you never play with the pots after being factory adjusted + * to work in the proper range. */ if (UNEXPECTED(v_cap > DSD_566__VMOD)) v_cap = DSD_566__VMOD; /* has it charged past upper limit? */ @@ -1545,8 +1545,8 @@ DISCRETE_STEP(dsd_566) DISCRETE_RESET(dsd_566) { - int v_int; - double v_float; + int v_int; + double v_float; m_out_type = (int)DSD_566__OPTIONS & DISC_566_OUT_MASK; m_fake_ac = (int)DSD_566__OPTIONS & DISC_566_OUT_AC; @@ -1571,8 +1571,8 @@ DISCRETE_RESET(dsd_566) m_v_sqr_high = DSD_566__VPOS - 1; m_v_sqr_low = ne566.sqr_low[v_int] + DSD_566__VNEG; m_v_sqr_diff = m_v_sqr_high - m_v_sqr_low; - m_v_osc_stable = ne566.osc_stable[v_int] + DSD_566__VNEG; - m_v_osc_stop = ne566.osc_stop[v_int] + DSD_566__VNEG; + m_v_osc_stable = ne566.osc_stable[v_int] + DSD_566__VNEG; + m_v_osc_stop = ne566.osc_stop[v_int] + DSD_566__VNEG; m_ac_shift = 0; if (m_fake_ac) @@ -1595,18 +1595,18 @@ DISCRETE_RESET(dsd_566) * Dec 2007, Couriersud based on data sheet * Oct 2009, complete re-write based on IC testing ************************************************************************/ -#define DSD_LS624__ENABLE DISCRETE_INPUT(0) -#define DSD_LS624__VMOD DISCRETE_INPUT(1) -#define DSD_LS624__VRNG DISCRETE_INPUT(2) -#define DSD_LS624__C DISCRETE_INPUT(3) -#define DSD_LS624__R_FREQ_IN DISCRETE_INPUT(4) -#define DSD_LS624__C_FREQ_IN DISCRETE_INPUT(5) -#define DSD_LS624__R_RNG_IN DISCRETE_INPUT(6) -#define DSD_LS624__OUTTYPE DISCRETE_INPUT(7) - -#define LS624_R_EXT 600.0 /* as specified in data sheet */ -#define LS624_OUT_HIGH 4.5 /* measured */ -#define LS624_IN_R RES_K(90) /* measured & 70K + 20k per data sheet */ +#define DSD_LS624__ENABLE DISCRETE_INPUT(0) +#define DSD_LS624__VMOD DISCRETE_INPUT(1) +#define DSD_LS624__VRNG DISCRETE_INPUT(2) +#define DSD_LS624__C DISCRETE_INPUT(3) +#define DSD_LS624__R_FREQ_IN DISCRETE_INPUT(4) +#define DSD_LS624__C_FREQ_IN DISCRETE_INPUT(5) +#define DSD_LS624__R_RNG_IN DISCRETE_INPUT(6) +#define DSD_LS624__OUTTYPE DISCRETE_INPUT(7) + +#define LS624_R_EXT 600.0 /* as specified in data sheet */ +#define LS624_OUT_HIGH 4.5 /* measured */ +#define LS624_IN_R RES_K(90) /* measured & 70K + 20k per data sheet */ /* * The 74LS624 series are constant current based VCOs. The Freq Control voltage @@ -1644,14 +1644,14 @@ DISCRETE_RESET(dsd_566) DISCRETE_STEP(dsd_ls624) { - double x_time = 0; - double freq, t1; - double v_freq_2, v_freq_3, v_freq_4; - double t_used = m_t_used; - double dt = this->sample_time();; - double v_freq = DSD_LS624__VMOD; - double v_rng = DSD_LS624__VRNG; - int count_f = 0, count_r = 0; + double x_time = 0; + double freq, t1; + double v_freq_2, v_freq_3, v_freq_4; + double t_used = m_t_used; + double dt = this->sample_time();; + double v_freq = DSD_LS624__VMOD; + double v_rng = DSD_LS624__VRNG; + int count_f = 0, count_r = 0; /* coefficients */ const double k1 = 1.9904769024796283E+03; |