1 /*
2
3 ES5503 - Ensoniq ES5503 "DOC" emulator v2.1.1
4 By R. Belmont.
5
6 Copyright R. Belmont.
7
8 This software is dual-licensed: it may be used in MAME and properly licensed
9 MAME derivatives under the terms of the MAME license. For use outside of
10 MAME and properly licensed derivatives, it is available under the
11 terms of the GNU Lesser General Public License (LGPL), version 2.1.
12 You may read the LGPL at http://www.gnu.org/licenses/lgpl.html
13
14 History: the ES5503 was the next design after the famous C64 "SID" by Bob Yannes.
15 It powered the legendary Mirage sampler (the first affordable pro sampler) as well
16 as the ESQ-1 synth/sequencer. The ES5505 (used in Taito's F3 System) and 5506
17 (used in the "Soundscape" series of ISA PC sound cards) followed on a fundamentally
18 similar architecture.
19
20 Bugs: On the real silicon, oscillators 30 and 31 have random volume fluctuations and are
21 unusable for playback. We don't attempt to emulate that. :-)
22
23 Additionally, in "swap" mode, there's one cycle when the switch takes place where the
24 oscillator's output is 0x80 (centerline) regardless of the sample data. This can
25 cause audible clicks and a general degradation of audio quality if the correct sample
26 data at that point isn't 0x80 or very near it.
27
28 Changes:
29 0.2 (RB) - improved behavior for volumes > 127, fixes missing notes in Nucleus & missing voices in Thexder
30 0.3 (RB) - fixed extraneous clicking, improved timing behavior for e.g. Music Construction Set & Music Studio
31 0.4 (RB) - major fixes to IRQ semantics and end-of-sample handling.
32 0.5 (RB) - more flexible wave memory hookup (incl. banking) and save state support.
33 1.0 (RB) - properly respects the input clock
34 2.0 (RB) - C++ conversion, more accurate oscillator IRQ timing
35 2.1 (RB) - Corrected phase when looping; synthLAB, Arkanoid, and Arkanoid II no longer go out of tune
36 2.1.1 (RB) - Fixed issue introduced in 2.0 where IRQs were delayed
37 */
38
39 //#include "emu.h"
40 //#include "streams.h"
41 #include <stdlib.h>
42 #include <string.h>
43 #include "mamedef.h"
44 #include "es5503.h"
45
46 typedef struct
47 {
48 UINT16 freq;
49 UINT16 wtsize;
50 UINT8 control;
51 UINT8 vol;
52 UINT8 data;
53 UINT32 wavetblpointer;
54 UINT8 wavetblsize;
55 UINT8 resolution;
56
57 UINT32 accumulator;
58 UINT8 irqpend;
59
60 UINT8 Muted;
61 } ES5503Osc;
62
63 typedef struct
64 {
65 ES5503Osc oscillators[32];
66
67 UINT32 dramsize;
68 UINT8 *docram;
69
70 //sound_stream * stream;
71
72 //void (*irq_callback)(running_device *, int); // IRQ callback
73
74 //read8_device_func adc_read; // callback for the 5503's built-in analog to digital converter
75
76 INT8 oscsenabled; // # of oscillators enabled
77 int rege0; // contents of register 0xe0
78
79 UINT8 channel_strobe;
80
81 UINT32 clock;
82 int output_channels;
83 int outchn_mask;
84 UINT32 output_rate;
85 //running_device *device;
86
87 SRATE_CALLBACK SmpRateFunc;
88 void* SmpRateData;
89 } ES5503Chip;
90
91 #define MAX_CHIPS 0x02
92 static ES5503Chip ES5503Data[MAX_CHIPS];
93
94 /*INLINE ES5503Chip *get_safe_token(running_device *device)
95 {
96 assert(device != NULL);
97 assert(device->type() == ES5503);
98 return (ES5503Chip *)downcast<legacy_device_base *>(device)->token();
99 }*/
100
101 static const UINT16 wavesizes[8] = { 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 };
102 static const UINT32 wavemasks[8] = { 0x1ff00, 0x1fe00, 0x1fc00, 0x1f800, 0x1f000, 0x1e000, 0x1c000, 0x18000 };
103 static const UINT32 accmasks[8] = { 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff };
104 static const int resshifts[8] = { 9, 10, 11, 12, 13, 14, 15, 16 };
105
106 enum
107 {
108 MODE_FREE = 0,
109 MODE_ONESHOT = 1,
110 MODE_SYNCAM = 2,
111 MODE_SWAP = 3
112 };
113
114 // halt_osc: handle halting an oscillator
115 // chip = chip ptr
116 // onum = oscillator #
117 // type = 1 for 0 found in sample data, 0 for hit end of table size
es5503_halt_osc(ES5503Chip * chip,int onum,int type,UINT32 * accumulator,int resshift)118 static void es5503_halt_osc(ES5503Chip *chip, int onum, int type, UINT32 *accumulator, int resshift)
119 {
120 ES5503Osc *pOsc = &chip->oscillators[onum];
121 ES5503Osc *pPartner = &chip->oscillators[onum^1];
122 int mode = (pOsc->control>>1) & 3;
123 int omode = (pPartner->control>>1) & 3;
124
125 // if 0 found in sample data or mode is not free-run, halt this oscillator
126 if ((mode != MODE_FREE) || (type != 0))
127 {
128 pOsc->control |= 1;
129 }
130 else // preserve the relative phase of the oscillator when looping
131 {
132 UINT16 wtsize = pOsc->wtsize - 1;
133 UINT32 altram = (*accumulator) >> resshift;
134
135 if (altram > wtsize)
136 {
137 altram -= wtsize;
138 }
139 else
140 {
141 altram = 0;
142 }
143
144 *accumulator = altram << resshift;
145 }
146
147 // if swap mode, start the partner
148 // Note: The swap mode fix breaks Silpheed and other games.
149 if ((mode == MODE_SWAP) /*|| (omode == MODE_SWAP)*/)
150 {
151 pPartner->control &= ~1; // clear the halt bit
152 pPartner->accumulator = 0; // and make sure it starts from the top (does this also need phase preservation?)
153 }
154
155 // IRQ enabled for this voice?
156 if (pOsc->control & 0x08)
157 {
158 pOsc->irqpend = 1;
159
160 /*if (chip->irq_callback)
161 {
162 chip->irq_callback(chip->device, 1);
163 }*/
164 }
165 }
166
167 //static STREAM_UPDATE( es5503_pcm_update )
es5503_pcm_update(UINT8 ChipID,stream_sample_t ** outputs,int samples)168 void es5503_pcm_update(UINT8 ChipID, stream_sample_t **outputs, int samples)
169 {
170 // Note: The advantage of NOT using this buffer is not only less RAM usage,
171 // but also a huge speedup. This is, because the array is not marked
172 // as 'static' and thus re-allocated for every single call.
173 //INT32 mix[48000*2];
174 //INT32 *mixp;
175 int osc, snum;
176 UINT32 ramptr;
177 //ES5503Chip *chip = (ES5503Chip *)param;
178 ES5503Chip *chip = &ES5503Data[ChipID];
179 int chnsStereo, chan;
180
181 memset(outputs[0], 0x00, samples * sizeof(stream_sample_t));
182 memset(outputs[1], 0x00, samples * sizeof(stream_sample_t));
183 //memset(mix, 0, sizeof(mix));
184
185 chnsStereo = chip->output_channels & ~1;
186 for (osc = 0; osc < chip->oscsenabled; osc++)
187 {
188 ES5503Osc *pOsc = &chip->oscillators[osc];
189
190 if (!(pOsc->control & 1) && ! pOsc->Muted)
191 {
192 UINT32 wtptr = pOsc->wavetblpointer & wavemasks[pOsc->wavetblsize], altram;
193 UINT32 acc = pOsc->accumulator;
194 UINT16 wtsize = pOsc->wtsize - 1;
195 //UINT8 ctrl = pOsc->control;
196 UINT16 freq = pOsc->freq;
197 INT16 vol = pOsc->vol;
198 //INT8 data = -128;
199 UINT8 chnMask = (pOsc->control >> 4) & 0x0F;
200 int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize;
201 UINT32 sizemask = accmasks[pOsc->wavetblsize];
202 INT32 outData;
203 //mixp = &mix[0] + chan;
204
205 chnMask &= chip->outchn_mask;
206 for (snum = 0; snum < samples; snum++)
207 {
208 altram = acc >> resshift;
209 ramptr = altram & sizemask;
210
211 acc += freq;
212
213 // channel strobe is always valid when reading; this allows potentially banking per voice
214 //chip->channel_strobe = (pOsc->control>>4) & 0xf;
215 //data = (INT32)chip->docram[ramptr + wtptr] ^ 0x80;
216 pOsc->data = chip->docram[ramptr + wtptr];
217
218 if (pOsc->data == 0x00)
219 {
220 es5503_halt_osc(chip, osc, 1, &acc, resshift);
221 }
222 else
223 {
224 outData = (pOsc->data - 0x80) * vol;
225 //*mixp += outData;
226 //mixp += output_channels;
227
228 // send groups of 2 channels to L or R
229 for (chan = 0; chan < chnsStereo; chan ++)
230 {
231 if (chan == chnMask)
232 outputs[chan & 1][snum] += outData;
233 }
234 outData = (outData * 181) >> 8; // outData *= sqrt(2)
235 // send remaining channels to L+R
236 for (; chan < chip->output_channels; chan ++)
237 {
238 if (chan == chnMask)
239 {
240 outputs[0][snum] += outData;
241 outputs[1][snum] += outData;
242 }
243 }
244
245 if (altram >= wtsize)
246 {
247 es5503_halt_osc(chip, osc, 0, &acc, resshift);
248 }
249 }
250
251 // if oscillator halted, we've got no more samples to generate
252 if (pOsc->control & 1)
253 {
254 //pOsc->control |= 1;
255 break;
256 }
257 }
258
259 //pOsc->control = ctrl;
260 pOsc->accumulator = acc;
261 //pOsc->data = data ^ 0x80;
262 }
263 }
264
265 /* mixp = &mix[0];
266 for (i = 0; i < samples; i++)
267 for (int chan = 0; chan < output_channels; chan++)
268 outputs[chan][i] = (*mixp++)>>1;*/
269 }
270
271
272 //static DEVICE_START( es5503 )
device_start_es5503(UINT8 ChipID,int clock,int channels)273 int device_start_es5503(UINT8 ChipID, int clock, int channels)
274 {
275 //const es5503_interface *intf;
276 int osc;
277 //ES5503Chip *chip = get_safe_token(device);
278 ES5503Chip *chip;
279
280 if (ChipID >= MAX_CHIPS)
281 return 0;
282
283 chip = &ES5503Data[ChipID];
284
285 //intf = (const es5503_interface *)device->baseconfig().static_config();
286
287 //chip->irq_callback = intf->irq_callback;
288 //chip->adc_read = intf->adc_read;
289 //chip->docram = intf->wave_memory;
290 chip->dramsize = 0x20000; // 128 KB
291 chip->docram = (UINT8*)malloc(chip->dramsize);
292 //chip->clock = device->clock();
293 //chip->device = device;
294 chip->clock = clock;
295
296 chip->output_channels = channels;
297 chip->outchn_mask = 1;
298 while(chip->outchn_mask < chip->output_channels)
299 chip->outchn_mask <<= 1;
300 chip->outchn_mask --;
301 chip->rege0 = 0xff;
302
303 /*for (osc = 0; osc < 32; osc++)
304 {
305 state_save_register_device_item(device, osc, chip->oscillators[osc].freq);
306 state_save_register_device_item(device, osc, chip->oscillators[osc].wtsize);
307 state_save_register_device_item(device, osc, chip->oscillators[osc].control);
308 state_save_register_device_item(device, osc, chip->oscillators[osc].vol);
309 state_save_register_device_item(device, osc, chip->oscillators[osc].data);
310 state_save_register_device_item(device, osc, chip->oscillators[osc].wavetblpointer);
311 state_save_register_device_item(device, osc, chip->oscillators[osc].wavetblsize);
312 state_save_register_device_item(device, osc, chip->oscillators[osc].resolution);
313 state_save_register_device_item(device, osc, chip->oscillators[osc].accumulator);
314 state_save_register_device_item(device, osc, chip->oscillators[osc].irqpend);
315 }*/
316
317 //chip->output_rate = (device->clock()/8)/34; // (input clock / 8) / # of oscs. enabled + 2
318 //chip->stream = stream_create(device, 0, 2, chip->output_rate, chip, es5503_pcm_update);
319 chip->output_rate = (chip->clock/8)/34; // (input clock / 8) / # of oscs. enabled + 2
320
321 for (osc = 0; osc < 32; osc ++)
322 chip->oscillators[osc].Muted = 0x00;
323
324 return chip->output_rate;
325 }
326
device_stop_es5503(UINT8 ChipID)327 void device_stop_es5503(UINT8 ChipID)
328 {
329 ES5503Chip *chip = &ES5503Data[ChipID];
330
331 free(chip->docram); chip->docram = NULL;
332
333 return;
334 }
335
device_reset_es5503(UINT8 ChipID)336 void device_reset_es5503(UINT8 ChipID)
337 {
338 ES5503Chip *chip = &ES5503Data[ChipID];
339 int osc;
340 ES5503Osc* tempOsc;
341
342 for (osc = 0; osc < 32; osc++)
343 {
344 tempOsc = &chip->oscillators[osc];
345 tempOsc->freq = 0;
346 tempOsc->wtsize = 0;
347 tempOsc->control = 0;
348 tempOsc->vol = 0;
349 tempOsc->data = 0x80;
350 tempOsc->wavetblpointer = 0;
351 tempOsc->wavetblsize = 0;
352 tempOsc->resolution = 0;
353 tempOsc->accumulator = 0;
354 tempOsc->irqpend = 0;
355 }
356
357 chip->oscsenabled = 1;
358
359 chip->channel_strobe = 0;
360 memset(chip->docram, 0x00, chip->dramsize);
361
362 chip->output_rate = (chip->clock/8)/(2+chip->oscsenabled); // (input clock / 8) / # of oscs. enabled + 2
363 if (chip->SmpRateFunc != NULL)
364 chip->SmpRateFunc(chip->SmpRateData, chip->output_rate);
365
366 return;
367 }
368
369
370 //READ8_DEVICE_HANDLER( es5503_r )
es5503_r(UINT8 ChipID,offs_t offset)371 UINT8 es5503_r(UINT8 ChipID, offs_t offset)
372 {
373 UINT8 retval;
374 int i;
375 //ES5503Chip *chip = get_safe_token(device);
376 ES5503Chip *chip = &ES5503Data[ChipID];
377
378 //stream_update(chip->stream);
379
380 if (offset < 0xe0)
381 {
382 int osc = offset & 0x1f;
383
384 switch(offset & 0xe0)
385 {
386 case 0: // freq lo
387 return (chip->oscillators[osc].freq & 0xff);
388
389 case 0x20: // freq hi
390 return (chip->oscillators[osc].freq >> 8);
391
392 case 0x40: // volume
393 return chip->oscillators[osc].vol;
394
395 case 0x60: // data
396 return chip->oscillators[osc].data;
397
398 case 0x80: // wavetable pointer
399 return (chip->oscillators[osc].wavetblpointer>>8) & 0xff;
400
401 case 0xa0: // oscillator control
402 return chip->oscillators[osc].control;
403
404 case 0xc0: // bank select / wavetable size / resolution
405 retval = 0;
406 if (chip->oscillators[osc].wavetblpointer & 0x10000)
407 {
408 retval |= 0x40;
409 }
410
411 retval |= (chip->oscillators[osc].wavetblsize<<3);
412 retval |= chip->oscillators[osc].resolution;
413 return retval;
414 }
415 }
416 else // global registers
417 {
418 switch (offset)
419 {
420 case 0xe0: // interrupt status
421 retval = chip->rege0;
422
423 //m_irq_func(0);
424
425 // scan all oscillators
426 for (i = 0; i < chip->oscsenabled; i++)
427 {
428 if (chip->oscillators[i].irqpend)
429 {
430 // signal this oscillator has an interrupt
431 retval = i<<1;
432
433 chip->rege0 = retval | 0x80;
434
435 // and clear its flag
436 chip->oscillators[i].irqpend = 0;
437
438 /*if (chip->irq_callback)
439 {
440 chip->irq_callback(chip->device, 0);
441 }*/
442 break;
443 }
444 }
445
446 // if any oscillators still need to be serviced, assert IRQ again immediately
447 /*for (i = 0; i < chip->oscsenabled; i++)
448 {
449 if (chip->oscillators[i].irqpend)
450 {
451 if (chip->irq_callback)
452 {
453 chip->irq_callback(chip->device, 1);
454 }
455 break;
456 }
457 }*/
458
459 return retval;
460
461 case 0xe1: // oscillator enable
462 return (chip->oscsenabled-1)<<1;
463
464 case 0xe2: // A/D converter
465 /*if (chip->adc_read)
466 {
467 return chip->adc_read(chip->device, 0);
468 }*/
469 break;
470 }
471 }
472
473 return 0;
474 }
475
476 //WRITE8_DEVICE_HANDLER( es5503_w )
es5503_w(UINT8 ChipID,offs_t offset,UINT8 data)477 void es5503_w(UINT8 ChipID, offs_t offset, UINT8 data)
478 {
479 //ES5503Chip *chip = get_safe_token(device);
480 ES5503Chip *chip = &ES5503Data[ChipID];
481
482 //stream_update(chip->stream);
483
484 if (offset < 0xe0)
485 {
486 int osc = offset & 0x1f;
487
488 switch(offset & 0xe0)
489 {
490 case 0: // freq lo
491 chip->oscillators[osc].freq &= 0xff00;
492 chip->oscillators[osc].freq |= data;
493 break;
494
495 case 0x20: // freq hi
496 chip->oscillators[osc].freq &= 0x00ff;
497 chip->oscillators[osc].freq |= (data<<8);
498 break;
499
500 case 0x40: // volume
501 chip->oscillators[osc].vol = data;
502 break;
503
504 case 0x60: // data - ignore writes
505 break;
506
507 case 0x80: // wavetable pointer
508 chip->oscillators[osc].wavetblpointer = (data<<8);
509 break;
510
511 case 0xa0: // oscillator control
512 // if a fresh key-on, reset the ccumulator
513 if ((chip->oscillators[osc].control & 1) && (!(data&1)))
514 {
515 chip->oscillators[osc].accumulator = 0;
516 }
517
518 chip->oscillators[osc].control = data;
519 break;
520
521 case 0xc0: // bank select / wavetable size / resolution
522 if (data & 0x40) // bank select - not used on the Apple IIgs
523 {
524 chip->oscillators[osc].wavetblpointer |= 0x10000;
525 }
526 else
527 {
528 chip->oscillators[osc].wavetblpointer &= 0xffff;
529 }
530
531 chip->oscillators[osc].wavetblsize = ((data>>3) & 7);
532 chip->oscillators[osc].wtsize = wavesizes[chip->oscillators[osc].wavetblsize];
533 chip->oscillators[osc].resolution = (data & 7);
534 break;
535 }
536 }
537 else // global registers
538 {
539 switch (offset)
540 {
541 case 0xe0: // interrupt status
542 break;
543
544 case 0xe1: // oscillator enable
545 chip->oscsenabled = 1 + ((data>>1) & 0x1f);
546
547 chip->output_rate = (chip->clock/8)/(2+chip->oscsenabled);
548 //stream_set_sample_rate(chip->stream, chip->output_rate);
549 if (chip->SmpRateFunc != NULL)
550 chip->SmpRateFunc(chip->SmpRateData, chip->output_rate);
551 break;
552
553 case 0xe2: // A/D converter
554 break;
555 }
556 }
557 }
558
559 /*void es5503_set_base(running_device *device, UINT8 *wavemem)
560 {
561 ES5503Chip *chip = get_safe_token(device);
562
563 chip->docram = wavemem;
564 }*/
565
es5503_write_ram(UINT8 ChipID,offs_t DataStart,offs_t DataLength,const UINT8 * RAMData)566 void es5503_write_ram(UINT8 ChipID, offs_t DataStart, offs_t DataLength, const UINT8* RAMData)
567 {
568 ES5503Chip *chip = &ES5503Data[ChipID];
569
570 if (DataStart >= chip->dramsize)
571 return;
572 if (DataStart + DataLength > chip->dramsize)
573 DataLength = chip->dramsize - DataStart;
574
575 memcpy(chip->docram + DataStart, RAMData, DataLength);
576
577 return;
578 }
579
es5503_set_mute_mask(UINT8 ChipID,UINT32 MuteMask)580 void es5503_set_mute_mask(UINT8 ChipID, UINT32 MuteMask)
581 {
582 ES5503Chip *chip = &ES5503Data[ChipID];
583 UINT8 CurChn;
584
585 for (CurChn = 0; CurChn < 32; CurChn ++)
586 chip->oscillators[CurChn].Muted = (MuteMask >> CurChn) & 0x01;
587
588 return;
589 }
590
es5503_set_srchg_cb(UINT8 ChipID,SRATE_CALLBACK CallbackFunc,void * DataPtr)591 void es5503_set_srchg_cb(UINT8 ChipID, SRATE_CALLBACK CallbackFunc, void* DataPtr)
592 {
593 ES5503Chip *chip = &ES5503Data[ChipID];
594
595 // set Sample Rate Change Callback routine
596 chip->SmpRateFunc = CallbackFunc;
597 chip->SmpRateData = DataPtr;
598
599 return;
600 }
601
602 /**************************************************************************
603 * Generic get_info
604 **************************************************************************/
605
606 /*DEVICE_GET_INFO( es5503 )
607 {
608 switch (state)
609 {
610 // --- the following bits of info are returned as 64-bit signed integers ---
611 case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ES5503Chip); break;
612
613 // --- the following bits of info are returned as pointers to data or functions --- //
614 case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( es5503 ); break;
615 case DEVINFO_FCT_STOP: // Nothing // break;
616 case DEVINFO_FCT_RESET: // Nothing // break;
617
618 // --- the following bits of info are returned as NULL-terminated strings ---
619 case DEVINFO_STR_NAME: strcpy(info->s, "ES5503"); break;
620 case DEVINFO_STR_FAMILY: strcpy(info->s, "Ensoniq ES550x"); break;
621 case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
622 case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
623 case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright R. Belmont"); break;
624 }
625 }
626
627
628 DEFINE_LEGACY_SOUND_DEVICE(ES5503, es5503);*/
629