summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Derrick Renaud <derrickr@mamedev.org>2009-10-01 04:12:28 +0000
committer Derrick Renaud <derrickr@mamedev.org>2009-10-01 04:12:28 +0000
commit54d913bda83dd7000bcc1e8418bc6ac3a49ba4f7 (patch)
tree0298f1535e6d3ec07c8d73cf7c904d632b3c5548
parent7286603bdfaa4591e4445cb12165870c9f6d6e81 (diff)
DISCRETE_555_MSTABLE - optimized speed and added new operating modes.
Sprint 8 - started discrete sound.
-rw-r--r--.gitattributes1
-rw-r--r--src/emu/sound/disc_dev.c153
-rw-r--r--src/emu/sound/discrete.h18
-rw-r--r--src/mame/audio/firetrk.c2
-rw-r--r--src/mame/audio/sprint8.c267
-rw-r--r--src/mame/drivers/sprint8.c49
-rw-r--r--src/mame/includes/sprint8.h12
-rw-r--r--src/mame/mame.mak2
8 files changed, 425 insertions, 79 deletions
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;
+ 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)
+ {
+ x_time = DSD_555_MSTBL__TRIGGER - trigger;
+ if (x_time != 0)
+ {
+ /* adjust sample to after trigger */
+ x_time = (1.0 - x_time);
+ update_exponent = 1;
+ dt = x_time * node->info->sample_time;
+ }
+ }
+ break;
+ }
- if (context->trig_is_logic)
- trigger = !DSD_555_MSTBL__TRIGGER;
- else
- trigger = DSD_555_MSTBL__TRIGGER < context->trigger;
+ if ((trigger_type & DISC_555_TRIGGER_DISCHARGES_CAP) && trigger)
+ context->cap_voltage = 0;
- if (context->trig_discharges_cap && trigger)
- context->cap_voltage = 0;
+ /* Wait for trigger */
+ if (!context->flip_flop && trigger)
+ context->flip_flop = 1;
+
+ if (context->flip_flop)
+ {
+ v_cap = context->cap_voltage;
- if (!context->flip_flop)
+ /* 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)
{
- /* Wait for trigger */
- if (trigger)
- context->flip_flop = 1;
+ 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
{
- v_cap = context->cap_voltage;
+ /* 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);
- /* 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)
+ /* 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)
{
+ 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;
- /* 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)
- {
- v_cap_next = 0;
- v_cap = context->threshold;
- context->flip_flop = 0;
- }
}
+ }
- context->cap_voltage = v_cap_next;
+ 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;
- }
- }
+ 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 \