1 #include "driver.h"
2 #include "cpu/m6502/m6502.h"
3 
4 
5 
6 
WRITE_HANDLER(gottlieb_sh_w)7 WRITE_HANDLER( gottlieb_sh_w )
8 {
9 	static int score_sample=7;
10 	static int random_offset=0;
11 	data &= 0x3f;
12 
13 	if ((data&0x0f) != 0xf) /* interrupt trigered by four low bits (not all 1's) */
14 	{
15 		if (Machine->samples)
16 		{
17 			if (!strcmp(Machine->gamedrv->name,"reactor"))	/* reactor */
18 			{
19 				switch (data ^ 0x3f)
20 				{
21 					case 53:
22 					case 54:
23 					case 55:
24 					case 56:
25 					case 57:
26 					case 58:
27 					case 59:
28 						sample_start(0,(data^0x3f)-53,0);
29 						break;
30 					case 31:
31 						sample_start(0,7,0);
32 						score_sample=7;
33 						break;
34 					case 39:
35 						score_sample++;
36 						if (score_sample<20) sample_start(0,score_sample,0);
37 						break;
38 				}
39 			}
40 			else	/* qbert */
41 			{
42 				switch (data ^ 0x3f)
43 				{
44 					case 17:
45 					case 18:
46 					case 19:
47 					case 20:
48 					case 21:
49 						sample_start(0,((data^0x3f)-17)*8+random_offset,0);
50 						random_offset= (random_offset+1)&7;
51 						break;
52 					case 22:
53 						sample_start(0,40,0);
54 						break;
55 					case 23:
56 						sample_start(0,41,0);
57 						break;
58 					case 28:
59 						sample_start(0,42,0);
60 						break;
61 					case 36:
62 						sample_start(0,43,0);
63 						break;
64 				}
65 			}
66 		}
67 
68 		soundlatch_w(offset,data);
69 
70 		switch (cpu_gettotalcpu())
71 		{
72 		case 2:
73 			/* Revision 1 sound board */
74 			cpu_cause_interrupt(1,M6502_INT_IRQ);
75 			break;
76 		case 3:
77 		case 4:
78 			/* Revision 2 & 3 sound board */
79 			cpu_cause_interrupt(cpu_gettotalcpu()-1,M6502_INT_IRQ);
80 			cpu_cause_interrupt(cpu_gettotalcpu()-2,M6502_INT_IRQ);
81 			break;
82 		}
83 	}
84 }
85 
86 
gottlieb_knocker(void)87 void gottlieb_knocker(void)
88 {
89 	if (Machine->samples)
90 	{
91 		if (!strcmp(Machine->gamedrv->name,"reactor"))	/* reactor */
92 		{
93 		}
94 		else	/* qbert */
95 			sample_start(0,44,0);
96 	}
97 }
98 
99 /* callback for the timer */
gottlieb_nmi_generate(int param)100 void gottlieb_nmi_generate(int param)
101 {
102 	cpu_cause_interrupt(1,M6502_INT_NMI);
103 }
104 
105 #if 0
106 static const char *PhonemeTable[65] =
107 {
108  "EH3","EH2","EH1","PA0","DT" ,"A1" ,"A2" ,"ZH",
109  "AH2","I3" ,"I2" ,"I1" ,"M"  ,"N"  ,"B"  ,"V",
110  "CH" ,"SH" ,"Z"  ,"AW1","NG" ,"AH1","OO1","OO",
111  "L"  ,"K"  ,"J"  ,"H"  ,"G"  ,"F"  ,"D"  ,"S",
112  "A"  ,"AY" ,"Y1" ,"UH3","AH" ,"P"  ,"O"  ,"I",
113  "U"  ,"Y"  ,"T"  ,"R"  ,"E"  ,"W"  ,"AE" ,"AE1",
114  "AW2","UH2","UH1","UH" ,"O2" ,"O1" ,"IU" ,"U1",
115  "THV","TH" ,"ER" ,"EH" ,"E1" ,"AW" ,"PA1","STOP",
116  0
117 };
118 #endif
119 
WRITE_HANDLER(gottlieb_speech_w)120 WRITE_HANDLER( gottlieb_speech_w )
121 {
122 	static int queue[100],pos;
123 
124 	data ^= 255;
125 
126 //logerror("Votrax: intonation %d, phoneme %02x %s\n",data >> 6,data & 0x3f,PhonemeTable[data & 0x3f]);
127 
128 	queue[pos++] = data & 0x3f;
129 
130 	if ((data & 0x3f) == 0x3f)
131 	{
132 #if 0
133 		if (pos > 1)
134 		{
135 			int i;
136 			char buf[200];
137 
138 			buf[0] = 0;
139 			for (i = 0;i < pos-1;i++)
140 			{
141 				if (queue[i] == 0x03 || queue[i] == 0x3e) strcat(buf," ");
142 				else strcat(buf,PhonemeTable[queue[i]]);
143 			}
144 
145 			usrintf_showmessage(buf);
146 		}
147 #endif
148 
149 		pos = 0;
150 	}
151 
152 	/* generate a NMI after a while to make the CPU continue to send data */
153 	timer_set(TIME_IN_USEC(50),0,gottlieb_nmi_generate);
154 }
155 
WRITE_HANDLER(gottlieb_speech_clock_DAC_w)156 WRITE_HANDLER( gottlieb_speech_clock_DAC_w )
157 {}
158 
159 
160 
161     /* partial decoding takes place to minimize chip count in a 6502+6532
162        system, so both page 0 (direct page) and 1 (stack) access the same
163        128-bytes ram,
164        either with the first 128 bytes of the page or the last 128 bytes */
165 
166 unsigned char *riot_ram;
167 
READ_HANDLER(riot_ram_r)168 READ_HANDLER( riot_ram_r )
169 {
170     return riot_ram[offset&0x7f];
171 }
172 
WRITE_HANDLER(riot_ram_w)173 WRITE_HANDLER( riot_ram_w )
174 {
175 	riot_ram[offset&0x7f]=data;
176 }
177 
178 static unsigned char riot_regs[32];
179     /* lazy handling of the 6532's I/O, and no handling of timers at all */
180 
READ_HANDLER(gottlieb_riot_r)181 READ_HANDLER( gottlieb_riot_r )
182 {
183     switch (offset&0x1f) {
184 	case 0: /* port A */
185 		return soundlatch_r(offset) ^ 0xff;	/* invert command */
186 	case 2: /* port B */
187 		return 0x40;    /* say that PB6 is 1 (test SW1 not pressed) */
188 	case 5: /* interrupt register */
189 		return 0x40;    /* say that edge detected on PA7 */
190 	default:
191 		return riot_regs[offset&0x1f];
192     }
193 }
194 
WRITE_HANDLER(gottlieb_riot_w)195 WRITE_HANDLER( gottlieb_riot_w )
196 {
197     riot_regs[offset&0x1f]=data;
198 }
199 
200 
201 
202 
203 static int psg_latch;
204 static void *nmi_timer;
205 static int nmi_rate;
206 static int ym2151_port;
207 
gottlieb_sound_init(void)208 void gottlieb_sound_init(void)
209 {
210 	nmi_timer = NULL;
211 }
212 
READ_HANDLER(stooges_sound_input_r)213 READ_HANDLER( stooges_sound_input_r )
214 {
215 	/* bits 0-3 are probably unused (future expansion) */
216 
217 	/* bits 4 & 5 are two dip switches. Unused? */
218 
219 	/* bit 6 is the test switch. When 0, the CPU plays a pulsing tone. */
220 
221 	/* bit 7 comes from the speech chip DATA REQUEST pin */
222 
223 	return 0xc0;
224 }
225 
WRITE_HANDLER(stooges_8910_latch_w)226 WRITE_HANDLER( stooges_8910_latch_w )
227 {
228 	psg_latch = data;
229 }
230 
231 /* callback for the timer */
nmi_callback(int param)232 static void nmi_callback(int param)
233 {
234 	cpu_cause_interrupt(cpu_gettotalcpu()-1, M6502_INT_NMI);
235 }
236 
WRITE_HANDLER(common_sound_control_w)237 static WRITE_HANDLER( common_sound_control_w )
238 {
239 	/* Bit 0 enables and starts NMI timer */
240 
241 	if (nmi_timer)
242 	{
243 		timer_remove(nmi_timer);
244 		nmi_timer = 0;
245 	}
246 
247 	if (data & 0x01)
248 	{
249 		/* base clock is 250kHz divided by 256 */
250 		timer_tm interval = TIME_IN_HZ(250000.0/256/(256-nmi_rate));
251 		nmi_timer = timer_pulse(interval, 0, nmi_callback);
252 	}
253 
254 	/* Bit 1 controls a LED on the sound board. I'm not emulating it */
255 }
256 
WRITE_HANDLER(stooges_sound_control_w)257 WRITE_HANDLER( stooges_sound_control_w )
258 {
259 	static int last;
260 
261 	common_sound_control_w(offset, data);
262 
263 	/* bit 2 goes to 8913 BDIR pin  */
264 	if ((last & 0x04) == 0x04 && (data & 0x04) == 0x00)
265 	{
266 		/* bit 3 selects which of the two 8913 to enable */
267 		if (data & 0x08)
268 		{
269 			/* bit 4 goes to the 8913 BC1 pin */
270 			if (data & 0x10)
271 				AY8910_control_port_0_w(0,psg_latch);
272 			else
273 				AY8910_write_port_0_w(0,psg_latch);
274 		}
275 		else
276 		{
277 			/* bit 4 goes to the 8913 BC1 pin */
278 			if (data & 0x10)
279 				AY8910_control_port_1_w(0,psg_latch);
280 			else
281 				AY8910_write_port_1_w(0,psg_latch);
282 		}
283 	}
284 
285 	/* bit 5 goes to the speech chip DIRECT DATA TEST pin */
286 
287 	/* bit 6 = speech chip DATA PRESENT pin; high then low to make the chip read data */
288 	if ((last & 0x40) == 0x40 && (data & 0x40) == 0x00)
289 	{
290 	}
291 
292 	/* bit 7 goes to the speech chip RESET pin */
293 
294 	last = data & 0x44;
295 }
296 
WRITE_HANDLER(exterm_sound_control_w)297 WRITE_HANDLER( exterm_sound_control_w )
298 {
299 	common_sound_control_w(offset, data);
300 
301 	/* Bit 7 selects YM2151 register or data port */
302 	ym2151_port = data & 0x80;
303 }
304 
WRITE_HANDLER(gottlieb_nmi_rate_w)305 WRITE_HANDLER( gottlieb_nmi_rate_w )
306 {
307 	nmi_rate = data;
308 }
309 
cause_dac_nmi_callback(int param)310 static void cause_dac_nmi_callback(int param)
311 {
312 	cpu_cause_interrupt(cpu_gettotalcpu()-2, M6502_INT_NMI);
313 }
314 
WRITE_HANDLER(gottlieb_cause_dac_nmi_w)315 WRITE_HANDLER( gottlieb_cause_dac_nmi_w )
316 {
317 	/* make all the CPUs synchronize, and only AFTER that cause the NMI */
318 	timer_set(TIME_NOW,0,cause_dac_nmi_callback);
319 }
320 
READ_HANDLER(gottlieb_cause_dac_nmi_r)321 READ_HANDLER( gottlieb_cause_dac_nmi_r )
322 {
323     gottlieb_cause_dac_nmi_w(offset, 0);
324 	return 0;
325 }
326 
WRITE_HANDLER(exterm_ym2151_w)327 WRITE_HANDLER( exterm_ym2151_w )
328 {
329 	if (ym2151_port)
330 	{
331 		YM2151_data_port_0_w(offset, data);
332 	}
333 	else
334 	{
335 		YM2151_register_port_0_w(offset, data);
336 	}
337 }
338