summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/sound/lc7535.cpp
blob: 00f86ea2945df9b4a06acb275714881d773b5a9c (plain) (tree)

























































































































































                                                                                                                       
// 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;
}