summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/msm5205.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/msm5205.cpp')
-rw-r--r--src/devices/sound/msm5205.cpp123
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);
}