diff options
author | Andrew Gardner <andrew-gardner@users.noreply.github.com> | 2012-12-28 21:26:58 +0000 |
---|---|---|
committer | Andrew Gardner <andrew-gardner@users.noreply.github.com> | 2012-12-28 21:26:58 +0000 |
commit | cdadb9c780c99b9d85f221549510c2970643190d (patch) | |
tree | fefcd0ad6a8bc9e2fe064e7cae83fc45e2a00172 /src/emu/sound | |
parent | 6cdf4c0242873cfa7b361677a95ca433535885e0 (diff) |
Modernize Gaelco sound devices. [Andrew Gardner]
Out of whatsnew:
These are really simple to do between the inevitable holiday distractions. Zen.
Etc.
Diffstat (limited to 'src/emu/sound')
-rw-r--r-- | src/emu/sound/gaelco.c | 193 | ||||
-rw-r--r-- | src/emu/sound/gaelco.h | 68 |
2 files changed, 123 insertions, 138 deletions
diff --git a/src/emu/sound/gaelco.c b/src/emu/sound/gaelco.c index 0fa01c919fb..43d1476ebd0 100644 --- a/src/emu/sound/gaelco.c +++ b/src/emu/sound/gaelco.c @@ -42,52 +42,43 @@ Registers per channel: #define LOG_SOUND(x) do { if (VERBOSE_SOUND) logerror x; } while (0) #define LOG_READ_WRITES(x) do { if (VERBOSE_READ_WRITES) logerror x; } while (0) -#define LOG_WAVE 0 //#define ALT_MIX -#define GAELCO_NUM_CHANNELS 0x07 -#define VOLUME_LEVELS 0x10 +#define LOG_WAVE 0 +static wav_file* wavraw; // Raw waveform -/* this structure defines a channel */ -struct gaelco_sound_channel -{ - int active; /* is it playing? */ - int loop; /* = 0 no looping, = 1 looping */ - int chunkNum; /* current chunk if looping */ -}; -/* this structure defines the Gaelco custom sound chip */ -struct gaelco_sound_state -{ - sound_stream *stream; /* our stream */ - UINT8 *snd_data; /* PCM data */ - int banks[4]; /* start of each ROM bank */ - gaelco_sound_channel channel[GAELCO_NUM_CHANNELS]; /* 7 stereo channels */ - - UINT16 sndregs[0x38]; +/*============================================================================ + Gaelco GAE1 sound device + ============================================================================*/ - /* table for converting from 8 to 16 bits with volume control */ - INT16 volume_table[VOLUME_LEVELS][256]; -}; +const device_type GAELCO_GAE1 = &device_creator<gaelco_gae1_device>; -static wav_file * wavraw; /* raw waveform */ +gaelco_gae1_device::gaelco_gae1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, GAELCO_GAE1, "Gaelco GAE1", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_stream(NULL), + m_snd_data(NULL) +{ +} -INLINE gaelco_sound_state *get_safe_token(device_t *device) +gaelco_gae1_device::gaelco_gae1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, type, name, tag, owner, clock), + device_sound_interface(mconfig, *this), + m_stream(NULL), + m_snd_data(NULL) { - assert(device != NULL); - assert(device->type() == GAELCO_GAE1 || device->type() == GAELCO_CG1V); - return (gaelco_sound_state *)downcast<gaelco_gae1_device *>(device)->token(); } + /*============================================================================ CG-1V/GAE1 Sound Update Writes length bytes to the sound buffer ============================================================================*/ -static STREAM_UPDATE( gaelco_update ) +void gaelco_gae1_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - gaelco_sound_state *info = (gaelco_sound_state *)param; int j, ch; /* fill all data needed */ @@ -97,7 +88,7 @@ static STREAM_UPDATE( gaelco_update ) /* for each channel */ for (ch = 0; ch < GAELCO_NUM_CHANNELS; ch ++){ int ch_data_l = 0, ch_data_r = 0; - gaelco_sound_channel *channel = &info->channel[ch]; + gaelco_sound_channel *channel = &m_channel[ch]; /* if the channel is playing */ if (channel->active == 1){ @@ -112,47 +103,47 @@ static STREAM_UPDATE( gaelco_update ) base_offset = ch*8 + chunkNum*4; /* get channel parameters */ - type = ((info->sndregs[base_offset + 1] >> 4) & 0x0f); - bank = info->banks[((info->sndregs[base_offset + 1] >> 0) & 0x03)]; - vol_l = ((info->sndregs[base_offset + 1] >> 12) & 0x0f); - vol_r = ((info->sndregs[base_offset + 1] >> 8) & 0x0f); - end_pos = info->sndregs[base_offset + 2] << 8; + type = ((m_sndregs[base_offset + 1] >> 4) & 0x0f); + bank = m_banks[((m_sndregs[base_offset + 1] >> 0) & 0x03)]; + vol_l = ((m_sndregs[base_offset + 1] >> 12) & 0x0f); + vol_r = ((m_sndregs[base_offset + 1] >> 8) & 0x0f); + end_pos = m_sndregs[base_offset + 2] << 8; /* generates output data (range 0x00000..0xffff) */ if (type == 0x08){ /* PCM, 8 bits mono */ - data = info->snd_data[bank + end_pos + info->sndregs[base_offset + 3]]; - ch_data_l = info->volume_table[vol_l][data]; - ch_data_r = info->volume_table[vol_r][data]; + data = m_snd_data[bank + end_pos + m_sndregs[base_offset + 3]]; + ch_data_l = m_volume_table[vol_l][data]; + ch_data_r = m_volume_table[vol_r][data]; - info->sndregs[base_offset + 3]--; + m_sndregs[base_offset + 3]--; } else if (type == 0x0c){ /* PCM, 8 bits stereo */ - data = info->snd_data[bank + end_pos + info->sndregs[base_offset + 3]]; - ch_data_l = info->volume_table[vol_l][data]; + data = m_snd_data[bank + end_pos + m_sndregs[base_offset + 3]]; + ch_data_l = m_volume_table[vol_l][data]; - info->sndregs[base_offset + 3]--; + m_sndregs[base_offset + 3]--; - if (info->sndregs[base_offset + 3] > 0){ - data = info->snd_data[bank + end_pos + info->sndregs[base_offset + 3]]; - ch_data_r = info->volume_table[vol_r][data]; + if (m_sndregs[base_offset + 3] > 0){ + data = m_snd_data[bank + end_pos + m_sndregs[base_offset + 3]]; + ch_data_r = m_volume_table[vol_r][data]; - info->sndregs[base_offset + 3]--; + m_sndregs[base_offset + 3]--; } } else { - LOG_SOUND(("(GAE1) Playing unknown sample format in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", ch, type, bank, end_pos, info->sndregs[base_offset + 3])); + LOG_SOUND(("(GAE1) Playing unknown sample format in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", ch, type, bank, end_pos, m_sndregs[base_offset + 3])); channel->active = 0; } /* check if the current sample has finished playing */ - if (info->sndregs[base_offset + 3] == 0){ + if (m_sndregs[base_offset + 3] == 0){ if (channel->loop == 0){ /* if no looping, we're done */ channel->active = 0; } else { /* if we're looping, swap chunks */ channel->chunkNum = (channel->chunkNum + 1) & 0x01; /* if the length of the next chunk is 0, we're done */ - if (info->sndregs[ch*8 + channel->chunkNum*4 + 3] == 0){ + if (m_sndregs[ch*8 + channel->chunkNum*4 + 3] == 0){ channel->active = 0; } } @@ -189,40 +180,37 @@ static STREAM_UPDATE( gaelco_update ) CG-1V/GAE1 Read Handler ============================================================================*/ -READ16_DEVICE_HANDLER( gaelcosnd_r ) +READ16_MEMBER( gaelco_gae1_device::gaelcosnd_r ) { - gaelco_sound_state *info = get_safe_token(device); - - LOG_READ_WRITES(("%s: (GAE1): read from %04x\n", device->machine().describe_context(), offset)); + LOG_READ_WRITES(("%s: (GAE1): read from %04x\n", machine().describe_context(), offset)); - return info->sndregs[offset]; + return m_sndregs[offset]; } /*============================================================================ CG-1V/GAE1 Write Handler ============================================================================*/ -WRITE16_DEVICE_HANDLER( gaelcosnd_w ) +WRITE16_MEMBER( gaelco_gae1_device::gaelcosnd_w ) { - gaelco_sound_state *info = get_safe_token(device); - gaelco_sound_channel *channel = &info->channel[offset >> 3]; + gaelco_sound_channel *channel = &m_channel[offset >> 3]; - LOG_READ_WRITES(("%s: (GAE1): write %04x to %04x\n", device->machine().describe_context(), data, offset)); + LOG_READ_WRITES(("%s: (GAE1): write %04x to %04x\n", machine().describe_context(), data, offset)); /* first update the stream to this point in time */ - info->stream->update(); + m_stream->update(); - COMBINE_DATA(&info->sndregs[offset]); + COMBINE_DATA(&m_sndregs[offset]); switch(offset & 0x07){ case 0x03: /* trigger sound */ - if ((info->sndregs[offset - 1] != 0) && (data != 0)){ + if ((m_sndregs[offset - 1] != 0) && (data != 0)){ if (!channel->active){ channel->active = 1; channel->chunkNum = 0; channel->loop = 0; - LOG_SOUND(("(GAE1) Playing sample channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (info->sndregs[offset - 2] >> 4) & 0x0f, info->sndregs[offset - 2] & 0x03, info->sndregs[offset - 1] << 8, data)); + LOG_SOUND(("(GAE1) Playing sample channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (m_sndregs[offset - 2] >> 4) & 0x0f, m_sndregs[offset - 2] & 0x03, m_sndregs[offset - 1] << 8, data)); } } else { channel->active = 0; @@ -231,8 +219,8 @@ WRITE16_DEVICE_HANDLER( gaelcosnd_w ) break; case 0x07: /* enable/disable looping */ - if ((info->sndregs[offset - 1] != 0) && (data != 0)){ - LOG_SOUND(("(GAE1) Looping in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (info->sndregs[offset - 2] >> 4) & 0x0f, info->sndregs[offset - 2] & 0x03, info->sndregs[offset - 1] << 8, data)); + if ((m_sndregs[offset - 1] != 0) && (data != 0)){ + LOG_SOUND(("(GAE1) Looping in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (m_sndregs[offset - 2] >> 4) & 0x0f, m_sndregs[offset - 2] & 0x03, m_sndregs[offset - 1] << 8, data)); channel->loop = 1; } else { channel->loop = 0; @@ -243,29 +231,27 @@ WRITE16_DEVICE_HANDLER( gaelcosnd_w ) } /*============================================================================ - CG-1V/GAE1 Init + CG-1V/GAE1 Init / Close ============================================================================*/ -static DEVICE_START( gaelco ) +void gaelco_gae1_device::device_start() { int j, vol; - const gaelcosnd_interface *intf = (const gaelcosnd_interface *)device->static_config(); - - gaelco_sound_state *info = get_safe_token(device); + const gaelcosnd_interface *intf = (const gaelcosnd_interface *)static_config(); /* copy rom banks */ for (j = 0; j < 4; j++){ - info->banks[j] = intf->banks[j]; + m_banks[j] = intf->banks[j]; } - info->stream = device->machine().sound().stream_alloc(*device, 0, 2, 8000, info, gaelco_update); - info->snd_data = (UINT8 *)device->machine().root_device().memregion(intf->gfxregion)->base(); - if (info->snd_data == NULL) - info->snd_data = *device->region(); + m_stream = stream_alloc(0, 2, 8000); + m_snd_data = (UINT8 *)machine().root_device().memregion(intf->gfxregion)->base(); + if (m_snd_data == NULL) + m_snd_data = *region(); /* init volume table */ for (vol = 0; vol < VOLUME_LEVELS; vol++){ for (j = -128; j <= 127; j++){ - info->volume_table[vol][(j ^ 0x80) & 0xff] = (vol*j*256)/(VOLUME_LEVELS - 1); + m_volume_table[vol][(j ^ 0x80) & 0xff] = (vol*j*256)/(VOLUME_LEVELS - 1); } } @@ -274,7 +260,7 @@ static DEVICE_START( gaelco ) } -static DEVICE_STOP( gaelco ) +void gaelco_gae1_device::device_stop() { if (wavraw) wav_close(wavraw); @@ -282,60 +268,11 @@ static DEVICE_STOP( gaelco ) } -const device_type GAELCO_GAE1 = &device_creator<gaelco_gae1_device>; -gaelco_gae1_device::gaelco_gae1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, GAELCO_GAE1, "Gaelco GAE1", tag, owner, clock), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(gaelco_sound_state); -} - -gaelco_gae1_device::gaelco_gae1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, type, name, tag, owner, clock), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(gaelco_sound_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void gaelco_gae1_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void gaelco_gae1_device::device_start() -{ - DEVICE_START_NAME( gaelco )(this); -} - -//------------------------------------------------- -// device_stop - device-specific stop -//------------------------------------------------- - -void gaelco_gae1_device::device_stop() -{ - DEVICE_STOP_NAME( gaelco )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void gaelco_gae1_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); -} +/*============================================================================ + Gaelco CG-1V sound device + ============================================================================*/ const device_type GAELCO_CG1V = &device_creator<gaelco_cg1v_device>; diff --git a/src/emu/sound/gaelco.h b/src/emu/sound/gaelco.h index 9a4fe4df54f..f0a6224b539 100644 --- a/src/emu/sound/gaelco.h +++ b/src/emu/sound/gaelco.h @@ -3,7 +3,42 @@ #ifndef __GALELCO_H__ #define __GALELCO_H__ -#include "devlegcy.h" +#define GAELCO_NUM_CHANNELS 0x07 +#define VOLUME_LEVELS 0x10 + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_GAELCO_GAE1_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, GAELCO_GAE1, _clock) \ + +#define MCFG_GAELCO_GAE1_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, GAELCO_GAE1, _clock) \ + +#define MCFG_GAELCO_CG1V_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, GAELCO_CG1V, _clock) \ + +#define MCFG_GAELCO_CG1V_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, GAELCO_CG1V, _clock) \ + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> Sound Channel + +struct gaelco_sound_channel +{ + int active; // is it playing? + int loop; // = 0 no looping, = 1 looping + int chunkNum; // current chunk if looping +}; + + +// ======================> External interface struct gaelcosnd_interface { @@ -11,34 +46,47 @@ struct gaelcosnd_interface int banks[4]; /* start of each ROM bank */ }; -DECLARE_WRITE16_DEVICE_HANDLER( gaelcosnd_w ); -DECLARE_READ16_DEVICE_HANDLER( gaelcosnd_r ); + +// ======================> gaelco_gae1_device class gaelco_gae1_device : public device_t, - public device_sound_interface + public device_sound_interface { public: gaelco_gae1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); gaelco_gae1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); - ~gaelco_gae1_device() { global_free(m_token); } + ~gaelco_gae1_device() { } - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); virtual void device_stop(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + +public: + DECLARE_WRITE16_MEMBER( gaelcosnd_w ); + DECLARE_READ16_MEMBER( gaelcosnd_r ); + private: - // internal state - void *m_token; + sound_stream *m_stream; /* our stream */ + UINT8 *m_snd_data; /* PCM data */ + int m_banks[4]; /* start of each ROM bank */ + gaelco_sound_channel m_channel[GAELCO_NUM_CHANNELS]; /* 7 stereo channels */ + + UINT16 m_sndregs[0x38]; + + // Table for converting from 8 to 16 bits with volume control + INT16 m_volume_table[VOLUME_LEVELS][256]; }; extern const device_type GAELCO_GAE1; + + +// ======================> gaelco_cg1v_device + class gaelco_cg1v_device : public gaelco_gae1_device { public: |