From 54d913bda83dd7000bcc1e8418bc6ac3a49ba4f7 Mon Sep 17 00:00:00 2001 From: Derrick Renaud Date: Thu, 1 Oct 2009 04:12:28 +0000 Subject: [PATCH] DISCRETE_555_MSTABLE - optimized speed and added new operating modes. Sprint 8 - started discrete sound. --- .gitattributes | 1 + src/emu/sound/disc_dev.c | 161 ++++++++++++++-------- src/emu/sound/discrete.h | 18 ++- src/mame/audio/firetrk.c | 2 +- src/mame/audio/sprint8.c | 267 ++++++++++++++++++++++++++++++++++++ src/mame/drivers/sprint8.c | 49 ++++--- src/mame/includes/sprint8.h | 12 ++ src/mame/mame.mak | 2 +- 8 files changed, 429 insertions(+), 83 deletions(-) create mode 100644 src/mame/audio/sprint8.c diff --git a/.gitattributes b/.gitattributes index 7e15b05779d..6be2e0d0259 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1215,6 +1215,7 @@ src/mame/audio/spiders.c svneol=native#text/plain src/mame/audio/sprint2.c svneol=native#text/plain src/mame/audio/sprint4.c svneol=native#text/plain src/mame/audio/sprint4.h svneol=native#text/plain +src/mame/audio/sprint8.c svneol=native#text/plain src/mame/audio/starshp1.c svneol=native#text/plain src/mame/audio/starwars.c svneol=native#text/plain src/mame/audio/subs.c svneol=native#text/plain diff --git a/src/emu/sound/disc_dev.c b/src/emu/sound/disc_dev.c index adac0ed4768..f8fca735fea 100644 --- a/src/emu/sound/disc_dev.c +++ b/src/emu/sound/disc_dev.c @@ -58,6 +58,8 @@ struct dsd_555_mstbl_context int output_is_ac; double ac_shift; /* DC shift needed to make waveform ac */ int flip_flop; /* 555 flip/flop output state */ + int has_rc_nodes; + double exp_charge; double cap_voltage; /* voltage on cap */ double threshold; double trigger; @@ -457,6 +459,9 @@ static DISCRETE_RESET(dsd_555_astbl) #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 + static DISCRETE_STEP(dsd_555_mstbl) { const discrete_555_desc *info = (const discrete_555_desc *)node->custom; @@ -464,6 +469,11 @@ static DISCRETE_STEP(dsd_555_mstbl) double v_cap; /* Current voltage on capacitor, before dt */ double v_cap_next = 0; /* Voltage on capacitor, after dt */ + double x_time = 0; /* time since change happened */ + double dt, exponent; + int trigger = 0; + int trigger_type; + int update_exponent = 0; if(DSD_555_MSTBL__RESET) { @@ -471,74 +481,104 @@ static DISCRETE_STEP(dsd_555_mstbl) node->output[0] = 0; context->flip_flop = 0; context->cap_voltage = 0; + return; } - else + + trigger_type = info->options; + dt = node->info->sample_time; + + switch (trigger_type & DSD_555_TRIGGER_TYPE_MASK) { - int trigger; - - if (context->trig_is_logic) - trigger = !DSD_555_MSTBL__TRIGGER; - else - trigger = DSD_555_MSTBL__TRIGGER < context->trigger; - - if (context->trig_discharges_cap && trigger) - context->cap_voltage = 0; - - if (!context->flip_flop) - { - /* Wait for trigger */ - if (trigger) - context->flip_flop = 1; - } - else - { - v_cap = context->cap_voltage; - - /* Sometimes a switching network is used to setup the capacitance. - * These may select 'no' capacitor, causing oscillation to stop. - */ - if (DSD_555_MSTBL__C == 0) + case DISC_555_TRIGGER_IS_LOGIC: + trigger = (int)!DSD_555_MSTBL__TRIGGER; + break; + case DISC_555_TRIGGER_IS_VOLTAGE: + trigger = (int)(DSD_555_MSTBL__TRIGGER < context->trigger); + break; + case DISC_555_TRIGGER_IS_COUNT: + trigger = (int)DSD_555_MSTBL__TRIGGER; + if (trigger && !context->flip_flop) { - context->flip_flop = 0; - /* The voltage goes high because the cap circuit is open. */ - v_cap_next = info->v_pos; - v_cap = info->v_pos; - context->cap_voltage = 0; - } - else - { - /* Charging */ - 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, - * regardless of threshold. */ - if ((v_cap_next >= context->threshold) && !trigger) + x_time = DSD_555_MSTBL__TRIGGER - trigger; + if (x_time != 0) { - v_cap_next = 0; - v_cap = context->threshold; - context->flip_flop = 0; + /* adjust sample to after trigger */ + x_time = (1.0 - x_time); + update_exponent = 1; + dt = x_time * node->info->sample_time; } } + break; + } - context->cap_voltage = v_cap_next; + if ((trigger_type & DISC_555_TRIGGER_DISCHARGES_CAP) && trigger) + context->cap_voltage = 0; - switch (info->options & DISC_555_OUT_MASK) + /* Wait for trigger */ + if (!context->flip_flop && trigger) + context->flip_flop = 1; + + if (context->flip_flop) + { + v_cap = context->cap_voltage; + + /* Sometimes a switching network is used to setup the capacitance. + * These may select 'no' capacitor, causing oscillation to stop. + */ + if (DSD_555_MSTBL__C == 0) + { + context->flip_flop = 0; + /* The voltage goes high because the cap circuit is open. */ + v_cap_next = info->v_pos; + v_cap = info->v_pos; + context->cap_voltage = 0; + } + else + { + /* Charging */ + update_exponent |= context->has_rc_nodes; + if (update_exponent) + exponent = RC_CHARGE_EXP_DT(DSD_555_MSTBL__R * DSD_555_MSTBL__C, dt); + else + exponent = context->exp_charge; + v_cap_next = v_cap + ((info->v_pos - v_cap) * exponent); + + /* Has it charged past upper limit? */ + /* If trigger is still enabled, then we keep charging, + * regardless of threshold. */ + if ((v_cap_next >= context->threshold) && !trigger) { - case DISC_555_OUT_SQW: - node->output[0] = context->flip_flop * context->v_out_high; - /* Fake it to AC if needed */ - if (context->output_is_ac) - node->output[0] -= context->v_out_high / 2.0; - break; - case DISC_555_OUT_CAP: - node->output[0] = v_cap_next; - /* Fake it to AC if needed */ - if (context->output_is_ac) - node->output[0] -= context->threshold * 3.0 /4.0; - break; + dt = DSD_555_MSTBL__R * DSD_555_MSTBL__C * log(1.0 / (1.0 - ((v_cap_next - context->threshold) / (context->v_charge - v_cap)))); + x_time = dt / node->info->sample_time; + v_cap_next = 0; + v_cap = context->threshold; + context->flip_flop = 0; } } + + context->cap_voltage = v_cap_next; + } + + switch (info->options & DISC_555_OUT_MASK) + { + case DISC_555_OUT_SQW: + node->output[0] = context->flip_flop * context->v_out_high; + /* Fake it to AC if needed */ + if (context->output_is_ac) + node->output[0] -= context->v_out_high / 2.0; + break; + case DISC_555_OUT_CAP: + node->output[0] = v_cap_next; + /* Fake it to AC if needed */ + if (context->output_is_ac) + node->output[0] -= context->threshold * 3.0 /4.0; + break; + case DISC_555_OUT_ENERGY: + if (x_time == 0) x_time = 1.0; + node->output[0] = context->v_out_high * (context->flip_flop ? x_time : (1.0 - x_time)); + if (context->output_is_ac) + node->output[0] -= context->v_out_high / 2.0; + break; } } @@ -572,6 +612,13 @@ static DISCRETE_RESET(dsd_555_mstbl) context->flip_flop = 0; context->cap_voltage = 0; + /* optimization if none of the values are nodes */ + context->has_rc_nodes = 0; + if (node->input_is_node & DSD_555_MSTBL_RC_MASK) + context->has_rc_nodes = 1; + else + context->exp_charge = RC_CHARGE_EXP(DSD_555_MSTBL__R * DSD_555_MSTBL__C); + node->output[0] = 0; } diff --git a/src/emu/sound/discrete.h b/src/emu/sound/discrete.h index 833726fdd7c..bbc17e7c047 100644 --- a/src/emu/sound/discrete.h +++ b/src/emu/sound/discrete.h @@ -2893,7 +2893,7 @@ * options, - bit mapped options * v_pos, - B+ voltage of 555 * v_charge, - voltage (or node) to charge circuit (Defaults to v_pos) - * v_out_high, - High output voltage of 555 (Defaults to v_pos - 1.2V) + * v_out_high - High output voltage of 555 (Defaults to v_pos - 1.2V) * } * * The last 2 options of discrete_555_desc can use the following defaults: @@ -2993,6 +2993,9 @@ * DISC_555_TRIGGER_IS_VOLTAGE - Input is actual voltage. * Voltage must drop below * trigger to activate. + * DISC_555_TRIGGER_IS_COUNT - 1 when trigger, allows passing of x_time. + * Mainly connected with other module using + * a xxx_COUNT_F_X type. * DISC_555_TRIGGER_DISCHARGES_CAP - some circuits connect an external * device (transistor) to the cap to * discharge it when the trigger is @@ -3006,8 +3009,9 @@ * Waveform Types: (ORed with trigger types) * DISC_555_OUT_SQW - Output is Squarewave. 0 or v_out_high. (DEFAULT) * DISC_555_OUT_CAP - Output is Timing Capacitor 'C' voltage. + * DISC_555_OUT_ENERGY - see DISCRETE_555_MSTABLE. * - * EXAMPLES: see Frogs + * EXAMPLES: see Frogs, Sprint 8 * *********************************************************************** * @@ -3555,14 +3559,16 @@ enum #define DISC_SCHMITT_OSC_ENAB_IS_NOR 0x06 #define DISC_SCHMITT_OSC_ENAB_MASK 0x06 /* Bits that define output enable type. - * Used only internally in module. */ + * Used only internally in module. */ /* 555 Common output flags */ #define DISC_555_OUT_DC 0x00 #define DISC_555_OUT_AC 0x10 #define DISC_555_TRIGGER_IS_LOGIC 0x00 -#define DISC_555_TRIGGER_IS_VOLTAGE 0x40 +#define DISC_555_TRIGGER_IS_VOLTAGE 0x20 +#define DISC_555_TRIGGER_IS_COUNT 0x40 +#define DSD_555_TRIGGER_TYPE_MASK 0x60 #define DISC_555_TRIGGER_DISCHARGES_CAP 0x80 #define DISC_555_OUT_SQW 0x00 /* Squarewave */ @@ -3575,7 +3581,7 @@ enum #define DISC_555_OUT_COUNT_R_X 0x07 #define DISC_555_OUT_MASK 0x07 /* Bits that define output type. - * Used only internally in module. */ + * Used only internally in module. */ #define DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE 0x80 #define DISCRETE_555_CC_TO_DISCHARGE_PIN 0x00 @@ -3593,7 +3599,7 @@ enum #define DISC_566_OUT_COUNT_F_X 0x50 #define DISC_566_OUT_COUNT_R_X 0x60 #define DISC_566_OUT_MASK 0x70 /* Bits that define output type. - * Used only internally in module. */ + * Used only internally in module. */ /* LS624 output flags */ #define DISC_LS624_OUT_ENERGY 0x01 diff --git a/src/mame/audio/firetrk.c b/src/mame/audio/firetrk.c index 8a8d8a0027d..b88c4f5dd27 100644 --- a/src/mame/audio/firetrk.c +++ b/src/mame/audio/firetrk.c @@ -68,7 +68,7 @@ popmessage("ASR"); } -#define FIRETRUCK_HSYNC 15750.0 +#define FIRETRUCK_HSYNC 15750.0 /* not checked */ #define FIRETRUCK_1V FIRETRUCK_HSYNC/2 #define FIRETRUCK_2V FIRETRUCK_1V/2 #define FIRETRUCK_8V FIRETRUCK_1V/8 diff --git a/src/mame/audio/sprint8.c b/src/mame/audio/sprint8.c new file mode 100644 index 00000000000..c24f433aabc --- /dev/null +++ b/src/mame/audio/sprint8.c @@ -0,0 +1,267 @@ +/************************************************************************ + * sprint8 Sound System Analog emulation + * Sept 2009, Derrick Renaud + ************************************************************************/ + +#include "driver.h" +#include "sprint8.h" + + +/* Discrete Sound Input Nodes */ +#define SPRINT8_CRASH_EN NODE_01 +#define SPRINT8_SCREECH_EN NODE_02 +#define SPRINT8_ATTRACT_EN NODE_03 +#define SPRINT8_MOTOR1_EN NODE_04 +#define SPRINT8_MOTOR2_EN NODE_05 +#define SPRINT8_MOTOR3_EN NODE_06 +#define SPRINT8_MOTOR4_EN NODE_07 +#define SPRINT8_MOTOR5_EN NODE_08 +#define SPRINT8_MOTOR6_EN NODE_09 +#define SPRINT8_MOTOR7_EN NODE_10 +#define SPRINT8_MOTOR8_EN NODE_11 + +/* Discrete Sound Output Nodes */ +#define SPRINT8_NOISE NODE_12 +#define SPRINT8_MOTOR1_SND NODE_13 +#define SPRINT8_MOTOR2_SND NODE_14 +#define SPRINT8_MOTOR3_SND NODE_15 +#define SPRINT8_MOTOR4_SND NODE_16 +#define SPRINT8_MOTOR5_SND NODE_17 +#define SPRINT8_MOTOR6_SND NODE_18 +#define SPRINT8_MOTOR7_SND NODE_19 +#define SPRINT8_MOTOR8_SND NODE_20 +#define SPRINT8_CRASH_SCREECH_SND NODE_21 +#define SPRINT8_AUDIO_1_2 NODE_22 +#define SPRINT8_AUDIO_3_7 NODE_23 +#define SPRINT8_AUDIO_5_6 NODE_24 +#define SPRINT8_AUDIO_4_8 NODE_25 + + +/* Parts List - Resistors */ +#define SPRINT8_R1 RES_K(47) +#define SPRINT8_R3 RES_K(47) +#define SPRINT8_R4 RES_K(47) +#define SPRINT8_R19 RES_K(1) +#define SPRINT8_R20 RES_K(1) +#define SPRINT8_R27 RES_K(18) +#define SPRINT8_R28 820 +#define SPRINT8_R29 RES_K(330) +#define SPRINT8_R39 RES_K(120) +#define SPRINT8_R40 RES_K(22) +#define SPRINT8_R41 RES_K(150) +#define SPRINT8_R89 RES_K(22) +#define SPRINT8_R91 RES_K(47) +#define SPRINT8_R93 RES_K(2.2) +#define SPRINT8_R96 RES_K(47) +#define SPRINT8_R97 RES_K(2.2) +#define SPRINT8_R99 RES_K(27) +#define SPRINT8_R100 RES_K(1) +#define SPRINT8_R145 RES_K(3.3) +#define SPRINT8_R146 RES_K(7.5) +#define SPRINT8_R147 100 +#define SPRINT8_R148 RES_K(1) + +/* Parts List - Capacitors */ +#define SPRINT8_C17 CAP_U(.001) +#define SPRINT8_C18 CAP_U(.047) +#define SPRINT8_C19 CAP_U(.047) +#define SPRINT8_C26 CAP_U(100) +#define SPRINT8_C27 CAP_U(.22) +#define SPRINT8_C28 CAP_U(.1) +#define SPRINT8_C59 CAP_U(.1) +#define SPRINT8_C64 CAP_U(.1) +#define SPRINT8_C89 CAP_U(.1) +#define SPRINT8_C90 CAP_U(.1) + +#define SPRINT8_HSYNC 15750.0 /* not checked */ +#define SPRINT8_1V SPRINT8_HSYNC/2 +#define SPRINT8_2V SPRINT8_1V/2 + + +static const discrete_lfsr_desc sprint8_lfsr = +{ + DISC_CLK_IS_FREQ, + 16, /* Bit Length */ + 0, /* Reset Value */ + 10, /* Use Bit 10 as XOR input 0 */ + 15, /* Use Bit 15 as XOR input 1 */ + DISC_LFSR_XOR, /* Feedback stage1 is XOR */ + DISC_LFSR_OR, /* Feedback stage2 is just stage 1 output OR with external feed */ + DISC_LFSR_REPLACE, /* Feedback stage3 replaces the shifted register contents */ + 0x000001, /* Everything is shifted into the first bit only */ + DISC_LFSR_FLAG_RESET_TYPE_H, /* Output is not inverted */ + 12 /* Output bit */ +}; + +static const discrete_555_desc sprint8_crash_555a_desc = +{ + DISC_555_OUT_ENERGY, + 5, DEFAULT_555_VALUES +}; + +static const discrete_integrate_info sprint8_crash_integrate = +{ + DISC_INTEGRATE_OP_AMP_1, + SPRINT8_R99, SPRINT8_R97, SPRINT8_R96, SPRINT8_C59, /*r1, r2, r3, c, */ + 5, 5, /* v1, vP*/ + 0, 0, 0 /* no functions */ +}; + +static const discrete_555_desc sprint8_motor_555a_desc = +{ + DISC_555_OUT_COUNT_F_X, + 5, DEFAULT_555_VALUES +}; + +static const discrete_555_desc sprint8_motor_555m_desc = +{ + DISC_555_OUT_ENERGY | DISC_555_TRIGGER_IS_COUNT, + 5, DEFAULT_555_VALUES +}; + +static const discrete_op_amp_filt_info sprint8_motor_filter = +{ + SPRINT8_R27, 0, SPRINT8_R28 + RES_2_PARALLEL(SPRINT8_R19, SPRINT8_R20), 0, SPRINT8_R29, /* r1, r2, r3, r4, rF, */ + SPRINT8_C18, SPRINT8_C19, 0, /* c1, c2, c3, */ + 5.0 * RES_VOLTAGE_DIVIDER(SPRINT8_R19, SPRINT8_R20), 5, 0 /* vRef, vP, vN */ +}; + +static const discrete_mixer_desc sprint8_mixer = +{ + DISC_MIXER_IS_RESISTOR, + {SPRINT8_R1 + SPRINT8_R100, SPRINT8_R3, SPRINT8_R4}, + {0}, {0}, 0, 0, 0, 0, 0, 1 /* no r_nodes, c, rI, rF, cF, cAmp, vRef, gain */ +}; + + +/************************************************ + * Car Motor + ************************************************/ +/* The first (astable) 555 generates a quick falling pulse that triggers the second (monostable) 555. + * This pulse is passed through C17 and pulled up with R40. This pulse is too fast to emulate so + * we will just tell the monostable it was triggered once and ignore C17/R40. + */ +#define SPRINT8_MOTOR_CIRCUIT(_car) \ +DISCRETE_RCFILTER(NODE_RELATIVE(NODE_30, _car - 1), 1, NODE_RELATIVE(SPRINT8_MOTOR1_EN, _car - 1), SPRINT8_R89, SPRINT8_C26) \ +DISCRETE_ADDER2(NODE_RELATIVE(NODE_40, _car - 1), 1, NODE_RELATIVE(NODE_30, _car - 1), 0.7) /* add Q21 shift */ \ +DISCRETE_555_ASTABLE_CV(NODE_RELATIVE(NODE_50, _car - 1), 1, SPRINT8_R39, 0, SPRINT8_C27, NODE_RELATIVE(NODE_40, _car - 1), &sprint8_motor_555a_desc) \ +DISCRETE_555_MSTABLE(NODE_RELATIVE(NODE_60, _car - 1), 1, NODE_RELATIVE(NODE_50, _car - 1), SPRINT8_R41, SPRINT8_C28, &sprint8_motor_555m_desc) \ +DISCRETE_OP_AMP_FILTER(NODE_RELATIVE(SPRINT8_MOTOR1_SND, _car - 1), 1, NODE_RELATIVE(NODE_60, _car - 1), 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &sprint8_motor_filter) + + +DISCRETE_SOUND_START( sprint8 ) + /************************************************ + * Input register mapping + ************************************************/ + DISCRETE_INPUT_NOT (SPRINT8_CRASH_EN) + DISCRETE_INPUT_NOT (SPRINT8_SCREECH_EN) + DISCRETE_INPUT_NOT (SPRINT8_ATTRACT_EN) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR1_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR2_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR3_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR4_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR5_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR6_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR7_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + DISCRETE_INPUTX_LOGIC(SPRINT8_MOTOR8_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0) + + /************************************************ + * Noise Generator, Crash, Screech + ************************************************/ + DISCRETE_LFSR_NOISE(SPRINT8_NOISE, /* IC F7, pin 13 */ + 1, /* ENAB */ + SPRINT8_ATTRACT_EN, /* RESET */ + SPRINT8_2V, 1, 0, 0.5, &sprint8_lfsr) /* CLK,AMPL,FEED,BIAS,LFSRTB */ + + DISCRETE_CONSTANT(NODE_70, 0) +// DISCRETE_CUSTOM4(NODE_70, SPRINT8_NOISE, SPRINT8_R148, SPRINT8_R147, SPRINT8_C90, &sprint8_custom_screech_charge) + DISCRETE_555_ASTABLE_CV(NODE_71, + SPRINT8_SCREECH_EN, /* RESET */ + SPRINT8_R145, SPRINT8_R146, SPRINT8_C89, + NODE_70, /* CTRLV */ + &sprint8_crash_555a_desc) + DISCRETE_INTEGRATE(NODE_72, SPRINT8_CRASH_EN, 0, &sprint8_crash_integrate) + DISCRETE_RCDISC2(NODE_73, + SPRINT8_NOISE, /* SWITCH - inverted by Q20 */ + NODE_72, SPRINT8_R93 + SPRINT8_R91, /* INP0,RVAL0 */ + 0, SPRINT8_R91, /* INP1,RVAL1 */ + SPRINT8_C64) /* CVAL */ + + DISCRETE_CONSTANT(SPRINT8_CRASH_SCREECH_SND, 0) + + /************************************************ + * Car Motor + ************************************************/ + DISCRETE_TASK_START() + SPRINT8_MOTOR_CIRCUIT(1) + SPRINT8_MOTOR_CIRCUIT(2) + DISCRETE_MIXER3(SPRINT8_AUDIO_1_2, + SPRINT8_ATTRACT_EN, /* ENAB */ + SPRINT8_CRASH_SCREECH_SND, + SPRINT8_MOTOR1_SND, + SPRINT8_MOTOR2_SND, + &sprint8_mixer) + DISCRETE_TASK_END() + + DISCRETE_TASK_START() + SPRINT8_MOTOR_CIRCUIT(3) + SPRINT8_MOTOR_CIRCUIT(7) + DISCRETE_MIXER3(SPRINT8_AUDIO_3_7, + SPRINT8_ATTRACT_EN, /* ENAB */ + SPRINT8_CRASH_SCREECH_SND, + SPRINT8_MOTOR3_SND, + SPRINT8_MOTOR7_SND, + &sprint8_mixer) + DISCRETE_TASK_END() + + DISCRETE_TASK_START() + SPRINT8_MOTOR_CIRCUIT(5) + SPRINT8_MOTOR_CIRCUIT(6) + DISCRETE_MIXER3(SPRINT8_AUDIO_5_6, + SPRINT8_ATTRACT_EN, /* ENAB */ + SPRINT8_CRASH_SCREECH_SND, + SPRINT8_MOTOR5_SND, + SPRINT8_MOTOR6_SND, + &sprint8_mixer) + DISCRETE_TASK_END() + + DISCRETE_TASK_START() + SPRINT8_MOTOR_CIRCUIT(4) + SPRINT8_MOTOR_CIRCUIT(8) + DISCRETE_MIXER3(SPRINT8_AUDIO_4_8, + SPRINT8_ATTRACT_EN, /* ENAB */ + SPRINT8_CRASH_SCREECH_SND, + SPRINT8_MOTOR4_SND, + SPRINT8_MOTOR8_SND, + &sprint8_mixer) + DISCRETE_TASK_END() + + /************************************************ + * Final Mix + ************************************************/ + DISCRETE_OUTPUT(SPRINT8_AUDIO_1_2, 32700.0/8) + DISCRETE_OUTPUT(SPRINT8_AUDIO_3_7, 32700.0/8) + DISCRETE_OUTPUT(SPRINT8_AUDIO_5_6, 32700.0/8) + DISCRETE_OUTPUT(SPRINT8_AUDIO_4_8, 32700.0/8) +DISCRETE_SOUND_END + + +WRITE8_DEVICE_HANDLER( sprint8_crash_w ) +{ + discrete_sound_w(device, SPRINT8_CRASH_EN, data & 0x01); +} + +WRITE8_DEVICE_HANDLER( sprint8_screech_w ) +{ + discrete_sound_w(device, SPRINT8_SCREECH_EN, data & 0x01); +} + +WRITE8_DEVICE_HANDLER( sprint8_attract_w ) +{ + discrete_sound_w(device, SPRINT8_ATTRACT_EN, data & 0x01); +} + +WRITE8_DEVICE_HANDLER( sprint8_motor_w ) +{ + discrete_sound_w(device, NODE_RELATIVE(SPRINT8_MOTOR1_EN, offset & 0x07), data & 0x01); +} diff --git a/src/mame/drivers/sprint8.c b/src/mame/drivers/sprint8.c index d50bacf947e..05e53bd8d80 100644 --- a/src/mame/drivers/sprint8.c +++ b/src/mame/drivers/sprint8.c @@ -103,16 +103,6 @@ static WRITE8_HANDLER( sprint8_int_reset_w ) } -/* names of sound effects taken from Tank 8, might differ for Sprint 8 */ - -static WRITE8_HANDLER( sprint8_crash_w ) {} -static WRITE8_HANDLER( sprint8_explosion_w ) {} -static WRITE8_HANDLER( sprint8_bugle_w ) {} -static WRITE8_HANDLER( sprint8_bug_w ) {} -static WRITE8_HANDLER( sprint8_attract_w ) {} -static WRITE8_HANDLER( sprint8_motor_w ) {} - - static ADDRESS_MAP_START( sprint8_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x00ff) AM_RAM AM_RANGE(0x1800, 0x1bff) AM_RAM_WRITE(sprint8_video_ram_w) AM_BASE(&sprint8_video_ram) @@ -126,13 +116,13 @@ static ADDRESS_MAP_START( sprint8_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x1c20, 0x1c2f) AM_WRITEONLY AM_BASE(&sprint8_pos_d_ram) AM_RANGE(0x1c30, 0x1c37) AM_WRITE(sprint8_lockout_w) AM_RANGE(0x1d00, 0x1d00) AM_WRITE(sprint8_int_reset_w) - AM_RANGE(0x1d01, 0x1d01) AM_WRITE(sprint8_crash_w) - AM_RANGE(0x1d02, 0x1d02) AM_WRITE(sprint8_explosion_w) - AM_RANGE(0x1d03, 0x1d03) AM_WRITE(sprint8_bugle_w) - AM_RANGE(0x1d04, 0x1d04) AM_WRITE(sprint8_bug_w) + AM_RANGE(0x1d01, 0x1d01) AM_DEVWRITE("discrete", sprint8_crash_w) + AM_RANGE(0x1d02, 0x1d02) AM_DEVWRITE("discrete", sprint8_screech_w) + AM_RANGE(0x1d03, 0x1d03) AM_WRITENOP + AM_RANGE(0x1d04, 0x1d04) AM_WRITENOP AM_RANGE(0x1d05, 0x1d05) AM_WRITEONLY AM_BASE(&sprint8_team) - AM_RANGE(0x1d06, 0x1d06) AM_WRITE(sprint8_attract_w) - AM_RANGE(0x1e00, 0x1e07) AM_WRITE(sprint8_motor_w) + AM_RANGE(0x1d06, 0x1d06) AM_DEVWRITE("discrete", sprint8_attract_w) + AM_RANGE(0x1e00, 0x1e07) AM_DEVWRITE("discrete", sprint8_motor_w) AM_RANGE(0x1f00, 0x1f00) AM_WRITENOP /* probably a watchdog, disabled in service mode */ AM_RANGE(0x2000, 0x3fff) AM_ROM AM_RANGE(0xf800, 0xffff) AM_ROM @@ -479,7 +469,30 @@ static MACHINE_DRIVER_START( sprint8 ) MDRV_VIDEO_UPDATE(sprint8) MDRV_VIDEO_EOF(sprint8) + /* sound hardware */ +#if 0 + /* the proper way is to hook up 4 speakers, but they are not really + * F/R/L/R speakers. Though you can pretend the 1-2 mix is the front. + * For now I just output 1-2 as mono. */ + MDRV_SPEAKER_ADD("speaker_1_2", 0.0, 0.0, 1.0) /* front */ + MDRV_SPEAKER_ADD("speaker_3_7", 0.0, 0.0, -0.5) /* back */ + MDRV_SPEAKER_ADD("speaker_5_6", -0.2, 0.0, 1.0) /* left */ + MDRV_SPEAKER_ADD("speaker_4_8", 0.2, 0.0, 1.0) /* right */ + + MDRV_SOUND_ADD("discrete", DISCRETE, 0) + MDRV_SOUND_CONFIG_DISCRETE(sprint8) + MDRV_SOUND_ROUTE(0, "speaker_1_2", 1.0) + MDRV_SOUND_ROUTE(1, "speaker_3_7", 1.0) + MDRV_SOUND_ROUTE(3, "speaker_5_6", 1.0) + MDRV_SOUND_ROUTE(4, "speaker_4_8", 1.0) +#else + MDRV_SPEAKER_STANDARD_MONO("speaker") + + MDRV_SOUND_ADD("discrete", DISCRETE, 0) + MDRV_SOUND_CONFIG_DISCRETE(sprint8) + MDRV_SOUND_ROUTE(0, "speaker", 1.0) +#endif MACHINE_DRIVER_END @@ -516,5 +529,5 @@ ROM_START( sprint8a ) ROM_END -GAME( 1977, sprint8, 0, sprint8, sprint8, 0, ROT0, "Atari", "Sprint 8", GAME_NO_SOUND ) -GAME( 1977, sprint8a, sprint8, sprint8, sprint8p, 0, ROT0, "Atari", "Sprint 8 (play tag & chase)", GAME_NO_SOUND ) +GAME( 1977, sprint8, 0, sprint8, sprint8, 0, ROT0, "Atari", "Sprint 8", GAME_IMPERFECT_SOUND ) +GAME( 1977, sprint8a, sprint8, sprint8, sprint8p, 0, ROT0, "Atari", "Sprint 8 (play tag & chase)", GAME_IMPERFECT_SOUND ) diff --git a/src/mame/includes/sprint8.h b/src/mame/includes/sprint8.h index 46964e72404..c88bdcadf98 100644 --- a/src/mame/includes/sprint8.h +++ b/src/mame/includes/sprint8.h @@ -1,3 +1,5 @@ +#include "sound/discrete.h" + /*----------- defined in drivers/sprint8.c -----------*/ void sprint8_set_collision(running_machine *machine, int n); @@ -17,3 +19,13 @@ VIDEO_START( sprint8 ); VIDEO_UPDATE( sprint8 ); WRITE8_HANDLER( sprint8_video_ram_w ); + + +/*----------- defined in audio/sprint8.c -----------*/ + +DISCRETE_SOUND_EXTERN( sprint8 ); + +WRITE8_DEVICE_HANDLER( sprint8_crash_w ); +WRITE8_DEVICE_HANDLER( sprint8_screech_w ); +WRITE8_DEVICE_HANDLER( sprint8_attract_w ); +WRITE8_DEVICE_HANDLER( sprint8_motor_w ); diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 68805fbf8eb..0d555b39221 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -433,7 +433,7 @@ $(MAMEOBJ)/atari.a: \ $(DRIVERS)/skyraid.o $(AUDIO)/skyraid.o $(VIDEO)/skyraid.o \ $(DRIVERS)/sprint2.o $(AUDIO)/sprint2.o $(VIDEO)/sprint2.o \ $(DRIVERS)/sprint4.o $(VIDEO)/sprint4.o $(AUDIO)/sprint4.o \ - $(DRIVERS)/sprint8.o $(VIDEO)/sprint8.o \ + $(DRIVERS)/sprint8.o $(AUDIO)/sprint8.o $(VIDEO)/sprint8.o \ $(DRIVERS)/starshp1.o $(AUDIO)/starshp1.o $(VIDEO)/starshp1.o \ $(DRIVERS)/starwars.o $(MACHINE)/starwars.o $(AUDIO)/starwars.o \ $(DRIVERS)/subs.o $(MACHINE)/subs.o $(AUDIO)/subs.o $(VIDEO)/subs.o \