diff options
Diffstat (limited to 'src/devices/sound/msm5205.cpp')
-rw-r--r-- | src/devices/sound/msm5205.cpp | 123 |
1 files changed, 42 insertions, 81 deletions
diff --git a/src/devices/sound/msm5205.cpp b/src/devices/sound/msm5205.cpp index 05646521f36..814b3191342 100644 --- a/src/devices/sound/msm5205.cpp +++ b/src/devices/sound/msm5205.cpp @@ -41,14 +41,15 @@ Differences between MSM6585 & MSM5205: - MSM6585 MSM5205 - Master clock frequency 640kHz 384kHz - Sampling frequency 4k/8k/16k/32kHz 4k/6k/8kHz - ADPCM bit length 4-bit 3-bit/4-bit - Data capture timing 5µsec 15.6µsec - DA converter 12-bit 10-bit - Low-pass filter -40dB/oct N/A - Overflow prevent circuit Included N/A + MSM6585 MSM5205 + Master clock frequency 640kHz 384k/768kHz + Sampling frequency 4k/8k/16k/32kHz at 640kHz 4k/6k/8kHz at 384kHz + ADPCM bit length 4-bit 3-bit/4-bit + Data capture timing 3µsec at 640kHz 15.6µsec at 384kHz + DA converter 12-bit 10-bit + Low-pass filter -40dB/oct N/A + Overflow prevent circuit Included N/A + Cutoff Frequency (Sampling Frequency/2.5)kHz N/A Data capture follows VCK falling edge on MSM5205 (VCK rising edge on MSM6585) @@ -57,21 +58,22 @@ */ -DEFINE_DEVICE_TYPE(MSM5205, msm5205_device, "msm5205", "MSM5205") -DEFINE_DEVICE_TYPE(MSM6585, msm6585_device, "msm6585", "MSM6585") +DEFINE_DEVICE_TYPE(MSM5205, msm5205_device, "msm5205", "OKI MSM5205 ADPCM") +DEFINE_DEVICE_TYPE(MSM6585, msm6585_device, "msm6585", "OKI MSM6585 ADPCM") msm5205_device::msm5205_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : msm5205_device(mconfig, MSM5205, tag, owner, clock) + : msm5205_device(mconfig, MSM5205, tag, owner, clock, 10) { } -msm5205_device::msm5205_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) +msm5205_device::msm5205_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 dac_bits) : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) , m_s1(false) , m_s2(false) , m_bitwidth(4) + , m_dac_bits(dac_bits) , m_vck_cb(*this) , m_vck_legacy_cb(*this) { @@ -79,7 +81,7 @@ msm5205_device::msm5205_device(const machine_config &mconfig, device_type type, msm6585_device::msm6585_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : msm5205_device(mconfig, MSM6585, tag, owner, clock) + : msm5205_device(mconfig, MSM6585, tag, owner, clock, 12) { } @@ -89,16 +91,13 @@ msm6585_device::msm6585_device(const machine_config &mconfig, const char *tag, d void msm5205_device::device_start() { - m_vck_cb.resolve_safe(); - m_vck_legacy_cb.resolve(); - /* compute the difference tables */ compute_tables(); /* stream system initialize */ - m_stream = machine().sound().stream_alloc(*this, 0, 1, clock()); - m_vck_timer = timer_alloc(TIMER_VCK); - m_capture_timer = timer_alloc(TIMER_ADPCM_CAPTURE); + m_stream = stream_alloc(0, 1, clock()); + m_vck_timer = timer_alloc(FUNC(msm5205_device::toggle_vck), this); + m_capture_timer = timer_alloc(FUNC(msm5205_device::update_adpcm), this); /* register for save states */ save_item(NAME(m_data)); @@ -170,35 +169,25 @@ void msm5205_device::compute_tables() //------------------------------------------------- -// device_timer - called whenever a device timer -// fires +// toggle_vck - //------------------------------------------------- -void msm5205_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(msm5205_device::toggle_vck) { - switch (id) - { - case TIMER_VCK: - m_vck = !m_vck; - m_vck_cb(m_vck); - if (!m_vck) - m_capture_timer->adjust(attotime::from_nsec(15600)); - break; - - case TIMER_ADPCM_CAPTURE: - update_adpcm(); - break; - } + m_vck = !m_vck; + m_vck_cb(m_vck); + if (!m_vck) + m_capture_timer->adjust(attotime::from_hz(clock() / adpcm_capture_divisor())); } // timer callback at VCK low edge on MSM5205 (at rising edge on MSM6585) -void msm5205_device::update_adpcm() +TIMER_CALLBACK_MEMBER(msm5205_device::update_adpcm) { int val; int new_signal; // callback user handler and latch next data - if (!m_vck_legacy_cb.isnull()) + if (!m_vck_legacy_cb.isunset()) m_vck_legacy_cb(1); // reset check at last hiedge of VCK @@ -224,7 +213,7 @@ void msm5205_device::update_adpcm() } /* update when signal changed */ - if( m_signal != new_signal) + if (m_signal != new_signal) { m_stream->update(); m_signal = new_signal; @@ -237,14 +226,14 @@ void msm5205_device::update_adpcm() * Handle an update of the VCK status of a chip (1 is reset ON, 0 is reset OFF) * This function can use selector = MSM5205_SEX only */ -WRITE_LINE_MEMBER(msm5205_device::vclk_w) +void msm5205_device::vclk_w(int state) { if (get_prescaler() != 0) logerror("Error: vclk_w() called but VCK selected master mode\n"); else { if (m_vck && !state) - m_capture_timer->adjust(attotime::from_nsec(15600)); + m_capture_timer->adjust(attotime::from_hz(clock()/6)); // 15.6 usec at 384KHz m_vck = state; } } @@ -253,7 +242,7 @@ WRITE_LINE_MEMBER(msm5205_device::vclk_w) * Handle an update of the reset status of a chip (1 is reset ON, 0 is reset OFF) */ -WRITE_LINE_MEMBER(msm5205_device::reset_w) +void msm5205_device::reset_w(int state) { m_reset = state; } @@ -262,7 +251,7 @@ WRITE_LINE_MEMBER(msm5205_device::reset_w) * Handle an update of the data to the chip */ -void msm5205_device::write_data(int data) +void msm5205_device::data_w(uint8_t data) { if (m_bitwidth == 4) m_data = data & 0x0f; @@ -309,7 +298,7 @@ void msm5205_device::playmode_w(int select) } } -WRITE_LINE_MEMBER(msm5205_device::s1_w) +void msm5205_device::s1_w(int state) { if (m_s1 != bool(state)) { @@ -319,7 +308,7 @@ WRITE_LINE_MEMBER(msm5205_device::s1_w) } } -WRITE_LINE_MEMBER(msm5205_device::s2_w) +void msm5205_device::s2_w(int state) { if (m_s2 != bool(state)) { @@ -337,6 +326,7 @@ WRITE_LINE_MEMBER(msm5205_device::s2_w) void msm5205_device::device_clock_changed() { + m_stream->set_sample_rate(clock()); int prescaler = get_prescaler(); if (prescaler != 0) { @@ -357,44 +347,15 @@ void msm5205_device::device_clock_changed() // sound_stream_update - handle a stream update //------------------------------------------------- -void msm5205_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void msm5205_device::sound_stream_update(sound_stream &stream) { - stream_sample_t *buffer = outputs[0]; - /* if this voice is active */ - if(m_signal) - { - short val = m_signal * 16; - while (samples) - { - *buffer++ = val; - samples--; - } - } - else - memset(buffer, 0, samples * sizeof(*buffer)); -} - - -//------------------------------------------------- -// device_timer - called whenever a device timer -// fires -//------------------------------------------------- - -void msm6585_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) + if (m_signal) { - case TIMER_VCK: - m_vck = !m_vck; - m_vck_cb(m_vck); - if (m_vck) - m_capture_timer->adjust(attotime::from_usec(3)); - break; - - case TIMER_ADPCM_CAPTURE: - update_adpcm(); - break; + constexpr sound_stream::sample_t sample_scale = 1.0 / double(1 << 12); + const int dac_mask = (m_dac_bits >= 12) ? 0 : (1 << (12 - m_dac_bits)) - 1; + sound_stream::sample_t val = sound_stream::sample_t(m_signal & ~dac_mask) * sample_scale; + stream.fill(0, val); } } @@ -403,8 +364,8 @@ void msm6585_device::device_timer(emu_timer &timer, device_timer_id id, int para // sound_stream_update - handle a stream update //------------------------------------------------- -void msm6585_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void msm6585_device::sound_stream_update(sound_stream &stream) { // should this be different? - msm5205_device::sound_stream_update(stream, inputs, outputs,samples); + msm5205_device::sound_stream_update(stream); } |