summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/adc1038.cpp
blob: 3baac1fd1bea176828c34b4b9edb442d2a4508b2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// 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;
}