summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/audio/mw8080bw.cpp
blob: 95e8752b3a7333fe66e80bf1cc03f9e66962f745 (plain) (tree)
1
2
3
4
5
6
7
8
9
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
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361


                                                                                                                              





                                                                             
                

                           
                              
                    

 

           

                                      




                                       
                                      

                         










                                                                                                                                       


  

                                      






























































































































































































































































































































































































































































































































                                                                                                                                 



                                       

                                                                                                     
                                                                                                     
                                                                                                      
                                                                                                       
                                                                                                          
                                                                                               
                                                                                                  
                                                                                                      
                                                                                                     
                                                                                                            


                                                                                                             
 


                                      












































































                                                                                                                                                                    



                                       



                                                                                                                        
 
 
 
                                         
 

                                        
 




                                                                     
 
                                                                
 

                                      
 









                                                                     
 
                                               
 




                                                       
 


                                         
 
                                


 





                                       


                                                                                                                          
 
 
 
                                          
 
                                                  
 
                                                                
 
                                                       



                                    

                                                     
                      

                                                       
                      

                                                   
                      

                                                            
                      
                
                                                                                                 



                      




























                                                                      



































































































































































                                                                                               
                                                              



































                                                                                                                    

                                                                  






















































                                                                                                                                  

















































































































































































































                                                                                                                                                                                  
 

                                      
 

                                                                                
 
                                
 


                                                          
 
 


                                                                      
 




                                                                    
 










                                                
 
 
 

                                      


                                            

                                       
 





                                     
 




































































































































































































































































                                                                                                                                                      


                                                                       
 

                                      
 
                                      
 
                                                                
 
                                                      
 
                                                                                                     
 

                                                                                                     
 
                                                                                                   
 

                                                                                                       

 


                                                   
 
                                           
 

                                      
 
                                         
 
                                                                                                           
 
                                                                             
 
                                                                                              
 
                                      
 
                                                                                                            
 
                                      

 
                                                                      
 




                                                   
 

                                                  
 



                                                              
 




                                                              
 



                                          
 
                  
 

                              



                                      




















































































                                                                                                                                                   
          
  
                                            


                                       





                                           
 




                                           
 

                                           
 


























                                                             

  
                                                              
 










                                                                                          

  
                                                                
 




















                                          

  
                                               
 


















                                                                      

  
                                            
 







                                                          
 



                                                                                              
 



                                                          

                                                         

                                           
                                                          

                                                                                    
 



                                                                                                                                                
 








                                                                                                                
 



                                                                                    
 





                                                                                                                          

                  




                                                  
                                                                                                                      
                                                                                    
                                    




                              
 
                                       
 







                                                                
 
 



                                       
 













                                                                        
 



                                                   
 
                                               
 






                                                         

 




                                                                  






                                        
                              

                              



                                      





























































































































































































































































































































































































                                                                                                                             
             
  
                             

                    

                                       
                 




                                           
 
                 





                                           
 
                                                                
 







































































































































































































                                                                                                                                  
 
                                                                      
 







                                       

  
                                                                      
 










                                        

  












                                                                  
 
                                                                  
 







                                        

  













                                                                                              
 
                                                                  
 



























































































                                                                  

  





                                                    
 
                                                 
 








                                                                             
            


                                           
                  







                                                

  
                                              

                                                         

                                                          






                                                                    

                                                         
                          
                                                          

                                                                            






                                                                                    

                                                         
                          
                                                          
                                                                            



                                                                             
                                                                           


                                                                            
                                                                           



                                                                           
                                                                            




                                                                                   
                                                       


                                                                           
 



                                                                           

                                                                                                       
                                                                           



                                                                             

                                                        


                                                                           
                               


                                                                          
                                  


                                                                                 
                              

                                                                                         
                                                                           


                                                                            

                                                                           



                                                                           
                                                                            





                                                                              

                                                         
                              
                                                          
                                                  
 



                                                                           





                                                                              


                                                                                        


                                                                           
                                 




                                                                           
                              









                                                                                                

                                                         
                    
                                                          
                                                                            





                                                                              
                                  


                                                                           
                                                 


                                                                                  
 



                                                                    





                                                                                       
                                                                    




                                                                                   
                                                                            


                                                                           
                                                                                                     

                                                                           
 



                                                          
 



                                                          








                                                                           
 
                                       

                  







                                                                                                                          
 
 
 
                                         
 
                                                      
 
                                                                                                    
 
                                                           
 

                                  
 


                                                          
 

                                                                 
 
                                      


 


                                                                 
 
                                                                     
 
                                       
 
                              
 
                                                           
 
                                     
 

                                      
 
                                                                      
 
                                               
 














                                                         
 


                                                         
 
                                          
 

                           
 
                                                                                                                                       
 
                             
 
                                         
 



                                                             
 

                                                                                     
 




                                                                                                                       
 
 

                                      
              


                                       







                                                                                                                          
 



                                         
 
                                                                        
 
                                                    
 










                                                                
 

                                      
 
                                  
 
                                                                             
 
                             
 



                                                                      
 




                                                   
 
                                               
 






                                                       
 
                        
 

                  
 


                              
 
 

                                      



                             

                                       
 
                                                                  
 










                                                   
 













                                                                                          
 











                                                
 







                                                                                                                          
 
                                         
 
                                                         
 







                                                                                        
 
 
 



                                         
 

                                                                                 
 
                                                             
 





































































































































































































































































                                                                                                                          













                                           


                                           
 
 
                                              
 



                                                                        
 





                                                                                           
 




                                                                                                                       
 



                                                                                             
 

                                                      
 
                  
 





                                                           


 
                                               
 
                                                                    
 
                                                                    
 
                                                                    
 
                                                  
 















                                                                         





                                      
                            


                                       



                                                        

 
                                              
 

                                                                        
 
                                                                     
 



                                                                     

 
                                              
 
                                                 
 










































                                                                                        
 


                                                                                                         


  
                                        
 
                                                      


  
                                                          
 




                                                     


  
                                                      
 



                                                     


  
                                                       
 








                                                                                                      


  
                                          

                                                         

                                                          




                                                                      
 
























                                                                                           
 























                                                                                                             
 























                                                                                                              
 
                                        


                  
                                                       
 
                                               

                                                        


 
                                                                        
 

                                                     
 



                                                                    
 





                                                                                           





                                      
             



                                       







                                           

                    


                                           

                       

                                           

 
                                                              
 




                                                     

  
 
                                                              
 




                                                     

  
 
                                                           
 








                                                                                                      

  
 
                                                             
 























                                                               

  
 
                                                 
 












                                                                      

  
                                              

                                                         

                                                          



                                                   
 




                                                                                                         
                                                                               
 
                                                         



                                                  
                                                          


























                                                                                         
 
                                                         
                         
                                                          








                                                                                                             
 


















                                                                                                             

                                                         
                               
                                                          





                                                                              


                  
                                                           
 
                                               

                                                        
 

 
                                               
 
                                                         
 
                                                                
 
                                                                      
 
                                                            
 

                                                                     





                                      




























































































































                                                                                               
 



                                                                                       

                                                         
                          
                                                          










                                                                                                        

                                                         
               
                                                          





                                                                                                                       
 












                                                                            

                                                         
                
                                                          


                                                                                
 










                                                                  


                  
                                                          
 
                                               
 

                                                        
 

 
                                                
 
                                                                
 
                                                                   
 
                                                            
 
                                                       
 


                                                                    

                                         


 
                                                
 
                                                               
 
                                                                      
 
                                     





                                      







                                       
                                         

                    
                                         



                                                         























                                                           


  
                                            

                                                         

                                                          



                                                         

                                                          
                                    











                                                                                 

                                                          


                                                                               




                                               

                                                         
                                               
 


                                                      

 
                                               


                                                         
                                                                      
 
                                                            
 
                                                              

                                                     

                                                                






                                                                     
                                               

                                                   
                                                            

                                                               
                                             






                                                                    
                                               

                                                               
                                             


 
                                               

                                                               
                                                


 
                                               

                                                              
                                  


 
                                               







                                                                       

                                                                      





                                      
              

                             

                   


                                       
                    




                                           

                    





                                           
 
                            





























































                                  
 
                             





















                                    

 
                                                            
 
                                                                                          

                                                                                                                                

  
                                                            

                                                                                              

                                                                                                                                

  
                                                                 

                                                   


                                                                                                            

  
                                                                 

                                                        


                                                                               

  
                                                        

                              

                                                                                        
  
 


                                               
                                            
                                                                                                









                                                                                              

  


                                                 
                                               
                           
                                                                                  

  


                                                                                             

                                                                                                                    




                                                                                             

                                                                                                                    




                                                                                             

                                                                                                                    





                                                       
                                                                                 




                                                         

                                                                                                                                    




                                                                                                 


                                                                                                            




                                                         


                                                                            
  


                                                 

                                                                                                                                    
                            
                                                                     
                                                                          

  
                                              

                                                         

                                                          
                                                            





                                                         



                                                                      
                                      


                                                                       
                                      
                                                                       
                                                               

                                                                       
                                            


                                                                      


                                                         

                                                          
                                                                 




                                                                                           

                                                         


                                                                                          

                                                         





                                                                                        
                                 







                                                                                      
                                  

                                                         



                                                                      
                                     

                                                                      
                                     

                                                                      

                                     
                                                                  


                                                                             


                                                                       
                                       


                                                                             
                                                                            

                                                                        

                                    
                                                                 

                                             
                                                                 

                                                             
                                                                 
                                                                             


                                                                       



                                                                   
                                                                 
                                 

                                                         

                                                          







                                     
                                       


                  

                                                           
                                               


                                                         

 
                                               
 
                                                                   
 
                                                                
 
                                                               
 
                                                                 

                                                                    
                                                    
 
                                                                   


                                         
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria, Tormod Tjaberg, Mirko Buffoni,Lee Taylor, Valerio Verrando, Zsolt Vasvari,Derrick Renaud
// thanks-to:Michael Strutts, Marco Cassili
/***************************************************************************

    Midway 8080-based black and white hardware

****************************************************************************/

#include "emu.h"
#include "audio/mw8080bw.h"

#include "includes/mw8080bw.h"
#include "speaker.h"


namespace {

/*************************************
 *
 *  Implementation of the common
 *  noise circuits
 *
 *************************************/

discrete_lfsr_desc const midway_lfsr =
{
	DISC_CLK_IS_FREQ,
	17,                 // bit length
						// the RC network fed into pin 4 has the effect of presetting all bits high at power up
	0x1ffff,            // reset value
	4,                  // use bit 4 as XOR input 0
	16,                 // use bit 16 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
	0,                  // output is not inverted
	12                  // output bit
};


/*************************************
 *
 *  Shared by Space Invaders and
 *  Space Invaders II (cocktail)
 *
 *************************************/

// sound board 1 or 2, for multi-board games
#define INVADERS_NODE(_node, _board)    (NODE(_node + ((_board - 1) * 100)))

// nodes - inputs
#define INVADERS_SAUCER_HIT_EN                01
#define INVADERS_FLEET_DATA                   02
#define INVADERS_BONUS_MISSLE_BASE_EN         03
#define INVADERS_INVADER_HIT_EN               04
#define INVADERS_EXPLOSION_EN                 05
#define INVADERS_MISSILE_EN                   06

// nodes - sounds
#define INVADERS_NOISE                        NODE_10
#define INVADERS_SAUCER_HIT_SND               11
#define INVADERS_FLEET_SND                    12
#define INVADERS_BONUS_MISSLE_BASE_SND        13
#define INVADERS_INVADER_HIT_SND              14
#define INVADERS_EXPLOSION_SND                15
#define INVADERS_MISSILE_SND                  16


/************************************************
 * Noise Generator
 ************************************************/

// Noise clock was breadboarded and measured at 7515
#define INVADERS_NOISE_GENERATOR                                                \
		DISCRETE_LFSR_NOISE(INVADERS_NOISE,             /* IC N5, pin 10 */     \
				1,                                      /* ENAB */              \
				1,                                      /* no RESET */          \
				7515,                                   /* CLK in Hz */         \
				12,                                     /* p-p AMPL */          \
				0,                                      /* no FEED input */     \
				12.0/2,                                 /* dc BIAS */           \
				&midway_lfsr)


/************************************************
 * Saucer Hit
 ************************************************/

discrete_op_amp_info const invaders_saucer_hit_op_amp_B3_9 =
{
	DISC_OP_AMP_IS_NORTON,
	0,              // no r1
	RES_K(100),     // R72
	RES_M(1),       // R71
	0,              // no r4
	CAP_U(1),       // C23
	0,              // vN
	12              // vP
};


discrete_op_amp_osc_info const invaders_saucer_hit_osc =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	RES_M(1),       // R70
	RES_K(470),     // R64
	RES_K(100),     // R61
	RES_K(120),     // R63
	RES_M(1),       // R62
	0,              // no r6
	0,              // no r7
	0,              // no r8
	CAP_U(0.1),     // C21
	12,             // vP
};

discrete_op_amp_osc_info const invaders_saucer_hit_vco =
{
	DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,
	RES_M(1),       // R65
	RES_K(470),     // R66
	RES_K(680),     // R67
	RES_M(1),       // R69
	RES_M(1),       // R68
	0,              // no r6
	0,              // no r7
	0,              // no r8
	CAP_P(470),     // C22
	12,             // vP
};

discrete_op_amp_info const invaders_saucer_hit_op_amp_B3_10 =
{
	DISC_OP_AMP_IS_NORTON,
	RES_K(680),     // R73
	RES_K(680),     // R77
	RES_M(2.7),     // R74
	RES_K(680),     // R75
	0,              // no c
	0,              // vN
	12              // vP
};

#define INVADERS_SAUCER_HIT(_board)                                                     \
		DISCRETE_INPUTX_LOGIC(INVADERS_NODE(INVADERS_SAUCER_HIT_EN, _board), 12, 0, 0)      \
		DISCRETE_OP_AMP(INVADERS_NODE(20, _board),                      /* IC B3, pin 9 */  \
				1,                                                      /* ENAB */          \
				0,                                                      /* no IN0 */        \
				INVADERS_NODE(INVADERS_SAUCER_HIT_EN, _board),          /* IN1 */           \
				&invaders_saucer_hit_op_amp_B3_9)                                   \
		DISCRETE_OP_AMP_OSCILLATOR(INVADERS_NODE(21, _board),           /* IC A4, pin 5 */  \
				1,                                                      /* ENAB */          \
				&invaders_saucer_hit_osc)                                           \
		DISCRETE_OP_AMP_VCO1(INVADERS_NODE(22, _board),                 /* IC A4, pin 9 */  \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(21, _board),                              /* VMOD1 */         \
				&invaders_saucer_hit_vco)                                           \
		DISCRETE_OP_AMP(INVADERS_NODE(INVADERS_SAUCER_HIT_SND, _board), /* IC B3, pin 10 */ \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(22, _board),                              /* IN0 */           \
				INVADERS_NODE(20, _board),                              /* IN1 */           \
				&invaders_saucer_hit_op_amp_B3_10)


/************************************************
 * Fleet movement
 ************************************************/

discrete_comp_adder_table const invaders_thump_resistors =
{
	DISC_COMP_P_RESISTOR,
	0,                          // no cDefault
	4,                          // length
	{ RES_K(20) + RES_K(20),    // R126 + R127
		RES_K(68),              // R128
		RES_K(82),              // R129
		RES_K(100) }            // R130
};

discrete_555_desc const invaders_thump_555 =
{
	DISC_555_OUT_ENERGY | DISC_555_OUT_DC,
	5,
	5.0 - 0.6,                  // 5V - diode drop
	DEFAULT_TTL_V_LOGIC_1       // Output of F3 7411 buffer
};

#define INVADERS_FLEET(_board)                                                              \
		DISCRETE_INPUT_DATA  (INVADERS_NODE(INVADERS_FLEET_DATA, _board))                   \
		DISCRETE_COMP_ADDER(INVADERS_NODE(30, _board),                                      \
				INVADERS_NODE(INVADERS_FLEET_DATA, _board),             /* DATA */          \
				&invaders_thump_resistors)                                                  \
		DISCRETE_555_ASTABLE(INVADERS_NODE(31, _board),                 /* IC F3, pin 6 */  \
				1,                                                      /* RESET */         \
				INVADERS_NODE(30, _board),                              /* R1 */            \
				RES_K(75),                                              /* R131 */          \
				CAP_U(0.1),                                             /* C29 */           \
				&invaders_thump_555)                                                        \
		DISCRETE_RCFILTER(INVADERS_NODE(32, _board),                                        \
				INVADERS_NODE(31, _board),                              /* IN0 */           \
				100,                                                    /* R132 */          \
				CAP_U(4.7) )                                            /* C31 */           \
		DISCRETE_RCFILTER(INVADERS_NODE(INVADERS_FLEET_SND, _board),                        \
				INVADERS_NODE(32, _board),                              /* IN0 */           \
				100 + 100,                                              /* R132 + R133 */   \
				CAP_U(10) )                                             /* C32 */


/************************************************
 * Bonus Missle Base
 ************************************************/

discrete_555_desc const invaders_bonus_555 =
{
	DISC_555_OUT_SQW | DISC_555_OUT_DC,
	5.0,                        // 5V
	DEFAULT_555_VALUES
};

#define INVADERS_BONUS_MISSLE_BASE(_board)                                                  \
		DISCRETE_INPUT_LOGIC (INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, _board))         \
		DISCRETE_555_ASTABLE(INVADERS_NODE(40, _board),                 /* IC F4, pin 9 */  \
				INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, _board),   /* RESET */         \
				RES_K(100),                                             /* R94 */           \
				RES_K(47),                                              /* R95 */           \
				CAP_U(1),                                               /* C34 */           \
				&invaders_bonus_555)                                                        \
		DISCRETE_SQUAREWFIX(INVADERS_NODE(41, _board),                                      \
				1,                                                      /* ENAB */          \
				480,                                                    /* FREQ */          \
				1,                                                      /* AMP */           \
				50,                                                     /* DUTY */          \
				1.0/2,                                                  /* BIAS */          \
				0)                                                      /* PHASE */         \
		DISCRETE_LOGIC_AND3(INVADERS_NODE(42, _board),                  /* IC F3, pin 12 */ \
				INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, _board),    /* INP0 */         \
				INVADERS_NODE(41, _board),                              /* INP1 */          \
				INVADERS_NODE(40, _board) )                             /* INP2 */          \
		DISCRETE_GAIN(INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_SND, _board),/* adjust from logic to TTL voltage level */\
				INVADERS_NODE(42, _board),                              /* IN0 */           \
				DEFAULT_TTL_V_LOGIC_1)                                  /* GAIN */


/************************************************
 * Invader Hit
 ************************************************/

discrete_op_amp_info const invaders_invader_hit_op_amp_D3_10 =
{
	DISC_OP_AMP_IS_NORTON,
	0,                          // no r1
	RES_K(10),                  // R53
	RES_M(1),                   // R137
	0,                          // no r4
	CAP_U(0.47),                // C19
	0,                          // vN
	12                          // vP
};

discrete_op_amp_osc_info const invaders_invader_hit_vco =
{
	DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	RES_M(1),                   // R42
	RES_K(470),                 // R43
	RES_K(680),                 // R44
	RES_M(1),                   // R46
	RES_M(1),                   // R45
	0,                          // no r6
	0,                          // no r7
	0,                          // no r8
	CAP_P(330),                 // C16
	12,                         // vP
};

discrete_op_amp_info const invaders_invader_hit_op_amp_D3_4 =
{
	DISC_OP_AMP_IS_NORTON,
	RES_K(470),                 // R55
	RES_K(680),                 // R54
	RES_M(2.7),                 // R56
	RES_K(680),                 // R57
	0,                          // no c
	0,                          // vN
	12                          // vP
};

#define INVADERS_INVADER_HIT(_board, _type)                                                 \
		DISCRETE_INPUTX_LOGIC(INVADERS_NODE(INVADERS_INVADER_HIT_EN, _board), 5, 0, 0)      \
		DISCRETE_OP_AMP_ONESHOT(INVADERS_NODE(50, _board),              /* IC D3, pin 9 */  \
				INVADERS_NODE(INVADERS_INVADER_HIT_EN, _board),         /* TRIG */          \
				&_type##_invader_hit_1sht)                                                  \
		DISCRETE_OP_AMP(INVADERS_NODE(51, _board),                      /* IC D3, pin 10 */ \
				1,                                                      /* ENAB */          \
				0,                                                      /* no IN0 */        \
				INVADERS_NODE(50, _board),                              /* IN1 */           \
				&invaders_invader_hit_op_amp_D3_10)                                         \
		DISCRETE_OP_AMP_OSCILLATOR(INVADERS_NODE(52, _board),           /* IC B4, pin 5 */  \
				1,                                                      /* ENAB */          \
				&_type##_invader_hit_osc)                                                   \
		DISCRETE_OP_AMP_VCO1(INVADERS_NODE(53, _board),                 /* IC B4, pin 4 */  \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(52, _board),                              /* VMOD1 */         \
				&invaders_invader_hit_vco)                                                  \
		DISCRETE_OP_AMP(INVADERS_NODE(INVADERS_INVADER_HIT_SND, _board),/* IC D3, pin 4 */  \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(53, _board),                              /* IN0 */           \
				INVADERS_NODE(51, _board),                              /* IN1 */           \
				&invaders_invader_hit_op_amp_D3_4)


/************************************************
 * Missle Sound
 ************************************************/

discrete_op_amp_1sht_info const invaders_missle_1sht =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(4.7),                         // R32
	RES_K(100),                         // R30
	RES_M(1),                           // R31
	RES_M(1),                           // R33
	RES_M(2.2),                         // R34
	CAP_U(1),                           // C12
	CAP_P(470),                         // C15
	0,                                  // vN
	12                                  // vP
};

discrete_op_amp_info const invaders_missle_op_amp_B3 =
{
	DISC_OP_AMP_IS_NORTON,
	0,                                  // no r1
	RES_K(10),                          // R35
	RES_M(1.5),                         // R36
	0,                                  // no r4
	CAP_U(0.22),                        // C13
	0,                                  // vN
	12                                  // vP
};

discrete_op_amp_osc_info const invaders_missle_op_amp_osc =
{
	DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,
	1.0 / (1.0 / RES_M(1) + 1.0 / RES_K(330)) + RES_M(1.5),     // R29||R11 + R12
	RES_M(1),                           // R16
	RES_K(560),                         // R17
	RES_M(2.2),                         // R19
	RES_M(1),                           // R16
	RES_M(4.7),                         // R14
	RES_M(3.3),                         // R13
	0,                                  // no r8
	CAP_P(330),                         // C58
	12,                                 // vP
};

discrete_op_amp_info const invaders_missle_op_amp_A3 =
{
	DISC_OP_AMP_IS_NORTON,
	RES_K(560),                         // R22
	RES_K(470),                         // R15
	RES_M(2.7),                         // R20
	RES_K(560),                         // R21
	0,                                  // no c
	0,                                  // vN
	12                                  // vP
};

discrete_op_amp_tvca_info const invaders_missle_tvca =
{
	RES_M(2.7),                         // R25
	RES_K(560),                         // R23
	0,                                  // no r3
	RES_K(560),                         // R26
	RES_K(1),                           //
	0,                                  // no r6
	RES_K(560),                         // R60
	0,                                  // no r8
	0,                                  // no r9
	0,                                  // no r10
	0,                                  // no r11
	CAP_U(0.1),                         // C14
	0,                                  // no c2
	0, 0,                               // no c3, c4
	5,                                  // v1
	0,                                  // no v2
	0,                                  // no v3
	12,                                 // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f0
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f1
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,  // f2
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f3
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f4
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE   // no f5
};

#define INVADERS_MISSILE(_board, _type)                                                     \
		DISCRETE_INPUTX_LOGIC(INVADERS_NODE(INVADERS_MISSILE_EN, _board), 5, 0, 0)          \
		DISCRETE_OP_AMP_ONESHOT(INVADERS_NODE(70, _board),              /* IC B3, pin 4 */  \
				INVADERS_NODE(INVADERS_MISSILE_EN, _board),             /* TRIG */          \
				&_type##_missle_1sht)                                                       \
		DISCRETE_OP_AMP(INVADERS_NODE(71, _board),                      /* IC B3, pin 5 */  \
				1,                                                      /* ENAB */          \
				0,                                                      /* no IN0 */        \
				INVADERS_NODE(70, _board),                              /* IN1 */           \
				&invaders_missle_op_amp_B3)                                                 \
		/* next 2 modules simulate the D1 voltage drop */                                   \
		DISCRETE_ADDER2(INVADERS_NODE(72, _board),                                          \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(71, _board),                              /* IN0 */           \
				-0.5)                                                   /* IN1 */           \
		DISCRETE_CLAMP(INVADERS_NODE(73, _board),                                           \
				INVADERS_NODE(72, _board),                              /* IN0 */           \
				0,                                                      /* MIN */           \
				12)                                                     /* MAX */           \
		DISCRETE_CRFILTER(INVADERS_NODE(74, _board),                                        \
				INVADERS_NOISE,                                         /* IN0 */           \
				RES_M(1) + RES_K(330),                                  /* R29, R11 */      \
				CAP_U(0.1) )                                            /* C57 */           \
		DISCRETE_GAIN(INVADERS_NODE(75, _board),                                            \
				INVADERS_NODE(74, _board),                              /* IN0 */           \
				RES_K(330)/(RES_M(1) + RES_K(330)))                     /* GAIN - R29 : R11 */  \
		DISCRETE_OP_AMP_VCO2(INVADERS_NODE(76, _board),                 /* IC C1, pin 4 */  \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(75, _board),                              /* VMOD1 */         \
				INVADERS_NODE(73, _board),                              /* VMOD2 */         \
				&invaders_missle_op_amp_osc)                                                \
		DISCRETE_OP_AMP(INVADERS_NODE(77, _board),                      /* IC A3, pin 9 */  \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(76, _board),                              /* IN0 */           \
				INVADERS_NODE(73, _board),                              /* IN1 */           \
				&invaders_missle_op_amp_A3)                                                 \
		DISCRETE_OP_AMP_TRIG_VCA(INVADERS_NODE(INVADERS_MISSILE_SND, _board),   /* IC A3, pin 10 */     \
				INVADERS_NODE(INVADERS_MISSILE_EN, _board),             /* TRG0 */          \
				0,                                                      /* no TRG1 */       \
				0,                                                      /* no TRG2 */       \
				INVADERS_NODE(77, _board),                              /* IN0 */           \
				0,                                                      /* no IN1 */        \
				&invaders_missle_tvca)


/************************************************
 * Explosion
 ************************************************/

discrete_op_amp_1sht_info const invaders_explosion_1sht =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(4.7),                         // R90
	RES_K(100),                         // R88
	RES_M(1),                           // R91
	RES_M(1),                           // R89
	RES_M(2.2),                         // R92
	CAP_U(2.2),                         // C24
	CAP_P(470),                         // C25
	0,                                  // vN
	12                                  // vP
};

discrete_op_amp_tvca_info const invaders_explosion_tvca =
{
	RES_M(2.7),                         // R80
	RES_K(680),                         // R79
	0,                                  // no r3
	RES_K(680),                         // R82
	RES_K(10),                          // R93
	0,                                  // no r6
	RES_K(680),                         // R83
	0,                                  // no r8
	0,                                  // no r9
	0,                                  // no r10
	0,                                  // no r11
	CAP_U(1),                           // C26
	0,                                  // no c2
	0, 0,                               // no c3, c4
	12.0 - OP_AMP_NORTON_VBE,           // v1
	0,                                  // no v2
	0,                                  // no v3
	12,                                 // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f0
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f1
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,  // f2
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f3
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f4
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE   // no f5
};

#define INVADERS_EXPLOSION(_board)                                                          \
		DISCRETE_INPUTX_LOGIC(INVADERS_NODE(INVADERS_EXPLOSION_EN, _board), 5, 0, 0)        \
		DISCRETE_OP_AMP_ONESHOT(INVADERS_NODE(60, _board),              /* IC D2, pin 10 */ \
				INVADERS_NODE(INVADERS_EXPLOSION_EN, _board),           /* TRIG */          \
				&invaders_explosion_1sht)                                                   \
		DISCRETE_OP_AMP_TRIG_VCA(INVADERS_NODE(61, _board),             /* IC D2, pin 4 */  \
				INVADERS_NODE(60, _board),                              /* TRG0 */          \
				0,                                                      /* no TRG1 */       \
				0,                                                      /* no TRG2 */       \
				INVADERS_NOISE,                                         /* IN0 */           \
				0,                                                      /* no IN1 */        \
				&invaders_explosion_tvca)                                                   \
		DISCRETE_RCFILTER(INVADERS_NODE(62, _board),                                        \
				INVADERS_NODE(61, _board),                              /* IN0 */           \
				RES_K(5.6),                                             /* R84 */           \
				CAP_U(0.1) )                                            /* C27 */           \
		DISCRETE_RCFILTER(INVADERS_NODE(INVADERS_EXPLOSION_SND, _board),                    \
				INVADERS_NODE(62, _board),                              /* IN0 */           \
				RES_K(5.6) + RES_K(6.8),                                /* R84 + R85 */     \
				CAP_U(0.1) )                                            /* C28 */


/************************************************
 * Final mix
 ************************************************/

discrete_mixer_desc const invaders_mixer =
{
	DISC_MIXER_IS_OP_AMP,               // type
	{ RES_K(200),                       // R78
		RES_K(10) + 100 + 100,          // R134 + R133 + R132
		RES_K(150),                     // R136
		RES_K(200),                     // R59
		RES_K(2) + RES_K(6.8) + RES_K(5.6), // R86 + R85 + R84
		RES_K(150) },                   // R28
	{0},                                // no rNode{}
	{ 0,
		0,
		0,
		0,
		0,
		CAP_U(0.001) },                 // C11
	0,                                  // no rI
	RES_K(100),                         // R105
	0,                                  // no cF
	CAP_U(0.1),                         // C45
	0,                                  // vRef = ground
	1                                   // gain
};

#define INVADERS_MIXER(_board, _type)                                                       \
		DISCRETE_MIXER6(INVADERS_NODE(90, _board),                                          \
				1,                                                      /* ENAB */          \
				INVADERS_NODE(INVADERS_SAUCER_HIT_SND, _board),         /* IN0 */           \
				INVADERS_NODE(INVADERS_FLEET_SND, _board),              /* IN1 */           \
				INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_SND, _board),  /* IN2 */           \
				INVADERS_NODE(INVADERS_INVADER_HIT_SND, _board),        /* IN3 */           \
				INVADERS_NODE(INVADERS_EXPLOSION_SND, _board),          /* IN4 */           \
				INVADERS_NODE(INVADERS_MISSILE_SND, _board),            /* IN5 */           \
				&_type##_mixer)                                                             \
		DISCRETE_OUTPUT(INVADERS_NODE(90, _board), 2500)

} // anonymous namespace


/*************************************
 *
 *  Device type globals
 *
 *************************************/

DEFINE_DEVICE_TYPE(SEAWOLF_AUDIO,  seawolf_audio_device,  "seawolf_audio",  "Midway Sea Wolf Audio")
DEFINE_DEVICE_TYPE(GUNFIGHT_AUDIO, gunfight_audio_device, "gunfight_audio", "Midway Gun Fight Audio")
DEFINE_DEVICE_TYPE(BOOTHILL_AUDIO, boothill_audio_device, "boothill_audio", "Midway Boot Hill Audio")
DEFINE_DEVICE_TYPE(DESERTGU_AUDIO, desertgu_audio_device, "desertgu_audio", "Midway Desert Gun Audio")
DEFINE_DEVICE_TYPE(DPLAY_AUDIO,    dplay_audio_device,    "dplay_audio",    "Midway Double Play Audio")
DEFINE_DEVICE_TYPE(GMISSILE_AUDIO, gmissile_audio_device, "gmissile_audio", "Midway Guided Missile Audio")
DEFINE_DEVICE_TYPE(M4_AUDIO,       m4_audio_device,       "m4_audio",       "Midway M-4 Audio")
DEFINE_DEVICE_TYPE(CLOWNS_AUDIO,   clowns_audio_device,   "clowns_audio",   "Midway Clowns Audio")
DEFINE_DEVICE_TYPE(SPACWALK_AUDIO, spacwalk_audio_device, "spacwalk_audio", "Midway Space Walk Audio")
DEFINE_DEVICE_TYPE(DOGPATCH_AUDIO, dogpatch_audio_device, "dogpatch_audio", "Midway Dog Patch Audio")
DEFINE_DEVICE_TYPE(SPCENCTR_AUDIO, spcenctr_audio_device, "spcenctr_audio", "Midway Space Encounters Audio")
DEFINE_DEVICE_TYPE(PHANTOM2_AUDIO, phantom2_audio_device, "phantom2_audio", "Midway Phantom 2 Audio")
DEFINE_DEVICE_TYPE(INVADERS_AUDIO, invaders_audio_device, "invaders_audio", "Taito Space Invaders Audio")
DEFINE_DEVICE_TYPE(INVAD2CT_AUDIO, invad2ct_audio_device, "invad2ct_audio", "Midway Space Invaders II Audio")


/*************************************
 *
 *  Implementation of tone generator used
 *  by a few of these games
 *
 *************************************/

#define MIDWAY_TONE_EN              NODE_100
#define MIDWAY_TONE_DATA_L          NODE_101
#define MIDWAY_TONE_DATA_H          NODE_102
#define MIDWAY_TONE_SND             NODE_103
#define MIDWAY_TONE_TRASFORM_OUT    NODE_104
#define MIDWAY_TONE_BEFORE_AMP_SND  NODE_105

#define MIDWAY_TONE_GENERATOR(discrete_op_amp_tvca_info) \
		/* bit 0 of tone data is always 0 */ \
		/* join the L & H tone bits */ \
		DISCRETE_INPUT_LOGIC(MIDWAY_TONE_EN) \
		DISCRETE_INPUT_DATA (MIDWAY_TONE_DATA_L) \
		DISCRETE_INPUT_DATA (MIDWAY_TONE_DATA_H) \
		DISCRETE_TRANSFORM4(MIDWAY_TONE_TRASFORM_OUT, MIDWAY_TONE_DATA_H, 0x40, MIDWAY_TONE_DATA_L, 0x02, "01*23*+") \
		DISCRETE_NOTE(MIDWAY_TONE_BEFORE_AMP_SND, 1, (double)MW8080BW_MASTER_CLOCK/10/2, MIDWAY_TONE_TRASFORM_OUT, 0xfff, 1, DISC_CLK_IS_FREQ) \
		DISCRETE_OP_AMP_TRIG_VCA(MIDWAY_TONE_SND, MIDWAY_TONE_BEFORE_AMP_SND, MIDWAY_TONE_EN, 0, 12, 0, &discrete_op_amp_tvca_info)

// most common values based on clowns schematic
static discrete_op_amp_tvca_info const midway_music_tvca_info =
{
	RES_M(3.3),             // r502
	RES_K(10) + RES_K(680), // r505 + r506
	0,
	RES_K(680),             // r503
	RES_K(10),              // r500
	0,
	RES_K(680),             // r501
	0,
	0,
	0,
	0,
	CAP_U(.001),            // c500
	0,
	0, 0,
	12,                     // v1
	0,                      // v2
	0,                      // v3
	12,                     // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG1,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

midway_tone_generator_device_base::midway_tone_generator_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, type, tag, owner, clock),
	m_discrete(*this, "discrete")
{
}

void midway_tone_generator_device_base::tone_generator_lo_w(u8 data)
{
	m_discrete->write(MIDWAY_TONE_EN, (data >> 0) & 0x01);

	m_discrete->write(MIDWAY_TONE_DATA_L, (data >> 1) & 0x1f);

	// D6 and D7 are not connected
}


void midway_tone_generator_device_base::tone_generator_hi_w(u8 data)
{
	m_discrete->write(MIDWAY_TONE_DATA_H, data & 0x3f);

	// D6 and D7 are not connected
}


/*************************************
 *
 *  Sea Wolf
 *
 *************************************/

seawolf_audio_device::seawolf_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, SEAWOLF_AUDIO, tag, owner, clock),
	m_samples(*this, "samples"),
	m_prev(0U)
{
}

void seawolf_audio_device::write(u8 data)
{
	u8 const rising(data & ~m_prev);
	m_prev = data;

	if (BIT(rising, 0)) m_samples->start(0, 0); // SHIP HIT sound
	if (BIT(rising, 1)) m_samples->start(1, 1); // TORPEDO sound
	if (BIT(rising, 2)) m_samples->start(2, 2); // DIVE sound
	if (BIT(rising, 3)) m_samples->start(3, 3); // SONAR sound
	if (BIT(rising, 4)) m_samples->start(4, 4); // MINE HIT sound

	machine().bookkeeping().coin_counter_w(0, BIT(data, 5));

	// D6 and D7 are not connected
}

void seawolf_audio_device::device_add_mconfig(machine_config &config)
{
	static char const *const sample_names[] = {
			"*seawolf",
			"shiphit",
			"torpedo",
			"dive",
			"sonar",
			"minehit",
			nullptr };

	SPEAKER(config, "mono").front_center();

	SAMPLES(config, m_samples);
	m_samples->set_channels(5);
	m_samples->set_samples_names(sample_names);
	m_samples->add_route(ALL_OUTPUTS, "mono", 0.6);
}

void seawolf_audio_device::device_start()
{
	m_prev = 0U;

	save_item(NAME(m_prev));
}


/*************************************
 *
 *  Gun Fight
 *
 *************************************/

gunfight_audio_device::gunfight_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, GUNFIGHT_AUDIO, tag, owner, clock),
	m_samples(*this, "samples%u", 1U)
{
}

void gunfight_audio_device::write(u8 data)
{
	// D0 and D1 are just tied to 1k resistors

	machine().bookkeeping().coin_counter_w(0, BIT(data, 2));

	// the 74175 latches and inverts the top 4 bits
	switch ((~data >> 4) & 0x0f)
	{
	case 0x00:
		break;
	case 0x01: // LEFT SHOOT sound (left speaker)
		m_samples[0]->start(0, 0);
		break;
	case 0x02: // RIGHT SHOOT sound (right speaker)
		m_samples[1]->start(0, 0);
		break;
	case 0x03: // LEFT HIT sound (left speaker)
		m_samples[0]->start(0, 1);
		break;
	case 0x04: // enable RIGHT HIT sound (right speaker)
		m_samples[1]->start(0, 1);
		break;
	default:
		logerror("%s: Unknown sh port write %02x\n", machine().describe_context(), data);
		break;
	}
}

void gunfight_audio_device::device_add_mconfig(machine_config &config)
{
	static char const *const sample_names[] = {
			"*gunfight",
			"gunshot",
			"killed",
			nullptr };

	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	SAMPLES(config, m_samples[0]);
	m_samples[0]->set_channels(1);
	m_samples[0]->set_samples_names(sample_names);
	m_samples[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);

	SAMPLES(config, m_samples[1]);
	m_samples[1]->set_channels(1);
	m_samples[1]->set_samples_names(sample_names);
	m_samples[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
}

void gunfight_audio_device::device_start()
{
}


/*************************************
 *
 *  Boot Hill
 *
 *  Discrete sound emulation: Jan 2007, D.R.
 *
 *************************************/

// nodes - inputs
#define BOOTHILL_GAME_ON_EN         NODE_01
#define BOOTHILL_LEFT_SHOT_EN       NODE_02
#define BOOTHILL_RIGHT_SHOT_EN      NODE_03
#define BOOTHILL_LEFT_HIT_EN        NODE_04
#define BOOTHILL_RIGHT_HIT_EN       NODE_05

// nodes - sounds
#define BOOTHILL_NOISE              NODE_06
#define BOOTHILL_L_SHOT_SND         NODE_07
#define BOOTHILL_R_SHOT_SND         NODE_08
#define BOOTHILL_L_HIT_SND          NODE_09
#define BOOTHILL_R_HIT_SND          NODE_10

// nodes - adjusters
#define BOOTHILL_MUSIC_ADJ          NODE_11

static discrete_op_amp_tvca_info const boothill_tone_tvca_info =
{
	RES_M(3.3),
	RES_K(100) + RES_K(680),
	0,
	RES_K(680),
	RES_K(10),
	0,
	RES_K(680),
	0,
	0,
	0,
	0,
	CAP_U(.001),
	0,
	0, 0,
	12,
	0,
	0,
	12,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG1,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_op_amp_tvca_info const boothill_shot_tvca_info =
{
	RES_M(2.7),
	RES_K(510),
	0,
	RES_K(510),
	RES_K(10),
	0,
	RES_K(510),
	0,
	0,
	0,
	0,
	CAP_U(0.22),
	0,
	0, 0,
	12,
	0,
	0,
	12,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_op_amp_tvca_info const boothill_hit_tvca_info =
{
	RES_M(2.7),
	RES_K(510),
	0,
	RES_K(510),
	RES_K(10),
	0,
	RES_K(510),
	0,
	0,
	0,
	0, 0,
	CAP_U(1),
	0,
	0,
	12,
	0,
	0,
	12,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_mixer_desc const boothill_l_mixer =
{
	DISC_MIXER_IS_OP_AMP,
	{ RES_K(12) + RES_K(68) + RES_K(33),
		RES_K(12) + RES_K(100) + RES_K(33) },
	{ 0 },
	{ 0 },
	0,
	RES_K(100),
	0,
	CAP_U(0.1),
	0,
	7200            // final gain
};

static discrete_mixer_desc const boothill_r_mixer =
{
	DISC_MIXER_IS_OP_AMP,
	{ RES_K(12) + RES_K(68) + RES_K(33),
		RES_K(12) + RES_K(100) + RES_K(33),
		RES_K(33) },
	{ 0,
		0,
		BOOTHILL_MUSIC_ADJ },
	{ 0 },
	0,
	RES_K(100),
	0,
	CAP_U(0.1),
	0,
	7200            // final gain
};

static DISCRETE_SOUND_START(boothill_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC(BOOTHILL_GAME_ON_EN)
	DISCRETE_INPUT_LOGIC(BOOTHILL_LEFT_SHOT_EN)
	DISCRETE_INPUT_LOGIC(BOOTHILL_RIGHT_SHOT_EN)
	DISCRETE_INPUT_LOGIC(BOOTHILL_LEFT_HIT_EN)
	DISCRETE_INPUT_LOGIC(BOOTHILL_RIGHT_HIT_EN)

	/* The low value of the pot is set to 75000.  A real 1M pot will never go to 0 anyways.
	   This will give the control more apparent volume range.
	   The music way overpowers the rest of the sounds anyways. */
	DISCRETE_ADJUSTMENT(BOOTHILL_MUSIC_ADJ, RES_M(1), 75000, DISC_LOGADJ, "MUSIC_ADJ")

	/************************************************
	 * Tone generator
	 ************************************************/
	MIDWAY_TONE_GENERATOR(boothill_tone_tvca_info)

	/************************************************
	 * Shot sounds
	 ************************************************/
	// Noise clock was breadboarded and measured at 7700Hz
	DISCRETE_LFSR_NOISE(BOOTHILL_NOISE, 1, 1, 7700, 12.0, 0, 12.0/2, &midway_lfsr)

	DISCRETE_OP_AMP_TRIG_VCA(NODE_30, BOOTHILL_LEFT_SHOT_EN, 0, 0, BOOTHILL_NOISE, 0, &boothill_shot_tvca_info)
	DISCRETE_RCFILTER(NODE_31, NODE_30, RES_K(12), CAP_U(.01))
	DISCRETE_RCFILTER(BOOTHILL_L_SHOT_SND, NODE_31, RES_K(12) + RES_K(68), CAP_U(.0022))

	DISCRETE_OP_AMP_TRIG_VCA(NODE_35, BOOTHILL_RIGHT_SHOT_EN, 0, 0, BOOTHILL_NOISE, 0, &boothill_shot_tvca_info)
	DISCRETE_RCFILTER(NODE_36, NODE_35, RES_K(12), CAP_U(.01))
	DISCRETE_RCFILTER(BOOTHILL_R_SHOT_SND, NODE_36, RES_K(12) + RES_K(68), CAP_U(.0033))

	/************************************************
	 * Hit sounds
	 ************************************************/
	DISCRETE_OP_AMP_TRIG_VCA(NODE_40, BOOTHILL_LEFT_HIT_EN, 0, 0, BOOTHILL_NOISE, 0, &boothill_hit_tvca_info)
	DISCRETE_RCFILTER(NODE_41, NODE_40, RES_K(12), CAP_U(.033))
	DISCRETE_RCFILTER(BOOTHILL_L_HIT_SND, NODE_41, RES_K(12) + RES_K(100), CAP_U(.0033))

	DISCRETE_OP_AMP_TRIG_VCA(NODE_45, BOOTHILL_RIGHT_HIT_EN, 0, 0, BOOTHILL_NOISE, 0, &boothill_hit_tvca_info)
	DISCRETE_RCFILTER(NODE_46, NODE_45, RES_K(12), CAP_U(.0033))
	DISCRETE_RCFILTER(BOOTHILL_R_HIT_SND, NODE_46, RES_K(12) + RES_K(100), CAP_U(.0022))

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	/* There is a 1uF cap on the input to the amp that I was too lazy to simulate.
	 * It is just a DC blocking cap needed by the Norton amp.  Doing the extra
	 * work to simulate it is not going to make a difference to the waveform
	 * or to how it sounds.  Also I use a regular amp in place of the Norton
	 * for the same reasons.  Ease of coding/simulation. */

	/* The schematics show the Hit sounds as shown.
	 * This makes the death of the enemy sound on the players side.
	 * This should be verified. */

	DISCRETE_MIXER2(NODE_91, BOOTHILL_GAME_ON_EN, BOOTHILL_L_SHOT_SND, BOOTHILL_L_HIT_SND, &boothill_l_mixer)

	// Music is only added to the right channel per schematics
	// This should be verified on the real game
	DISCRETE_MIXER3(NODE_92, BOOTHILL_GAME_ON_EN, BOOTHILL_R_SHOT_SND, BOOTHILL_R_HIT_SND, MIDWAY_TONE_SND, &boothill_r_mixer)

	DISCRETE_OUTPUT(NODE_91, 1)
	DISCRETE_OUTPUT(NODE_92, 1)
DISCRETE_SOUND_END

static INPUT_PORTS_START(boothill_audio)
	PORT_START("MUSIC_ADJ")
	PORT_ADJUSTER( 35, "Music Volume" )
INPUT_PORTS_END

boothill_audio_device::boothill_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	midway_tone_generator_device_base(mconfig, BOOTHILL_AUDIO, tag, owner, clock)
{
}

void boothill_audio_device::write(u8 data)
{
	// D0 and D1 are not connected

	machine().bookkeeping().coin_counter_w(0, BIT(data, 2));

	m_discrete->write(BOOTHILL_GAME_ON_EN, BIT(data, 3));

	m_discrete->write(BOOTHILL_LEFT_SHOT_EN, BIT(data, 4));

	m_discrete->write(BOOTHILL_RIGHT_SHOT_EN, BIT(data, 5));

	m_discrete->write(BOOTHILL_LEFT_HIT_EN, BIT(data, 6));

	m_discrete->write(BOOTHILL_RIGHT_HIT_EN, BIT(data, 7));
}

void boothill_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	DISCRETE(config, m_discrete, boothill_discrete);
	m_discrete->add_route(0, "lspeaker", 1.0);
	m_discrete->add_route(1, "rspeaker", 1.0);
}

ioport_constructor boothill_audio_device::device_input_ports() const
{
	return INPUT_PORTS_NAME(boothill_audio);
}

void boothill_audio_device::device_start()
{
}


/*************************************
 *
 *  Desert Gun
 *
 *  Discrete sound emulation: Jan 2007, D.R.
 *
 *************************************/

// nodes - inputs
#define DESERTGU_GAME_ON_EN                   NODE_01
#define DESERTGU_RIFLE_SHOT_EN                NODE_02
#define DESERTGU_BOTTLE_HIT_EN                NODE_03
#define DESERTGU_ROAD_RUNNER_HIT_EN           NODE_04
#define DESERTGU_CREATURE_HIT_EN              NODE_05
#define DESERTGU_ROADRUNNER_BEEP_BEEP_EN      NODE_06
#define DESERTGU_TRIGGER_CLICK_EN             NODE_07

// nodes - sounds
#define DESERTGU_NOISE                        NODE_08
#define DESERTGU_RIFLE_SHOT_SND               NODE_09
#define DESERTGU_BOTTLE_HIT_SND               NODE_10
#define DESERTGU_ROAD_RUNNER_HIT_SND          NODE_11
#define DESERTGU_CREATURE_HIT_SND             NODE_12
#define DESERTGU_ROADRUNNER_BEEP_BEEP_SND     NODE_13
#define DESERTGU_TRIGGER_CLICK_SND            DESERTGU_TRIGGER_CLICK_EN

// nodes - adjusters
#define DESERTGU_MUSIC_ADJ                    NODE_15

static discrete_op_amp_tvca_info const desertgu_rifle_shot_tvca_info =
{
	RES_M(2.7),
	RES_K(680),
	0,
	RES_K(680),
	RES_K(10),
	0,
	RES_K(680),
	0,
	0,
	0,
	0,
	CAP_U(0.47),
	0,
	0, 0,
	12,         // v1
	0,          // v2
	0,          // v3
	12,         // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};


static discrete_mixer_desc const desertgu_filter_mixer =
{
	DISC_MIXER_IS_RESISTOR,
	{ RES_K(2),
		RES_K(27),
		RES_K(2) + RES_K(1) },
	{ 0 },
	{ 0 },
	0,
	0,
	0,
	0,
	0,
	1
};


static discrete_op_amp_filt_info const desertgu_filter =
{
	1.0 / ( 1.0 / RES_K(2) + 1.0 / RES_K(27) + 1.0 / (RES_K(2) + RES_K(1))),
	0,
	68,
	0,
	RES_K(39),
	CAP_U(0.033),
	CAP_U(0.033),
	0,
	0,
	12,
	0
};


static const discrete_mixer_desc desertgu_mixer =
{
	DISC_MIXER_IS_OP_AMP,
	{ RES_K(12) + RES_K(68) + RES_K(30),
		RES_K(56),
		RES_K(180),
		RES_K(47),
		RES_K(30) },
	{ 0,
		0,
		0,
		0,
		DESERTGU_MUSIC_ADJ },
	{ CAP_U(0.1),
		CAP_U(0.1),
		CAP_U(0.1),
		CAP_U(0.1),
		CAP_U(0.1) },
	0,
	RES_K(100),
	0,
	CAP_U(0.1),
	0,
	6000        // final gain
};


static DISCRETE_SOUND_START(desertgu_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC(DESERTGU_GAME_ON_EN)
	DISCRETE_INPUT_LOGIC(DESERTGU_RIFLE_SHOT_EN)
	DISCRETE_INPUT_LOGIC(DESERTGU_BOTTLE_HIT_EN)
	DISCRETE_INPUT_LOGIC(DESERTGU_ROAD_RUNNER_HIT_EN)
	DISCRETE_INPUT_LOGIC(DESERTGU_CREATURE_HIT_EN)
	DISCRETE_INPUT_LOGIC(DESERTGU_ROADRUNNER_BEEP_BEEP_EN)
	DISCRETE_INPUTX_LOGIC(DESERTGU_TRIGGER_CLICK_SND, 12, 0, 0)

	// The low value of the pot is set to 75000.  A real 1M pot will never go to 0 anyways.
	// This will give the control more apparent volume range.
	// The music way overpowers the rest of the sounds anyways.
	DISCRETE_ADJUSTMENT(DESERTGU_MUSIC_ADJ, RES_M(1), 75000, DISC_LOGADJ, "MUSIC_ADJ")

	/************************************************
	 * Tone generator
	 ************************************************/
	MIDWAY_TONE_GENERATOR(midway_music_tvca_info)

	/************************************************
	 * Rifle shot sound
	 ************************************************/
	// Noise clock was breadboarded and measured at 7515Hz
	DISCRETE_LFSR_NOISE(DESERTGU_NOISE, 1, 1, 7515, 12.0, 0, 12.0/2, &midway_lfsr)

	DISCRETE_OP_AMP_TRIG_VCA(NODE_30, DESERTGU_RIFLE_SHOT_EN, 0, 0, DESERTGU_NOISE, 0, &desertgu_rifle_shot_tvca_info)
	DISCRETE_RCFILTER(NODE_31, NODE_30, RES_K(12), CAP_U(.01))
	DISCRETE_CRFILTER(DESERTGU_RIFLE_SHOT_SND, NODE_31, RES_K(12) + RES_K(68), CAP_U(.0022))

	/************************************************
	 * Bottle hit sound
	 ************************************************/
	DISCRETE_CONSTANT(DESERTGU_BOTTLE_HIT_SND, 0)  // placeholder for incomplete sound

	/************************************************
	 * Road Runner hit sound
	 ************************************************/
	DISCRETE_CONSTANT(DESERTGU_ROAD_RUNNER_HIT_SND, 0)  // placeholder for incomplete sound

	/************************************************
	 * Creature hit sound
	 ************************************************/
	DISCRETE_CONSTANT(DESERTGU_CREATURE_HIT_SND, 0)  // placeholder for incomplete sound

	/************************************************
	 * Beep-Beep sound
	 ************************************************/
	DISCRETE_CONSTANT(DESERTGU_ROADRUNNER_BEEP_BEEP_SND, 0) // placeholder for incomplete sound

	/************************************************
	 * Mix and filter
	 ************************************************/
	DISCRETE_MIXER3(NODE_80, 1, DESERTGU_BOTTLE_HIT_SND, DESERTGU_ROADRUNNER_BEEP_BEEP_SND, DESERTGU_TRIGGER_CLICK_SND, &desertgu_filter_mixer)
	DISCRETE_OP_AMP_FILTER(NODE_81, 1, NODE_80, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1, &desertgu_filter)

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	DISCRETE_MIXER5(NODE_91, DESERTGU_GAME_ON_EN, DESERTGU_RIFLE_SHOT_SND, DESERTGU_ROAD_RUNNER_HIT_SND, DESERTGU_CREATURE_HIT_SND, NODE_81, MIDWAY_TONE_SND, &desertgu_mixer)

	DISCRETE_OUTPUT(NODE_91, 1)
DISCRETE_SOUND_END

INPUT_PORTS_START(desertgu_audio)
	PORT_START("MUSIC_ADJ")  // 3
	PORT_ADJUSTER( 60, "Music Volume" )
INPUT_PORTS_END

desertgu_audio_device::desertgu_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	midway_tone_generator_device_base(mconfig, DESERTGU_AUDIO, tag, owner, clock),
	m_ctrl_sel_out(*this),
	m_recoil(*this, "Player1_Gun_Recoil"),
	m_p2(0U)
{
}

void desertgu_audio_device::p1_w(u8 data)
{
	// D0 and D1 are not connected

	machine().bookkeeping().coin_counter_w(0, BIT(data, 2));

	m_discrete->write(DESERTGU_GAME_ON_EN, (data >> 3) & 0x01);
	m_discrete->write(DESERTGU_RIFLE_SHOT_EN, (data >> 4) & 0x01);
	m_discrete->write(DESERTGU_BOTTLE_HIT_EN, (data >> 5) & 0x01);
	m_discrete->write(DESERTGU_ROAD_RUNNER_HIT_EN, (data >> 6) & 0x01);
	m_discrete->write(DESERTGU_CREATURE_HIT_EN, (data >> 7) & 0x01);
}

void desertgu_audio_device::p2_w(u8 data)
{
	u8 const changed(data ^ m_p2);
	m_p2 = data;

	m_discrete->write(DESERTGU_ROADRUNNER_BEEP_BEEP_EN, (data >> 0) & 0x01);
	m_discrete->write(DESERTGU_TRIGGER_CLICK_EN, (data >> 1) & 0x01);

	m_recoil = BIT(data, 2);

	if (BIT(changed, 3)) m_ctrl_sel_out(BIT(data, 3));

	// D4-D7 are not connected
}

void desertgu_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "mono").front_center();

	DISCRETE(config, m_discrete, desertgu_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 0.8);
}

ioport_constructor desertgu_audio_device::device_input_ports() const
{
	return INPUT_PORTS_NAME(desertgu_audio);
}

void desertgu_audio_device::device_start()
{
	m_ctrl_sel_out.resolve();
	m_recoil.resolve();

	m_p2 = 0U;

	save_item(NAME(m_p2));
}


/*************************************
 *
 *  Double Play / Extra Inning
 *
 *  Discrete sound emulation: Jan 2007, D.R.
 *
 *************************************/

// nodes - inputs
#define DPLAY_GAME_ON_EN      NODE_01
#define DPLAY_TONE_ON_EN      NODE_02
#define DPLAY_SIREN_EN        NODE_03
#define DPLAY_WHISTLE_EN      NODE_04
#define DPLAY_CHEER_EN        NODE_05

// nodes - sounds
#define DPLAY_NOISE           NODE_06
#define DPLAY_TONE_SND        NODE_07
#define DPLAY_SIREN_SND       NODE_08
#define DPLAY_WHISTLE_SND     NODE_09
#define DPLAY_CHEER_SND       NODE_10

// nodes - adjusters
#define DPLAY_MUSIC_ADJ       NODE_11

static discrete_lfsr_desc const dplay_lfsr =
{
	DISC_CLK_IS_FREQ,
	17,                 // bit length
						// the RC network fed into pin 4, has the effect of presetting all bits high at power up
	0x1ffff,            // reset value
	4,                  // use bit 4 as XOR input 0
	16,                 // use bit 16 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
	0,                  // output is not inverted
	8                   // output bit
};

static discrete_integrate_info const dplay_siren_integrate_info =
{
	DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(1),
	RES_K(100),
	0,
	CAP_U(3.3),
	12,
	12,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_op_amp_osc_info const dplay_siren_osc =
{
	DISC_OP_AMP_OSCILLATOR_VCO_2 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,  // type
	RES_K(390),         // r1
	RES_M(5.6),         // r2
	RES_M(1),           // r3
	RES_M(1.5),         // r4
	RES_M(3.3),         // r5
	RES_K(56),          // r6
	0,                  // no r7
	0,                  // no r8
	CAP_U(0.0022),      // c
	12                  // vP
};

static discrete_integrate_info const dplay_whistle_integrate_info =
{
	DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(1),
	RES_K(220) + RES_K(10),
	0,
	CAP_U(3.3),
	12,
	12,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_op_amp_osc_info const dplay_whistle_osc =
{
	DISC_OP_AMP_OSCILLATOR_VCO_2 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,  // type
	RES_K(510),         // r1
	RES_M(5.6),         // r2
	RES_M(1),           // r3
	RES_M(1.5),         // r4
	RES_M(3.3),         // r5
	RES_K(300),         // r6
	0,                  // no r7
	0,                  // no r8
	CAP_P(220),         // c
	12                  // vP
};

static discrete_integrate_info const dplay_cheer_integrate_info =
{
	DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(1.5),
	RES_K(100),
	0,
	CAP_U(4.7),
	12,
	12,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_op_amp_filt_info const dplay_cheer_filter =
{
	RES_K(100),
	0,
	RES_K(100),
	0,
	RES_K(150),
	CAP_U(0.0047),
	CAP_U(0.0047),
	0,
	0,
	12,
	0
};

static discrete_mixer_desc const dplay_mixer =
{
	DISC_MIXER_IS_OP_AMP,
	{ RES_K(68),
		RES_K(68),
		RES_K(68),
		RES_K(18),
		RES_K(68) },
	{ 0,
		0,
		0,
		0,
		DPLAY_MUSIC_ADJ },
	{ CAP_U(0.1),
		CAP_U(0.1),
		CAP_U(0.1),
		CAP_U(0.1),
		CAP_U(0.1) }
	, 0, RES_K(100), 0, CAP_U(0.1), 0,
	2000    /* final gain */
};

static DISCRETE_SOUND_START(dplay_discrete)
	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC (DPLAY_GAME_ON_EN)
	DISCRETE_INPUT_LOGIC (DPLAY_TONE_ON_EN)
	DISCRETE_INPUTX_LOGIC(DPLAY_SIREN_EN, 5, 0, 0)
	DISCRETE_INPUTX_LOGIC(DPLAY_WHISTLE_EN, 12, 0, 0)
	DISCRETE_INPUTX_LOGIC(DPLAY_CHEER_EN, 5, 0, 0)

	// The low value of the pot is set to 1000.  A real 1M pot will never go to 0 anyways.
	// This will give the control more apparent volume range.
	// The music way overpowers the rest of the sounds anyways.
	DISCRETE_ADJUSTMENT(DPLAY_MUSIC_ADJ, RES_M(1), 1000, DISC_LOGADJ, "MUSIC_ADJ")

	/************************************************
	 * Music and Tone Generator
	 ************************************************/
	MIDWAY_TONE_GENERATOR(midway_music_tvca_info)

	DISCRETE_OP_AMP_TRIG_VCA(DPLAY_TONE_SND, MIDWAY_TONE_BEFORE_AMP_SND, DPLAY_TONE_ON_EN, 0, 12, 0, &midway_music_tvca_info)

	/************************************************
	 * Siren
	 ************************************************/
	DISCRETE_INTEGRATE(NODE_30,
			DPLAY_SIREN_EN,                 // TRG0
			0,                              // TRG1
			&dplay_siren_integrate_info)
	DISCRETE_OP_AMP_VCO1(DPLAY_SIREN_SND,
			1,                              // ENAB
			NODE_30,                        // VMOD1
			&dplay_siren_osc)

	/************************************************
	 * Whistle
	 ************************************************/
	DISCRETE_INTEGRATE(NODE_40,
			DPLAY_WHISTLE_EN,               // TRG0
			0,                              // TRG1
			&dplay_whistle_integrate_info)
	DISCRETE_OP_AMP_VCO1(DPLAY_WHISTLE_SND,
			1,                              // ENAB
			NODE_40,                        // VMOD1
			&dplay_whistle_osc)

	/************************************************
	 * Cheer
	 ************************************************/
	// Noise clock was breadboarded and measured at 7700Hz
	DISCRETE_LFSR_NOISE(DPLAY_NOISE, 1, 1, 7700, 12.0, 0, 12.0/2, &dplay_lfsr)

	DISCRETE_INTEGRATE(NODE_50, DPLAY_CHEER_EN, 0, &dplay_cheer_integrate_info)
	DISCRETE_SWITCH(NODE_51, 1, DPLAY_NOISE, 0, NODE_50)
	DISCRETE_OP_AMP_FILTER(DPLAY_CHEER_SND, 1, NODE_51, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &dplay_cheer_filter)

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	DISCRETE_MIXER5(NODE_91, DPLAY_GAME_ON_EN, DPLAY_TONE_SND, DPLAY_SIREN_SND, DPLAY_WHISTLE_SND, DPLAY_CHEER_SND, MIDWAY_TONE_SND, &dplay_mixer)

	DISCRETE_OUTPUT(NODE_91, 1)
DISCRETE_SOUND_END

static INPUT_PORTS_START(dplay_audio)
	PORT_START("MUSIC_ADJ")  // 3
	PORT_ADJUSTER( 60, "Music Volume" )
INPUT_PORTS_END

dplay_audio_device::dplay_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	midway_tone_generator_device_base(mconfig, DPLAY_AUDIO, tag, owner, clock)
{
}

void dplay_audio_device::write(u8 data)
{
	m_discrete->write(DPLAY_TONE_ON_EN, BIT(data, 0));

	m_discrete->write(DPLAY_CHEER_EN, BIT(data, 1));

	m_discrete->write(DPLAY_SIREN_EN, BIT(data, 2));

	m_discrete->write(DPLAY_WHISTLE_EN, BIT(data, 3));

	m_discrete->write(DPLAY_GAME_ON_EN, BIT(data, 4));

	machine().bookkeeping().coin_counter_w(0, BIT(data, 5));

	// D6 and D7 are not connected
}

void dplay_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "mono").front_center();

	DISCRETE(config, m_discrete, dplay_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 0.8);
}

ioport_constructor dplay_audio_device::device_input_ports() const
{
	return INPUT_PORTS_NAME(dplay_audio);
}

void dplay_audio_device::device_start()
{
}


/*************************************
 *
 *  Guided Missile
 *
 *************************************/

gmissile_audio_device::gmissile_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, GMISSILE_AUDIO, tag, owner, clock),
	m_samples(*this, "samples%u", 1U),
	m_l_exp(*this, "L_EXP_LIGHT"),
	m_r_exp(*this, "R_EXP_LIGHT"),
	m_p1(0U)
{
}

void gmissile_audio_device::p1_w(u8 data)
{
	/* note that the schematics shows the left and right explosions
	   reversed (D5=R, D7=L), but the software confirms that
	   ours is right */

	u8 const rising(data & ~m_p1);
	m_p1 = data;

	// D0 and D1 are not connected

	machine().bookkeeping().coin_counter_w(0, BIT(data, 2));

	machine().sound().system_enable(BIT(data, 3));

	if (BIT(rising, 4)) m_samples[1]->start(0, 0); // RIGHT MISSILE sound (goes to right speaker)

	m_l_exp = BIT(data, 5);
	if (BIT(rising, 5)) m_samples[0]->start(0, 1); // LEFT EXPLOSION sound (goes to left speaker)

	if (BIT(rising, 6)) m_samples[0]->start(0, 0); // LEFT MISSILE sound (goes to left speaker)

	m_r_exp = BIT(data, 7);
	if (BIT(rising, 7)) m_samples[1]->start(0, 1); // RIGHT EXPLOSION sound (goes to right speaker)
}

void gmissile_audio_device::p2_w(u8 data)
{
	// set AIRPLANE/COPTER/JET PAN(data & 0x07)

	// set TANK PAN((data >> 3) & 0x07)

	// D6 and D7 are not connected
}

void gmissile_audio_device::p3_w(u8 data)
{
	// if (data & 0x01)  enable AIRPLANE (bi-plane) sound (goes to AIRPLANE/COPTER/JET panning circuit)

	// if (data & 0x02)  enable TANK sound (goes to TANK panning circuit)

	// if (data & 0x04)  enable COPTER sound (goes to AIRPLANE/COPTER/JET panning circuit)

	// D3 and D4 are not connected

	// if (data & 0x20)  enable JET (3 fighter jets) sound (goes to AIRPLANE/COPTER/JET panning circuit)

	// D6 and D7 are not connected
}

void gmissile_audio_device::device_add_mconfig(machine_config &config)
{
	static char const *const sample_names[] = {
			"*gmissile",
			"1",        // missle
			"2",        // explosion
			nullptr };

	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	SAMPLES(config, m_samples[0]);
	m_samples[0]->set_channels(1);
	m_samples[0]->set_samples_names(sample_names);
	m_samples[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0);

	SAMPLES(config, m_samples[1]);
	m_samples[1]->set_channels(1);
	m_samples[1]->set_samples_names(sample_names);
	m_samples[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
}

void gmissile_audio_device::device_start()
{
	m_l_exp.resolve();
	m_r_exp.resolve();

	m_p1 = 0U;

	save_item(NAME(m_p1));
}


/*************************************
 *
 *  M-4
 *
 *************************************/

// Noise clock was breadboarded and measured at 3760Hz

m4_audio_device::m4_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, M4_AUDIO, tag, owner, clock),
	m_samples(*this, "samples%u", 1U),
	m_p1(0U),
	m_p2(0U)
{
}

void m4_audio_device::p1_w(u8 data)
{
	u8 const rising(data & ~m_p1);
	m_p1 = data;

	// D0 and D1 are not connected

	machine().bookkeeping().coin_counter_w(0, BIT(data, 2));

	machine().sound().system_enable(BIT(data, 3));

	if (BIT(rising, 4)) m_samples[0]->start(0, 0); // LEFT PLAYER SHOT sound (goes to left speaker)
	if (BIT(rising, 5)) m_samples[1]->start(0, 0); // RIGHT PLAYER SHOT sound (goes to right speaker)
	if (BIT(rising, 6)) m_samples[0]->start(1, 1); // LEFT PLAYER EXPLOSION sound via 300K res (goes to left speaker)
	if (BIT(rising, 7)) m_samples[1]->start(1, 1); // RIGHT PLAYER EXPLOSION sound via 300K res (goes to right speaker)
}


void m4_audio_device::p2_w(u8 data)
{
	u8 const rising(data & ~m_p2);
	m_p2 = data;

	if (BIT(rising, 0)) m_samples[0]->start(1, 1); // LEFT PLAYER EXPLOSION sound via 510K res (goes to left speaker)
	if (BIT(rising, 1)) m_samples[1]->start(1, 1); // RIGHT PLAYER EXPLOSION sound via 510K res (goes to right speaker)

	// if (data & 0x04)  enable LEFT TANK MOTOR sound (goes to left speaker)

	// if (data & 0x08)  enable RIGHT TANK MOTOR sound (goes to right speaker)

	// if (data & 0x10)  enable sound that is playing while the right plane is flying.  Circuit not named on schematics  (goes to left speaker)

	// if (data & 0x20)  enable sound that is playing while the left plane is flying.  Circuit not named on schematics  (goes to right speaker)

	// D6 and D7 are not connected
}

void m4_audio_device::device_add_mconfig(machine_config &config)
{
	static char const *const sample_names[] = {
			"*m4",
			"1",        // missle
			"2",        // explosion
			nullptr };

	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	SAMPLES(config, m_samples[0]);
	m_samples[0]->set_channels(2);
	m_samples[0]->set_samples_names(sample_names);
	m_samples[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0);

	SAMPLES(config, m_samples[1]);
	m_samples[1]->set_channels(2);
	m_samples[1]->set_samples_names(sample_names);
	m_samples[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
}

void m4_audio_device::device_start()
{
	m_p1 = 0U;
	m_p2 = 0U;

	save_item(NAME(m_p1));
	save_item(NAME(m_p2));
}


/*************************************
 *
 *  Clowns
 *
 *  Discrete sound emulation: Mar 2005, D.R.
 *
 *************************************/

// nodes - inputs
#define CLOWNS_POP_BOTTOM_EN        NODE_01
#define CLOWNS_POP_MIDDLE_EN        NODE_02
#define CLOWNS_POP_TOP_EN           NODE_03
#define CLOWNS_SPRINGBOARD_HIT_EN   NODE_04
#define CLOWNS_SPRINGBOARD_MISS_EN  NODE_05

// nodes - sounds
#define CLOWNS_NOISE                NODE_06
#define CLOWNS_POP_SND              NODE_07
#define CLOWNS_SB_HIT_SND           NODE_08
#define CLOWNS_SB_MISS_SND          NODE_09

// nodes - adjusters
#define CLOWNS_R507_POT             NODE_11

static discrete_op_amp_tvca_info const clowns_pop_tvca_info =
{
	RES_M(2.7),     // r304
	RES_K(680),     // r303
	0,
	RES_K(680),     // r305
	RES_K(1),       // j3
	0,
	RES_K(470),     // r300
	RES_K(1),       // j3
	RES_K(510),     // r301
	RES_K(1),       // j3
	RES_K(680),     // r302
	CAP_U(.015),    // c300
	CAP_U(.1),      // c301
	CAP_U(.082),    // c302
	0,              // no c4
	5,              // v1
	5,              // v2
	5,              // v3
	12,             // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG1,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG2
};

static discrete_op_amp_osc_info const clowns_sb_hit_osc_info =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,
	RES_K(820),     // r200
	RES_K(33),      // r203
	RES_K(150),     // r201
	RES_K(240),     // r204
	RES_M(1),       // r202
	0,
	0,
	0,
	CAP_U(0.01),    // c200
	12
};

static discrete_op_amp_tvca_info const clowns_sb_hit_tvca_info =
{
	RES_M(2.7),     // r207
	RES_K(680),     // r205
	0,
	RES_K(680),     // r208
	RES_K(1),       // j3
	0,
	RES_K(680),     // r206
	0,0,0,0,
	CAP_U(1),       // c201
	0,
	0, 0,
	5,              // v1
	0,              // v2
	0,              // v3
	12,             // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_mixer_desc const clowns_mixer =
{
	DISC_MIXER_IS_OP_AMP,
	{ RES_K(10),
		RES_K(10),
		RES_K(10) + 1.0 / (1.0 / RES_K(15) + 1.0 / RES_K(39)),
		RES_K(1) },
	{ 0,
		0,
		0,
		CLOWNS_R507_POT },
	{ 0,
		CAP_U(0.022),
		0,
		0 },
	0,
	RES_K(100),
	0,
	CAP_U(1),
	0,
	1
};

static DISCRETE_SOUND_START(clowns_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC(CLOWNS_POP_BOTTOM_EN)
	DISCRETE_INPUT_LOGIC(CLOWNS_POP_MIDDLE_EN)
	DISCRETE_INPUT_LOGIC(CLOWNS_POP_TOP_EN)
	DISCRETE_INPUT_LOGIC(CLOWNS_SPRINGBOARD_HIT_EN)
	DISCRETE_INPUT_LOGIC(CLOWNS_SPRINGBOARD_MISS_EN)

	// The low value of the pot is set to 7000.  A real 1M pot will never go to 0 anyways.
	// This will give the control more apparent volume range.
	// The music way overpowers the rest of the sounds anyways.
	DISCRETE_ADJUSTMENT(CLOWNS_R507_POT, RES_M(1), 7000, DISC_LOGADJ, "R507")

	/************************************************
	 * Tone generator
	 ************************************************/
	MIDWAY_TONE_GENERATOR(midway_music_tvca_info)

	/************************************************
	 * Balloon hit sounds
	 * The LFSR is the same as boothill
	 ************************************************/
	// Noise clock was breadboarded and measured at 7700Hz
	DISCRETE_LFSR_NOISE(CLOWNS_NOISE, 1, 1, 7700, 12.0, 0, 12.0/2, &midway_lfsr)

	DISCRETE_OP_AMP_TRIG_VCA(NODE_30, CLOWNS_POP_TOP_EN, CLOWNS_POP_MIDDLE_EN, CLOWNS_POP_BOTTOM_EN, CLOWNS_NOISE, 0, &clowns_pop_tvca_info)
	DISCRETE_RCFILTER(NODE_31, NODE_30, RES_K(15), CAP_U(.01))
	DISCRETE_CRFILTER(NODE_32, NODE_31, RES_K(15) + RES_K(39), CAP_U(.01))
	DISCRETE_GAIN(CLOWNS_POP_SND, NODE_32, RES_K(39)/(RES_K(15) + RES_K(39)))

	/************************************************
	 * Springboard hit
	 ************************************************/
	DISCRETE_OP_AMP_OSCILLATOR(NODE_40, 1, &clowns_sb_hit_osc_info)
	DISCRETE_OP_AMP_TRIG_VCA(NODE_41, CLOWNS_SPRINGBOARD_HIT_EN, 0, 0, NODE_40, 0, &clowns_sb_hit_tvca_info)
	// The rest of the circuit is a filter.  The frequency response was calculated with SPICE.
	DISCRETE_FILTER2(NODE_42, 1, NODE_41, 500, 1.0/.8, DISC_FILTER_LOWPASS)
	// The filter has a gain of 0.5
	DISCRETE_GAIN(CLOWNS_SB_HIT_SND, NODE_42, 0.5)

	/************************************************
	 * Springboard miss - INCOMPLETE
	 ************************************************/
	DISCRETE_CONSTANT(CLOWNS_SB_MISS_SND, 0) // Placeholder for incomplete sound

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	DISCRETE_MIXER4(NODE_91, 1, CLOWNS_SB_HIT_SND, CLOWNS_SB_MISS_SND, CLOWNS_POP_SND, MIDWAY_TONE_SND, &clowns_mixer)

	DISCRETE_OUTPUT(NODE_91, 11000)
DISCRETE_SOUND_END

static INPUT_PORTS_START(clowns_audio)
	PORT_START("R507")
	PORT_ADJUSTER( 40, "R507 - Music Volume" )
INPUT_PORTS_END

clowns_audio_device::clowns_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	midway_tone_generator_device_base(mconfig, CLOWNS_AUDIO, tag, owner, clock),
	m_samples(*this, "samples"),
	m_ctrl_sel_out(*this),
	m_p1(0U),
	m_p2(0U)
{
}

void clowns_audio_device::p1_w(u8 data)
{
	u8 const changed(data ^ m_p1);
	m_p1 = data;

	machine().bookkeeping().coin_counter_w(0, BIT(data, 0));

	if (BIT(changed, 1)) m_ctrl_sel_out(BIT(data, 1));

	// D2-D7 are not connected
}

void clowns_audio_device::p2_w(u8 data)
{
	u8 const rising(data & ~m_p2);
	m_p2 = data;

	m_discrete->write(CLOWNS_POP_BOTTOM_EN, BIT(data, 0));
	m_discrete->write(CLOWNS_POP_MIDDLE_EN, BIT(data, 1));
	m_discrete->write(CLOWNS_POP_TOP_EN, BIT(data, 2));

	machine().sound().system_enable(BIT(data, 3));

	m_discrete->write(CLOWNS_SPRINGBOARD_HIT_EN, BIT(data, 4));

	if (BIT(rising, 5)) m_samples->start(0, 0);  // springboard miss

	// D6 and D7 are not connected
}

void clowns_audio_device::device_add_mconfig(machine_config &config)
{
	static char const *const sample_names[] = {
			"*clowns",
			"miss",
			nullptr };

	SPEAKER(config, "mono").front_center();

	SAMPLES(config, m_samples);
	m_samples->set_channels(1);
	m_samples->set_samples_names(sample_names);
	m_samples->add_route(ALL_OUTPUTS, "mono", 0.70);

	DISCRETE(config, m_discrete, clowns_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 0.25);
}

ioport_constructor clowns_audio_device::device_input_ports() const
{
	return INPUT_PORTS_NAME(clowns_audio);
}

void clowns_audio_device::device_start()
{
	m_ctrl_sel_out.resolve_safe();

	m_p1 = 0U;
	m_p2 = 0U;

	save_item(NAME(m_p1));
	save_item(NAME(m_p2));
}


/*************************************
 *
 *  Space Walk
 *
 *  Discrete sound emulation: Oct 2009, D.R.
 *
 *************************************/

// Discrete Sound Input Nodes
#define SPACWALK_TARGET_HIT_BOTTOM_EN         NODE_01
#define SPACWALK_TARGET_HIT_MIDDLE_EN         NODE_02
#define SPACWALK_TARGET_HIT_TOP_EN            NODE_03
#define SPACWALK_SPRINGBOARD_HIT1_EN          NODE_04
#define SPACWALK_SPRINGBOARD_HIT2_EN          NODE_05
#define SPACWALK_SPRINGBOARD_MISS_EN          NODE_06
#define SPACWALK_SPACE_SHIP_EN                NODE_07

// Discrete Sound Output Nodes
#define SPACWALK_NOISE                        NODE_10
#define SPACWALK_TARGET_HIT_SND               NODE_11
#define SPACWALK_SPRINGBOARD_HIT1_SND         NODE_12
#define SPACWALK_SPRINGBOARD_HIT2_SND         NODE_13
#define SPACWALK_SPRINGBOARD_MISS_SND         NODE_14
#define SPACWALK_SPACE_SHIP_SND               NODE_15

// Adjusters
#define SPACWALK_R507_POT                     NODE_19

// Parts List - Resistors
#define SPACWALK_R200       RES_K(820)
#define SPACWALK_R201       RES_K(150)
#define SPACWALK_R202       RES_M(1)
#define SPACWALK_R203       RES_K(82)
#define SPACWALK_R204       RES_K(240)
#define SPACWALK_R205       RES_K(220)
#define SPACWALK_R206       RES_K(120)
#define SPACWALK_R207       RES_M(1)
#define SPACWALK_R208       RES_K(300)
#define SPACWALK_R210       RES_K(56)
#define SPACWALK_R211       RES_K(100)
#define SPACWALK_R213       RES_K(300)
#define SPACWALK_R214       RES_K(27)
#define SPACWALK_R215       RES_K(51)
#define SPACWALK_R216       RES_K(30)
#define SPACWALK_R300       RES_K(270)
#define SPACWALK_R301       RES_K(300)
#define SPACWALK_R302       RES_K(330)
#define SPACWALK_R303       RES_K(680)
#define SPACWALK_R304       RES_M(1)
#define SPACWALK_R305       RES_K(3680)
#define SPACWALK_R307       RES_K(20)
#define SPACWALK_R308       RES_K(20)       // not labeled but it's beside R307
#define SPACWALK_R400       RES_K(1)
#define SPACWALK_R401       RES_K(200)
#define SPACWALK_R403       RES_K(51)
#define SPACWALK_R404       RES_K(220)
#define SPACWALK_R406       RES_M(1)
#define SPACWALK_R407       RES_K(820)
#define SPACWALK_R410       RES_K(47)
#define SPACWALK_R411       RES_K(300)
#define SPACWALK_R412       RES_K(330)
#define SPACWALK_R413       RES_M(1)
#define SPACWALK_R414       RES_M(1)
#define SPACWALK_R416       RES_M(4.7)
#define SPACWALK_R417       RES_K(10)
#define SPACWALK_R418       RES_K(100)
#define SPACWALK_R419       RES_K(2.7)
#define SPACWALK_R420       RES_K(20)
#define SPACWALK_R421       RES_K(11)
#define SPACWALK_R422       RES_K(75)
#define SPACWALK_R507       RES_M(1)
#define SPACWALK_RJ3        RES_K(1)

// Parts List - Capacitors
#define SPACWALK_C200       CAP_U(0.0022)
#define SPACWALK_C201       CAP_U(3.3)
#define SPACWALK_C203       CAP_U(0.0033)
#define SPACWALK_C204       CAP_U(0.0033)
#define SPACWALK_C300       CAP_U(2.2)
#define SPACWALK_C301       CAP_U(2.2)
#define SPACWALK_C302       CAP_U(2.2)
#define SPACWALK_C303       CAP_U(0.0047)
#define SPACWALK_C304       CAP_U(0.0047)   // not labeled but it's beside C303
#define SPACWALK_C401       CAP_U(1)
#define SPACWALK_C402       CAP_U(0.68)
#define SPACWALK_C403       CAP_U(0.0022)
#define SPACWALK_C451       CAP_U(0.001)
#define SPACWALK_C452       CAP_U(0.001)
#define SPACWALK_C453       CAP_U(0.001)
#define SPACWALK_C602       CAP_U(1)

static discrete_op_amp_tvca_info const spacwalk_hit_tvca_info =
{
	SPACWALK_R304, SPACWALK_R303, 0, SPACWALK_R305,                     // r1, r2, r3, r4
	SPACWALK_RJ3, 0, SPACWALK_R300,                                     // r5, r6, r7
	SPACWALK_RJ3, SPACWALK_R301,                                        // r8, r9
	SPACWALK_RJ3, SPACWALK_R302,                                        // r10, r11
	SPACWALK_C300, SPACWALK_C301, SPACWALK_C302, 0,                     // c1, c2, c3, c4
	5, 5, 5, 12,                                                        // v1, v2, v3, vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG1,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG2
};

static discrete_op_amp_osc_info const spacwalk_sb_hit_vco =
{
	DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON,
	RES_K(330 + 150 + 30), SPACWALK_R203, SPACWALK_R201, SPACWALK_R204, // r1, r2, r3, r4
	SPACWALK_R202, 0, SPACWALK_R200, 0,                                 // r5, r6, r7, r8
	SPACWALK_C200, 12                                                   // c, vP
};

static discrete_op_amp_tvca_info const spacwalk_sb_hit_tvca_info =
{
	SPACWALK_R207, SPACWALK_R205, 0, SPACWALK_R208,                     // r1, r2, r3, r4
	SPACWALK_RJ3, 0, SPACWALK_R206,                                     // r5, r6, r7
	0, 0, 0, 0                  ,                                       // r8, r9, r10, r11
	SPACWALK_C201, 0, 0, 0,                                             // c1, c2, c3, c4
	5, 0, 0, 12,                                                        // v1, v2, v3, vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_integrate_info const spacwalk_sb_miss_integrate =
{
	DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON,
	SPACWALK_R406, SPACWALK_R401, 0, SPACWALK_C402,                     // r1, r2, r3, c
	12, 12,                                                             // v1, vP
	0, 0, 0                                                             // f0, f1, f2
};

static discrete_op_amp_osc_info const spacwalk_sb_miss_vco =
{
	DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,
	SPACWALK_R407, SPACWALK_R412, SPACWALK_R410, SPACWALK_R411, SPACWALK_R413, 0, 0, 0, // r1, r2, r3, r4, r5, r6, r7, r8
	SPACWALK_C403, 12                                                   // c, vP
};

static discrete_op_amp_filt_info const spacwalk_sb_miss_filter =
{
	// we use r1, not r2 because vref is taken into acount by the CRFILTER
	SPACWALK_R417, 0, SPACWALK_R414, 0, SPACWALK_R416,                  // r1, r2, r3, r4, rF
	SPACWALK_C451, SPACWALK_C452, 0,                                    // c1, c2, c3
	0, 12, 0                                                            // vRef, vP, vN
};

static discrete_op_amp_info const spacwalk_sb_miss_amp =
{
	DISC_OP_AMP_IS_NORTON,
	SPACWALK_R418, SPACWALK_R404, 0, SPACWALK_R403, /* r1, r2, r3, r4 */
	0,  /* c */
	0, 12,  /* vN, vP */
};

static discrete_op_amp_osc_info const spacwalk_spaceship_osc =
{
	DISC_OP_AMP_OSCILLATOR_2 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	RES_K(75), RES_M(1), RES_M(6.8), RES_M(2.4), 0, 0, 0, 0,            // r1, r2, r3, r4, r5, r6, r7, r8
	CAP_U(2.2), 12                                                      // c, vP
};

static discrete_op_amp_osc_info const spacwalk_spaceship_vco =
{
	DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	RES_K(680), RES_K(300), RES_K(100), RES_K(150), RES_K(120), 0, 0, 0,    // r1, r2, r3, r4, r5, r6, r7, r8
	CAP_U(0.0012), 12                                                   // c, vP
};

static discrete_mixer_desc const spacwalk_mixer =
{
	DISC_MIXER_IS_RESISTOR,
	{SPACWALK_R422, SPACWALK_R422, RES_K(39 + 10 + 1), SPACWALK_R421, SPACWALK_R420, SPACWALK_R419},
	{0, 0, 0, 0, 0, SPACWALK_R507_POT},                                 // r_nodes
	{0}, 0, 0, 0, SPACWALK_C602, 0, 1                                   // c, rI, rF, cF, cAmp, vRef, gain
};


/************************************************
 * Springboard Hit Circuit   1 or 2
 ************************************************/
#define SPACWALK_SPRINGBOARD_HIT_CIRCUIT(_num)                                                          \
		DISCRETE_RCFILTER(NODE_RELATIVE(NODE_29, _num),                                                 \
				SPACWALK_NOISE,                                                 /* IN0 */               \
				RES_K(330), CAP_U(.1))                                                                  \
		DISCRETE_RCFILTER(NODE_RELATIVE(NODE_31, _num),                                                 \
				NODE_RELATIVE(NODE_29, _num),                                   /* IN0 */               \
				RES_K(330) + RES_K(150), CAP_U(.1))                                                     \
		DISCRETE_OP_AMP_VCO1(NODE_RELATIVE(NODE_33, _num),                      /* IC M2-3, pin 5 */    \
				1,                                                              /* ENAB */              \
				NODE_RELATIVE(NODE_31, _num),                                   /* VMOD1 */             \
				&spacwalk_sb_hit_vco)                                                                   \
		DISCRETE_OP_AMP_TRIG_VCA(NODE_RELATIVE(NODE_35, _num),                  /* IC M2-3, pin 9 */    \
				NODE_RELATIVE(SPACWALK_SPRINGBOARD_HIT1_EN, _num - 1), 0, 0,    /* TRG0, TRG1, TRG2 */  \
				NODE_RELATIVE(NODE_33, _num), 0,                                /* IN0, IN1 */          \
				&spacwalk_sb_hit_tvca_info)                                                             \
		/* Wrong values.  Untested */                                                                   \
		/* The rest of the circuit is a filter. */                                                      \
		DISCRETE_FILTER2(NODE_RELATIVE(NODE_37, _num),                                                  \
				1,                                                              /* ENAB */              \
				NODE_RELATIVE(NODE_35, _num),                                   /* INP0 */              \
				2000.0 - _num * 500, 1.0/.8,                                    /* FREQ, DAMP */        \
				DISC_FILTER_LOWPASS)                                                                    \
		/* The filter has a gain of 0.5 */                                                              \
		DISCRETE_GAIN(NODE_RELATIVE(SPACWALK_SPRINGBOARD_HIT1_SND, _num - 1),                           \
				NODE_RELATIVE(NODE_37, _num), 0.5)

static DISCRETE_SOUND_START(spacwalk_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC(SPACWALK_TARGET_HIT_BOTTOM_EN)
	DISCRETE_INPUT_LOGIC(SPACWALK_TARGET_HIT_MIDDLE_EN)
	DISCRETE_INPUT_LOGIC(SPACWALK_TARGET_HIT_TOP_EN)
	DISCRETE_INPUT_LOGIC(SPACWALK_SPRINGBOARD_HIT1_EN)
	DISCRETE_INPUT_LOGIC(SPACWALK_SPRINGBOARD_HIT2_EN)
	DISCRETE_INPUT_LOGIC(SPACWALK_SPRINGBOARD_MISS_EN)
	DISCRETE_INPUT_LOGIC(SPACWALK_SPACE_SHIP_EN)

	// The low value of the pot is set to 7000.  A real 1M pot will never go to 0 anyways.
	// This will give the control more apparent volume range.
	// The music way overpowers the rest of the sounds anyways.
	DISCRETE_ADJUSTMENT(SPACWALK_R507_POT, SPACWALK_R507, 7000, DISC_LOGADJ, "R507")

	/************************************************
	 * Tone generator
	 ************************************************/
	MIDWAY_TONE_GENERATOR(midway_music_tvca_info)

	/************************************************
	 * Target hit sounds
	 * The LFSR is the same as boothill
	 ************************************************/
	// Noise clock was breadboarded and measured at 7700Hz
	DISCRETE_LFSR_NOISE(SPACWALK_NOISE,             // IC L4, pin 10
			1, 1,                                   // ENAB, RESET
			7700, 12.0, 0, 12.0/2, &midway_lfsr)    // CLK,AMPL,FEED,BIAS,LFSRTB

	DISCRETE_OP_AMP_TRIG_VCA(NODE_20,               // IC K3, pin 9
			SPACWALK_TARGET_HIT_TOP_EN, SPACWALK_TARGET_HIT_MIDDLE_EN, SPACWALK_TARGET_HIT_BOTTOM_EN,
			SPACWALK_NOISE, 0,                      // IN0, IN1
			&spacwalk_hit_tvca_info)
	DISCRETE_RCFILTER(NODE_21,
			NODE_20,                                // IN0
			SPACWALK_R307, SPACWALK_C303)
	DISCRETE_RCFILTER(SPACWALK_TARGET_HIT_SND,
			NODE_21,                                // IN0
			SPACWALK_R307 + SPACWALK_R308, SPACWALK_C304)

	/************************************************
	 * Springboard hit sounds
	 ************************************************/
	/* Nodes 30 - 40 */
	SPACWALK_SPRINGBOARD_HIT_CIRCUIT(1)
	SPACWALK_SPRINGBOARD_HIT_CIRCUIT(2)

	/************************************************
	 * Springboard miss sound
	 ************************************************/
	DISCRETE_RCDISC2(NODE_50,                       // voltage on C401
			SPACWALK_SPRINGBOARD_MISS_EN,           // SWITCH
			OP_AMP_NORTON_VBE, RES_2_PARALLEL(SPACWALK_R401, SPACWALK_R407),    // INP0,RVAL0
			12.0 - .5, SPACWALK_R400,               // INP1,RVAL1
			SPACWALK_C401)
	DISCRETE_INTEGRATE(NODE_51,                     // IC K4, pin 9
			NODE_50, 0,                             // TRG0,TRG1
			&spacwalk_sb_miss_integrate)
	DISCRETE_OP_AMP_VCO1(NODE_52,                   // IC K4, pin 5
			1,                                      // ENAB
			NODE_50,                                // VMOD1
			&spacwalk_sb_miss_vco)
	DISCRETE_CRFILTER(NODE_53,
			NODE_52,                                // IN0
			SPACWALK_R417, SPACWALK_C453)
	// this filter type probably does not work right. I need to test it.
	DISCRETE_OP_AMP_FILTER(NODE_54,                 // IC K3, pin 5
			1,                                      // ENAB
			NODE_53, 0,                             // INP0,INP1
			DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON, &spacwalk_sb_miss_filter)
	DISCRETE_OP_AMP(SPACWALK_SPRINGBOARD_MISS_SND,  // IC K4, pin 10
			1,                                      // ENAB
			NODE_54, NODE_51,                       // IN0,IN1
			&spacwalk_sb_miss_amp)

	/************************************************
	 * Space ship sound
	 ************************************************/
	DISCRETE_OP_AMP_OSCILLATOR(NODE_60,             // voltage on 2.2uF cap near IC JK-2
			1,                                      // ENAB
			&spacwalk_spaceship_osc)
	DISCRETE_OP_AMP_VCO1(NODE_61,                   // IC JK-2, pin 5
			SPACWALK_SPACE_SHIP_EN,                 // ENAB
			NODE_60,                                // VMOD1
			&spacwalk_spaceship_vco)
	DISCRETE_RCFILTER(NODE_62,
			NODE_61,                                // IN0
			RES_K(1), CAP_U(0.15))
	DISCRETE_RCFILTER(SPACWALK_SPACE_SHIP_SND,
			NODE_62,                                // IN0
			RES_K(1) + RES_K(10), CAP_U(0.015))

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	DISCRETE_MIXER6(NODE_90,
			1,                                      // ENAB
			SPACWALK_SPRINGBOARD_HIT1_SND,
			SPACWALK_SPRINGBOARD_HIT2_SND,
			SPACWALK_SPACE_SHIP_SND,
			SPACWALK_SPRINGBOARD_MISS_SND,
			SPACWALK_TARGET_HIT_SND,
			MIDWAY_TONE_SND,
			&spacwalk_mixer)
	DISCRETE_OUTPUT(NODE_90, 11000)
DISCRETE_SOUND_END

static INPUT_PORTS_START(spacwalk_audio)
	PORT_START("R507")
	PORT_ADJUSTER( 40, "R507 - Music Volume" )
INPUT_PORTS_END

spacwalk_audio_device::spacwalk_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	midway_tone_generator_device_base(mconfig, SPACWALK_AUDIO, tag, owner, clock),
	m_ctrl_sel_out(*this),
	m_p1(0U)
{
}

void spacwalk_audio_device::p1_w(u8 data)
{
	u8 const changed(data ^ m_p1);
	m_p1 = data;

	machine().bookkeeping().coin_counter_w(0, BIT(data, 0));

	if (BIT(changed, 1)) m_ctrl_sel_out(BIT(data, 1));

	machine().sound().system_enable(BIT(data, 2));

	m_discrete->write(SPACWALK_SPACE_SHIP_EN, (data >> 3) & 0x01);
}

void spacwalk_audio_device::p2_w(u8 data)
{
	m_discrete->write(SPACWALK_TARGET_HIT_BOTTOM_EN, (data >> 0) & 0x01);
	m_discrete->write(SPACWALK_TARGET_HIT_MIDDLE_EN, (data >> 1) & 0x01);
	m_discrete->write(SPACWALK_TARGET_HIT_TOP_EN, (data >> 2) & 0x01);
	m_discrete->write(SPACWALK_SPRINGBOARD_HIT1_EN, (data >> 3) & 0x01);
	m_discrete->write(SPACWALK_SPRINGBOARD_HIT2_EN, (data >> 4) & 0x01);
	m_discrete->write(SPACWALK_SPRINGBOARD_MISS_EN, (data >> 5) & 0x01);
}

void spacwalk_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "mono").front_center();

	DISCRETE(config, m_discrete, spacwalk_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0);
}

ioport_constructor spacwalk_audio_device::device_input_ports() const
{
	return INPUT_PORTS_NAME(spacwalk_audio);
}

void spacwalk_audio_device::device_start()
{
	m_ctrl_sel_out.resolve();

	m_p1 = 0U;

	save_item(NAME(m_p1));
}


/*************************************
 *
 *  Dog Patch
 *
 *  Discrete sound emulation:
 *   Sept 2011, D.R.
 *
 *************************************/

// nodes - inputs
#define DOGPATCH_GAME_ON_EN         NODE_01
#define DOGPATCH_LEFT_SHOT_EN       NODE_02
#define DOGPATCH_RIGHT_SHOT_EN      NODE_03
#define DOGPATCH_HIT_EN             NODE_04
#define DOGPATCH_PAN_DATA           NODE_05

// nodes - sounds
#define DOGPATCH_NOISE              NODE_06
#define DOGPATCH_L_SHOT_SND         NODE_07
#define DOGPATCH_R_SHOT_SND         NODE_08
#define DOGPATCH_HIT_SND            NODE_09
#define DOGPATCH_L_HIT_SND          NODE_10
#define DOGPATCH_R_HIT_SND          NODE_11

static discrete_op_amp_tvca_info const dogpatch_shot_tvca_info =
{
	RES_M(2.7),
	RES_K(510),
	0,
	RES_K(510),
	RES_K(10),
	0,
	RES_K(510),
	0,
	0,
	0,
	0,
	CAP_U(0.22),
	0,
	0, 0,
	12,
	0,
	0,
	12,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE
};

static discrete_mixer_desc const dogpatch_l_mixer =
{
	DISC_MIXER_IS_OP_AMP,
	{ RES_K(12) + RES_K(68) + RES_K(33),
		RES_K(33) },
	{ 0 },
	{ 0 },
	0,
	RES_K(100),
	0,
	CAP_U(0.1),
	0,
	1               // final gain
};

static discrete_mixer_desc const dogpatch_r_mixer =
{
	DISC_MIXER_IS_OP_AMP,
	{ RES_K(12) + RES_K(68) + RES_K(33),
		RES_K(33),
		RES_K(510) + RES_K(33) },
	{ 0 },
	{ 0 },
	0,
	RES_K(100),
	0,
	CAP_U(0.1),
	0,
	1               // final gain
};

static DISCRETE_SOUND_START(dogpatch_discrete)
	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC(DOGPATCH_GAME_ON_EN)
	DISCRETE_INPUT_LOGIC(DOGPATCH_LEFT_SHOT_EN)
	DISCRETE_INPUT_LOGIC(DOGPATCH_RIGHT_SHOT_EN)
	DISCRETE_INPUT_LOGIC(DOGPATCH_HIT_EN)

	/************************************************
	 * Tone generator
	 ************************************************/
	MIDWAY_TONE_GENERATOR(midway_music_tvca_info)

	// Noise clock was breadboarded and measured at 7700Hz
	DISCRETE_LFSR_NOISE(DOGPATCH_NOISE, 1, 1, 7700, 12.0, 0, 12.0/2, &midway_lfsr)

	/************************************************
	 * Shot sounds
	 ************************************************/
	DISCRETE_OP_AMP_TRIG_VCA(NODE_20, DOGPATCH_LEFT_SHOT_EN, 0, 0, DOGPATCH_NOISE, 0, &dogpatch_shot_tvca_info)
	DISCRETE_RCFILTER(NODE_21, NODE_20, RES_K(12), CAP_U(.01))
	DISCRETE_RCFILTER(DOGPATCH_L_SHOT_SND, NODE_21, RES_K(12) + RES_K(68), CAP_U(.0022))

	DISCRETE_OP_AMP_TRIG_VCA(NODE_30, DOGPATCH_RIGHT_SHOT_EN, 0, 0, DOGPATCH_NOISE, 0, &dogpatch_shot_tvca_info)
	DISCRETE_RCFILTER(NODE_31, NODE_30, RES_K(12), CAP_U(.01))
	DISCRETE_RCFILTER(DOGPATCH_R_SHOT_SND, NODE_31, RES_K(12) + RES_K(68), CAP_U(.0033))

	/************************************************
	 * Target hit sounds
	 ************************************************/
	DISCRETE_CONSTANT(DOGPATCH_L_HIT_SND, 0)
	DISCRETE_CONSTANT(DOGPATCH_R_HIT_SND, 0)

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	/* There is a 1uF cap on the input to the amp that I was too lazy to simulate.
	 * It is just a DC blocking cap needed by the Norton amp.  Doing the extra
	 * work to simulate it is not going to make a difference to the waveform
	 * or to how it sounds.  Also I use a regular amp in place of the Norton
	 * for the same reasons.  Ease of coding/simulation. */

	DISCRETE_MIXER2(NODE_91, DOGPATCH_GAME_ON_EN, DOGPATCH_L_SHOT_SND, DOGPATCH_L_HIT_SND, &dogpatch_l_mixer)

	// Music is only added to the right channel per schematics
	// This should be verified on the real game
	DISCRETE_MIXER3(NODE_92, DOGPATCH_GAME_ON_EN, DOGPATCH_R_SHOT_SND, DOGPATCH_R_HIT_SND, MIDWAY_TONE_SND, &dogpatch_r_mixer)

	DISCRETE_OUTPUT(NODE_91, 32760.0 / 5.8)
	DISCRETE_OUTPUT(NODE_92, 32760.0 / 5.8)
DISCRETE_SOUND_END

dogpatch_audio_device::dogpatch_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	midway_tone_generator_device_base(mconfig, DOGPATCH_AUDIO, tag, owner, clock)
{
}

void dogpatch_audio_device::write(u8 data)
{
	// D0, D1 and D7 are not used

	machine().bookkeeping().coin_counter_w(0, BIT(data, 2));

	machine().sound().system_enable(BIT(data, 3));
	m_discrete->write(DOGPATCH_GAME_ON_EN, BIT(data, 3));

	m_discrete->write(DOGPATCH_LEFT_SHOT_EN, BIT(data, 4));

	m_discrete->write(DOGPATCH_RIGHT_SHOT_EN, BIT(data, 5));

	m_discrete->write(DOGPATCH_HIT_EN, BIT(data, 6));
}

void dogpatch_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	DISCRETE(config, m_discrete, dogpatch_discrete);
	m_discrete->add_route(0, "lspeaker", 1.0);
	m_discrete->add_route(1, "rspeaker", 1.0);
}

void dogpatch_audio_device::device_start()
{
}


/*************************************
 *
 *  Space Encounters
 *
 *  Discrete sound emulation:
 *  Apr 2007, D.R.
 *************************************/

// nodes - inputs
#define SPCENCTR_ENEMY_SHIP_SHOT_EN       NODE_01
#define SPCENCTR_PLAYER_SHOT_EN           NODE_02
#define SPCENCTR_SCREECH_EN               NODE_03
#define SPCENCTR_CRASH_EN                 NODE_04
#define SPCENCTR_EXPLOSION_EN             NODE_05
#define SPCENCTR_BONUS_EN                 NODE_06
#define SPCENCTR_WIND_DATA                NODE_07

// nodes - sounds
#define SPCENCTR_NOISE                    NODE_10
#define SPCENCTR_ENEMY_SHIP_SHOT_SND      NODE_11
#define SPCENCTR_PLAYER_SHOT_SND          NODE_12
#define SPCENCTR_SCREECH_SND              NODE_13
#define SPCENCTR_CRASH_SND                NODE_14
#define SPCENCTR_EXPLOSION_SND            NODE_15
#define SPCENCTR_BONUS_SND                NODE_16
#define SPCENCTR_WIND_SND                 NODE_17

static discrete_op_amp_info const spcenctr_enemy_ship_shot_op_amp_E1 =
{
	DISC_OP_AMP_IS_NORTON,
	0,                      // no r1
	RES_K(510),             // R100
	RES_M(2.2),             // R101
	RES_M(2.2),             // R102
	CAP_U(0.1),             // C100
	0,                      // vN
	12                      // vP
};

static discrete_op_amp_osc_info const spcenctr_enemy_ship_shot_op_amp_osc =
{
	DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,
	RES_K(560),             // R103
	RES_K(7.5),             // R118
	RES_K(22),              // R104
	RES_K(47),              // R106
	RES_K(100),             // R105
	0,                      // no r6
	0,                      // no r7
	0,                      // no r8
	CAP_U(0.0022),          // C101
	12,                     // vP
};


static discrete_op_amp_info const spcenctr_enemy_ship_shot_op_amp_D1 =
{
	DISC_OP_AMP_IS_NORTON,
	RES_K(100),             // R107
	RES_K(100),             // R109
	RES_M(2.7),             // R108
	RES_K(100),             // R110
	0,                      // no c
	0,                      // vN
	12                      // vP
};

static discrete_op_amp_filt_info const spcenctr_enemy_ship_shot_filt =
{
	RES_K(100),             // R112
	RES_K(10),              // R113
	RES_M(4.3),             // r3
	0,                      // no r4
	RES_M(2.2),             // R114
	CAP_U(0.001),           // c1
	CAP_U(0.001),           // c2
	0,                      // no c3
	0,                      // vRef
	12,                     // vP
	0                       // vN
};

static discrete_op_amp_1sht_info const spcenctr_player_shot_1sht =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(4.7),             // R500
	RES_K(100),             // R502
	RES_M(1),               // R501
	RES_M(1),               // R503
	RES_M(2.2),             // R504
	CAP_U(1),               // C500
	CAP_P(470),             // C501
	0,                      // vN
	12                      // vP
};

static discrete_op_amp_info const spcenctr_player_shot_op_amp_E1 =
{
	DISC_OP_AMP_IS_NORTON,
	0,                      // no r1
	RES_K(10),              // R505
	RES_M(1.5),             // R506
	0,                      // no r4
	CAP_U(0.22),            // C502
	0,                      // vN
	12                      // vP
};

static discrete_op_amp_osc_info const spcenctr_player_shot_op_amp_osc =
{
	DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,
	1.0 / (1.0 / RES_M(1) + 1.0 / RES_K(330)) + RES_M(1.5),     // R507||R509 + R508
	RES_M(1),               // R513
	RES_K(560),             // R512
	RES_M(2.7),             // R516
	RES_M(1),               // R515
	RES_M(4.7),             // R510
	RES_M(3.3),             // R511
	0,                      // no r8
	CAP_P(330),             // C504
	12,                     // vP
};

static discrete_op_amp_info const spcenctr_player_shot_op_amp_C1 =
{
	DISC_OP_AMP_IS_NORTON,
	RES_K(560),             // R517
	RES_K(470),             // R514
	RES_M(2.7),             // R518
	RES_K(560),             // R524
	0,                      // no c
	0,                      // vN
	12                      // vP
};

static discrete_op_amp_tvca_info const spcenctr_player_shot_tvca =
{
	RES_M(2.7),                         // R522
	RES_K(560),                         // R521
	0,                                  // no r3
	RES_K(560),                         // R560
	RES_K(1),                           // R42
	0,                                  // no r6
	RES_K(560),                         // R523
	0,                                  // no r8
	0,                                  // no r9
	0,                                  // no r10
	0,                                  // no r11
	CAP_U(1),                           // C506
	0,                                  // no c2
	0, 0,                               // no c3, c4
	12,                                 // v1
	0,                                  // no v2
	0,                                  // no v3
	12,                                 // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f0
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f1
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,  // f2
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f3
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f4
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE   // no f5
};

static discrete_op_amp_tvca_info const spcenctr_crash_tvca =
{
	RES_M(2.7),                         // R302
	RES_K(470),                         // R300
	0,                                  // no r3
	RES_K(470),                         // R303
	RES_K(1),                           // R56
	0,                                  // no r6
	RES_K(470),                         // R301
	0,                                  // no r8
	0,                                  // no r9
	0,                                  // no r10
	0,                                  // no r11
	CAP_U(2.2),                         // C304
	0,                                  // no c2
	0, 0,                               // no c3, c4
	5,                                  // v1
	0,                                  // no v2
	0,                                  // no v3
	12,                                 // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f0
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f1
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,  // f2
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f3
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f4
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE   // no f5
};

static discrete_op_amp_tvca_info const spcenctr_explosion_tvca =
{
	RES_M(2.7),                         // R402
	RES_K(680),                         // R400
	0,                                  // no r3
	RES_K(680),                         // R403
	RES_K(1),                           // R41
	0,                                  // no r6
	RES_K(680),                         // R401
	0,                                  // no r8
	0,                                  // no r9
	0,                                  // no r10
	0,                                  // no r11
	CAP_U(2.2),                         // C400
	0,                                  // no c2
	0, 0,                               // no c3, c4
	12,                                 // v1
	0,                                  // no v2
	0,                                  // no v3
	12,                                 // vP
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f0
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f1
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,  // f2
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f3
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  // no f4
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE   // no f5
};

static const discrete_555_desc spcenctr_555_bonus =
{
	DISC_555_OUT_SQW | DISC_555_OUT_DC,
	5,                      // B+ voltage of 555
	DEFAULT_555_VALUES
};

static const discrete_mixer_desc spcenctr_mixer =
{
	DISC_MIXER_IS_RESISTOR, // type
	{ RES_K(15),            // R117
		RES_K(15),          // R526
		RES_K(22),          // R211
		RES_K(3.6),         // R309
		RES_K(1.8) +  RES_K(3.6) + RES_K(4.7),  // R405 + R406 + R407
		RES_K(27),          // R715
		RES_K(27)},         // R51
	{0},                    // no rNode{}
	{ 0,
		CAP_U(0.001),       // C505
		CAP_U(0.1),         // C202
		CAP_U(1),           // C303
		0,
		0,
		CAP_U(10)},         // C16
	0,                      // no rI
	0,                      // no rF
	0,                      // no cF
	CAP_U(1),               // C900
	0,                      // vRef = ground
	1                       // gain
};

static DISCRETE_SOUND_START(spcenctr_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUTX_LOGIC(SPCENCTR_ENEMY_SHIP_SHOT_EN, 12, 0, 0)
	DISCRETE_INPUTX_LOGIC(SPCENCTR_PLAYER_SHOT_EN, 12, 0, 0)
	DISCRETE_INPUT_LOGIC (SPCENCTR_SCREECH_EN)
	DISCRETE_INPUT_LOGIC (SPCENCTR_CRASH_EN)
	DISCRETE_INPUT_LOGIC (SPCENCTR_EXPLOSION_EN)
	DISCRETE_INPUT_LOGIC (SPCENCTR_BONUS_EN)
	DISCRETE_INPUT_DATA  (SPCENCTR_WIND_DATA)

	/************************************************
	 * Noise Generator
	 ************************************************/
	// Noise clock was breadboarded and measured at 7515
	DISCRETE_LFSR_NOISE(SPCENCTR_NOISE,                 // IC A0, pin 10
			1,                                          // ENAB
			1,                                          // no RESET
			7515,                                       // CLK in Hz
			12,                                         // p-p AMPL
			0,                                          // no FEED input
			12.0/2,                                     // dc BIAS
			&midway_lfsr)

	/************************************************
	 * Enemy Ship Shot
	 ************************************************/
	DISCRETE_OP_AMP(NODE_20,                            // IC E1, pin 10
			1,                                          // ENAB
			0,                                          // no IN0
			SPCENCTR_ENEMY_SHIP_SHOT_EN,                // IN1
			&spcenctr_enemy_ship_shot_op_amp_E1)
	DISCRETE_OP_AMP_VCO1(NODE_21,                       // IC D1, pin 5
			1,                                          // ENAB
			NODE_20,                                    // VMOD1
			&spcenctr_enemy_ship_shot_op_amp_osc)
	DISCRETE_OP_AMP(NODE_22,                            // IC D1, pin 9
			1,                                          // ENAB
			NODE_21,                                    // IN0
			NODE_20,                                    // IN1
			&spcenctr_enemy_ship_shot_op_amp_D1)
	DISCRETE_OP_AMP_FILTER(NODE_23,                     // IC D1, pin 10
			1,                                          // ENAB
			NODE_22,                                    // INP0
			0,                                          // no INP1
			DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON,
			&spcenctr_enemy_ship_shot_filt)
	DISCRETE_CRFILTER(SPCENCTR_ENEMY_SHIP_SHOT_SND,
			NODE_23,                                    // IN0
			RES_K(1.8),                                 // R116
			CAP_U(0.1) )                                // C104

	/************************************************
	 * Player Shot
	 ************************************************/
	DISCRETE_OP_AMP_ONESHOT(NODE_30,                    // IC E1, pin 4
			SPCENCTR_PLAYER_SHOT_EN,                    // TRIG
			&spcenctr_player_shot_1sht)                 // breadboarded and scoped at 325mS
	DISCRETE_OP_AMP(NODE_31,                            // IC E1, pin 5
			1,                                          // ENAB
			0,                                          // no IN0
			NODE_30,                                    // IN1
			&spcenctr_player_shot_op_amp_E1)
	// next 2 modules simulate the D502 voltage drop
	DISCRETE_ADDER2(NODE_32,
			1,                                          // ENAB
			NODE_31,                                    // IN0
			-0.5)                                       // IN1
	DISCRETE_CLAMP(NODE_33,
			NODE_32,                                    // IN0
			0,                                          // MIN
			12)                                         // MAX
	DISCRETE_CRFILTER(NODE_34,
			SPCENCTR_NOISE,                             // IN0
			RES_M(1) + RES_K(330),                      // R507, R509
			CAP_U(0.1) )                                // C503
	DISCRETE_GAIN(NODE_35,
			NODE_34,                                    // IN0
			RES_K(330)/(RES_M(1) + RES_K(330)))         // GAIN - R507 : R509
	DISCRETE_OP_AMP_VCO2(NODE_36,                       // IC C1, pin 4
			1,                                          // ENAB
			NODE_35,                                    // VMOD1
			NODE_33,                                    // VMOD2
					&spcenctr_player_shot_op_amp_osc)
	DISCRETE_OP_AMP(NODE_37,                            // IC C1, pin 9
			1,                                          // ENAB
			NODE_36,                                    // IN0
			NODE_33,                                    // IN1
			&spcenctr_player_shot_op_amp_C1)
	DISCRETE_OP_AMP_TRIG_VCA(SPCENCTR_PLAYER_SHOT_SND,  // IC C1, pin 10
			SPCENCTR_PLAYER_SHOT_EN,                    // TRG0
			0,                                          // no TRG1
			0,                                          // no TRG2
			NODE_37,                                    // IN0
			0,                                          // no IN1
			&spcenctr_player_shot_tvca)

	/************************************************
	 *Screech - unemulated
	 ************************************************/
	DISCRETE_CONSTANT(SPCENCTR_SCREECH_SND, 0)

	/************************************************
	 * Crash
	 ************************************************/
	DISCRETE_OP_AMP_TRIG_VCA(NODE_60,                   // IC C2, pin 4
			SPCENCTR_CRASH_EN,                          // TRG0
			0,                                          // no TRG1
			0,                                          // no TRG2
			SPCENCTR_NOISE,                             // IN0
			0,                                          // no IN1
			&spcenctr_crash_tvca)
	// The next 5 modules emulate the filter.
	// The DC level was breadboarded and the frequency response was SPICEd
	DISCRETE_ADDER2(NODE_61,                            // center on filter DC level
			1,                                          // ENAB
			NODE_60,                                    // IN0
			-6.8)                                       // IN1
	DISCRETE_FILTER2(NODE_62,
			1,                                          // ENAB
			NODE_61,                                    // INP0
			130,                                        // FREQ
			1.0 / 8,                                    // DAMP
			DISC_FILTER_BANDPASS)
	DISCRETE_GAIN(NODE_63,
			NODE_62,                                    // IN0
			6)                                          // GAIN
	DISCRETE_ADDER2(NODE_64,                                    // center on filter DC level
			1,                                          // ENAB
			NODE_63,                                    // IN0
			6.8)                                        // IN1
	DISCRETE_CLAMP(SPCENCTR_CRASH_SND,                          // IC C2, pin 5
			NODE_64,                                    // IN0
			0,                                          // MIN
			12.0 - OP_AMP_NORTON_VBE)                   // MAX

	/************************************************
	 * Explosion
	 ************************************************/
	DISCRETE_OP_AMP_TRIG_VCA(NODE_70,                   // IC D2, pin 10
			SPCENCTR_EXPLOSION_EN,                      // TRG0
			0,                                          // no TRG1
			0,                                          // no TRG2
			SPCENCTR_NOISE,                             // IN0
			0,                                          // no IN1
			&spcenctr_explosion_tvca)
	DISCRETE_RCFILTER(NODE_71,
			NODE_70,                                    // IN0
			RES_K(1.8),                                 // R405
			CAP_U(0.22) )                               // C401
	DISCRETE_RCFILTER(SPCENCTR_EXPLOSION_SND,
			NODE_71,                                    // IN0
			RES_K(1.8) + RES_K(3.6),                    // R405 + R406
			CAP_U(0.22) )                               // C402

	/************************************************
	 *Bonus
	 ************************************************/
	DISCRETE_555_ASTABLE(NODE_80,                       // pin 5
			// the pin 4 reset is not connected in schematic, but should be
			SPCENCTR_BONUS_EN,                          // RESET
			RES_K(1),                                   // R710
			RES_K(27),                                  // R711
			CAP_U(0.047),                               // C710
			&spcenctr_555_bonus)
	DISCRETE_555_ASTABLE(NODE_81,                       // pin 9
			SPCENCTR_BONUS_EN,                          // RESET pin 10
			RES_K(100),                                 // R713
			RES_K(47),                                  // R714
			CAP_U(1),                                   // C713
			&spcenctr_555_bonus)
	DISCRETE_LOGIC_AND3(NODE_82,                        // IC C-D, pin 6
			NODE_80,                                    // INP0
			NODE_81,                                    // INP1
			SPCENCTR_BONUS_EN)                          // INP2
	DISCRETE_GAIN(SPCENCTR_BONUS_SND,                   // adjust from logic to TTL voltage level
			NODE_82,                                    // IN0
			DEFAULT_TTL_V_LOGIC_1)                      // GAIN

	/************************************************
	 *Wind - unemulated
	 ************************************************/
	DISCRETE_CONSTANT(SPCENCTR_WIND_SND, 0)

	/************************************************
	 * Final mix
	 ************************************************/
	DISCRETE_MIXER7(NODE_91,
			1,                                          // ENAB
			SPCENCTR_ENEMY_SHIP_SHOT_SND,               // IN0
			SPCENCTR_PLAYER_SHOT_SND,                   // IN1
			SPCENCTR_SCREECH_SND,                       // IN2
			SPCENCTR_CRASH_SND,                         // IN3
			SPCENCTR_EXPLOSION_SND,                     // IN4
			SPCENCTR_BONUS_SND,                         // IN5
			SPCENCTR_WIND_SND,                          // IN6
			&spcenctr_mixer)

	DISCRETE_OUTPUT(NODE_91, 20000)
DISCRETE_SOUND_END

spcenctr_audio_device::spcenctr_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, SPCENCTR_AUDIO, tag, owner, clock),
	m_sn(*this, "snsnd"),
	m_discrete(*this, "discrete"),
	m_lamp(*this, "LAMP"),
	m_strobe(*this, "STROBE"),
	m_strobe_timer(nullptr),
	m_strobe_enable(0U)
{
}

void spcenctr_audio_device::p1_w(u8 data)
{
	machine().sound().system_enable(BIT(data, 0));

	// D1 is marked as 'OPTIONAL SWITCH VIDEO FOR COCKTAIL', but it is never set by the software

	m_discrete->write(SPCENCTR_CRASH_EN, BIT(data, 2));

	// D3-D7 are not connected
}

void spcenctr_audio_device::p2_w(u8 data)
{
	// set WIND SOUND FREQ(data & 0x0f)  0, if no wind

	m_discrete->write(SPCENCTR_EXPLOSION_EN, BIT(data, 4));
	m_discrete->write(SPCENCTR_PLAYER_SHOT_EN, BIT(data, 5));

	// D6 and D7 are not connected
}


void spcenctr_audio_device::p3_w(u8 data)
{
	// if (data & 0x01)  enable SCREECH (hit the sides) sound

	m_discrete->write(SPCENCTR_ENEMY_SHIP_SHOT_EN, BIT(data, 1));

	m_strobe_enable = BIT(data, 2);

	m_lamp = BIT(data, 3);

	m_discrete->write(SPCENCTR_BONUS_EN, BIT(data, 4));

	m_sn->enable_w(BIT(data, 5));

	// D6 and D7 are not connected
}

void spcenctr_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "mono").front_center();

	SN76477(config, m_sn);
	m_sn->set_noise_params(0, 0, 0);
	m_sn->set_decay_res(0);
	m_sn->set_attack_params(0, RES_K(100));
	m_sn->set_amp_res(RES_K(56));
	m_sn->set_feedback_res(RES_K(10));
	m_sn->set_vco_params(0, CAP_U(0.047), RES_K(56));
	m_sn->set_pitch_voltage(5.0);
	m_sn->set_slf_params(CAP_U(1.0), RES_K(150));
	m_sn->set_oneshot_params(0, 0);
	m_sn->set_vco_mode(1);
	m_sn->set_mixer_params(0, 0, 0);
	m_sn->set_envelope_params(1, 0);
	m_sn->set_enable(1);
	m_sn->add_route(ALL_OUTPUTS, "mono", 0.20);

	DISCRETE(config, m_discrete, spcenctr_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 0.45);
}

void spcenctr_audio_device::device_start()
{
	m_lamp.resolve();
	m_strobe.resolve();

	m_strobe_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spcenctr_audio_device::strobe_callback), this));

	m_strobe_enable = 0U;

	save_item(NAME(m_strobe_enable));

	strobe_callback(nullptr, 0U);
}

TIMER_CALLBACK_MEMBER(spcenctr_audio_device::strobe_callback)
{
	constexpr double STROBE_FREQ = 9.00;    // Hz - calculated from the 555 timer
	constexpr u32 STROBE_DUTY_CYCLE = 95;   // %

	m_strobe = (param && m_strobe_enable) ? 1 : 0;
	m_strobe_timer->adjust(
			attotime::from_hz(STROBE_FREQ) * (param ? (100 - STROBE_DUTY_CYCLE) : STROBE_DUTY_CYCLE) / 100,
			param ? 0 : 1);
}


/*************************************
 *
 *  Phantom II
 *
 *************************************/

phantom2_audio_device::phantom2_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, PHANTOM2_AUDIO, tag, owner, clock),
	m_samples(*this, "samples"),
	m_exp(*this, "EXPLAMP"),
	m_p1(0U),
	m_p2(0U)
{
}

void phantom2_audio_device::p1_w(u8 data)
{
	u8 const rising(data & ~m_p1);
	m_p1 = data;

	if (BIT(rising, 0)) m_samples->start(0, 0); // PLAYER SHOT sound

	// if (data & 0x02)  enable ENEMY SHOT sound

	machine().sound().system_mute(!BIT(data, 5));
	machine().sound().system_enable(BIT(data, 2));

	machine().bookkeeping().coin_counter_w(0, BIT(data, 3));

	// if (data & 0x10)  enable RADAR sound

	// D5-D7 are not connected
}

void phantom2_audio_device::p2_w(u8 data)
{
	u8 const rising(data & ~m_p2);
	m_p2 = data;

	// D0-D2 are not connected

	if (BIT(rising, 3)) m_samples->start(1, 1); // enable EXPLOSION sound

	m_exp = BIT(data, 4);

	// set JET SOUND FREQ((data >> 5) & 0x07)  0, if no jet sound
}

void phantom2_audio_device::device_add_mconfig(machine_config &config)
{
	static char const *const sample_names[] = {
			"*phantom2",
			"1",        // shot
			"2",        // explosion
			nullptr };

	SPEAKER(config, "mono").front_center();

	SAMPLES(config, m_samples);
	m_samples->set_channels(2);
	m_samples->set_samples_names(sample_names);
	m_samples->add_route(ALL_OUTPUTS, "mono", 1.0);
}

void phantom2_audio_device::device_start()
{
	m_exp.resolve();

	m_p1 = 0U;
	m_p2 = 0U;

	save_item(NAME(m_p1));
	save_item(NAME(m_p2));
}


/*************************************
 *
 *  Space Invaders
 *
 *  Discrete sound emulation:
 *  Apr 2007, D.R.
 *
 *************************************/

static discrete_op_amp_1sht_info const invaders_invader_hit_1sht =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(4.7),     // R49
	RES_K(100),     // R51
	RES_M(1),       // R48
	RES_M(1),       // R50
	RES_M(2.2),     // R52
	CAP_U(0.1),     // C18
	CAP_P(470),     // C20
	0,              // vN
	12              // vP
};

static const discrete_op_amp_osc_info invaders_invader_hit_osc =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	RES_M(1),       // R37
	RES_K(10),      // R41
	RES_K(100),     // R38
	RES_K(120),     // R40
	RES_M(1),       // R39
	0,              // no r6
	0,              // no r7
	0,              // no r8
	CAP_U(0.1),     // C16
	12,             // vP
};

// Schematic M051-00739-A005 and M051-00739-B005
// P.C.      A084-90700-B000 and A084-90700-C000
static DISCRETE_SOUND_START(invaders_discrete)
	INVADERS_NOISE_GENERATOR
	INVADERS_SAUCER_HIT(1)
	INVADERS_FLEET(1)
	INVADERS_BONUS_MISSLE_BASE(1)
	INVADERS_INVADER_HIT(1, invaders)
	INVADERS_EXPLOSION(1)
	INVADERS_MISSILE(1, invaders)
	INVADERS_MIXER(1, invaders)
DISCRETE_SOUND_END

invaders_audio_device::invaders_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, INVADERS_AUDIO, tag, owner, clock),
	m_sn(*this, "snsnd"),
	m_discrete(*this, "discrete"),
	m_flip_screen_out(*this),
	m_p2(0U)
{
}

void invaders_audio_device::p1_w(u8 data)
{
	m_sn->enable_w(BIT(~data, 0));    // saucer sound

	m_discrete->write(INVADERS_NODE(INVADERS_MISSILE_EN, 1), data & 0x02);
	m_discrete->write(INVADERS_NODE(INVADERS_EXPLOSION_EN, 1), data & 0x04);
	m_discrete->write(INVADERS_NODE(INVADERS_INVADER_HIT_EN, 1), data & 0x08);
	m_discrete->write(INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, 1), data & 0x10);

	machine().sound().system_enable(data & 0x20);

	// D6 and D7 are not connected
}


void invaders_audio_device::p2_w(u8 data)
{
	u8 const changed(data ^ m_p2);
	m_p2 = data;

	m_discrete->write(INVADERS_NODE(INVADERS_FLEET_DATA, 1), data & 0x0f);
	m_discrete->write(INVADERS_NODE(INVADERS_SAUCER_HIT_EN, 1), data & 0x10);

	if (BIT(changed, 5)) m_flip_screen_out(BIT(data, 5));

	// D6 and D7 are not connected
}

void invaders_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "mono").front_center();

	SN76477(config, m_sn);
	m_sn->set_noise_params(0, 0, 0);
	m_sn->set_decay_res(0);
	m_sn->set_attack_params(0, RES_K(100));
	m_sn->set_amp_res(RES_K(56));
	m_sn->set_feedback_res(RES_K(10));
	m_sn->set_vco_params(0, CAP_U(0.1), RES_K(8.2));
	m_sn->set_pitch_voltage(5.0);
	m_sn->set_slf_params(CAP_U(1.0), RES_K(120));
	m_sn->set_oneshot_params(0, 0);
	m_sn->set_vco_mode(1);
	m_sn->set_mixer_params(0, 0, 0);
	m_sn->set_envelope_params(1, 0);
	m_sn->set_enable(1);
	m_sn->add_route(ALL_OUTPUTS, "mono", 0.5);

	DISCRETE(config, m_discrete, invaders_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 0.5);
}

void invaders_audio_device::device_start()
{
	m_flip_screen_out.resolve_safe();

	m_p2 = 0U;

	save_item(NAME(m_p2));
}


/*************************************
 *
 *  Space Invaders II (cocktail)
 *
 *************************************/

static discrete_op_amp_1sht_info const invad2ct_invader_hit_1sht =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(4.7),                 // R49
	RES_K(100),                 // R51
	RES_M(1),                   // R48
	RES_M(1),                   // R50
	RES_M(2.2),                 // R52
	CAP_U(0.22),                // C18
	CAP_P(470),                 // C20
	0,                          // vN
	12                          // vP
};

static discrete_op_amp_osc_info const invad2ct_invader_hit_osc =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	RES_M(1),                   // R37
	RES_K(10),                  // R41
	RES_K(100),                 // R38
	RES_K(120),                 // R40
	RES_M(1),                   // R39
	0,                          // no r6
	0,                          // no r7
	0,                          // no r8
	CAP_U(0.22),                // C16
	12,                         // vP
};

static discrete_op_amp_1sht_info const invad2ct_brd2_invader_hit_1sht =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(4.7),                 // R49
	RES_K(100),                 // R51
	RES_M(1),                   // R48
	RES_M(1),                   // R50
	RES_M(2.2),                 // R52
	CAP_U(1),                   // C18
	CAP_P(470),                 // C20
	0,                          // vN
	12                          // vP
};

static discrete_op_amp_osc_info const invad2ct_brd2_invader_hit_osc =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	RES_M(1),                   // R37
	RES_K(10),                  // R41
	RES_K(100),                 // R38
	RES_K(120),                 // R40
	RES_M(1),                   // R39
	0,                          // no r6
	0,                          // no r7
	0,                          // no r8
	CAP_U(0.1),                 // C16
	12,                         // vP
};

static discrete_op_amp_1sht_info const invad2ct_missle_1sht =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	RES_M(4.7),                 // R32
	RES_K(100),                 // R30
	RES_M(1),                   // R31
	RES_M(1),                   // R33
	RES_M(2.2),                 // R34
	CAP_U(0.22),                // C12
	CAP_P(470),                 // C15
	0,                          // vN
	12                          // vP
};

static discrete_mixer_desc const invad2ct_mixer =
{
	DISC_MIXER_IS_OP_AMP,       // type
	{ RES_K(100),               // R78
		RES_K(15) + 100 + 100,  // R134 + R133 + R132
		RES_K(150),             // R136
		RES_K(150),             // R59
		RES_K(10) + RES_K(6.8) + RES_K(5.6),    // R86 + R85 + R84
		RES_K(150) },           // R28
	{0},                        // no rNode{}
	{ 0,
		0,
		0,
		0,
		0,
		CAP_U(0.001) },         // C11
	0,                          // no rI
	RES_K(100),                 // R105
	0,                          // no cF
	CAP_U(0.1),                 // C45
	0,                          // vRef = ground
	1                           // gain
};

static DISCRETE_SOUND_START(invad2ct_discrete)
	// sound board 1
	// P.C. A082-90700-A000
	// Schematic M051-00851-A002
	INVADERS_NOISE_GENERATOR
	INVADERS_SAUCER_HIT(1)
	INVADERS_FLEET(1)
	INVADERS_BONUS_MISSLE_BASE(1)
	INVADERS_INVADER_HIT(1, invad2ct)
	INVADERS_EXPLOSION(1)
	INVADERS_MISSILE(1, invad2ct)
	INVADERS_MIXER(1, invad2ct)

	// sound board 2
	// P.C. A084-90901-C851
	// Schematic M051-00851-A005
	INVADERS_SAUCER_HIT(2)
	INVADERS_FLEET(2)
	INVADERS_BONUS_MISSLE_BASE(2)
	INVADERS_INVADER_HIT(2, invad2ct_brd2)
	INVADERS_EXPLOSION(2)
	INVADERS_MISSILE(2, invaders)
	INVADERS_MIXER(2, invaders)
DISCRETE_SOUND_END

invad2ct_audio_device::invad2ct_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
	device_t(mconfig, INVAD2CT_AUDIO, tag, owner, clock),
	m_discrete(*this, "discrete"),
	m_sn(*this, "sn%u", 1U)
{
}

void invad2ct_audio_device::p1_w(u8 data)
{
	m_sn[0]->enable_w(BIT(~data, 0));   // saucer sound

	m_discrete->write(INVADERS_NODE(INVADERS_MISSILE_EN, 1), data & 0x02);
	m_discrete->write(INVADERS_NODE(INVADERS_EXPLOSION_EN, 1), data & 0x04);
	m_discrete->write(INVADERS_NODE(INVADERS_INVADER_HIT_EN, 1), data & 0x08);
	m_discrete->write(INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, 1), data & 0x10);

	machine().sound().system_enable(data & 0x20);

	// D6 and D7 are not connected
}

void invad2ct_audio_device::p2_w(u8 data)
{
	m_discrete->write(INVADERS_NODE(INVADERS_FLEET_DATA, 1), data & 0x0f);
	m_discrete->write(INVADERS_NODE(INVADERS_SAUCER_HIT_EN, 1), data & 0x10);

	// D5-D7 are not connected
}

void invad2ct_audio_device::p3_w(u8 data)
{
	m_sn[1]->enable_w(BIT(~data, 0));   // saucer sound

	m_discrete->write(INVADERS_NODE(INVADERS_MISSILE_EN, 2), data & 0x02);
	m_discrete->write(INVADERS_NODE(INVADERS_EXPLOSION_EN, 2), data & 0x04);
	m_discrete->write(INVADERS_NODE(INVADERS_INVADER_HIT_EN, 2), data & 0x08);
	m_discrete->write(INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, 2), data & 0x10);

	// D5-D7 are not connected
}

void invad2ct_audio_device::p4_w(u8 data)
{
	m_discrete->write(INVADERS_NODE(INVADERS_FLEET_DATA, 2), data & 0x0f);
	m_discrete->write(INVADERS_NODE(INVADERS_SAUCER_HIT_EN, 2), data & 0x10);

	// D5-D7 are not connected
}

void invad2ct_audio_device::device_add_mconfig(machine_config &config)
{
	SPEAKER(config, "spk1").front_left();
	SPEAKER(config, "spk2").front_right();

	DISCRETE(config, m_discrete, invad2ct_discrete);
	m_discrete->add_route(0, "spk1", 0.5);
	m_discrete->add_route(1, "spk2", 0.5);

	SN76477(config, m_sn[0]);
	m_sn[0]->set_noise_params(0, 0, 0);
	m_sn[0]->set_decay_res(0);
	m_sn[0]->set_attack_params(0, RES_K(100));
	m_sn[0]->set_amp_res(RES_K(56));
	m_sn[0]->set_feedback_res(RES_K(10));
	m_sn[0]->set_vco_params(0, CAP_U(0.1), RES_K(8.2));
	m_sn[0]->set_pitch_voltage(5.0);
	m_sn[0]->set_slf_params(CAP_U(1.0), RES_K(120));
	m_sn[0]->set_oneshot_params(0, 0);
	m_sn[0]->set_vco_mode(1);
	m_sn[0]->set_mixer_params(0, 0, 0);
	m_sn[0]->set_envelope_params(1, 0);
	m_sn[0]->set_enable(1);
	m_sn[0]->add_route(ALL_OUTPUTS, "spk1", 0.3);

	SN76477(config, m_sn[1]);
	m_sn[1]->set_noise_params(0, 0, 0);
	m_sn[1]->set_decay_res(0);
	m_sn[1]->set_attack_params(0, RES_K(100));
	m_sn[1]->set_amp_res(RES_K(56));
	m_sn[1]->set_feedback_res(RES_K(10));
	m_sn[1]->set_vco_params(0, CAP_U(0.047),  RES_K(39));
	m_sn[1]->set_pitch_voltage(5.0);
	m_sn[1]->set_slf_params(CAP_U(1.0), RES_K(120));
	m_sn[1]->set_oneshot_params(0, 0);
	m_sn[1]->set_vco_mode(1);
	m_sn[1]->set_mixer_params(0, 0, 0);
	m_sn[1]->set_envelope_params(1, 0);
	m_sn[1]->set_enable(1);
	m_sn[1]->add_route(ALL_OUTPUTS, "spk2", 0.3);
}

void invad2ct_audio_device::device_start()
{
}


/*************************************
 *
 *  Tornado Baseball
 *
 *************************************/

#define TORNBASE_SQUAREW_240        NODE_01
#define TORNBASE_SQUAREW_960        NODE_02
#define TORNBASE_SQUAREW_120        NODE_03

#define TORNBASE_TONE_240_EN        NODE_04
#define TORNBASE_TONE_960_EN        NODE_05
#define TORNBASE_TONE_120_EN        NODE_06

#define TORNBASE_TONE_240_SND       NODE_07
#define TORNBASE_TONE_960_SND       NODE_08
#define TORNBASE_TONE_120_SND       NODE_09
#define TORNBASE_TONE_SND           NODE_10
#define TORNBASE_TONE_SND_FILT      NODE_11


static DISCRETE_SOUND_START(tornbase_discrete)

	/* the 3 enable lines coming out of the 74175 flip-flop at G5 */
	DISCRETE_INPUT_LOGIC(TORNBASE_TONE_240_EN)      /* pin 2 */
	DISCRETE_INPUT_LOGIC(TORNBASE_TONE_960_EN)      /* pin 7 */
	DISCRETE_INPUT_LOGIC(TORNBASE_TONE_120_EN)      /* pin 5 */

	/* 3 different freq square waves (240, 960 and 120Hz).
	   Originates from the CPU board via an edge connector.
	   The wave is in the 0/+1 range */
	DISCRETE_SQUAREWFIX(TORNBASE_SQUAREW_240, 1, 240, 1.0, 50.0, 1.0/2, 0)  /* pin X */
	DISCRETE_SQUAREWFIX(TORNBASE_SQUAREW_960, 1, 960, 1.0, 50.0, 1.0/2, 0)  /* pin Y */
	DISCRETE_SQUAREWFIX(TORNBASE_SQUAREW_120, 1, 120, 1.0, 50.0, 1.0/2, 0)  /* pin V */

	/* 7403 O/C NAND gate at G6.  3 of the 4 gates used with their outputs tied together */
	DISCRETE_LOGIC_NAND(TORNBASE_TONE_240_SND, TORNBASE_SQUAREW_240, TORNBASE_TONE_240_EN)  /* pins 4,5,6 */
	DISCRETE_LOGIC_NAND(TORNBASE_TONE_960_SND, TORNBASE_SQUAREW_960, TORNBASE_TONE_960_EN)  /* pins 2,1,3 */
	DISCRETE_LOGIC_NAND(TORNBASE_TONE_120_SND, TORNBASE_SQUAREW_120, TORNBASE_TONE_120_EN)  /* pins 13,12,11 */
	DISCRETE_LOGIC_AND3(TORNBASE_TONE_SND,     TORNBASE_TONE_240_SND, TORNBASE_TONE_960_SND, TORNBASE_TONE_120_SND)

	/* 47K resistor (R601) and 0.047uF capacitor (C601)
	   There is also a 50K pot acting as a volume control, but we output at
	   the maximum volume as MAME has its own volume adjustment */
	DISCRETE_CRFILTER(TORNBASE_TONE_SND_FILT, TORNBASE_TONE_SND, RES_K(47), CAP_U(0.047))

	/* amplify for output */
	DISCRETE_OUTPUT(TORNBASE_TONE_SND_FILT, 32767)

DISCRETE_SOUND_END


void mw8080bw_state::tornbase_audio(machine_config &config)
{
	SPEAKER(config, "mono").front_center();
	DISCRETE(config, m_discrete, tornbase_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 1);
}


WRITE8_MEMBER(mw8080bw_state::tornbase_audio_w)
{
	m_discrete->write(TORNBASE_TONE_240_EN, (data >> 0) & 0x01);

	m_discrete->write(TORNBASE_TONE_960_EN, (data >> 1) & 0x01);

	m_discrete->write(TORNBASE_TONE_120_EN, (data >> 2) & 0x01);

	/* if (data & 0x08)  enable SIREN sound */

	/* if (data & 0x10)  enable CHEER sound */

	if (tornbase_get_cabinet_type() == TORNBASE_CAB_TYPE_UPRIGHT_OLD)
	{
		/* if (data & 0x20)  enable WHISTLE sound */

		/* D6 is not connected on this cabinet type */
	}
	else
	{
		/* D5 is not connected on this cabinet type */

		/* if (data & 0x40)  enable WHISTLE sound */
	}

	machine().bookkeeping().coin_counter_w(0, (data >> 7) & 0x01);
}



/*************************************
 *
 *  280 ZZZAP / Laguna Racer
 *
 *************************************/

void mw8080bw_state::zzzap_audio(machine_config &config)
{
	SPEAKER(config, "mono").front_center();
}


WRITE8_MEMBER(mw8080bw_state::zzzap_audio_1_w)
{
	/* set ENGINE SOUND FREQ(data & 0x0f)  the value written is
	                                       the gas pedal position */

	/* if (data & 0x10)  enable HI SHIFT engine sound modifier */

	/* if (data & 0x20)  enable LO SHIFT engine sound modifier */

	/* D6 and D7 are not connected */
}


WRITE8_MEMBER(mw8080bw_state::zzzap_audio_2_w)
{
	/* if (data & 0x01)  enable BOOM sound */

	/* if (data & 0x02)  enable ENGINE sound (global) */

	/* if (data & 0x04)  enable CR 1 (screeching sound) */

	/* if (data & 0x08)  enable NOISE CR 2 (happens only after the car blows up, but
	                                        before it appears again, not sure what
	                                        it is supposed to sound like) */

	machine().bookkeeping().coin_counter_w(0, (data >> 5) & 0x01);

	/* D4, D6 and D7 are not connected */
}



/*************************************
 *
 *  Amazing Maze
 *
 *  Discrete sound emulation: Feb 2007, D.R.
 *
 *************************************/

/* nodes - inputs */
#define MAZE_P1_DATA             NODE_01
#define MAZE_P2_DATA             NODE_02
#define MAZE_TONE_TIMING         NODE_03
#define MAZE_COIN                NODE_04

/* nodes - other */
#define MAZE_JOYSTICK_IN_USE     NODE_11
#define MAZE_AUDIO_ENABLE        NODE_12
#define MAZE_TONE_ENABLE         NODE_13
#define MAZE_GAME_OVER           NODE_14
#define MAZE_R305_306_308        NODE_15
#define MAZE_R303_309            NODE_16
#define MAZE_PLAYER_SEL          NODE_17

/* nodes - sounds */
#define MAZE_SND                 NODE_18


static const discrete_555_desc maze_555_F2 =
{
	DISC_555_OUT_SQW | DISC_555_OUT_DC | DISC_555_TRIGGER_IS_LOGIC | DISC_555_TRIGGER_DISCHARGES_CAP,
	5,              /* B+ voltage of 555 */
	DEFAULT_555_VALUES
};


static const double maze_74147_table[] =
{
	3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 1, 1, 2, 3
};


static const discrete_comp_adder_table maze_r305_306_308 =
{
	DISC_COMP_P_RESISTOR,   /* type of circuit */
	RES_K(100),             /* R308 */
	2,                      /* length */
	{ RES_M(1.5),           /* R304 */
		RES_K(820) }            /* R304 */
};


static const discrete_comp_adder_table maze_r303_309 =
{
	DISC_COMP_P_RESISTOR,   /* type of circuit */
	RES_K(330),             /* R309 */
	1,                      /* length */
	{ RES_M(1) }            /* R303 */
};


static const discrete_op_amp_osc_info maze_op_amp_osc =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,  /* type */
	RES_M(1),           /* R306 */
	RES_K(430),         /* R307 */
	MAZE_R305_306_308,  /* R304, R305, R308 switchable circuit */
	MAZE_R303_309,      /* R303, R309 switchable circuit */
	RES_K(330),         /* R310 */
	0, 0, 0,            /* not used */
	CAP_P(3300),        /* C300 */
	5                   /* vP */
};


static DISCRETE_SOUND_START(maze_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_DATA (MAZE_P1_DATA)
	DISCRETE_INPUT_DATA (MAZE_P2_DATA)
	DISCRETE_INPUT_LOGIC(MAZE_TONE_TIMING)
	DISCRETE_INPUT_LOGIC(MAZE_COIN)
	DISCRETE_INPUT_LOGIC(MAZE_JOYSTICK_IN_USE)  /* IC D2, pin 8 */

	/* The following circuits control when audio is heard. */
	/* Basically there is sound for 30s after a coin is inserted. */
	/* This time is extended whenever a control is pressed. */
	/* After the 30s has expired, there is no sound until the next coin is inserted. */
	/* There is also sound for the first 30s after power up even without a coin. */
	DISCRETE_LOGIC_INVERT(NODE_20,              /* IC E2, pin 8 */
					MAZE_JOYSTICK_IN_USE)       /* IN0 */
	DISCRETE_555_MSTABLE(MAZE_GAME_OVER,        /* IC F2, pin 3 */
					1,                          /* RESET */
					NODE_20,                    /* TRIG */
					RES_K(270),                 /* R203 */
					CAP_U(100),                 /* C204 */
					&maze_555_F2)
	DISCRETE_LOGIC_JKFLIPFLOP(MAZE_AUDIO_ENABLE,/* IC F1, pin 5 */
					MAZE_COIN,                  /* RESET */
					1,                          /* SET */
					MAZE_GAME_OVER,             /* CLK */
					1,                          /* J */
					0)                          /* K */
	DISCRETE_LOGIC_INVERT(MAZE_TONE_ENABLE,     /* IC F1, pin 6 */
					MAZE_AUDIO_ENABLE)          /* IN0 */
	DISCRETE_LOGIC_AND3(NODE_21,
					MAZE_JOYSTICK_IN_USE,       /* INP0 */
					MAZE_TONE_ENABLE,           /* INP1 */
					MAZE_TONE_TIMING)           /* INP2 */

	/* The following circuits use the control info to generate a tone. */
	DISCRETE_LOGIC_JKFLIPFLOP(MAZE_PLAYER_SEL,  /* IC C1, pin 3 */
					1,                          /* RESET */
					1,                          /* SET */
					MAZE_TONE_TIMING,           /* CLK */
					1,                          /* J */
					1)                          /* K */
	DISCRETE_MULTIPLEX2(NODE_31,                /* IC D1 */
					MAZE_PLAYER_SEL,            /* ADDR */
					MAZE_P1_DATA,               /* INP0 */
					MAZE_P2_DATA)               /* INP1 */
	DISCRETE_LOOKUP_TABLE(NODE_32,              /* IC E1 */
					NODE_31,                    /* ADDR */
					16,                         /* SIZE */
					&maze_74147_table)
	DISCRETE_COMP_ADDER(MAZE_R305_306_308,      /* value of selected parallel circuit R305, R306, R308 */
					NODE_32,                    /* DATA */
					&maze_r305_306_308)
	DISCRETE_COMP_ADDER(MAZE_R303_309,          /* value of selected parallel circuit R303, R309 */
					MAZE_PLAYER_SEL,            /* DATA */
					&maze_r303_309)
	DISCRETE_OP_AMP_OSCILLATOR(NODE_36,         /* IC J1, pin 4 */
					1,                          /* ENAB */
					&maze_op_amp_osc)

	/* The following circuits remove DC poping noises when the tone is switched in/out. */
	DISCRETE_CRFILTER_VREF(NODE_40,
					NODE_36,                    /* IN0 */
					RES_K(250),                 /* R311, R312, R402, R403 in parallel */
					CAP_U(0.1),                 /* c301 */
					2.5)                        /* center voltage of R311, R312 */
	DISCRETE_SWITCH(NODE_41,                    /* IC H3, pin 10 */
					1,                          /* ENAB */
					NODE_21,                    /* switch */
					2.5,                        /* INP0 - center voltage of R402, R403 */
					NODE_40)                    /* INP1 */
	DISCRETE_CRFILTER(NODE_42,
					NODE_41,                    /* IN0 */
					RES_K(56 + 390),            /* R404 + R405 */
					CAP_P(0.01) )               /* C401 */
	DISCRETE_RCFILTER(NODE_43,
					NODE_42,                    /* IN0 */
					RES_K(56),                  /* R404 */
					CAP_P(4700) )               /* C400 */
	DISCRETE_SWITCH(MAZE_SND,                   /* H3 saturates op-amp J3 when enabled, disabling audio */
					1,                          /* ENAB */
					MAZE_AUDIO_ENABLE,          /* SWITCH */
					NODE_43,                    /* INP0 */
					0)                          /* INP1 */

	DISCRETE_OUTPUT(MAZE_SND, 96200)
DISCRETE_SOUND_END


void mw8080bw_state::maze_audio(machine_config &config)
{
	SPEAKER(config, "mono").front_center();
	DISCRETE(config, m_discrete, maze_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0);
}


void mw8080bw_state::maze_write_discrete(uint8_t maze_tone_timing_state)
{
	/* controls need to be active low */
	int controls = ~ioport("IN0")->read() & 0xff;

	m_discrete->write(MAZE_TONE_TIMING, maze_tone_timing_state);
	m_discrete->write(MAZE_P1_DATA, controls & 0x0f);
	m_discrete->write(MAZE_P2_DATA, (controls >> 4) & 0x0f);
	m_discrete->write(MAZE_JOYSTICK_IN_USE, controls != 0xff);

	/* The coin line is connected directly to the discrete circuit. */
	/* We can't really do that, so updating it with the tone timing is close enough. */
	/* A better option might be to update it at vblank or set a timer to do it. */
	/* The only noticeable difference doing it here, is that the controls don't */
	/* immediately start making tones if pressed right after the coin is inserted. */
	m_discrete->write(MAZE_COIN, (~ioport("IN1")->read() >> 3) & 0x01);
}



/*************************************
 *
 *  Checkmate
 *
 *************************************/

/* nodes - inputs */
#define CHECKMAT_BOOM_EN            NODE_01
#define CHECKMAT_TONE_EN            NODE_02
#define CHECKMAT_TONE_DATA_45       NODE_03
#define CHECKMAT_TONE_DATA_67       NODE_04

/* nodes - other */
#define CHECKMAT_R401_402_400       NODE_06
#define CHECKMAT_R407_406_410       NODE_07

/* nodes - sounds */
#define CHECKMAT_BOOM_SND           NODE_10
#define CHECKMAT_TONE_SND           NODE_11
#define CHECKMAT_FINAL_SND          NODE_12

/* nodes - adjusters */
#define CHECKMAT_R309               NODE_15
#define CHECKMAT_R411               NODE_16


static const discrete_comp_adder_table checkmat_r401_402_400 =
{
	DISC_COMP_P_RESISTOR,   /* type of circuit */
	RES_K(100),             /* R401 */
	2,                      /* length */
	{ RES_M(1.5),           /* R402 */
		RES_K(820) }            /* R400 */
};


static const discrete_comp_adder_table checkmat_r407_406_410 =
{
	DISC_COMP_P_RESISTOR,   /* type of circuit */
	RES_K(330),             /* R407 */
	2,                      /* length */
	{ RES_M(1),             /* R406 */
		RES_K(510) }            /* R410 */
};


static const discrete_op_amp_osc_info checkmat_op_amp_osc =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,  /* type */
	RES_M(1),               /* R403 */
	RES_K(430),             /* R405 */
	CHECKMAT_R401_402_400,  /* R401, R402, R400 switchable circuit */
	CHECKMAT_R407_406_410,  /* R407, R406, R410 switchable circuit */
	RES_K(330),             /* R404 */
	0, 0, 0,                /* not used */
	CAP_P(3300),            /* C400 */
	5                       /* vP */
};


static const discrete_op_amp_tvca_info checkmat_op_amp_tvca =
{
	RES_M(1.2), /* R302 */
	RES_M(1),   /* R305 */
	0,          /* r3 - not used */
	RES_M(1.2), /* R304 */
	RES_K(1),   /* M4 */
	0,          /* r6 - not used */
	RES_M(1),   /* R303 */
	0,          /* r8 - not used */
	0,          /* r9 - not used */
	0,          /* r10 - not used */
	0,          /* r11 - not used */
	CAP_U(1),   /* C300 */
	0,          /* c2 - not used */
	0, 0,       /* c3, c4 - not used */
	5,          /* v1 */
	0,          /* v2 */
	0,          /* v3 */
	5,          /* vP */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* f0 - not used */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* f1 - not used */
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,  /* f2 */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* f3 - not used */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* f4 - not used */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* f5 - not used */
};


static const discrete_mixer_desc checkmat_mixer =
{
	DISC_MIXER_IS_OP_AMP,   /* type */
	{ RES_K(100),       /* R308 - VERIFY - can't read schematic */
		RES_K(56 + 47) },   /* R412 + R408 */
	{ CHECKMAT_R309,    /* R309 */
		CHECKMAT_R411}, /* R411 */
	{ CAP_U(10),        /* C305 */
		CAP_U(0.01) },  /* C401 */
	0,                  /* rI - not used */
	RES_K(100),         /* R507 */
	0,                  /* cF - not used */
	CAP_U(1),           /* C505 */
	0,                  /* vRef - GND */
	1                   /* gain */
};

static DISCRETE_SOUND_START(checkmat_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC(CHECKMAT_BOOM_EN)
	DISCRETE_INPUT_LOGIC(CHECKMAT_TONE_EN)
	DISCRETE_INPUT_DATA (CHECKMAT_TONE_DATA_45)
	DISCRETE_INPUT_DATA (CHECKMAT_TONE_DATA_67)

	/* The low value of the resistors are tweaked to give a good volume range. */
	/* This is needed because the original controls are infinite, but the UI only gives 100 steps. */
	/* Also real variable resistors never hit 0 ohms.  There is always some resistance. */
	/* R309 mostly just increases the Boom clipping, making it sound bassier. */
	DISCRETE_ADJUSTMENT(CHECKMAT_R309, RES_K(100), 1000, DISC_LOGADJ, "R309")
	DISCRETE_ADJUSTMENT(CHECKMAT_R411, RES_M(1), 1000, DISC_LOGADJ, "R411")

	/************************************************
	 * Boom Sound
	 *
	 * The zener diode noise source is hard to
	 * emulate.  Guess for now.
	 ************************************************/
	/* FIX - find noise freq and amplitude */
	DISCRETE_NOISE(NODE_20,
					1,                          /* ENAB */
					1500,                       /* FREQ */
					2,                          /* AMP */
					0)                      /* BIAS */
	DISCRETE_OP_AMP_TRIG_VCA(NODE_21,
					CHECKMAT_BOOM_EN,           /* TRG0 */
					0,                          /* TRG1 - not used */
					0,                          /* TRG2 - not used */
					NODE_20,                    /* IN0 */
					0,                          /* IN1 - not used */
					&checkmat_op_amp_tvca)
	/* The next 5 modules emulate the filter. */
	DISCRETE_FILTER2(NODE_23,
					1,                          /* ENAB */
					NODE_21,                    /* INP0 */
					35,                         /* FREQ */
					1.0 / 8,                    /* DAMP */
					DISC_FILTER_BANDPASS)
	DISCRETE_GAIN(NODE_24,
					NODE_23,                    /* IN0 */
					15)                         /* GAIN */
	DISCRETE_CLAMP(CHECKMAT_BOOM_SND,           /* IC Q2/3, pin 10 */
					NODE_24,                    /* IN0 */
					0 - 6,                      /* MIN */
					12.0 - OP_AMP_NORTON_VBE -6)/* MAX */

	/************************************************
	 * Tone generator
	 ************************************************/
	DISCRETE_COMP_ADDER(CHECKMAT_R401_402_400,  /* value of selected parallel circuit R401, R402, R400 */
					CHECKMAT_TONE_DATA_45,      /* DATA */
					&checkmat_r401_402_400)
	DISCRETE_COMP_ADDER(CHECKMAT_R407_406_410,  /* value of selected parallel circuit R407, R406, R410 */
					CHECKMAT_TONE_DATA_67,      /* DATA */
					&checkmat_r407_406_410)
	DISCRETE_OP_AMP_OSCILLATOR(NODE_30,         /* IC N3/4, pin 4 */
					1,                          /* ENAB */
					&checkmat_op_amp_osc)

	/* The following circuits remove DC poping noises when the tone is switched in/out. */
	DISCRETE_CRFILTER_VREF(NODE_31,
					NODE_30,                    /* IN0 */
					RES_K(250),                 /* R409, R415, R414, R413 in parallel */
					CAP_U(0.1),                 /* c401 */
					2.5)                        /* center voltage of R409, R415 */
	DISCRETE_SWITCH(NODE_32,                    /* IC R3/4, pin 9 */
					1,                          /* ENAB */
					CHECKMAT_TONE_EN,           /* switch */
					2.5,                        /* INP0 - center voltage of R413, R414 */
					NODE_31)                    /* INP1 */
	DISCRETE_CRFILTER(NODE_33,
					NODE_32,                    /* IN0 */
					RES_K(56 + 47 + 200),       /* R412 + R408 + part of R411 */
					CAP_P(0.01) )               /* C404 */
	DISCRETE_RCFILTER(CHECKMAT_TONE_SND,
					NODE_33,                    /* IN0 */
					RES_K(56),                  /* R412 */
					CAP_P(4700) )               /* C403 */

	/************************************************
	 * Final mix and output
	 ************************************************/
	DISCRETE_MIXER2(CHECKMAT_FINAL_SND,
					1,                          /* ENAB */
					CHECKMAT_BOOM_SND,          /* IN0 */
					CHECKMAT_TONE_SND,          /* IN1 */
					&checkmat_mixer)
	DISCRETE_OUTPUT(CHECKMAT_FINAL_SND, 300000)
DISCRETE_SOUND_END


void mw8080bw_state::checkmat_audio(machine_config &config)
{
	SPEAKER(config, "mono").front_center();
	DISCRETE(config, m_discrete, checkmat_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 0.4);
}


WRITE8_MEMBER(mw8080bw_state::checkmat_audio_w)
{
	m_discrete->write(CHECKMAT_TONE_EN, data & 0x01);

	m_discrete->write(CHECKMAT_BOOM_EN, (data >> 1) & 0x01);

	machine().bookkeeping().coin_counter_w(0, (data >> 2) & 0x01);

	machine().sound().system_enable((data >> 3) & 0x01);

	m_discrete->write(CHECKMAT_TONE_DATA_45, (data >> 4) & 0x03);
	m_discrete->write(CHECKMAT_TONE_DATA_67, (data >> 6) & 0x03);
}



/*************************************
 *
 *  Shuffleboard
 *
 *  Discrete sound emulation: Oct 2009, D.R.
 *
 *************************************/

	/* Discrete Sound Input Nodes */
#define SHUFFLE_ROLLING_1_EN        NODE_01
#define SHUFFLE_ROLLING_2_EN        NODE_02
#define SHUFFLE_ROLLING_3_EN        NODE_03
#define SHUFFLE_FOUL_EN             NODE_04
#define SHUFFLE_ROLLOVER_EN         NODE_05
#define SHUFFLE_CLICK_EN            NODE_06

/* Discrete Sound Output Nodes */
#define SHUFFLE_NOISE               NODE_10
#define SHUFFLE_ROLLING_SND         NODE_11
#define SHUFFLE_FOUL_SND            NODE_12
#define SHUFFLE_ROLLOVER_SND        NODE_13
#define SHUFFLE_CLICK_SND           NODE_14

/* Parts List - Resistors */
#define SHUFFLE_R300    RES_K(33)
#define SHUFFLE_R400    RES_K(200)
#define SHUFFLE_R401    RES_K(3)
#define SHUFFLE_R402    RES_K(5.6)
#define SHUFFLE_R403    RES_K(5.6)
#define SHUFFLE_R404    RES_M(1)
#define SHUFFLE_R406    RES_K(300)
#define SHUFFLE_R407    RES_K(680)
#define SHUFFLE_R408    RES_K(680)
#define SHUFFLE_R409    RES_K(680)
#define SHUFFLE_R410    RES_K(680)
#define SHUFFLE_R411    RES_K(680)
#define SHUFFLE_R412    RES_M(2.7)
#define SHUFFLE_R500    RES_K(300)
#define SHUFFLE_R503    RES_M(2.7)
#define SHUFFLE_R504    RES_K(680)
#define SHUFFLE_R505    RES_K(680)
#define SHUFFLE_R506    RES_K(100)
#define SHUFFLE_R507    RES_K(47)
#define SHUFFLE_R508    RES_K(47)
#define SHUFFLE_R509    RES_K(100)
#define SHUFFLE_R511    RES_M(2)
#define SHUFFLE_R512    RES_M(5.6)
#define SHUFFLE_R513    RES_K(680)
#define SHUFFLE_R514    RES_M(1.5)
#define SHUFFLE_R515    RES_M(1)
#define SHUFFLE_R516    RES_K(510)

/* Parts List - Capacitors */
#define SHUFFLE_C300    CAP_U(0.1)
#define SHUFFLE_C400    CAP_U(0.1)
#define SHUFFLE_C401    CAP_U(1)
#define SHUFFLE_C402    CAP_U(1)
#define SHUFFLE_C403    CAP_U(1)
#define SHUFFLE_C404    CAP_U(0.1)
#define SHUFFLE_C405    CAP_U(0.1)
#define SHUFFLE_C500    CAP_U(0.1)
#define SHUFFLE_C503    CAP_U(0.0022)
#define SHUFFLE_C504    CAP_U(0.0022)
#define SHUFFLE_C505    CAP_U(0.33)
#define SHUFFLE_C506    CAP_U(1)
#define SHUFFLE_C507    CAP_U(1)
#define SHUFFLE_C508    CAP_U(1)


static const discrete_op_amp_tvca_info shuffle_rolling_tvca =
{
	SHUFFLE_R512, 0, 0, SHUFFLE_R511,                   /* r1, r2, r3, r4 */
	RES_K(10), 0, SHUFFLE_R516,                         /* r5, r6, r7 */
	RES_K(10), SHUFFLE_R515,                            /* r8, r9 */
	RES_K(10), SHUFFLE_R514,                            /* r10, r11 */
	SHUFFLE_C508, SHUFFLE_C507, SHUFFLE_C506, SHUFFLE_C505,     /* c1, c2, c3, c4 */
	12, 12, 12, 12,                                     /* v1, v2, v3, vP */
	0, 0, DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, 0,         /* f0, f1, f2, f3 */
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG1,                  /* f4 */
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG2                   /* f5 */
};

static const discrete_op_amp_info shuffle_rolling_amp =
{
	DISC_OP_AMP_IS_NORTON,
	SHUFFLE_R513, SHUFFLE_R505, SHUFFLE_R503, SHUFFLE_R504, /* r1, r2, r3, r4 */
	0,                      /* c */
	0, 12,                  /* vN, vP */
};

static const discrete_op_amp_tvca_info shuffle_foul_tvca =
{
	SHUFFLE_R412, SHUFFLE_R411, 0, SHUFFLE_R408,        /* r1, r2, r3, r4 */
	RES_K(1), 0, SHUFFLE_R406,                          /* r5, r6, r7 */
	0, 0, 0, 0,                                         /* r8, r9, r10, r11 */
	SHUFFLE_C404, 0, 0, 0,                              /* c1, c2, c3, c4 */
	5, 0, 0, 12,                                        /* v1, v2, v3, vP */
	0, 0, DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, 0, 0, 0    /* f0, f1, f2, f3, f4, f5 */
};

static const discrete_op_amp_tvca_info shuffle_rollover_tvca =
{
	SHUFFLE_R404, SHUFFLE_R410, 0, SHUFFLE_R407,        /* r1, r2, r3, r4 */
	RES_K(10), 0, SHUFFLE_R409,                         /* r5, r6, r7 */
	0, 0, 0, 0,                                         /* r8, r9, r10, r11 */
	SHUFFLE_C405, 0, 0, 0,                              /* c1, c2, c3, c4 */
	12, 0, 0, 12,                                       /* v1, v2, v3, vP */
	0, 0, DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, 0, 0, 0    /* f0, f1, f2, f3, f4, f5 */
};

static const discrete_mixer_desc shuffle_mixer =
{
	DISC_MIXER_IS_RESISTOR,
	{SHUFFLE_R500, SHUFFLE_R400, SHUFFLE_R403 + SHUFFLE_R402 + SHUFFLE_R401, SHUFFLE_R300},
	{0},        /* r_nodes */
	{SHUFFLE_C500, SHUFFLE_C400, SHUFFLE_C401, SHUFFLE_C300},
	0, 0, 0, 0, 0 ,1        /* rI, rF, cF, cAmp, vRef, gain */
};


static DISCRETE_SOUND_START(shuffle_discrete)
	DISCRETE_INPUT_LOGIC(SHUFFLE_ROLLING_1_EN)
	DISCRETE_INPUT_LOGIC(SHUFFLE_ROLLING_2_EN)
	DISCRETE_INPUT_LOGIC(SHUFFLE_ROLLING_3_EN)
	DISCRETE_INPUT_LOGIC(SHUFFLE_FOUL_EN)
	DISCRETE_INPUT_LOGIC(SHUFFLE_ROLLOVER_EN)
	DISCRETE_INPUTX_LOGIC(SHUFFLE_CLICK_EN, 11.5, 0, 0)

	/* Noise clock was breadboarded and measured at 1210Hz */
	DISCRETE_LFSR_NOISE(SHUFFLE_NOISE,          /* IC N5, pin 10 */
		1, 1,                                   /* ENAB, RESET */
		1210, 12.0, 0, 12.0 / 2, &midway_lfsr)  /* CLK,AMPL,FEED,BIAS,LFSRTB */

	/************************************************
	 * Shuffle rolling
	 ************************************************/
	DISCRETE_OP_AMP_TRIG_VCA(NODE_20,           /* IC P3-4, pin 5 */
		SHUFFLE_ROLLING_1_EN, SHUFFLE_ROLLING_2_EN, SHUFFLE_ROLLING_3_EN,   /* TRG0,TRG1,TRG2 */
		0, 0,                                   /*IN0,IN1 */
		&shuffle_rolling_tvca)
	DISCRETE_OP_AMP(NODE_21,                    /* IC P3-4, pin 4 */
		1,                                      /* ENAB */
		SHUFFLE_NOISE, NODE_20,                 /* IN0,IN1 */
		&shuffle_rolling_amp)
	/* filter not accurate */
	DISCRETE_FILTER1(NODE_22, 1, NODE_21, 800, DISC_FILTER_LOWPASS)
	DISCRETE_GAIN(SHUFFLE_ROLLING_SND, NODE_22, .2)

	/************************************************
	 * Foul
	 ************************************************/
	DISCRETE_SQUAREWFIX(NODE_30,                /* Connected to edge connector V - 120Hz */
		1, 120, DEFAULT_TTL_V_LOGIC_1, 50, DEFAULT_TTL_V_LOGIC_1 / 2, 0)    /* ENAB,FREQ,AMP,DUTY,BIAS,PHASE */
	DISCRETE_OP_AMP_TRIG_VCA(SHUFFLE_FOUL_SND,  /* IC M3-4, pin 5 */
		SHUFFLE_FOUL_EN, 0, 0,                  /* TRG0,TRG1,TRG2 */
		NODE_30, 0,                             /*IN0,IN1 */
		&shuffle_foul_tvca)

	/************************************************
	 * Shuffle rollover
	 ************************************************/
	DISCRETE_OP_AMP_TRIG_VCA(NODE_40,           /* IC M3-4, pin 4 */
		SHUFFLE_ROLLOVER_EN, 0, 0,              /* TRG0,TRG1,TRG2 */
		SHUFFLE_NOISE, 0,                       /*IN0,IN1 */
		&shuffle_rollover_tvca)
	DISCRETE_RCFILTER(NODE_41,
		NODE_40,                                /* IN0 */
		SHUFFLE_R403, SHUFFLE_C403)
	DISCRETE_RCFILTER(SHUFFLE_ROLLOVER_SND,
		NODE_41,                                /* IN0 */
		SHUFFLE_R403 + SHUFFLE_R402, SHUFFLE_C402)

	/************************************************
	 * Click
	 ************************************************/
	/* filter not accurate */
	DISCRETE_FILTER1(NODE_50, 1, SHUFFLE_CLICK_EN, 300, DISC_FILTER_LOWPASS)
	DISCRETE_GAIN(SHUFFLE_CLICK_SND, NODE_50, .3)

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	DISCRETE_MIXER4(NODE_90,
		1,                                      /* ENAB */
		SHUFFLE_ROLLING_SND,
		SHUFFLE_FOUL_SND,
		SHUFFLE_ROLLOVER_SND,
		SHUFFLE_CLICK_SND,
		&shuffle_mixer)
	DISCRETE_OUTPUT(NODE_90, 59200)
DISCRETE_SOUND_END


void mw8080bw_state::shuffle_audio(machine_config &config)
{
	SPEAKER(config, "mono").front_center();

	DISCRETE(config, m_discrete, shuffle_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0);
}


WRITE8_MEMBER(mw8080bw_state::shuffle_audio_1_w)
{
	m_discrete->write(SHUFFLE_CLICK_EN, (data >> 0) & 0x01);

	m_discrete->write(SHUFFLE_ROLLOVER_EN, (data >> 1) & 0x01);

	machine().sound().system_enable((data >> 2) & 0x01);

	m_discrete->write(NODE_29, (data >> 3) & 0x07);

	m_discrete->write(SHUFFLE_ROLLING_3_EN, (data >> 3) & 0x01);
	m_discrete->write(SHUFFLE_ROLLING_2_EN, (data >> 4) & 0x01);
	m_discrete->write(SHUFFLE_ROLLING_1_EN, (data >> 5) & 0x01);

	/* D6 and D7 are not connected */
}


WRITE8_MEMBER(mw8080bw_state::shuffle_audio_2_w)
{
	m_discrete->write(SHUFFLE_FOUL_EN, (data >> 0) & 0x01);

	machine().bookkeeping().coin_counter_w(0, (data >> 1) & 0x01);

	/* D2-D7 are not connected */
}



/*************************************
 *
 *  Bowling Alley
 *
 *  Discrete sound emulation:
 *  Apr 2007, D.R.
 *
 *************************************/

/* nodes - inputs */
#define BOWLER_FOWL_EN            NODE_01

/* nodes - sounds */
#define BOWLER_FOWL_SND           NODE_10


static const discrete_op_amp_tvca_info bowler_fowl_tvca =
{
	RES_M(2.7),                         /* R1103 */
	RES_K(680),                         /* R1102 */
	0,                                  /* no r3 */
	RES_K(680),                         /* R1104 */
	RES_K(1),                           /* SIP */
	0,                                  /* no r6 */
	RES_K(300),                         /* R1101 */
	0,                                  /* no r8 */
	0,                                  /* no r9 */
	0,                                  /* no r10 */
	0,                                  /* no r11 */
	CAP_U(0.1),                         /* C1050 */
	0,                                  /* no c2 */
	0, 0,                               /* no c3, c4 */
	5,                                  /* v1 */
	0,                                  /* no v2 */
	0,                                  /* no v3 */
	12,                                 /* vP */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* no f0 */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* no f1 */
	DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,  /* f2 */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* no f3 */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE,  /* no f4 */
	DISC_OP_AMP_TRIGGER_FUNCTION_NONE   /* no f5 */
};


static DISCRETE_SOUND_START(bowler_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUT_LOGIC(BOWLER_FOWL_EN)


	/************************************************
	 * Explosion
	 ************************************************/
	DISCRETE_SQUAREWFIX(NODE_20,
					1,                          /* ENAB */
					180,                        /* FREQ */
					DEFAULT_TTL_V_LOGIC_1,      /* p-p AMP */
					50,                         /* DUTY */
					DEFAULT_TTL_V_LOGIC_1 / 2,  /* dc BIAS */
					0)                          /* PHASE */
	DISCRETE_OP_AMP_TRIG_VCA(NODE_21,           /* IC P3, pin 9 */
					BOWLER_FOWL_EN,             /* TRG0 */
					0,                          /* no TRG1 */
					0,                          /* no TRG2 */
					NODE_20,                    /* IN0 */
					0,                          /* no IN1 */
					&bowler_fowl_tvca)
	DISCRETE_CRFILTER(BOWLER_FOWL_SND,
					NODE_21,                    /* IN0 */
					RES_K(68),                  /* R1120 */
					CAP_U(0.1) )                /* C1048 */

	DISCRETE_OUTPUT(BOWLER_FOWL_SND, 10000)
DISCRETE_SOUND_END


void mw8080bw_state::bowler_audio(machine_config &config)
{
	SPEAKER(config, "mono").front_center();

	DISCRETE(config, m_discrete, bowler_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 1);
}


WRITE8_MEMBER(mw8080bw_state::bowler_audio_1_w)
{
	/* D0 - selects controller on the cocktail PCB */

	machine().bookkeeping().coin_counter_w(0, (data >> 1) & 0x01);

	machine().sound().system_enable((data >> 2) & 0x01);

	m_discrete->write(BOWLER_FOWL_EN, (data >> 3) & 0x01);

	/* D4 - appears to be a screen flip, but it's
	        shown unconnected on the schematics for both the
	        upright and cocktail PCB's */

	/* D5 - triggered on a 'strike', sound circuit not labeled */

	/* D6 and D7 are not connected */
}


WRITE8_MEMBER(mw8080bw_state::bowler_audio_2_w)
{
	/* set BALL ROLLING SOUND FREQ(data & 0x0f)
	   0, if no rolling, 0x08 used during ball return */

	/* D4 -  triggered when the ball crosses the foul line,
	         sound circuit not labeled */

	/* D5 - triggered on a 'spare', sound circuit not labeled */

	/* D6 and D7 are not connected */
}


WRITE8_MEMBER(mw8080bw_state::bowler_audio_3_w)
{
	/* regardless of the data, enable BALL HITS PIN 1 sound
	   (top circuit on the schematics) */
}


WRITE8_MEMBER(mw8080bw_state::bowler_audio_4_w)
{
	/* regardless of the data, enable BALL HITS PIN 2 sound
	   (bottom circuit on the schematics) */
}


WRITE8_MEMBER(mw8080bw_state::bowler_audio_5_w)
{
	/* not sure, appears to me trigerred alongside the two
	   BALL HITS PIN sounds */
}


WRITE8_MEMBER(mw8080bw_state::bowler_audio_6_w)
{
	/* D0 is not connected */

	/* D3 is not connected */

	/* D6 and D7 are not connected */

	/* D1, D2, D4 and D5 have something to do with a chime circuit.
	   D1 and D4 are HI when a 'strike' happens, and D2 and D5 are
	   HI on a 'spare' */
}



/*************************************
 *
 *  Blue Shark
 *
 *  Discrete sound emulation:
 *   Jan 2007, D.R.
 *   Oct 2009, D.R.
 *
 *************************************/

/* nodes - inputs */
#define BLUESHRK_OCTOPUS_EN         NODE_01
#define BLUESHRK_HIT_EN             NODE_02
#define BLUESHRK_SHARK_EN           NODE_03
#define BLUESHRK_SHOT_EN            NODE_04
#define BLUESHRK_GAME_ON_EN         NODE_05

/* nodes - sounds */
#define BLUESHRK_NOISE_1            NODE_11
#define BLUESHRK_NOISE_2            NODE_12
#define BLUESHRK_OCTOPUS_SND        NODE_13
#define BLUESHRK_HIT_SND            NODE_14
#define BLUESHRK_SHARK_SND          NODE_15
#define BLUESHRK_SHOT_SND           NODE_16

/* Parts List - Resistors */
#define BLUESHRK_R300   RES_M(1)
#define BLUESHRK_R301   RES_K(100)
#define BLUESHRK_R302   RES_M(1)
#define BLUESHRK_R303   RES_K(33)
#define BLUESHRK_R304   RES_K(120)
#define BLUESHRK_R305   RES_M(1)
#define BLUESHRK_R306   RES_K(470)
#define BLUESHRK_R307   RES_K(680)
#define BLUESHRK_R308   RES_M(1)
#define BLUESHRK_R309   RES_M(1)
#define BLUESHRK_R310   RES_K(680)
#define BLUESHRK_R311   RES_K(1)
#define BLUESHRK_R312   RES_K(100)
#define BLUESHRK_R313   RES_M(1)
#define BLUESHRK_R314   RES_M(1)
#define BLUESHRK_R315   RES_M(4.7)
#define BLUESHRK_R316   RES_M(2.2)
#define BLUESHRK_R317   RES_K(10)
#define BLUESHRK_R318   RES_M(1)
#define BLUESHRK_R319   RES_K(680)
#define BLUESHRK_R320   RES_M(2.7)
#define BLUESHRK_R321   RES_K(680)
#define BLUESHRK_R324   RES_K(750)
#define BLUESHRK_R520   RES_K(510)
#define BLUESHRK_R521   RES_K(22)
#define BLUESHRK_R529   RES_K(33)
#define BLUESHRK_R601   RES_K(47)
#define BLUESHRK_R602   RES_K(22)
#define BLUESHRK_R603   RES_K(39)
#define BLUESHRK_R604   RES_K(1)
#define BLUESHRK_R605   RES_M(1)
#define BLUESHRK_R700   RES_K(68)
#define BLUESHRK_R701   RES_K(470)
#define BLUESHRK_R702   RES_M(1.2)
#define BLUESHRK_R703   RES_M(1.5)
#define BLUESHRK_R704   RES_K(22)
#define BLUESHRK_R705   RES_K(100)
#define BLUESHRK_R706   RES_K(470)
#define BLUESHRK_R707   RES_M(1.2)
#define BLUESHRK_R708   RES_M(1.5)
#define BLUESHRK_R709   RES_K(22)
#define BLUESHRK_R710   RES_K(470)
#define BLUESHRK_R711   RES_K(39)
#define BLUESHRK_R712   RES_M(1.2)
#define BLUESHRK_R713   RES_M(1.5)
#define BLUESHRK_R714   RES_K(22)
#define BLUESHRK_R715   RES_K(47)
#define BLUESHRK_R716   RES_K(75)
#define BLUESHRK_R717   RES_M(1.5)
#define BLUESHRK_R718   RES_M(2.2)
#define BLUESHRK_R719   RES_K(560)
#define BLUESHRK_R720   RES_M(1.5)
#define BLUESHRK_R721   RES_M(2.2)
#define BLUESHRK_R722   RES_M(2.2)
#define BLUESHRK_R723   RES_K(560)
#define BLUESHRK_R724   RES_K(12)
#define BLUESHRK_R725   RES_K(68)
#define BLUESHRK_R726   RES_K(330)
#define BLUESHRK_R727   RES_M(2.2)
#define BLUESHRK_R728   RES_M(1)
#define BLUESHRK_R730   RES_K(56)
#define BLUESHRK_R1000  RES_K(1)

/* Parts List - Capacitors */
#define BLUESHRK_C300   CAP_U(0.1)
#define BLUESHRK_C301   CAP_P(470)
#define BLUESHRK_C302   CAP_P(470)
#define BLUESHRK_C303   CAP_U(0.47)
#define BLUESHRK_C304   CAP_U(1)
#define BLUESHRK_C305   CAP_U(1)
#define BLUESHRK_C508   CAP_U(1)
#define BLUESHRK_C600   CAP_U(2.2)
#define BLUESHRK_C602   CAP_U(0.022)
#define BLUESHRK_C603   CAP_U(0.01)
#define BLUESHRK_C604   CAP_U(0.015)
#define BLUESHRK_C606   CAP_U(1)
#define BLUESHRK_C700   CAP_U(22)
#define BLUESHRK_C701   CAP_U(22)
#define BLUESHRK_C702   CAP_U(10)
#define BLUESHRK_C703   CAP_U(0.033)
#define BLUESHRK_C704   CAP_U(0.015)
#define BLUESHRK_C705   CAP_U(0.015)
#define BLUESHRK_C706   CAP_U(0.033)
#define BLUESHRK_C707   CAP_U(2.2)
#define BLUESHRK_C708   CAP_U(1)
#define BLUESHRK_C900   CAP_U(10)


static const discrete_op_amp_osc_info blueshrk_octopus_osc =
{
	DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_CAP,
	BLUESHRK_R300, BLUESHRK_R303, BLUESHRK_R301, BLUESHRK_R304, BLUESHRK_R302, 0, 0, 0, /* r1, r2, r3, r4, r5, r6, r7, r8 */
	BLUESHRK_C300, 12               /*c, vP */
};

static const discrete_op_amp_osc_info blueshrk_octopus_vco =
{
	DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW,
	BLUESHRK_R305, BLUESHRK_R306, BLUESHRK_R307, BLUESHRK_R309, BLUESHRK_R308, 0, 0, 0, /* r1, r2, r3, r4, r5, r6, r7, r8 */
	BLUESHRK_C301, 12               /*c, vP */
};

static const discrete_op_amp_1sht_info blueshrk_octopus_oneshot =
{
	DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON,
	BLUESHRK_R315, BLUESHRK_R312, BLUESHRK_R314, BLUESHRK_R313, BLUESHRK_R316,  /* r1, r2, r3, r4, r5 */
	BLUESHRK_C303, BLUESHRK_C302,                                               /* c1, c2 */
	0, 12                                                                       /* vN, vP */
};

static const discrete_integrate_info blueshrk_octopus_integrate =
{
	DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON,
	BLUESHRK_R318, BLUESHRK_R317, 0, BLUESHRK_C304,     /* r1, r2, r3, c */
	12, 12,                                             /* v1, vP */
	0, 0, 0                                             /* f0, f1, f2 */
};

static const discrete_op_amp_info blueshrk_octopus_amp =
{
	DISC_OP_AMP_IS_NORTON,
	BLUESHRK_R310, BLUESHRK_R319, BLUESHRK_R320, BLUESHRK_R321, /* r1, r2, r3, r4 */
	0, 0, 12                                                        /* c, vN, vP */
};

static const discrete_lfsr_desc blueshrk_lfsr =
{
	DISC_CLK_IS_FREQ,
	17,                 /* bit length */
						/* the RC network fed into pin 4, has the effect
						   of presetting all bits high at power up */
	0x1ffff,            /* reset value */
	4,                  /* use bit 4 as XOR input 0 */
	16,                 /* use bit 16 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_OUTPUT_SR_SN1,       /* output is not inverted */
	12                  /* output bit */
};

static const discrete_555_desc blueshrk_555_H1B =
{
	DISC_555_OUT_ENERGY | DISC_555_OUT_DC,
	5,              /* B+ voltage of 555 */
	DEFAULT_555_CHARGE,
	12              /* the OC buffer H2 converts the output voltage to 12V. */
};

static const discrete_op_amp_osc_info blueshrk_shark_osc1 =
{
	DISC_OP_AMP_OSCILLATOR_2 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_ENERGY,
	0, BLUESHRK_R701, BLUESHRK_R703, BLUESHRK_R702, 0, BLUESHRK_R700, 0, 0, /* r1, r2, r3, r4, r5, r6, r7, r8 */
	BLUESHRK_C700, 12               /*c, vP */
};

static const discrete_op_amp_osc_info blueshrk_shark_osc2 =
{
	DISC_OP_AMP_OSCILLATOR_2 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_ENERGY,
	0, BLUESHRK_R706, BLUESHRK_R708, BLUESHRK_R707, 0, BLUESHRK_R705, 0, 0, /* r1, r2, r3, r4, r5, r6, r7, r8 */
	BLUESHRK_C700, 12               /*c, vP */
};

static const discrete_op_amp_osc_info blueshrk_shark_osc3 =
{
	DISC_OP_AMP_OSCILLATOR_2 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_ENERGY,
	0, BLUESHRK_R711, BLUESHRK_R713, BLUESHRK_R712, 0, BLUESHRK_R710, 0, 0, /* r1, r2, r3, r4, r5, r6, r7, r8 */
	BLUESHRK_C700, 12               /*c, vP */
};

static const discrete_mixer_desc blueshrk_shark_mixer =
{
	DISC_MIXER_IS_RESISTOR,
	{BLUESHRK_R704, BLUESHRK_R709, BLUESHRK_R714},
	{0}, {0}, 0, 0, 0, 0, 0, 1  /* r_node, c, rI, rF, cF, cAmp, vRef, gain */
};

static const discrete_op_amp_info blueshrk_shark_amp_m3 =
{
	DISC_OP_AMP_IS_NORTON,
	0, BLUESHRK_R715 + RES_3_PARALLEL(BLUESHRK_R704, BLUESHRK_R709, BLUESHRK_R714), BLUESHRK_R716, 0,       /* r1, r2, r3, r4 */
	0, 0, 12                                /* c, vN, vP */
};

static const discrete_op_amp_osc_info blueshrk_shark_vco =
{
	DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_ENERGY,
	BLUESHRK_R717, BLUESHRK_R722, BLUESHRK_R719, BLUESHRK_R721, BLUESHRK_R720,  /* r1, r2, r3, r4, r5 */
	0, 0, BLUESHRK_R718,    /* r6, r7, r8 */
	BLUESHRK_C703, 12                   /*c, vP */
};

static const discrete_op_amp_info blueshrk_shark_amp_k3 =
{
	DISC_OP_AMP_IS_NORTON,
	BLUESHRK_R724 + BLUESHRK_R725 + BLUESHRK_R726,      /* r1 */
	BLUESHRK_R723 , BLUESHRK_R727, BLUESHRK_R728,       /* r2, r3, r4 */
	0, 0, 12                                            /* c, vN, vP */
};

static const discrete_mixer_desc blueshrk_mixer =
{
	DISC_MIXER_IS_RESISTOR,
	{BLUESHRK_R324, RES_2_PARALLEL(BLUESHRK_R520, BLUESHRK_R521) + BLUESHRK_R529, BLUESHRK_R604 + BLUESHRK_R605, BLUESHRK_R730},
	{0},    /* r_node */
	{BLUESHRK_C305, BLUESHRK_C508, BLUESHRK_C606, BLUESHRK_C708},
	0, 0, 0, BLUESHRK_C900, 0, 1    /* rI, rF, cF, cAmp, vRef, gain */
};

static DISCRETE_SOUND_START(blueshrk_discrete)

	/************************************************
	 * Input register mapping
	 ************************************************/
	DISCRETE_INPUTX_LOGIC(BLUESHRK_OCTOPUS_EN, 12, 0, 0)
	DISCRETE_INPUT_LOGIC(BLUESHRK_HIT_EN)
	DISCRETE_INPUT_LOGIC(BLUESHRK_SHARK_EN)
	DISCRETE_INPUT_LOGIC(BLUESHRK_SHOT_EN)
	DISCRETE_INPUT_LOGIC(BLUESHRK_GAME_ON_EN)

	/************************************************
	 * Octopus sound
	 ************************************************/
	DISCRETE_OP_AMP_OSCILLATOR(NODE_20,         /* IC M5, pin 5 */
		1,                                      /* ENAB */
		&blueshrk_octopus_osc)
	DISCRETE_OP_AMP_VCO1(NODE_21,               /* IC M5, pin 10 */
		1,                                      /* ENAB */
		NODE_20,                                /* VMOD1 */
		&blueshrk_octopus_vco)
	DISCRETE_OP_AMP_ONESHOT(NODE_22,            /* IC J5, pin 10 */
		BLUESHRK_OCTOPUS_EN, &blueshrk_octopus_oneshot)
	DISCRETE_INTEGRATE(NODE_23,                 /* IC J5, pin 5 */
		NODE_22, 0,                             /* TRG0,TRG1 */
		&blueshrk_octopus_integrate)
	DISCRETE_OP_AMP(BLUESHRK_OCTOPUS_SND,       /* IC J5, pin 4 */
		1,                                      /* ENAB */
		NODE_21, NODE_23,                       /* IN0,IN1 */
		&blueshrk_octopus_amp)

	/************************************************
	 * Noise
	 ************************************************/
	/* Noise clock was breadboarded and measured at 7700Hz */
	DISCRETE_LFSR_NOISE(BLUESHRK_NOISE_1,           /* IC N5, pin 10 (NODE_11) */
		1, 1,                                       /* ENAB, RESET */
		7700, 12.0, 0, 12.0 / 2, &blueshrk_lfsr)    /* CLK,AMPL,FEED,BIAS,LFSRTB */
	DISCRETE_BIT_DECODE(BLUESHRK_NOISE_2,           /* IC N5, pin 13 */
		NODE_SUB(BLUESHRK_NOISE_1, 1), 8, 12)       /* INP,BIT_N,VOUT */

	/************************************************
	 * Shot sound
	 ************************************************/
	DISCRETE_CONSTANT(BLUESHRK_SHOT_SND, 0)     /* placeholder for incomplete sound */

	/************************************************
	 * Hit sound
	 ************************************************/
	DISCRETE_COUNTER(NODE_40,                           /* IC H3, pin 5 */
		1, BLUESHRK_HIT_EN,                             /* ENAB,RESET */
		FREQ_OF_555(BLUESHRK_R601, 0, BLUESHRK_C600),   /* CLK - IC H1, pin 9 */
		0,1, DISC_COUNT_UP, 0,                          /* MIN,MAX,DIR,INIT0 */
		DISC_CLK_IS_FREQ)
	DISCRETE_SWITCH(NODE_41,                    /* value of toggled caps */
		1,                                      /* ENAB */
		NODE_40,                                /* SWITCH */
		BLUESHRK_C602 + BLUESHRK_C603,          /* INP0 - IC H3, pin 5 low */
		BLUESHRK_C604)                          /* INP1 - IC H3, pin 6 low  */
	DISCRETE_555_ASTABLE(BLUESHRK_HIT_SND,      /* IC H2, pin 2 */
		BLUESHRK_HIT_EN,                        /* RESET */
		BLUESHRK_R602, BLUESHRK_R603, NODE_41,  /* R1,R2,C */
		&blueshrk_555_H1B)

	/************************************************
	 * Shark sound
	 ************************************************/
	DISCRETE_OP_AMP_OSCILLATOR(NODE_50,         /* IC M3, pin 4 */
		1,                                      /* ENAB */
		&blueshrk_shark_osc1)
	DISCRETE_OP_AMP_OSCILLATOR(NODE_51,         /* IC M3, pin 5 */
		1,                                      /* ENAB */
		&blueshrk_shark_osc2)
	DISCRETE_OP_AMP_OSCILLATOR(NODE_52,         /* IC M3, pin 9 */
		1,                                      /* ENAB */
		&blueshrk_shark_osc3)
	DISCRETE_MIXER3(NODE_53,
		1,                                      /* ENAB */
		NODE_50, NODE_51, NODE_52, &blueshrk_shark_mixer)
	/* threshold detector */
	/* if any of the above oscillators are low, then the output is low */
	DISCRETE_OP_AMP(NODE_54,                    /* IC M3, pin 10 */
		1,                                      /* ENAB */
		0, NODE_53,                             /* IN0,IN1 */
		&blueshrk_shark_amp_m3)
	DISCRETE_ADDER2(NODE_55,                    /* diode drops voltage */
		1, NODE_54, -0.7)                       /* ENAB,IN0,IN1 */
	DISCRETE_CLAMP(NODE_56, NODE_55, 0, 12)     /* IN0,MIN,MAX */
	/* VCO disabled if any of the above oscillators or enable are low */
	DISCRETE_OP_AMP_VCO1(NODE_57,               /* IC K3, pin 5 */
		BLUESHRK_SHARK_EN, NODE_56,             /* ENAB,VMOD1 */
		&blueshrk_shark_vco)
	DISCRETE_RCFILTER(NODE_58,
		BLUESHRK_NOISE_1,                       /* IN0 */
		BLUESHRK_R724, BLUESHRK_C704)
	DISCRETE_RCFILTER(NODE_59,
		NODE_58,                                /* IN0 */
		BLUESHRK_R724 + BLUESHRK_R725, BLUESHRK_C704)
	DISCRETE_RCFILTER(NODE_60,
		NODE_59,                                /* IN0 */
		BLUESHRK_R724 + BLUESHRK_R725 + BLUESHRK_R726, BLUESHRK_C704)
	DISCRETE_OP_AMP(NODE_61,                    /* IC K3, pin 10 */
		1,                                      /* ENAB */
		NODE_60, NODE_57,                       /* IN0,IN1 */
		&blueshrk_shark_amp_k3)
	/* the opamp output is connected directly to a capacitor */
	/* we will simulate this using a 1 ohm resistor */
	DISCRETE_RCFILTER(BLUESHRK_SHARK_SND,
		NODE_61,                                /* IN0 */
		1, BLUESHRK_C707)

	/************************************************
	 * Combine all sound sources.
	 ************************************************/
	DISCRETE_MIXER4(NODE_91,
		BLUESHRK_GAME_ON_EN,
		BLUESHRK_OCTOPUS_SND,
		BLUESHRK_SHOT_SND,
		BLUESHRK_HIT_SND,
		BLUESHRK_SHARK_SND,
		&blueshrk_mixer)

	DISCRETE_OUTPUT(NODE_91, 90000)
DISCRETE_SOUND_END


void mw8080bw_state::blueshrk_audio(machine_config &config)
{
	SPEAKER(config, "mono").front_center();
	DISCRETE(config, m_discrete, blueshrk_discrete);
	m_discrete->add_route(ALL_OUTPUTS, "mono", 0.25);
}


WRITE8_MEMBER(mw8080bw_state::blueshrk_audio_w)
{
	m_discrete->write(BLUESHRK_GAME_ON_EN, (data >> 0) & 0x01);

	m_discrete->write(BLUESHRK_SHOT_EN, (data >> 1) & 0x01);

	m_discrete->write(BLUESHRK_HIT_EN, (data >> 2) & 0x01);

	m_discrete->write(BLUESHRK_SHARK_EN, (data >> 3) & 0x01);

	/* if (data & 0x10)  enable KILLED DIVER sound, this circuit
	   doesn't appear to be on the schematics */

	m_discrete->write(BLUESHRK_OCTOPUS_EN, (data >> 5) & 0x01);

	/* D6 and D7 are not connected */
}