1 /***************************************************************************
2
3 NAMCO sound driver.
4
5 This driver handles the four known types of NAMCO wavetable sounds:
6
7 - 3-voice mono (PROM-based design: Pac-Man, Pengo, Dig Dug, etc)
8 - 8-voice quadrophonic (Pole Position 1, Pole Position 2)
9 - 8-voice mono (custom 15XX: Mappy, Dig Dug 2, etc)
10 - 8-voice stereo (System 1)
11
12 ***************************************************************************/
13
14 #include "driver.h"
15 #include "namco.h"
16
17
18 /* 8 voices max */
19 #define MAX_VOICES 8
20
21 #define MAX_VOLUME 16
22
23 /* quality parameter: internal sample rate is 192 KHz, output is 48 KHz */
24 #define INTERNAL_RATE 192000
25 #define OUTPUT_RATE 48000
26
27 /* oversampling rate */
28 #define OVERSAMPLING_RATE (INTERNAL_RATE / OUTPUT_RATE)
29
30 /* 16 bits: sample bits of the stream buffer */
31 /* 4 bits: volume */
32 /* 4 bits: prom sample bits */
33 #define MIXLEVEL ((1 << (16 - 4 - 4)) / OVERSAMPLING_RATE)
34
35 /* stream output level */
36 #define OUTPUT_LEVEL(n) ((n) * MIXLEVEL / num_voices)
37
38 /* a position of waveform sample */
39 #define WAVEFORM_POSITION(n) (((n) >> f_fracbits) & 0x1f)
40
41
42 /* this structure defines the parameters for a channel */
43 typedef struct
44 {
45 UINT32 frequency;
46 UINT32 counter;
47 int volume[2];
48 int noise_sw;
49 int noise_state;
50 int noise_seed;
51 UINT32 noise_counter;
52 int waveform_select;
53 } sound_channel;
54
55
56 /* globals available to everyone */
57 unsigned char *namco_soundregs;
58 unsigned char *namco_wavedata;
59
60 /* data about the sound system */
61 static sound_channel channel_list[MAX_VOICES];
62 static sound_channel *last_channel;
63
64 /* global sound parameters */
65 static int wave_size;
66 static int num_voices;
67 static int sound_enable;
68 static int stream;
69 static int namco_clock;
70 static int sample_rate;
71 static int f_fracbits;
72
73 /* decoded waveform table */
74 static INT16 *waveform[MAX_VOLUME];
75
76
77 /* update the decoded waveform data */
update_namco_waveform(int offset,data8_t data)78 static void update_namco_waveform(int offset, data8_t data)
79 {
80 if (wave_size == 1)
81 {
82 INT16 wdata;
83 int v;
84
85 /* use full byte, first 4 high bits, then low 4 bits */
86 for (v = 0; v < MAX_VOLUME; v++)
87 {
88 wdata = ((data >> 4) & 0x0f) - 8;
89 waveform[v][offset * 2] = OUTPUT_LEVEL(wdata * v);
90 wdata = (data & 0x0f) - 8;
91 waveform[v][offset * 2 + 1] = OUTPUT_LEVEL(wdata * v);
92 }
93 }
94 else
95 {
96 int v;
97
98 /* use only low 4 bits */
99 for (v = 0; v < MAX_VOLUME; v++)
100 waveform[v][offset] = OUTPUT_LEVEL(((data & 0x0f) - 8) * v);
101 }
102 }
103
104
105 /* build the decoded waveform table */
build_decoded_waveform(int region)106 static int build_decoded_waveform(int region)
107 {
108 INT16 *p;
109 int size;
110 int offset;
111 int v;
112
113 /* 20pacgal has waves in RAM but old sound system */
114 if (region == -1 && num_voices != 3)
115 {
116 wave_size = 1;
117 size = 32 * 16; /* 32 samples, 16 waveforms */
118 }
119 else
120 {
121 wave_size = 0;
122 size = 32 * 8; /* 32 samples, 8 waveforms */
123 }
124
125 if ((p = (INT16 *)auto_malloc(size * MAX_VOLUME * sizeof (INT16))) == NULL)
126 return 1;
127
128 for (v = 0; v < MAX_VOLUME; v++)
129 {
130 waveform[v] = p;
131 p += size;
132 }
133
134 if (region != -1)
135 namco_wavedata = memory_region(region);
136
137 /* We need waveform data. It fails if region is not specified. */
138 if (namco_wavedata)
139 {
140 for (offset = 0; offset < 256; offset++)
141 update_namco_waveform(offset, namco_wavedata[offset]);
142 }
143
144 return 0;
145 }
146
147
148 /* generate sound by oversampling */
namco_update_one(INT16 * buffer,int length,const INT16 * wave,UINT32 counter,UINT32 freq)149 INLINE UINT32 namco_update_one(INT16 *buffer, int length, const INT16 *wave, UINT32 counter, UINT32 freq)
150 {
151 while (length-- > 0)
152 {
153 INT16 data = 0;
154 int i;
155
156 for (i = 0; i < OVERSAMPLING_RATE; i++)
157 {
158 data += wave[WAVEFORM_POSITION(counter)];
159 counter += freq;
160 }
161
162 *buffer++ += data;
163 }
164
165 return counter;
166 }
167
168
169 /* generate sound to the mix buffer in mono */
namco_update_mono(int ch,INT16 * buffer,int length)170 static void namco_update_mono(int ch, INT16 *buffer, int length)
171 {
172 sound_channel *voice;
173
174 /* zap the contents of the buffer */
175 memset(buffer, 0, length * sizeof(INT16));
176
177 /* if no sound, we're done */
178 if (sound_enable == 0)
179 return;
180
181 /* loop over each voice and add its contribution */
182 for (voice = channel_list; voice < last_channel; voice++)
183 {
184 INT16 *mix = buffer;
185 int v = voice->volume[0];
186
187 if (voice->noise_sw)
188 {
189 int f = voice->frequency & 0xff;
190
191 /* only update if we have non-zero volume and frequency */
192 if (v && f)
193 {
194 UINT32 delta = (f << (f_fracbits - 15 + 4)) * OVERSAMPLING_RATE;
195 UINT32 c = voice->noise_counter;
196 INT16 noise_data = OUTPUT_LEVEL(0x07 * (v >> 1) * OVERSAMPLING_RATE);
197 int i;
198
199 /* add our contribution */
200 for (i = 0; i < length; i++)
201 {
202 int cnt;
203
204 if (voice->noise_state)
205 *mix++ += noise_data;
206 else
207 *mix++ -= noise_data;
208
209 c += delta;
210 cnt = (c >> 12);
211 c &= (1 << 12) - 1;
212 for( ;cnt > 0; cnt--)
213 {
214 if ((voice->noise_seed + 1) & 2) voice->noise_state ^= 1;
215 if (voice->noise_seed & 1) voice->noise_seed ^= 0x28000;
216 voice->noise_seed >>= 1;
217 }
218 }
219
220 /* update the counter for this voice */
221 voice->noise_counter = c;
222 }
223 }
224 else
225 {
226 /* only update if we have non-zero volume and frequency */
227 if (v && voice->frequency)
228 {
229 const INT16 *w = &waveform[v][voice->waveform_select * 32];
230
231 /* generate sound into buffer and update the counter for this voice */
232 voice->counter = namco_update_one(mix, length, w, voice->counter, voice->frequency);
233 }
234 }
235 }
236 }
237
238
239 /* generate sound to the mix buffer in stereo */
namco_update_stereo(int ch,INT16 ** buffer,int length)240 static void namco_update_stereo(int ch, INT16 **buffer, int length)
241 {
242 sound_channel *voice;
243
244 /* zap the contents of the buffers */
245 memset(buffer[0], 0, length * sizeof(INT16));
246 memset(buffer[1], 0, length * sizeof(INT16));
247
248 /* if no sound, we're done */
249 if (sound_enable == 0)
250 return;
251
252 /* loop over each voice and add its contribution */
253 for (voice = channel_list; voice < last_channel; voice++)
254 {
255 INT16 *lmix = buffer[0];
256 INT16 *rmix = buffer[1];
257 int lv = voice->volume[0];
258 int rv = voice->volume[1];
259
260 if (voice->noise_sw)
261 {
262 int f = voice->frequency & 0xff;
263
264 /* only update if we have non-zero volume and frequency */
265 if ((lv || rv) && f)
266 {
267 UINT32 delta = (f << (f_fracbits - 15 + 4)) * OVERSAMPLING_RATE;
268 UINT32 c = voice->noise_counter;
269 INT16 l_noise_data = OUTPUT_LEVEL(0x07 * (lv >> 1) * OVERSAMPLING_RATE);
270 INT16 r_noise_data = OUTPUT_LEVEL(0x07 * (rv >> 1) * OVERSAMPLING_RATE);
271 int i;
272
273 /* add our contribution */
274 for (i = 0; i < length; i++)
275 {
276 int cnt;
277
278 if (voice->noise_state)
279 {
280 *lmix++ += l_noise_data;
281 *rmix++ += r_noise_data;
282 }
283 else
284 {
285 *lmix++ -= l_noise_data;
286 *rmix++ -= r_noise_data;
287 }
288
289 c += delta;
290 cnt = (c >> 12);
291 c &= (1 << 12) - 1;
292 for( ;cnt > 0; cnt--)
293 {
294 if ((voice->noise_seed + 1) & 2) voice->noise_state ^= 1;
295 if (voice->noise_seed & 1) voice->noise_seed ^= 0x28000;
296 voice->noise_seed >>= 1;
297 }
298 }
299
300 /* update the counter for this voice */
301 voice->noise_counter = c;
302 }
303 }
304 else
305 {
306 /* only update if we have non-zero frequency */
307 if (voice->frequency)
308 {
309 /* save the counter for this voice */
310 UINT32 c = voice->counter;
311
312 /* only update if we have non-zero left volume */
313 if (lv)
314 {
315 const INT16 *lw = &waveform[lv][voice->waveform_select * 32];
316
317 /* generate sound into the buffer */
318 c = namco_update_one(lmix, length, lw, voice->counter, voice->frequency);
319 }
320
321 /* only update if we have non-zero right volume */
322 if (rv)
323 {
324 const INT16 *rw = &waveform[rv][voice->waveform_select * 32];
325
326 /* generate sound into the buffer */
327 c = namco_update_one(rmix, length, rw, voice->counter, voice->frequency);
328 }
329
330 /* update the counter for this voice */
331 voice->counter = c;
332 }
333 }
334 }
335 }
336
337
namco_sh_start(const struct MachineSound * msound)338 int namco_sh_start(const struct MachineSound *msound)
339 {
340 sound_channel *voice;
341 const struct namco_interface *intf = msound->sound_interface;
342 int clock_multiple;
343
344 /* extract globals from the interface */
345 num_voices = intf->voices;
346 last_channel = channel_list + num_voices;
347
348 /* adjust internal clock */
349 namco_clock = intf->samplerate;
350 for (clock_multiple = 0; namco_clock < INTERNAL_RATE; clock_multiple++)
351 namco_clock *= 2;
352
353 f_fracbits = clock_multiple + 15;
354
355 /* adjust output clock */
356 sample_rate = namco_clock / OVERSAMPLING_RATE;
357
358 logerror("Namco: freq fractional bits = %d: internal freq = %d, output freq = %d\n", f_fracbits, namco_clock, sample_rate);
359
360 /* build the waveform table */
361 if (build_decoded_waveform(intf->region))
362 return 1;
363
364 /* get stream channels */
365 if (intf->stereo)
366 {
367 int vol[2];
368 char buf[2][40];
369 const char *name[2];
370
371 name[0] = buf[0];
372 sprintf(buf[0],"%s left",sound_name(msound));
373 name[1] = buf[1];
374 sprintf(buf[1],"%s right",sound_name(msound));
375 vol[0] = MIXER(intf->volume,MIXER_PAN_LEFT);
376 vol[1] = MIXER(intf->volume,MIXER_PAN_RIGHT);
377 stream = stream_init_multi(2, name, vol, sample_rate, 0, namco_update_stereo);
378 }
379 else
380 {
381 stream = stream_init(sound_name(msound), intf->volume, sample_rate, 0, namco_update_mono);
382 }
383
384 /* start with sound enabled, many games don't have a sound enable register */
385 sound_enable = 1;
386
387 /* reset all the voices */
388 for (voice = channel_list; voice < last_channel; voice++)
389 {
390 voice->frequency = 0;
391 voice->volume[0] = voice->volume[1] = 0;
392 voice->waveform_select = 0;
393 voice->counter = 0;
394 voice->noise_sw = 0;
395 voice->noise_state = 0;
396 voice->noise_seed = 1;
397 voice->noise_counter = 0;
398 }
399
400 return 0;
401 }
402
403
namco_sh_stop(void)404 void namco_sh_stop(void)
405 {
406 }
407
408
409 /********************************************************************************/
410
411 /* pengo register map
412 0x05: ch 0 waveform select
413 0x0a: ch 1 waveform select
414 0x0f: ch 2 waveform select
415
416 0x10: ch 0 the first voice has extra frequency bits
417 0x11-0x14: ch 0 frequency
418 0x15: ch 0 volume
419
420 0x16-0x19: ch 1 frequency
421 0x1a: ch 1 volume
422
423 0x1b-0x1e: ch 2 frequency
424 0x1f: ch 2 volume
425 */
426
WRITE_HANDLER(pengo_sound_enable_w)427 WRITE_HANDLER( pengo_sound_enable_w )
428 {
429 sound_enable = data;
430 }
431
WRITE_HANDLER(pengo_sound_w)432 WRITE_HANDLER( pengo_sound_w )
433 {
434 sound_channel *voice;
435 int ch;
436
437 data &= 0x0f;
438 if (namco_soundregs[offset] == data)
439 return;
440
441 /* update the streams */
442 stream_update(stream, 0);
443
444 /* set the register */
445 namco_soundregs[offset] = data;
446
447 if (offset < 0x10)
448 ch = (offset - 5) / 5;
449 else if (offset == 0x10)
450 ch = 0;
451 else
452 ch = (offset - 0x11) / 5;
453
454 if (ch >= num_voices)
455 return;
456
457 /* recompute the voice parameters */
458 voice = channel_list + ch;
459 switch (offset - ch * 5)
460 {
461 case 0x05:
462 voice->waveform_select = data & 7;
463 break;
464
465 case 0x10:
466 case 0x11:
467 case 0x12:
468 case 0x13:
469 case 0x14:
470 /* the frequency has 20 bits */
471 /* the first voice has extra frequency bits */
472 voice->frequency = (ch == 0) ? namco_soundregs[0x10] : 0;
473 voice->frequency += (namco_soundregs[ch * 5 + 0x11] << 4);
474 voice->frequency += (namco_soundregs[ch * 5 + 0x12] << 8);
475 voice->frequency += (namco_soundregs[ch * 5 + 0x13] << 12);
476 voice->frequency += (namco_soundregs[ch * 5 + 0x14] << 16); /* always 0 */
477 break;
478
479 case 0x15:
480 voice->volume[0] = data;
481 break;
482 }
483 }
484
485
486 /********************************************************************************/
487
488 /* polepos register map
489 Note: even if there are 8 voices, the game doesn't use the first 2 because
490 it select the 54XX/52XX outputs on those channels
491
492 0x00-0x01 ch 0 frequency
493 0x02 ch 0 xxxx---- GAIN 2 volume
494 0x03 ch 0 xxxx---- GAIN 3 volume
495 ----xxxx GAIN 4 volume
496
497 0x04-0x07 ch 1
498
499 .
500 .
501 .
502
503 0x1c-0x1f ch 7
504
505 0x23 ch 0 xxxx---- GAIN 1 volume
506 -----xxx waveform select
507 ----x-xx channel output select
508 0-7 (all the same, shared with waveform select) = wave
509 8 = CHANL1 (54XX pins 17-20)
510 9 = CHANL2 (54XX pins 8-11)
511 A = CHANL3 (54XX pins 4-7)
512 B = CHANL4 (52XX)
513 0x27 ch 1
514 0x2b ch 2
515 0x2f ch 3
516 0x33 ch 4
517 0x37 ch 5
518 0x3b ch 6
519 0x3f ch 7
520 */
521
polepos_sound_enable(int enable)522 void polepos_sound_enable(int enable)
523 {
524 sound_enable = enable;
525 }
526
WRITE_HANDLER(polepos_sound_w)527 WRITE_HANDLER( polepos_sound_w )
528 {
529 sound_channel *voice;
530 int ch;
531
532 if (namco_soundregs[offset] == data)
533 return;
534
535 /* update the streams */
536 stream_update(stream, 0);
537
538 /* set the register */
539 namco_soundregs[offset] = data;
540
541 ch = (offset & 0x1f) / 4;
542
543 /* recompute the voice parameters */
544 voice = channel_list + ch;
545 switch (offset & 0x23)
546 {
547 case 0x00:
548 case 0x01:
549 /* the frequency has 16 bits */
550 voice->frequency = namco_soundregs[ch * 4 + 0x00];
551 voice->frequency += namco_soundregs[ch * 4 + 0x01] << 8;
552 break;
553
554 case 0x23:
555 voice->waveform_select = data & 7;
556 /* fall through */
557 case 0x02:
558 case 0x03:
559 voice->volume[0] = voice->volume[1] = 0;
560 // front speakers ?
561 voice->volume[0] += namco_soundregs[ch * 4 + 0x03] >> 4;
562 voice->volume[1] += namco_soundregs[ch * 4 + 0x03] & 0x0f;
563 // rear speakers ?
564 voice->volume[0] += namco_soundregs[ch * 4 + 0x23] >> 4;
565 voice->volume[1] += namco_soundregs[ch * 4 + 0x02] >> 4;
566
567 voice->volume[0] /= 2;
568 voice->volume[1] /= 2;
569
570 /* if 54XX or 52XX selected, silence this voice */
571 if (namco_soundregs[ch * 4 + 0x23] & 8)
572 voice->volume[0] = voice->volume[1] = 0;
573 break;
574 }
575 }
576
577
578 /********************************************************************************/
579
580 /* 15XX register map
581 0x03 ch 0 volume
582 0x04-0x05 ch 0 frequency
583 0x06 ch 0 waveform select & frequency
584
585 0x0b ch 1 volume
586 0x0c-0x0d ch 1 frequency
587 0x0e ch 1 waveform select & frequency
588
589 .
590 .
591 .
592
593 0x3b ch 7 volume
594 0x3c-0x3d ch 7 frequency
595 0x3e ch 7 waveform select & frequency
596 */
597
598
WRITE_HANDLER(mappy_sound_enable_w)599 WRITE_HANDLER( mappy_sound_enable_w ) //remove this when drivers are updated this is so our old drivers work
600 {
601 sound_enable = offset;
602 }
603
mappy_sound_enable(int enable)604 void mappy_sound_enable(int enable)
605 {
606 sound_enable = enable;
607 }
608
WRITE_HANDLER(namco_15xx_w)609 WRITE_HANDLER( namco_15xx_w )
610 {
611 sound_channel *voice;
612 int ch;
613
614 if (namco_soundregs[offset] == data)
615 return;
616
617 /* update the streams */
618 stream_update(stream, 0);
619
620 /* set the register */
621 namco_soundregs[offset] = data;
622
623 ch = offset / 8;
624 if (ch >= num_voices)
625 return;
626
627 /* recompute the voice parameters */
628 voice = channel_list + ch;
629 switch (offset - ch * 8)
630 {
631 case 0x03:
632 voice->volume[0] = data & 0x0f;
633 break;
634
635 case 0x06:
636 voice->waveform_select = (data >> 4) & 7;
637 case 0x04:
638 case 0x05:
639 /* the frequency has 20 bits */
640 voice->frequency = namco_soundregs[ch * 8 + 0x04];
641 voice->frequency += namco_soundregs[ch * 8 + 0x05] << 8;
642 voice->frequency += (namco_soundregs[ch * 8 + 0x06] & 15) << 16; /* high bits are from here */
643 break;
644 }
645 }
646
647 /********************************************************************************/
648
649 /* namcos1 register map
650 0x00 ch 0 left volume
651 0x01 ch 0 waveform select & frequency
652 0x02-0x03 ch 0 frequency
653 0x04 ch 0 right volume AND
654 0x04 ch 1 noise sw
655
656 0x08 ch 1 left volume
657 0x09 ch 1 waveform select & frequency
658 0x0a-0x0b ch 1 frequency
659 0x0c ch 1 right volume AND
660 0x0c ch 2 noise sw
661
662 .
663 .
664 .
665
666 0x38 ch 7 left volume
667 0x39 ch 7 waveform select & frequency
668 0x3a-0x3b ch 7 frequency
669 0x3c ch 7 right volume AND
670 0x3c ch 0 noise sw
671 */
672
WRITE_HANDLER(namcos1_sound_w)673 WRITE_HANDLER( namcos1_sound_w )
674 {
675 sound_channel *voice;
676 int ch;
677 int nssw;
678
679 /* verify the offset */
680 if (offset > 63)
681 {
682 logerror("NAMCOS1 sound: Attempting to write past the 64 registers segment\n");
683 return;
684 }
685
686 if (namco_soundregs[offset] == data)
687 return;
688
689 /* update the streams */
690 stream_update(stream,0);
691
692 /* set the register */
693 namco_soundregs[offset] = data;
694
695 ch = offset / 8;
696 if (ch >= num_voices)
697 return;
698
699 /* recompute the voice parameters */
700 voice = channel_list + ch;
701 switch (offset - ch * 8)
702 {
703 case 0x00:
704 voice->volume[0] = data & 0x0f;
705 break;
706
707 case 0x01:
708 voice->waveform_select = (data >> 4) & 15;
709 case 0x02:
710 case 0x03:
711 /* the frequency has 20 bits */
712 voice->frequency = (namco_soundregs[ch * 8 + 0x01] & 15) << 16; /* high bits are from here */
713 voice->frequency += namco_soundregs[ch * 8 + 0x02] << 8;
714 voice->frequency += namco_soundregs[ch * 8 + 0x03];
715 break;
716
717 case 0x04:
718 voice->volume[1] = data & 0x0f;
719
720 nssw = ((data & 0x80) >> 7);
721 if (++voice == last_channel)
722 voice = channel_list;
723 voice->noise_sw = nssw;
724 break;
725 }
726 }
727
READ_HANDLER(namcos1_sound_r)728 READ_HANDLER( namcos1_sound_r )
729 {
730 return namco_soundregs[offset];
731 }
732
WRITE_HANDLER(namcos1_wavedata_w)733 WRITE_HANDLER( namcos1_wavedata_w )
734 {
735 if (namco_wavedata[offset] != data)
736 {
737 /* update the streams */
738 stream_update(stream,0);
739
740 namco_wavedata[offset] = data;
741
742 /* update the decoded waveform table */
743 update_namco_waveform(offset, data);
744 }
745 }
746
READ_HANDLER(namcos1_wavedata_r)747 READ_HANDLER( namcos1_wavedata_r )
748 {
749 return namco_wavedata[offset];
750 }
751
752
753 /********************************************************************************/
754
WRITE_HANDLER(snkwave_w)755 WRITE_HANDLER( snkwave_w )
756 {
757 static int freq0 = 0xff;
758 sound_channel *voice = channel_list;
759 if( offset==0 ) freq0 = data;
760 if( offset==1 )
761 {
762 stream_update(stream, 0);
763 if( data==0xff || freq0==0 )
764 {
765 voice->volume[0] = 0x0;
766 }
767 else
768 {
769 voice->volume[0] = 0x8;
770 voice->frequency = (data<<16)/freq0;
771 }
772 }
773 }
774