// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***************************************************************************
National Semiconductor ADC1038
10-Bit Serial I/O A/D Converters with Analog Multiplexer and
Track/hold Function
***************************************************************************/
#include "emu.h"
#include "adc1038.h"
DEFINE_DEVICE_TYPE(ADC1038, adc1038_device, "adc1038", "ADC1038")
adc1038_device::adc1038_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ADC1038, tag, owner, clock)
, m_cycle(0)
, m_clk(0)
, m_adr(0)
, m_data_in(0)
, m_data_out(0)
, m_adc_data(0)
, m_sars(0)
, m_gticlub_hack(false)
, m_input_cb(*this)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void adc1038_device::device_start()
{
m_input_cb.resolve();
save_item(NAME(m_cycle));
save_item(NAME(m_clk));
save_item(NAME(m_adr));
save_item(NAME(m_data_in));
save_item(NAME(m_data_out));
save_item(NAME(m_adc_data));
save_item(NAME(m_sars));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void adc1038_device::device_reset()
{
m_cycle = 0;
m_clk = 0;
m_adr = 0;
m_data_in = 0;
m_data_out = 0;
m_adc_data = 0;
m_sars = 1;
}
/*****************************************************************************
DEVICE HANDLERS
*****************************************************************************/
READ_LINE_MEMBER( adc1038_device::do_read )
{
m_data_out = (m_adc_data & 0x200) ? 1 : 0;
m_adc_data <<= 1;
//printf("ADC DO\n");
return m_data_out;
}
WRITE_LINE_MEMBER( adc1038_device::di_write )
{
m_data_in = state;
}
WRITE_LINE_MEMBER( adc1038_device::clk_write )
{
// GTI Club doesn't sync on SARS
if (m_gticlub_hack)
{
if (m_clk == 0 && state == 0)
{
m_cycle = 0;
/* notice that m_adr is always < 7! */
m_adc_data = m_input_cb(m_adr);
}
}
if (state == 1)
{
//printf("ADC CLK, DI = %d, cycle = %d\n", m_data_in, m_cycle);
if (m_cycle == 0) // A2
{
m_adr = 0;
m_adr |= (m_data_in << 2);
}
else if (m_cycle == 1) // A1
{
m_adr |= (m_data_in << 1);
}
else if (m_cycle == 2) // A0
{
m_adr |= (m_data_in << 0);
}
m_cycle++;
}
m_clk = state;
}
READ_LINE_MEMBER( adc1038_device::sars_read )
{
m_cycle = 0;
/* notice that m_adr is always < 7! */
m_adc_data = m_input_cb(m_adr);
m_sars ^= 1;
return m_sars;
}