31
31
0.4 (RB) - major fixes to IRQ semantics and end-of-sample handling.
32
32
0.5 (RB) - more flexible wave memory hookup (incl. banking) and save state support.
33
33
1.0 (RB) - properly respects the input clock
34
2.0 (RB) - C++ conversion, more accurate oscillator IRQ timing
37
38
#include "es5503.h"
48
UINT32 wavetblpointer;
59
ES5503Osc oscillators[32];
63
sound_stream * stream;
65
void (*irq_callback)(device_t *, int); // IRQ callback
67
read8_device_func adc_read; // callback for the 5503's built-in analog to digital converter
69
INT8 oscsenabled; // # of oscillators enabled
71
int rege0; // contents of register 0xe0
78
INLINE ES5503Chip *get_safe_token(device_t *device)
80
assert(device != NULL);
81
assert(device->type() == ES5503);
82
return (ES5503Chip *)downcast<legacy_device_base *>(device)->token();
40
// device type definition
41
const device_type ES5503 = &device_creator<es5503_device>;
85
44
static const UINT16 wavesizes[8] = { 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 };
86
45
static const UINT32 wavemasks[8] = { 0x1ff00, 0x1fe00, 0x1fc00, 0x1f800, 0x1f000, 0x1e000, 0x1c000, 0x18000 };
87
46
static const UINT32 accmasks[8] = { 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff };
88
47
static const int resshifts[8] = { 9, 10, 11, 12, 13, 14, 15, 16 };
49
// default address map
50
static ADDRESS_MAP_START( es5503, AS_0, 8 )
51
AM_RANGE(0x000000, 0x1ffff) AM_ROM
54
//**************************************************************************
56
//**************************************************************************
58
//-------------------------------------------------
59
// es5503_device - constructor
60
//-------------------------------------------------
62
es5503_device::es5503_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
63
: device_t(mconfig, ES5503, "Ensoniq ES5503", tag, owner, clock),
64
device_sound_interface(mconfig, *this),
65
device_memory_interface(mconfig, *this),
66
m_space_config("es5503_samples", ENDIANNESS_LITTLE, 8, 17, 0, NULL, *ADDRESS_MAP_NAME(es5503)),
72
//-------------------------------------------------
73
// memory_space_config - return a description of
74
// any address spaces owned by this device
75
//-------------------------------------------------
77
const address_space_config *es5503_device::memory_space_config(address_spacenum spacenum) const
79
return (spacenum == 0) ? &m_space_config : NULL;
82
//-------------------------------------------------
83
// static_set_type - configuration helper to set
85
//-------------------------------------------------
87
void es5503_device::static_set_irqf(device_t &device, void (*irqf)(device_t *device, int state))
89
es5503_device &es5503 = downcast<es5503_device &>(device);
90
es5503.m_irq_func = irqf;
93
void es5503_device::static_set_adcf(device_t &device, UINT8 (*adcf)(device_t *device))
95
es5503_device &es5503 = downcast<es5503_device &>(device);
96
es5503.m_adc_func = adcf;
99
//-------------------------------------------------
100
// device_timer - called when our device timer expires
101
//-------------------------------------------------
103
void es5503_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
98
108
// halt_osc: handle halting an oscillator
99
109
// chip = chip ptr
100
110
// onum = oscillator #
101
111
// type = 1 for 0 found in sample data, 0 for hit end of table size
102
static void es5503_halt_osc(ES5503Chip *chip, int onum, int type, UINT32 *accumulator)
112
void es5503_device::halt_osc(int onum, int type, UINT32 *accumulator)
104
ES5503Osc *pOsc = &chip->oscillators[onum];
105
ES5503Osc *pPartner = &chip->oscillators[onum^1];
114
ES5503Osc *pOsc = &oscillators[onum];
115
ES5503Osc *pPartner = &oscillators[onum^1];
106
116
int mode = (pOsc->control>>1) & 3;
108
118
// if 0 found in sample data or mode is not free-run, halt this oscillator
129
139
pOsc->irqpend = 1;
131
if (chip->irq_callback)
133
chip->irq_callback(chip->device, 1);
138
static TIMER_CALLBACK( es5503_timer_cb )
140
ES5503Osc *osc = (ES5503Osc *)ptr;
141
ES5503Chip *chip = (ES5503Chip *)osc->chip;
143
chip->stream->update();
146
static STREAM_UPDATE( es5503_pcm_update )
148
void es5503_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
150
static INT32 mix[(44100/60)*4];
150
152
int osc, snum, i;
152
ES5503Chip *chip = (ES5503Chip *)param;
155
assert(samples < (44100/60)*2);
154
156
memset(mix, 0, sizeof(mix));
156
for (osc = 0; osc < (chip->oscsenabled+1); osc++)
158
for (osc = 0; osc < (oscsenabled+1); osc++)
158
ES5503Osc *pOsc = &chip->oscillators[osc];
160
ES5503Osc *pOsc = &oscillators[osc];
229
static DEVICE_START( es5503 )
233
void es5503_device::device_start()
231
const es5503_interface *intf;
233
ES5503Chip *chip = get_safe_token(device);
235
intf = (const es5503_interface *)device->static_config();
237
chip->irq_callback = intf->irq_callback;
238
chip->adc_read = intf->adc_read;
239
chip->docram = intf->wave_memory;
240
chip->clock = device->clock();
241
chip->device = device;
237
// find our direct access
238
m_direct = &space()->direct();
245
242
for (osc = 0; osc < 32; osc++)
247
device->save_item(NAME(chip->oscillators[osc].freq), osc);
248
device->save_item(NAME(chip->oscillators[osc].wtsize), osc);
249
device->save_item(NAME(chip->oscillators[osc].control), osc);
250
device->save_item(NAME(chip->oscillators[osc].vol), osc);
251
device->save_item(NAME(chip->oscillators[osc].data), osc);
252
device->save_item(NAME(chip->oscillators[osc].wavetblpointer), osc);
253
device->save_item(NAME(chip->oscillators[osc].wavetblsize), osc);
254
device->save_item(NAME(chip->oscillators[osc].resolution), osc);
255
device->save_item(NAME(chip->oscillators[osc].accumulator), osc);
256
device->save_item(NAME(chip->oscillators[osc].irqpend), osc);
258
chip->oscillators[osc].data = 0x80;
259
chip->oscillators[osc].irqpend = 0;
260
chip->oscillators[osc].accumulator = 0;
262
chip->oscillators[osc].timer = device->machine().scheduler().timer_alloc(FUNC(es5503_timer_cb), &chip->oscillators[osc]);
263
chip->oscillators[osc].chip = (void *)chip;
266
chip->oscsenabled = 1;
268
chip->output_rate = (device->clock()/8)/34; // (input clock / 8) / # of oscs. enabled + 2
269
chip->stream = device->machine().sound().stream_alloc(*device, 0, 2, chip->output_rate, chip, es5503_pcm_update);
272
READ8_DEVICE_HANDLER( es5503_r )
244
save_item(NAME(oscillators[osc].freq), osc);
245
save_item(NAME(oscillators[osc].wtsize), osc);
246
save_item(NAME(oscillators[osc].control), osc);
247
save_item(NAME(oscillators[osc].vol), osc);
248
save_item(NAME(oscillators[osc].data), osc);
249
save_item(NAME(oscillators[osc].wavetblpointer), osc);
250
save_item(NAME(oscillators[osc].wavetblsize), osc);
251
save_item(NAME(oscillators[osc].resolution), osc);
252
save_item(NAME(oscillators[osc].accumulator), osc);
253
save_item(NAME(oscillators[osc].irqpend), osc);
256
output_rate = (clock()/8)/34; // (input clock / 8) / # of oscs. enabled + 2
257
m_stream = machine().sound().stream_alloc(*this, 0, 2, output_rate, this);
259
m_timer = timer_alloc(0, NULL);
260
m_timer->adjust(attotime::from_hz(output_rate));
263
void es5503_device::device_reset()
267
for (int osc = 0; osc < 32; osc++)
269
oscillators[osc].data = 0x80;
270
oscillators[osc].irqpend = 0;
271
oscillators[osc].accumulator = 0;
276
m_channel_strobe = 0;
278
output_rate = (clock()/8)/34; // (input clock / 8) / # of oscs. enabled + 2
281
READ8_MEMBER( es5503_device::read )
276
ES5503Chip *chip = get_safe_token(device);
278
chip->stream->update();
280
288
if (offset < 0xe0)
284
292
switch(offset & 0xe0)
286
294
case 0: // freq lo
287
return (chip->oscillators[osc].freq & 0xff);
295
return (oscillators[osc].freq & 0xff);
289
297
case 0x20: // freq hi
290
return (chip->oscillators[osc].freq >> 8);
298
return (oscillators[osc].freq >> 8);
292
300
case 0x40: // volume
293
return chip->oscillators[osc].vol;
301
return oscillators[osc].vol;
295
303
case 0x60: // data
296
return chip->oscillators[osc].data;
304
return oscillators[osc].data;
298
306
case 0x80: // wavetable pointer
299
return (chip->oscillators[osc].wavetblpointer>>8) & 0xff;
307
return (oscillators[osc].wavetblpointer>>8) & 0xff;
301
309
case 0xa0: // oscillator control
302
return chip->oscillators[osc].control;
310
return oscillators[osc].control;
304
312
case 0xc0: // bank select / wavetable size / resolution
306
if (chip->oscillators[osc].wavetblpointer & 0x10000)
314
if (oscillators[osc].wavetblpointer & 0x10000)
311
retval |= (chip->oscillators[osc].wavetblsize<<3);
312
retval |= chip->oscillators[osc].resolution;
319
retval |= (oscillators[osc].wavetblsize<<3);
320
retval |= oscillators[osc].resolution;
320
328
case 0xe0: // interrupt status
321
retval = chip->rege0;
323
331
// scan all oscillators
324
for (i = 0; i < chip->oscsenabled+1; i++)
332
for (i = 0; i < oscsenabled+1; i++)
326
if (chip->oscillators[i].irqpend)
334
if (oscillators[i].irqpend)
328
336
// signal this oscillator has an interrupt
331
chip->rege0 = retval | 0x80;
339
rege0 = retval | 0x80;
333
341
// and clear its flag
334
chip->oscillators[i].irqpend--;
342
oscillators[i].irqpend--;
336
if (chip->irq_callback)
338
chip->irq_callback(chip->device, 0);
344
352
// if any oscillators still need to be serviced, assert IRQ again immediately
345
for (i = 0; i < chip->oscsenabled+1; i++)
353
for (i = 0; i < oscsenabled+1; i++)
347
if (chip->oscillators[i].irqpend)
355
if (oscillators[i].irqpend)
349
if (chip->irq_callback)
351
chip->irq_callback(chip->device, 1);
384
390
switch(offset & 0xe0)
386
392
case 0: // freq lo
387
chip->oscillators[osc].freq &= 0xff00;
388
chip->oscillators[osc].freq |= data;
393
oscillators[osc].freq &= 0xff00;
394
oscillators[osc].freq |= data;
391
397
case 0x20: // freq hi
392
chip->oscillators[osc].freq &= 0x00ff;
393
chip->oscillators[osc].freq |= (data<<8);
398
oscillators[osc].freq &= 0x00ff;
399
oscillators[osc].freq |= (data<<8);
396
402
case 0x40: // volume
397
chip->oscillators[osc].vol = data;
403
oscillators[osc].vol = data;
400
406
case 0x60: // data - ignore writes
403
409
case 0x80: // wavetable pointer
404
chip->oscillators[osc].wavetblpointer = (data<<8);
410
oscillators[osc].wavetblpointer = (data<<8);
407
413
case 0xa0: // oscillator control
408
414
// if a fresh key-on, reset the ccumulator
409
if ((chip->oscillators[osc].control & 1) && (!(data&1)))
411
chip->oscillators[osc].accumulator = 0;
413
// if this voice generates interrupts, set a timer to make sure we service it on time
414
if (((data & 0x09) == 0x08) && (chip->oscillators[osc].freq > 0))
417
UINT32 wtptr = chip->oscillators[osc].wavetblpointer & wavemasks[chip->oscillators[osc].wavetblsize];
419
UINT16 wtsize = chip->oscillators[osc].wtsize-1;
420
UINT16 freq = chip->oscillators[osc].freq;
422
int resshift = resshifts[chip->oscillators[osc].resolution] - chip->oscillators[osc].wavetblsize;
423
UINT32 sizemask = accmasks[chip->oscillators[osc].wavetblsize];
424
UINT32 ramptr, altram;
431
ramptr = (acc >> resshift) & sizemask;
432
altram = (acc >> resshift);
434
data = (INT32)chip->docram[ramptr + wtptr];
436
if ((data == 0) || (altram >= wtsize))
446
// ok, we run for this long
447
period = attotime::from_hz(chip->output_rate) * length;
449
chip->oscillators[osc].timer->adjust(period, 0, period);
452
else if (!(chip->oscillators[osc].control & 1) && (data&1))
455
chip->oscillators[osc].timer->adjust(attotime::never);
458
chip->oscillators[osc].control = data;
415
if ((oscillators[osc].control & 1) && (!(data&1)))
417
oscillators[osc].accumulator = 0;
420
oscillators[osc].control = data;
461
423
case 0xc0: // bank select / wavetable size / resolution
462
424
if (data & 0x40) // bank select - not used on the Apple IIgs
464
chip->oscillators[osc].wavetblpointer |= 0x10000;
426
oscillators[osc].wavetblpointer |= 0x10000;
468
chip->oscillators[osc].wavetblpointer &= 0xffff;
430
oscillators[osc].wavetblpointer &= 0xffff;
471
chip->oscillators[osc].wavetblsize = ((data>>3) & 7);
472
chip->oscillators[osc].wtsize = wavesizes[chip->oscillators[osc].wavetblsize];
473
chip->oscillators[osc].resolution = (data & 7);
433
oscillators[osc].wavetblsize = ((data>>3) & 7);
434
oscillators[osc].wtsize = wavesizes[oscillators[osc].wavetblsize];
435
oscillators[osc].resolution = (data & 7);
497
void es5503_set_base(device_t *device, UINT8 *wavemem)
499
ES5503Chip *chip = get_safe_token(device);
501
chip->docram = wavemem;
504
/**************************************************************************
506
**************************************************************************/
508
DEVICE_GET_INFO( es5503 )
512
/* --- the following bits of info are returned as 64-bit signed integers --- */
513
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ES5503Chip); break;
515
/* --- the following bits of info are returned as pointers to data or functions --- */
516
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( es5503 ); break;
517
case DEVINFO_FCT_STOP: /* Nothing */ break;
518
case DEVINFO_FCT_RESET: /* Nothing */ break;
520
/* --- the following bits of info are returned as NULL-terminated strings --- */
521
case DEVINFO_STR_NAME: strcpy(info->s, "ES5503"); break;
522
case DEVINFO_STR_FAMILY: strcpy(info->s, "Ensoniq ES550x"); break;
523
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
524
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
525
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright R. Belmont"); break;
530
DEFINE_LEGACY_SOUND_DEVICE(ES5503, es5503);