summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/lc7535.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/lc7535.cpp')
-rw-r--r--src/devices/sound/lc7535.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/devices/sound/lc7535.cpp b/src/devices/sound/lc7535.cpp
new file mode 100644
index 00000000000..00f86ea2945
--- /dev/null
+++ b/src/devices/sound/lc7535.cpp
@@ -0,0 +1,154 @@
+// license: BSD-3-Clause
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Sanyo LC7535
+
+ Electronic Volume/Loudness Control with Serial Data Control
+
+ It uses the Sanyo CCB (Computer Control Bus) to communicate. The
+ device address is 0x08 or 0x09 (depending on the select pin).
+
+***************************************************************************/
+
+#include "emu.h"
+#include "lc7535.h"
+
+
+//**************************************************************************
+// CONSTEXPR DEFINITIONS
+//**************************************************************************
+
+constexpr int lc7535_device::m_5db[];
+constexpr int lc7535_device::m_1db[];
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(LC7535, lc7535_device, "lc7535", "Sanyo LC7535")
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// lc7535_device - constructor
+//-------------------------------------------------
+
+lc7535_device::lc7535_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, LC7535, tag, owner, clock),
+ m_select_cb(*this),
+ m_addr(0), m_data(0),
+ m_count(0),
+ m_ce(0), m_di(0), m_clk(0)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void lc7535_device::device_start()
+{
+ // resolve callbacks
+ m_select_cb.resolve();
+ m_volume_cb.bind_relative_to(*owner());
+
+ // register for save states
+ save_item(NAME(m_addr));
+ save_item(NAME(m_data));
+ save_item(NAME(m_count));
+ save_item(NAME(m_ce));
+ save_item(NAME(m_di));
+ save_item(NAME(m_clk));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void lc7535_device::device_reset()
+{
+}
+
+//-------------------------------------------------
+// normalize - convert attenuation to range 0-1
+//-------------------------------------------------
+
+float lc7535_device::normalize(int attenuation)
+{
+ return (attenuation + (MAX * (-1.0))) / (MAX * (-1.0));
+}
+
+
+//**************************************************************************
+// INTERFACE
+//**************************************************************************
+
+WRITE_LINE_MEMBER( lc7535_device::ce_w )
+{
+ m_ce = state;
+}
+
+WRITE_LINE_MEMBER( lc7535_device::di_w )
+{
+ m_di = state;
+}
+
+WRITE_LINE_MEMBER( lc7535_device::clk_w )
+{
+ if (m_clk == 0 && state == 1)
+ {
+ if (m_ce == 0)
+ {
+ if (m_count == 0)
+ m_addr = 0;
+
+ m_addr <<= 1;
+ m_addr |= m_di;
+
+ if (++m_count == 4)
+ {
+ m_addr = bitswap(m_addr, 0, 1, 2, 3);
+ m_count = 0;
+ }
+ }
+ else
+ {
+ // our address is either 8 or 9
+ if (m_addr == (8 | (m_select_cb() ? 0 : 1)))
+ {
+ m_data <<= 1;
+ m_data |= m_di;
+
+ if (++m_count == 16)
+ {
+ m_data = bitswap(m_data, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+
+ // right channel
+ int att_r = m_1db[(m_data >> 4) & 0x07];
+ if (att_r != MAX)
+ att_r += m_5db[(m_data >> 0) & 0x0f];
+
+ // left channel
+ int att_l = m_1db[(m_data >> 12) & 0x07];
+ if (att_l != MAX)
+ att_l += m_5db[(m_data >> 8) & 0x0f];
+
+ bool loudness = bool(BIT(m_data, 7));
+
+ if (!m_volume_cb.isnull())
+ m_volume_cb(att_r, att_l, loudness);
+
+ m_addr = 0;
+ m_count = 0;
+ }
+ }
+ }
+ }
+
+ m_clk = state;
+}