summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/msm6253.cpp
blob: 96722247d083237d25b64b52280000c51a5fe8ce (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15














                                                                            
                                                                                   









                                                                                                          


                                                                                                                                 
 



                                                                                            



































                                                                                                                             
                                                                                        

































                                                                  
                                               
                                       











                                                   
                                                    








                                                   
                                                           
 
// license:BSD-3-Clause
// copyright-holders: AJR
/**********************************************************************

    OKI MSM6253 8-Bit 4-Channel A/D Converter

**********************************************************************/

#include "emu.h"
#include "machine/msm6253.h"

//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

DEFINE_DEVICE_TYPE(MSM6253, msm6253_device, "msm6253", "OKI MSM6253 A/D Converter")

//**************************************************************************
//  DEVICE DEFINITION
//**************************************************************************

//-------------------------------------------------
//  msm6253_device - constructor
//-------------------------------------------------

msm6253_device::msm6253_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: device_t(mconfig, MSM6253, tag, owner, clock)
	, m_analog_ports(*this, {finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG})
	, m_shift_register(0)
{
	m_analog_input_cb[0] = port_read_delegate(FUNC(msm6253_device::port_read<0>), this);
	m_analog_input_cb[1] = port_read_delegate(FUNC(msm6253_device::port_read<1>), this);
	m_analog_input_cb[2] = port_read_delegate(FUNC(msm6253_device::port_read<2>), this);
	m_analog_input_cb[3] = port_read_delegate(FUNC(msm6253_device::port_read<3>), this);
}

//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void msm6253_device::device_start()
{
	for (int port = 0; port < 4; port++)
	{
		// resolve each callback
		m_analog_input_cb[port].bind_relative_to(*owner());

		// ensure that any configured ports truly are analog
		if (m_analog_ports[port].found())
		{
			for (ioport_field &field : m_analog_ports[port]->fields())
				if (!field.is_analog() && field.type() != IPT_UNKNOWN && field.type() != IPT_UNUSED)
					throw emu_fatalerror("Port %s is not an analog port\n", m_analog_ports[port]->tag());
		}
	}

	// save our state
	save_item(NAME(m_shift_register));
}

//-------------------------------------------------
//  port_read - helper to read configured ports
//-------------------------------------------------

template<int port>
ioport_value msm6253_device::port_read()
{
	if (m_analog_ports[port].found())
		return m_analog_ports[port]->read();

	logerror("%s: Read from unassigned IN%d\n", machine().describe_context(), port);
	return 0xff;
}

//-------------------------------------------------
//  address_w - write from address bus to select
//  one of four internal latches
//-------------------------------------------------

WRITE8_MEMBER(msm6253_device::address_w)
{
	// fill the shift register from the internal A/D latch
	m_shift_register = m_analog_input_cb[offset & 3]();
}

//-------------------------------------------------
//  select_w - write D0/D1 to address latch
//-------------------------------------------------

WRITE8_MEMBER(msm6253_device::select_w)
{
	// fill the shift register from the internal A/D latch
	m_shift_register = m_analog_input_cb[data & 3]();
}

//-------------------------------------------------
//  shift_out - MSB-first serial data output
//-------------------------------------------------

bool msm6253_device::shift_out()
{
	// capture the shifted bit
	bool msb = BIT(m_shift_register, 7);

	// shift the bit out, with zero coming in on the other end
	if (!machine().side_effects_disabled())
		m_shift_register <<= 1;

	// return the bit
	return msb;
}

//-------------------------------------------------
//  d0_r - shift data bit out to D0
//-------------------------------------------------

READ8_MEMBER(msm6253_device::d0_r)
{
	// offset is ignored
	return shift_out() | (space.unmap() & 0xfe);
}

//-------------------------------------------------
//  d7_r - shift data bit out to D7
//-------------------------------------------------

READ8_MEMBER(msm6253_device::d7_r)
{
	// offset is ignored
	return (shift_out() << 7) | (space.unmap() & 0x7f);
}