summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2025-02-22 10:03:06 -0500
committer arbee <rb6502@users.noreply.github.com>2025-02-22 10:03:06 -0500
commit3eaedf23c3dad1d5e1c77262c91d40fdb2974faa (patch)
tree3714dc09cffc88ef21df456c951ce8af58fe853d
parenta3bdebb78fa6f349cc23512b2437c6230d63303f (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.cpp43
-rwxr-xr-xsrc/mame/taito/tc0060dca.cpp48
-rwxr-xr-xsrc/mame/taito/tc0060dca.h30
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