1 /* 8080bw.c *********************************
2  updated: 1997-04-09 08:46 TT
3  updated  20-3-1998 LT Added color changes on base explosion
4  *
5  * Author      : Tormod Tjaberg
6  * Created     : 1997-04-09
7  * Description : Sound routines for the 'invaders' games
8  *
9  * Note:
10  * The samples were taken from Michael Strutt's (mstrutt@pixie.co.za)
11  * excellent space invader emulator and converted to signed samples so
12  * they would work under SEAL. The port info was also gleaned from
13  * his emulator. These sounds should also work on all the invader games.
14  *
15  * The sounds are generated using output port 3 and 5
16  *
17  * Port 3:
18  * bit 0=UFO  (repeats)       emulated
19  * bit 1=Shot                 1.raw
20  * bit 2=Base hit             2.raw
21  * bit 3=Invader hit          3.raw
22  * bit 4=Bonus base           9.raw
23  *
24  * Port 5:
25  * bit 0=Fleet movement 1     4.raw
26  * bit 1=Fleet movement 2     5.raw
27  * bit 2=Fleet movement 3     6.raw
28  * bit 3=Fleet movement 4     7.raw
29  * bit 4=UFO 2                8.raw
30  */
31 #include "driver.h"
32 #include "cpu/i8039/i8039.h"
33 #include "machine/74123.h"
34 #include "vidhrdw/generic.h"
35 #include "8080bw.h"
36 
37 static WRITE_HANDLER( invad2ct_sh_port1_w );
38 static WRITE_HANDLER( invaders_sh_port3_w );
39 static WRITE_HANDLER( invaders_sh_port5_w );
40 static WRITE_HANDLER( invad2ct_sh_port7_w );
41 
42 static WRITE_HANDLER( sheriff_sh_port4_w );
43 static WRITE_HANDLER( sheriff_sh_port5_w );
44 static WRITE_HANDLER( sheriff_sh_port6_w );
45 
46 static WRITE_HANDLER( helifire_sh_port4_w );
47 static WRITE_HANDLER( helifire_sh_port5_w );
48 static WRITE_HANDLER( helifire_sh_port6_w );
49 
50 static WRITE_HANDLER( ballbomb_sh_port3_w );
51 static WRITE_HANDLER( ballbomb_sh_port5_w );
52 
53 static WRITE_HANDLER( boothill_sh_port3_w );
54 static WRITE_HANDLER( boothill_sh_port5_w );
55 
56 static WRITE_HANDLER( clowns_sh_port7_w );
57 extern struct Samplesinterface circus_samples_interface;
58 
59 static WRITE_HANDLER( seawolf_sh_port5_w );
60 
61 static WRITE_HANDLER( schaser_sh_port3_w );
62 static WRITE_HANDLER( schaser_sh_port5_w );
63 static int  schaser_sh_start(const struct MachineSound *msound);
64 static void schaser_sh_stop(void);
65 static void schaser_sh_update(void);
66 
67 static WRITE_HANDLER( polaris_sh_port2_w );
68 static WRITE_HANDLER( polaris_sh_port4_w );
69 static WRITE_HANDLER( polaris_sh_port6_w );
70 
71 
72 struct SN76477interface invaders_sn76477_interface =
73 {
74 	1,	/* 1 chip */
75 	{ 25 },  /* mixing level   pin description		 */
76 	{ 0	/* N/C */},		/*	4  noise_res		 */
77 	{ 0	/* N/C */},		/*	5  filter_res		 */
78 	{ 0	/* N/C */},		/*	6  filter_cap		 */
79 	{ 0	/* N/C */},		/*	7  decay_res		 */
80 	{ 0	/* N/C */},		/*	8  attack_decay_cap  */
81 	{ RES_K(100) },		/* 10  attack_res		 */
82 	{ RES_K(56)  },		/* 11  amplitude_res	 */
83 	{ RES_K(10)  },		/* 12  feedback_res 	 */
84 	{ 0	/* N/C */},		/* 16  vco_voltage		 */
85 	{ CAP_U(0.1) },		/* 17  vco_cap			 */
86 	{ RES_K(8.2) },		/* 18  vco_res			 */
87 	{ 5.0		 },		/* 19  pitch_voltage	 */
88 	{ RES_K(120) },		/* 20  slf_res			 */
89 	{ CAP_U(1.0) },		/* 21  slf_cap			 */
90 	{ 0	/* N/C */},		/* 23  oneshot_cap		 */
91 	{ 0	/* N/C */}		/* 24  oneshot_res		 */
92 };
93 
94 static const char *invaders_sample_names[] =
95 {
96 	"*invaders",
97 	"1.wav",	/* Shot/Missle */
98 	"2.wav",	/* Base Hit/Explosion */
99 	"3.wav",	/* Invader Hit */
100 	"4.wav",	/* Fleet move 1 */
101 	"5.wav",	/* Fleet move 2 */
102 	"6.wav",	/* Fleet move 3 */
103 	"7.wav",	/* Fleet move 4 */
104 	"8.wav",	/* UFO/Saucer Hit */
105 	"9.wav",	/* Bonus Base */
106 	0       /* end of array */
107 };
108 
109 struct Samplesinterface invaders_samples_interface =
110 {
111 	4,	/* 4 channels */
112 	25,	/* volume */
113 	invaders_sample_names
114 };
115 
116 
117 struct SN76477interface invad2ct_sn76477_interface =
118 {
119 	2,	/* 2 chips */
120 	{ 25,         25 },  /* mixing level   pin description		 */
121 	{ 0,          0	/* N/C */  },	/*	4  noise_res		 */
122 	{ 0,          0	/* N/C */  },	/*	5  filter_res		 */
123 	{ 0,          0	/* N/C */  },	/*	6  filter_cap		 */
124 	{ 0,          0	/* N/C */  },	/*	7  decay_res		 */
125 	{ 0,          0	/* N/C */  },	/*	8  attack_decay_cap  */
126 	{ RES_K(100), RES_K(100)   },	/* 10  attack_res		 */
127 	{ RES_K(56),  RES_K(56)    },	/* 11  amplitude_res	 */
128 	{ RES_K(10),  RES_K(10)    },	/* 12  feedback_res 	 */
129 	{ 0,          0	/* N/C */  },	/* 16  vco_voltage		 */
130 	{ CAP_U(0.1), CAP_U(0.047) },	/* 17  vco_cap			 */
131 	{ RES_K(8.2), RES_K(39)    },	/* 18  vco_res			 */
132 	{ 5.0,        5.0		   },	/* 19  pitch_voltage	 */
133 	{ RES_K(120), RES_K(120)   },	/* 20  slf_res			 */
134 	{ CAP_U(1.0), CAP_U(1.0)   },	/* 21  slf_cap			 */
135 	{ 0,          0	/* N/C */  },	/* 23  oneshot_cap		 */
136 	{ 0,          0	/* N/C */  }	/* 24  oneshot_res		 */
137 };
138 
139 static const char *invad2ct_sample_names[] =
140 {
141 	"*invaders",
142 	"1.wav",	/* Shot/Missle - Player 1 */
143 	"2.wav",	/* Base Hit/Explosion - Player 1 */
144 	"3.wav",	/* Invader Hit - Player 1 */
145 	"4.wav",	/* Fleet move 1 - Player 1 */
146 	"5.wav",	/* Fleet move 2 - Player 1 */
147 	"6.wav",	/* Fleet move 3 - Player 1 */
148 	"7.wav",	/* Fleet move 4 - Player 1 */
149 	"8.wav",	/* UFO/Saucer Hit - Player 1 */
150 	"9.wav",	/* Bonus Base - Player 1 */
151 	"11.wav",	/* Shot/Missle - Player 2 */
152 	"12.wav",	/* Base Hit/Explosion - Player 2 */
153 	"13.wav",	/* Invader Hit - Player 2 */
154 	"14.wav",	/* Fleet move 1 - Player 2 */
155 	"15.wav",	/* Fleet move 2 - Player 2 */
156 	"16.wav",	/* Fleet move 3 - Player 2 */
157 	"17.wav",	/* Fleet move 4 - Player 2 */
158 	"18.wav",	/* UFO/Saucer Hit - Player 2 */
159 	0       /* end of array */
160 };
161 
162 struct Samplesinterface invad2ct_samples_interface =
163 {
164 	8,	/* 8 channels */
165 	25,	/* volume */
166 	invad2ct_sample_names
167 };
168 
169 
MACHINE_INIT(invaders)170 MACHINE_INIT( invaders )
171 {
172 	install_port_write_handler(0, 0x03, 0x03, invaders_sh_port3_w);
173 	install_port_write_handler(0, 0x05, 0x05, invaders_sh_port5_w);
174 
175 	SN76477_envelope_1_w(0, 1);
176 	SN76477_envelope_2_w(0, 0);
177 	SN76477_mixer_a_w(0, 0);
178 	SN76477_mixer_b_w(0, 0);
179 	SN76477_mixer_c_w(0, 0);
180 	SN76477_vco_w(0, 1);
181 }
182 
MACHINE_INIT(sstrangr)183 MACHINE_INIT( sstrangr )
184 {
185 	install_port_write_handler(0, 0x42, 0x42, invaders_sh_port3_w);
186 	install_port_write_handler(0, 0x44, 0x44, invaders_sh_port5_w);
187 
188 	SN76477_envelope_1_w(0, 1);
189 	SN76477_envelope_2_w(0, 0);
190 	SN76477_mixer_a_w(0, 0);
191 	SN76477_mixer_b_w(0, 0);
192 	SN76477_mixer_c_w(0, 0);
193 	SN76477_vco_w(0, 1);
194 }
195 
MACHINE_INIT(invad2ct)196 MACHINE_INIT( invad2ct )
197 {
198 	machine_init_invaders();
199 
200 	install_port_write_handler(0, 0x01, 0x01, invad2ct_sh_port1_w);
201 	install_port_write_handler(0, 0x07, 0x07, invad2ct_sh_port7_w);
202 
203 	SN76477_envelope_1_w(1, 1);
204 	SN76477_envelope_2_w(1, 0);
205 	SN76477_mixer_a_w(1, 0);
206 	SN76477_mixer_b_w(1, 0);
207 	SN76477_mixer_c_w(1, 0);
208 	SN76477_vco_w(1, 1);
209 }
210 
211 
212 /*
213    Note: For invad2ct, the Player 1 sounds are the same as for the
214          original and deluxe versions.  Player 2 sounds are all
215          different, and are triggered by writes to port 1 and port 7.
216 
217 */
218 
invaders_sh_1_w(int board,int data,unsigned char * last)219 static void invaders_sh_1_w(int board, int data, unsigned char *last)
220 {
221 	int base_channel, base_sample;
222 
223 	base_channel = 4 * board;
224 	base_sample  = 9 * board;
225 
226 	SN76477_enable_w(board, !(data & 0x01));				/* Saucer Sound */
227 
228 	if (data & 0x02 && ~*last & 0x02)
229 		sample_start (base_channel+0, base_sample+0, 0);	/* Shot Sound */
230 
231 	if (data & 0x04 && ~*last & 0x04)
232 		sample_start (base_channel+1, base_sample+1, 0);	/* Base Hit */
233 
234 	if (~data & 0x04 && *last & 0x04)
235 		sample_stop (base_channel+1);
236 
237 	if (data & 0x08 && ~*last & 0x08)
238 		sample_start (base_channel+0, base_sample+2, 0);	/* Invader Hit */
239 
240 	if (data & 0x10 && ~*last & 0x10)
241 		sample_start (base_channel+2, 8, 0);				/* Bonus Missle Base */
242 
243 	c8080bw_screen_red_w(data & 0x04);
244 
245 	*last = data;
246 }
247 
invaders_sh_2_w(int board,int data,unsigned char * last)248 static void invaders_sh_2_w(int board, int data, unsigned char *last)
249 {
250 	int base_channel, base_sample;
251 
252 	base_channel = 4 * board;
253 	base_sample  = 9 * board;
254 
255 	if (data & 0x01 && ~*last & 0x01)
256 		sample_start (base_channel+1, base_sample+3, 0);	/* Fleet 1 */
257 
258 	if (data & 0x02 && ~*last & 0x02)
259 		sample_start (base_channel+1, base_sample+4, 0);	/* Fleet 2 */
260 
261 	if (data & 0x04 && ~*last & 0x04)
262 		sample_start (base_channel+1, base_sample+5, 0);	/* Fleet 3 */
263 
264 	if (data & 0x08 && ~*last & 0x08)
265 		sample_start (base_channel+1, base_sample+6, 0);	/* Fleet 4 */
266 
267 	if (data & 0x10 && ~*last & 0x10)
268 		sample_start (base_channel+3, base_sample+7, 0);	/* Saucer Hit */
269 
270 	c8080bw_flip_screen_w(data & 0x20);
271 
272 	*last = data;
273 }
274 
275 
WRITE_HANDLER(invad2ct_sh_port1_w)276 static WRITE_HANDLER( invad2ct_sh_port1_w )
277 {
278 	static unsigned char last = 0;
279 
280 	invaders_sh_1_w(1, data, &last);
281 }
282 
WRITE_HANDLER(invaders_sh_port3_w)283 static WRITE_HANDLER( invaders_sh_port3_w )
284 {
285 	static unsigned char last = 0;
286 
287 	invaders_sh_1_w(0, data, &last);
288 }
289 
WRITE_HANDLER(invaders_sh_port5_w)290 static WRITE_HANDLER( invaders_sh_port5_w )
291 {
292 	static unsigned char last = 0;
293 
294 	invaders_sh_2_w(0, data, &last);
295 }
296 
WRITE_HANDLER(invad2ct_sh_port7_w)297 static WRITE_HANDLER( invad2ct_sh_port7_w )
298 {
299 	static unsigned char last = 0;
300 
301 	invaders_sh_2_w(1, data, &last);
302 }
303 
304 
305 /*******************************************************/
306 /*                                                     */
307 /* Midway "Gun Fight"                                  */
308 /*                                                     */
309 /*******************************************************/
310 
MACHINE_INIT(gunfight)311 MACHINE_INIT( gunfight )
312 {
313 	install_port_read_handler(0, 0x00, 0x00, gunfight_port_0_r);
314 	install_port_read_handler(0, 0x01, 0x01, gunfight_port_1_r);
315 }
316 
317 
318 /*******************************************************/
319 /*                                                     */
320 /* Midway "Boot Hill"                                  */
321 /*                                                     */
322 /*******************************************************/
323 
324 static const char *boothill_sample_names[] =
325 {
326 	"*boothill", /* in case we ever find any bootlegs hehehe */
327 	"addcoin.wav",
328 	"endgame.wav",
329 	"gunshot.wav",
330 	"killed.wav",
331 	0       /* end of array */
332 };
333 
334 struct Samplesinterface boothill_samples_interface =
335 {
336 	9,	/* 9 channels */
337 	25,	/* volume */
338 	boothill_sample_names
339 };
340 
341 
342 /* HC 4/14/98 NOTE: *I* THINK there are sounds missing...
343 i dont know for sure... but that is my guess....... */
344 
MACHINE_INIT(boothill)345 MACHINE_INIT( boothill )
346 {
347 	install_port_read_handler (0, 0x00, 0x00, boothill_port_0_r);
348 	install_port_read_handler (0, 0x01, 0x01, boothill_port_1_r);
349 
350 	install_port_write_handler(0, 0x03, 0x03, boothill_sh_port3_w);
351 	install_port_write_handler(0, 0x05, 0x05, boothill_sh_port5_w);
352 }
353 
WRITE_HANDLER(boothill_sh_port3_w)354 static WRITE_HANDLER( boothill_sh_port3_w )
355 {
356 	switch (data)
357 	{
358 		case 0x0c:
359 			sample_start (0, 0, 0);
360 			break;
361 
362 		case 0x18:
363 		case 0x28:
364 			sample_start (1, 2, 0);
365 			break;
366 
367 		case 0x48:
368 		case 0x88:
369 			sample_start (2, 3, 0);
370 			break;
371 	}
372 }
373 
374 /* HC 4/14/98 */
WRITE_HANDLER(boothill_sh_port5_w)375 static WRITE_HANDLER( boothill_sh_port5_w )
376 {
377 	switch (data)
378 	{
379 		case 0x3b:
380 			sample_start (2, 1, 0);
381 			break;
382 	}
383 }
384 
385 
386 /*******************************************************/
387 /*                                                     */
388 /* Taito "Balloon Bomber"                              */
389 /*                                                     */
390 /*******************************************************/
391 
392 /* This only does the color swap for the explosion */
393 /* We do not have correct samples so sound not done */
394 
MACHINE_INIT(ballbomb)395 MACHINE_INIT( ballbomb )
396 {
397 	install_port_write_handler(0, 0x03, 0x03, ballbomb_sh_port3_w);
398 	install_port_write_handler(0, 0x05, 0x05, ballbomb_sh_port5_w);
399 }
400 
WRITE_HANDLER(ballbomb_sh_port3_w)401 static WRITE_HANDLER( ballbomb_sh_port3_w )
402 {
403 	c8080bw_screen_red_w(data & 0x04);
404 }
405 
WRITE_HANDLER(ballbomb_sh_port5_w)406 static WRITE_HANDLER( ballbomb_sh_port5_w )
407 {
408 	c8080bw_flip_screen_w(data & 0x20);
409 }
410 
411 
412 /*******************************************************/
413 /*                                                     */
414 /* Taito "Polaris"		                       */
415 /*                                                     */
416 /*******************************************************/
417 
418 const struct discrete_lfsr_desc polaris_lfsr={
419 	17,			/* Bit Length */
420 	0,			/* Reset Value */
421 	4,			/* Use Bit 4 as XOR input 0 */
422 	16,			/* Use Bit 16 as XOR input 1 */
423 	DISC_LFSR_XOR,		/* Feedback stage1 is XOR */
424 	DISC_LFSR_OR,		/* Feedback stage2 is just stage 1 output OR with external feed */
425 	DISC_LFSR_REPLACE,	/* Feedback stage3 replaces the shifted register contents */
426 	0x000001,		/* Everything is shifted into the first bit only */
427 	0,			/* Output is not inverted */
428 	12			/* Output bit */
429 };
430 
431 DISCRETE_SOUND_START(polaris_sound_interface)
432 
433 /* Nodes - Inputs */
434 #define POLARIS_MUSIC_DATA	NODE_01
435 #define POLARIS_SX0_EN		NODE_02
436 #define POLARIS_SX1_EN		NODE_03
437 #define POLARIS_SX2_EN		NODE_04
438 #define POLARIS_SX3_EN		NODE_05
439 #define POLARIS_SX5_EN		NODE_06
440 #define POLARIS_SX6_EN		NODE_07
441 #define POLARIS_SX7_EN		NODE_08
442 #define POLARIS_SX9_EN		NODE_09
443 #define POLARIS_SX10_EN		NODE_10
444 /* Nodes - Sounds */
445 #define POLARIS_MUSIC		NODE_11
446 #define POLARIS_NOISE_LO	NODE_12
447 #define POLARIS_NOISE_LO_FILT	NODE_13
448 #define POLARIS_NOISE_HI_FILT	NODE_14
449 #define POLARIS_SHOTSND		NODE_15
450 #define POLARIS_SHIP_HITSND	NODE_16
451 #define POLARIS_SHIPSND		NODE_17
452 #define POLARIS_EXPLOSIONSND	NODE_18
453 #define POLARIS_PLANESND	NODE_19
454 #define POLARIS_HITSND		NODE_20
455 #define POLARIS_SONARSND	NODE_21
456 #define POLARIS_FINAL_MIX	NODE_22
457 /* Nodes - Adjust */
458 #define POLARIS_ADJ_VR1		NODE_97
459 #define POLARIS_ADJ_VR2		NODE_98
460 #define POLARIS_ADJ_VR3		NODE_99
461 
462 	/************************************************/
463 	/* Polaris sound system: 8 Sound Sources        */
464 	/*                                              */
465 	/* Relative volumes are adjustable              */
466 	/*                                              */
467 	/*  Discrete sound mapping via:                 */
468 	/*     discrete_sound_w($register,value)        */
469 	/*  $00 - Music Data                            */
470 	/*  $01 - SX0                                   */
471 	/*  $02 - SX1                                   */
472 	/*  $03 - SX2                                   */
473 	/*  $04 - SX3                                   */
474 	/*  $05 - SX5                                   */
475 	/*  $06 - SX6                                   */
476 	/*  $07 - SX7                                   */
477 	/*  $08 - SX9                                   */
478 	/*  $09 - SX10                                  */
479 	/*                                              */
480 	/************************************************/
481 
482 	/************************************************/
483 	/* Input register mapping for polaris           */
484 	/************************************************/
485 	/*               NODE                ADDR  MASK    INIT */
486 	DISCRETE_INPUT(POLARIS_MUSIC_DATA  , 0x00, 0x000f, 0.0)
487 	DISCRETE_INPUT(POLARIS_SX0_EN      , 0x01, 0x000f, 0.0)
488 	DISCRETE_INPUT(POLARIS_SX1_EN      , 0x02, 0x000f, 0.0)
489 	DISCRETE_INPUT(POLARIS_SX2_EN      , 0x03, 0x000f, 0.0)
490 	DISCRETE_INPUT(POLARIS_SX3_EN      , 0x04, 0x000f, 0.0)
491 	DISCRETE_INPUT(POLARIS_SX5_EN      , 0x05, 0x000f, 0.0)
492 	DISCRETE_INPUT(POLARIS_SX6_EN      , 0x06, 0x000f, 0.0)
493 	DISCRETE_INPUT(POLARIS_SX7_EN      , 0x07, 0x000f, 0.0)
494 	DISCRETE_INPUT(POLARIS_SX9_EN      , 0x08, 0x000f, 0.0)
495 	DISCRETE_INPUT(POLARIS_SX10_EN     , 0x09, 0x000f, 0.0)
496 
497 	DISCRETE_ADJUSTMENT(POLARIS_ADJ_VR1, 1, 0, 1000, 800, DISC_LINADJ, "Sub Volume VR1")
498 	DISCRETE_ADJUSTMENT(POLARIS_ADJ_VR2, 1, 0, 1000, 700, DISC_LINADJ, "Sub Volume VR2")
499 	DISCRETE_ADJUSTMENT(POLARIS_ADJ_VR3, 1, 0, 1000, 900, DISC_LINADJ, "Sub Volume VR3")
500 
501 /******************************************************************************
502  *
503  * Music Generator
504  *
505  * This is a simulation of the following circuit:
506  * 555 Timer (Ra = 1k, Rb = 1k, C =.01uF) running at 48kHz.  Connected to a
507  * 1 bit counter (/2) for 24kHz.  But I will use the breadboarded frequency
508  * of 44140Hz/2.
509  * This is then sent to a preloadable 8 bit counter, which loads the value
510  * from Port 2 when overflowing from 0xFF to 0x00.  Therefore it divides by
511  * 2 (Port 2 = FE) to 256 (Port 2 = 00).
512  * This goes to a 2 bit counter which has a 47k resistor on Q0 and a 12k on Q1.
513  * This creates a sawtooth ramp of: 0%, 12/59%, 47/59%, 100% then back to 0%
514  *
515  * Note that there is no music disable line.  When there is no music, the game
516  * sets the oscillator to 0Hz.  (Port 2 = FF)
517  *
518  ******************************************************************************/
519 	DISCRETE_ADDER2(NODE_23, 1, POLARIS_MUSIC_DATA, 1)	/* To get values of 1 - 256 */
520 	DISCRETE_DIVIDE(NODE_24, 1, 44140.0/2/2, NODE_23)	/* /2 counter frequency */
521 	DISCRETE_DIVIDE(NODE_25, 1, 44140.0/2/4, NODE_23)	/* /4 counter frequency */
522 	DISCRETE_SQUAREWAVE(NODE_26, 1, NODE_24, 12.0/59.0*0.7527, 50.0, 0, 0.0)	/* /2 */
523 	DISCRETE_SQUAREWAVE(NODE_27, 1, NODE_25, 47.0/59.0*0.7527, 50.0, 0, 0.0)	/* /4 */
DISCRETE_ADDER2(NODE_28,POLARIS_MUSIC_DATA,NODE_26,NODE_27)524 	DISCRETE_ADDER2(NODE_28, POLARIS_MUSIC_DATA, NODE_26, NODE_27)	/* Port2=FF Disables audio */
525 	DISCRETE_MULTIPLY(NODE_29, 1, NODE_28, POLARIS_ADJ_VR3)	/* Basic Volume Adj */
526 	DISCRETE_RCFILTER(POLARIS_MUSIC, 1, NODE_29, 9559.0, 1.8e-10)
527 
528 /******************************************************************************
529  *
530  * Noise sources
531  *
532  * The frequencies for the noise sources were breadboarded to
533  * get an accurate value.
534  *
535  * Also we are going to cheat and reduce the gain of the HI noise a little to
536  * compensate for the computer being too accurate.
537  *
538  ******************************************************************************/
539 	DISCRETE_SQUAREWFIX(NODE_30, 1, (60.0/512.0), 1, 0.01, 1.0/2, 359.0)	/* feed frequency to keep the noise going */
540 
541 	DISCRETE_LFSR_NOISE(POLARIS_NOISE_LO, 1, 1, 830.0, 1.0, NODE_30, 0, &polaris_lfsr)  /* Unfiltered Lo noise */
542 
543 	DISCRETE_RCFILTER(NODE_31, 1, POLARIS_NOISE_LO, 560.0, 2.2e-7)
544 	DISCRETE_RCFILTER(POLARIS_NOISE_LO_FILT, 1, NODE_31, 6800.0, 2.2e-7)	/* Filtered Lo noise */
545 
546 	DISCRETE_LFSR_NOISE(NODE_32, 1, 1, 44140.0/2, 0.8, NODE_30, 0, &polaris_lfsr)
547 	DISCRETE_RCFILTER(NODE_33, 1, NODE_32, 560.0, 1.e-8)
548 	DISCRETE_RCFILTER(POLARIS_NOISE_HI_FILT, 1, NODE_33, 6800.0, 1.e-8)	/* Filtered Hi noise */
549 
550 /******************************************************************************
551  *
552  * Background Sonar Sound
553  *
554  * This is a background sonar that plays at all times during the game.
555  * It is a VCO triangle wave genarator, that uses the Low frequency filtered
556  * noise source for the frequency.  It goes from 1 to 1/1.12 of it's VCO range.
557  * This is then amplitude modulated, by some fancy clocking scheme.
558  * It is disabled during SX3.  (No sonar when you die.)
559  *
560  ******************************************************************************/
561 	DISCRETE_MULTIPLY(NODE_74, 1, POLARIS_ADJ_VR1, 0.7527)	/* Basic Volume Adj * Relative Gain */
562 
563 	DISCRETE_ADDER2(NODE_80, 1, POLARIS_NOISE_LO_FILT, 1.0/2)	/* Shift back to DC */
564 	DISCRETE_SQUAREWAVE(NODE_81, 1, 60.0/16.0, 1, 50.0, 1.0/2, 0)	/* Clock */
565 	DISCRETE_SQUAREWAVE(NODE_82, 1, 60.0/16.0/8.0, 1, 50.0, 1.0/2, 0)	/* Data */
566 	DISCRETE_LOGIC_OR(NODE_83, 1, NODE_82, POLARIS_SX3_EN)	/* OR for later enable */
567 	DISCRETE_SWITCH(NODE_84, 1, NODE_83, 0, NODE_74)	/* Overall gain */
568 	DISCRETE_SAMPLHOLD(NODE_85, 1, NODE_84, NODE_81, DISC_SAMPHOLD_REDGE)
569 	DISCRETE_SWITCH(NODE_86, 1, NODE_83, NODE_85, 0)/* Invert */
570 	DISCRETE_RCDISC2(NODE_87, NODE_85, NODE_86, 680000.0, NODE_86, 1000.0, 1e-6)	/* Decay envelope */
571 	DISCRETE_GAIN(NODE_88, NODE_80, 1800.0-(1800.0/1.12))
572 	DISCRETE_ADDER2(NODE_89, 1, NODE_88, 1800.0/1.12)
573 	DISCRETE_TRIANGLEWAVE(POLARIS_SONARSND, NODE_86, NODE_89, NODE_87, 0, 0)
574 
575 
576 /******************************************************************************
577  *
578  * Shot - SX0
579  *
580  * When Enabled it makes a low frequency RC filtered noise.  As soon as it
581  * disables, it switches to a high frequency RC filtered noise with the volume
582  * decaying based on the RC values of 680k and 1uF.
583  *
584  ******************************************************************************/
585 	DISCRETE_MULTIPLY(NODE_34, 1, POLARIS_SX0_EN, POLARIS_ADJ_VR1)	/* Basic Volume Adj */
586 	DISCRETE_MULTIPLY(NODE_35, 1, NODE_34, 0.6034)	/* Relative Gain */
587 	DISCRETE_RCDISC2(NODE_36, POLARIS_SX0_EN, NODE_35, 680000.0, NODE_35, 1000.0, 1e-6)	/* Decay envelope */
588 
589 	DISCRETE_MULTIPLY(NODE_37, 1, POLARIS_NOISE_LO_FILT, NODE_36)	/* Amplify noise using envelope */
590 	DISCRETE_MULTIPLY(NODE_38, 1, POLARIS_NOISE_HI_FILT, NODE_36)	/* Amplify noise using envelope */
591 
592 	DISCRETE_SWITCH(POLARIS_SHOTSND, 1, POLARIS_SX0_EN, NODE_38, NODE_37)
593 
594 /******************************************************************************
595  *
596  * Ship Hit (Sub) - SX1
597  *
598  * When Enabled it makes a low frequency RC filtered noise.  As soon as it
599  * disables, it's  volume starts decaying based on the RC values of 680k and
600  * 1uF.  Also as it decays, a decaying high frequency RC filtered noise is
601  * mixed in.
602  *
603  ******************************************************************************/
604 	DISCRETE_MULTIPLY(NODE_40, 1, POLARIS_SX1_EN, POLARIS_ADJ_VR2)	/* Basic Volume Adj */
605 	DISCRETE_MULTIPLY(NODE_41, 1, NODE_40, 0.4375)	/* Relative Gain */
606 	DISCRETE_RCDISC2(NODE_42, POLARIS_SX1_EN, NODE_41, 680000.0, NODE_41, 1000.0, 1e-6)	/* Decay envelope */
607 
608 	DISCRETE_MULTIPLY(NODE_43, 1, POLARIS_NOISE_LO_FILT, NODE_42)	/* Amplify noise using envelope */
609 	DISCRETE_MULTIPLY(NODE_44, 1, POLARIS_NOISE_HI_FILT, NODE_42)	/* Amplify noise using envelope */
610 
611 	DISCRETE_SWITCH(NODE_45, 1, POLARIS_SX1_EN, 0, NODE_44)
612 	DISCRETE_ADDER2(POLARIS_SHIP_HITSND, 1, NODE_43, NODE_45)
613 
614 /******************************************************************************
615  *
616  * Ship - SX2
617  *
618  * This uses a 5.75Hz |\|\ sawtooth the modulate the frequency of a
619  * voltage controlled triangle wave oscillator.  The voltage varies 10.5V - 1.5V
620  * causing the frequency to change from 2040Hz to 245Hz with a rise percentage
621  * changing from 60% to 68%.  Close enough to a 50% triangle to most ears.
622  *
623  ******************************************************************************/
624 	DISCRETE_SAWTOOTHWAVE(NODE_50, POLARIS_SX2_EN, 5.75, 2040.0-245.0, (2040.0-245.0)/2, 1, 0)	/* Modulation Wave */
625 	DISCRETE_ADDER2(NODE_51, 1, NODE_50, 245.0)
626 	DISCRETE_MULTIPLY(NODE_52, 1, POLARIS_ADJ_VR2, 0.6034)	/* Basic Volume Adj * Relative Gain */
627 	DISCRETE_TRIANGLEWAVE(POLARIS_SHIPSND, POLARIS_SX2_EN, NODE_51, NODE_52, 0, 0)
628 
629 /******************************************************************************
630  *
631  * Explosion - SX3
632  *
633  * When Enabled it makes a low frequency noise.  As soon as it disables, it's
634  * volume starts decaying based on the RC values of 680k and 0.33uF.  The
635  * final output is RC filtered.
636  *
637  * Note that when this is triggered, the sonar sound clock is disabled.
638  *
639  ******************************************************************************/
640 	DISCRETE_GAIN(NODE_55, POLARIS_SX3_EN, 2000.0)
641 	DISCRETE_RCDISC2(NODE_56, POLARIS_SX3_EN, NODE_55, 680000.0, NODE_55, 1000.0, 3.3e-7)	/* Decay envelope */
642 
643 	DISCRETE_MULTIPLY(NODE_57, 1, POLARIS_NOISE_LO, NODE_56)	/* Amplify noise using envelope */
644 
645 	DISCRETE_RCFILTER(NODE_58, 1, NODE_57, 560.0, 2.2e-7)
646 	DISCRETE_RCFILTER(POLARIS_EXPLOSIONSND, 1, NODE_58, 6800.0, 2.2e-7)
647 
648 /******************************************************************************
649  *
650  * Plane Down - SX6
651  * Plane Up   - SX7
652  *
653  * The oscillator is enabled when SX7 goes high. When SX6 is enabled the
654  * frequency lowers.  When SX6 is disabled the frequency ramps back up.
655  * Also some NOISE_HI_FILT is mixed in so the frequency varies some.
656  *
657  ******************************************************************************/
658 	DISCRETE_RAMP(NODE_70, POLARIS_SX7_EN, POLARIS_SX6_EN, (3240.0-410.0)/1.2, 3240.0, 410.0, 0)
659 	DISCRETE_GAIN(NODE_71, POLARIS_NOISE_HI_FILT, 0.1)
660 	DISCRETE_MULTIPLY(NODE_72, 1, NODE_70, NODE_71)
661 //	DISCRETE_MULTIPLY(NODE_72, 1, POLARIS_NOISE_LO, (3240.0-410.0)/10.0/2.0)
662 	DISCRETE_ADDER2(NODE_73, 1, NODE_70, NODE_72)	/* Add in 10% hi freq shift to final plane freq. */
663 	DISCRETE_TRIANGLEWAVE(POLARIS_PLANESND, POLARIS_SX7_EN, NODE_73, NODE_74, 0, 0)
664 
665 /******************************************************************************
666  *
667  * HIT - SX9 & SX10
668  *
669  * SX9 seems to be never used, so I am not sure if the schematic is correct.
670  * Following the schematic, 3 different sounds are produced.
671  * SX10  SX9  Effect
672  *  0     0   no sound
673  *  0     1   NOISE_HI_FILT while enabled
674  *  1     0   NOISE_LO_FILT while enabled
675  *  1     1   NOISE_HI_FILT & NOISE_LO_FILT decaying imediately @ 680k, 0.22uF
676  *
677  ******************************************************************************/
678 	DISCRETE_LOGIC_NAND(NODE_60, 1, POLARIS_SX9_EN, POLARIS_SX10_EN)
679 	DISCRETE_SWITCH(NODE_61, 1, NODE_60, 0, POLARIS_ADJ_VR1)	/* Always on except when SX9 and SX10 enabled */
680 	DISCRETE_RCDISC2(NODE_62, NODE_61, NODE_61, 680000.0, NODE_61, 1000.0, 2.2e-7)
681 	DISCRETE_MULTIPLY(NODE_63, POLARIS_SX9_EN, POLARIS_NOISE_HI_FILT, NODE_62)
682 	DISCRETE_MULTIPLY(NODE_64, POLARIS_SX10_EN, POLARIS_NOISE_LO_FILT, NODE_62)
683 	DISCRETE_ADDER2(POLARIS_HITSND, 1, NODE_63, NODE_64)
684 
685 /******************************************************************************
686  *
687  * Final Mixing and Output
688  *
689  ******************************************************************************/
690 
691 	DISCRETE_ADDER4(NODE_90, 1, POLARIS_SHOTSND, POLARIS_HITSND, POLARIS_PLANESND, POLARIS_SONARSND)	/* VR1 */
692 	DISCRETE_ADDER2(NODE_91, 1, POLARIS_SHIP_HITSND, POLARIS_SHIPSND)					/* VR2 */
693 	DISCRETE_ADDER4(NODE_92, POLARIS_SX5_EN, NODE_90, NODE_91, POLARIS_MUSIC, POLARIS_EXPLOSIONSND)
694 	DISCRETE_GAIN(POLARIS_FINAL_MIX, NODE_92, 65534.0/3000.0)
695 	DISCRETE_OUTPUT(POLARIS_FINAL_MIX, 100)
696 
697 DISCRETE_SOUND_END
698 
699 MACHINE_INIT( polaris )
700 {
701 	install_port_write_handler(0, 0x02, 0x02, polaris_sh_port2_w);
702 	install_port_write_handler(0, 0x04, 0x04, polaris_sh_port4_w);
703 	install_port_write_handler(0, 0x06, 0x06, polaris_sh_port6_w);
704 }
705 
WRITE_HANDLER(polaris_sh_port2_w)706 static WRITE_HANDLER( polaris_sh_port2_w )
707 {
708 	discrete_sound_w(0, (~data) & 0xff);
709 }
710 
WRITE_HANDLER(polaris_sh_port4_w)711 static WRITE_HANDLER( polaris_sh_port4_w )
712 {
713 	/* 0x01 - SX0 - Shot */
714 	discrete_sound_w(1, data & 0x01);
715 
716 	/* 0x02 - SX1 - Ship Hit (Sub) */
717 	discrete_sound_w(2, (data & 0x02) >> 1);
718 
719 	/* 0x04 - SX2 - Ship */
720 	discrete_sound_w(3, (data & 0x04) >> 2 );
721 
722 	/* 0x08 - SX3 - Explosion */
723 	discrete_sound_w(4, (data & 0x08) >> 3);
724 
725 	/* 0x10 - SX4 */
726 
727 	/* 0x20 - SX5 - Sound Enable */
728 	discrete_sound_w(5, (data & 0x20) >> 5);
729 }
730 
WRITE_HANDLER(polaris_sh_port6_w)731 static WRITE_HANDLER( polaris_sh_port6_w )
732 {
733 	coin_lockout_global_w(data & 0x04);  /* SX8 */
734 
735 	c8080bw_flip_screen_w(data & 0x20);  /* SX11 */
736 
737 	/* 0x01 - SX6 - Plane Down */
738 	discrete_sound_w(6, (data & 0x01) );
739 
740 	/* 0x02 - SX7 - Plane Up */
741 	discrete_sound_w(7, (data & 0x02) >> 1 );
742 
743 	/* 0x08 - SX9 - Hit */
744 	discrete_sound_w(9, (data & 0x08) >> 3);
745 
746 	/* 0x10 - SX10 - Hit */
747 	discrete_sound_w(9, (data & 0x10) >> 4);
748 }
749 
750 
751 /*******************************************************/
752 /*                                                     */
753 /* Nintendo "Sheriff"                              	   */
754 /*                                                     */
755 /*******************************************************/
756 
757 struct DACinterface sheriff_dac_interface =
758 {
759 	1,
760 	{ 50 }
761 };
762 
763 struct SN76477interface sheriff_sn76477_interface =
764 {
765 	1,	/* 1 chip */
766 	{ 50 },  /* mixing level   pin description		 */
767 	{ RES_K( 36)   },		/*	4  noise_res		 */
768 	{ RES_K(100)   },		/*	5  filter_res		 */
769 	{ CAP_U(0.001) },		/*	6  filter_cap		 */
770 	{ RES_K(620)   },		/*	7  decay_res		 */
771 	{ CAP_U(1.0)   },		/*	8  attack_decay_cap  */
772 	{ RES_K(20)    },		/* 10  attack_res		 */
773 	{ RES_K(150)   },		/* 11  amplitude_res	 */
774 	{ RES_K(47)    },		/* 12  feedback_res 	 */
775 	{ 0            },		/* 16  vco_voltage		 */
776 	{ CAP_U(0.001) },		/* 17  vco_cap			 */
777 	{ RES_M(1.5)   },		/* 18  vco_res			 */
778 	{ 0.0		   },		/* 19  pitch_voltage	 */
779 	{ RES_M(1.5)   },		/* 20  slf_res			 */
780 	{ CAP_U(0.047) },		/* 21  slf_cap			 */
781 	{ CAP_U(0.047) },		/* 23  oneshot_cap		 */
782 	{ RES_K(560)   }		/* 24  oneshot_res		 */
783 };
784 
785 
sheriff_74123_0_output_changed_cb(void)786 static void sheriff_74123_0_output_changed_cb(void)
787 {
788 logerror("74123 0 triggered\n");
789 	SN76477_vco_w    (0,  TTL74123_output_r(0));
790 	SN76477_mixer_b_w(0, !TTL74123_output_r(0));
791 
792 	SN76477_enable_w(0, TTL74123_output_comp_r(0) && TTL74123_output_comp_r(1));
793 }
794 
sheriff_74123_1_output_changed_cb(void)795 static void sheriff_74123_1_output_changed_cb(void)
796 {
797 logerror("74123 1 triggered\n");
798 	SN76477_set_vco_voltage(0, !TTL74123_output_comp_r(1) ? 5.0 : 0.0);
799 
800 	SN76477_enable_w(0, TTL74123_output_comp_r(0) && TTL74123_output_comp_r(1));
801 }
802 
803 static struct TTL74123_interface sheriff_74123_0_intf =
804 {
805 	RES_K(33),
806 	CAP_U(33),
807 	sheriff_74123_0_output_changed_cb
808 };
809 
810 static struct TTL74123_interface sheriff_74123_1_intf =
811 {
812 	RES_K(33),
813 	CAP_U(33),
814 	sheriff_74123_1_output_changed_cb
815 };
816 
817 
MACHINE_INIT(sheriff)818 MACHINE_INIT( sheriff )
819 {
820 	install_port_write_handler(0, 0x04, 0x04, sheriff_sh_port4_w);
821 	install_port_write_handler(0, 0x05, 0x05, sheriff_sh_port5_w);
822 	install_port_write_handler(0, 0x06, 0x06, sheriff_sh_port6_w);
823 
824 	TTL74123_config(0, &sheriff_74123_0_intf);
825 	TTL74123_config(1, &sheriff_74123_1_intf);
826 
827 	/* set up the fixed connections */
828 	TTL74123_reset_comp_w  (0, 1);
829 	TTL74123_trigger_comp_w(0, 0);
830 
831 	TTL74123_trigger_comp_w(1, 0);
832 
833 	SN76477_envelope_1_w(0, 1);
834 	SN76477_envelope_2_w(0, 0);
835 	SN76477_noise_clock_w(0, 0);
836 	SN76477_mixer_a_w(0, 0);
837 	SN76477_mixer_c_w(0, 0);
838 }
839 
840 
841 static int sheriff_t0,sheriff_t1,sheriff_p1,sheriff_p2;
842 
843 
WRITE_HANDLER(sheriff_sh_port4_w)844 static WRITE_HANDLER( sheriff_sh_port4_w )
845 {
846 static int last = -1;
847 	// 0 - P2.7 - GAME
848 	// 1 - P2.5 - EXCEL
849 	// 2 - P2.6 - IMAN BRK
850 	// 3 - P2.3 - GMAN BRK
851 	// 4 - P2.4 - GMAN TRIG
852 	// 5 - P2.1 - BRD APR
853 if ((last & 0x10) != (data & 0x10))
854 {
855 logerror("***Gun: %02X %04X\n", data & 0x14, activecpu_get_pc());
856 last = data;
857 }
858 
859 	sheriff_t0 = data & 1;
860 
861 	sheriff_p1 = (sheriff_p1 & 0x4f) |
862 				 ((data & 0x02) << 3) |		/* P1.4 */
863 				 ((data & 0x08) << 2) |		/* P1.5 */
864 				 ((data & 0x20) << 2);		/* P1.7 */
865 
866 	soundlatch_w(0, sheriff_p1);
867 
868 	cpu_set_irq_line(1, 0, ((sheriff_p1 & 0x70) == 0x70) ? ASSERT_LINE : CLEAR_LINE);
869 
870 	TTL74123_trigger_w   (0, data & 0x04);
871 
872 	TTL74123_reset_comp_w(1, ~data & 0x04);
873 	TTL74123_trigger_w   (1, data & 0x10);
874 }
875 
WRITE_HANDLER(sheriff_sh_port5_w)876 static WRITE_HANDLER( sheriff_sh_port5_w )
877 {
878 	// 0 - P2.8  - IMAN S0
879 	// 1 - P2.9  - IMAN S1
880 	// 2 - P2.10 - IMAN S2
881 	// 3 - P2.11 - IMAN S3
882 	// 4 - P2.2  - ARROW
883 	// 5 - P2.12 - BRD BRK
884 
885 	sheriff_t1 = (data >> 5) & 1;
886 
887 	sheriff_p1 = (sheriff_p1 & 0xb0) |
888 				 ((data & 0x01) << 3) |		/* P1.3 */
889 				 ((data & 0x02) << 1) |		/* P1.2 */
890 				 ((data & 0x04) >> 1) |		/* P1.1 */
891 				 ((data & 0x08) >> 3) |		/* P1.0 */
892 				 ((data & 0x10) << 2);		/* P1.6 */
893 
894 	soundlatch_w(0, sheriff_p1);
895 
896 	cpu_set_irq_line(1, 0, ((sheriff_p1 & 0x70) == 0x70) ? ASSERT_LINE : CLEAR_LINE);
897 }
898 
WRITE_HANDLER(sheriff_sh_port6_w)899 static WRITE_HANDLER( sheriff_sh_port6_w )
900 {
901 	flip_screen_set(data & 0x20);
902 }
903 
904 
READ_HANDLER(sheriff_sh_t0_r)905 READ_HANDLER( sheriff_sh_t0_r )
906 {
907 	return sheriff_t0;
908 }
909 
READ_HANDLER(sheriff_sh_t1_r)910 READ_HANDLER( sheriff_sh_t1_r )
911 {
912 	return sheriff_t1;
913 }
914 
READ_HANDLER(sheriff_sh_p1_r)915 READ_HANDLER( sheriff_sh_p1_r )
916 {
917 	return soundlatch_r(0);;
918 }
919 
READ_HANDLER(sheriff_sh_p2_r)920 READ_HANDLER( sheriff_sh_p2_r )
921 {
922 	return sheriff_p2;
923 }
924 
WRITE_HANDLER(sheriff_sh_p2_w)925 WRITE_HANDLER( sheriff_sh_p2_w )
926 {
927 	sheriff_p2 = data;
928 
929 	DAC_data_w(0, sheriff_p2 & 0x80 ? 0xff : 0x00);
930 }
931 
932 
933 /*******************************************************/
934 /*                                                     */
935 /* Nintendo "HeliFire"		                           */
936 /*                                                     */
937 /*******************************************************/
938 
939 /* Note: the game uses 8-bit DAC and a RC circuit to control the DAC's volume */
940 
941 /* I used 16 bits for the DAC data for better quality of the volume control */
942 
943 /* the following resistances are a guesswork */
944 #define R1		500		/* DAC Vref charge resistance */
945 #define R2		16000	/* DAC Vref discharge resistance */
946 #define C43		10.0e-6	/* C43 is 10 uF in the schematics */
947 
948 #define VMIN	0		/* I'm not sure whether the circuit can discharge to zero level? */
949 #define VMAX	32768
950 
951 static int Vref;		/* reference voltage for the 8-bit DAC */
952 static int counter;
953 
954 static double ar_rate;
955 static double dr_rate;
956 
957 static int Vref_control;		/* 1 - charge capacitor, 0 - discharge it */
958 static int samplerate = 400;	/* 400 changes per second - arbitrary resolution */
959 static void	*capacitor_timer;	/* samplerate timer for capacitor calculations */
960 
961 static int current_dac_data;
962 
cap_timer_callback(int param_not_used)963 void cap_timer_callback (int param_not_used)
964 {
965 	switch( Vref_control)
966 	{
967 		case 1:		/* capacitor charge */
968 			if (Vref < VMAX)
969 			{
970 				counter -= (int)((VMAX - Vref) / ar_rate);
971 				if ( counter <= 0 )
972 				{
973 					int n = -counter / samplerate + 1;
974 					counter += n * samplerate;
975 					if ( (Vref += n) > VMAX )
976 						Vref = VMAX;
977 				}
978 				/*logerror("vref charge=%4x\n",Vref);*/
979 			}
980 			break;
981 
982 		default:	/* capacitor discharge */
983 			if (Vref > VMIN)
984 			{
985 				counter -= (int)((Vref - VMIN) / dr_rate);
986 				if ( counter <= 0 )
987 				{
988 					int n = -counter / samplerate + 1;
989 					counter += n * samplerate;
990 					if ( (Vref -= n) < VMIN )
991 						Vref = VMIN;
992 				}
993 				/*logerror("vref discharge=%4x\n",Vref);*/
994 			}
995 			break;
996 	}
997 
998 	DAC_data_16_w(0, (current_dac_data * Vref) >> 8 );
999 }
1000 
MACHINE_INIT(helifire)1001 MACHINE_INIT( helifire )
1002 {
1003 	install_port_write_handler(0, 0x04, 0x04, helifire_sh_port4_w);
1004 	install_port_write_handler(0, 0x05, 0x05, helifire_sh_port5_w);
1005 	install_port_write_handler(0, 0x06, 0x06, helifire_sh_port6_w);
1006 
1007 	Vref = 0;
1008 	Vref_control = 0;
1009 
1010 	counter = 0;
1011 	ar_rate= (double)R1 * (double)C43;
1012 	dr_rate= (double)R2 * (double)C43;
1013 
1014 	capacitor_timer = timer_alloc(cap_timer_callback);
1015 	timer_adjust(capacitor_timer, TIME_IN_HZ(samplerate), 0, TIME_IN_HZ(samplerate));
1016 }
1017 
1018 static int helifire_t0, helifire_t1;//, helifire_p1, helifire_p2;
1019 static int helifire_snd_latch;
1020 
WRITE_HANDLER(helifire_sh_port4_w)1021 static WRITE_HANDLER( helifire_sh_port4_w )
1022 {
1023 	// 0 - P2.7 -      ->D0
1024 	// 1 - NC
1025 	// 2 - P2.6 -      ->INT
1026 	// 3 - P2.3 -      ->T0
1027 	// 4 - P2.4 -      ->T1
1028 	// 5 - P2.1 - GAME ->D3
1029 
1030 	data ^= 0xff; /* negated on page 2 just before going to P2 */
1031 
1032 	helifire_t1 = (data&0x10) >> 4;
1033 	helifire_t0 = (data&0x08) >> 3;
1034 
1035 	helifire_snd_latch = (helifire_snd_latch & 0x06) |
1036 				 ((data & 0x01) << 0) |
1037 				 ((data & 0x20) >> 2);
1038 
1039 	cpu_set_irq_line(1, 0, (data & 0x04) ? ASSERT_LINE : CLEAR_LINE);
1040 
1041 logerror("port04 write: %02x &4=%1x\n", data, data&4);
1042 }
1043 
WRITE_HANDLER(helifire_sh_port5_w)1044 static WRITE_HANDLER( helifire_sh_port5_w )
1045 {
1046 	// 0 - P2.8  -     ->D1 (or D2 ?)
1047 	// 1 - P2.9  -     ->D2 (or D1 ?)
1048 	// 2 - P2.10 -
1049 	// 3 - P2.11 -
1050 	// 4 - P2.2  -
1051 	// 5 - P2.12 -     ->PB4
1052 
1053 	data ^= 0xff; /* negated on page 2 just before going to P2 */
1054 
1055 	helifire_snd_latch = (helifire_snd_latch & 0x09) |
1056 				 ((data & 0x01) << 1) |
1057 				 ((data & 0x02) << 1);
1058 
1059 	c8080bw_helifire_colors_change_w(data & 0x20); /* 1 - don't change colors, 0 - change font and object colors */
1060 
1061 logerror("port05 write: %02x\n",data);
1062 
1063 }
1064 
WRITE_HANDLER(helifire_sh_port6_w)1065 static WRITE_HANDLER( helifire_sh_port6_w )
1066 {
1067 	flip_screen_set(data & 0x20);
1068 }
1069 
WRITE_HANDLER(helifire_sh_p1_w)1070 WRITE_HANDLER( helifire_sh_p1_w )
1071 {
1072 	current_dac_data = data;
1073 
1074 	DAC_data_16_w(0, (current_dac_data * Vref) >> 8);
1075 }
1076 
1077 
WRITE_HANDLER(helifire_sh_p2_w)1078 WRITE_HANDLER( helifire_sh_p2_w )
1079 {
1080 	Vref_control = (data&0x80) >> 7;
1081 	/*logerror("dac_vref_charge=%1x\n", Vref_control);*/
1082 }
1083 
READ_HANDLER(helifire_sh_p1_r)1084 READ_HANDLER( helifire_sh_p1_r )
1085 {
1086 	return helifire_snd_latch;
1087 }
1088 
1089 /*******************************************************/
1090 /*                                                     */
1091 /* Midway "Phantom II"		                           */
1092 /*                                                     */
1093 /*******************************************************/
1094 
MACHINE_INIT(phantom2)1095 MACHINE_INIT( phantom2 )
1096 {
1097 	install_port_write_handler(0, 0x04, 0x04, watchdog_reset_w);
1098 }
1099 
1100 
1101 /*******************************************************/
1102 /*                                                     */
1103 /* Midway "4 Player Bowling Alley"					   */
1104 /*                                                     */
1105 /*******************************************************/
1106 
MACHINE_INIT(bowler)1107 MACHINE_INIT( bowler )
1108 {
1109 	install_port_write_handler(0, 0x04, 0x04, watchdog_reset_w);
1110 	install_port_write_handler(0, 0x07, 0x07, bowler_bonus_display_w);
1111 }
1112 
1113 
1114 /*******************************************************/
1115 /*                                                     */
1116 /* Midway "Sea Wolf"                                   */
1117 /*                                                     */
1118 /*******************************************************/
1119 
1120 static const char *seawolf_sample_names[] =
1121 {
1122 	"*seawolf",
1123 	"shiphit.wav",
1124 	"torpedo.wav",
1125 	"dive.wav",
1126 	"sonar.wav",
1127 	"minehit.wav",
1128 	0       /* end of array */
1129 };
1130 
1131 struct Samplesinterface seawolf_samples_interface =
1132 {
1133 	5,	/* 5 channels */
1134 	25,	/* volume */
1135 	seawolf_sample_names
1136 };
1137 
MACHINE_INIT(seawolf)1138 MACHINE_INIT( seawolf )
1139 {
1140 /*  Lamp Display Output (write) Ports are as follows:
1141 
1142 Port 1:
1143   Basically D0-D3 are column drivers and D4-D7 are row drivers.
1144   The folowing table shows values that light up individual lamps.
1145 
1146 	D7 D6 D5 D4 D3 D2 D1 D0   Function
1147 	--------------------------------------------------------------------------------------
1148 	 0  0  0  1  1  0  0  0   Explosion Lamp 0
1149 	 0  0  0  1  0  1  0  0   Explosion Lamp 1
1150 	 0  0  0  1  0  0  1  0   Explosion Lamp 2
1151 	 0  0  0  1  0  0  0  1   Explosion Lamp 3
1152 	 0  0  1  0  1  0  0  0   Explosion Lamp 4
1153 	 0  0  1  0  0  1  0  0   Explosion Lamp 5
1154 	 0  0  1  0  0  0  1  0   Explosion Lamp 6
1155 	 0  0  1  0  0  0  0  1   Explosion Lamp 7
1156 	 0  1  0  0  1  0  0  0   Explosion Lamp 8
1157 	 0  1  0  0  0  1  0  0   Explosion Lamp 9
1158 	 0  1  0  0  0  0  1  0   Explosion Lamp A
1159 	 0  1  0  0  0  0  0  1   Explosion Lamp B
1160 	 1  0  0  0  1  0  0  0   Explosion Lamp C
1161 	 1  0  0  0  0  1  0  0   Explosion Lamp D
1162 	 1  0  0  0  0  0  1  0   Explosion Lamp E
1163 	 1  0  0  0  0  0  0  1   Explosion Lamp F
1164 
1165 Port 2:
1166 	D7 D6 D5 D4 D3 D2 D1 D0   Function
1167 	--------------------------------------------------------------------------------------
1168 	 x  x  x  x  x  x  x  1   Torpedo 1
1169 	 x  x  x  x  x  x  1  x   Torpedo 2
1170 	 x  x  x  x  x  1  x  x   Torpedo 3
1171 	 x  x  x  x  1  x  x  x   Torpedo 4
1172 	 x  x  x  1  x  x  x  x   Ready
1173 	 x  x  1  x  x  x  x  x   Reload
1174 
1175 */
1176 
1177 	install_port_read_handler (0, 0x01, 0x01, seawolf_port_1_r);
1178 
1179 	install_port_write_handler(0, 0x05, 0x05, seawolf_sh_port5_w);
1180 
1181 }
1182 
WRITE_HANDLER(seawolf_sh_port5_w)1183 static WRITE_HANDLER( seawolf_sh_port5_w )
1184 {
1185 	if (data & 0x01)
1186 		sample_start (0, 0, 0);  /* Ship Hit */
1187 	if (data & 0x02)
1188 		sample_start (1, 1, 0);  /* Torpedo */
1189 	if (data & 0x04)
1190 		sample_start (2, 2, 0);  /* Dive */
1191 	if (data & 0x08)
1192 		sample_start (3, 3, 0);  /* Sonar */
1193 	if (data & 0x10)
1194 		sample_start (4, 4, 0);  /* Mine Hit */
1195 
1196 	coin_counter_w(0, (data & 0x20) >> 5);    /* Coin Counter */
1197 }
1198 
1199 
1200 /*******************************************************/
1201 /*                                                     */
1202 /* Midway "Desert Gun"                                 */
1203 /*                                                     */
1204 /*******************************************************/
1205 
MACHINE_INIT(desertgu)1206 MACHINE_INIT( desertgu )
1207 {
1208 	install_port_read_handler (0, 0x01, 0x01, desertgu_port_1_r);
1209 
1210 	install_port_write_handler(0, 0x07, 0x07, desertgu_controller_select_w);
1211 }
1212 
1213 
1214 /*******************************************************/
1215 /*                                                     */
1216 /* Taito "Space Chaser" 							   */
1217 /*                                                     */
1218 /*******************************************************/
1219 
1220 /*
1221  *  The dot sound is a square wave clocked by either the
1222  *  the 8V or 4V signals
1223  *
1224  *  The frequencies are (for the 8V signal):
1225  *
1226  *  19.968 MHz crystal / 2 (Qa of 74160 #10) -> 9.984MHz
1227  *					   / 2 (7474 #14) -> 4.992MHz
1228  *					   / 256+16 (74161 #5 and #8) -> 18352.94Hz
1229  *					   / 8 (8V) -> 2294.12 Hz
1230  * 					   / 2 the final freq. is 2 toggles -> 1147.06Hz
1231  *
1232  *  for 4V, it's double at 2294.12Hz
1233  */
1234 
1235 static int channel_dot;
1236 
1237 struct SN76477interface schaser_sn76477_interface =
1238 {
1239 	1,	/* 1 chip */
1240 	{ 50 },  /* mixing level   pin description		 */
1241 	{ RES_K( 47)   },		/*	4  noise_res		 */
1242 	{ RES_K(330)   },		/*	5  filter_res		 */
1243 	{ CAP_P(470)   },		/*	6  filter_cap		 */
1244 	{ RES_M(2.2)   },		/*	7  decay_res		 */
1245 	{ CAP_U(1.0)   },		/*	8  attack_decay_cap  */
1246 	{ RES_K(4.7)   },		/* 10  attack_res		 */
1247 	{ 0			   },		/* 11  amplitude_res (variable)	 */
1248 	{ RES_K(33)    },		/* 12  feedback_res 	 */
1249 	{ 0            },		/* 16  vco_voltage		 */
1250 	{ CAP_U(0.1)   },		/* 17  vco_cap			 */
1251 	{ RES_K(39)    },		/* 18  vco_res			 */
1252 	{ 5.0		   },		/* 19  pitch_voltage	 */
1253 	{ RES_K(120)   },		/* 20  slf_res			 */
1254 	{ CAP_U(1.0)   },		/* 21  slf_cap			 */
1255 	{ 0 		   },		/* 23  oneshot_cap (variable) */
1256 	{ RES_K(220)   }		/* 24  oneshot_res		 */
1257 };
1258 
1259 struct DACinterface schaser_dac_interface =
1260 {
1261 	1,
1262 	{ 50 }
1263 };
1264 
1265 struct CustomSound_interface schaser_custom_interface =
1266 {
1267 	schaser_sh_start,
1268 	schaser_sh_stop,
1269 	schaser_sh_update
1270 };
1271 
1272 static INT16 backgroundwave[32] =
1273 {
1274     0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
1275     0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
1276    -0x8000,-0x8000,-0x8000,-0x8000,-0x8000,-0x8000,-0x8000,-0x8000,
1277    -0x8000,-0x8000,-0x8000,-0x8000,-0x8000,-0x8000,-0x8000,-0x8000,
1278 };
1279 
MACHINE_INIT(schaser)1280 MACHINE_INIT( schaser )
1281 {
1282 	install_port_write_handler(0, 0x03, 0x03, schaser_sh_port3_w);
1283 	install_port_write_handler(0, 0x05, 0x05, schaser_sh_port5_w);
1284 
1285 	SN76477_mixer_a_w(0, 0);
1286 	SN76477_mixer_c_w(0, 0);
1287 
1288 	SN76477_envelope_1_w(0, 1);
1289 	SN76477_envelope_2_w(0, 0);
1290 }
1291 
WRITE_HANDLER(schaser_sh_port3_w)1292 static WRITE_HANDLER( schaser_sh_port3_w )
1293 {
1294 	int explosion;
1295 
1296 	/* bit 0 - Dot Sound Enable (SX0)
1297 	   bit 1 - Dot Sound Pitch (SX1)
1298 	   bit 2 - Effect Sound A (SX2)
1299 	   bit 3 - Effect Sound B (SX3)
1300 	   bit 4 - Effect Sound C (SX4)
1301 	   bit 5 - Explosion (SX5) */
1302 
1303 	if (channel_dot)
1304 	{
1305 		int freq;
1306 
1307 		mixer_set_volume(channel_dot, (data & 0x01) ? 100 : 0);
1308 
1309 		freq = 19968000 / 2 / 2 / (256+16) / ((data & 0x02) ? 8 : 4) / 2;
1310 		mixer_set_sample_frequency(channel_dot, freq);
1311 	}
1312 
1313 	explosion = (data >> 5) & 0x01;
1314 	if (explosion)
1315 	{
1316 		SN76477_set_amplitude_res(0, RES_K(200));
1317 		SN76477_set_oneshot_cap(0, CAP_U(0.1));		/* ???? */
1318 	}
1319 	else
1320 	{
1321 		/* 68k and 200k resistors in parallel */
1322 		SN76477_set_amplitude_res(0, RES_K(1.0/((1.0/200.0)+(1.0/68.0))));
1323 		SN76477_set_oneshot_cap(0, CAP_U(0.1));		/* ???? */
1324 	}
1325 	SN76477_enable_w(0, !explosion);
1326 	SN76477_mixer_b_w(0, explosion);
1327 }
1328 
WRITE_HANDLER(schaser_sh_port5_w)1329 static WRITE_HANDLER( schaser_sh_port5_w )
1330 {
1331 	/* bit 0 - Music (DAC) (SX6)
1332 	   bit 1 - Sound Enable (SX7)
1333 	   bit 2 - Coin Lockout (SX8)
1334 	   bit 3 - Field Control A (SX9)
1335 	   bit 4 - Field Control B (SX10)
1336 	   bit 5 - Flip Screen */
1337 
1338 	DAC_data_w(0, data & 0x01 ? 0xff : 0x00);
1339 
1340 	mixer_sound_enable_global_w(data & 0x02);
1341 
1342 	coin_lockout_global_w(data & 0x04);
1343 
1344 	c8080bw_flip_screen_w(data & 0x20);
1345 }
1346 
schaser_sh_start(const struct MachineSound * msound)1347 static int schaser_sh_start(const struct MachineSound *msound)
1348 {
1349 	channel_dot = mixer_allocate_channel(50);
1350 	mixer_set_name(channel_dot,"Dot Sound");
1351 
1352 	mixer_set_volume(channel_dot,0);
1353 	mixer_play_sample_16(channel_dot,backgroundwave,sizeof(backgroundwave),1000,1);
1354 
1355 	return 0;
1356 }
1357 
schaser_sh_stop(void)1358 static void schaser_sh_stop(void)
1359 {
1360 	mixer_stop_sample(channel_dot);
1361 }
1362 
schaser_sh_update(void)1363 static void schaser_sh_update(void)
1364 {
1365 }
1366 
1367 
WRITE_HANDLER(clowns_sh_port7_w)1368 static WRITE_HANDLER( clowns_sh_port7_w )
1369 {
1370 /* bit 0x08 seems to always be enabled.  Possibly sound enable? */
1371 /* A new sample set needs to be made with 3 different balloon sounds,
1372    and the code modified to suit. */
1373 
1374 	if (data & 0x01)
1375 		sample_start (0, 0, 0);  /* Bottom Balloon Pop */
1376 
1377 	if (data & 0x02)
1378 		sample_start (0, 0, 0);  /* Middle Balloon Pop */
1379 
1380 	if (data & 0x04)
1381 		sample_start (0, 0, 0);  /* Top Balloon Pop */
1382 
1383 	if (data & 0x10)
1384 		sample_start (2, 2, 0);  /* Bounce */
1385 
1386 	if (data & 0x20)
1387 		sample_start (1, 1, 0);  /* Splat */
1388 }
1389 
MACHINE_INIT(clowns)1390 MACHINE_INIT( clowns )
1391 {
1392 	/* Ports 5 & 6 are probably the music channels. They change value when
1393 	 * a bonus is made. */
1394 
1395 	install_port_write_handler (0, 0x07, 0x07, clowns_sh_port7_w);
1396 }
1397