1 // license:BSD-3-Clause
2 // copyright-holders:Derrick Renaud
3 /*************************************************************************
4 
5     audio\sprint4.c
6 
7 *************************************************************************/
8 #include "emu.h"
9 #include "sprint4.h"
10 #include "sound/discrete.h"
11 
12 
13 /************************************************************************
14  * sprint4 Sound System Analog emulation
15  *
16  * R/C labels in the comments are from the player 1 circuits of Sprint 4.
17  *
18  * Mar 2007, D.R.
19  ************************************************************************/
20 
21 #define SPRINT4_2V  (15750.0/4)
22 
23 static const discrete_lfsr_desc sprint4_lfsr =
24 {
25 	DISC_CLK_IS_FREQ,
26 	16,                 /* Bit Length */
27 	0,                  /* Reset Value */
28 	0,                  /* Use Bit 0 as XOR input 0 */
29 	14,                 /* Use Bit 14 as XOR input 1 */
30 	DISC_LFSR_XNOR,     /* Feedback stage1 is XNOR */
31 	DISC_LFSR_OR,       /* Feedback stage2 is just stage 1 output OR with external feed */
32 	DISC_LFSR_REPLACE,  /* Feedback stage3 replaces the shifted register contents */
33 	0x000001,           /* Everything is shifted into the first bit only */
34 	0,                  /* Output is not inverted */
35 	15                  /* Output bit */
36 };
37 
38 
39 static const discrete_dac_r1_ladder sprint4_motor_freq_DAC =
40 {
41 	4,                  /* size */
42 	{ RES_M(2.2),       /* R20 */
43 		RES_M(1),           /* R23 */
44 		RES_K(470),     /* R22 */
45 		RES_K(220) },       /* R21 */
46 	5.0 - 0.6,          /* 5V - CR1 junction voltage */
47 	RES_K(68),          /* R24 */
48 	0,                  /* no rGnd */
49 	CAP_U(2.2)          /* C28 */
50 };
51 
52 
53 #define SPRINT4_MOTOR_OUT_RES   (1.0 / (1.0 / RES_K(10) + 1.0 / RES_K(10) + 1.0 / RES_K(10)))
54 static const discrete_dac_r1_ladder sprint4_motor_out_DAC =
55 {
56 	4,                  /* size */
57 	{ RES_K(10),        /* R76 */
58 		0,              /* not connected */
59 		RES_K(10),      /* R77 */
60 		RES_K(10) },        /* R75 */
61 	0,                  /* no vBias */
62 	0,                  /* no rBias */
63 	0,                  /* no rGnd */
64 	CAP_U(0.1)          /* C47 */
65 };
66 
67 
68 #define SPRINT4_BANG_RES    (1.0 / (1.0 / RES_K(8.2) + 1.0 / RES_K(3.9) + 1.0 / RES_K(2.2) + 1.0 / RES_K(1)))
69 static const discrete_dac_r1_ladder sprint4_bang_DAC =
70 {
71 	4,                  /* size */
72 	{ RES_K(8.2),       /* R19 */
73 		RES_K(3.9),     /* R18 */
74 		RES_K(2.2),     /* R17 */
75 		RES_K(1) },     /* R16 */
76 	0,                  /* no vBias */
77 	0,                  /* no rBias */
78 	0,                  /* no rGnd */
79 	CAP_U(0.1)          /* C32 */
80 };
81 
82 
83 static const discrete_555_cc_desc sprint4_motor_vco =
84 {
85 	DISC_555_OUT_DC | DISC_555_OUT_SQW,
86 	5,                  // B+ voltage of 555
87 	DEFAULT_555_VALUES,
88 	0.7                 // Q1 junction voltage
89 };
90 
91 
92 /* this will make 4 slightly different screech circuits due to part tolerance */
93 /* otherwise they would all sound identical */
94 #define SPRINT4_SCREECH_CIRCUIT(_plr)                               \
95 static const discrete_schmitt_osc_desc sprint4_screech_osc_##_plr = \
96 {                                                                   \
97 	RES_K(1),                           /* R65 */                   \
98 	100,                                /* R64 */                   \
99 	CAP_U(10) + CAP_U((_plr-2) * .2),   /* C44 */                   \
100 	DEFAULT_7414_VALUES,                                            \
101 	DISC_SCHMITT_OSC_IN_IS_LOGIC | DISC_SCHMITT_OSC_ENAB_IS_AND     \
102 };
103 SPRINT4_SCREECH_CIRCUIT(1)
104 SPRINT4_SCREECH_CIRCUIT(2)
105 SPRINT4_SCREECH_CIRCUIT(3)
106 SPRINT4_SCREECH_CIRCUIT(4)
107 
108 
109 static const discrete_mixer_desc sprint4_mixer =
110 {
111 	DISC_MIXER_IS_RESISTOR,
112 	{ RES_K(10) + SPRINT4_MOTOR_OUT_RES,    /* R105 */
113 		RES_K(10) + SPRINT4_MOTOR_OUT_RES,  /* R106 */
114 		RES_K(10) + SPRINT4_BANG_RES,           /* R104 */
115 		RES_K(47),                          /* R102 */
116 		RES_K(47) },                            /* R103 */
117 	{ 0 },                                  /* no rNode{} */
118 	{ 0 },                                  /* no c{} */
119 	0,                                      /* no rI */
120 	RES_K(5),                               /* R109 */
121 	0,                                      /* no cF */
122 	CAP_U(0.1),                             /* C51 */
123 	0,                                      /* vRef = Gnd */
124 	1                                       /* gain */
125 };
126 
127 
128 /* discrete sound output nodes */
129 #define SPRINT4_MOTOR_SND_1         NODE_11
130 #define SPRINT4_MOTOR_SND_2         NODE_12
131 #define SPRINT4_MOTOR_SND_3         NODE_13
132 #define SPRINT4_MOTOR_SND_4         NODE_14
133 #define SPRINT4_SCREECH_SND_1       NODE_15
134 #define SPRINT4_SCREECH_SND_2       NODE_16
135 #define SPRINT4_SCREECH_SND_3       NODE_17
136 #define SPRINT4_SCREECH_SND_4       NODE_18
137 #define SPRINT4_BANG_SND            NODE_19
138 #define SPRINT4_NOISE               NODE_20
139 #define SPRINT4_FINAL_MIX_1_2       NODE_21
140 #define SPRINT4_FINAL_MIX_3_4       NODE_22
141 
142 #define SPRINT4_ATTRACT_INV         NODE_23
143 
144 
145 /* setup the attract input and it's inverse */
146 #define SPRINT4_ATTRACT                                                 \
147 	DISCRETE_INPUT_NOT(SPRINT4_ATTRACT_EN)                              \
148 	DISCRETE_LOGIC_INVERT(SPRINT4_ATTRACT_INV, SPRINT4_ATTRACT_EN)
149 
150 
151 /* port tags used for the discrete adjusters */
152 #define SPRINT4_MOTOR_TAG_1     "MOTOR1"
153 #define SPRINT4_MOTOR_TAG_2     "MOTOR2"
154 #define SPRINT4_MOTOR_TAG_3     "MOTOR3"
155 #define SPRINT4_MOTOR_TAG_4     "MOTOR4"
156 
157 
158 /* used to offset the motor nodes based on the player so the nodes do not overlap */
159 /* _plr must be 1, 2, 3, or 4 */
160 /* so it uses NODES_30 to NODE_69 */
161 #define SPRINT4_PLAYER_MOTOR_NODE(_node, _plr)      NODE(20 + 10 * _plr + _node)
162 
163 
164 /************************************************
165  * Motor sound
166  *
167  * complete motor effects for each player
168  * _plr must be 1, 2, 3, or 4
169  ************************************************/
170 #define SPRINT4_PLAYER_MOTOR(_plr)                                                                  \
171 	DISCRETE_INPUTX_DATA(SPRINT4_MOTOR_DATA_##_plr,                                                 \
172 					-1, 0x0f, 0)    /* latch IC D8 inverts the data */                              \
173 	DISCRETE_DAC_R1(SPRINT4_PLAYER_MOTOR_NODE(1, _plr),                                             \
174 					SPRINT4_MOTOR_DATA_##_plr,                  /* DATA */                          \
175 					DEFAULT_TTL_V_LOGIC_1,                      /* VDATA */                         \
176 					&sprint4_motor_freq_DAC)                    /* LADDER */                        \
177 	DISCRETE_ADJUSTMENT(SPRINT4_PLAYER_MOTOR_NODE(2, _plr),                                     \
178 					RES_K(10) + RES_K(250),                     /* MIN */                           \
179 					RES_K(10),                                  /* MAX */                           \
180 					DISC_LOGADJ,                                /* LOGLIN */                        \
181 					SPRINT4_MOTOR_TAG_##_plr)                   /* PORT TAG */                      \
182 	DISCRETE_555_CC(SPRINT4_PLAYER_MOTOR_NODE(3, _plr),         /* IC D8, pin 3 */                  \
183 					1,                                          /* RESET */                         \
184 					SPRINT4_PLAYER_MOTOR_NODE(1, _plr),         /* VIN */                           \
185 					SPRINT4_PLAYER_MOTOR_NODE(2, _plr),         /* R */                             \
186 					CAP_U(0.01),                                /* C34 */                           \
187 					RES_M(3.3),                                 /* R42 */                           \
188 					0,                                          /* no RGND */                       \
189 					0,                                          /* no RDIS */                       \
190 					&sprint4_motor_vco)                         /* OPTIONS */                       \
191 	DISCRETE_COUNTER_7492(SPRINT4_PLAYER_MOTOR_NODE(4, _plr),   /* IC D9, pins 11,9,8 */            \
192 					1,                                          /* ENAB */                          \
193 					SPRINT4_ATTRACT_EN,                         /* RESET */                         \
194 					SPRINT4_PLAYER_MOTOR_NODE(3, _plr),         /* CLK */                           \
195 					DISC_CLK_ON_F_EDGE)                                                             \
196 	DISCRETE_TRANSFORM3(SPRINT4_PLAYER_MOTOR_NODE(5, _plr),     /* IC B10, pin 3 */                 \
197 					SPRINT4_PLAYER_MOTOR_NODE(4, _plr),         /* INP0 */                          \
198 					0x01,                                       /* INP1 */                          \
199 					0x04,                                       /* INP2 */                          \
200 					"01&02&2/^")                                /* XOR QA and QC */                 \
201 	DISCRETE_COUNTER(SPRINT4_PLAYER_MOTOR_NODE(6, _plr),        /* IC D9, pin 12 */                 \
202 					1,                                          /* ENAB */                          \
203 					SPRINT4_ATTRACT_EN,                         /* RESET */                         \
204 					SPRINT4_PLAYER_MOTOR_NODE(5, _plr),         /* CLK */                           \
205 					0, 1,                                       /* MIN, MAX */                      \
206 					DISC_COUNT_UP,                              /* DIR */                           \
207 					0,                                          /* INIT0 */                         \
208 					DISC_CLK_ON_F_EDGE)                         /* CLKTYPE */                       \
209 	DISCRETE_TRANSFORM3(SPRINT4_PLAYER_MOTOR_NODE(7, _plr),     /*  */                              \
210 					SPRINT4_PLAYER_MOTOR_NODE(4, _plr),         /* INP0 */                          \
211 					SPRINT4_PLAYER_MOTOR_NODE(6, _plr),         /* INP1 */                          \
212 					0x08,                                       /* INP2 */                          \
213 					"012*+")                                    /* join 7492 bits together */       \
214 	DISCRETE_DAC_R1(SPRINT4_MOTOR_SND_##_plr,                                                       \
215 					SPRINT4_PLAYER_MOTOR_NODE(7, _plr),         /* DATA */                          \
216 					DEFAULT_TTL_V_LOGIC_1,                      /* VDATA */                         \
217 					&sprint4_motor_out_DAC)                     /* LADDER */
218 
219 
220 /************************************************
221  * Bang sound
222  ************************************************/
223 #define SPRINT4_BANG                                                    \
224 	DISCRETE_LFSR_NOISE(SPRINT4_NOISE,                                  \
225 					1,                                  /* ENAB */      \
226 					SPRINT4_ATTRACT_INV,                /* RESET */     \
227 					SPRINT4_2V,                         /* CLK */       \
228 					1,                                  /* AMPL */      \
229 					0,                                  /* FEED */      \
230 					1.0/2,                              /* BIAS */      \
231 					&sprint4_lfsr)                      /* LFSRTB */    \
232 	DISCRETE_INPUT_DATA(SPRINT4_BANG_DATA)                              \
233 	DISCRETE_ONOFF(NODE_70,                             /* IC F7 */     \
234 					SPRINT4_NOISE,                      /* ENAB */      \
235 					SPRINT4_BANG_DATA)                  /* INP0 */      \
236 	DISCRETE_DAC_R1(SPRINT4_BANG_SND,                                   \
237 					NODE_70,                            /* DATA */      \
238 					DEFAULT_TTL_V_LOGIC_1,              /* VDATA */     \
239 					&sprint4_bang_DAC)                  /* LADDER */
240 
241 
242 /************************************************
243  * Screech sound
244  *
245  * Complete screech effects for each player.
246  * This must follow the Bang sound code because
247  * it uses the bang noise source.
248  * _plr must be 1, 2, 3, or 4
249  ************************************************/
250 #define SPRINT4_PLAYER_SCREECH(_plr)                                    \
251 	DISCRETE_INPUT_LOGIC(SPRINT4_SCREECH_EN_##_plr)                     \
252 	DISCRETE_SCHMITT_OSCILLATOR(SPRINT4_SCREECH_SND_##_plr,             \
253 					SPRINT4_SCREECH_EN_##_plr,          /* ENAB */      \
254 					SPRINT4_NOISE,                      /* INP0 */      \
255 					DEFAULT_TTL_V_LOGIC_1,              /* AMPL */      \
256 					&sprint4_screech_osc_##_plr)        /* TABLE */
257 
258 
259 /************************************************
260  * Final mixer
261  * _plr_a must be 1 and _plr_b must be 2
262  * or
263  * _plr_a must be 3 and _plr_b must be 4
264  ************************************************/
265 #define SPRINT4_MIXER(_plr_a, _plr_b, _gain)                            \
266 	DISCRETE_MIXER5(SPRINT4_FINAL_MIX_##_plr_a##_##_plr_b,              \
267 					1,                                  /* ENAB */      \
268 					SPRINT4_MOTOR_SND_##_plr_a,         /* IN0 */       \
269 					SPRINT4_MOTOR_SND_##_plr_b,         /* IN1 */       \
270 					SPRINT4_BANG_SND,                   /* IN2 */       \
271 					SPRINT4_SCREECH_SND_##_plr_a,       /* IN3 */       \
272 					SPRINT4_SCREECH_SND_##_plr_b,       /* IN4 */       \
273 					&sprint4_mixer)                     /* INFO */      \
274 	DISCRETE_OUTPUT(SPRINT4_FINAL_MIX_##_plr_a##_##_plr_b, _gain)
275 
276 
277 
278 
279 DISCRETE_SOUND_START(sprint4_discrete)
280 	SPRINT4_ATTRACT
281 	SPRINT4_PLAYER_MOTOR(1)
282 	SPRINT4_PLAYER_MOTOR(2)
283 	SPRINT4_PLAYER_MOTOR(3)
284 	SPRINT4_PLAYER_MOTOR(4)
285 	SPRINT4_BANG
286 	SPRINT4_PLAYER_SCREECH(1)
287 	SPRINT4_PLAYER_SCREECH(2)
288 	SPRINT4_PLAYER_SCREECH(3)
289 	SPRINT4_PLAYER_SCREECH(4)
290 	SPRINT4_MIXER(1, 2, 30000)
291 	SPRINT4_MIXER(3, 4, 30000)
292 DISCRETE_SOUND_END
293 
294 
295 DISCRETE_SOUND_START(ultratnk_discrete)
296 	SPRINT4_ATTRACT
297 	SPRINT4_PLAYER_MOTOR(1)
298 	SPRINT4_PLAYER_MOTOR(2)
299 	SPRINT4_BANG
300 	SPRINT4_PLAYER_SCREECH(1)
301 	SPRINT4_PLAYER_SCREECH(2)
302 	SPRINT4_MIXER(1, 2, 30000)
303 DISCRETE_SOUND_END
304