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