1 /***************************************************************************
2
3 Cinematronics vector hardware
4
5 Special thanks to Neil Bradley, Zonn Moore, and Jeff Mitchell of the
6 Retrocade Alliance
7
8 Update:
9 6/27/99 Jim Hernandez -- 1st Attempt at Fixing Drone Star Castle sound and
10 pitch adjustments.
11 6/30/99 MLR added Rip Off, Solar Quest, Armor Attack (no samples yet)
12
13 Bugs: Sometimes the death explosion (small explosion) does not trigger.
14
15 ***************************************************************************/
16
17 #include "driver.h"
18 #include "machine/z80fmly.h"
19 #include "cinemat.h"
20
21
22 static UINT32 current_shift = 0;
23 static UINT32 last_shift = 0;
24 static UINT32 last_shift16= 0;
25 static UINT32 current_pitch = 0x20000;
26 static UINT32 last_frame = 0;
27
28 static int cinemat_outputs = 0xff;
29
30 cinemat_sound_handler_proc cinemat_sound_handler;
31
32
33
34 /*************************************
35 *
36 * General read/write handlers
37 *
38 *************************************/
39
READ16_HANDLER(cinemat_output_port_r)40 READ16_HANDLER( cinemat_output_port_r )
41 {
42 return cinemat_outputs;
43 }
44
45
WRITE16_HANDLER(cinemat_output_port_w)46 WRITE16_HANDLER( cinemat_output_port_w )
47 {
48 if ((cinemat_outputs ^ data) & 0x9f)
49 {
50 if (cinemat_sound_handler)
51 cinemat_sound_handler (data & 0x9f, (cinemat_outputs ^ data) & 0x9f);
52 }
53
54 cinemat_outputs = data;
55 }
56
57
58
59 /*************************************
60 *
61 * Sound reset
62 *
63 *************************************/
64
MACHINE_INIT(cinemat_sound)65 MACHINE_INIT( cinemat_sound )
66 {
67 current_shift = 0xffff;
68 last_shift = 0xffff;
69 last_shift16 = 0xffff;
70 current_pitch = 0x20000;
71 last_frame = 0;
72
73 // Pitch the Drone sound will start off at
74
75 }
76
cinemat_shift(UINT8 sound_val,UINT8 bits_changed,UINT8 A1,UINT8 CLK)77 static void cinemat_shift(UINT8 sound_val, UINT8 bits_changed, UINT8 A1, UINT8 CLK)
78 {
79 // See if we're latching a shift
80
81 if ((bits_changed & CLK) && (0 == (sound_val & CLK)))
82 {
83 current_shift <<= 1;
84 if (sound_val & A1)
85 current_shift |= 1;
86 }
87 }
88
89
90 /*************************************
91 *
92 * Sundance
93 *
94 *************************************/
95
96 static const char *sundance_sample_names[] =
97 {
98 "*sundance",
99 "bong.wav",
100 "whoosh.wav",
101 "explsion.wav",
102 "ping1.wav",
103 "ping2.wav",
104 "hatch.wav",
105
106 0 /* end of array */
107 };
108
109 struct Samplesinterface sundance_samples_interface =
110 {
111 6, /* 8 channels */
112 25, /* volume */
113 sundance_sample_names
114 };
115
sundance_sound_w(UINT8 sound_val,UINT8 bits_changed)116 void sundance_sound_w(UINT8 sound_val, UINT8 bits_changed)
117 {
118
119 if (bits_changed & 0x01) //Bong
120 {
121 if (sound_val & 0x01)
122 {
123
124 sample_start(0, 0, 0);
125
126 }
127 }
128
129
130 if ((bits_changed & 0x02) && (0 == (sound_val & 0x02)))
131 sample_start(1, 1, 0);
132
133
134 if ((bits_changed & 0x04) && (0 == (sound_val & 0x04)))
135 sample_start(2, 2, 0);
136
137
138 if ((bits_changed & 0x08) && (0 == (sound_val & 0x08)))
139 sample_start(3, 3, 0);
140
141
142 if ((bits_changed & 0x10) && (0 == (sound_val & 0x10)))
143 {
144 sample_start(4, 4, 0);
145 }
146
147
148 if ((bits_changed & 0x80) && (0 == (sound_val & 0x80)))
149 sample_start(5, 5, 0);
150
151 }
152
153
154
155 /*************************************
156 *
157 * Star Castle
158 *
159 *************************************/
160
161 static const char *starcas_sample_names[] =
162 {
163 "*starcas",
164 "lexplode.wav",
165 "sexplode.wav",
166 "cfire.wav",
167 "pfire.wav",
168 "drone.wav",
169 "shield.wav",
170 "star.wav",
171 "thrust.wav",
172 0 /* end of array */
173 };
174
175 struct Samplesinterface starcas_samples_interface =
176 {
177 8, /* 8 channels */
178 25, /* volume */
179 starcas_sample_names
180 };
181
starcas_sound_w(UINT8 sound_val,UINT8 bits_changed)182 void starcas_sound_w(UINT8 sound_val, UINT8 bits_changed)
183 {
184 UINT32 target_pitch;
185 UINT8 shift_diff;
186
187 cinemat_shift (sound_val, bits_changed, 0x80, 0x10);
188
189 // Now see if it's time to act upon the shifted data
190
191 if ((bits_changed & 0x01) && (0 == (sound_val & 0x01)))
192 {
193 // Yep. Falling edge! Find out what has changed.
194
195 shift_diff = current_shift ^ last_shift;
196
197 if ((shift_diff & 1) && (0 == (current_shift & 1)))
198 sample_start(2, 2, 0); // Castle fire
199
200 if ((shift_diff & 2) && (0 == (current_shift & 2)))
201 sample_start(5, 5, 0); // Shield hit
202
203 if (shift_diff & 0x04)
204 {
205 if (current_shift & 0x04)
206 sample_start(6, 6, 1); // Star sound
207 else
208 sample_stop(6); // Stop it!
209 }
210
211 if (shift_diff & 0x08)
212 {
213 if (current_shift & 0x08)
214 sample_stop(7); // Stop it!
215 else
216 sample_start(7, 7, 1); // Thrust sound
217 }
218
219 if (shift_diff & 0x10)
220 {
221 if (current_shift & 0x10)
222 sample_stop(4);
223 else
224 sample_start(4, 4, 1); // Drone
225 }
226
227 // Latch the drone pitch
228
229 target_pitch = (current_shift & 0x60) >> 3;
230 target_pitch |= ((current_shift & 0x40) >> 5);
231 target_pitch |= ((current_shift & 0x80) >> 7);
232
233 // target_pitch = (current_shift & 0x60) >> 3;
234 // is the the target drone pitch to rise and stop at.
235
236 target_pitch = 0x10000 + (target_pitch << 12);
237
238 // 0x10000 is lowest value the pitch will drop to
239 // Star Castle drone sound
240
241 if (cpu_getcurrentframe() > last_frame)
242 {
243 if (current_pitch > target_pitch)
244 current_pitch -= 300;
245 if (current_pitch < target_pitch)
246 current_pitch += 200;
247 sample_set_freq(4, current_pitch);
248 last_frame = cpu_getcurrentframe();
249 }
250
251 last_shift = current_shift;
252 }
253
254 if ((bits_changed & 0x08) && (0 == (sound_val & 0x08)))
255 sample_start(3, 3, 0); // Player fire
256
257 if ((bits_changed & 0x04) && (0 == (sound_val & 0x04)))
258 sample_start(1, 1, 0); // Soft explosion
259
260 if ((bits_changed & 0x02) && (0 == (sound_val & 0x02)))
261 sample_start(0, 0, 0); // Loud explosion
262
263 }
264
265
266 /*************************************
267 *
268 * Warrior
269 *
270 *************************************/
271
272 static const char *warrior_sample_names[] =
273 {
274 "*warrior",
275 "appear.wav",
276 "bgmhum1.wav",
277 "bgmhum2.wav",
278 "fall.wav",
279 "killed.wav",
280 0 /* end of array */
281 };
282
283 struct Samplesinterface warrior_samples_interface =
284 {
285 5, /* 8 channels */
286 25, /* volume */
287 warrior_sample_names
288 };
289
warrior_sound_w(UINT8 sound_val,UINT8 bits_changed)290 void warrior_sound_w(UINT8 sound_val, UINT8 bits_changed)
291 {
292
293 if ((bits_changed & 0x10) && (0 == (sound_val & 0x10)))
294 {
295 sample_start(0, 0, 0); // appear
296 }
297
298 if ((bits_changed & 0x08) && (0 == (sound_val & 0x08)))
299 sample_start(3, 3, 0); // fall
300
301 if ((bits_changed & 0x04) && (0 == (sound_val & 0x04)))
302 sample_start(4, 4, 0); // explosion (kill)
303
304 if (bits_changed & 0x02)
305 {
306 if ((sound_val & 0x02) == 0)
307 sample_start(2, 2, 1); // hi level
308 else
309 sample_stop(2);
310 }
311
312 if (bits_changed & 0x01)
313 {
314 if ((sound_val & 0x01) == 0)
315 sample_start(1, 1, 1); // normal level
316 else
317 sample_stop(1);
318 }
319 }
320
321
322 /*************************************
323 *
324 * Armor Attack
325 *
326 *************************************/
327
328 static const char *armora_sample_names[] = //Added retrocade samples 10-27-03 Tim C.
329 {
330 "*armora",
331 "tankfire.wav",
332 "hiexp.wav",
333 "jeepfire.wav",
334 "loexp.wav",
335 "tankeng.wav",
336 "beep.wav",
337 "jeepfire.wav",
338 0 /* end of array */
339 };
340
341 struct Samplesinterface armora_samples_interface =
342 {
343 7, /* 8 channels */
344 25, /* volume */
345 armora_sample_names
346 };
347
348
armora_sound_w(UINT8 sound_val,UINT8 bits_changed)349 void armora_sound_w(UINT8 sound_val, UINT8 bits_changed)
350 {
351 UINT8 shift_diff;
352
353 cinemat_shift (sound_val, bits_changed, 0x80, 0x10);
354
355 // Now see if it's time to act upon the shifted data
356
357 if ((bits_changed & 0x01) && (0 == (sound_val & 0x01)))
358 {
359 // Yep. Falling edge! Find out what has changed.
360
361 shift_diff = current_shift ^ last_shift;
362
363 if ((shift_diff & 1) && (0 == (current_shift & 1)))
364 sample_start(0, 0, 0); // Tank fire
365
366 if ((shift_diff & 2) && (0 == (current_shift & 2)))
367 sample_start(1, 1, 0); // Hi explosion
368
369 if ((shift_diff & 4) && (0 == (current_shift & 4)))
370 sample_start(2, 2, 0); // Jeep fire
371
372 if ((shift_diff & 8) && (0 == (current_shift & 8)))
373 sample_start(3, 3, 0); // Lo explosion
374
375 /* High nibble unknown */
376 last_shift = current_shift;
377 }
378
379 if (bits_changed & 0x2) // Fixed incorrect inverted triggering 10-27-03 Tim C.
380 { //Still not totally correct. Should be 2 speeds
381 if (sound_val & 0x2)
382 sample_stop(4);
383 else
384 sample_start(4, 4, 1); // Tank +
385
386 }
387 if (bits_changed & 0x4) // Fixed incorrect inverted triggering 10-27-03 Tim C.
388 {
389 if (sound_val & 0x4)
390 sample_stop(5);
391 else
392 sample_start(5, 5, 1); // Beep +
393 }
394 if (bits_changed & 0x8) // Fixed incorrect inverted triggering 10-27-03 Tim C.
395 {
396 if (sound_val & 0x8)
397 sample_stop(6);
398 else
399 sample_start(6, 6, 1); // Chopper +
400 }
401 }
402
403
404 /*************************************
405 *
406 * Ripoff
407 *
408 *************************************/
409
410 static const char *ripoff_sample_names[] =
411 {
412 "*ripoff",
413 "efire.wav",
414 "eattack.wav",
415 "bonuslvl.wav",
416 "explosn.wav",
417 "shipfire.wav",
418 "bg1.wav",
419 "bg2.wav",
420 "bg3.wav",
421 "bg4.wav",
422 "bg5.wav",
423 "bg6.wav",
424 "bg7.wav",
425 "bg8.wav",
426 0 /* end of array */
427 };
428
429 struct Samplesinterface ripoff_samples_interface =
430 {
431 8, /* 8 channels */
432 25, /* volume */
433 ripoff_sample_names
434 };
435
ripoff_sound_w(UINT8 sound_val,UINT8 bits_changed)436 void ripoff_sound_w(UINT8 sound_val, UINT8 bits_changed)
437 {
438 UINT8 shift_diff, current_bg_sound;
439 static UINT8 last_bg_sound;
440
441 cinemat_shift (sound_val, bits_changed, 0x01, 0x02);
442
443 // Now see if it's time to act upon the shifted data
444
445 if ((bits_changed & 0x04) && (0 == (sound_val & 0x04)))
446 {
447 // Yep. Falling edge! Find out what has changed.
448
449 shift_diff = current_shift ^ last_shift;
450
451 current_bg_sound = ((current_shift & 0x1) << 2) | (current_shift & 0x2) | ((current_shift & 0x4) >> 2);
452 if (current_bg_sound != last_bg_sound) // use another background sound ?
453 {
454 shift_diff |= 0x08;
455 sample_stop(4);
456 last_bg_sound = current_bg_sound;
457 }
458
459 if (shift_diff & 0x08)
460 {
461 if (current_shift & 0x08)
462 sample_stop(5);
463 else
464 sample_start(5, 5+last_bg_sound, 1); // Background
465 }
466
467 if ((shift_diff & 0x10) && (0 == (current_shift & 0x10)))
468 sample_start(2, 2, 0); // Beep
469
470 if (shift_diff & 0x20)
471 {
472 if (current_shift & 0x20)
473 sample_stop(1); // Stop it!
474 else
475 sample_start(1, 1, 1); // Motor
476 }
477
478 last_shift = current_shift;
479 }
480
481 if ((bits_changed & 0x08) && (0 == (sound_val & 0x08)))
482 sample_start(4, 4, 0); // Torpedo
483
484 if ((bits_changed & 0x10) && (0 == (sound_val & 0x10)))
485 sample_start(0, 0, 0); // Laser
486
487 if ((bits_changed & 0x80) && (0 == (sound_val & 0x80)))
488 sample_start(3, 3, 0); // Explosion
489
490 }
491
492
493 /*************************************
494 *
495 * Solar Quest
496 *
497 *************************************/
498
499 static const char *solarq_sample_names[] =
500 {
501 "*solarq",
502 "bigexpl.wav",
503 "smexpl.wav",
504 "lthrust.wav",
505 "slaser.wav",
506 "pickup.wav",
507 "nuke1.wav",
508 "nuke2.wav",
509 "hypersp.wav",
510 "extra.wav",
511 "phase.wav",
512 "efire.wav",
513 0 /* end of array */
514 };
515
516 struct Samplesinterface solarq_samples_interface =
517 {
518 8, /* 8 channels */
519 25, /* volume */
520 solarq_sample_names
521 };
522
523
solarq_sound_w(UINT8 sound_val,UINT8 bits_changed)524 void solarq_sound_w(UINT8 sound_val, UINT8 bits_changed)
525 {
526 UINT32 shift_diff, shift_diff16;
527 static int target_volume, current_volume;
528
529 cinemat_shift (sound_val, bits_changed, 0x80, 0x10);
530
531 if ((bits_changed & 0x01) && (0 == (sound_val & 0x01)))
532 {
533 shift_diff16 = current_shift ^ last_shift16;
534
535 if ((shift_diff16 & 0x1) && (current_shift & 0x1))
536 {
537 switch (current_shift & 0xffff)
538 {
539 case 0xceb3:
540 sample_start(7, 7, 0); // Hyperspace
541 break;
542 case 0x13f3:
543 sample_start(7, 8, 0); // Extra
544 break;
545 case 0xfdf3:
546 sample_start(7, 9, 0); // Phase
547 break;
548 case 0x7bf3:
549 sample_start(7, 10, 0); // Enemy fire
550 break;
551 default:
552 logerror("Unknown sound starting with: %x\n", current_shift & 0xffff);
553 break;
554 }
555 }
556
557 last_shift16 = current_shift;
558 }
559
560 // Now see if it's time to act upon the shifted data
561
562 if ((bits_changed & 0x02) && (0 == (sound_val & 0x02)))
563 {
564 // Yep. Falling edge! Find out what has changed.
565
566 shift_diff = current_shift ^ last_shift;
567
568 if ((shift_diff & 0x01) && (0 == (current_shift & 0x01)))
569 sample_start(0, 0, 0); // loud expl.
570
571 if ((shift_diff & 0x02) && (0 == (current_shift & 0x02)))
572 sample_start(1, 1, 0); // soft expl.
573
574 if (shift_diff & 0x04) // thrust
575 {
576 if (current_shift & 0x04)
577 target_volume = 0;
578 else
579 {
580 target_volume = 255;
581 current_volume = 0;
582 sample_start(2, 2, 1);
583 }
584 }
585
586 if (sample_playing(2) && (last_frame < cpu_getcurrentframe()))
587 {
588 if (current_volume > target_volume)
589 current_volume -= 20;
590 if (current_volume < target_volume)
591 current_volume += 20;
592 if (current_volume > 0)
593 sample_set_volume(2, current_volume);
594 else
595 sample_stop(2);
596 last_frame = cpu_getcurrentframe();
597 }
598
599 if ((shift_diff & 0x08) && (0 == (current_shift & 0x08)))
600 sample_start(3, 3, 0); // Fire
601
602 if ((shift_diff & 0x10) && (0 == (current_shift & 0x10)))
603 sample_start(4, 4, 0); // Capture
604
605 if (shift_diff & 0x20)
606 {
607 if (current_shift & 0x20)
608 sample_start(6, 6, 1); // Nuke +
609 else
610 sample_stop(6);
611 }
612
613 if ((shift_diff & 0x40) && (0 == (current_shift & 0x40)))
614 sample_start(5, 5, 0); // Photon
615
616 last_shift = current_shift;
617 }
618 }
619
620
621 /*************************************
622 *
623 * Space Wars
624 *
625 *************************************/
626
627 static const char *spacewar_sample_names[] =
628 {
629 "*spacewar",
630 "explode1.wav",
631 "fire1.wav",
632 "idle.wav",
633 "thrust1.wav",
634 "thrust2.wav",
635 "pop.wav",
636 "explode2.wav",
637 "fire2.wav",
638 0 /* end of array */
639 };
640
641 struct Samplesinterface spacewar_samples_interface =
642 {
643 8, /* 8 channels */
644 25, /* volume */
645 spacewar_sample_names
646 };
647
spacewar_sound_w(UINT8 sound_val,UINT8 bits_changed)648 void spacewar_sound_w(UINT8 sound_val, UINT8 bits_changed)
649 {
650
651 // Explosion
652
653 if (bits_changed & 0x01)
654 {
655 if (sound_val & 0x01)
656 {
657 if (rand() & 1)
658 sample_start(0, 0, 0);
659 else
660 sample_start(0, 6, 0);
661 }
662 }
663 // Fire sound
664
665 if ((sound_val & 0x02) && (bits_changed & 0x02))
666 {
667 if (rand() & 1)
668 sample_start(1, 1, 0);
669 else
670 sample_start(1, 7, 0);
671 }
672
673 // Player 1 thrust
674
675 if (bits_changed & 0x04)
676 {
677 if (sound_val & 0x04)
678 sample_stop(3);
679 else
680 sample_start(3, 3, 1);
681 }
682
683 // Player 2 thrust
684
685 if (bits_changed & 0x08)
686 {
687 if (sound_val & 0x08)
688 sample_stop(4);
689 else
690 sample_start(4, 4, 1);
691 }
692
693 // Sound board shutoff (or enable)
694
695 if (bits_changed & 0x10)
696 {
697 // This is a toggle bit. If sound is enabled, shut everything off.
698
699 if (sound_val & 0x10)
700 {
701 int i;
702
703 for (i = 0; i < 5; i++)
704 {
705 if (i != 2)
706 sample_stop(i);
707 }
708
709 sample_start(2, 5, 0); // Pop when board is shut off
710 }
711 else
712 sample_start(2, 2, 1); // Otherwise play idle sound
713 }
714 }
715
716
717 /*************************************
718 *
719 * Demon
720 *
721 *************************************/
722
723 /* circular queue with read and write pointers */
724 #define QUEUE_ENTRY_COUNT 10
725 static int sound_latch_rp = 0;
726 static int sound_latch_wp = 0;
727 static int sound_latch[QUEUE_ENTRY_COUNT];
728
demon_sound_w(UINT8 sound_val,UINT8 bits_changed)729 void demon_sound_w(UINT8 sound_val, UINT8 bits_changed)
730 {
731 int pc = activecpu_get_pc();
732
733 if (pc == 0x0fbc ||
734 pc == 0x1fed ||
735 pc == 0x2ff1 ||
736 pc == 0x3fd3)
737 {
738 sound_latch[sound_latch_wp] = ((sound_val & 0x07) << 3);
739 }
740 if (pc == 0x0fc8 ||
741 pc == 0x1ff9 ||
742 pc == 0x2ffd ||
743 pc == 0x3fdf)
744 {
745 sound_latch[sound_latch_wp] |= (sound_val & 0x07);
746
747 //logerror("Writing Sound Latch %04X = %02X\n", pc, sound_latch[sound_latch_wp]);
748
749 sound_latch_wp++;
750 if (sound_latch_wp == QUEUE_ENTRY_COUNT) sound_latch_wp = 0;
751 }
752 }
753
READ_HANDLER(demon_sound_r)754 static READ_HANDLER( demon_sound_r )
755 {
756 int ret;
757
758 if (sound_latch_rp == sound_latch_wp) return 0x80; /* no data in queue */
759
760 ret = sound_latch[sound_latch_rp];
761
762 sound_latch_rp++;
763 if (sound_latch_rp == QUEUE_ENTRY_COUNT) sound_latch_rp = 0;
764
765 //logerror("Reading Sound Latch %04X = %02X\n", activecpu_get_pc(), ret);
766
767 return ret;
768 }
769
770
771 struct AY8910interface demon_ay8910_interface =
772 {
773 3, /* 3 chips */
774 3579545, /* 3.579545 MHz */
775 { 25, 25, 25 },
776 { demon_sound_r },
777 { 0 }, /* there are sound enable bits in here, but don't know what is what */
778 { 0 },
779 { 0 }
780 };
781
782
ctc_interrupt(int state)783 static void ctc_interrupt(int state)
784 {
785 cpu_set_irq_line_and_vector(1, 0, HOLD_LINE, Z80_VECTOR(0,state));
786 }
787
788
789 z80ctc_interface demon_z80ctc_interface =
790 {
791 1, /* 1 chip */
792 { 0 }, /* clock (filled in from the CPU clock) */
793 { 0 }, /* timer disables */
794 { ctc_interrupt }, /* interrupt handler */
795 { 0 }, /* ZC/TO0 callback */
796 { 0 }, /* ZC/TO1 callback */
797 { 0 } /* ZC/TO2 callback */
798 };
799
800
MACHINE_INIT(demon_sound)801 MACHINE_INIT( demon_sound )
802 {
803 demon_z80ctc_interface.baseclock[0] = Machine->drv->cpu[1].cpu_clock;
804 z80ctc_init(&demon_z80ctc_interface);
805 }
806
807
MEMORY_READ_START(demon_sound_readmem)808 MEMORY_READ_START( demon_sound_readmem )
809 { 0x0000, 0x0fff, MRA_ROM },
810 { 0x3000, 0x33ff, MRA_RAM },
811 { 0x4001, 0x4001, AY8910_read_port_0_r },
812 { 0x5001, 0x5001, AY8910_read_port_1_r },
813 { 0x6001, 0x6001, AY8910_read_port_2_r },
814 MEMORY_END
815
816
817 MEMORY_WRITE_START( demon_sound_writemem )
818 { 0x0000, 0x0fff, MWA_ROM },
819 { 0x3000, 0x33ff, MWA_RAM },
820 { 0x4002, 0x4002, AY8910_write_port_0_w },
821 { 0x4003, 0x4003, AY8910_control_port_0_w },
822 { 0x5002, 0x5002, AY8910_write_port_1_w },
823 { 0x5003, 0x5003, AY8910_control_port_1_w },
824 { 0x6002, 0x6002, AY8910_write_port_2_w },
825 { 0x6003, 0x6003, AY8910_control_port_2_w },
826 { 0x7000, 0x7000, MWA_NOP }, /* watchdog? */
827 MEMORY_END
828
829
830 PORT_WRITE_START( demon_sound_writeport )
831 { 0x00, 0x03, z80ctc_0_w },
832 { 0x1c, 0x1f, z80ctc_0_w },
833 PORT_END
834
835
836 static Z80_DaisyChain daisy_chain[] =
837 {
838 { z80ctc_reset, z80ctc_interrupt, z80ctc_reti, 0 }, /* CTC number 0 */
839 { 0,0,0,-1} /* end mark */
840 };
841
842
843 MACHINE_DRIVER_START( demon_sound )
844
845 /* basic machine hardware */
846 MDRV_CPU_ADD(Z80, 3579545)
847 MDRV_CPU_FLAGS(CPU_AUDIO_CPU);
848 MDRV_CPU_CONFIG(daisy_chain)
849 MDRV_CPU_MEMORY(demon_sound_readmem,demon_sound_writemem)
850 MDRV_CPU_PORTS(0,demon_sound_writeport)
851
852 MDRV_MACHINE_INIT( demon_sound )
853
854 /* sound hardware */
855 MDRV_SOUND_ADD(AY8910, demon_ay8910_interface)
856 MACHINE_DRIVER_END
857