1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
// license:BSD-3-Clause
// copyright-holders:Derrick Renaud
/************************************************************************
* sprint8 Sound System Analog emulation
* Sept 2009, Derrick Renaud
************************************************************************/
#include "emu.h"
#include "includes/sprint8.h"
#include "speaker.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
/* Adjusters */
#define SPRINT8_R132_POT NODE_29
/* 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_R101 RES_K(2.2)
#define SPRINT8_R132 RES_K(100)
#define SPRINT8_R145 RES_K(3.3)
#define SPRINT8_R146 RES_K(7.5)
#define SPRINT8_R147 100
#define SPRINT8_R148 RES_K(1)
#define SPRINT8_R149 RES_K(22)
/* Parts List - Capacitors */
#define SPRINT8_C8 CAP_U(.01)
#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_C63 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_XNOR, /* Feedback stage1 is XNOR */
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_L, /* 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_crash_screech_mixer =
{
DISC_MIXER_IS_RESISTOR,
{SPRINT8_R149, SPRINT8_R91},
{0, NODE_80}, /* R93 switched in/out of circuit */
{0}, 0, 0, SPRINT8_C64, 0, 0, 1 /* c, rI, rF, cF, cAmp, vRef, gain */
};
static const discrete_mixer_desc sprint8_mixer =
{
DISC_MIXER_IS_RESISTOR,
{SPRINT8_R1 + SPRINT8_R100, SPRINT8_R3, SPRINT8_R4},
{0}, {0}, 0, 0, 0, SPRINT8_C8, 0, 1 /* 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), 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_discrete )
/************************************************
* Input register mapping
************************************************/
DISCRETE_INPUT_LOGIC(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)
DISCRETE_TASK_START(0)
DISCRETE_ADJUSTMENT(SPRINT8_R132_POT, 0, SPRINT8_R132, DISC_LINADJ, "R132")
/************************************************
* Noise Generator, Crash, Screech
************************************************/
/* Address line A2 is used to XOR the feedback bits.
* This can not easily be implemented, so I just set the
* feedback as XNOR. */
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_TASK_END()
DISCRETE_TASK_START(1)
DISCRETE_GAIN(NODE_70, SPRINT8_NOISE, DEFAULT_TTL_V_LOGIC_1 * RES_VOLTAGE_DIVIDER(SPRINT8_R148, SPRINT8_R147))
DISCRETE_CRFILTER_VREF(NODE_71,
NODE_70, /* IN0 */
RES_2_PARALLEL(SPRINT8_R148, SPRINT8_R147) + RES_2_PARALLEL(RES_K(5), RES_K(10)),
SPRINT8_C90,
5.0 * RES_VOLTAGE_DIVIDER(RES_K(5), RES_K(10))) /* ref to 555 CV pin */
DISCRETE_555_ASTABLE_CV(NODE_72,
SPRINT8_SCREECH_EN, /* RESET */
SPRINT8_R145, SPRINT8_R146, SPRINT8_C89,
NODE_71, /* CTRLV */
&sprint8_crash_555a_desc)
DISCRETE_INTEGRATE(NODE_73, SPRINT8_CRASH_EN, 0, &sprint8_crash_integrate)
DISCRETE_SWITCH(NODE_80,
1, /* ENAB */
SPRINT8_NOISE, /* SWITCH */
SPRINT8_R93, 1) /* INP0,INP1*/
DISCRETE_SWITCH(NODE_74, /* effect of Q20 */
1, /* ENAB */
SPRINT8_NOISE, /* SWITCH */
NODE_73, 0) /* INP0,INP1*/
DISCRETE_MIXER2(NODE_75,
1, /* ENAB */
NODE_72,
NODE_74,
&sprint8_crash_screech_mixer)
DISCRETE_CRFILTER_VREF(NODE_76,
NODE_75, /* IN0 */
SPRINT8_R93 + SPRINT8_R91, SPRINT8_C63,
5) /* VREF */
/* IC E5, pin 14 gain. Does not simulate minor DC offset caused by R93. */
DISCRETE_TRANSFORM5(NODE_77, NODE_76, 5, SPRINT8_R132_POT, SPRINT8_R101, 1, "01-23/4+*1+")
DISCRETE_CLAMP(SPRINT8_CRASH_SCREECH_SND, NODE_77, 0, 15.0 - 1.5)
DISCRETE_TASK_END()
/************************************************
* Car Motor
************************************************/
DISCRETE_TASK_START(1)
SPRINT8_MOTOR_CIRCUIT(1)
SPRINT8_MOTOR_CIRCUIT(2)
DISCRETE_TASK_END()
DISCRETE_TASK_START(1)
SPRINT8_MOTOR_CIRCUIT(3)
SPRINT8_MOTOR_CIRCUIT(7)
DISCRETE_TASK_END()
DISCRETE_TASK_START(1)
SPRINT8_MOTOR_CIRCUIT(5)
SPRINT8_MOTOR_CIRCUIT(6)
DISCRETE_TASK_END()
DISCRETE_TASK_START(1)
SPRINT8_MOTOR_CIRCUIT(4)
SPRINT8_MOTOR_CIRCUIT(8)
DISCRETE_TASK_END()
/************************************************
* Final Mix
************************************************/
DISCRETE_TASK_START(2)
DISCRETE_MIXER3(SPRINT8_AUDIO_1_2,
SPRINT8_ATTRACT_EN, /* ENAB */
SPRINT8_CRASH_SCREECH_SND,
SPRINT8_MOTOR1_SND,
SPRINT8_MOTOR2_SND,
&sprint8_mixer)
DISCRETE_MIXER3(SPRINT8_AUDIO_3_7,
SPRINT8_ATTRACT_EN, /* ENAB */
SPRINT8_CRASH_SCREECH_SND,
SPRINT8_MOTOR3_SND,
SPRINT8_MOTOR7_SND,
&sprint8_mixer)
DISCRETE_MIXER3(SPRINT8_AUDIO_5_6,
SPRINT8_ATTRACT_EN, /* ENAB */
SPRINT8_CRASH_SCREECH_SND,
SPRINT8_MOTOR5_SND,
SPRINT8_MOTOR6_SND,
&sprint8_mixer)
DISCRETE_MIXER3(SPRINT8_AUDIO_4_8,
SPRINT8_ATTRACT_EN, /* ENAB */
SPRINT8_CRASH_SCREECH_SND,
SPRINT8_MOTOR4_SND,
SPRINT8_MOTOR8_SND,
&sprint8_mixer)
DISCRETE_OUTPUT(SPRINT8_AUDIO_1_2, 65500.0/8)
DISCRETE_OUTPUT(SPRINT8_AUDIO_3_7, 65500.0/8)
DISCRETE_OUTPUT(SPRINT8_AUDIO_5_6, 65500.0/8)
DISCRETE_OUTPUT(SPRINT8_AUDIO_4_8, 65500.0/8)
DISCRETE_TASK_END()
DISCRETE_SOUND_END
MACHINE_CONFIG_START(sprint8_state::sprint8_audio)
/* sound hardware */
/* 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. */
MCFG_SPEAKER_ADD("speaker_1_2", 0.0, 0.0, 1.0) /* front */
MCFG_SPEAKER_ADD("speaker_3_7", -0.2, 0.0, 1.0) /* left */
MCFG_SPEAKER_ADD("speaker_5_6", 0.0, 0.0, -0.5) /* back */
MCFG_SPEAKER_ADD("speaker_4_8", 0.2, 0.0, 1.0) /* right */
MCFG_DEVICE_ADD("discrete", DISCRETE, sprint8_discrete)
MCFG_SOUND_ROUTE(0, "speaker_1_2", 1.0)
/* volumes on other channels defaulted to off, */
/* user can turn them up if needed. */
/* The game does not sound good with all channels mixed to stereo. */
MCFG_SOUND_ROUTE(1, "speaker_3_7", 0.0)
MCFG_SOUND_ROUTE(2, "speaker_5_6", 0.0)
MCFG_SOUND_ROUTE(3, "speaker_4_8", 0.0)
MCFG_DEVICE_ADD("latch", F9334, 0)
MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(*this, sprint8_state, int_reset_w))
MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_CRASH_EN>))
MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_SCREECH_EN>))
MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(*this, sprint8_state, team_w))
MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_ATTRACT_EN>))
MCFG_DEVICE_ADD("motor", F9334, 0)
MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR1_EN>))
MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR2_EN>))
MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR3_EN>))
MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR4_EN>))
MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR5_EN>))
MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR6_EN>))
MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR7_EN>))
MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE("discrete", discrete_device, write_line<SPRINT8_MOTOR8_EN>))
MACHINE_CONFIG_END
|