1 /***************************************************************************
2 
3 	Cinematronics Cosmic Chasm hardware
4 
5 ***************************************************************************/
6 
7 #include "driver.h"
8 #include "cpu/z80/z80.h"
9 #include "machine/z80fmly.h"
10 #include "cchasm.h"
11 
12 static int sound_flags;
13 
READ_HANDLER(cchasm_snd_io_r)14 READ_HANDLER( cchasm_snd_io_r )
15 {
16     int coin;
17 
18     switch (offset & 0x61 )
19     {
20     case 0x00:
21         coin = (input_port_3_r (offset) >> 4) & 0x7;
22         if (coin != 0x7) coin |= 0x8;
23         return sound_flags | coin;
24 
25     case 0x01:
26         return AY8910_read_port_0_r (offset);
27 
28     case 0x21:
29         return AY8910_read_port_1_r (offset);
30 
31     case 0x40:
32         return soundlatch_r (offset);
33 
34     case 0x41:
35         sound_flags &= ~0x80;
36         z80ctc_0_trg2_w (0, 0);
37         return soundlatch2_r (offset);
38     default:
39         logerror("Read from unmapped internal IO device at 0x%x\n", offset + 0x6000);
40         return 0;
41     }
42 }
43 
WRITE_HANDLER(cchasm_snd_io_w)44 WRITE_HANDLER( cchasm_snd_io_w )
45 {
46     switch (offset & 0x61 )
47     {
48     case 0x00:
49         AY8910_control_port_0_w (offset, data);
50         break;
51 
52     case 0x01:
53         AY8910_write_port_0_w (offset, data);
54         break;
55 
56     case 0x20:
57         AY8910_control_port_1_w (offset, data);
58         break;
59 
60     case 0x21:
61         AY8910_write_port_1_w (offset, data);
62         break;
63 
64     case 0x40:
65         soundlatch3_w (offset, data);
66         break;
67 
68     case 0x41:
69         sound_flags |= 0x40;
70         soundlatch4_w (offset, data);
71         cpu_set_irq_line(0, 1, HOLD_LINE);
72         break;
73 
74     case 0x61:
75         z80ctc_0_trg0_w (0, 0);
76         break;
77 
78     default:
79         logerror("Write %x to unmapped internal IO device at 0x%x\n", data, offset + 0x6000);
80     }
81 }
82 
WRITE16_HANDLER(cchasm_io_w)83 WRITE16_HANDLER( cchasm_io_w )
84 {
85     static int led;
86 
87 	if (ACCESSING_MSB)
88 	{
89 		data >>= 8;
90 		switch (offset & 0xf)
91 		{
92 		case 0:
93 			soundlatch_w (offset, data);
94 			break;
95 		case 1:
96 			sound_flags |= 0x80;
97 			soundlatch2_w (offset, data);
98 			z80ctc_0_trg2_w (0, 1);
99 			cpu_set_irq_line(1, IRQ_LINE_NMI, PULSE_LINE);
100 			break;
101 		case 2:
102 			led = data;
103 			break;
104 		}
105 	}
106 }
107 
READ16_HANDLER(cchasm_io_r)108 READ16_HANDLER( cchasm_io_r )
109 {
110 	switch (offset & 0xf)
111 	{
112 	case 0x0:
113 		return soundlatch3_r (offset) << 8;
114 	case 0x1:
115 		sound_flags &= ~0x40;
116 		return soundlatch4_r (offset) << 8;
117 	case 0x2:
118 		return (sound_flags| (input_port_3_r (offset) & 0x07) | 0x08) << 8;
119 	case 0x5:
120 		return input_port_2_r (offset) << 8;
121 	case 0x8:
122 		return input_port_1_r (offset) << 8;
123 	default:
124 		return 0xff << 8;
125 	}
126 }
127 
128 static int channel[2], channel_active[2];
129 static int output[2];
130 
ctc_interrupt(int state)131 static void ctc_interrupt (int state)
132 {
133 	cpu_set_irq_line_and_vector(1, 0, HOLD_LINE, Z80_VECTOR(0,state));
134 }
135 
WRITE_HANDLER(ctc_timer_1_w)136 static WRITE_HANDLER( ctc_timer_1_w )
137 {
138 
139     if (data) /* rising edge */
140     {
141         output[0] ^= 0x7f;
142         channel_active[0] = 1;
143         stream_update(channel[0], 0);
144     }
145 }
146 
WRITE_HANDLER(ctc_timer_2_w)147 static WRITE_HANDLER( ctc_timer_2_w )
148 {
149 
150     if (data) /* rising edge */
151     {
152         output[1] ^= 0x7f;
153         channel_active[1] = 1;
154         stream_update(channel[1], 0);
155     }
156 }
157 
158 static z80ctc_interface ctc_intf =
159 {
160 	1,                   /* 1 chip */
161 	{ 0 },               /* clock (filled in from the CPU 0 clock */
162 	{ 0 },               /* timer disables */
163 	{ ctc_interrupt },   /* interrupt handler */
164 	{ 0 },               /* ZC/TO0 callback */
165 	{ ctc_timer_1_w },     /* ZC/TO1 callback */
166 	{ ctc_timer_2_w }      /* ZC/TO2 callback */
167 };
168 
tone_update(int num,INT16 * buffer,int length)169 static void tone_update(int num,INT16 *buffer,int length)
170 {
171 	INT16 out = 0;
172 
173 	if (channel_active[num])
174 		out = output[num] << 8;
175 
176 	while (length--) *(buffer++) = out;
177 	channel_active[num] = 0;
178 }
179 
cchasm_sh_start(const struct MachineSound * msound)180 int cchasm_sh_start(const struct MachineSound *msound)
181 {
182     sound_flags = 0;
183     output[0] = 0; output[1] = 0;
184 
185     channel[0] = stream_init("CTC sound 1", 50, Machine->sample_rate, 0, tone_update);
186     channel[1] = stream_init("CTC sound 2", 50, Machine->sample_rate, 1, tone_update);
187 
188 	ctc_intf.baseclock[0] = Machine->drv->cpu[1].cpu_clock;
189 	z80ctc_init (&ctc_intf);
190 
191 	return 0;
192 }
193 
cchasm_sh_update(void)194 void cchasm_sh_update(void)
195 {
196     if ((input_port_3_r (0) & 0x70) != 0x70)
197         z80ctc_0_trg0_w (0, 1);
198 }
199 
200 
201