diff options
author | Andrew Gardner <andrew-gardner@users.noreply.github.com> | 2013-02-05 16:17:15 +0000 |
---|---|---|
committer | Andrew Gardner <andrew-gardner@users.noreply.github.com> | 2013-02-05 16:17:15 +0000 |
commit | 3e7883e3fcf57399319157242ee4031b6323ca3b (patch) | |
tree | ad1e311d5495a86415cb79dc5a223c52496969c4 | |
parent | 96d5e7fea38a52481b800c60694aff7c34238a69 (diff) |
Modernized iremga20 & k005289 sound devices. [Andrew Gardner]
-rw-r--r-- | src/emu/sound/iremga20.c | 250 | ||||
-rw-r--r-- | src/emu/sound/iremga20.h | 55 | ||||
-rw-r--r-- | src/emu/sound/k005289.c | 261 | ||||
-rw-r--r-- | src/emu/sound/k005289.h | 73 | ||||
-rw-r--r-- | src/mame/drivers/m107.c | 4 | ||||
-rw-r--r-- | src/mame/drivers/m92.c | 4 | ||||
-rw-r--r-- | src/mame/drivers/nemesis.c | 28 |
7 files changed, 339 insertions, 336 deletions
diff --git a/src/emu/sound/iremga20.c b/src/emu/sound/iremga20.c index 2203aa0a6d4..c2e32675731 100644 --- a/src/emu/sound/iremga20.c +++ b/src/emu/sound/iremga20.c @@ -31,41 +31,80 @@ Revisions: #define MAX_VOL 256 -struct IremGA20_channel_def + +// device type definition +const device_type IREMGA20 = &device_creator<iremga20_device>; + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// iremga20_device - constructor +//------------------------------------------------- + +iremga20_device::iremga20_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, IREMGA20, "Irem GA20", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_rom(NULL), + m_rom_size(0), + m_stream(NULL) { - UINT32 rate; - UINT32 size; - UINT32 start; - UINT32 pos; - UINT32 frac; - UINT32 end; - UINT32 volume; - UINT32 pan; - UINT32 effect; - UINT32 play; -}; - -struct ga20_state +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void iremga20_device::device_start() { - UINT8 *rom; - INT32 rom_size; - sound_stream * stream; - UINT16 regs[0x40]; - struct IremGA20_channel_def channel[4]; -}; + int i; + + /* Initialize our chip structure */ + m_rom = m_region->base(); + m_rom_size = m_region->bytes(); + + iremga20_reset(); + + for ( i = 0; i < 0x40; i++ ) + m_regs[i] = 0; + m_stream = stream_alloc(0, 2, clock()/4); -INLINE ga20_state *get_safe_token(device_t *device) + save_item(NAME(m_regs)); + for (i = 0; i < 4; i++) + { + save_item(NAME(m_channel[i].rate), i); + save_item(NAME(m_channel[i].size), i); + save_item(NAME(m_channel[i].start), i); + save_item(NAME(m_channel[i].pos), i); + save_item(NAME(m_channel[i].end), i); + save_item(NAME(m_channel[i].volume), i); + save_item(NAME(m_channel[i].pan), i); + save_item(NAME(m_channel[i].effect), i); + save_item(NAME(m_channel[i].play), i); + } +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void iremga20_device::device_reset() { - assert(device != NULL); - assert(device->type() == IREMGA20); - return (ga20_state *)downcast<iremga20_device *>(device)->token(); + iremga20_reset(); } -static STREAM_UPDATE( IremGA20_update ) +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void iremga20_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - ga20_state *chip = (ga20_state *)param; UINT32 rate[4], pos[4], frac[4], end[4], vol[4], play[4]; UINT8 *pSamples; stream_sample_t *outL, *outR; @@ -74,16 +113,16 @@ static STREAM_UPDATE( IremGA20_update ) /* precache some values */ for (i=0; i < 4; i++) { - rate[i] = chip->channel[i].rate; - pos[i] = chip->channel[i].pos; - frac[i] = chip->channel[i].frac; - end[i] = chip->channel[i].end - 0x20; - vol[i] = chip->channel[i].volume; - play[i] = chip->channel[i].play; + rate[i] = m_channel[i].rate; + pos[i] = m_channel[i].pos; + frac[i] = m_channel[i].frac; + end[i] = m_channel[i].end - 0x20; + vol[i] = m_channel[i].volume; + play[i] = m_channel[i].play; } i = samples; - pSamples = chip->rom; + pSamples = m_rom; outL = outputs[0]; outR = outputs[1]; @@ -133,72 +172,70 @@ static STREAM_UPDATE( IremGA20_update ) /* update the regs now */ for (i=0; i < 4; i++) { - chip->channel[i].pos = pos[i]; - chip->channel[i].frac = frac[i]; - chip->channel[i].play = play[i]; + m_channel[i].pos = pos[i]; + m_channel[i].frac = frac[i]; + m_channel[i].play = play[i]; } } -WRITE8_DEVICE_HANDLER( irem_ga20_w ) +WRITE8_MEMBER( iremga20_device::irem_ga20_w ) { - ga20_state *chip = get_safe_token(device); int channel; //logerror("GA20: Offset %02x, data %04x\n",offset,data); - chip->stream->update(); + m_stream->update(); channel = offset >> 3; - chip->regs[offset] = data; + m_regs[offset] = data; switch (offset & 0x7) { case 0: /* start address low */ - chip->channel[channel].start = ((chip->channel[channel].start)&0xff000) | (data<<4); + m_channel[channel].start = ((m_channel[channel].start)&0xff000) | (data<<4); break; case 1: /* start address high */ - chip->channel[channel].start = ((chip->channel[channel].start)&0x00ff0) | (data<<12); + m_channel[channel].start = ((m_channel[channel].start)&0x00ff0) | (data<<12); break; case 2: /* end address low */ - chip->channel[channel].end = ((chip->channel[channel].end)&0xff000) | (data<<4); + m_channel[channel].end = ((m_channel[channel].end)&0xff000) | (data<<4); break; case 3: /* end address high */ - chip->channel[channel].end = ((chip->channel[channel].end)&0x00ff0) | (data<<12); + m_channel[channel].end = ((m_channel[channel].end)&0x00ff0) | (data<<12); break; case 4: - chip->channel[channel].rate = 0x1000000 / (256 - data); + m_channel[channel].rate = 0x1000000 / (256 - data); break; case 5: //AT: gain control - chip->channel[channel].volume = (data * MAX_VOL) / (data + 10); + m_channel[channel].volume = (data * MAX_VOL) / (data + 10); break; case 6: //AT: this is always written 2(enabling both channels?) - chip->channel[channel].play = data; - chip->channel[channel].pos = chip->channel[channel].start; - chip->channel[channel].frac = 0; + m_channel[channel].play = data; + m_channel[channel].pos = m_channel[channel].start; + m_channel[channel].frac = 0; break; } } -READ8_DEVICE_HANDLER( irem_ga20_r ) +READ8_MEMBER( iremga20_device::irem_ga20_r ) { - ga20_state *chip = get_safe_token(device); int channel; - chip->stream->update(); + m_stream->update(); channel = offset >> 3; switch (offset & 0x7) { case 7: // voice status. bit 0 is 1 if active. (routine around 0xccc in rtypeleo) - return chip->channel[channel].play ? 1 : 0; + return m_channel[channel].play ? 1 : 0; default: logerror("GA20: read unk. register %d, channel %d\n", offset & 0xf, channel); @@ -208,104 +245,21 @@ READ8_DEVICE_HANDLER( irem_ga20_r ) return 0; } -static void iremga20_reset(ga20_state *chip) -{ - int i; - - for( i = 0; i < 4; i++ ) { - chip->channel[i].rate = 0; - chip->channel[i].size = 0; - chip->channel[i].start = 0; - chip->channel[i].pos = 0; - chip->channel[i].frac = 0; - chip->channel[i].end = 0; - chip->channel[i].volume = 0; - chip->channel[i].pan = 0; - chip->channel[i].effect = 0; - chip->channel[i].play = 0; - } -} - - -static DEVICE_RESET( iremga20 ) -{ - iremga20_reset(get_safe_token(device)); -} -static DEVICE_START( iremga20 ) +void iremga20_device::iremga20_reset() { - ga20_state *chip = get_safe_token(device); int i; - /* Initialize our chip structure */ - chip->rom = *device->region(); - chip->rom_size = device->region()->bytes(); - - iremga20_reset(chip); - - for ( i = 0; i < 0x40; i++ ) - chip->regs[i] = 0; - - chip->stream = device->machine().sound().stream_alloc( *device, 0, 2, device->clock()/4, chip, IremGA20_update ); - - device->save_item(NAME(chip->regs)); - for (i = 0; i < 4; i++) - { - device->save_item(NAME(chip->channel[i].rate), i); - device->save_item(NAME(chip->channel[i].size), i); - device->save_item(NAME(chip->channel[i].start), i); - device->save_item(NAME(chip->channel[i].pos), i); - device->save_item(NAME(chip->channel[i].end), i); - device->save_item(NAME(chip->channel[i].volume), i); - device->save_item(NAME(chip->channel[i].pan), i); - device->save_item(NAME(chip->channel[i].effect), i); - device->save_item(NAME(chip->channel[i].play), i); + for( i = 0; i < 4; i++ ) { + m_channel[i].rate = 0; + m_channel[i].size = 0; + m_channel[i].start = 0; + m_channel[i].pos = 0; + m_channel[i].frac = 0; + m_channel[i].end = 0; + m_channel[i].volume = 0; + m_channel[i].pan = 0; + m_channel[i].effect = 0; + m_channel[i].play = 0; } } - -const device_type IREMGA20 = &device_creator<iremga20_device>; - -iremga20_device::iremga20_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, IREMGA20, "Irem GA20", tag, owner, clock), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(ga20_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void iremga20_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void iremga20_device::device_start() -{ - DEVICE_START_NAME( iremga20 )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void iremga20_device::device_reset() -{ - DEVICE_RESET_NAME( iremga20 )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void iremga20_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"); -} diff --git a/src/emu/sound/iremga20.h b/src/emu/sound/iremga20.h index bd90e7082e3..02a70f5aaa4 100644 --- a/src/emu/sound/iremga20.h +++ b/src/emu/sound/iremga20.h @@ -8,31 +8,66 @@ #ifndef __IREMGA20_H__ #define __IREMGA20_H__ -#include "devlegcy.h" -DECLARE_WRITE8_DEVICE_HANDLER( irem_ga20_w ); -DECLARE_READ8_DEVICE_HANDLER( irem_ga20_r ); +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_IREMGA20_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, IREMGA20, _clock) +#define MCFG_IREMGA20_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, IREMGA20, _clock) + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +struct IremGA20_channel_def +{ + UINT32 rate; + UINT32 size; + UINT32 start; + UINT32 pos; + UINT32 frac; + UINT32 end; + UINT32 volume; + UINT32 pan; + UINT32 effect; + UINT32 play; +}; + + +// ======================> iremga20_device class iremga20_device : public device_t, - public device_sound_interface + public device_sound_interface { public: iremga20_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~iremga20_device() { global_free(m_token); } + ~iremga20_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_reset(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + +public: + DECLARE_WRITE8_MEMBER( irem_ga20_w ); + DECLARE_READ8_MEMBER( irem_ga20_r ); + +private: + void iremga20_reset(); + private: - // internal state - void *m_token; + UINT8 *m_rom; + INT32 m_rom_size; + sound_stream *m_stream; + UINT16 m_regs[0x40]; + IremGA20_channel_def m_channel[4]; }; extern const device_type IREMGA20; diff --git a/src/emu/sound/k005289.c b/src/emu/sound/k005289.c index 243064ec4c5..c3f492e6df2 100644 --- a/src/emu/sound/k005289.c +++ b/src/emu/sound/k005289.c @@ -30,77 +30,89 @@ #define FREQBASEBITS 16 -/* this structure defines the parameters for a channel */ -struct k005289_sound_channel -{ - int frequency; - int counter; - int volume; - const unsigned char *wave; -}; -struct k005289_state -{ - k005289_sound_channel channel_list[2]; +// device type definition +const device_type K005289 = &device_creator<k005289_device>; - /* global sound parameters */ - const unsigned char *sound_prom; - sound_stream * stream; - int mclock,rate; - /* mixer tables and internal buffers */ - INT16 *mixer_table; - INT16 *mixer_lookup; - short *mixer_buffer; +//************************************************************************** +// LIVE DEVICE +//************************************************************************** - int k005289_A_frequency,k005289_B_frequency; - int k005289_A_volume,k005289_B_volume; - int k005289_A_waveform,k005289_B_waveform; - int k005289_A_latch,k005289_B_latch; -}; +//------------------------------------------------- +// k005289_device - constructor +//------------------------------------------------- -INLINE k005289_state *get_safe_token(device_t *device) +k005289_device::k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, K005289, "K005289", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_sound_prom(NULL), + m_stream(NULL), + m_mclock(0), + m_rate(0), + m_mixer_table(NULL), + m_mixer_lookup(NULL), + m_mixer_buffer(NULL), + m_k005289_A_frequency(0), + m_k005289_B_frequency(0), + m_k005289_A_volume(0), + m_k005289_B_volume(0), + m_k005289_A_waveform(0), + m_k005289_B_waveform(0), + m_k005289_A_latch(0), + m_k005289_B_latch(0) { - assert(device != NULL); - assert(device->type() == K005289); - return (k005289_state *)downcast<k005289_device *>(device)->token(); } -/* build a table to divide by the number of voices */ -static void make_mixer_table(running_machine &machine, k005289_state *info, int voices) + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void k005289_device::device_start() { - int count = voices * 128; - int i; - int gain = 16; + k005289_sound_channel *voice; - /* allocate memory */ - info->mixer_table = auto_alloc_array(machine, INT16, 256 * voices); + voice = m_channel_list; - /* find the middle of the table */ - info->mixer_lookup = info->mixer_table + (128 * voices); + /* get stream channels */ + m_rate = clock()/16; + m_stream = stream_alloc(0, 1, m_rate); + m_mclock = clock(); - /* fill in the table - 16 bit case */ - for (i = 0; i < count; i++) - { - int val = i * gain * 16 / voices; - if (val > 32767) val = 32767; - info->mixer_lookup[ i] = val; - info->mixer_lookup[-i] = -val; - } + /* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */ + m_mixer_buffer = auto_alloc_array(machine(), short, 2 * m_rate); + + /* build the mixer table */ + make_mixer_table(2); + + m_sound_prom = m_region->base(); + + /* reset all the voices */ + voice[0].frequency = 0; + voice[0].volume = 0; + voice[0].wave = &m_sound_prom[0]; + voice[0].counter = 0; + voice[1].frequency = 0; + voice[1].volume = 0; + voice[1].wave = &m_sound_prom[0x100]; + voice[1].counter = 0; } -/* generate sound to the mix buffer */ -static STREAM_UPDATE( K005289_update ) +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void k005289_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - k005289_state *info = (k005289_state *)param; - k005289_sound_channel *voice=info->channel_list; + k005289_sound_channel *voice=m_channel_list; stream_sample_t *buffer = outputs[0]; short *mix; int i,v,f; /* zap the contents of the mixer buffer */ - memset(info->mixer_buffer, 0, samples * sizeof(INT16)); + memset(m_mixer_buffer, 0, samples * sizeof(INT16)); v=voice[0].volume; f=voice[0].frequency; @@ -109,14 +121,14 @@ static STREAM_UPDATE( K005289_update ) const unsigned char *w = voice[0].wave; int c = voice[0].counter; - mix = info->mixer_buffer; + mix = m_mixer_buffer; /* add our contribution */ for (i = 0; i < samples; i++) { int offs; - c+=(long)((((float)info->mclock / (float)(f * 16))*(float)(1<<FREQBASEBITS)) / (float)(info->rate / 32)); + c+=(long)((((float)m_mclock / (float)(f * 16))*(float)(1<<FREQBASEBITS)) / (float)(m_rate / 32)); offs = (c >> 16) & 0x1f; *mix++ += ((w[offs] & 0x0f) - 8) * v; } @@ -132,14 +144,14 @@ static STREAM_UPDATE( K005289_update ) const unsigned char *w = voice[1].wave; int c = voice[1].counter; - mix = info->mixer_buffer; + mix = m_mixer_buffer; /* add our contribution */ for (i = 0; i < samples; i++) { int offs; - c+=(long)((((float)info->mclock / (float)(f * 16))*(float)(1<<FREQBASEBITS)) / (float)(info->rate / 32)); + c+=(long)((((float)m_mclock / (float)(f * 16))*(float)(1<<FREQBASEBITS)) / (float)(m_rate / 32)); offs = (c >> 16) & 0x1f; *mix++ += ((w[offs] & 0x0f) - 8) * v; } @@ -149,135 +161,92 @@ static STREAM_UPDATE( K005289_update ) } /* mix it down */ - mix = info->mixer_buffer; + mix = m_mixer_buffer; for (i = 0; i < samples; i++) - *buffer++ = info->mixer_lookup[*mix++]; + *buffer++ = m_mixer_lookup[*mix++]; } -static DEVICE_START( k005289 ) -{ - k005289_sound_channel *voice; - k005289_state *info = get_safe_token(device); - - voice = info->channel_list; - - /* get stream channels */ - info->rate = device->clock()/16; - info->stream = device->machine().sound().stream_alloc(*device, 0, 1, info->rate, info, K005289_update); - info->mclock = device->clock(); - - /* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */ - info->mixer_buffer = auto_alloc_array(device->machine(), short, 2 * info->rate); - - /* build the mixer table */ - make_mixer_table(device->machine(), info, 2); - - info->sound_prom = *device->region(); - /* reset all the voices */ - voice[0].frequency = 0; - voice[0].volume = 0; - voice[0].wave = &info->sound_prom[0]; - voice[0].counter = 0; - voice[1].frequency = 0; - voice[1].volume = 0; - voice[1].wave = &info->sound_prom[0x100]; - voice[1].counter = 0; -} /********************************************************************************/ -static void k005289_recompute(k005289_state *info) +/* build a table to divide by the number of voices */ +void k005289_device::make_mixer_table(int voices) { - k005289_sound_channel *voice = info->channel_list; + int count = voices * 128; + int i; + int gain = 16; - info->stream->update(); /* update the streams */ + /* allocate memory */ + m_mixer_table = auto_alloc_array(machine(), INT16, 256 * voices); - voice[0].frequency = info->k005289_A_frequency; - voice[1].frequency = info->k005289_B_frequency; - voice[0].volume = info->k005289_A_volume; - voice[1].volume = info->k005289_B_volume; - voice[0].wave = &info->sound_prom[32 * info->k005289_A_waveform]; - voice[1].wave = &info->sound_prom[32 * info->k005289_B_waveform + 0x100]; -} + /* find the middle of the table */ + m_mixer_lookup = m_mixer_table + (128 * voices); -WRITE8_DEVICE_HANDLER( k005289_control_A_w ) -{ - k005289_state *info = get_safe_token(device); - info->k005289_A_volume=data&0xf; - info->k005289_A_waveform=data>>5; - k005289_recompute(info); + /* fill in the table - 16 bit case */ + for (i = 0; i < count; i++) + { + int val = i * gain * 16 / voices; + if (val > 32767) val = 32767; + m_mixer_lookup[ i] = val; + m_mixer_lookup[-i] = -val; + } } -WRITE8_DEVICE_HANDLER( k005289_control_B_w ) -{ - k005289_state *info = get_safe_token(device); - info->k005289_B_volume=data&0xf; - info->k005289_B_waveform=data>>5; - k005289_recompute(info); -} -WRITE8_DEVICE_HANDLER( k005289_pitch_A_w ) +void k005289_device::k005289_recompute() { - k005289_state *info = get_safe_token(device); - info->k005289_A_latch = 0x1000 - offset; -} + k005289_sound_channel *voice = m_channel_list; -WRITE8_DEVICE_HANDLER( k005289_pitch_B_w ) -{ - k005289_state *info = get_safe_token(device); - info->k005289_B_latch = 0x1000 - offset; + m_stream->update(); /* update the streams */ + + voice[0].frequency = m_k005289_A_frequency; + voice[1].frequency = m_k005289_B_frequency; + voice[0].volume = m_k005289_A_volume; + voice[1].volume = m_k005289_B_volume; + voice[0].wave = &m_sound_prom[32 * m_k005289_A_waveform]; + voice[1].wave = &m_sound_prom[32 * m_k005289_B_waveform + 0x100]; } -WRITE8_DEVICE_HANDLER( k005289_keylatch_A_w ) + +WRITE8_MEMBER( k005289_device::k005289_control_A_w ) { - k005289_state *info = get_safe_token(device); - info->k005289_A_frequency = info->k005289_A_latch; - k005289_recompute(info); + m_k005289_A_volume=data&0xf; + m_k005289_A_waveform=data>>5; + k005289_recompute(); } -WRITE8_DEVICE_HANDLER( k005289_keylatch_B_w ) + +WRITE8_MEMBER( k005289_device::k005289_control_B_w ) { - k005289_state *info = get_safe_token(device); - info->k005289_B_frequency = info->k005289_B_latch; - k005289_recompute(info); + m_k005289_B_volume=data&0xf; + m_k005289_B_waveform=data>>5; + k005289_recompute(); } -const device_type K005289 = &device_creator<k005289_device>; -k005289_device::k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, K005289, "K005289", tag, owner, clock), - device_sound_interface(mconfig, *this) +WRITE8_MEMBER( k005289_device::k005289_pitch_A_w ) { - m_token = global_alloc_clear(k005289_state); + m_k005289_A_latch = 0x1000 - offset; } -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- -void k005289_device::device_config_complete() +WRITE8_MEMBER( k005289_device::k005289_pitch_B_w ) { + m_k005289_B_latch = 0x1000 - offset; } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- -void k005289_device::device_start() +WRITE8_MEMBER( k005289_device::k005289_keylatch_A_w ) { - DEVICE_START_NAME( k005289 )(this); + m_k005289_A_frequency = m_k005289_A_latch; + k005289_recompute(); } -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- -void k005289_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +WRITE8_MEMBER( k005289_device::k005289_keylatch_B_w ) { - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); + m_k005289_B_frequency = m_k005289_B_latch; + k005289_recompute(); } diff --git a/src/emu/sound/k005289.h b/src/emu/sound/k005289.h index a593006813f..cef1781df7c 100644 --- a/src/emu/sound/k005289.h +++ b/src/emu/sound/k005289.h @@ -3,34 +3,79 @@ #ifndef __K005289_H__ #define __K005289_H__ -#include "devlegcy.h" -DECLARE_WRITE8_DEVICE_HANDLER( k005289_control_A_w ); -DECLARE_WRITE8_DEVICE_HANDLER( k005289_control_B_w ); -DECLARE_WRITE8_DEVICE_HANDLER( k005289_pitch_A_w ); -DECLARE_WRITE8_DEVICE_HANDLER( k005289_pitch_B_w ); -DECLARE_WRITE8_DEVICE_HANDLER( k005289_keylatch_A_w ); -DECLARE_WRITE8_DEVICE_HANDLER( k005289_keylatch_B_w ); +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_K005289_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, K005289, _clock) +#define MCFG_K005289_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, K005289, _clock) + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +struct k005289_sound_channel +{ + int frequency; + int counter; + int volume; + const unsigned char *wave; +}; + + +// ======================> k005289_device class k005289_device : public device_t, - public device_sound_interface + public device_sound_interface { public: k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~k005289_device() { global_free(m_token); } + ~k005289_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(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + +public: + DECLARE_WRITE8_MEMBER( k005289_control_A_w ); + DECLARE_WRITE8_MEMBER( k005289_control_B_w ); + DECLARE_WRITE8_MEMBER( k005289_pitch_A_w ); + DECLARE_WRITE8_MEMBER( k005289_pitch_B_w ); + DECLARE_WRITE8_MEMBER( k005289_keylatch_A_w ); + DECLARE_WRITE8_MEMBER( k005289_keylatch_B_w ); + +private: + void make_mixer_table(int voices); + void k005289_recompute(); + private: - // internal state - void *m_token; + k005289_sound_channel m_channel_list[2]; + + const unsigned char *m_sound_prom; + sound_stream *m_stream; + int m_mclock; + int m_rate; + + /* mixer tables and internal buffers */ + INT16 *m_mixer_table; + INT16 *m_mixer_lookup; + short *m_mixer_buffer; + + int m_k005289_A_frequency; + int m_k005289_B_frequency; + int m_k005289_A_volume; + int m_k005289_B_volume; + int m_k005289_A_waveform; + int m_k005289_B_waveform; + int m_k005289_A_latch; + int m_k005289_B_latch; }; extern const device_type K005289; diff --git a/src/mame/drivers/m107.c b/src/mame/drivers/m107.c index be3129ae458..0693ee272e9 100644 --- a/src/mame/drivers/m107.c +++ b/src/mame/drivers/m107.c @@ -180,7 +180,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 16, m107_state ) AM_RANGE(0x00000, 0x1ffff) AM_ROM AM_RANGE(0xa0000, 0xa3fff) AM_RAM - AM_RANGE(0xa8000, 0xa803f) AM_DEVREADWRITE8_LEGACY("irem", irem_ga20_r, irem_ga20_w, 0x00ff) + AM_RANGE(0xa8000, 0xa803f) AM_DEVREADWRITE8("irem", iremga20_device, irem_ga20_r, irem_ga20_w, 0x00ff) AM_RANGE(0xa8040, 0xa8043) AM_DEVREADWRITE8("ymsnd", ym2151_device, read, write, 0x00ff) AM_RANGE(0xa8044, 0xa8045) AM_READWRITE(m107_soundlatch_r, m107_sound_irq_ack_w) AM_RANGE(0xa8046, 0xa8047) AM_WRITE(m107_sound_status_w) @@ -789,7 +789,7 @@ static MACHINE_CONFIG_START( firebarr, m107_state ) MCFG_SOUND_ROUTE(0, "lspeaker", 0.40) MCFG_SOUND_ROUTE(1, "rspeaker", 0.40) - MCFG_SOUND_ADD("irem", IREMGA20, 14318180/4) + MCFG_IREMGA20_ADD("irem", 14318180/4) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END diff --git a/src/mame/drivers/m92.c b/src/mame/drivers/m92.c index eb51a005964..0be3bbd847a 100644 --- a/src/mame/drivers/m92.c +++ b/src/mame/drivers/m92.c @@ -402,7 +402,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 16, m92_state ) AM_RANGE(0x00000, 0x1ffff) AM_ROM AM_RANGE(0xa0000, 0xa3fff) AM_RAM - AM_RANGE(0xa8000, 0xa803f) AM_DEVREADWRITE8_LEGACY("irem", irem_ga20_r, irem_ga20_w, 0x00ff) + AM_RANGE(0xa8000, 0xa803f) AM_DEVREADWRITE8("irem", iremga20_device, irem_ga20_r, irem_ga20_w, 0x00ff) AM_RANGE(0xa8040, 0xa8043) AM_DEVREADWRITE8("ymsnd", ym2151_device, read, write, 0x00ff) AM_RANGE(0xa8044, 0xa8045) AM_READWRITE(m92_soundlatch_r, m92_sound_irq_ack_w) AM_RANGE(0xa8046, 0xa8047) AM_WRITE(m92_sound_status_w) @@ -953,7 +953,7 @@ static MACHINE_CONFIG_START( m92, m92_state ) MCFG_SOUND_ROUTE(0, "mono", 0.40) MCFG_SOUND_ROUTE(1, "mono", 0.40) - MCFG_SOUND_ADD("irem", IREMGA20, XTAL_14_31818MHz/4) + MCFG_IREMGA20_ADD("irem", XTAL_14_31818MHz/4) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MACHINE_CONFIG_END diff --git a/src/mame/drivers/nemesis.c b/src/mame/drivers/nemesis.c index c2d92fe09bd..8a3ff560aa1 100644 --- a/src/mame/drivers/nemesis.c +++ b/src/mame/drivers/nemesis.c @@ -392,11 +392,11 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, nemesis_state ) AM_RANGE(0x0000, 0x3fff) AM_ROM AM_RANGE(0x4000, 0x47ff) AM_RAM - AM_RANGE(0xa000, 0xafff) AM_DEVWRITE_LEGACY("k007232", k005289_pitch_A_w) - AM_RANGE(0xc000, 0xcfff) AM_DEVWRITE_LEGACY("k007232", k005289_pitch_B_w) + AM_RANGE(0xa000, 0xafff) AM_DEVWRITE("k007232", k005289_device, k005289_pitch_A_w) + AM_RANGE(0xc000, 0xcfff) AM_DEVWRITE("k007232", k005289_device, k005289_pitch_B_w) AM_RANGE(0xe001, 0xe001) AM_READ(soundlatch_byte_r) - AM_RANGE(0xe003, 0xe003) AM_DEVWRITE_LEGACY("k007232", k005289_keylatch_A_w) - AM_RANGE(0xe004, 0xe004) AM_DEVWRITE_LEGACY("k007232", k005289_keylatch_B_w) + AM_RANGE(0xe003, 0xe003) AM_DEVWRITE("k007232", k005289_device, k005289_keylatch_A_w) + AM_RANGE(0xe004, 0xe004) AM_DEVWRITE("k007232", k005289_device, k005289_keylatch_B_w) AM_RANGE(0xe005, 0xe005) AM_DEVWRITE_LEGACY("ay2", ay8910_address_w) AM_RANGE(0xe006, 0xe006) AM_DEVWRITE_LEGACY("ay1", ay8910_address_w) AM_RANGE(0xe086, 0xe086) AM_DEVREAD_LEGACY("ay1", ay8910_r) @@ -408,12 +408,12 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( gx400_sound_map, AS_PROGRAM, 8, nemesis_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM AM_RANGE(0x4000, 0x87ff) AM_RAM AM_SHARE("gx400_shared") - AM_RANGE(0xa000, 0xafff) AM_DEVWRITE_LEGACY("k007232", k005289_pitch_A_w) - AM_RANGE(0xc000, 0xcfff) AM_DEVWRITE_LEGACY("k007232", k005289_pitch_B_w) + AM_RANGE(0xa000, 0xafff) AM_DEVWRITE("k007232", k005289_device, k005289_pitch_A_w) + AM_RANGE(0xc000, 0xcfff) AM_DEVWRITE("k007232", k005289_device, k005289_pitch_B_w) AM_RANGE(0xe000, 0xe000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w) AM_RANGE(0xe001, 0xe001) AM_READ(soundlatch_byte_r) - AM_RANGE(0xe003, 0xe003) AM_DEVWRITE_LEGACY("k007232", k005289_keylatch_A_w) - AM_RANGE(0xe004, 0xe004) AM_DEVWRITE_LEGACY("k007232", k005289_keylatch_B_w) + AM_RANGE(0xe003, 0xe003) AM_DEVWRITE("k007232", k005289_device, k005289_keylatch_A_w) + AM_RANGE(0xe004, 0xe004) AM_DEVWRITE("k007232", k005289_device, k005289_keylatch_B_w) AM_RANGE(0xe005, 0xe005) AM_DEVWRITE_LEGACY("ay2", ay8910_address_w) AM_RANGE(0xe006, 0xe006) AM_DEVWRITE_LEGACY("ay1", ay8910_address_w) AM_RANGE(0xe030, 0xe030) AM_WRITE(gx400_speech_start_w) @@ -1476,8 +1476,8 @@ static const ay8910_interface ay8910_interface_2 = AY8910_DEFAULT_LOADS, DEVCB_NULL, DEVCB_NULL, - DEVCB_DEVICE_HANDLER("k007232", k005289_control_A_w), - DEVCB_DEVICE_HANDLER("k007232", k005289_control_B_w) + DEVCB_DEVICE_MEMBER("k007232", k005289_device, k005289_control_A_w), + DEVCB_DEVICE_MEMBER("k007232", k005289_device, k005289_control_B_w) }; static void sound_irq(device_t *device, int state) @@ -1574,7 +1574,7 @@ static MACHINE_CONFIG_START( nemesis, nemesis_state ) MCFG_SOUND_CONFIG(ay8910_interface_2) /* fixed */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) /* verified with OST */ - MCFG_SOUND_ADD("k007232", K005289, 3579545/2) + MCFG_K005289_ADD("k007232", 3579545/2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.35) /* verified with OST */ MCFG_SOUND_ADD("vlm", VLM5030, 3579545) @@ -1617,7 +1617,7 @@ static MACHINE_CONFIG_START( gx400, nemesis_state ) MCFG_SOUND_CONFIG(ay8910_interface_2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) /* verified with OST */ - MCFG_SOUND_ADD("k007232", K005289, 3579545/2) + MCFG_K005289_ADD("k007232", 3579545/2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.35) /* verified with OST */ MCFG_SOUND_ADD("vlm", VLM5030, 3579545) @@ -1659,7 +1659,7 @@ static MACHINE_CONFIG_START( konamigt, nemesis_state ) MCFG_SOUND_CONFIG(ay8910_interface_2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) - MCFG_SOUND_ADD("k007232", K005289, 3579545/2) + MCFG_K005289_ADD("k007232", 3579545/2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60) MACHINE_CONFIG_END @@ -1699,7 +1699,7 @@ static MACHINE_CONFIG_START( rf2_gx400, nemesis_state ) MCFG_SOUND_CONFIG(ay8910_interface_2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) - MCFG_SOUND_ADD("k007232", K005289, 3579545/2) + MCFG_K005289_ADD("k007232", 3579545/2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60) MCFG_SOUND_ADD("vlm", VLM5030, 3579545) |