diff options
Diffstat (limited to 'src/emu/sound/k005289.c')
-rw-r--r-- | src/emu/sound/k005289.c | 261 |
1 files changed, 115 insertions, 146 deletions
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(); } |