diff options
author | 2025-02-22 10:03:06 -0500 | |
---|---|---|
committer | 2025-02-22 10:03:06 -0500 | |
commit | 3eaedf23c3dad1d5e1c77262c91d40fdb2974faa (patch) | |
tree | 3714dc09cffc88ef21df456c951ce8af58fe853d | |
parent | a3bdebb78fa6f349cc23512b2437c6230d63303f (diff) |
taito/tc0060dca.cpp: Added support for Taito TC0060DCA volume control and hooked up to Operation Wolf. (Github #13369) [R. Belmont, Stephen Leary]
-rw-r--r-- | src/mame/taito/opwolf.cpp | 43 | ||||
-rwxr-xr-x | src/mame/taito/tc0060dca.cpp | 48 | ||||
-rwxr-xr-x | src/mame/taito/tc0060dca.h | 30 |
3 files changed, 109 insertions, 12 deletions
diff --git a/src/mame/taito/opwolf.cpp b/src/mame/taito/opwolf.cpp index 93d751f6231..397d7640f16 100644 --- a/src/mame/taito/opwolf.cpp +++ b/src/mame/taito/opwolf.cpp @@ -276,6 +276,7 @@ register. So what is controlling priority. #include "taitosnd.h" #include "taitoipt.h" #include "taitocchip.h" +#include "tc0060dca.h" #include "pc080sn.h" #include "pc090oj.h" @@ -314,6 +315,7 @@ public: m_pc080sn(*this, "pc080sn"), m_pc090oj(*this, "pc090oj"), m_msm(*this, "msm%u", 0), + m_tc0060dca(*this, "tc0060dca%u", 0), m_lspeaker(*this, "lspeaker"), m_rspeaker(*this, "rspeaker"), m_z80bank(*this, "z80bank"), @@ -384,6 +386,7 @@ private: required_device<pc080sn_device> m_pc080sn; required_device<pc090oj_device> m_pc090oj; required_device_array<msm5205_device, 2> m_msm; + required_device_array<tc0060dca_device, 2> m_tc0060dca; required_device<speaker_device> m_lspeaker; required_device<speaker_device> m_rspeaker; required_memory_bank m_z80bank; @@ -755,7 +758,7 @@ void opwolf_state::opwolf_adpcm_b_w(offs_t offset, uint8_t data) m_adpcm_pos[0] = start; m_adpcm_end[0] = end; m_msm[0]->reset_w(0); - m_msm[0]->set_output_gain(0, m_adpcm_b[5] / 255.0); + m_tc0060dca[0]->set_level(m_adpcm_b[5]); //logerror("TRIGGER MSM1\n"); } @@ -778,7 +781,7 @@ void opwolf_state::opwolf_adpcm_c_w(offs_t offset, uint8_t data) m_adpcm_pos[1] = start; m_adpcm_end[1] = end; m_msm[1]->reset_w(0); - m_msm[1]->set_output_gain(0, m_adpcm_c[5] / 255.0); + m_tc0060dca[1]->set_level(m_adpcm_c[5]); //logerror("TRIGGER MSM2\n"); } @@ -931,17 +934,25 @@ void opwolf_state::opwolf(machine_config &config) ymsnd.add_route(0, "lspeaker", 1.0); ymsnd.add_route(1, "rspeaker", 1.0); + TC0060DCA(config, m_tc0060dca[0], 384000); + m_tc0060dca[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_tc0060dca[0]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + MSM5205(config, m_msm[0], 384000); m_msm[0]->vck_legacy_callback().set(FUNC(opwolf_state::msm5205_vck_w<0>)); m_msm[0]->set_prescaler_selector(msm5205_device::S48_4B); /* 8 kHz */ - m_msm[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - m_msm[0]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_msm[0]->add_route(ALL_OUTPUTS, m_tc0060dca[0], 1.0); + m_msm[0]->add_route(ALL_OUTPUTS, m_tc0060dca[0], 1.0); + + TC0060DCA(config, m_tc0060dca[1], 384000); + m_tc0060dca[1]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_tc0060dca[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); MSM5205(config, m_msm[1], 384000); m_msm[1]->vck_legacy_callback().set(FUNC(opwolf_state::msm5205_vck_w<1>)); m_msm[1]->set_prescaler_selector(msm5205_device::S48_4B); /* 8 kHz */ - m_msm[1]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - m_msm[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_msm[1]->add_route(ALL_OUTPUTS, m_tc0060dca[1], 1.0); + m_msm[1]->add_route(ALL_OUTPUTS, m_tc0060dca[1], 1.0); pc060ha_device &ciu(PC060HA(config, "ciu", 0)); ciu.nmi_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI); @@ -1002,17 +1013,25 @@ void opwolf_state::opwolfb(machine_config &config) /* OSC clocks unknown for the ymsnd.add_route(0, "lspeaker", 1.0); ymsnd.add_route(1, "rspeaker", 1.0); + TC0060DCA(config, m_tc0060dca[0], 384000); + m_tc0060dca[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_tc0060dca[0]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + MSM5205(config, m_msm[0], 384000); m_msm[0]->vck_legacy_callback().set(FUNC(opwolf_state::msm5205_vck_w<0>)); - m_msm[0]->set_prescaler_selector(msm5205_device::S48_4B); /* 8 kHz */ - m_msm[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - m_msm[0]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_msm[0]->set_prescaler_selector(msm5205_device::S48_4B); /* 8 kHz */ + m_msm[0]->add_route(ALL_OUTPUTS, m_tc0060dca[0], 1.0); + m_msm[0]->add_route(ALL_OUTPUTS, m_tc0060dca[0], 1.0); + + TC0060DCA(config, m_tc0060dca[1], 384000); + m_tc0060dca[1]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + m_tc0060dca[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); MSM5205(config, m_msm[1], 384000); m_msm[1]->vck_legacy_callback().set(FUNC(opwolf_state::msm5205_vck_w<1>)); - m_msm[1]->set_prescaler_selector(msm5205_device::S48_4B); /* 8 kHz */ - m_msm[1]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - m_msm[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); + m_msm[1]->set_prescaler_selector(msm5205_device::S48_4B); /* 8 kHz */ + m_msm[1]->add_route(ALL_OUTPUTS, m_tc0060dca[1], 1.0); + m_msm[1]->add_route(ALL_OUTPUTS, m_tc0060dca[1], 1.0); pc060ha_device &ciu(PC060HA(config, "ciu", 0)); ciu.nmi_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI); diff --git a/src/mame/taito/tc0060dca.cpp b/src/mame/taito/tc0060dca.cpp new file mode 100755 index 00000000000..90226d96b23 --- /dev/null +++ b/src/mame/taito/tc0060dca.cpp @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/*************************************************************************** + + tc0060dca.cpp - Taito TC0060DCA programmable volume control + Emulation by R. Belmont, volume curve measured by Stephen Leary + +***************************************************************************/ + +#include "emu.h" +#include "tc0060dca.h" + +#include <cmath> + +DEFINE_DEVICE_TYPE(TC0060DCA, tc0060dca_device, "tc0060dca", "Taito TC0060DCA programmable volume control") + +tc0060dca_device::tc0060dca_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, TC0060DCA, tag, owner, clock), + device_sound_interface(mconfig, *this), + m_stream(nullptr), + m_level(0) +{ +} + +void tc0060dca_device::device_start() +{ + m_stream = stream_alloc(8, 2, clock(), STREAM_DEFAULT_FLAGS); + + for (int x = 0; x < 256; x++) + { + m_atten_table[x] = 1.0 / (1.0 + exp(-10 * ((x / 256.0) - 0.6))); + } + + save_item(NAME(m_level)); +} + +void tc0060dca_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + for (int i = 0; i < inputs[0].samples(); i++) + { + const stream_buffer::sample_t l = inputs[0].get(i); + const stream_buffer::sample_t r = inputs[1].get(i); + outputs[0].put(i, l * m_atten_table[m_level]); + outputs[1].put(i, r * m_atten_table[m_level]); + } +} + + diff --git a/src/mame/taito/tc0060dca.h b/src/mame/taito/tc0060dca.h new file mode 100755 index 00000000000..a89016ddbd2 --- /dev/null +++ b/src/mame/taito/tc0060dca.h @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +#ifndef MAME_TAITO_TC0060DCA_H +#define MAME_TAITO_TC0060DCA_H + +#pragma once + +class tc0060dca_device : public device_t, public device_sound_interface +{ +public: + tc0060dca_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + void set_level(u8 level) { m_level = level; } + +protected: + // device_t override + virtual void device_start() override ATTR_COLD; + + // device_sound_interface override + virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; + +private: + sound_stream *m_stream; + u8 m_level; + float m_atten_table[256]; +}; + +DECLARE_DEVICE_TYPE(TC0060DCA, tc0060dca_device) + +#endif // MAME_TAITO_TC0060DCA_H |