1 /***************************************************************************
2 
3   machine.c
4 
5   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
6   I/O ports)
7 
8 ***************************************************************************/
9 
10 #include "driver.h"
11 #include "vidhrdw/generic.h"
12 #include "sndhrdw/williams.h"
13 #include "cpu/m6800/m6800.h"
14 #include "cpu/m6809/m6809.h"
15 #include "6821pia.h"
16 #include "machine/ticket.h"
17 #include "williams.h"
18 
19 
20 /* banking addresses set by the drivers */
21 UINT8 *williams_bank_base;
22 UINT8 *defender_bank_base;
23 const UINT32 *defender_bank_list;
24 UINT8 *mayday_protection;
25 
26 /* internal bank switching tracking */
27 static UINT8 blaster_bank;
28 static UINT8 vram_bank;
29 UINT8 williams2_bank;
30 
31 /* switches controlled by $c900 */
32 UINT16 sinistar_clip;
33 UINT8 williams_cocktail;
34 
35 /* other stuff */
36 static UINT16 joust2_current_sound_data;
37 
38 /* older-Williams routines */
39 static void williams_main_irq(int state);
40 static void williams_main_firq(int state);
41 static void williams_snd_irq(int state);
42 static WRITE_HANDLER( williams_snd_cmd_w );
43 static WRITE_HANDLER( playball_snd_cmd_w );
44 
45 /* input port mapping */
46 static UINT8 port_select;
47 static WRITE_HANDLER( williams_port_select_w );
48 static READ_HANDLER( williams_input_port_0_3_r );
49 static READ_HANDLER( williams_input_port_49way_0_5_r );
50 static READ_HANDLER( williams_input_port_1_4_r );
51 static READ_HANDLER( williams_49way_port_0_r );
52 
53 /* newer-Williams routines */
54 static WRITE_HANDLER( williams2_snd_cmd_w );
55 
56 /* Defender-specific code */
57 READ_HANDLER( defender_input_port_0_r );
58 static READ_HANDLER( defender_io_r );
59 static WRITE_HANDLER( defender_io_w );
60 
61 /* Stargate-specific code */
62 READ_HANDLER( stargate_input_port_0_r );
63 
64 /* Lotto Fun-specific code */
65 static READ_HANDLER( lottofun_input_port_0_r );
66 
67 /* Turkey Shoot-specific code */
68 static READ_HANDLER( tshoot_input_port_0_3_r );
69 static WRITE_HANDLER( tshoot_lamp_w );
70 static WRITE_HANDLER( tshoot_maxvol_w );
71 
72 /* Joust 2-specific code */
73 static WRITE_HANDLER( joust2_snd_cmd_w );
74 static WRITE_HANDLER( joust2_pia_3_cb1_w );
75 
76 
77 
78 /*************************************
79  *
80  *	Generic old-Williams PIA interfaces
81  *
82  *************************************/
83 
84 /* Generic PIA 0, maps to input ports 0 and 1 */
85 struct pia6821_interface williams_pia_0_intf =
86 {
87 	/*inputs : A/B,CA/B1,CA/B2 */ input_port_0_r, input_port_1_r, 0, 0, 0, 0,
88 	/*outputs: A/B,CA/B2       */ 0, 0, 0, 0,
89 	/*irqs   : A/B             */ 0, 0
90 };
91 
92 /* Generic muxing PIA 0, maps to input ports 0/3 and 1; port select is CB2 */
93 struct pia6821_interface williams_muxed_pia_0_intf =
94 {
95 	/*inputs : A/B,CA/B1,CA/B2 */ williams_input_port_0_3_r, input_port_1_r, 0, 0, 0, 0,
96 	/*outputs: A/B,CA/B2       */ 0, 0, 0, williams_port_select_w,
97 	/*irqs   : A/B             */ 0, 0
98 };
99 
100 /* Generic dual muxing PIA 0, maps to input ports 0/3 and 1/4; port select is CB2 */
101 struct pia6821_interface williams_dual_muxed_pia_0_intf =
102 {
103 	/*inputs : A/B,CA/B1,CA/B2 */ williams_input_port_0_3_r, williams_input_port_1_4_r, 0, 0, 0, 0,
104 	/*outputs: A/B,CA/B2       */ 0, 0, 0, williams_port_select_w,
105 	/*irqs   : A/B             */ 0, 0
106 };
107 
108 /* Generic 49-way joystick PIA 0 for Sinistar/Blaster */
109 struct pia6821_interface williams_49way_pia_0_intf =
110 {
111 	/*inputs : A/B,CA/B1,CA/B2 */ williams_49way_port_0_r, input_port_1_r, 0, 0, 0, 0,
112 	/*outputs: A/B,CA/B2       */ 0, 0, 0, 0,
113 	/*irqs   : A/B             */ 0, 0
114 };
115 
116 /* Muxing 49-way joystick PIA 0 for Blaster kit */
117 struct pia6821_interface williams_49way_muxed_pia_0_intf =
118 {
119 	/*inputs : A/B,CA/B1,CA/B2 */ williams_input_port_49way_0_5_r, input_port_1_r, 0, 0, 0, 0,
120 	/*outputs: A/B,CA/B2       */ 0, 0, 0, williams_port_select_w,
121 	/*irqs   : A/B             */ 0, 0
122 };
123 
124 /* Generic PIA 1, maps to input port 2, sound command out, and IRQs */
125 struct pia6821_interface williams_pia_1_intf =
126 {
127 	/*inputs : A/B,CA/B1,CA/B2 */ input_port_2_r, 0, 0, 0, 0, 0,
128 	/*outputs: A/B,CA/B2       */ 0, williams_snd_cmd_w, 0, 0,
129 	/*irqs   : A/B             */ williams_main_irq, williams_main_irq
130 };
131 
132 /* Generic PIA 2, maps to DAC data in and sound IRQs */
133 struct pia6821_interface williams_snd_pia_intf =
134 {
135 	/*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0,
136 	/*outputs: A/B,CA/B2       */ DAC_0_data_w, 0, 0, 0,
137 	/*irqs   : A/B             */ williams_snd_irq, williams_snd_irq
138 };
139 
140 
141 
142 /*************************************
143  *
144  *	Game-specific old-Williams PIA interfaces
145  *
146  *************************************/
147 
148 /* Special PIA 0 for Defender, to handle the controls */
149 struct pia6821_interface defender_pia_0_intf =
150 {
151 	/*inputs : A/B,CA/B1,CA/B2 */ defender_input_port_0_r, input_port_1_r, 0, 0, 0, 0,
152 	/*outputs: A/B,CA/B2       */ 0, 0, 0, 0,
153 	/*irqs   : A/B             */ 0, 0
154 };
155 
156 /* Special PIA 0 for Stargate, to handle the controls */
157 struct pia6821_interface stargate_pia_0_intf =
158 {
159 	/*inputs : A/B,CA/B1,CA/B2 */ stargate_input_port_0_r, input_port_1_r, 0, 0, 0, 0,
160 	/*outputs: A/B,CA/B2       */ 0, 0, 0, 0,
161 	/*irqs   : A/B             */ 0, 0
162 };
163 
164 /* Special PIA 0 for Lotto Fun, to handle the controls and ticket dispenser */
165 struct pia6821_interface lottofun_pia_0_intf =
166 {
167 	/*inputs : A/B,CA/B1,CA/B2 */ lottofun_input_port_0_r, input_port_1_r, 0, 0, 0, 0,
168 	/*outputs: A/B,CA/B2       */ 0, ticket_dispenser_w, 0, 0,
169 	/*irqs   : A/B             */ 0, 0
170 };
171 
172 /* Special PIA 2 for Sinistar, to handle the CVSD */
173 struct pia6821_interface sinistar_snd_pia_intf =
174 {
175 	/*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0,
176 	/*outputs: A/B,CA/B2       */ DAC_0_data_w, 0, hc55516_0_digit_w, hc55516_0_clock_w,
177 	/*irqs   : A/B             */ williams_snd_irq, williams_snd_irq
178 };
179 
180 /* Special PIA 1 for PlayBall, doesn't set the high bits on sound commands */
181 struct pia6821_interface playball_pia_1_intf =
182 {
183 	/*inputs : A/B,CA/B1,CA/B2 */ input_port_2_r, 0, 0, 0, 0, 0,
184 	/*outputs: A/B,CA/B2       */ 0, playball_snd_cmd_w, 0, 0,
185 	/*irqs   : A/B             */ williams_main_irq, williams_main_irq
186 };
187 
188 /* extra PIA 3 for Speed Ball */
189 struct pia6821_interface spdball_pia_3_intf =
190 {
191 	/*inputs : A/B,CA/B1,CA/B2 */ input_port_3_r, input_port_4_r, 0, 0, 0, 0,
192 	/*outputs: A/B,CA/B2       */ 0, 0, 0, 0,
193 	/*irqs   : A/B             */ 0, 0
194 };
195 
196 
197 
198 /*************************************
199  *
200  *	Generic later-Williams PIA interfaces
201  *
202  *************************************/
203 
204 /* Generic muxing PIA 0, maps to input ports 0/3 and 1; port select is CA2 */
205 struct pia6821_interface williams2_muxed_pia_0_intf =
206 {
207 	/*inputs : A/B,CA/B1,CA/B2 */ williams_input_port_0_3_r, input_port_1_r, 0, 0, 0, 0,
208 	/*outputs: A/B,CA/B2       */ 0, 0, williams_port_select_w, 0,
209 	/*irqs   : A/B             */ 0, 0
210 };
211 
212 /* Generic PIA 1, maps to input port 2, sound command out, and IRQs */
213 struct pia6821_interface williams2_pia_1_intf =
214 {
215 	/*inputs : A/B,CA/B1,CA/B2 */ input_port_2_r, 0, 0, 0, 0, 0,
216 	/*outputs: A/B,CA/B2       */ 0, williams2_snd_cmd_w, 0, pia_2_ca1_w,
217 	/*irqs   : A/B             */ williams_main_irq, williams_main_irq
218 };
219 
220 /* Generic PIA 2, maps to DAC data in and sound IRQs */
221 struct pia6821_interface williams2_snd_pia_intf =
222 {
223 	/*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0,
224 	/*outputs: A/B,CA/B2       */ pia_1_portb_w, DAC_0_data_w, pia_1_cb1_w, 0,
225 	/*irqs   : A/B             */ williams_snd_irq, williams_snd_irq
226 };
227 
228 
229 
230 /*************************************
231  *
232  *	Game-specific later-Williams PIA interfaces
233  *
234  *************************************/
235 
236 /* Mystic Marathon PIA 0 */
237 struct pia6821_interface mysticm_pia_0_intf =
238 {
239 	/*inputs : A/B,CA/B1,CA/B2 */ input_port_0_r, input_port_1_r, 0, 0, 0, 0,
240 	/*outputs: A/B,CA/B2       */ 0, 0, 0, 0,
241 	/*irqs   : A/B             */ williams_main_firq, williams_main_irq
242 };
243 
244 /* Turkey Shoot PIA 0 */
245 struct pia6821_interface tshoot_pia_0_intf =
246 {
247 	/*inputs : A/B,CA/B1,CA/B2 */ tshoot_input_port_0_3_r, input_port_1_r, 0, 0, 0, 0,
248 	/*outputs: A/B,CA/B2       */ 0, tshoot_lamp_w, williams_port_select_w, 0,
249 	/*irqs   : A/B             */ williams_main_irq, williams_main_irq
250 };
251 
252 /* Turkey Shoot PIA 2 */
253 struct pia6821_interface tshoot_snd_pia_intf =
254 {
255 	/*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0,
256 	/*outputs: A/B,CA/B2       */ pia_1_portb_w, DAC_0_data_w, pia_1_cb1_w, tshoot_maxvol_w,
257 	/*irqs   : A/B             */ williams_snd_irq, williams_snd_irq
258 };
259 
260 /* Joust 2 PIA 1 */
261 struct pia6821_interface joust2_pia_1_intf =
262 {
263 	/*inputs : A/B,CA/B1,CA/B2 */ input_port_2_r, 0, 0, 0, 0, 0,
264 	/*outputs: A/B,CA/B2       */ 0, joust2_snd_cmd_w, joust2_pia_3_cb1_w, pia_2_ca1_w,
265 	/*irqs   : A/B             */ williams_main_irq, williams_main_irq
266 };
267 
268 
269 
270 /*************************************
271  *
272  *	Older Williams interrupts
273  *
274  *************************************/
275 
williams_va11_callback(int scanline)276 static void williams_va11_callback(int scanline)
277 {
278 	/* the IRQ signal comes into CB1, and is set to VA11 */
279 	pia_1_cb1_w(0, scanline & 0x20);
280 
281 	/* update the screen while we're here */
282 	force_partial_update(scanline - 1);
283 
284 	/* set a timer for the next update */
285 	scanline += 8;
286 	if (scanline >= 256) scanline = 0;
287 	timer_set(cpu_getscanlinetime(scanline), scanline, williams_va11_callback);
288 }
289 
290 
williams_count240_off_callback(int param)291 static void williams_count240_off_callback(int param)
292 {
293 	/* the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 */
294 	pia_1_ca1_w(0, 0);
295 }
296 
297 
williams_count240_callback(int param)298 static void williams_count240_callback(int param)
299 {
300 	/* the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 */
301 	pia_1_ca1_w(0, 1);
302 
303 	/* set a timer to turn it off once the scanline counter resets */
304 	timer_set(cpu_getscanlinetime(0), 0, williams_count240_off_callback);
305 
306 	/* set a timer for next frame */
307 	timer_set(cpu_getscanlinetime(240), 0, williams_count240_callback);
308 }
309 
310 
williams_main_irq(int state)311 static void williams_main_irq(int state)
312 {
313 	/* IRQ to the main CPU */
314 	cpu_set_irq_line(0, M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
315 }
316 
317 
williams_main_firq(int state)318 static void williams_main_firq(int state)
319 {
320 	/* FIRQ to the main CPU */
321 	cpu_set_irq_line(0, M6809_FIRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
322 }
323 
324 
williams_snd_irq(int state)325 static void williams_snd_irq(int state)
326 {
327 	/* IRQ to the sound CPU */
328 	cpu_set_irq_line(1, M6800_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
329 }
330 
331 
332 
333 /*************************************
334  *
335  *	Older Williams initialization
336  *
337  *************************************/
338 
MACHINE_INIT(williams)339 MACHINE_INIT( williams )
340 {
341 	/* reset the PIAs */
342 	pia_reset();
343 
344 	/* reset the ticket dispenser (Lotto Fun) */
345 	ticket_dispenser_init(70, TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_HIGH);
346 
347 	/* set a timer to go off every 16 scanlines, to toggle the VA11 line and update the screen */
348 	timer_set(cpu_getscanlinetime(0), 0, williams_va11_callback);
349 
350 	/* also set a timer to go off on scanline 240 */
351 	timer_set(cpu_getscanlinetime(240), 0, williams_count240_callback);
352 }
353 
354 
355 
356 /*************************************
357  *
358  *	Older Williams VRAM/ROM banking
359  *
360  *************************************/
361 
WRITE_HANDLER(williams_vram_select_w)362 WRITE_HANDLER( williams_vram_select_w )
363 {
364 	/* VRAM/ROM banking from bit 0 */
365 	vram_bank = data & 0x01;
366 
367 	/* cocktail flip from bit 1 */
368 	williams_cocktail = data & 0x02;
369 
370 	/* sinistar clipping enable from bit 2 */
371 	sinistar_clip = (data & 0x04) ? 0x7400 : 0xffff;
372 
373 	/* set the bank */
374 	if (vram_bank)
375 	{
376 		cpu_setbank(1, williams_bank_base);
377 	}
378 	else
379 	{
380 		cpu_setbank(1, williams_videoram);
381 	}
382 }
383 
384 
385 
386 /*************************************
387  *
388  *	Older Williams sound commands
389  *
390  *************************************/
391 
williams_deferred_snd_cmd_w(int param)392 static void williams_deferred_snd_cmd_w(int param)
393 {
394 	pia_2_portb_w(0, param);
395 	pia_2_cb1_w(0, (param == 0xff) ? 0 : 1);
396 }
397 
WRITE_HANDLER(williams_snd_cmd_w)398 WRITE_HANDLER( williams_snd_cmd_w )
399 {
400 	/* the high two bits are set externally, and should be 1 */
401 	timer_set(TIME_NOW, data | 0xc0, williams_deferred_snd_cmd_w);
402 }
403 
WRITE_HANDLER(playball_snd_cmd_w)404 WRITE_HANDLER( playball_snd_cmd_w )
405 {
406 	timer_set(TIME_NOW, data, williams_deferred_snd_cmd_w);
407 }
408 
409 
410 
411 /*************************************
412  *
413  *	General input port handlers
414  *
415  *************************************/
416 
WRITE_HANDLER(williams_port_select_w)417 WRITE_HANDLER( williams_port_select_w )
418 {
419 	port_select = data;
420 }
421 
422 
READ_HANDLER(williams_input_port_0_3_r)423 READ_HANDLER( williams_input_port_0_3_r )
424 {
425 	return readinputport(port_select ? 3 : 0);
426 }
427 
428 
READ_HANDLER(williams_input_port_1_4_r)429 READ_HANDLER( williams_input_port_1_4_r )
430 {
431 	return readinputport(port_select ? 4 : 1);
432 }
433 
434 
435 /*
436  *  Williams 49-way joystick
437  *
438  * The joystick has 48 positions + center.
439  *
440  * I'm not 100% sure but it looks like it's mapped this way:
441  *
442  *	xxxx1000 = up full
443  *	xxxx1100 = up 2/3
444  *	xxxx1110 = up 1/3
445  *	xxxx0111 = center
446  *	xxxx0011 = down 1/3
447  *	xxxx0001 = down 2/3
448  *	xxxx0000 = down full
449  *
450  *	1000xxxx = right full
451  *	1100xxxx = right 2/3
452  *	1110xxxx = right 1/3
453  *	0111xxxx = center
454  *	0011xxxx = left 1/3
455  *	0001xxxx = left 2/3
456  *	0000xxxx = left full
457  *
458  */
459 
READ_HANDLER(williams_49way_port_0_r)460 READ_HANDLER( williams_49way_port_0_r )
461 {
462 	int joy_x, joy_y;
463 	int bits_x, bits_y;
464 
465 	joy_x = readinputport(3) >> 4;	/* 0 = left 3 = center 6 = right */
466 	joy_y = readinputport(4) >> 4;	/* 0 = down 3 = center 6 = up */
467 
468 	bits_x = (0x70 >> (7 - joy_x)) & 0x0f;
469 	bits_y = (0x70 >> (7 - joy_y)) & 0x0f;
470 
471 	return (bits_x << 4) | bits_y;
472 }
473 
474 
READ_HANDLER(williams_input_port_49way_0_5_r)475 READ_HANDLER( williams_input_port_49way_0_5_r )
476 {
477 	if (port_select)
478 		return williams_49way_port_0_r(0);
479 	else
480 		return readinputport(5);
481 }
482 
483 
484 
485 /*************************************
486  *
487  *	Newer Williams interrupts
488  *
489  *************************************/
490 
williams2_va11_callback(int scanline)491 static void williams2_va11_callback(int scanline)
492 {
493 	/* the IRQ signal comes into CB1, and is set to VA11 */
494 	pia_0_cb1_w(0, scanline & 0x20);
495 	pia_1_ca1_w(0, scanline & 0x20);
496 
497 	/* update the screen while we're here */
498 	force_partial_update(scanline);
499 
500 	/* set a timer for the next update */
501 	scanline += 8;
502 	if (scanline >= 256) scanline = 0;
503 	timer_set(cpu_getscanlinetime(scanline), scanline, williams2_va11_callback);
504 }
505 
506 
williams2_endscreen_off_callback(int param)507 static void williams2_endscreen_off_callback(int param)
508 {
509 	/* the /ENDSCREEN signal comes into CA1 */
510 	pia_0_ca1_w(0, 1);
511 }
512 
513 
williams2_endscreen_callback(int param)514 static void williams2_endscreen_callback(int param)
515 {
516 	/* the /ENDSCREEN signal comes into CA1 */
517 	pia_0_ca1_w(0, 0);
518 
519 	/* set a timer to turn it off once the scanline counter resets */
520 	timer_set(cpu_getscanlinetime(8), 0, williams2_endscreen_off_callback);
521 
522 	/* set a timer for next frame */
523 	timer_set(cpu_getscanlinetime(254), 0, williams2_endscreen_callback);
524 }
525 
526 
527 
528 /*************************************
529  *
530  *	Newer Williams initialization
531  *
532  *************************************/
533 
MACHINE_INIT(williams2)534 MACHINE_INIT( williams2 )
535 {
536 	/* reset the PIAs */
537 	pia_reset();
538 
539 	/* make sure our banking is reset */
540 	williams2_bank_select_w(0, 0);
541 
542 	/* set a timer to go off every 16 scanlines, to toggle the VA11 line and update the screen */
543 	timer_set(cpu_getscanlinetime(0), 0, williams2_va11_callback);
544 
545 	/* also set a timer to go off on scanline 254 */
546 	timer_set(cpu_getscanlinetime(254), 0, williams2_endscreen_callback);
547 }
548 
549 
550 
551 /*************************************
552  *
553  *	Newer Williams ROM banking
554  *
555  *************************************/
556 
WRITE_HANDLER(williams2_bank_select_w)557 WRITE_HANDLER( williams2_bank_select_w )
558 {
559 	static const UINT32 bank[8] = { 0, 0x10000, 0x20000, 0x10000, 0, 0x30000, 0x40000, 0x30000 };
560 
561 	/* select bank index (only lower 3 bits used by IC56) */
562 	williams2_bank = data & 0x07;
563 
564 	/* bank 0 references videoram */
565 	if (williams2_bank == 0)
566 	{
567 		cpu_setbank(1, williams_videoram);
568 		cpu_setbank(2, williams_videoram + 0x8000);
569 	}
570 
571 	/* other banks reference ROM plus either palette RAM or the top of videoram */
572 	else
573 	{
574 		unsigned char *RAM = memory_region(REGION_CPU1);
575 
576 		cpu_setbank(1, &RAM[bank[williams2_bank]]);
577 
578 		if ((williams2_bank & 0x03) == 0x03)
579 		{
580 			cpu_setbank(2, williams2_paletteram);
581 		}
582 		else
583 		{
584 			cpu_setbank(2, williams_videoram + 0x8000);
585 		}
586 	}
587 
588 	/* regardless, the top 2k references videoram */
589 	cpu_setbank(3, williams_videoram + 0x8800);
590 }
591 
592 
593 
594 /*************************************
595  *
596  *	Newer Williams sound commands
597  *
598  *************************************/
599 
williams2_deferred_snd_cmd_w(int param)600 static void williams2_deferred_snd_cmd_w(int param)
601 {
602 	pia_2_porta_w(0, param);
603 }
604 
605 
WRITE_HANDLER(williams2_snd_cmd_w)606 static WRITE_HANDLER( williams2_snd_cmd_w )
607 {
608 	timer_set(TIME_NOW, data, williams2_deferred_snd_cmd_w);
609 }
610 
611 
612 
613 /*************************************
614  *
615  *	Newer Williams other stuff
616  *
617  *************************************/
618 
WRITE_HANDLER(williams2_7segment_w)619 WRITE_HANDLER( williams2_7segment_w )
620 {
621 	int n;
622 	char dot;
623 
624 	switch (data & 0x7F)
625 	{
626 		case 0x40:	n = 0; break;
627 		case 0x79:	n = 1; break;
628 		case 0x24:	n = 2; break;
629 		case 0x30:	n = 3; break;
630 		case 0x19:	n = 4; break;
631 		case 0x12:	n = 5; break;
632 		case 0x02:	n = 6; break;
633 		case 0x03:	n = 6; break;
634 		case 0x78:	n = 7; break;
635 		case 0x00:	n = 8; break;
636 		case 0x18:	n = 9; break;
637 		case 0x10:	n = 9; break;
638 		default:	n =-1; break;
639 	}
640 
641 	if ((data & 0x80) == 0x00)
642 		dot = '.';
643 	else
644 		dot = ' ';
645 
646 	if (n == -1)
647 		logerror("[ %c]\n", dot);
648 	else
649 		logerror("[%d%c]\n", n, dot);
650 }
651 
652 
653 
654 /*************************************
655  *
656  *	Defender-specific routines
657  *
658  *************************************/
659 
MACHINE_INIT(defender)660 MACHINE_INIT( defender )
661 {
662 	/* standard init */
663 	machine_init_williams();
664 
665 	/* make sure the banking is reset to 0 */
666 	defender_bank_select_w(0, 0);
667 	cpu_setbank(1, williams_videoram);
668 }
669 
670 
671 
WRITE_HANDLER(defender_bank_select_w)672 WRITE_HANDLER( defender_bank_select_w )
673 {
674 	UINT32 bank_offset = defender_bank_list[data & 7];
675 
676 	/* set bank address */
677 	cpu_setbank(2, &memory_region(REGION_CPU1)[bank_offset]);
678 
679 	/* if the bank maps into normal RAM, it represents I/O space */
680 	if (bank_offset < 0x10000)
681 	{
682 		memory_set_bankhandler_r(2, 0, defender_io_r);
683 		memory_set_bankhandler_w(2, 0, defender_io_w);
684 	}
685 
686 	/* otherwise, it's ROM space */
687 	else
688 	{
689 		memory_set_bankhandler_r(2, 0, MRA_BANK2);
690 		memory_set_bankhandler_w(2, 0, MWA_ROM);
691 	}
692 }
693 
694 
READ_HANDLER(defender_input_port_0_r)695 READ_HANDLER( defender_input_port_0_r )
696 {
697 	int keys, altkeys;
698 
699 	/* read the standard keys and the cheat keys */
700 	keys = readinputport(0);
701 	altkeys = readinputport(3);
702 
703 	/* modify the standard keys with the cheat keys */
704 	if (altkeys)
705 	{
706 		keys |= altkeys;
707 		if (memory_region(REGION_CPU1)[0xa0bb] == 0xfd)
708 		{
709 			if (keys & 0x02)
710 				keys = (keys & 0xfd) | 0x40;
711 			else if (keys & 0x40)
712 				keys = (keys & 0xbf) | 0x02;
713 		}
714 	}
715 
716 	return keys;
717 }
718 
719 
READ_HANDLER(defender_io_r)720 READ_HANDLER( defender_io_r )
721 {
722 	/* PIAs */
723 	if (offset >= 0x0c00 && offset < 0x0c04)
724 		return pia_1_r(offset & 3);
725 	else if (offset >= 0x0c04 && offset < 0x0c08)
726 		return pia_0_r(offset & 3);
727 
728 	/* video counter */
729 	else if (offset == 0x800)
730 		return williams_video_counter_r(offset);
731 
732 	/* If not bank 0 then return banked RAM */
733 	return defender_bank_base[offset];
734 }
735 
736 
WRITE_HANDLER(defender_io_w)737 WRITE_HANDLER( defender_io_w )
738 {
739 	/* write the data through */
740 	defender_bank_base[offset] = data;
741 
742 	/* watchdog */
743 	if (offset == 0x03fc)
744 		watchdog_reset_w(offset, data);
745 
746 	/* palette */
747 	else if (offset < 0x10)
748 		paletteram_BBGGGRRR_w(offset, data);
749 
750 	/* PIAs */
751 	else if (offset >= 0x0c00 && offset < 0x0c04)
752 		pia_1_w(offset & 3, data);
753 	else if (offset >= 0x0c04 && offset < 0x0c08)
754 		pia_0_w(offset & 3, data);
755 }
756 
757 
758 
759 /*************************************
760  *
761  *	Mayday-specific routines
762  *
763  *************************************/
764 
READ_HANDLER(mayday_protection_r)765 READ_HANDLER( mayday_protection_r )
766 {
767 	/* Mayday does some kind of protection check that is not currently understood  */
768 	/* However, the results of that protection check are stored at $a190 and $a191 */
769 	/* These are compared against $a193 and $a194, respectively. Thus, to prevent  */
770 	/* the protection from resetting the machine, we just return $a193 for $a190,  */
771 	/* and $a194 for $a191. */
772 	return mayday_protection[offset + 3];
773 }
774 
775 
776 
777 /*************************************
778  *
779  *	Stargate-specific routines
780  *
781  *************************************/
782 
READ_HANDLER(stargate_input_port_0_r)783 READ_HANDLER( stargate_input_port_0_r )
784 {
785 	int keys, altkeys;
786 
787 	/* read the standard keys and the cheat keys */
788 	keys = input_port_0_r(0);
789 	altkeys = input_port_3_r(0);
790 
791 	/* modify the standard keys with the cheat keys */
792 	if (altkeys)
793 	{
794 		keys |= altkeys;
795 		if (memory_region(REGION_CPU1)[0x9c92] == 0xfd)
796 		{
797 			if (keys & 0x02)
798 				keys = (keys & 0xfd) | 0x40;
799 			else if (keys & 0x40)
800 				keys = (keys & 0xbf) | 0x02;
801 		}
802 	}
803 
804 	return keys;
805 }
806 
807 
808 
809 /*************************************
810  *
811  *	Blaster-specific routines
812  *
813  *************************************/
814 
815 static const UINT32 blaster_bank_offset[16] =
816 {
817 	0x00000, 0x10000, 0x14000, 0x18000, 0x1c000, 0x20000, 0x24000, 0x28000,
818 	0x2c000, 0x30000, 0x34000, 0x38000, 0x2c000, 0x30000, 0x34000, 0x38000
819 };
820 
821 
WRITE_HANDLER(blaster_vram_select_w)822 WRITE_HANDLER( blaster_vram_select_w )
823 {
824 	unsigned char *RAM = memory_region(REGION_CPU1);
825 
826 	vram_bank = data;
827 
828 	/* non-zero banks map to RAM and the currently-selected bank */
829 	if (vram_bank)
830 	{
831 		cpu_setbank(1, &RAM[blaster_bank_offset[blaster_bank]]);
832 		cpu_setbank(2, williams_bank_base + 0x4000);
833 	}
834 
835 	/* bank 0 maps to videoram */
836 	else
837 	{
838 		cpu_setbank(1, williams_videoram);
839 		cpu_setbank(2, williams_videoram + 0x4000);
840 	}
841 }
842 
843 
WRITE_HANDLER(blaster_bank_select_w)844 WRITE_HANDLER( blaster_bank_select_w )
845 {
846 	unsigned char *RAM = memory_region(REGION_CPU1);
847 
848 	blaster_bank = data & 15;
849 
850 	/* only need to change anything if we're not pointing to VRAM */
851 	if (vram_bank)
852 	{
853 		cpu_setbank(1, &RAM[blaster_bank_offset[blaster_bank]]);
854 	}
855 }
856 
857 
858 
859 /*************************************
860  *
861  *	Lotto Fun-specific routines
862  *
863  *************************************/
864 
READ_HANDLER(lottofun_input_port_0_r)865 static READ_HANDLER( lottofun_input_port_0_r )
866 {
867 	/* merge in the ticket dispenser status */
868 	return input_port_0_r(offset) | ticket_dispenser_r(offset);
869 }
870 
871 
872 
873 /*************************************
874  *
875  *	Turkey Shoot-specific routines
876  *
877  *************************************/
878 
READ_HANDLER(tshoot_input_port_0_3_r)879 static READ_HANDLER( tshoot_input_port_0_3_r )
880 {
881 	/* merge in the gun inputs with the standard data */
882 	int data = williams_input_port_0_3_r(offset);
883 	int gun = (data & 0x3f) ^ ((data & 0x3f) >> 1);
884 	return (data & 0xc0) | gun;
885 }
886 
887 
WRITE_HANDLER(tshoot_maxvol_w)888 static WRITE_HANDLER( tshoot_maxvol_w )
889 {
890 	/* something to do with the sound volume */
891 	logerror("tshoot maxvol = %d (pc:%x)\n", data, activecpu_get_pc());
892 }
893 
894 
WRITE_HANDLER(tshoot_lamp_w)895 static WRITE_HANDLER( tshoot_lamp_w )
896 {
897 	/* set the grenade lamp */
898 	set_led_status(0,data & 0x04);
899 
900 	/* set the gun lamp */
901 	set_led_status(1,data & 0x08);
902 
903 #if 0
904 	/* gun coil */
905 	if (data & 0x10)
906 		printf("[gun coil] ");
907 	else
908 		printf("           ");
909 
910 	/* feather coil */
911 	if (data & 0x20)
912 		printf("[feather coil] ");
913 	else
914 		printf("               ");
915 
916 	printf("\n");
917 #endif
918 }
919 
920 
921 
922 /*************************************
923  *
924  *	Joust 2-specific routines
925  *
926  *************************************/
927 
MACHINE_INIT(joust2)928 MACHINE_INIT( joust2 )
929 {
930 	/* standard init */
931 	machine_init_williams2();
932 
933 	/* make sure sound board starts out in the reset state */
934 	williams_cvsd_init(2, 3);
935 	pia_reset();
936 }
937 
938 
joust2_deferred_snd_cmd_w(int param)939 static void joust2_deferred_snd_cmd_w(int param)
940 {
941 	pia_2_porta_w(0, param & 0xff);
942 }
943 
944 
WRITE_HANDLER(joust2_pia_3_cb1_w)945 static WRITE_HANDLER( joust2_pia_3_cb1_w )
946 {
947 	joust2_current_sound_data = (joust2_current_sound_data & ~0x100) | ((data << 8) & 0x100);
948 	pia_3_cb1_w(offset, data);
949 }
950 
951 
WRITE_HANDLER(joust2_snd_cmd_w)952 static WRITE_HANDLER( joust2_snd_cmd_w )
953 {
954 	joust2_current_sound_data = (joust2_current_sound_data & ~0xff) | (data & 0xff);
955 	williams_cvsd_data_w(joust2_current_sound_data);
956 	timer_set(TIME_NOW, joust2_current_sound_data, joust2_deferred_snd_cmd_w);
957 }
958