1 /***************************************************************************
2 
3 Atari Audio Board II
4 --------------------
5 
6 6502 MEMORY MAP
7 
8 Function                                  Address     R/W  Data
9 ---------------------------------------------------------------
10 Program RAM                               0000-1FFF   R/W  D0-D7
11 
12 Music (YM-2151)                           2000-2001   R/W  D0-D7
13 
14 Read 68010 Port (Input Buffer)            280A        R    D0-D7
15 
16 Self-test                                 280C        R    D7
17 Output Buffer Full (@2A02) (Active High)              R    D5
18 Left Coin Switch                                      R    D1
19 Right Coin Switch                                     R    D0
20 
21 Interrupt acknowledge                     2A00        W    xx
22 Write 68010 Port (Outbut Buffer)          2A02        W    D0-D7
23 Banked ROM select (at 3000-3FFF)          2A04        W    D6-D7
24 ???                                       2A06        W
25 
26 Effects                                   2C00-2C0F   R/W  D0-D7
27 
28 Banked Program ROM (4 pages)              3000-3FFF   R    D0-D7
29 Static Program ROM (48K bytes)            4000-FFFF   R    D0-D7
30 
31 ****************************************************************************/
32 
33 #include "machine/atarigen.h"
34 #include "sndhrdw/atarijsa.h"
35 #include "cpu/m6502/m6502.h"
36 
37 static UINT8 *bank_base;
38 static UINT8 *bank_source_data;
39 
40 static UINT8 speech_data;
41 static UINT8 last_ctl;
42 
43 static UINT8 cpu_num;
44 static UINT8 input_port;
45 static UINT8 test_port;
46 static UINT16 test_mask;
47 
48 static UINT8 has_pokey;
49 static UINT8 has_ym2151;
50 static UINT8 has_tms5220;
51 static UINT8 has_oki6295;
52 
53 static UINT32 oki6295_bank_base;
54 
55 static UINT8 overall_volume;
56 static UINT8 pokey_volume;
57 static UINT8 ym2151_volume;
58 static UINT8 tms5220_volume;
59 static UINT8 oki6295_volume;
60 
61 static void update_all_volumes(void);
62 
63 static READ_HANDLER( jsa1_io_r );
64 static WRITE_HANDLER( jsa1_io_w );
65 static READ_HANDLER( jsa2_io_r );
66 static WRITE_HANDLER( jsa2_io_w );
67 static READ_HANDLER( jsa3_io_r );
68 static WRITE_HANDLER( jsa3_io_w );
69 
70 
71 /*************************************
72  *
73  *	External interfaces
74  *
75  *************************************/
76 
atarijsa_init(int cpunum,int inputport,int testport,int testmask)77 void atarijsa_init(int cpunum, int inputport, int testport, int testmask)
78 {
79 	int i;
80 
81 	/* copy in the parameters */
82 	cpu_num = cpunum;
83 	input_port = inputport;
84 	test_port = testport;
85 	test_mask = testmask;
86 
87 	/* predetermine the bank base */
88 	bank_base = &memory_region(REGION_CPU1+cpunum)[0x03000];
89 	bank_source_data = &memory_region(REGION_CPU1+cpunum)[0x10000];
90 
91 	/* determine which sound hardware is installed */
92 	has_tms5220 = has_oki6295 = has_pokey = has_ym2151 = 0;
93 	for (i = 0; i < MAX_SOUND; i++)
94 	{
95 		switch (Machine->drv->sound[i].sound_type)
96 		{
97 			case SOUND_TMS5220:
98 				has_tms5220 = 1;
99 				break;
100 			case SOUND_OKIM6295:
101 				has_oki6295 = 1;
102 				break;
103 			case SOUND_POKEY:
104 				has_pokey = 1;
105 				break;
106 			case SOUND_YM2151:
107 				has_ym2151 = 1;
108 				break;
109 		}
110 	}
111 
112 	/* install POKEY memory handlers */
113 	if (has_pokey)
114 	{
115 		install_mem_read_handler(cpunum, 0x2c00, 0x2c0f, pokey1_r);
116 		install_mem_write_handler(cpunum, 0x2c00, 0x2c0f, pokey1_w);
117 	}
118 
119 	atarijsa_reset();
120 }
121 
122 
atarijsa_reset(void)123 void atarijsa_reset(void)
124 {
125 	/* reset the sound I/O system */
126 	atarigen_sound_io_reset(cpu_num);
127 
128 	/* reset the static states */
129 	speech_data = 0;
130 	last_ctl = 0;
131 	oki6295_bank_base = 0x00000;
132 	overall_volume = 100;
133 	pokey_volume = 100;
134 	ym2151_volume = 100;
135 	tms5220_volume = 100;
136 	oki6295_volume = 100;
137 
138 	/* Guardians of the Hood assumes we're reset to bank 0 on startup */
139 	memcpy(bank_base, &bank_source_data[0x0000], 0x1000);
140 }
141 
142 
143 
144 /*************************************
145  *
146  *	JSA I I/O handlers
147  *
148  *************************************/
149 
READ_HANDLER(jsa1_io_r)150 static READ_HANDLER( jsa1_io_r )
151 {
152 	int result = 0xff;
153 
154 	switch (offset & 0x206)
155 	{
156 		case 0x000:		/* n/c */
157 			//logerror("atarijsa: Unknown read at %04X\n", offset & 0x206);
158 			break;
159 
160 		case 0x002:		/* /RDP */
161 			result = atarigen_6502_sound_r(offset);
162 			break;
163 
164 		case 0x004:		/* /RDIO */
165 			/*
166 				0x80 = self test
167 				0x40 = NMI line state (active low)
168 				0x20 = sound output full
169 				0x10 = TMS5220 ready (active low)
170 				0x08 = +5V
171 				0x04 = +5V
172 				0x02 = coin 2
173 				0x01 = coin 1
174 			*/
175 			result = readinputport(input_port);
176 			if (!(readinputport(test_port) & test_mask)) result ^= 0x80;
177 			if (atarigen_cpu_to_sound_ready) result ^= 0x40;
178 			if (atarigen_sound_to_cpu_ready) result ^= 0x20;
179 			if (!has_tms5220 || tms5220_ready_r()) result ^= 0x10;
180 			break;
181 
182 		case 0x006:		/* /IRQACK */
183 			atarigen_6502_irq_ack_r(0);
184 			break;
185 
186 		case 0x200:		/* /VOICE */
187 		case 0x202:		/* /WRP */
188 		case 0x204:		/* /WRIO */
189 		case 0x206:		/* /MIX */
190 			//logerror("atarijsa: Unknown read at %04X\n", offset & 0x206);
191 			break;
192 	}
193 
194 	return result;
195 }
196 
197 
WRITE_HANDLER(jsa1_io_w)198 static WRITE_HANDLER( jsa1_io_w )
199 {
200 	switch (offset & 0x206)
201 	{
202 		case 0x000:		/* n/c */
203 		case 0x002:		/* /RDP */
204 		case 0x004:		/* /RDIO */
205 			//logerror("atarijsa: Unknown write (%02X) at %04X\n", data & 0xff, offset & 0x206);
206 			break;
207 
208 		case 0x006:		/* /IRQACK */
209 			atarigen_6502_irq_ack_r(0);
210 			break;
211 
212 		case 0x200:		/* /VOICE */
213 			speech_data = data;
214 			break;
215 
216 		case 0x202:		/* /WRP */
217 			atarigen_6502_sound_w(offset, data);
218 			break;
219 
220 		case 0x204:		/* WRIO */
221 			/*
222 				0xc0 = bank address
223 				0x20 = coin counter 2
224 				0x10 = coin counter 1
225 				0x08 = squeak (tweaks the 5220 frequency)
226 				0x04 = TMS5220 reset (active low)
227 				0x02 = TMS5220 write strobe (active low)
228 				0x01 = YM2151 reset (active low)
229 			*/
230 
231 			/* handle TMS5220 I/O */
232 			if (has_tms5220)
233 			{
234 				int count;
235 
236 				if (((data ^ last_ctl) & 0x02) && (data & 0x02))
237 					tms5220_data_w(0, speech_data);
238 				count = 5 | ((data >> 2) & 2);
239 				tms5220_set_frequency(ATARI_CLOCK_14MHz/2 / (16 - count));
240 			}
241 
242 			/* update the bank */
243 			memcpy(bank_base, &bank_source_data[0x1000 * ((data >> 6) & 3)], 0x1000);
244 			last_ctl = data;
245 			break;
246 
247 		case 0x206:		/* MIX */
248 			/*
249 				0xc0 = TMS5220 volume (0-3)
250 				0x30 = POKEY volume (0-3)
251 				0x0e = YM2151 volume (0-7)
252 				0x01 = low-pass filter enable
253 			*/
254 			tms5220_volume = ((data >> 6) & 3) * 100 / 3;
255 			pokey_volume = ((data >> 4) & 3) * 100 / 3;
256 			ym2151_volume = ((data >> 1) & 7) * 100 / 7;
257 			update_all_volumes();
258 			break;
259 	}
260 }
261 
262 
263 
264 /*************************************
265  *
266  *	JSA II I/O handlers
267  *
268  *************************************/
269 
READ_HANDLER(jsa2_io_r)270 static READ_HANDLER( jsa2_io_r )
271 {
272 	int result = 0xff;
273 
274 	switch (offset & 0x206)
275 	{
276 		case 0x000:		/* /RDV */
277 			if (has_oki6295)
278 				result = OKIM6295_status_0_r(offset);
279 			/*else
280 				logerror("atarijsa: Unknown read at %04X\n", offset & 0x206);*/
281 			break;
282 
283 		case 0x002:		/* /RDP */
284 			result = atarigen_6502_sound_r(offset);
285 			break;
286 
287 		case 0x004:		/* /RDIO */
288 			/*
289 				0x80 = self test
290 				0x40 = NMI line state (active low)
291 				0x20 = sound output full
292 				0x10 = +5V
293 				0x08 = +5V
294 				0x04 = +5V
295 				0x02 = coin 2
296 				0x01 = coin 1
297 			*/
298 			result = readinputport(input_port);
299 			if (!(readinputport(test_port) & test_mask)) result ^= 0x80;
300 			if (atarigen_cpu_to_sound_ready) result ^= 0x40;
301 			if (atarigen_sound_to_cpu_ready) result ^= 0x20;
302 			break;
303 
304 		case 0x006:		/* /IRQACK */
305 			atarigen_6502_irq_ack_r(0);
306 			break;
307 
308 		case 0x200:		/* /WRV */
309 		case 0x202:		/* /WRP */
310 		case 0x204:		/* /WRIO */
311 		case 0x206:		/* /MIX */
312 			//logerror("atarijsa: Unknown read at %04X\n", offset & 0x206);
313 			break;
314 	}
315 
316 	return result;
317 }
318 
319 
WRITE_HANDLER(jsa2_io_w)320 static WRITE_HANDLER( jsa2_io_w )
321 {
322 	switch (offset & 0x206)
323 	{
324 		case 0x000:		/* /RDV */
325 		case 0x002:		/* /RDP */
326 		case 0x004:		/* /RDIO */
327 			//logerror("atarijsa: Unknown write (%02X) at %04X\n", data & 0xff, offset & 0x206);
328 			break;
329 
330 		case 0x006:		/* /IRQACK */
331 			atarigen_6502_irq_ack_r(0);
332 			break;
333 
334 		case 0x200:		/* /WRV */
335 			if (has_oki6295)
336 				OKIM6295_data_0_w(offset, data);
337 			/*else
338 				logerror("atarijsa: Unknown write (%02X) at %04X\n", data & 0xff, offset & 0x206);*/
339 			break;
340 
341 		case 0x202:		/* /WRP */
342 			atarigen_6502_sound_w(offset, data);
343 			break;
344 
345 		case 0x204:		/* /WRIO */
346 			/*
347 				0xc0 = bank address
348 				0x20 = coin counter 2
349 				0x10 = coin counter 1
350 				0x08 = voice frequency (tweaks the OKI6295 frequency)
351 				0x04 = OKI6295 reset (active low)
352 				0x02 = n/c
353 				0x01 = YM2151 reset (active low)
354 			*/
355 
356 			/* update the bank */
357 			memcpy(bank_base, &bank_source_data[0x1000 * ((data >> 6) & 3)], 0x1000);
358 			last_ctl = data;
359 
360 			/* update the OKI frequency */
361 			OKIM6295_set_frequency(0, ALL_VOICES, ATARI_CLOCK_14MHz/4/3 / ((data & 8) ? 132 : 165));
362 			break;
363 
364 		case 0x206:		/* /MIX */
365 			/*
366 				0xc0 = n/c
367 				0x20 = low-pass filter enable
368 				0x10 = n/c
369 				0x0e = YM2151 volume (0-7)
370 				0x01 = OKI6295 volume (0-1)
371 			*/
372 			ym2151_volume = ((data >> 1) & 7) * 100 / 7;
373 			oki6295_volume = 50 + (data & 1) * 50;
374 			update_all_volumes();
375 			break;
376 	}
377 }
378 
379 
380 
381 /*************************************
382  *
383  *	JSA III I/O handlers
384  *
385  *************************************/
386 
READ_HANDLER(jsa3_io_r)387 static READ_HANDLER( jsa3_io_r )
388 {
389 	int result = 0xff;
390 
391 	switch (offset & 0x206)
392 	{
393 		case 0x000:		/* /RDV */
394 			if (has_oki6295)
395 				result = OKIM6295_status_0_r(offset);
396 			break;
397 
398 		case 0x002:		/* /RDP */
399 			result = atarigen_6502_sound_r(offset);
400 			break;
401 
402 		case 0x004:		/* /RDIO */
403 			/*
404 				0x80 = self test (active high)
405 				0x40 = NMI line state (active high)
406 				0x20 = sound output full (active high)
407 				0x10 = self test (active high)
408 				0x08 = service (active high)
409 				0x04 = tilt (active high)
410 				0x02 = coin L (active high)
411 				0x01 = coin R (active high)
412 			*/
413 			result = readinputport(input_port);
414 			if (!(readinputport(test_port) & test_mask)) result ^= 0x90;
415 			if (atarigen_cpu_to_sound_ready) result ^= 0x40;
416 			if (atarigen_sound_to_cpu_ready) result ^= 0x20;
417 			break;
418 
419 		case 0x006:		/* /IRQACK */
420 			atarigen_6502_irq_ack_r(0);
421 			break;
422 
423 		case 0x200:		/* /WRV */
424 		case 0x202:		/* /WRP */
425 		case 0x204:		/* /WRIO */
426 		case 0x206:		/* /MIX */
427 			//logerror("atarijsa: Unknown read at %04X\n", offset & 0x206);
428 			break;
429 	}
430 
431 	return result;
432 }
433 
434 
WRITE_HANDLER(jsa3_io_w)435 static WRITE_HANDLER( jsa3_io_w )
436 {
437 	switch (offset & 0x206)
438 	{
439 		case 0x000:		/* /RDV */
440 			overall_volume = data * 100 / 127;
441 			update_all_volumes();
442 			break;
443 
444 		case 0x002:		/* /RDP */
445 		case 0x004:		/* /RDIO */
446 			//logerror("atarijsa: Unknown write (%02X) at %04X\n", data & 0xff, offset & 0x206);
447 			break;
448 
449 		case 0x006:		/* /IRQACK */
450 			atarigen_6502_irq_ack_r(0);
451 			break;
452 
453 		case 0x200:		/* /WRV */
454 			if (has_oki6295)
455 				OKIM6295_data_0_w(offset, data);
456 			break;
457 
458 		case 0x202:		/* /WRP */
459 			atarigen_6502_sound_w(offset, data);
460 			break;
461 
462 		case 0x204:		/* /WRIO */
463 			/*
464 				0xc0 = bank address
465 				0x20 = coin counter 2
466 				0x10 = coin counter 1
467 				0x08 = voice frequency (tweaks the OKI6295 frequency)
468 				0x04 = OKI6295 reset (active low)
469 				0x02 = OKI6295 bank bit 0
470 				0x01 = YM2151 reset (active low)
471 			*/
472 
473 			/* update the OKI bank */
474 			oki6295_bank_base = (0x40000 * ((data >> 1) & 1)) | (oki6295_bank_base & 0x80000);
475 			OKIM6295_set_bank_base(0, ALL_VOICES, oki6295_bank_base);
476 
477 			/* update the bank */
478 			memcpy(bank_base, &bank_source_data[0x1000 * ((data >> 6) & 3)], 0x1000);
479 			last_ctl = data;
480 
481 			/* update the OKI frequency */
482 			OKIM6295_set_frequency(0, ALL_VOICES, ATARI_CLOCK_14MHz/4/3 / ((data & 8) ? 132 : 165));
483 			break;
484 
485 		case 0x206:		/* /MIX */
486 			/*
487 				0xc0 = n/c
488 				0x20 = low-pass filter enable
489 				0x10 = OKI6295 bank bit 1
490 				0x0e = YM2151 volume (0-7)
491 				0x01 = OKI6295 volume (0-1)
492 			*/
493 
494 			/* update the OKI bank */
495 			oki6295_bank_base = (0x80000 * ((data >> 4) & 1)) | (oki6295_bank_base & 0x40000);
496 			OKIM6295_set_bank_base(0, ALL_VOICES, oki6295_bank_base);
497 
498 			/* update the volumes */
499 			ym2151_volume = ((data >> 1) & 7) * 100 / 7;
500 			oki6295_volume = 50 + (data & 1) * 50;
501 			update_all_volumes();
502 			break;
503 	}
504 }
505 
506 
507 
508 /*************************************
509  *
510  *	JSA IIIS I/O handlers
511  *
512  *************************************/
513 
READ_HANDLER(jsa3s_io_r)514 static READ_HANDLER( jsa3s_io_r )
515 {
516 	int result = 0xff;
517 
518 	switch (offset & 0x206)
519 	{
520 		case 0x000:		/* /RDV */
521 			if (has_oki6295)
522 			{
523 				if (offset & 1)
524 					result = OKIM6295_status_1_r(offset);
525 				else
526 					result = OKIM6295_status_0_r(offset);
527 			}
528 			break;
529 
530 		case 0x002:		/* /RDP */
531 			result = atarigen_6502_sound_r(offset);
532 			break;
533 
534 		case 0x004:		/* /RDIO */
535 			/*
536 				0x80 = self test (active high)
537 				0x40 = NMI line state (active high)
538 				0x20 = sound output full (active high)
539 				0x10 = self test (active high)
540 				0x08 = service (active high)
541 				0x04 = tilt (active high)
542 				0x02 = coin L (active high)
543 				0x01 = coin R (active high)
544 			*/
545 			result = readinputport(input_port);
546 			if (!(readinputport(test_port) & test_mask)) result ^= 0x90;
547 			if (atarigen_cpu_to_sound_ready) result ^= 0x40;
548 			if (atarigen_sound_to_cpu_ready) result ^= 0x20;
549 			break;
550 
551 		case 0x006:		/* /IRQACK */
552 			atarigen_6502_irq_ack_r(0);
553 			break;
554 
555 		case 0x200:		/* /WRV */
556 		case 0x202:		/* /WRP */
557 		case 0x204:		/* /WRIO */
558 		case 0x206:		/* /MIX */
559 			//logerror("atarijsa: Unknown read at %04X\n", offset & 0x206);
560 			break;
561 	}
562 
563 	return result;
564 }
565 
566 
WRITE_HANDLER(jsa3s_io_w)567 static WRITE_HANDLER( jsa3s_io_w )
568 {
569 	switch (offset & 0x206)
570 	{
571 		case 0x000:		/* /RDV */
572 			overall_volume = data * 100 / 127;
573 			update_all_volumes();
574 			break;
575 
576 		case 0x002:		/* /RDP */
577 		case 0x004:		/* /RDIO */
578 			//logerror("atarijsa: Unknown write (%02X) at %04X\n", data & 0xff, offset & 0x206);
579 			break;
580 
581 		case 0x006:		/* /IRQACK */
582 			atarigen_6502_irq_ack_r(0);
583 			break;
584 
585 		case 0x200:		/* /WRV */
586 			if (has_oki6295)
587 			{
588 				if (offset & 1)
589 					OKIM6295_data_1_w(offset, data);
590 				else
591 					OKIM6295_data_0_w(offset, data);
592 			}
593 			break;
594 
595 		case 0x202:		/* /WRP */
596 			atarigen_6502_sound_w(offset, data);
597 			break;
598 
599 		case 0x204:		/* /WRIO */
600 			/*
601 				0xc0 = bank address
602 				0x20 = coin counter 2
603 				0x10 = coin counter 1
604 				0x08 = voice frequency (tweaks the OKI6295 frequency)
605 				0x04 = OKI6295 reset (active low)
606 				0x02 = left OKI6295 bank bit 0
607 				0x01 = YM2151 reset (active low)
608 			*/
609 
610 			/* update the OKI bank */
611 			oki6295_bank_base = (0x40000 * ((data >> 1) & 1)) | (oki6295_bank_base & 0x80000);
612 			OKIM6295_set_bank_base(0, ALL_VOICES, oki6295_bank_base);
613 
614 			/* update the bank */
615 			memcpy(bank_base, &bank_source_data[0x1000 * ((data >> 6) & 3)], 0x1000);
616 			last_ctl = data;
617 
618 			/* update the OKI frequency */
619 			OKIM6295_set_frequency(0, ALL_VOICES, ATARI_CLOCK_14MHz/4/3 / ((data & 8) ? 132 : 165));
620 			OKIM6295_set_frequency(1, ALL_VOICES, ATARI_CLOCK_14MHz/4/3 / ((data & 8) ? 132 : 165));
621 			break;
622 
623 		case 0x206:		/* /MIX */
624 			/*
625 				0xc0 = right OKI6295 bank bits 0-1
626 				0x20 = low-pass filter enable
627 				0x10 = left OKI6295 bank bit 1
628 				0x0e = YM2151 volume (0-7)
629 				0x01 = OKI6295 volume (0-1)
630 			*/
631 
632 			/* update the OKI bank */
633 			oki6295_bank_base = (0x80000 * ((data >> 4) & 1)) | (oki6295_bank_base & 0x40000);
634 			OKIM6295_set_bank_base(0, ALL_VOICES, oki6295_bank_base);
635 			OKIM6295_set_bank_base(1, ALL_VOICES, 0x40000 * (data >> 6));
636 
637 			/* update the volumes */
638 			ym2151_volume = ((data >> 1) & 7) * 100 / 7;
639 			oki6295_volume = 50 + (data & 1) * 50;
640 			update_all_volumes();
641 			break;
642 	}
643 }
644 
645 
646 
647 /*************************************
648  *
649  *	Volume helpers
650  *
651  *************************************/
652 
update_all_volumes(void)653 static void update_all_volumes(void)
654 {
655 	if (has_pokey) atarigen_set_pokey_vol(overall_volume * pokey_volume / 100);
656 	if (has_ym2151) atarigen_set_ym2151_vol(overall_volume * ym2151_volume / 100);
657 	if (has_tms5220) atarigen_set_tms5220_vol(overall_volume * tms5220_volume / 100);
658 	if (has_oki6295) atarigen_set_oki6295_vol(overall_volume * oki6295_volume / 100);
659 }
660 
661 
662 
663 /*************************************
664  *
665  *	Sound CPU memory handlers
666  *
667  *************************************/
668 
669 struct MemoryReadAddress atarijsa1_readmem[] =
670 {
671 	{ 0x0000, 0x1fff, MRA_RAM },
672 	{ 0x2000, 0x2001, YM2151_status_port_0_r },
673 	{ 0x2800, 0x2bff, jsa1_io_r },
674 	{ 0x3000, 0xffff, MRA_ROM },
675 	{ -1 }  /* end of table */
676 };
677 
678 
679 struct MemoryWriteAddress atarijsa1_writemem[] =
680 {
681 	{ 0x0000, 0x1fff, MWA_RAM },
682 	{ 0x2000, 0x2000, YM2151_register_port_0_w },
683 	{ 0x2001, 0x2001, YM2151_data_port_0_w },
684 	{ 0x2800, 0x2bff, jsa1_io_w },
685 	{ 0x3000, 0xffff, MWA_ROM },
686 	{ -1 }  /* end of table */
687 };
688 
689 
690 struct MemoryReadAddress atarijsa2_readmem[] =
691 {
692 	{ 0x0000, 0x1fff, MRA_RAM },
693 	{ 0x2000, 0x2001, YM2151_status_port_0_r },
694 	{ 0x2800, 0x2bff, jsa2_io_r },
695 	{ 0x3000, 0xffff, MRA_ROM },
696 	{ -1 }  /* end of table */
697 };
698 
699 
700 struct MemoryWriteAddress atarijsa2_writemem[] =
701 {
702 	{ 0x0000, 0x1fff, MWA_RAM },
703 	{ 0x2000, 0x2000, YM2151_register_port_0_w },
704 	{ 0x2001, 0x2001, YM2151_data_port_0_w },
705 	{ 0x2800, 0x2bff, jsa2_io_w },
706 	{ 0x3000, 0xffff, MWA_ROM },
707 	{ -1 }  /* end of table */
708 };
709 
710 
711 struct MemoryReadAddress atarijsa3_readmem[] =
712 {
713 	{ 0x0000, 0x1fff, MRA_RAM },
714 	{ 0x2000, 0x2001, YM2151_status_port_0_r },
715 	{ 0x2800, 0x2bff, jsa3_io_r },
716 	{ 0x3000, 0xffff, MRA_ROM },
717 	{ -1 }  /* end of table */
718 };
719 
720 
721 struct MemoryWriteAddress atarijsa3_writemem[] =
722 {
723 	{ 0x0000, 0x1fff, MWA_RAM },
724 	{ 0x2000, 0x2000, YM2151_register_port_0_w },
725 	{ 0x2001, 0x2001, YM2151_data_port_0_w },
726 	{ 0x2800, 0x2bff, jsa3_io_w },
727 	{ 0x3000, 0xffff, MWA_ROM },
728 	{ -1 }  /* end of table */
729 };
730 
731 
732 struct MemoryReadAddress atarijsa3s_readmem[] =
733 {
734 	{ 0x0000, 0x1fff, MRA_RAM },
735 	{ 0x2000, 0x2001, YM2151_status_port_0_r },
736 	{ 0x2800, 0x2bff, jsa3s_io_r },
737 	{ 0x3000, 0xffff, MRA_ROM },
738 	{ -1 }  /* end of table */
739 };
740 
741 
742 struct MemoryWriteAddress atarijsa3s_writemem[] =
743 {
744 	{ 0x0000, 0x1fff, MWA_RAM },
745 	{ 0x2000, 0x2000, YM2151_register_port_0_w },
746 	{ 0x2001, 0x2001, YM2151_data_port_0_w },
747 	{ 0x2800, 0x2bff, jsa3s_io_w },
748 	{ 0x3000, 0xffff, MWA_ROM },
749 	{ -1 }  /* end of table */
750 };
751 
752 
753 
754 /*************************************
755  *
756  *	Sound definitions
757  *
758  *************************************/
759 
760 struct TMS5220interface atarijsa_tms5220_interface =
761 {
762 	ATARI_CLOCK_14MHz/2/11,	/* potentially ATARI_CLOCK_14MHz/2/9 as well */
763 	100,
764 	0
765 };
766 
767 
768 struct POKEYinterface atarijsa_pokey_interface =
769 {
770 	1,			/* 1 chip */
771 	ATARI_CLOCK_14MHz/8,
772 	{ 40 },
773 };
774 
775 
776 struct YM2151interface atarijsa_ym2151_interface_mono =
777 {
778 	1,			/* 1 chip */
779 	ATARI_CLOCK_14MHz/4,
780 	{ YM3012_VOL(30,MIXER_PAN_CENTER,30,MIXER_PAN_CENTER) },
781 	{ atarigen_ym2151_irq_gen }
782 };
783 
784 
785 struct YM2151interface atarijsa_ym2151_interface_stereo =
786 {
787 	1,			/* 1 chip */
788 	ATARI_CLOCK_14MHz/4,
789 	{ YM3012_VOL(60,MIXER_PAN_LEFT,60,MIXER_PAN_RIGHT) },
790 	{ atarigen_ym2151_irq_gen }
791 };
792 
793 
794 struct YM2151interface atarijsa_ym2151_interface_stereo_swapped =
795 {
796 	1,			/* 1 chip */
797 	ATARI_CLOCK_14MHz/4,
798 	{ YM3012_VOL(60,MIXER_PAN_RIGHT,60,MIXER_PAN_LEFT) },
799 	{ atarigen_ym2151_irq_gen }
800 };
801 
802 
803 struct OKIM6295interface atarijsa_okim6295_interface_REGION_SOUND1 =
804 {
805 	1,              /* 1 chip */
806 	{ ATARI_CLOCK_14MHz/4/3/132 },
807 	{ REGION_SOUND1 },
808 	{ 75 }
809 };
810 
811 
812 struct OKIM6295interface atarijsa_okim6295s_interface_REGION_SOUND1 =
813 {
814 	2, 				/* 2 chips */
815 	{ ATARI_CLOCK_14MHz/4/3/132, ATARI_CLOCK_14MHz/4/3/132 },
816 	{ REGION_SOUND1, REGION_SOUND1 },
817 	{ MIXER(75,MIXER_PAN_LEFT), MIXER(75,MIXER_PAN_RIGHT) }
818 };
819