mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
es5503: Make the number of output channels configurable [O. Galibert]
This commit is contained in:
parent
592df02da8
commit
bcbec121dc
@ -86,6 +86,12 @@ const address_space_config *es5503_device::memory_space_config(address_spacenum
|
||||
// the IRQ callback
|
||||
//-------------------------------------------------
|
||||
|
||||
void es5503_device::static_set_channels(device_t &device, int channels)
|
||||
{
|
||||
es5503_device &es5503 = downcast<es5503_device &>(device);
|
||||
es5503.output_channels = channels;
|
||||
}
|
||||
|
||||
void es5503_device::static_set_irqf(device_t &device, void (*irqf)(device_t *device, int state))
|
||||
{
|
||||
es5503_device &es5503 = downcast<es5503_device &>(device);
|
||||
@ -160,7 +166,7 @@ void es5503_device::halt_osc(int onum, int type, UINT32 *accumulator, int resshi
|
||||
|
||||
void es5503_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
static INT32 mix[(44100/60)*4];
|
||||
static INT32 mix[(44100/60)*2*8];
|
||||
INT32 *mixp;
|
||||
int osc, snum, i;
|
||||
UINT32 ramptr;
|
||||
@ -168,78 +174,70 @@ void es5503_device::sound_stream_update(sound_stream &stream, stream_sample_t **
|
||||
assert(samples < (44100/60)*2);
|
||||
memset(mix, 0, sizeof(mix));
|
||||
|
||||
for (osc = 0; osc < (oscsenabled+1); osc++)
|
||||
for (int chan = 0; chan < output_channels; chan++)
|
||||
{
|
||||
ES5503Osc *pOsc = &oscillators[osc];
|
||||
|
||||
mixp = &mix[0];
|
||||
|
||||
if (!(pOsc->control & 1))
|
||||
for (osc = 0; osc < (oscsenabled+1); osc++)
|
||||
{
|
||||
UINT32 wtptr = pOsc->wavetblpointer & wavemasks[pOsc->wavetblsize], altram;
|
||||
UINT32 acc = pOsc->accumulator;
|
||||
UINT16 wtsize = pOsc->wtsize - 1;
|
||||
UINT8 ctrl = pOsc->control;
|
||||
UINT16 freq = pOsc->freq;
|
||||
INT16 vol = pOsc->vol;
|
||||
INT8 data = -128;
|
||||
int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize;
|
||||
UINT32 sizemask = accmasks[pOsc->wavetblsize];
|
||||
ES5503Osc *pOsc = &oscillators[osc];
|
||||
|
||||
for (snum = 0; snum < samples; snum++)
|
||||
if (!(pOsc->control & 1) && ((pOsc->control >> 4) & (output_channels - 1)) == chan)
|
||||
{
|
||||
altram = acc >> resshift;
|
||||
ramptr = altram & sizemask;
|
||||
UINT32 wtptr = pOsc->wavetblpointer & wavemasks[pOsc->wavetblsize], altram;
|
||||
UINT32 acc = pOsc->accumulator;
|
||||
UINT16 wtsize = pOsc->wtsize - 1;
|
||||
UINT8 ctrl = pOsc->control;
|
||||
UINT16 freq = pOsc->freq;
|
||||
INT16 vol = pOsc->vol;
|
||||
INT8 data = -128;
|
||||
int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize;
|
||||
UINT32 sizemask = accmasks[pOsc->wavetblsize];
|
||||
mixp = &mix[0] + chan;
|
||||
|
||||
acc += freq;
|
||||
|
||||
// channel strobe is always valid when reading; this allows potentially banking per voice
|
||||
m_channel_strobe = (ctrl>>4) & 0xf;
|
||||
data = (INT32)m_direct->read_raw_byte(ramptr + wtptr) ^ 0x80;
|
||||
|
||||
if (m_direct->read_raw_byte(ramptr + wtptr) == 0x00)
|
||||
for (snum = 0; snum < samples; snum++)
|
||||
{
|
||||
halt_osc(osc, 1, &acc, resshift);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pOsc->control & 0x10)
|
||||
altram = acc >> resshift;
|
||||
ramptr = altram & sizemask;
|
||||
|
||||
acc += freq;
|
||||
|
||||
// channel strobe is always valid when reading; this allows potentially banking per voice
|
||||
m_channel_strobe = (ctrl>>4) & 0xf;
|
||||
data = (INT32)m_direct->read_raw_byte(ramptr + wtptr) ^ 0x80;
|
||||
|
||||
if (m_direct->read_raw_byte(ramptr + wtptr) == 0x00)
|
||||
{
|
||||
*mixp++ += (data * vol);
|
||||
mixp++;
|
||||
halt_osc(osc, 1, &acc, resshift);
|
||||
}
|
||||
else
|
||||
{
|
||||
mixp++;
|
||||
*mixp++ += (data * vol);
|
||||
*mixp += data * vol;
|
||||
mixp += output_channels;
|
||||
|
||||
if (altram >= wtsize)
|
||||
{
|
||||
halt_osc(osc, 0, &acc, resshift);
|
||||
}
|
||||
}
|
||||
|
||||
if (altram >= wtsize)
|
||||
// if oscillator halted, we've got no more samples to generate
|
||||
if (pOsc->control & 1)
|
||||
{
|
||||
halt_osc(osc, 0, &acc, resshift);
|
||||
ctrl |= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if oscillator halted, we've got no more samples to generate
|
||||
if (pOsc->control & 1)
|
||||
{
|
||||
ctrl |= 1;
|
||||
break;
|
||||
}
|
||||
pOsc->control = ctrl;
|
||||
pOsc->accumulator = acc;
|
||||
pOsc->data = data ^ 0x80;
|
||||
}
|
||||
|
||||
pOsc->control = ctrl;
|
||||
pOsc->accumulator = acc;
|
||||
pOsc->data = data ^ 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
mixp = &mix[0];
|
||||
for (i = 0; i < samples; i++)
|
||||
{
|
||||
outputs[0][i] = (*mixp++)>>1;
|
||||
outputs[1][i] = (*mixp++)>>1;
|
||||
}
|
||||
for (int chan = 0; chan < output_channels; chan++)
|
||||
outputs[chan][i] = (*mixp++)>>1;
|
||||
}
|
||||
|
||||
|
||||
@ -267,7 +265,7 @@ void es5503_device::device_start()
|
||||
}
|
||||
|
||||
output_rate = (clock()/8)/34; // (input clock / 8) / # of oscs. enabled + 2
|
||||
m_stream = machine().sound().stream_alloc(*this, 0, 2, output_rate, this);
|
||||
m_stream = machine().sound().stream_alloc(*this, 0, output_channels, output_rate, this);
|
||||
|
||||
m_timer = timer_alloc(0, NULL);
|
||||
m_timer->adjust(attotime::from_hz(output_rate), 0, attotime::from_hz(output_rate));
|
||||
|
@ -3,16 +3,23 @@
|
||||
#ifndef __ES5503_H__
|
||||
#define __ES5503_H__
|
||||
|
||||
#define MCFG_ES5503_ADD(_tag, _clock, _irqf, _adcf) \
|
||||
// channels must be a power of two
|
||||
|
||||
#define MCFG_ES5503_ADD(_tag, _clock, _channels, _irqf, _adcf) \
|
||||
MCFG_DEVICE_ADD(_tag, ES5503, _clock) \
|
||||
MCFG_ES5503_OUTPUT_CHANNELS(_channels) \
|
||||
MCFG_ES5503_IRQ_FUNC(_irqf) \
|
||||
MCFG_ES5503_ADC_FUNC(_adcf)
|
||||
|
||||
#define MCFG_ES5503_REPLACE(_tag, _clock, _irqf, _adcf) \
|
||||
#define MCFG_ES5503_REPLACE(_tag, _clock, _channels, _irqf, _adcf) \
|
||||
MCFG_DEVICE_REPLACE(_tag, ES5503, _clock) \
|
||||
MCFG_ES5503_OUTPUT_CHANNELS(_channels) \
|
||||
MCFG_ES5503_IRQ_FUNC(_irqf) \
|
||||
MCFG_ES5503_ADC_FUNC(_adcf)
|
||||
|
||||
#define MCFG_ES5503_OUTPUT_CHANNELS(_channels) \
|
||||
es5503_device::static_set_channels(*device, _channels); \
|
||||
|
||||
#define MCFG_ES5503_IRQ_FUNC(_irqf) \
|
||||
es5503_device::static_set_irqf(*device, _irqf); \
|
||||
|
||||
@ -29,6 +36,7 @@ public:
|
||||
// construction/destruction
|
||||
es5503_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
static void static_set_channels(device_t &device, int channels);
|
||||
static void static_set_irqf(device_t &device, void (*irqf)(device_t *device, int state));
|
||||
static void static_set_adcf(device_t &device, UINT8 (*adcf)(device_t *device));
|
||||
|
||||
@ -89,6 +97,7 @@ private:
|
||||
|
||||
UINT8 m_channel_strobe;
|
||||
|
||||
int output_channels;
|
||||
UINT32 output_rate;
|
||||
|
||||
emu_timer *m_timer;
|
||||
|
@ -370,12 +370,10 @@ static MACHINE_CONFIG_START( mquake, amiga_state )
|
||||
MCFG_SOUND_ROUTE(2, "rspeaker", 0.50)
|
||||
MCFG_SOUND_ROUTE(3, "lspeaker", 0.50)
|
||||
|
||||
MCFG_ES5503_ADD("es5503", 7159090, NULL, NULL) /* ES5503 is likely mono due to channel strobe used as bank select */
|
||||
MCFG_ES5503_ADD("es5503", 7159090, 1, NULL, NULL) /* ES5503 is likely mono due to channel strobe used as bank select */
|
||||
MCFG_DEVICE_ADDRESS_MAP(AS_0, mquake_es5503_map)
|
||||
MCFG_SOUND_ROUTE(0, "lspeaker", 0.50)
|
||||
MCFG_SOUND_ROUTE(0, "rspeaker", 0.50)
|
||||
MCFG_SOUND_ROUTE(1, "lspeaker", 0.50)
|
||||
MCFG_SOUND_ROUTE(1, "rspeaker", 0.50)
|
||||
|
||||
/* cia */
|
||||
MCFG_LEGACY_MOS8520_ADD("cia_0", AMIGA_68000_NTSC_CLOCK / 10, 0, cia_0_intf)
|
||||
|
@ -256,7 +256,7 @@ static MACHINE_CONFIG_START( apple2gs, apple2gs_state )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
|
||||
MCFG_ES5503_ADD("es5503", APPLE2GS_7M, apple2gs_doc_irq, apple2gs_adc_read)
|
||||
MCFG_ES5503_ADD("es5503", APPLE2GS_7M, 2, apple2gs_doc_irq, apple2gs_adc_read)
|
||||
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
|
||||
|
||||
|
@ -63,7 +63,7 @@ TODO:
|
||||
|
||||
#define WD1772_TAG "wd1772"
|
||||
|
||||
#define KEYBOARD_HACK (0)
|
||||
#define KEYBOARD_HACK (1)
|
||||
|
||||
class esq1_state : public driver_device
|
||||
{
|
||||
@ -160,6 +160,8 @@ static ADDRESS_MAP_START( esq1_map, AS_PROGRAM, 8, esq1_state )
|
||||
AM_RANGE(0x4000, 0x5fff) AM_RAM // SEQRAM
|
||||
AM_RANGE(0x6000, 0x63ff) AM_DEVREADWRITE("es5503", es5503_device, read, write)
|
||||
AM_RANGE(0x6400, 0x640f) AM_DEVREADWRITE_LEGACY("duart", duart68681_r, duart68681_w)
|
||||
AM_RANGE(0x6800, 0x68ff) AM_NOP
|
||||
|
||||
AM_RANGE(0x7000, 0x7fff) AM_ROMBANK("osbank")
|
||||
AM_RANGE(0x8000, 0xffff) AM_ROM AM_REGION("osrom", 0x8000) // OS "high" ROM is always mapped here
|
||||
ADDRESS_MAP_END
|
||||
@ -272,9 +274,15 @@ static MACHINE_CONFIG_START( esq1, esq1_state )
|
||||
MCFG_ESQ2x40_ADD("vfd")
|
||||
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
MCFG_ES5503_ADD("es5503", 7000000, esq1_doc_irq, esq1_adc_read)
|
||||
MCFG_ES5503_ADD("es5503", 7000000, 8, esq1_doc_irq, esq1_adc_read)
|
||||
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(2, "lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(3, "rspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(4, "lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(5, "rspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(6, "lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(7, "rspeaker", 1.0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED(sq80, esq1)
|
||||
|
@ -262,7 +262,7 @@ static MACHINE_CONFIG_START( mirage, mirage_state )
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 319, 1, 239)
|
||||
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
MCFG_ES5503_ADD("es5503", 7000000, mirage_doc_irq, mirage_adc_read)
|
||||
MCFG_ES5503_ADD("es5503", 7000000, 2, mirage_doc_irq, mirage_adc_read)
|
||||
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user