1 #include "burnint.h"
2 #include "m6502_intf.h"
3 #include "burn_ym2151.h"
4 #include "msm6295.h"
5 #include "pokey.h"
6 #include "tms5220.h"
7 
8 static INT32 atarijsa_bank;
9 static INT32 speech_data;
10 static INT32 last_ctl;
11 static INT32 oki_banks[2];
12 static INT32 timed_int;
13 static INT32 ym2151_int;
14 static INT32 ym2151_ct1;
15 
16 static double pokey_volume;
17 static double ym2151_volume;
18 //static double tms5220_volume;
19 static double oki6295_volume;
20 
21 INT32 atarigen_cpu_to_sound;
22 INT32 atarigen_sound_to_cpu;
23 INT32 atarigen_cpu_to_sound_ready;
24 INT32 atarigen_sound_to_cpu_ready;
25 
26 UINT8 atarijsa_input_port;
27 UINT8 atarijsa_test_port;
28 UINT8 atarijsa_test_mask;
29 
30 static INT32 atarijsa_sound_timer;
31 INT32 atarijsa_int_state;
32 
33 static INT32 has_pokey = 0;
34 static INT32 has_tms5220 = 0;
35 static UINT8 *samples[2] = { NULL, NULL };
36 static UINT8 *atarijsa_rom;
37 static UINT8 *atarijsa_ram;
38 static void (*update_int_callback)();
39 
update_6502_irq()40 static void update_6502_irq()
41 {
42 	M6502SetIRQLine(0, (timed_int || ym2151_int) ? CPU_IRQSTATUS_ACK : CPU_IRQSTATUS_NONE);
43 }
44 
bankswitch(INT32 data)45 static void bankswitch(INT32 data)
46 {
47 	atarijsa_bank = data & 3;
48 	M6502MapMemory(atarijsa_rom + (data & 3) * 0x1000, 0x3000, 0x3fff, MAP_ROM);
49 }
50 
oki_bankswitch(INT32 chip,INT32 data)51 static void oki_bankswitch(INT32 chip, INT32 data)
52 {
53 	oki_banks[chip] = data;
54 
55 	data = data & 3;
56 	if (data) data -= 1; // bank #1 is the same as bank #0
57 
58 	MSM6295SetBank(chip, samples[chip] + data * 0x20000, 0x00000, 0x1ffff);
59 }
60 
update_all_volumes()61 static void update_all_volumes()
62 {
63 	if (has_tms5220) {
64 //		m_tms5220->set_output_gain(ALL_OUTPUTS, tms5220_volume * ym2151_ct1);	// NOT SUPPORTED!!
65 	}
66 	if (has_pokey) {
67 //		PokeySetRoute(0, pokey_volume * ym2151_ct1, BURN_SND_ROUTE_BOTH);
68 	}
69 
70 //	BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, ym2151_volume, BURN_SND_ROUTE_LEFT);
71 //	BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, ym2151_volume, BURN_SND_ROUTE_RIGHT);
72 }
73 
atarijsa_write(UINT16 address,UINT8 data)74 static void atarijsa_write(UINT16 address, UINT8 data)
75 {
76 	if ((address & 0xfc00) == 0x2c00) { // jsai only!
77 		if (has_pokey) pokey_write(0, address & 0xf, data);
78 		return;
79 	}
80 
81 //	if (samples[0] == NULL) {
82 //		if ((address & 0xfc00) == 0x2800) address &= ~0x1f9;
83 //	} else {
84 //		if ((address & 0xf800) == 0x2000) address &= ~0x7fe;
85 //		if ((address & 0xfc00) == 0x2800) address &= ~0x5f8;
86 //	}
87 
88 //	bprintf (0, _T("JSA W: %4.4x, %2.2x\n"), address, data);
89 
90 	switch (address)
91 	{
92 		case 0x2000:
93 			BurnYM2151SelectRegister(data);
94 		return;
95 
96 		case 0x2001:
97 			BurnYM2151WriteRegister(data);
98 		return;
99 
100 		case 0x2800:
101 		case 0x2900:
102 			// :overall_volume_w (jsaiii) (volumes)
103 		return;
104 
105 		case 0x2806:
106 		case 0x2807:
107 			timed_int = 0;
108 			update_6502_irq();
109 		return;
110 
111 		case 0x2a00:
112             speech_data = data;
113             tms5220_write(data);
114 			if (samples[0]) MSM6295Write(0, data); // jsaii, jsaiii
115 		return;
116 
117 		case 0x2a01:
118 			if (samples[1]) MSM6295Write(1, data); // jsaiii
119 		return;
120 
121 		case 0x2a02:
122 		case 0x2a03:
123 		{
124 			atarigen_sound_to_cpu = data;
125 			atarigen_sound_to_cpu_ready = 1;
126 			atarijsa_int_state = 1;
127 			(*update_int_callback)();
128 		}
129 		return;
130 
131 		case 0x2a04:
132 		case 0x2a05:
133 		{
134             if (~data & 0x01) BurnYM2151Reset();
135 
136 			if (has_tms5220)
137 			{
138                 tms5220_wsq_w((data >> 1) & 1);
139                 tms5220_rsq_w((data >> 2) & 1);
140 
141                 INT32 count = 5 | ((data >> 2) & 2);
142                 tms5220_set_frequency((3579545*2) / (16 - count));
143 			}
144 
145 			// coin counter = data & 0x30
146 
147 			if (~data & 0x04) {
148 				INT32 pin = (data & 8) ? MSM6295_PIN7_HIGH : MSM6295_PIN7_LOW;
149 				if (samples[0]) MSM6295SetSamplerate(0, (3579545/3) / pin);
150 				if (samples[1]) MSM6295SetSamplerate(1, (3579545/3) / pin);
151 				if (samples[0]) MSM6295Reset(0);
152 				if (samples[1]) MSM6295Reset(1);
153 			}
154 
155 			oki_banks[0] = (oki_banks[0] & 2) | ((data >> 1) & 1);
156 			if (samples[0]) oki_bankswitch(0, oki_banks[0]);
157 
158             bankswitch(data >> 6);
159             last_ctl = data;
160         }
161 		return;
162 
163 		case 0x2a06:
164 		case 0x2a07:
165 		{
166 			oki_banks[1] = data >> 6;
167 			if (samples[1]) oki_bankswitch(1, oki_banks[1]);
168 
169 			oki_banks[0] = (oki_banks[0] & 1) | ((data >> 3) & 2);
170 			if (samples[0]) oki_bankswitch(0, oki_banks[0]);
171 
172 			ym2151_volume = ((data >> 1) & 7) / 7.0;
173 			oki6295_volume = (data & 1) ? 1.0 : 0.5;
174 			update_all_volumes();
175 		}
176 		return;
177 	}
178 
179 	bprintf (0, _T("MISS JSA W: %4.4x, %2.2x\n"), address, data);
180 }
181 
atarijsa_read(UINT16 address)182 static UINT8 atarijsa_read(UINT16 address)
183 {
184 	if ((address & 0xfc00) == 0x2c00) { // jsai only!
185 		return has_pokey ? pokey_read(0, address & 0xf) : 0xff;
186 	}
187 
188 //	bprintf (0, _T("JSA R: %4.4x\n"), address);
189 
190 //	if (if (samples[0] == NULL) { // iq_132
191 //		if ((address & 0xfc00) == 0x2800) address &= ~0x1f9;
192 //	} else {
193 //		if ((address & 0xf800) == 0x2000) address &= ~0x7fe;
194 //		if ((address & 0xfc00) == 0x2800) address &= ~0x5f8;
195 //	}
196 
197 	switch (address)
198 	{
199 		case 0x2000:
200 			return 0xff;
201 
202 		case 0x2001:
203 			return BurnYM2151Read();
204 
205 		case 0x2800: // jsaii && iii
206 		case 0x2808:
207 			return (samples[0]) ? MSM6295Read(0) : 0xff;
208 
209 		case 0x2801: // jsa iii
210 			return (samples[1]) ? MSM6295Read(1) : 0xff;
211 
212 		case 0x2802:
213 		case 0x280a:
214 		{
215 			if (atarigen_sound_to_cpu_ready)
216 				bprintf (0, _T("Missed result from 6502\n"));
217 
218 			atarigen_cpu_to_sound_ready = 0;
219 			M6502SetIRQLine(0x20, CPU_IRQSTATUS_NONE);
220 			return atarigen_cpu_to_sound;
221 		}
222 
223 		case 0x2804:
224 		case 0x280c:
225 		{
226             UINT8 result = (atarijsa_input_port) | 0x10;
227             if (!(atarijsa_test_port & atarijsa_test_mask)) result ^= 0x80;
228 			if (atarigen_cpu_to_sound_ready) result ^= 0x40;
229 			if (atarigen_sound_to_cpu_ready) result ^= 0x20;
230             if (has_tms5220 && tms5220_ready() == 0) result ^= 0x10;
231             return result;
232 		}
233 
234 		case 0x2806:
235 		case 0x280e:
236 			timed_int = 0;
237 			update_6502_irq();
238 			return 0xff;
239 	}
240 
241 	bprintf (0, _T("MISS JSA R: %4.4x\n"), address);
242 
243 	return 0xff;
244 }
245 
JsaYM2151IrqHandler(INT32 nStatus)246 static void JsaYM2151IrqHandler(INT32 nStatus)
247 {
248 	ym2151_int = nStatus;
249 	update_6502_irq();
250 }
251 
JsaYM2151Write(UINT32,UINT32 data)252 static void JsaYM2151Write(UINT32 , UINT32 data)
253 {
254 	ym2151_ct1 = (data >> 0) & 1;
255 	update_all_volumes();
256 }
257 
AtariJSAReset()258 void AtariJSAReset()
259 {
260 	M6502Open(0);
261 	bankswitch(0);
262 	M6502Reset();
263 	M6502Close();
264 
265 	if (samples[0]) {
266 		oki_bankswitch(0, 0);
267 		MSM6295Reset(0);
268 	}
269 
270 	if (samples[1]) {
271 		oki_bankswitch(1, 0);
272 		MSM6295Reset(1);
273 	}
274 
275 	BurnYM2151Reset();
276 
277 	if (has_pokey) PokeyReset();
278 	if (has_tms5220) tms5220_reset();
279 
280 	speech_data = 0;
281 	last_ctl = 0;
282 	timed_int = 0;
283 	ym2151_int = 0;
284 	ym2151_ct1 = 0;
285 
286 	atarijsa_sound_timer = 0;
287 
288 	pokey_volume = 1.0;
289 	ym2151_volume = 1.0;
290 	//tms5220_volume = 1.0;
291 
292 	atarigen_cpu_to_sound = 0;
293 	atarigen_cpu_to_sound_ready = 0;
294 	atarigen_sound_to_cpu = 0;
295 	atarigen_sound_to_cpu_ready = 0;
296 
297 	atarijsa_int_state = 0;
298 }
299 
AtariJSAInit(UINT8 * rom,void (* int_cb)(),UINT8 * samples0,UINT8 * samples1)300 void AtariJSAInit(UINT8 *rom, void (*int_cb)(), UINT8 *samples0, UINT8 *samples1)
301 {
302 	atarijsa_rom = rom;
303 	atarijsa_ram = (UINT8*)BurnMalloc(0x2000);
304 
305 	update_int_callback = int_cb;
306 
307 	samples[0] = samples0;
308 	samples[1] = samples1;
309 
310 	has_tms5220 = (samples0 == NULL) && (samples1 == NULL);
311 	has_pokey = has_tms5220;
312 
313 	M6502Init(0, TYPE_M6502);
314 	M6502Open(0);
315 	M6502MapMemory(atarijsa_ram,			0x0000, 0x1fff, MAP_RAM);
316 	M6502MapMemory(atarijsa_rom + 0x4000,	0x4000, 0xffff, MAP_ROM);
317 	M6502SetWriteHandler(atarijsa_write);
318 	M6502SetReadHandler(atarijsa_read);
319 	M6502Close();
320 
321 	BurnYM2151Init(3579545);
322 	BurnYM2151SetIrqHandler(&JsaYM2151IrqHandler);
323 	YM2151SetPortWriteHandler(0, &JsaYM2151Write);
324 	BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_1, 0.60, BURN_SND_ROUTE_LEFT);
325 	BurnYM2151SetRoute(BURN_SND_YM2151_YM2151_ROUTE_2, 0.60, BURN_SND_ROUTE_RIGHT);
326 
327 	MSM6295Init(0, (3579545/3) / MSM6295_PIN7_HIGH, 1);
328 	MSM6295Init(1, (3579545/3) / MSM6295_PIN7_HIGH, 1);
329 	MSM6295SetRoute(0, 0.75, BURN_SND_ROUTE_BOTH);
330 	MSM6295SetRoute(1, 0.75, BURN_SND_ROUTE_BOTH);
331 	if (samples[0]) {
332 		MSM6295SetBank(0, samples[0] + 0x00000, 0x00000, 0x1ffff);
333 		MSM6295SetBank(0, samples[0] + 0x60000, 0x20000, 0x3ffff);
334 	}
335 
336 	if (samples[1]) {
337 		MSM6295SetBank(1, samples[1] + 0x00000, 0x00000, 0x1ffff);
338 		MSM6295SetBank(1, samples[1] + 0x60000, 0x20000, 0x3ffff);
339 	}
340 
341 	PokeyInit(3579545/2, 1, 0.40, 1);
342 	PokeySetTotalCyclesCB(M6502TotalCycles);
343 
344 	tms5220c_init(M6502TotalCycles, 1789773);
345     tms5220_set_frequency((3579545*2)/11);
346     tms5220_volume(1.50);
347 }
348 
AtariJSAExit()349 void AtariJSAExit()
350 {
351 	BurnYM2151Exit();
352 	MSM6295Exit(0);
353 	MSM6295Exit(1);
354 	tms5220_exit();
355 	PokeyExit();
356 	M6502Exit();
357 
358 	BurnFree (atarijsa_ram);
359 
360 	has_tms5220 = 0;
361 	MSM6295ROM = NULL;
362 }
363 
AtariJSAScan(INT32 nAction,INT32 * pnMin)364 void AtariJSAScan(INT32 nAction, INT32 *pnMin)
365 {
366 	struct BurnArea ba;
367 
368 	if (pnMin) {
369 		*pnMin = 0x029722;
370 	}
371 
372 	if (nAction & ACB_VOLATILE) {
373 		memset(&ba, 0, sizeof(ba));
374 		ba.Data	  = atarijsa_ram;
375 		ba.nLen	  = 0x2000;
376 		ba.szName = "JSA Ram";
377 		BurnAcb(&ba);
378 
379 		M6502Scan(nAction);
380 
381 		BurnYM2151Scan(nAction, pnMin);
382 		MSM6295Scan(nAction, pnMin);
383 		pokey_scan(nAction, pnMin);
384 		tms5220_scan(nAction, pnMin);
385 
386 		SCAN_VAR(atarijsa_bank);
387 		SCAN_VAR(speech_data);
388 		SCAN_VAR(last_ctl);
389 		SCAN_VAR(oki_banks);
390 		SCAN_VAR(atarigen_cpu_to_sound);
391 		SCAN_VAR(atarigen_cpu_to_sound_ready);
392 		SCAN_VAR(atarigen_sound_to_cpu);
393 		SCAN_VAR(atarigen_sound_to_cpu_ready);
394 		SCAN_VAR(atarijsa_int_state);
395 	}
396 	if (nAction & ACB_WRITE)
397 	{
398 		M6502Open(0);
399 		bankswitch(atarijsa_bank);
400 		M6502Close();
401 	}
402 }
403 
404 // use AtariJSAInterruptUpdate unless we're not at ~60hz
AtariJSAInterrupt()405 void AtariJSAInterrupt() // TIME_IN_HZ((double)ATARI_CLOCK_3MHz/4/16/16/14) call 4x per frame (if 60hz)
406 {
407 	timed_int = 1;
408 	update_6502_irq();
409 }
410 
AtariJSAInterruptUpdate(INT32 interleave)411 void AtariJSAInterruptUpdate(INT32 interleave)
412 {
413 	INT32 modr = (((interleave * 1000) / 416) + 5) / 10; // should happen 4.16x per frame
414 	if (modr == 0) modr = 63;
415 
416 	if ((atarijsa_sound_timer % modr) == (modr-1))
417     {
418 		timed_int = 1;
419 		update_6502_irq();
420 	}
421 
422 	atarijsa_sound_timer++;
423 }
424 
AtariJSAUpdate(INT16 * output,INT32 length)425 void AtariJSAUpdate(INT16 *output, INT32 length)
426 {
427 	BurnYM2151Render(output, length);
428 	if (samples[0] || samples[1]) MSM6295Render(output, length);
429 	if (has_pokey) pokey_update(output, length);
430 
431 	if ((output + (length*2)) == (pBurnSoundOut + (nBurnSoundLen*2))) {
432         if (has_tms5220) tms5220_update(pBurnSoundOut, nBurnSoundLen);
433 	}
434 }
435 
436 //#include "m68000_intf.h" // debug
437 
AtariJSARead()438 UINT16 AtariJSARead()
439 {
440 //	bprintf (0, _T("JSA MAIN READ %4.4x\n"), atarigen_sound_to_cpu | 0xff00);
441 
442 	atarigen_sound_to_cpu_ready = 0;
443 	atarijsa_int_state = 0;
444 	(*update_int_callback)();
445 	return atarigen_sound_to_cpu | 0xff00;
446 }
447 
AtariJSAWrite(UINT8 data)448 void AtariJSAWrite(UINT8 data)
449 {
450 	if (atarigen_cpu_to_sound_ready)
451 		bprintf (0, _T("Missed command from 68010\n"));
452 
453 //	bprintf (0, _T("JSA MAIN WRITE %2.2x\n"), data);
454 	atarigen_cpu_to_sound = data;
455 	atarigen_cpu_to_sound_ready = 1;
456 	M6502SetIRQLine(0x20, CPU_IRQSTATUS_ACK);
457 }
458 
AtariJSAResetWrite(UINT8 data)459 void AtariJSAResetWrite(UINT8 data)
460 {
461 	if (data == 0) {
462 		M6502Reset();
463 	}
464 
465 //	bprintf (0, _T("JSA MAIN RESET %2.2x\n"), data);
466 	atarigen_sound_to_cpu_ready = 0;
467 	atarijsa_int_state = 0;
468 	(*update_int_callback)();
469 }
470