diff options
Diffstat (limited to 'src/devices/sound/k005289.cpp')
-rw-r--r-- | src/devices/sound/k005289.cpp | 155 |
1 files changed, 33 insertions, 122 deletions
diff --git a/src/devices/sound/k005289.cpp b/src/devices/sound/k005289.cpp index 9e65eb5783d..5a766ddc8af 100644 --- a/src/devices/sound/k005289.cpp +++ b/src/devices/sound/k005289.cpp @@ -37,10 +37,6 @@ #include "emu.h" #include "k005289.h" -// is this an actual hardware limit? or just an arbitrary divider -// to bring the output frequency down to a reasonable value for MAME? -#define CLOCK_DIVIDER 32 - // device type definition DEFINE_DEVICE_TYPE(K005289, k005289_device, "k005289", "K005289 SCC") @@ -53,15 +49,11 @@ DEFINE_DEVICE_TYPE(K005289, k005289_device, "k005289", "K005289 SCC") // k005289_device - constructor //------------------------------------------------- -k005289_device::k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +k005289_device::k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, K005289, tag, owner, clock) , device_sound_interface(mconfig, *this) , m_sound_prom(*this, DEVICE_SELF) , m_stream(nullptr) - , m_rate(0) - , m_mixer_table(nullptr) - , m_mixer_lookup(nullptr) - , m_mixer_buffer(nullptr) { } @@ -73,30 +65,19 @@ k005289_device::k005289_device(const machine_config &mconfig, const char *tag, d void k005289_device::device_start() { /* get stream channels */ - m_rate = clock() / CLOCK_DIVIDER; - m_stream = stream_alloc(0, 1, m_rate); - - /* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */ - m_mixer_buffer = std::make_unique<short[]>(2 * m_rate); - - /* build the mixer table */ - make_mixer_table(2); + m_stream = stream_alloc(0, 1, clock()); /* reset all the voices */ - for (int i = 0; i < 2; i++) + for (auto & voice : m_voice) { - m_counter[i] = 0; - m_frequency[i] = 0; - m_freq_latch[i] = 0; - m_waveform[i] = i * 0x100; - m_volume[i] = 0; + voice.reset(); } - save_item(NAME(m_counter)); - save_item(NAME(m_frequency)); - save_item(NAME(m_freq_latch)); - save_item(NAME(m_waveform)); - save_item(NAME(m_volume)); + save_item(STRUCT_MEMBER(m_voice, counter)); + save_item(STRUCT_MEMBER(m_voice, frequency)); + save_item(STRUCT_MEMBER(m_voice, pitch)); + save_item(STRUCT_MEMBER(m_voice, waveform)); + save_item(STRUCT_MEMBER(m_voice, volume)); } @@ -104,137 +85,67 @@ void k005289_device::device_start() // 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) +void k005289_device::sound_stream_update(sound_stream &stream) { - stream_sample_t *buffer = outputs[0]; - short *mix; - int i,v,f; - - /* zap the contents of the mixer buffer */ - memset(m_mixer_buffer.get(), 0, samples * sizeof(int16_t)); - - v=m_volume[0]; - f=m_frequency[0]; - if (v && f) + for (int sampid = 0; sampid < stream.samples(); sampid++) { - const unsigned char *w = &m_sound_prom[m_waveform[0]]; - int c = m_counter[0]; - - mix = m_mixer_buffer.get(); - - /* add our contribution */ - for (i = 0; i < samples; i++) - { - int offs; - - c += CLOCK_DIVIDER; - offs = (c / f) & 0x1f; - *mix++ += ((w[offs] & 0x0f) - 8) * v; - } - - /* update the counter for this voice */ - m_counter[0] = c % (f * 0x20); - } - - v=m_volume[1]; - f=m_frequency[1]; - if (v && f) - { - const unsigned char *w = &m_sound_prom[m_waveform[1]]; - int c = m_counter[1]; - - mix = m_mixer_buffer.get(); - - /* add our contribution */ - for (i = 0; i < samples; i++) + for (int i = 0; i < 2; i++) { - int offs; - - c += CLOCK_DIVIDER; - offs = (c / f) & 0x1f; - *mix++ += ((w[offs] & 0x0f) - 8) * v; + voice_t &v = m_voice[i]; + if (--v.counter < 0) + { + v.waveform = (v.waveform & ~0x1f) | ((v.waveform + 1) & 0x1f); + v.counter = v.frequency; + } + stream.add_int(0, sampid, ((m_sound_prom[((i & 1) << 8) | v.waveform] & 0xf) - 8) * v.volume, 512); } - - /* update the counter for this voice */ - m_counter[1] = c % (f * 0x20); } - - /* mix it down */ - mix = m_mixer_buffer.get(); - for (i = 0; i < samples; i++) - *buffer++ = m_mixer_lookup[*mix++]; } - - /********************************************************************************/ -/* build a table to divide by the number of voices */ -void k005289_device::make_mixer_table(int voices) -{ - int count = voices * 128; - int i; - int gain = 16; - - /* allocate memory */ - m_mixer_table = std::make_unique<int16_t[]>(256 * voices); - - /* find the middle of the table */ - m_mixer_lookup = m_mixer_table.get() + (128 * voices); - - /* 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_MEMBER( k005289_device::k005289_control_A_w ) +void k005289_device::control_A_w(u8 data) { m_stream->update(); - m_volume[0] = data & 0xf; - m_waveform[0] = data & 0xe0; + m_voice[0].volume = data & 0xf; + m_voice[0].waveform = (m_voice[0].waveform & ~0xe0) | (data & 0xe0); } -WRITE8_MEMBER( k005289_device::k005289_control_B_w ) +void k005289_device::control_B_w(u8 data) { m_stream->update(); - m_volume[1] = data & 0xf; - m_waveform[1] = (data & 0xe0) + 0x100; + m_voice[1].volume = data & 0xf; + m_voice[1].waveform = (m_voice[1].waveform & ~0xe0) | (data & 0xe0); } -WRITE8_MEMBER( k005289_device::ld1_w ) +void k005289_device::ld1_w(offs_t offset, u8 data) { - m_freq_latch[0] = 0xfff - offset; + m_voice[0].pitch = 0xfff - offset; } -WRITE8_MEMBER( k005289_device::ld2_w ) +void k005289_device::ld2_w(offs_t offset, u8 data) { - m_freq_latch[1] = 0xfff - offset; + m_voice[1].pitch = 0xfff - offset; } -WRITE8_MEMBER( k005289_device::tg1_w ) +void k005289_device::tg1_w(u8 data) { m_stream->update(); - m_frequency[0] = m_freq_latch[0]; + m_voice[0].frequency = m_voice[0].pitch; } -WRITE8_MEMBER( k005289_device::tg2_w ) +void k005289_device::tg2_w(u8 data) { m_stream->update(); - m_frequency[1] = m_freq_latch[1]; + m_voice[1].frequency = m_voice[1].pitch; } |