1 // license:BSD-3-Clause
2 // copyright-holders:Hans Andersson
3 /*************************************************************************
4 
5     audio\tank8.c
6 
7 *************************************************************************/
8 #include "emu.h"
9 #include "includes/tank8.h"
10 #include "sound/discrete.h"
11 
12 
13 /************************************************************************/
14 /* tank8 Sound System Analog emulation                                  */
15 /* Written by Hans Andersson. Feb 2005                                  */
16 /************************************************************************/
17 
18 static const discrete_lfsr_desc tank8_lfsr =
19 {
20 	DISC_CLK_IS_FREQ,
21 	16,         /* Bit Length */
22 	0,          /* Reset Value */
23 	10,         /* Use Bit 10 as F0 input 0 */
24 	15,         /* Use Bit 15 as F0 input 1 */
25 	DISC_LFSR_XOR,      /* F0 is XOR */
26 	DISC_LFSR_XOR,      /* F1 is F0 XOR with external feed. External feed is (address line) A2 */
27 	DISC_LFSR_REPLACE,  /* F2 replaces the shifted register contents */
28 	0x000001,       /* Everything is shifted into the first bit only */
29 	1,          /* Output is inverted by Q20 */
30 	12          /* Output bit */
31 };
32 
33 static const discrete_integrate_info tank8_op1_integrate_info =
34 {
35 	DISC_INTEGRATE_OP_AMP_1,
36 	RES_K(27),      /* R98 */
37 	RES_K(2.2),     /* R97 */
38 	RES_K(47),      /* R96 */
39 	CAP_U(0.22),    /* C60 */
40 	5,
41 	12,             // B+ is 12V, not 15V shown in the schematic.
42 	0,
43 	0,
44 	0,
45 };
46 
47 static const discrete_integrate_info tank8_op2_integrate_info =
48 {
49 	DISC_INTEGRATE_OP_AMP_1,
50 	RES_K(27),      /* R99 */
51 	RES_K(2.2),     /* R97 */
52 	RES_K(47),      /* R96 */
53 	CAP_U(0.1),     /* C59 */
54 	5,
55 	12,             // B+ is 12V, not 15V shown in the schematic.
56 	0,
57 	0,
58 	0,
59 };
60 
61 static const discrete_555_desc tank8_555_a =
62 {
63 	DISC_555_OUT_SQW | DISC_555_OUT_DC,
64 	5,      // B+ voltage of 555
65 	DEFAULT_555_VALUES
66 };
67 
68 static const discrete_555_desc tank8_555_m =
69 {
70 	DISC_555_OUT_SQW | DISC_555_OUT_DC | DISC_555_TRIGGER_IS_VOLTAGE,
71 	5,      // B+ voltage of 555
72 	DEFAULT_555_VALUES
73 };
74 
75 
76 static const discrete_op_amp_filt_info tank8_filt =
77 {
78 	RES_K(18),      // R56
79 	0,
80 	RES_K(0.820),   //R57
81 	0,
82 	RES_K(330),     //R58
83 	CAP_U(.047),    //C42
84 	CAP_U(.047),    //C43
85 	0,
86 	2.5,
87 	5, /* VCC */
88 	0  /* VEE */
89 };
90 
91 static const discrete_dac_r1_ladder tank8_dac =
92 {
93 	1,
94 	{RES_K(4.7)},   // R89
95 	5,              // 555 Vcc
96 	RES_K(5),       // 555 internal
97 	RES_K(10),      // 555 internal
98 	CAP_U(100)      // C26
99 };
100 
101 /* Nodes - Sounds */
102 #define TANK8_MOTOR1        NODE_15
103 #define TANK8_MOTOR2        NODE_16
104 #define TANK8_MOTOR3        NODE_17
105 #define TANK8_MOTOR4        NODE_18
106 #define TANK8_MOTOR5        NODE_19
107 #define TANK8_MOTOR6        NODE_20
108 #define TANK8_MOTOR7        NODE_21
109 #define TANK8_MOTOR8        NODE_22
110 #define TANK8_CRASHEXPL     NODE_23
111 #define TANK8_BUGLE         NODE_24
112 #define TANK8_FINAL_MIX     NODE_25
113 #define TANK8_A2_LINE       NODE_26
114 
115 
116 DISCRETE_SOUND_START(tank8_discrete)
117 	/************************************************/
118 	/* Tank8 sound system: 10 Sound Sources         */
119 	/*    Motor 1-8                                 */
120 	/*    Crash                                     */
121 	/*    Explosion                                 */
122 	/*    Bugle                                     */
123 	/************************************************/
124 
125 	/************************************************/
126 	/* Input register mapping for tank8           */
127 	/************************************************/
128 	/*                   NODE        */
129 	DISCRETE_INPUT_LOGIC(TANK8_CRASH_EN)
130 	DISCRETE_INPUT_LOGIC(TANK8_EXPLOSION_EN)
131 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR1_EN)
132 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR2_EN)
133 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR3_EN)
134 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR4_EN)
135 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR5_EN)
136 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR6_EN)
137 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR7_EN)
138 	DISCRETE_INPUT_LOGIC(TANK8_MOTOR8_EN)
139 	DISCRETE_INPUT_NOT(TANK8_ATTRACT_EN)
140 	DISCRETE_INPUT_LOGIC(TANK8_BUGLE_EN)
141 	DISCRETE_INPUT_DATA(TANK8_BUGLE_DATA1)
142 	DISCRETE_INPUT_DATA(TANK8_BUGLE_DATA2)
143 
144 	/************************************************/
145 	/* Motor sound circuit is based on a 556 VCO    */
146 	/* with the input frequency set by a charging   */
147 	/* Capacitor. The DAC emulates the 555's        */
148 	/* internal CV resistance.                      */
149 	/* A 9334 has typical 3.6V output.              */
150 	/************************************************/
151 
152 	DISCRETE_LOGIC_INVERT(NODE_30, TANK8_MOTOR1_EN)
153 	DISCRETE_DAC_R1(NODE_32, TANK8_MOTOR1_EN, 3.6, &tank8_dac)
154 	DISCRETE_555_ASTABLE_CV(NODE_33, NODE_30, RES_K(220), RES_K(39), CAP_U(0.22), NODE_32, &tank8_555_a)
155 	DISCRETE_CRFILTER_VREF(NODE_34, NODE_33, RES_K(22), CAP_U(0.001), 5.0)
156 	DISCRETE_555_MSTABLE(NODE_35, 1, NODE_34, RES_K(56), CAP_U(0.1), &tank8_555_m)
157 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR1, 1, NODE_35, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
158 
159 	DISCRETE_LOGIC_INVERT(NODE_40, TANK8_MOTOR2_EN)
160 	DISCRETE_DAC_R1(NODE_42, TANK8_MOTOR2_EN, 3.6, &tank8_dac)
161 	DISCRETE_555_ASTABLE_CV(NODE_43, NODE_40, RES_K(220), RES_K(39), CAP_U(0.22), NODE_42, &tank8_555_a)
162 	DISCRETE_CRFILTER_VREF(NODE_44, NODE_43, RES_K(22), CAP_U(0.001), 5.0)
163 	DISCRETE_555_MSTABLE(NODE_45, 1, NODE_44, RES_K(56), CAP_U(0.1), &tank8_555_m)
164 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR2, 1, NODE_45, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
165 
166 	DISCRETE_LOGIC_INVERT(NODE_50, TANK8_MOTOR3_EN)
167 	DISCRETE_DAC_R1(NODE_52, TANK8_MOTOR3_EN, 3.6, &tank8_dac)
168 	DISCRETE_555_ASTABLE_CV(NODE_53, NODE_50, RES_K(220), RES_K(39), CAP_U(0.22), NODE_52, &tank8_555_a)
169 	DISCRETE_CRFILTER_VREF(NODE_54, NODE_53, RES_K(22), CAP_U(0.001), 5.0)
170 	DISCRETE_555_MSTABLE(NODE_55, 1, NODE_54, RES_K(56), CAP_U(0.1), &tank8_555_m)
171 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR3, 1, NODE_55, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
172 
173 	DISCRETE_LOGIC_INVERT(NODE_60, TANK8_MOTOR4_EN)
174 	DISCRETE_DAC_R1(NODE_62, TANK8_MOTOR4_EN, 3.6, &tank8_dac)
175 	DISCRETE_555_ASTABLE_CV(NODE_63, NODE_60, RES_K(220), RES_K(39), CAP_U(0.22), NODE_62, &tank8_555_a)
176 	DISCRETE_CRFILTER_VREF(NODE_64, NODE_63, RES_K(22), CAP_U(0.001), 5.0)
177 	DISCRETE_555_MSTABLE(NODE_65, 1, NODE_64, RES_K(56), CAP_U(0.1), &tank8_555_m)
178 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR4, 1, NODE_65, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
179 
180 	DISCRETE_LOGIC_INVERT(NODE_70, TANK8_MOTOR5_EN)
181 	DISCRETE_DAC_R1(NODE_72, TANK8_MOTOR5_EN, 3.6, &tank8_dac)
182 	DISCRETE_555_ASTABLE_CV(NODE_73, NODE_70, RES_K(220), RES_K(39), CAP_U(0.22), NODE_72, &tank8_555_a)
183 	DISCRETE_CRFILTER_VREF(NODE_74, NODE_73, RES_K(22), CAP_U(0.001), 5.0)
184 	DISCRETE_555_MSTABLE(NODE_75, 1, NODE_74, RES_K(56), CAP_U(0.1), &tank8_555_m)
185 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR5, 1, NODE_75, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
186 
187 	DISCRETE_LOGIC_INVERT(NODE_80, TANK8_MOTOR6_EN)
188 	DISCRETE_DAC_R1(NODE_82, TANK8_MOTOR6_EN, 3.6, &tank8_dac)
189 	DISCRETE_555_ASTABLE_CV(NODE_83, NODE_80, RES_K(220), RES_K(39), CAP_U(0.22), NODE_82, &tank8_555_a)
190 	DISCRETE_CRFILTER_VREF(NODE_84, NODE_83, RES_K(22), CAP_U(0.001), 5.0)
191 	DISCRETE_555_MSTABLE(NODE_85, 1, NODE_84, RES_K(56), CAP_U(0.1), &tank8_555_m)
192 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR6, 1, NODE_85, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
193 
194 	DISCRETE_LOGIC_INVERT(NODE_90, TANK8_MOTOR7_EN)
195 	DISCRETE_DAC_R1(NODE_92, TANK8_MOTOR7_EN, 3.6, &tank8_dac)
196 	DISCRETE_555_ASTABLE_CV(NODE_93, NODE_90, RES_K(220), RES_K(39), CAP_U(0.22), NODE_92, &tank8_555_a)
197 	DISCRETE_CRFILTER_VREF(NODE_94, NODE_93, RES_K(22), CAP_U(0.001), 5.0)
198 	DISCRETE_555_MSTABLE(NODE_95, 1, NODE_94, RES_K(56), CAP_U(0.1), &tank8_555_m)
199 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR7, 1, NODE_95, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
200 
201 	DISCRETE_LOGIC_INVERT(NODE_100, TANK8_MOTOR8_EN)
202 	DISCRETE_DAC_R1(NODE_102, TANK8_MOTOR8_EN, 3.6, &tank8_dac)
203 	DISCRETE_555_ASTABLE_CV(NODE_103, NODE_100, RES_K(220), RES_K(39), CAP_U(0.22), NODE_102, &tank8_555_a)
204 	DISCRETE_CRFILTER_VREF(NODE_104, NODE_103, RES_K(22), CAP_U(0.001), 5.0)
205 	DISCRETE_555_MSTABLE(NODE_105, 1, NODE_104, RES_K(56), CAP_U(0.1), &tank8_555_m)
206 	DISCRETE_OP_AMP_FILTER(TANK8_MOTOR8, 1, NODE_105, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &tank8_filt)
207 
208 	/************************************************/
209 	/* Bugle call is built from 9316 counter        */
210 	/* counter is  clocked by the 1V signal.        */
211 	/* 1V = HSYNC/2                                 */
212 	/*    = 15750/2                                 */
213 	/************************************************/
214 	DISCRETE_DIVIDE(NODE_110,1,TANK8_BUGLE_DATA1,7875.0)
215 	DISCRETE_DIVIDE(NODE_111,1,TANK8_BUGLE_DATA2,7875.0)
216 	DISCRETE_SQUAREWAVE2(NODE_112,TANK8_BUGLE_EN,3.4, NODE_110, NODE_111,1.7,0)
217 	DISCRETE_RCDISC3(NODE_113,1, NODE_112, RES_K(10),RES_K(1),CAP_U(0.1), 0.5)
218 	DISCRETE_CRFILTER(TANK8_BUGLE, NODE_113, RES_K(47), CAP_U(.01))
219 
220 	/************************************************/
221 	/* Noise generator is built from 2 shift        */
222 	/* registers that are clocked by the 2V signal. */
223 	/* 2V = HSYNC/4                                 */
224 	/*    = 15750/4                                 */
225 	/************************************************/
226 	/* The A2 address line is also mixed in to the noise generator,
227 	 * but that is currently not implemented. */
228 	DISCRETE_CONSTANT(TANK8_A2_LINE,1)
229 	DISCRETE_LFSR_NOISE(NODE_120, TANK8_ATTRACT_EN, TANK8_ATTRACT_EN, 15750.0/4, 1, TANK8_A2_LINE, 0, &tank8_lfsr)
230 
231 	/************************************************/
232 	/* Explosion envelope is created by integrating */
233 	/* a constant voltage                           */
234 	/************************************************/
235 	DISCRETE_INTEGRATE(NODE_121, TANK8_EXPLOSION_EN, 0, &tank8_op1_integrate_info)
236 	DISCRETE_GAIN(NODE_122, NODE_121, RES_K(2.2)/(RES_K(1.0)+RES_K(2.2)))
237 
238 	/************************************************/
239 	/* Crash envelope is created by integrating     */
240 	/* a constant voltage                           */
241 	/************************************************/
242 	DISCRETE_INTEGRATE(NODE_123, TANK8_CRASH_EN, 0, &tank8_op2_integrate_info)
243 	DISCRETE_GAIN(NODE_124, NODE_123, RES_K(1)/(RES_K(1.0)+RES_K(2.2)))
244 
245 	/************************************************/
246 	/* Add the envelopes and apply it to the noise  */
247 	/* generator                                    */
248 	/************************************************/
249 	DISCRETE_ADDER2(NODE_125, 1 , NODE_122, NODE_124 )
250 	DISCRETE_MULTIPLY(NODE_126, NODE_120, NODE_125 )
251 	DISCRETE_RCFILTER(NODE_127, NODE_126, RES_K(47), CAP_U(0.1))
252 	DISCRETE_ADJUSTMENT(NODE_128,
253 				1.0,                // min gain of E5
254 				1.0 + 100.0/22,     // max gain of E5 = 1 + r132/r101
255 				DISC_LINADJ, "CRASH")
256 	DISCRETE_MULTIPLY(NODE_129, NODE_127, NODE_128 )
257 	DISCRETE_CLAMP(TANK8_CRASHEXPL, NODE_129, -(12.0 - OP_AMP_VP_RAIL_OFFSET)/2, (12.0 - OP_AMP_VP_RAIL_OFFSET)/2)
258 
259 	/************************************************/
260 	/* Combine all 10 sound sources.                */
261 	/************************************************/
262 	DISCRETE_ADDER4(NODE_130, 1, TANK8_MOTOR1, TANK8_MOTOR2, TANK8_MOTOR3, TANK8_MOTOR4)
263 	DISCRETE_MULTADD(NODE_131, NODE_130, 1.0, -10)
264 	DISCRETE_ADDER4(NODE_132, 1, TANK8_MOTOR5, TANK8_MOTOR6, TANK8_MOTOR7, TANK8_MOTOR8)
265 	DISCRETE_MULTADD(NODE_133, NODE_132, 1.0, -10)
266 	DISCRETE_ADDER4(TANK8_FINAL_MIX, TANK8_ATTRACT_EN, TANK8_CRASHEXPL, TANK8_BUGLE, NODE_131, NODE_133)
267 
268 	DISCRETE_OUTPUT(TANK8_FINAL_MIX, 5000)
269 DISCRETE_SOUND_END
270