1 /***************************************************************************
2
3 Cinemat/Leland driver
4
5 Leland sound hardware
6 driver by Aaron Giles and Paul Leaman
7
8 -------------------------------------------------------------------
9
10 1st generation sound hardware was controlled by the master Z80.
11 It drove an AY-8910/AY-8912 pair for music. It also had two DACs
12 that were driven by the video refresh. At the end of each scanline
13 there are 8-bit DAC samples that can be enabled via the output
14 ports on the AY-8910. The DACs run at a fixed frequency of 15.3kHz,
15 since they are clocked once each scanline.
16
17 -------------------------------------------------------------------
18
19 2nd generation sound hardware was used in Redline Racer. It
20 consisted of an 80186 microcontroller driving 8 8-bit DACs. The
21 frequency of the DACs were controlled by one of 3 Intel 8254
22 programmable interval timers (PITs):
23
24 DAC number Clock source
25 ---------- -----------------
26 0 8254 PIT 1 output 0
27 1 8254 PIT 1 output 1
28 2 8254 PIT 1 output 2
29 3 8254 PIT 2 output 0
30 4 8254 PIT 2 output 1
31 5-7 8254 PIT 3 output 0
32
33 The clock outputs for each DAC can be read, and are polled to
34 determine when data should be updated on the chips. The 80186's
35 two DMA channels are generally used to drive the first two DACs,
36 with the remaining 6 DACs being fed manually via polling.
37
38 -------------------------------------------------------------------
39
40 3rd generation sound hardware appeared in the football games
41 (Quarterback, AAFB) and the later games up through Pigout. This
42 variant is closely based on the Redline Racer sound system, but
43 they took out two of the DACs and replaced them with a higher
44 resolution (10-bit) DAC. The driving clocks have been rearranged
45 a bit, and the number of PITs reduced from 3 to 2:
46
47 DAC number Clock source
48 ---------- -----------------
49 0 8254 PIT 1 output 0
50 1 8254 PIT 1 output 1
51 2 8254 PIT 1 output 2
52 3 8254 PIT 2 output 0
53 4 8254 PIT 2 output 1
54 5 8254 PIT 2 output 2
55 10-bit 80186 timer 0
56
57 Like the 2nd generation board, the first two DACs are driven via
58 the DMA channels, and the remaining 5 DACs are polled.
59
60 -------------------------------------------------------------------
61
62 4th generation sound hardware showed up in Ataxx, Indy Heat, and
63 World Soccer Finals. For this variant, they removed one more PIT
64 and 3 of the 8-bit DACs, and added a YM2151 music chip and an
65 externally-fed 8-bit DAC.
66
67 DAC number Clock source
68 ---------- -----------------
69 0 8254 PIT 1 output 0
70 1 8254 PIT 1 output 1
71 2 8254 PIT 1 output 2
72 10-bit 80186 timer 0
73 ext 80186 timer 1
74
75 The externally driven DACs have registers for a start/stop address
76 and triggers to control the clocking.
77
78 ***************************************************************************/
79
80 #include "driver.h"
81 #include "cpu/i86/i186intf.h"
82 #include "cpu/z80/z80.h"
83 #include "leland.h"
84
85
86 /*************************************
87 *
88 * 1st generation sound
89 *
90 *************************************/
91
92 #define DAC_BUFFER_SIZE 1024
93 #define DAC_BUFFER_MASK (DAC_BUFFER_SIZE - 1)
94
95 static UINT8 *dac_buffer[2];
96 static UINT32 dac_bufin[2];
97 static UINT32 dac_bufout[2];
98
99 static int dac_stream;
100
leland_update(int param,INT16 * buffer,int length)101 static void leland_update(int param, INT16 *buffer, int length)
102 {
103 int dacnum;
104
105 /* reset the buffer */
106 memset(buffer, 0, length * sizeof(INT16));
107 for (dacnum = 0; dacnum < 2; dacnum++)
108 {
109 int bufout = dac_bufout[dacnum];
110 int count = (dac_bufin[dacnum] - bufout) & DAC_BUFFER_MASK;
111
112 if (count > 300)
113 {
114 UINT8 *base = dac_buffer[dacnum];
115 int i;
116
117 for (i = 0; i < length && count > 0; i++, count--)
118 {
119 buffer[i] += ((INT16)base[bufout] - 0x80) * 0x40;
120 bufout = (bufout + 1) & DAC_BUFFER_MASK;
121 }
122 dac_bufout[dacnum] = bufout;
123 }
124 }
125 }
126
127
leland_sh_start(const struct MachineSound * msound)128 int leland_sh_start(const struct MachineSound *msound)
129 {
130 /* reset globals */
131 dac_buffer[0] = dac_buffer[1] = NULL;
132 dac_bufin[0] = dac_bufin[1] = 0;
133 dac_bufout[0] = dac_bufout[1] = 0;
134
135 /* skip if no sound */
136 if (Machine->sample_rate == 0)
137 return 0;
138
139 /* allocate the stream */
140 dac_stream = stream_init("Onboard DACs", 50, 256*60, 0, leland_update);
141
142 /* allocate memory */
143 dac_buffer[0] = auto_malloc(DAC_BUFFER_SIZE);
144 dac_buffer[1] = auto_malloc(DAC_BUFFER_SIZE);
145 if (!dac_buffer[0] || !dac_buffer[1])
146 return 1;
147
148 return 0;
149 }
150
151
leland_sh_stop(void)152 void leland_sh_stop(void)
153 {
154 }
155
156
leland_dac_update(int dacnum,UINT8 sample)157 void leland_dac_update(int dacnum, UINT8 sample)
158 {
159 UINT8 *buffer = dac_buffer[dacnum];
160 int bufin = dac_bufin[dacnum];
161
162 /* skip if nothing */
163 if (!buffer)
164 return;
165
166 /* copy data from VRAM */
167 buffer[bufin] = sample;
168 bufin = (bufin + 1) & DAC_BUFFER_MASK;
169
170 /* update the buffer */
171 dac_bufin[dacnum] = bufin;
172 }
173
174
175
176 /*************************************
177 *
178 * 2nd-4th generation sound
179 *
180 *************************************/
181
182 #define LOG_INTERRUPTS 0
183 #define LOG_DMA 0
184 #define LOG_SHORTAGES 0
185 #define LOG_TIMER 0
186 #define LOG_COMM 0
187 #define LOG_PORTS 0
188 #define LOG_DAC 0
189 #define LOG_EXTERN 0
190 #define LOG_PIT 0
191 #define LOG_OPTIMIZATION 0
192
193
194 /* according to the Intel manual, external interrupts are not latched */
195 /* however, I cannot get this system to work without latching them */
196 #define LATCH_INTS 1
197
198 #define DAC_VOLUME_SCALE 4
199 #define CPU_RESUME_TRIGGER 7123
200
201
202 static int dma_stream;
203 static int nondma_stream;
204 static int extern_stream;
205
206 static UINT8 *ram_base;
207 static UINT8 has_ym2151;
208 static UINT8 is_redline;
209
210 static UINT8 last_control;
211 static UINT8 clock_active;
212 static UINT8 clock_tick;
213
214 static UINT8 sound_command[2];
215 static UINT8 sound_response;
216
217 static UINT32 ext_start;
218 static UINT32 ext_stop;
219 static UINT8 ext_active;
220 static UINT8 *ext_base;
221
222 static UINT8 *active_mask;
223 static int total_reads;
224
225 struct mem_state
226 {
227 UINT16 lower;
228 UINT16 upper;
229 UINT16 middle;
230 UINT16 middle_size;
231 UINT16 peripheral;
232 };
233
234 struct timer_state
235 {
236 UINT16 control;
237 UINT16 maxA;
238 UINT16 maxB;
239 UINT16 count;
240 void * int_timer;
241 void * time_timer;
242 UINT8 time_timer_active;
243 double last_time;
244 };
245
246 struct dma_state
247 {
248 UINT32 source;
249 UINT32 dest;
250 UINT16 count;
251 UINT16 control;
252 UINT8 finished;
253 void * finish_timer;
254 };
255
256 struct intr_state
257 {
258 UINT8 pending;
259 UINT16 ack_mask;
260 UINT16 priority_mask;
261 UINT16 in_service;
262 UINT16 request;
263 UINT16 status;
264 UINT16 poll_status;
265 UINT16 timer;
266 UINT16 dma[2];
267 UINT16 ext[4];
268 };
269
270 static struct i186_state
271 {
272 struct timer_state timer[3];
273 struct dma_state dma[2];
274 struct intr_state intr;
275 struct mem_state mem;
276 } i186;
277
278
279 #define DAC_BUFFER_SIZE 1024
280 #define DAC_BUFFER_SIZE_MASK (DAC_BUFFER_SIZE - 1)
281 static struct dac_state
282 {
283 INT16 value;
284 INT16 volume;
285 UINT32 frequency;
286 UINT32 step;
287 UINT32 fraction;
288
289 INT16 buffer[DAC_BUFFER_SIZE];
290 UINT32 bufin;
291 UINT32 bufout;
292 UINT32 buftarget;
293 } dac[8];
294
295 static struct counter_state
296 {
297 void *timer;
298 INT32 count;
299 UINT8 mode;
300 UINT8 readbyte;
301 UINT8 writebyte;
302 } counter[9];
303
304 static void set_dac_frequency(int which, int frequency);
305
306 static READ_HANDLER( peripheral_r );
307 static WRITE_HANDLER( peripheral_w );
308
309
310
311 /*************************************
312 *
313 * Manual DAC sound generation
314 *
315 *************************************/
316
leland_i186_dac_update(int param,INT16 * buffer,int length)317 static void leland_i186_dac_update(int param, INT16 *buffer, int length)
318 {
319 int i, j, start, stop;
320
321 if (LOG_SHORTAGES) logerror("----\n");
322
323 /* reset the buffer */
324 memset(buffer, 0, length * sizeof(INT16));
325
326 /* if we're redline racer, we have more DACs */
327 if (!is_redline)
328 start = 2, stop = 7;
329 else
330 start = 0, stop = 8;
331
332 /* loop over manual DAC channels */
333 for (i = start; i < stop; i++)
334 {
335 struct dac_state *d = &dac[i];
336 int count = (d->bufin - d->bufout) & DAC_BUFFER_SIZE_MASK;
337
338 /* if we have data, process it */
339 if (count > 0)
340 {
341 INT16 *base = d->buffer;
342 int source = d->bufout;
343 int frac = d->fraction;
344 int step = d->step;
345
346 /* sample-rate convert to the output frequency */
347 for (j = 0; j < length && count > 0; j++)
348 {
349 buffer[j] += base[source];
350 frac += step;
351 source += frac >> 24;
352 count -= frac >> 24;
353 frac &= 0xffffff;
354 source &= DAC_BUFFER_SIZE_MASK;
355 }
356
357 if (LOG_SHORTAGES && j < length)
358 logerror("DAC #%d short by %d/%d samples\n", i, length - j, length);
359
360 /* update the DAC state */
361 d->fraction = frac;
362 d->bufout = source;
363 }
364
365 /* update the clock status */
366 if (count < d->buftarget)
367 {
368 if (LOG_OPTIMIZATION) logerror(" - trigger due to clock active in update\n");
369 cpu_trigger(CPU_RESUME_TRIGGER);
370 clock_active |= 1 << i;
371 }
372 }
373 }
374
375
376
377 /*************************************
378 *
379 * DMA-based DAC sound generation
380 *
381 *************************************/
382
leland_i186_dma_update(int param,INT16 * buffer,int length)383 static void leland_i186_dma_update(int param, INT16 *buffer, int length)
384 {
385 int i, j;
386
387 /* reset the buffer */
388 memset(buffer, 0, length * sizeof(INT16));
389
390 /* loop over DMA buffers */
391 for (i = 0; i < 2; i++)
392 {
393 struct dma_state *d = &i186.dma[i];
394
395 /* check for enabled DMA */
396 if (d->control & 0x0002)
397 {
398 /* make sure the parameters meet our expectations */
399 if ((d->control & 0xfe00) != 0x1600)
400 {
401 logerror("Unexpected DMA control %02X\n", d->control);
402 }
403 else if (!is_redline && ((d->dest & 1) || (d->dest & 0x3f) > 0x0b))
404 {
405 logerror("Unexpected DMA destination %02X\n", d->dest);
406 }
407 else if (is_redline && (d->dest & 0xf000) != 0x4000 && (d->dest & 0xf000) != 0x5000)
408 {
409 logerror("Unexpected DMA destination %02X\n", d->dest);
410 }
411
412 /* otherwise, we're ready for liftoff */
413 else
414 {
415 UINT8 *base = memory_region(REGION_CPU3);
416 int source = d->source;
417 int count = d->count;
418 int which, frac, step, volume;
419
420 /* adjust for redline racer */
421 if (!is_redline)
422 which = (d->dest & 0x3f) / 2;
423 else
424 which = (d->dest >> 9) & 7;
425
426 frac = dac[which].fraction;
427 step = dac[which].step;
428 volume = dac[which].volume;
429
430 /* sample-rate convert to the output frequency */
431 for (j = 0; j < length && count > 0; j++)
432 {
433 buffer[j] += ((int)base[source] - 0x80) * volume;
434 frac += step;
435 source += frac >> 24;
436 count -= frac >> 24;
437 frac &= 0xffffff;
438 }
439
440 /* update the DMA state */
441 if (count > 0)
442 {
443 d->source = source;
444 d->count = count;
445 }
446 else
447 {
448 /* let the timer callback actually mark the transfer finished */
449 d->source = source + count - 1;
450 d->count = 1;
451 d->finished = 1;
452 }
453
454 if (LOG_DMA) logerror("DMA Generated %d samples - new count = %04X, source = %04X\n", j, d->count, d->source);
455
456 /* update the DAC state */
457 dac[which].fraction = frac;
458 }
459 }
460 }
461 }
462
463
464
465 /*************************************
466 *
467 * Externally-driven DAC sound generation
468 *
469 *************************************/
470
leland_i186_extern_update(int param,INT16 * buffer,int length)471 static void leland_i186_extern_update(int param, INT16 *buffer, int length)
472 {
473 struct dac_state *d = &dac[7];
474 int count = ext_stop - ext_start;
475 int j;
476
477 /* reset the buffer */
478 memset(buffer, 0, length * sizeof(INT16));
479
480 /* if we have data, process it */
481 if (count > 0 && ext_active)
482 {
483 int source = ext_start;
484 int frac = d->fraction;
485 int step = d->step;
486
487 /* sample-rate convert to the output frequency */
488 for (j = 0; j < length && count > 0; j++)
489 {
490 buffer[j] += ((INT16)ext_base[source] - 0x80) * d->volume;
491 frac += step;
492 source += frac >> 24;
493 count -= frac >> 24;
494 frac &= 0xffffff;
495 }
496
497 /* update the DAC state */
498 d->fraction = frac;
499 ext_start = source;
500 }
501 }
502
503
504
505 /*************************************
506 *
507 * Sound initialization
508 *
509 *************************************/
510
511 static void internal_timer_int(int which);
512 static void dma_timer_callback(int which);
513
leland_i186_sh_start(const struct MachineSound * msound)514 int leland_i186_sh_start(const struct MachineSound *msound)
515 {
516 int i;
517
518 /* bail if nothing to play */
519 if (Machine->sample_rate == 0)
520 return 0;
521
522 /* determine which sound hardware is installed */
523 has_ym2151 = 0;
524 for (i = 0; i < MAX_SOUND; i++)
525 if (Machine->drv->sound[i].sound_type == SOUND_YM2151)
526 has_ym2151 = 1;
527
528 /* allocate separate streams for the DMA and non-DMA DACs */
529 dma_stream = stream_init("80186 DMA-driven DACs", 100, Machine->sample_rate, 0, leland_i186_dma_update);
530 nondma_stream = stream_init("80186 manually-driven DACs", 100, Machine->sample_rate, 0, leland_i186_dac_update);
531
532 /* if we have a 2151, install an externally driven DAC stream */
533 if (has_ym2151)
534 {
535 ext_base = memory_region(REGION_SOUND1);
536 extern_stream = stream_init("80186 externally-driven DACs", 100, Machine->sample_rate, 0, leland_i186_extern_update);
537 }
538
539 /* by default, we're not redline racer */
540 is_redline = 0;
541
542 /* create timers here so they stick around */
543 i186.timer[0].int_timer = timer_alloc(internal_timer_int);
544 i186.timer[1].int_timer = timer_alloc(internal_timer_int);
545 i186.timer[2].int_timer = timer_alloc(internal_timer_int);
546 i186.timer[0].time_timer = timer_alloc(NULL);
547 i186.timer[1].time_timer = timer_alloc(NULL);
548 i186.timer[2].time_timer = timer_alloc(NULL);
549 i186.dma[0].finish_timer = timer_alloc(dma_timer_callback);
550 i186.dma[1].finish_timer = timer_alloc(dma_timer_callback);
551
552 for (i = 0; i < 9; i++)
553 counter[i].timer = timer_alloc(NULL);
554
555 return 0;
556 }
557
558
redline_i186_sh_start(const struct MachineSound * msound)559 int redline_i186_sh_start(const struct MachineSound *msound)
560 {
561 int result = leland_i186_sh_start(msound);
562 is_redline = 1;
563 return result;
564 }
565
566
leland_i186_reset(void)567 static void leland_i186_reset(void)
568 {
569 struct i186_state oldstate = i186;
570 void *counter_timer[9];
571 int i;
572
573 /* reset the i186 state, but save the timers */
574 memset(&i186, 0, sizeof(i186));
575 i186.timer[0].int_timer = oldstate.timer[0].int_timer;
576 i186.timer[1].int_timer = oldstate.timer[1].int_timer;
577 i186.timer[2].int_timer = oldstate.timer[2].int_timer;
578 i186.timer[0].time_timer = oldstate.timer[0].time_timer;
579 i186.timer[1].time_timer = oldstate.timer[1].time_timer;
580 i186.timer[2].time_timer = oldstate.timer[2].time_timer;
581 i186.dma[0].finish_timer = oldstate.dma[0].finish_timer;
582 i186.dma[1].finish_timer = oldstate.dma[1].finish_timer;
583
584 /* reset the interrupt state */
585 i186.intr.priority_mask = 0x0007;
586 i186.intr.timer = 0x000f;
587 i186.intr.dma[0] = 0x000f;
588 i186.intr.dma[1] = 0x000f;
589 i186.intr.ext[0] = 0x000f;
590 i186.intr.ext[1] = 0x000f;
591 i186.intr.ext[2] = 0x000f;
592 i186.intr.ext[3] = 0x000f;
593
594 /* reset the DAC and counter states as well */
595 memset(&dac, 0, sizeof(dac));
596 for (i = 0; i < 9; i++)
597 counter_timer[i] = counter[i].timer;
598 memset(&counter, 0, sizeof(counter));
599 for (i = 0; i < 9; i++)
600 counter[i].timer = counter_timer[i];
601
602 /* send a trigger in case we're suspended */
603 if (LOG_OPTIMIZATION) logerror(" - trigger due to reset\n");
604 cpu_trigger(CPU_RESUME_TRIGGER);
605 total_reads = 0;
606 }
607
608
leland_i186_sound_init(void)609 void leland_i186_sound_init(void)
610 {
611 /* RAM is multiply mapped in the first 128k of address space */
612 cpu_setbank(6, ram_base);
613 cpu_setbank(7, ram_base);
614
615 /* reset the I86 registers */
616 leland_i186_reset();
617
618 /* reset our internal stuff */
619 last_control = 0xf8;
620 clock_active = 0;
621
622 /* reset the external DAC */
623 ext_start = 0;
624 ext_stop = 0;
625 ext_active = 0;
626 }
627
628
629
630 /*************************************
631 *
632 * 80186 interrupt controller
633 *
634 *************************************/
635
int_callback(int line)636 static int int_callback(int line)
637 {
638 if (LOG_INTERRUPTS) logerror("(%f) **** Acknowledged interrupt vector %02X\n", timer_get_time(), i186.intr.poll_status & 0x1f);
639
640 /* clear the interrupt */
641 i86_set_irq_line(0, CLEAR_LINE);
642 i186.intr.pending = 0;
643
644 /* clear the request and set the in-service bit */
645 #if LATCH_INTS
646 i186.intr.request &= ~i186.intr.ack_mask;
647 #else
648 i186.intr.request &= ~(i186.intr.ack_mask & 0x0f);
649 #endif
650 i186.intr.in_service |= i186.intr.ack_mask;
651 if (i186.intr.ack_mask == 0x0001)
652 {
653 switch (i186.intr.poll_status & 0x1f)
654 {
655 case 0x08: i186.intr.status &= ~0x01; break;
656 case 0x12: i186.intr.status &= ~0x02; break;
657 case 0x13: i186.intr.status &= ~0x04; break;
658 }
659 }
660 i186.intr.ack_mask = 0;
661
662 /* a request no longer pending */
663 i186.intr.poll_status &= ~0x8000;
664
665 /* return the vector */
666 return i186.intr.poll_status & 0x1f;
667 }
668
669
update_interrupt_state(void)670 static void update_interrupt_state(void)
671 {
672 int i, j, new_vector = 0;
673
674 if (LOG_INTERRUPTS) logerror("update_interrupt_status: req=%02X stat=%02X serv=%02X\n", i186.intr.request, i186.intr.status, i186.intr.in_service);
675
676 /* loop over priorities */
677 for (i = 0; i <= i186.intr.priority_mask; i++)
678 {
679 /* note: by checking 4 bits, we also verify that the mask is off */
680 if ((i186.intr.timer & 15) == i)
681 {
682 /* if we're already servicing something at this level, don't generate anything new */
683 if (i186.intr.in_service & 0x01)
684 return;
685
686 /* if there's something pending, generate an interrupt */
687 if (i186.intr.status & 0x07)
688 {
689 if (i186.intr.status & 1)
690 new_vector = 0x08;
691 else if (i186.intr.status & 2)
692 new_vector = 0x12;
693 else if (i186.intr.status & 4)
694 new_vector = 0x13;
695 else
696 usrintf_showmessage("Invalid timer interrupt!");
697
698 /* set the clear mask and generate the int */
699 i186.intr.ack_mask = 0x0001;
700 goto generate_int;
701 }
702 }
703
704 /* check DMA interrupts */
705 for (j = 0; j < 2; j++)
706 if ((i186.intr.dma[j] & 15) == i)
707 {
708 /* if we're already servicing something at this level, don't generate anything new */
709 if (i186.intr.in_service & (0x04 << j))
710 return;
711
712 /* if there's something pending, generate an interrupt */
713 if (i186.intr.request & (0x04 << j))
714 {
715 new_vector = 0x0a + j;
716
717 /* set the clear mask and generate the int */
718 i186.intr.ack_mask = 0x0004 << j;
719 goto generate_int;
720 }
721 }
722
723 /* check external interrupts */
724 for (j = 0; j < 4; j++)
725 if ((i186.intr.ext[j] & 15) == i)
726 {
727 /* if we're already servicing something at this level, don't generate anything new */
728 if (i186.intr.in_service & (0x10 << j))
729 return;
730
731 /* if there's something pending, generate an interrupt */
732 if (i186.intr.request & (0x10 << j))
733 {
734 /* otherwise, generate an interrupt for this request */
735 new_vector = 0x0c + j;
736
737 /* set the clear mask and generate the int */
738 i186.intr.ack_mask = 0x0010 << j;
739 goto generate_int;
740 }
741 }
742 }
743 return;
744
745 generate_int:
746 /* generate the appropriate interrupt */
747 i186.intr.poll_status = 0x8000 | new_vector;
748 if (!i186.intr.pending)
749 cpu_set_irq_line(2, 0, ASSERT_LINE);
750 i186.intr.pending = 1;
751 cpu_trigger(CPU_RESUME_TRIGGER);
752 if (LOG_OPTIMIZATION) logerror(" - trigger due to interrupt pending\n");
753 if (LOG_INTERRUPTS) logerror("(%f) **** Requesting interrupt vector %02X\n", timer_get_time(), new_vector);
754 }
755
756
handle_eoi(int data)757 static void handle_eoi(int data)
758 {
759 int i, j;
760
761 /* specific case */
762 if (!(data & 0x8000))
763 {
764 /* turn off the appropriate in-service bit */
765 switch (data & 0x1f)
766 {
767 case 0x08: i186.intr.in_service &= ~0x01; break;
768 case 0x12: i186.intr.in_service &= ~0x01; break;
769 case 0x13: i186.intr.in_service &= ~0x01; break;
770 case 0x0a: i186.intr.in_service &= ~0x04; break;
771 case 0x0b: i186.intr.in_service &= ~0x08; break;
772 case 0x0c: i186.intr.in_service &= ~0x10; break;
773 case 0x0d: i186.intr.in_service &= ~0x20; break;
774 case 0x0e: i186.intr.in_service &= ~0x40; break;
775 case 0x0f: i186.intr.in_service &= ~0x80; break;
776 default: logerror("%05X:ERROR - 80186 EOI with unknown vector %02X\n", activecpu_get_pc(), data & 0x1f);
777 }
778 if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for vector %02X\n", timer_get_time(), data & 0x1f);
779 }
780
781 /* non-specific case */
782 else
783 {
784 /* loop over priorities */
785 for (i = 0; i <= 7; i++)
786 {
787 /* check for in-service timers */
788 if ((i186.intr.timer & 7) == i && (i186.intr.in_service & 0x01))
789 {
790 i186.intr.in_service &= ~0x01;
791 if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for timer\n", timer_get_time());
792 return;
793 }
794
795 /* check for in-service DMA interrupts */
796 for (j = 0; j < 2; j++)
797 if ((i186.intr.dma[j] & 7) == i && (i186.intr.in_service & (0x04 << j)))
798 {
799 i186.intr.in_service &= ~(0x04 << j);
800 if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for DMA%d\n", timer_get_time(), j);
801 return;
802 }
803
804 /* check external interrupts */
805 for (j = 0; j < 4; j++)
806 if ((i186.intr.ext[j] & 7) == i && (i186.intr.in_service & (0x10 << j)))
807 {
808 i186.intr.in_service &= ~(0x10 << j);
809 if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for INT%d\n", timer_get_time(), j);
810 return;
811 }
812 }
813 }
814 }
815
816
817
818 /*************************************
819 *
820 * 80186 internal timers
821 *
822 *************************************/
823
internal_timer_int(int which)824 static void internal_timer_int(int which)
825 {
826 struct timer_state *t = &i186.timer[which];
827
828 if (LOG_TIMER) logerror("Hit interrupt callback for timer %d\n", which);
829
830 /* set the max count bit */
831 t->control |= 0x0020;
832
833 /* request an interrupt */
834 if (t->control & 0x2000)
835 {
836 i186.intr.status |= 0x01 << which;
837 update_interrupt_state();
838 if (LOG_TIMER) logerror(" Generating timer interrupt\n");
839 }
840
841 /* if we're continuous, reset */
842 if (t->control & 0x0001)
843 {
844 int count = t->maxA ? t->maxA : 0x10000;
845 timer_adjust(t->int_timer, (double)count * TIME_IN_HZ(2000000), which, 0);
846 if (LOG_TIMER) logerror(" Repriming interrupt\n");
847 }
848 else
849 timer_adjust(t->int_timer, TIME_NEVER, which, 0);
850 }
851
852
internal_timer_sync(int which)853 static void internal_timer_sync(int which)
854 {
855 struct timer_state *t = &i186.timer[which];
856
857 /* if we have a timing timer running, adjust the count */
858 if (t->time_timer_active)
859 {
860 double current_time = timer_timeelapsed(t->time_timer);
861 int net_clocks = (int)((current_time - t->last_time) * 2000000.);
862 t->last_time = current_time;
863
864 /* set the max count bit if we passed the max */
865 if ((int)t->count + net_clocks >= t->maxA)
866 t->control |= 0x0020;
867
868 /* set the new count */
869 if (t->maxA != 0)
870 t->count = (t->count + net_clocks) % t->maxA;
871 else
872 t->count = t->count + net_clocks;
873 }
874 }
875
876
internal_timer_update(int which,int new_count,int new_maxA,int new_maxB,int new_control)877 static void internal_timer_update(int which, int new_count, int new_maxA, int new_maxB, int new_control)
878 {
879 struct timer_state *t = &i186.timer[which];
880 int update_int_timer = 0;
881
882 /* if we have a new count and we're on, update things */
883 if (new_count != -1)
884 {
885 if (t->control & 0x8000)
886 {
887 internal_timer_sync(which);
888 update_int_timer = 1;
889 }
890 t->count = new_count;
891 }
892
893 /* if we have a new max and we're on, update things */
894 if (new_maxA != -1 && new_maxA != t->maxA)
895 {
896 if (t->control & 0x8000)
897 {
898 internal_timer_sync(which);
899 update_int_timer = 1;
900 }
901 t->maxA = new_maxA;
902 if (new_maxA == 0) new_maxA = 0x10000;
903
904 /* redline racer controls nothing externally? */
905 if (is_redline)
906 ;
907
908 /* on the common board, timer 0 controls the 10-bit DAC frequency */
909 else if (which == 0)
910 set_dac_frequency(6, 2000000 / new_maxA);
911
912 /* timer 1 controls the externally driven DAC on Indy Heat/WSF */
913 else if (which == 1 && has_ym2151)
914 set_dac_frequency(7, 2000000 / (new_maxA * 2));
915 }
916
917 /* if we have a new max and we're on, update things */
918 if (new_maxB != -1 && new_maxB != t->maxB)
919 {
920 if (t->control & 0x8000)
921 {
922 internal_timer_sync(which);
923 update_int_timer = 1;
924 }
925 t->maxB = new_maxB;
926 if (new_maxB == 0) new_maxB = 0x10000;
927
928 /* timer 1 controls the externally driven DAC on Indy Heat/WSF */
929 /* they alternate the use of maxA and maxB in a way that makes no */
930 /* sense according to the 80186 documentation! */
931 if (which == 1 && has_ym2151)
932 set_dac_frequency(7, 2000000 / (new_maxB * 2));
933 }
934
935 /* handle control changes */
936 if (new_control != -1)
937 {
938 int diff;
939
940 /* merge back in the bits we don't modify */
941 new_control = (new_control & ~0x1fc0) | (t->control & 0x1fc0);
942
943 /* handle the /INH bit */
944 if (!(new_control & 0x4000))
945 new_control = (new_control & ~0x8000) | (t->control & 0x8000);
946 new_control &= ~0x4000;
947
948 /* check for control bits we don't handle */
949 diff = new_control ^ t->control;
950 if (diff & 0x001c)
951 logerror("ERROR! - unsupported timer mode %04X\n", new_control);
952
953 /* if we have real changes, update things */
954 if (diff != 0)
955 {
956 /* if we're going off, make sure our timers are gone */
957 if ((diff & 0x8000) && !(new_control & 0x8000))
958 {
959 /* compute the final count */
960 internal_timer_sync(which);
961
962 /* nuke the timer and force the interrupt timer to be recomputed */
963 timer_adjust(t->time_timer, TIME_NEVER, which, 0);
964 t->time_timer_active = 0;
965 update_int_timer = 1;
966 }
967
968 /* if we're going on, start the timers running */
969 else if ((diff & 0x8000) && (new_control & 0x8000))
970 {
971 /* start the timing */
972 timer_adjust(t->time_timer, TIME_NEVER, which, 0);
973 t->time_timer_active = 1;
974 update_int_timer = 1;
975 }
976
977 /* if something about the interrupt timer changed, force an update */
978 if (!(diff & 0x8000) && (diff & 0x2000))
979 {
980 internal_timer_sync(which);
981 update_int_timer = 1;
982 }
983 }
984
985 /* set the new control register */
986 t->control = new_control;
987 }
988
989 /* update the interrupt timer */
990
991 /* kludge: the YM2151 games sometimes crank timer 1 really high, and leave interrupts */
992 /* enabled, even though the handler for timer 1 does nothing. To alleviate this, we */
993 /* just ignore it */
994 if (!has_ym2151 || which != 1)
995 if (update_int_timer)
996 {
997 if ((t->control & 0x8000) && (t->control & 0x2000))
998 {
999 int diff = t->maxA - t->count;
1000 if (diff <= 0) diff += 0x10000;
1001 timer_adjust(t->int_timer, (double)diff * TIME_IN_HZ(2000000), which, 0);
1002 if (LOG_TIMER) logerror("Set interrupt timer for %d\n", which);
1003 }
1004 else
1005 timer_adjust(t->int_timer, TIME_NEVER, which, 0);
1006 }
1007 }
1008
1009
1010
1011 /*************************************
1012 *
1013 * 80186 internal DMA
1014 *
1015 *************************************/
1016
dma_timer_callback(int which)1017 static void dma_timer_callback(int which)
1018 {
1019 struct dma_state *d = &i186.dma[which];
1020
1021 /* force an update and see if we're really done */
1022 stream_update(dma_stream, 0);
1023
1024 /* complete the status update */
1025 d->control &= ~0x0002;
1026 d->source += d->count;
1027 d->count = 0;
1028
1029 /* check for interrupt generation */
1030 if (d->control & 0x0100)
1031 {
1032 if (LOG_DMA) logerror("DMA%d timer callback - requesting interrupt: count = %04X, source = %04X\n", which, d->count, d->source);
1033 i186.intr.request |= 0x04 << which;
1034 update_interrupt_state();
1035 }
1036 }
1037
1038
update_dma_control(int which,int new_control)1039 static void update_dma_control(int which, int new_control)
1040 {
1041 struct dma_state *d = &i186.dma[which];
1042 int diff;
1043
1044 /* handle the CHG bit */
1045 if (!(new_control & 0x0004))
1046 new_control = (new_control & ~0x0002) | (d->control & 0x0002);
1047 new_control &= ~0x0004;
1048
1049 /* check for control bits we don't handle */
1050 diff = new_control ^ d->control;
1051 if (diff & 0x6811)
1052 logerror("ERROR! - unsupported DMA mode %04X\n", new_control);
1053
1054 /* if we're going live, set a timer */
1055 if ((diff & 0x0002) && (new_control & 0x0002))
1056 {
1057 /* make sure the parameters meet our expectations */
1058 if ((new_control & 0xfe00) != 0x1600)
1059 {
1060 logerror("Unexpected DMA control %02X\n", new_control);
1061 }
1062 else if (!is_redline && ((d->dest & 1) || (d->dest & 0x3f) > 0x0b))
1063 {
1064 logerror("Unexpected DMA destination %02X\n", d->dest);
1065 }
1066 else if (is_redline && (d->dest & 0xf000) != 0x4000 && (d->dest & 0xf000) != 0x5000)
1067 {
1068 logerror("Unexpected DMA destination %02X\n", d->dest);
1069 }
1070
1071 /* otherwise, set a timer */
1072 else
1073 {
1074 int count = d->count;
1075 int dacnum;
1076
1077 /* adjust for redline racer */
1078 if (!is_redline)
1079 dacnum = (d->dest & 0x3f) / 2;
1080 else
1081 {
1082 dacnum = (d->dest >> 9) & 7;
1083 dac[dacnum].volume = (d->dest & 0x1fe) / 2 / DAC_VOLUME_SCALE;
1084 }
1085
1086 if (LOG_DMA) logerror("Initiated DMA %d - count = %04X, source = %04X, dest = %04X\n", which, d->count, d->source, d->dest);
1087
1088 d->finished = 0;
1089 timer_adjust(d->finish_timer, TIME_IN_HZ(dac[dacnum].frequency) * (double)count, which, 0);
1090 }
1091 }
1092
1093 /* set the new control register */
1094 d->control = new_control;
1095 }
1096
1097
1098
1099 /*************************************
1100 *
1101 * 80186 internal I/O reads
1102 *
1103 *************************************/
1104
READ_HANDLER(i186_internal_port_r)1105 static READ_HANDLER( i186_internal_port_r )
1106 {
1107 int shift = 8 * (offset & 1);
1108 int temp, which;
1109
1110 switch (offset & ~1)
1111 {
1112 case 0x22:
1113 logerror("%05X:ERROR - read from 80186 EOI\n", activecpu_get_pc());
1114 break;
1115
1116 case 0x24:
1117 if (LOG_PORTS) logerror("%05X:read 80186 interrupt poll\n", activecpu_get_pc());
1118 if (i186.intr.poll_status & 0x8000)
1119 int_callback(0);
1120 return (i186.intr.poll_status >> shift) & 0xff;
1121
1122 case 0x26:
1123 if (LOG_PORTS) logerror("%05X:read 80186 interrupt poll status\n", activecpu_get_pc());
1124 return (i186.intr.poll_status >> shift) & 0xff;
1125
1126 case 0x28:
1127 if (LOG_PORTS) logerror("%05X:read 80186 interrupt mask\n", activecpu_get_pc());
1128 temp = (i186.intr.timer >> 3) & 0x01;
1129 temp |= (i186.intr.dma[0] >> 1) & 0x04;
1130 temp |= (i186.intr.dma[1] >> 0) & 0x08;
1131 temp |= (i186.intr.ext[0] << 1) & 0x10;
1132 temp |= (i186.intr.ext[1] << 2) & 0x20;
1133 temp |= (i186.intr.ext[2] << 3) & 0x40;
1134 temp |= (i186.intr.ext[3] << 4) & 0x80;
1135 return (temp >> shift) & 0xff;
1136
1137 case 0x2a:
1138 if (LOG_PORTS) logerror("%05X:read 80186 interrupt priority mask\n", activecpu_get_pc());
1139 return (i186.intr.priority_mask >> shift) & 0xff;
1140
1141 case 0x2c:
1142 if (LOG_PORTS) logerror("%05X:read 80186 interrupt in-service\n", activecpu_get_pc());
1143 return (i186.intr.in_service >> shift) & 0xff;
1144
1145 case 0x2e:
1146 if (LOG_PORTS) logerror("%05X:read 80186 interrupt request\n", activecpu_get_pc());
1147 temp = i186.intr.request & ~0x0001;
1148 if (i186.intr.status & 0x0007)
1149 temp |= 1;
1150 return (temp >> shift) & 0xff;
1151
1152 case 0x30:
1153 if (LOG_PORTS) logerror("%05X:read 80186 interrupt status\n", activecpu_get_pc());
1154 return (i186.intr.status >> shift) & 0xff;
1155
1156 case 0x32:
1157 if (LOG_PORTS) logerror("%05X:read 80186 timer interrupt control\n", activecpu_get_pc());
1158 return (i186.intr.timer >> shift) & 0xff;
1159
1160 case 0x34:
1161 if (LOG_PORTS) logerror("%05X:read 80186 DMA 0 interrupt control\n", activecpu_get_pc());
1162 return (i186.intr.dma[0] >> shift) & 0xff;
1163
1164 case 0x36:
1165 if (LOG_PORTS) logerror("%05X:read 80186 DMA 1 interrupt control\n", activecpu_get_pc());
1166 return (i186.intr.dma[1] >> shift) & 0xff;
1167
1168 case 0x38:
1169 if (LOG_PORTS) logerror("%05X:read 80186 INT 0 interrupt control\n", activecpu_get_pc());
1170 return (i186.intr.ext[0] >> shift) & 0xff;
1171
1172 case 0x3a:
1173 if (LOG_PORTS) logerror("%05X:read 80186 INT 1 interrupt control\n", activecpu_get_pc());
1174 return (i186.intr.ext[1] >> shift) & 0xff;
1175
1176 case 0x3c:
1177 if (LOG_PORTS) logerror("%05X:read 80186 INT 2 interrupt control\n", activecpu_get_pc());
1178 return (i186.intr.ext[2] >> shift) & 0xff;
1179
1180 case 0x3e:
1181 if (LOG_PORTS) logerror("%05X:read 80186 INT 3 interrupt control\n", activecpu_get_pc());
1182 return (i186.intr.ext[3] >> shift) & 0xff;
1183
1184 case 0x50:
1185 case 0x58:
1186 case 0x60:
1187 if (LOG_PORTS) logerror("%05X:read 80186 Timer %d count\n", activecpu_get_pc(), (offset - 0x50) / 8);
1188 which = (offset - 0x50) / 8;
1189 if (!(offset & 1))
1190 internal_timer_sync(which);
1191 return (i186.timer[which].count >> shift) & 0xff;
1192
1193 case 0x52:
1194 case 0x5a:
1195 case 0x62:
1196 if (LOG_PORTS) logerror("%05X:read 80186 Timer %d max A\n", activecpu_get_pc(), (offset - 0x50) / 8);
1197 which = (offset - 0x50) / 8;
1198 return (i186.timer[which].maxA >> shift) & 0xff;
1199
1200 case 0x54:
1201 case 0x5c:
1202 logerror("%05X:read 80186 Timer %d max B\n", activecpu_get_pc(), (offset - 0x50) / 8);
1203 which = (offset - 0x50) / 8;
1204 return (i186.timer[which].maxB >> shift) & 0xff;
1205
1206 case 0x56:
1207 case 0x5e:
1208 case 0x66:
1209 if (LOG_PORTS) logerror("%05X:read 80186 Timer %d control\n", activecpu_get_pc(), (offset - 0x50) / 8);
1210 which = (offset - 0x50) / 8;
1211 return (i186.timer[which].control >> shift) & 0xff;
1212
1213 case 0xa0:
1214 if (LOG_PORTS) logerror("%05X:read 80186 upper chip select\n", activecpu_get_pc());
1215 return (i186.mem.upper >> shift) & 0xff;
1216
1217 case 0xa2:
1218 if (LOG_PORTS) logerror("%05X:read 80186 lower chip select\n", activecpu_get_pc());
1219 return (i186.mem.lower >> shift) & 0xff;
1220
1221 case 0xa4:
1222 if (LOG_PORTS) logerror("%05X:read 80186 peripheral chip select\n", activecpu_get_pc());
1223 return (i186.mem.peripheral >> shift) & 0xff;
1224
1225 case 0xa6:
1226 if (LOG_PORTS) logerror("%05X:read 80186 middle chip select\n", activecpu_get_pc());
1227 return (i186.mem.middle >> shift) & 0xff;
1228
1229 case 0xa8:
1230 if (LOG_PORTS) logerror("%05X:read 80186 middle P chip select\n", activecpu_get_pc());
1231 return (i186.mem.middle_size >> shift) & 0xff;
1232
1233 case 0xc0:
1234 case 0xd0:
1235 if (LOG_PORTS) logerror("%05X:read 80186 DMA%d lower source address\n", activecpu_get_pc(), (offset - 0xc0) / 0x10);
1236 which = (offset - 0xc0) / 0x10;
1237 stream_update(dma_stream, 0);
1238 return (i186.dma[which].source >> shift) & 0xff;
1239
1240 case 0xc2:
1241 case 0xd2:
1242 if (LOG_PORTS) logerror("%05X:read 80186 DMA%d upper source address\n", activecpu_get_pc(), (offset - 0xc0) / 0x10);
1243 which = (offset - 0xc0) / 0x10;
1244 stream_update(dma_stream, 0);
1245 return (i186.dma[which].source >> (shift + 16)) & 0xff;
1246
1247 case 0xc4:
1248 case 0xd4:
1249 if (LOG_PORTS) logerror("%05X:read 80186 DMA%d lower dest address\n", activecpu_get_pc(), (offset - 0xc0) / 0x10);
1250 which = (offset - 0xc0) / 0x10;
1251 stream_update(dma_stream, 0);
1252 return (i186.dma[which].dest >> shift) & 0xff;
1253
1254 case 0xc6:
1255 case 0xd6:
1256 if (LOG_PORTS) logerror("%05X:read 80186 DMA%d upper dest address\n", activecpu_get_pc(), (offset - 0xc0) / 0x10);
1257 which = (offset - 0xc0) / 0x10;
1258 stream_update(dma_stream, 0);
1259 return (i186.dma[which].dest >> (shift + 16)) & 0xff;
1260
1261 case 0xc8:
1262 case 0xd8:
1263 if (LOG_PORTS) logerror("%05X:read 80186 DMA%d transfer count\n", activecpu_get_pc(), (offset - 0xc0) / 0x10);
1264 which = (offset - 0xc0) / 0x10;
1265 stream_update(dma_stream, 0);
1266 return (i186.dma[which].count >> shift) & 0xff;
1267
1268 case 0xca:
1269 case 0xda:
1270 if (LOG_PORTS) logerror("%05X:read 80186 DMA%d control\n", activecpu_get_pc(), (offset - 0xc0) / 0x10);
1271 which = (offset - 0xc0) / 0x10;
1272 stream_update(dma_stream, 0);
1273 return (i186.dma[which].control >> shift) & 0xff;
1274
1275 default:
1276 logerror("%05X:read 80186 port %02X\n", activecpu_get_pc(), offset);
1277 break;
1278 }
1279 return 0x00;
1280 }
1281
1282
1283
1284 /*************************************
1285 *
1286 * 80186 internal I/O writes
1287 *
1288 *************************************/
1289
WRITE_HANDLER(i186_internal_port_w)1290 static WRITE_HANDLER( i186_internal_port_w )
1291 {
1292 static UINT8 even_byte;
1293 int temp, which, data16;
1294
1295 /* warning: this assumes all port writes here are word-sized */
1296 if (!(offset & 1))
1297 {
1298 even_byte = data;
1299 return;
1300 }
1301 data16 = (data << 8) | even_byte;
1302
1303 switch (offset & ~1)
1304 {
1305 case 0x22:
1306 if (LOG_PORTS) logerror("%05X:80186 EOI = %04X\n", activecpu_get_pc(), data16);
1307 handle_eoi(0x8000);
1308 update_interrupt_state();
1309 break;
1310
1311 case 0x24:
1312 logerror("%05X:ERROR - write to 80186 interrupt poll = %04X\n", activecpu_get_pc(), data16);
1313 break;
1314
1315 case 0x26:
1316 logerror("%05X:ERROR - write to 80186 interrupt poll status = %04X\n", activecpu_get_pc(), data16);
1317 break;
1318
1319 case 0x28:
1320 if (LOG_PORTS) logerror("%05X:80186 interrupt mask = %04X\n", activecpu_get_pc(), data16);
1321 i186.intr.timer = (i186.intr.timer & ~0x08) | ((data16 << 3) & 0x08);
1322 i186.intr.dma[0] = (i186.intr.dma[0] & ~0x08) | ((data16 << 1) & 0x08);
1323 i186.intr.dma[1] = (i186.intr.dma[1] & ~0x08) | ((data16 << 0) & 0x08);
1324 i186.intr.ext[0] = (i186.intr.ext[0] & ~0x08) | ((data16 >> 1) & 0x08);
1325 i186.intr.ext[1] = (i186.intr.ext[1] & ~0x08) | ((data16 >> 2) & 0x08);
1326 i186.intr.ext[2] = (i186.intr.ext[2] & ~0x08) | ((data16 >> 3) & 0x08);
1327 i186.intr.ext[3] = (i186.intr.ext[3] & ~0x08) | ((data16 >> 4) & 0x08);
1328 update_interrupt_state();
1329 break;
1330
1331 case 0x2a:
1332 if (LOG_PORTS) logerror("%05X:80186 interrupt priority mask = %04X\n", activecpu_get_pc(), data16);
1333 i186.intr.priority_mask = data16 & 0x0007;
1334 update_interrupt_state();
1335 break;
1336
1337 case 0x2c:
1338 if (LOG_PORTS) logerror("%05X:80186 interrupt in-service = %04X\n", activecpu_get_pc(), data16);
1339 i186.intr.in_service = data16 & 0x00ff;
1340 update_interrupt_state();
1341 break;
1342
1343 case 0x2e:
1344 if (LOG_PORTS) logerror("%05X:80186 interrupt request = %04X\n", activecpu_get_pc(), data16);
1345 i186.intr.request = (i186.intr.request & ~0x00c0) | (data16 & 0x00c0);
1346 update_interrupt_state();
1347 break;
1348
1349 case 0x30:
1350 if (LOG_PORTS) logerror("%05X:WARNING - wrote to 80186 interrupt status = %04X\n", activecpu_get_pc(), data16);
1351 i186.intr.status = (i186.intr.status & ~0x8007) | (data16 & 0x8007);
1352 update_interrupt_state();
1353 break;
1354
1355 case 0x32:
1356 if (LOG_PORTS) logerror("%05X:80186 timer interrupt contol = %04X\n", activecpu_get_pc(), data16);
1357 i186.intr.timer = data16 & 0x000f;
1358 break;
1359
1360 case 0x34:
1361 if (LOG_PORTS) logerror("%05X:80186 DMA 0 interrupt control = %04X\n", activecpu_get_pc(), data16);
1362 i186.intr.dma[0] = data16 & 0x000f;
1363 break;
1364
1365 case 0x36:
1366 if (LOG_PORTS) logerror("%05X:80186 DMA 1 interrupt control = %04X\n", activecpu_get_pc(), data16);
1367 i186.intr.dma[1] = data16 & 0x000f;
1368 break;
1369
1370 case 0x38:
1371 if (LOG_PORTS) logerror("%05X:80186 INT 0 interrupt control = %04X\n", activecpu_get_pc(), data16);
1372 i186.intr.ext[0] = data16 & 0x007f;
1373 break;
1374
1375 case 0x3a:
1376 if (LOG_PORTS) logerror("%05X:80186 INT 1 interrupt control = %04X\n", activecpu_get_pc(), data16);
1377 i186.intr.ext[1] = data16 & 0x007f;
1378 break;
1379
1380 case 0x3c:
1381 if (LOG_PORTS) logerror("%05X:80186 INT 2 interrupt control = %04X\n", activecpu_get_pc(), data16);
1382 i186.intr.ext[2] = data16 & 0x001f;
1383 break;
1384
1385 case 0x3e:
1386 if (LOG_PORTS) logerror("%05X:80186 INT 3 interrupt control = %04X\n", activecpu_get_pc(), data16);
1387 i186.intr.ext[3] = data16 & 0x001f;
1388 break;
1389
1390 case 0x50:
1391 case 0x58:
1392 case 0x60:
1393 if (LOG_PORTS) logerror("%05X:80186 Timer %d count = %04X\n", activecpu_get_pc(), (offset - 0x50) / 8, data16);
1394 which = (offset - 0x50) / 8;
1395 internal_timer_update(which, data16, -1, -1, -1);
1396 break;
1397
1398 case 0x52:
1399 case 0x5a:
1400 case 0x62:
1401 if (LOG_PORTS) logerror("%05X:80186 Timer %d max A = %04X\n", activecpu_get_pc(), (offset - 0x50) / 8, data16);
1402 which = (offset - 0x50) / 8;
1403 internal_timer_update(which, -1, data16, -1, -1);
1404 break;
1405
1406 case 0x54:
1407 case 0x5c:
1408 if (LOG_PORTS) logerror("%05X:80186 Timer %d max B = %04X\n", activecpu_get_pc(), (offset - 0x50) / 8, data16);
1409 which = (offset - 0x50) / 8;
1410 internal_timer_update(which, -1, -1, data16, -1);
1411 break;
1412
1413 case 0x56:
1414 case 0x5e:
1415 case 0x66:
1416 if (LOG_PORTS) logerror("%05X:80186 Timer %d control = %04X\n", activecpu_get_pc(), (offset - 0x50) / 8, data16);
1417 which = (offset - 0x50) / 8;
1418 internal_timer_update(which, -1, -1, -1, data16);
1419 break;
1420
1421 case 0xa0:
1422 if (LOG_PORTS) logerror("%05X:80186 upper chip select = %04X\n", activecpu_get_pc(), data16);
1423 i186.mem.upper = data16 | 0xc038;
1424 break;
1425
1426 case 0xa2:
1427 if (LOG_PORTS) logerror("%05X:80186 lower chip select = %04X\n", activecpu_get_pc(), data16);
1428 i186.mem.lower = (data16 & 0x3fff) | 0x0038;
1429 break;
1430
1431 case 0xa4:
1432 if (LOG_PORTS) logerror("%05X:80186 peripheral chip select = %04X\n", activecpu_get_pc(), data16);
1433 i186.mem.peripheral = data16 | 0x0038;
1434 break;
1435
1436 case 0xa6:
1437 if (LOG_PORTS) logerror("%05X:80186 middle chip select = %04X\n", activecpu_get_pc(), data16);
1438 i186.mem.middle = data16 | 0x01f8;
1439 break;
1440
1441 case 0xa8:
1442 if (LOG_PORTS) logerror("%05X:80186 middle P chip select = %04X\n", activecpu_get_pc(), data16);
1443 i186.mem.middle_size = data16 | 0x8038;
1444
1445 temp = (i186.mem.peripheral & 0xffc0) << 4;
1446 if (i186.mem.middle_size & 0x0040)
1447 {
1448 install_mem_read_handler(2, temp, temp + 0x2ff, peripheral_r);
1449 install_mem_write_handler(2, temp, temp + 0x2ff, peripheral_w);
1450 }
1451 else
1452 {
1453 temp &= 0xffff;
1454 install_port_read_handler(2, temp, temp + 0x2ff, peripheral_r);
1455 install_port_write_handler(2, temp, temp + 0x2ff, peripheral_w);
1456 }
1457
1458 /* we need to do this at a time when the I86 context is swapped in */
1459 /* this register is generally set once at startup and never again, so it's a good */
1460 /* time to set it up */
1461 i86_set_irq_callback(int_callback);
1462 break;
1463
1464 case 0xc0:
1465 case 0xd0:
1466 if (LOG_PORTS) logerror("%05X:80186 DMA%d lower source address = %04X\n", activecpu_get_pc(), (offset - 0xc0) / 0x10, data16);
1467 which = (offset - 0xc0) / 0x10;
1468 stream_update(dma_stream, 0);
1469 i186.dma[which].source = (i186.dma[which].source & ~0x0ffff) | (data16 & 0x0ffff);
1470 break;
1471
1472 case 0xc2:
1473 case 0xd2:
1474 if (LOG_PORTS) logerror("%05X:80186 DMA%d upper source address = %04X\n", activecpu_get_pc(), (offset - 0xc0) / 0x10, data16);
1475 which = (offset - 0xc0) / 0x10;
1476 stream_update(dma_stream, 0);
1477 i186.dma[which].source = (i186.dma[which].source & ~0xf0000) | ((data16 << 16) & 0xf0000);
1478 break;
1479
1480 case 0xc4:
1481 case 0xd4:
1482 if (LOG_PORTS) logerror("%05X:80186 DMA%d lower dest address = %04X\n", activecpu_get_pc(), (offset - 0xc0) / 0x10, data16);
1483 which = (offset - 0xc0) / 0x10;
1484 stream_update(dma_stream, 0);
1485 i186.dma[which].dest = (i186.dma[which].dest & ~0x0ffff) | (data16 & 0x0ffff);
1486 break;
1487
1488 case 0xc6:
1489 case 0xd6:
1490 if (LOG_PORTS) logerror("%05X:80186 DMA%d upper dest address = %04X\n", activecpu_get_pc(), (offset - 0xc0) / 0x10, data16);
1491 which = (offset - 0xc0) / 0x10;
1492 stream_update(dma_stream, 0);
1493 i186.dma[which].dest = (i186.dma[which].dest & ~0xf0000) | ((data16 << 16) & 0xf0000);
1494 break;
1495
1496 case 0xc8:
1497 case 0xd8:
1498 if (LOG_PORTS) logerror("%05X:80186 DMA%d transfer count = %04X\n", activecpu_get_pc(), (offset - 0xc0) / 0x10, data16);
1499 which = (offset - 0xc0) / 0x10;
1500 stream_update(dma_stream, 0);
1501 i186.dma[which].count = data16;
1502 break;
1503
1504 case 0xca:
1505 case 0xda:
1506 if (LOG_PORTS) logerror("%05X:80186 DMA%d control = %04X\n", activecpu_get_pc(), (offset - 0xc0) / 0x10, data16);
1507 which = (offset - 0xc0) / 0x10;
1508 stream_update(dma_stream, 0);
1509 update_dma_control(which, data16);
1510 break;
1511
1512 case 0xfe:
1513 if (LOG_PORTS) logerror("%05X:80186 relocation register = %04X\n", activecpu_get_pc(), data16);
1514
1515 /* we assume here there that this doesn't happen too often */
1516 /* plus, we can't really remove the old memory range, so we also assume that it's */
1517 /* okay to leave us mapped where we were */
1518 temp = (data16 & 0x0fff) << 8;
1519 if (data16 & 0x1000)
1520 {
1521 install_mem_read_handler(2, temp, temp + 0xff, i186_internal_port_r);
1522 install_mem_write_handler(2, temp, temp + 0xff, i186_internal_port_w);
1523 }
1524 else
1525 {
1526 temp &= 0xffff;
1527 install_port_read_handler(2, temp, temp + 0xff, i186_internal_port_r);
1528 install_port_write_handler(2, temp, temp + 0xff, i186_internal_port_w);
1529 }
1530 /* usrintf_showmessage("Sound CPU reset");*/
1531 break;
1532
1533 default:
1534 logerror("%05X:80186 port %02X = %04X\n", activecpu_get_pc(), offset, data16);
1535 break;
1536 }
1537 }
1538
1539
1540
1541 /*************************************
1542 *
1543 * 8254 PIT accesses
1544 *
1545 *************************************/
1546
counter_update_count(int which)1547 static INLINE void counter_update_count(int which)
1548 {
1549 /* only update if the timer is running */
1550 if (counter[which].timer)
1551 {
1552 /* determine how many 2MHz cycles are remaining */
1553 int count = (int)(timer_timeleft(counter[which].timer) / TIME_IN_HZ(2000000));
1554 counter[which].count = (count < 0) ? 0 : count;
1555 }
1556 }
1557
1558
READ_HANDLER(pit8254_r)1559 static READ_HANDLER( pit8254_r )
1560 {
1561 struct counter_state *ctr;
1562 int which = offset / 0x80;
1563 int reg = (offset / 2) & 3;
1564
1565 /* ignore odd offsets */
1566 if (offset & 1)
1567 return 0;
1568
1569 /* switch off the register */
1570 switch (offset & 3)
1571 {
1572 case 0:
1573 case 1:
1574 case 2:
1575 /* warning: assumes LSB/MSB addressing and no latching! */
1576 which = (which * 3) + reg;
1577 ctr = &counter[which];
1578
1579 /* update the count */
1580 counter_update_count(which);
1581
1582 /* return the LSB */
1583 if (counter[which].readbyte == 0)
1584 {
1585 counter[which].readbyte = 1;
1586 return counter[which].count & 0xff;
1587 }
1588
1589 /* write the MSB and reset the counter */
1590 else
1591 {
1592 counter[which].readbyte = 0;
1593 return (counter[which].count >> 8) & 0xff;
1594 }
1595 break;
1596 }
1597 return 0;
1598 }
1599
1600
WRITE_HANDLER(pit8254_w)1601 static WRITE_HANDLER( pit8254_w )
1602 {
1603 struct counter_state *ctr;
1604 int which = offset / 0x80;
1605 int reg = (offset / 2) & 3;
1606
1607 /* ignore odd offsets */
1608 if (offset & 1)
1609 return;
1610
1611 /* switch off the register */
1612 switch (reg)
1613 {
1614 case 0:
1615 case 1:
1616 case 2:
1617 /* warning: assumes LSB/MSB addressing and no latching! */
1618 which = (which * 3) + reg;
1619 ctr = &counter[which];
1620
1621 /* write the LSB */
1622 if (ctr->writebyte == 0)
1623 {
1624 ctr->count = (ctr->count & 0xff00) | (data & 0x00ff);
1625 ctr->writebyte = 1;
1626 }
1627
1628 /* write the MSB and reset the counter */
1629 else
1630 {
1631 ctr->count = (ctr->count & 0x00ff) | ((data << 8) & 0xff00);
1632 ctr->writebyte = 0;
1633
1634 /* treat 0 as $10000 */
1635 if (ctr->count == 0) ctr->count = 0x10000;
1636
1637 /* reset/start the timer */
1638 timer_adjust(ctr->timer, TIME_NEVER, 0, 0);
1639
1640 if (LOG_PIT) logerror("PIT counter %d set to %d (%d Hz)\n", which, ctr->count, 4000000 / ctr->count);
1641
1642 /* set the frequency of the associated DAC */
1643 if (!is_redline)
1644 set_dac_frequency(which, 4000000 / ctr->count);
1645 else
1646 {
1647 if (which < 5)
1648 set_dac_frequency(which, 7000000 / ctr->count);
1649 else if (which == 6)
1650 {
1651 set_dac_frequency(5, 7000000 / ctr->count);
1652 set_dac_frequency(6, 7000000 / ctr->count);
1653 set_dac_frequency(7, 7000000 / ctr->count);
1654 }
1655 }
1656 }
1657 break;
1658
1659 case 3:
1660 /* determine which counter */
1661 if ((data & 0xc0) == 0xc0) break;
1662 which = (which * 3) + (data >> 6);
1663 ctr = &counter[which];
1664
1665 /* set the mode */
1666 ctr->mode = (data >> 1) & 7;
1667 break;
1668 }
1669 }
1670
1671
1672
1673 /*************************************
1674 *
1675 * External 80186 control
1676 *
1677 *************************************/
1678
WRITE_HANDLER(leland_i86_control_w)1679 WRITE_HANDLER( leland_i86_control_w )
1680 {
1681 /* see if anything changed */
1682 int diff = (last_control ^ data) & 0xf8;
1683 if (!diff)
1684 return;
1685 last_control = data;
1686
1687 if (LOG_COMM)
1688 {
1689 logerror("%04X:I86 control = %02X", activecpu_get_previouspc(), data);
1690 if (!(data & 0x80)) logerror(" /RESET");
1691 if (!(data & 0x40)) logerror(" ZNMI");
1692 if (!(data & 0x20)) logerror(" INT0");
1693 if (!(data & 0x10)) logerror(" /TEST");
1694 if (!(data & 0x08)) logerror(" INT1");
1695 logerror("\n");
1696 }
1697
1698 /* /RESET */
1699 cpu_set_reset_line(2, data & 0x80 ? CLEAR_LINE : ASSERT_LINE);
1700
1701 /* /NMI */
1702 /* If the master CPU doesn't get a response by the time it's ready to send
1703 the next command, it uses an NMI to force the issue; unfortunately, this
1704 seems to really screw up the sound system. It turns out it's better to
1705 just wait for the original interrupt to occur naturally */
1706 /* cpu_set_nmi_line (2, data & 0x40 ? CLEAR_LINE : ASSERT_LINE);*/
1707
1708 /* INT0 */
1709 if (data & 0x20)
1710 {
1711 if (!LATCH_INTS) i186.intr.request &= ~0x10;
1712 }
1713 else if (i186.intr.ext[0] & 0x10)
1714 i186.intr.request |= 0x10;
1715 else if (diff & 0x20)
1716 i186.intr.request |= 0x10;
1717
1718 /* INT1 */
1719 if (data & 0x08)
1720 {
1721 if (!LATCH_INTS) i186.intr.request &= ~0x20;
1722 }
1723 else if (i186.intr.ext[1] & 0x10)
1724 i186.intr.request |= 0x20;
1725 else if (diff & 0x08)
1726 i186.intr.request |= 0x20;
1727
1728 /* handle reset here */
1729 if ((diff & 0x80) && (data & 0x80))
1730 leland_i186_reset();
1731
1732 update_interrupt_state();
1733 }
1734
1735
1736
1737 /*************************************
1738 *
1739 * Sound command handling
1740 *
1741 *************************************/
1742
command_lo_sync(int data)1743 static void command_lo_sync(int data)
1744 {
1745 if (LOG_COMM) logerror("%04X:Write sound command latch lo = %02X\n", activecpu_get_previouspc(), data);
1746 sound_command[0] = data;
1747 }
1748
1749
WRITE_HANDLER(leland_i86_command_lo_w)1750 WRITE_HANDLER( leland_i86_command_lo_w )
1751 {
1752 timer_set(TIME_NOW, data, command_lo_sync);
1753 }
1754
1755
WRITE_HANDLER(leland_i86_command_hi_w)1756 WRITE_HANDLER( leland_i86_command_hi_w )
1757 {
1758 if (LOG_COMM) logerror("%04X:Write sound command latch hi = %02X\n", activecpu_get_previouspc(), data);
1759 sound_command[1] = data;
1760 }
1761
1762
READ_HANDLER(main_to_sound_comm_r)1763 static READ_HANDLER( main_to_sound_comm_r )
1764 {
1765 if (!(offset & 1))
1766 {
1767 if (LOG_COMM) logerror("%05X:Read sound command latch lo = %02X\n", activecpu_get_pc(), sound_command[0]);
1768 return sound_command[0];
1769 }
1770 else
1771 {
1772 if (LOG_COMM) logerror("%05X:Read sound command latch hi = %02X\n", activecpu_get_pc(), sound_command[1]);
1773 return sound_command[1];
1774 }
1775 }
1776
1777
1778
1779
1780 /*************************************
1781 *
1782 * Sound response handling
1783 *
1784 *************************************/
1785
delayed_response_r(int checkpc)1786 static void delayed_response_r(int checkpc)
1787 {
1788 int pc = cpunum_get_reg(0, Z80_PC);
1789 int oldaf = cpunum_get_reg(0, Z80_AF);
1790
1791 /* This is pretty cheesy, but necessary. Since the CPUs run in round-robin order,
1792 synchronizing on the write to this register from the slave side does nothing.
1793 In order to make sure the master CPU get the real response, we synchronize on
1794 the read. However, the value we returned the first time around may not be
1795 accurate, so after the system has synced up, we go back into the master CPUs
1796 state and put the proper value into the A register. */
1797 if (pc == checkpc)
1798 {
1799 if (LOG_COMM) logerror("(Updated sound response latch to %02X)\n", sound_response);
1800
1801 oldaf = (oldaf & 0x00ff) | (sound_response << 8);
1802 cpunum_set_reg(0, Z80_AF, oldaf);
1803 }
1804 else
1805 logerror("ERROR: delayed_response_r - current PC = %04X, checkPC = %04X\n", pc, checkpc);
1806 }
1807
1808
READ_HANDLER(leland_i86_response_r)1809 READ_HANDLER( leland_i86_response_r )
1810 {
1811 if (LOG_COMM) logerror("%04X:Read sound response latch = %02X\n", activecpu_get_previouspc(), sound_response);
1812
1813 /* if sound is disabled, toggle between FF and 00 */
1814 if (Machine->sample_rate == 0)
1815 return sound_response ^= 0xff;
1816 else
1817 {
1818 /* synchronize the response */
1819 timer_set(TIME_NOW, activecpu_get_previouspc() + 2, delayed_response_r);
1820 return sound_response;
1821 }
1822 }
1823
1824
WRITE_HANDLER(sound_to_main_comm_w)1825 static WRITE_HANDLER( sound_to_main_comm_w )
1826 {
1827 if (LOG_COMM) logerror("%05X:Write sound response latch = %02X\n", activecpu_get_pc(), data);
1828 sound_response = data;
1829 }
1830
1831
1832
1833 /*************************************
1834 *
1835 * Low-level DAC I/O
1836 *
1837 *************************************/
1838
set_dac_frequency(int which,int frequency)1839 static void set_dac_frequency(int which, int frequency)
1840 {
1841 struct dac_state *d = &dac[which];
1842 int count = (d->bufin - d->bufout) & DAC_BUFFER_SIZE_MASK;
1843
1844 /* set the frequency of the associated DAC */
1845 d->frequency = frequency;
1846 d->step = (int)((double)frequency * (double)(1 << 24) / (double)Machine->sample_rate);
1847
1848 /* also determine the target buffer size */
1849 d->buftarget = dac[which].frequency / 60 + 50;
1850 if (d->buftarget > DAC_BUFFER_SIZE - 1)
1851 d->buftarget = DAC_BUFFER_SIZE - 1;
1852
1853 /* reevaluate the count */
1854 if (count > d->buftarget)
1855 clock_active &= ~(1 << which);
1856 else if (count < d->buftarget)
1857 {
1858 if (LOG_OPTIMIZATION) logerror(" - trigger due to clock active in set_dac_frequency\n");
1859 cpu_trigger(CPU_RESUME_TRIGGER);
1860 clock_active |= 1 << which;
1861 }
1862
1863 if (LOG_DAC) logerror("DAC %d frequency = %d, step = %08X\n", which, d->frequency, d->step);
1864 }
1865
1866
WRITE_HANDLER(dac_w)1867 static WRITE_HANDLER( dac_w )
1868 {
1869 int which = offset / 2;
1870 struct dac_state *d = &dac[which];
1871
1872 /* handle value changes */
1873 if (!(offset & 1))
1874 {
1875 int count = (d->bufin - d->bufout) & DAC_BUFFER_SIZE_MASK;
1876
1877 /* set the new value */
1878 d->value = (INT16)data - 0x80;
1879 if (LOG_DAC) logerror("%05X:DAC %d value = %02X\n", activecpu_get_pc(), offset / 2, data);
1880
1881 /* if we haven't overflowed the buffer, add the value value to it */
1882 if (count < DAC_BUFFER_SIZE - 1)
1883 {
1884 /* if this is the first byte, sync the stream */
1885 if (count == 0)
1886 stream_update(nondma_stream, 0);
1887
1888 /* prescale by the volume */
1889 d->buffer[d->bufin] = d->value * d->volume;
1890 d->bufin = (d->bufin + 1) & DAC_BUFFER_SIZE_MASK;
1891
1892 /* update the clock status */
1893 if (++count > d->buftarget)
1894 clock_active &= ~(1 << which);
1895 }
1896 }
1897
1898 /* handle volume changes */
1899 else
1900 {
1901 d->volume = (data ^ 0x00) / DAC_VOLUME_SCALE;
1902 if (LOG_DAC) logerror("%05X:DAC %d volume = %02X\n", activecpu_get_pc(), offset / 2, data);
1903 }
1904 }
1905
1906
WRITE_HANDLER(redline_dac_w)1907 static WRITE_HANDLER( redline_dac_w )
1908 {
1909 int which = offset / 0x200;
1910 struct dac_state *d = &dac[which];
1911 int count = (d->bufin - d->bufout) & DAC_BUFFER_SIZE_MASK;
1912
1913 /* set the new value */
1914 d->value = (INT16)data - 0x80;
1915
1916 /* if we haven't overflowed the buffer, add the value value to it */
1917 if (count < DAC_BUFFER_SIZE - 1)
1918 {
1919 /* if this is the first byte, sync the stream */
1920 if (count == 0)
1921 stream_update(nondma_stream, 0);
1922
1923 /* prescale by the volume */
1924 d->buffer[d->bufin] = d->value * d->volume;
1925 d->bufin = (d->bufin + 1) & DAC_BUFFER_SIZE_MASK;
1926
1927 /* update the clock status */
1928 if (++count > d->buftarget)
1929 clock_active &= ~(1 << which);
1930 }
1931
1932 /* update the volume */
1933 d->volume = (offset & 0x1fe) / 2 / DAC_VOLUME_SCALE;
1934 if (LOG_DAC) logerror("%05X:DAC %d value = %02X, volume = %02X\n", activecpu_get_pc(), which, data, (offset & 0x1fe) / 2);
1935 }
1936
1937
WRITE_HANDLER(dac_10bit_w)1938 static WRITE_HANDLER( dac_10bit_w )
1939 {
1940 static UINT8 even_byte;
1941 struct dac_state *d = &dac[6];
1942 int count = (d->bufin - d->bufout) & DAC_BUFFER_SIZE_MASK;
1943 int data16;
1944
1945 /* warning: this assumes all port writes here are word-sized */
1946 /* if the offset is even, just stash the value */
1947 if (!(offset & 1))
1948 {
1949 even_byte = data;
1950 return;
1951 }
1952 data16 = (data << 8) | even_byte;
1953
1954 /* set the new value */
1955 d->value = (INT16)data16 - 0x200;
1956 if (LOG_DAC) logerror("%05X:DAC 10-bit value = %02X\n", activecpu_get_pc(), data16);
1957
1958 /* if we haven't overflowed the buffer, add the value value to it */
1959 if (count < DAC_BUFFER_SIZE - 1)
1960 {
1961 /* if this is the first byte, sync the stream */
1962 if (count == 0)
1963 stream_update(nondma_stream, 0);
1964
1965 /* prescale by the volume */
1966 d->buffer[d->bufin] = d->value * (0xff / DAC_VOLUME_SCALE / 2);
1967 d->bufin = (d->bufin + 1) & DAC_BUFFER_SIZE_MASK;
1968
1969 /* update the clock status */
1970 if (++count > d->buftarget)
1971 clock_active &= ~0x40;
1972 }
1973 }
1974
1975
WRITE_HANDLER(ataxx_dac_control)1976 static WRITE_HANDLER( ataxx_dac_control )
1977 {
1978 /* handle common offsets */
1979 switch (offset)
1980 {
1981 case 0x00:
1982 case 0x02:
1983 case 0x04:
1984 dac_w(offset, data);
1985 return;
1986
1987 case 0x06:
1988 dac_w(1, ((data << 5) & 0xe0) | ((data << 2) & 0x1c) | (data & 0x03));
1989 dac_w(3, ((data << 2) & 0xe0) | ((data >> 1) & 0x1c) | ((data >> 4) & 0x03));
1990 dac_w(5, (data & 0xc0) | ((data >> 2) & 0x30) | ((data >> 4) & 0x0c) | ((data >> 6) & 0x03));
1991 return;
1992 }
1993
1994 /* if we have a YM2151 (and an external DAC), handle those offsets */
1995 if (has_ym2151)
1996 {
1997 stream_update(extern_stream, 0);
1998 switch (offset)
1999 {
2000 case 0x08:
2001 case 0x09:
2002 ext_active = 1;
2003 if (LOG_EXTERN) logerror("External DAC active\n");
2004 return;
2005
2006 case 0x0a:
2007 case 0x0b:
2008 ext_active = 0;
2009 if (LOG_EXTERN) logerror("External DAC inactive\n");
2010 return;
2011
2012 case 0x0c:
2013 ext_start = (ext_start & 0xff00f) | ((data << 4) & 0x00ff0);
2014 if (LOG_EXTERN) logerror("External DAC start = %05X\n", ext_start);
2015 return;
2016
2017 case 0x0d:
2018 ext_start = (ext_start & 0x00fff) | ((data << 12) & 0xff000);
2019 if (LOG_EXTERN) logerror("External DAC start = %05X\n", ext_start);
2020 return;
2021
2022 case 0x0e:
2023 ext_stop = (ext_stop & 0xff00f) | ((data << 4) & 0x00ff0);
2024 if (LOG_EXTERN) logerror("External DAC stop = %05X\n", ext_stop);
2025 return;
2026
2027 case 0x0f:
2028 ext_stop = (ext_stop & 0x00fff) | ((data << 12) & 0xff000);
2029 if (LOG_EXTERN) logerror("External DAC stop = %05X\n", ext_stop);
2030 return;
2031
2032 case 0x42:
2033 case 0x43:
2034 dac_w(offset - 0x42 + 14, data);
2035 return;
2036 }
2037 }
2038 logerror("%05X:Unexpected peripheral write %d/%02X = %02X\n", activecpu_get_pc(), 5, offset, data);
2039 }
2040
2041
2042
2043 /*************************************
2044 *
2045 * Peripheral chip dispatcher
2046 *
2047 *************************************/
2048
READ_HANDLER(peripheral_r)2049 static READ_HANDLER( peripheral_r )
2050 {
2051 int select = offset / 0x80;
2052 offset &= 0x7f;
2053
2054 switch (select)
2055 {
2056 case 0:
2057 if (offset & 1)
2058 return 0;
2059
2060 /* we have to return 0 periodically so that they handle interrupts */
2061 if ((++clock_tick & 7) == 0)
2062 return 0;
2063
2064 /* if we've filled up all the active channels, we can give this CPU a reset */
2065 /* until the next interrupt */
2066 {
2067 UINT8 result;
2068
2069 if (!is_redline)
2070 result = ((clock_active >> 1) & 0x3e);
2071 else
2072 result = ((clock_active << 1) & 0x7e);
2073
2074 if (!i186.intr.pending && active_mask && (*active_mask & result) == 0 && ++total_reads > 100)
2075 {
2076 if (LOG_OPTIMIZATION) logerror("Suspended CPU: active_mask = %02X, result = %02X\n", *active_mask, result);
2077 cpu_spinuntil_trigger(CPU_RESUME_TRIGGER);
2078 }
2079 else if (LOG_OPTIMIZATION)
2080 {
2081 if (i186.intr.pending) logerror("(can't suspend - interrupt pending)\n");
2082 else if (active_mask && (*active_mask & result) != 0) logerror("(can't suspend: mask=%02X result=%02X\n", *active_mask, result);
2083 }
2084
2085 return result;
2086 }
2087
2088 case 1:
2089 return main_to_sound_comm_r(offset);
2090
2091 case 2:
2092 return pit8254_r(offset);
2093
2094 case 3:
2095 if (!has_ym2151)
2096 return pit8254_r(offset | 0x80);
2097 else
2098 return (offset & 1) ? 0 : YM2151_status_port_0_r(offset);
2099
2100 case 4:
2101 if (is_redline)
2102 return pit8254_r(offset | 0x100);
2103 else
2104 logerror("%05X:Unexpected peripheral read %d/%02X\n", activecpu_get_pc(), select, offset);
2105 break;
2106
2107 default:
2108 logerror("%05X:Unexpected peripheral read %d/%02X\n", activecpu_get_pc(), select, offset);
2109 break;
2110 }
2111 return 0xff;
2112 }
2113
2114
WRITE_HANDLER(peripheral_w)2115 static WRITE_HANDLER( peripheral_w )
2116 {
2117 int select = offset / 0x80;
2118 offset &= 0x7f;
2119
2120 switch (select)
2121 {
2122 case 1:
2123 sound_to_main_comm_w(offset, data);
2124 break;
2125
2126 case 2:
2127 pit8254_w(offset, data);
2128 break;
2129
2130 case 3:
2131 if (!has_ym2151)
2132 pit8254_w(offset | 0x80, data);
2133 else if (offset == 0)
2134 YM2151_register_port_0_w(offset, data);
2135 else if (offset == 2)
2136 YM2151_data_port_0_w(offset, data);
2137 break;
2138
2139 case 4:
2140 if (is_redline)
2141 pit8254_w(offset | 0x100, data);
2142 else
2143 dac_10bit_w(offset, data);
2144 break;
2145
2146 case 5: /* Ataxx/WSF/Indy Heat only */
2147 ataxx_dac_control(offset, data);
2148 break;
2149
2150 default:
2151 logerror("%05X:Unexpected peripheral write %d/%02X = %02X\n", activecpu_get_pc(), select, offset, data);
2152 break;
2153 }
2154 }
2155
2156
2157
2158 /*************************************
2159 *
2160 * Optimizations
2161 *
2162 *************************************/
2163
leland_i86_optimize_address(offs_t offset)2164 void leland_i86_optimize_address(offs_t offset)
2165 {
2166 if (offset)
2167 active_mask = memory_region(REGION_CPU3) + offset;
2168 else
2169 active_mask = NULL;
2170 }
2171
2172
2173
2174 /*************************************
2175 *
2176 * Game-specific handlers
2177 *
2178 *************************************/
2179
WRITE_HANDLER(ataxx_i86_control_w)2180 WRITE_HANDLER( ataxx_i86_control_w )
2181 {
2182 /* compute the bit-shuffled variants of the bits and then write them */
2183 int modified = ((data & 0x01) << 7) |
2184 ((data & 0x02) << 5) |
2185 ((data & 0x04) << 3) |
2186 ((data & 0x08) << 1);
2187 leland_i86_control_w(offset, modified);
2188 }
2189
2190
2191
2192 /*************************************
2193 *
2194 * Sound CPU memory handlers
2195 *
2196 *************************************/
2197
MEMORY_READ_START(leland_i86_readmem)2198 MEMORY_READ_START( leland_i86_readmem )
2199 { 0x00000, 0x03fff, MRA_RAM },
2200 { 0x0c000, 0x0ffff, MRA_BANK6 }, /* used by Ataxx */
2201 { 0x1c000, 0x1ffff, MRA_BANK7 }, /* used by Super Offroad */
2202 { 0x20000, 0xfffff, MRA_ROM },
2203 MEMORY_END
2204
2205
2206 MEMORY_WRITE_START( leland_i86_writemem )
2207 { 0x00000, 0x03fff, MWA_RAM, &ram_base },
2208 { 0x0c000, 0x0ffff, MWA_BANK6 },
2209 { 0x1c000, 0x1ffff, MWA_BANK7 },
2210 { 0x20000, 0xfffff, MWA_ROM },
2211 MEMORY_END
2212
2213
2214 PORT_READ_START( leland_i86_readport )
2215 { 0xff00, 0xffff, i186_internal_port_r },
2216 PORT_END
2217
2218
2219 PORT_WRITE_START( redline_i86_writeport )
2220 { 0x6000, 0x6fff, redline_dac_w },
2221 { 0xff00, 0xffff, i186_internal_port_w },
2222 PORT_END
2223
2224
2225 PORT_WRITE_START( leland_i86_writeport )
2226 { 0x0000, 0x000b, dac_w },
2227 { 0x0080, 0x008b, dac_w },
2228 { 0x00c0, 0x00cb, dac_w },
2229 { 0xff00, 0xffff, i186_internal_port_w },
2230 PORT_END
2231
2232
2233 PORT_WRITE_START( ataxx_i86_writeport )
2234 { 0xff00, 0xffff, i186_internal_port_w },
2235 PORT_END
2236
2237
2238 /************************************************************************
2239
2240 Memory configurations:
2241
2242 Redline Racer:
2243 FFDF7:80186 upper chip select = E03C -> E0000-FFFFF, 128k long
2244 FFDF7:80186 lower chip select = 00FC -> 00000-00FFF, 4k long
2245 FFDF7:80186 peripheral chip select = 013C -> 01000, 01080, 01100, 01180, 01200, 01280, 01300
2246 FFDF7:80186 middle chip select = 81FC -> 80000-C0000, 64k chunks, 256k total
2247 FFDF7:80186 middle P chip select = A0FC
2248
2249 Quarterback, Team Quarterback, AAFB, Super Offroad, Track Pack, Pigout, Viper:
2250 FFDFA:80186 upper chip select = E03C -> E0000-FFFFF, 128k long
2251 FFDFA:80186 peripheral chip select = 203C -> 20000, 20080, 20100, 20180, 20200, 20280, 20300
2252 FFDFA:80186 middle chip select = 01FC -> 00000-7FFFF, 128k chunks, 512k total
2253 FFDFA:80186 middle P chip select = C0FC
2254
2255 Ataxx, Indy Heat, World Soccer Finals:
2256 FFD9D:80186 upper chip select = E03C -> E0000-FFFFF, 128k long
2257 FFD9D:80186 peripheral chip select = 043C -> 04000, 04080, 04100, 04180, 04200, 04280, 04300
2258 FFD9D:80186 middle chip select = 01FC -> 00000-7FFFF, 128k chunks, 512k total
2259 FFD9D:80186 middle P chip select = C0BC
2260
2261 ************************************************************************/
2262