summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound
diff options
context:
space:
mode:
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
commitcdadb9c780c99b9d85f221549510c2970643190d (patch)
treefefcd0ad6a8bc9e2fe064e7cae83fc45e2a00172 /src/emu/sound
parent6cdf4c0242873cfa7b361677a95ca433535885e0 (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.c193
-rw-r--r--src/emu/sound/gaelco.h68
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: