summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/adc0808.h
blob: 4d717446be0a8063da526d203c31d0d1821e4350 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/***************************************************************************

    ADC0808/ADC0809

    A/D Converter with 8 Channel-Multiplexer

                ___ ___
       IN3   1 |*  u   | 28  IN2
       IN4   2 |       | 27  IN1
       IN5   3 |       | 26  IN0
       IN6   4 |       | 25  ADD A
       IN7   5 |       | 24  ADD B
     START   6 |       | 23  ADD C
       EOC   7 |       | 22  ALE
        D4   8 |       | 21  D0
        OE   9 |       | 20  D1
     CLOCK  10 |       | 19  D2
       VCC  11 |       | 18  D3
     VREF+  12 |       | 17  D7
       DND  13 |       | 16  VREF-
        D6  14 |_______| 15  D5

    Notes:
    * The difference between the two devices is the total adjusted
      error: ADC0808 ±½ LSB, ADC0809 ±1 LSB
    * MM74C949 and M58990P are equivalent to ADC0808
    * MM74C949-1 and M58990P-1 are equivalent to ADC0809
    * ADC0816 and ADC0817 are 16 channel equivalents

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

#ifndef MAME_DEVICES_MACHINE_ADC0808_H
#define MAME_DEVICES_MACHINE_ADC0808_H

#pragma once


//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_ADC0808_EOC_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_eoc_callback(DEVCB_##_devcb);

// common hookup where the eoc output is connected to a flip-flop
#define MCFG_ADC0808_EOC_FF_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_eoc_ff_callback(DEVCB_##_devcb);

#define MCFG_ADC0808_IN0_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 0);

#define MCFG_ADC0808_IN1_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 1);

#define MCFG_ADC0808_IN2_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 2);

#define MCFG_ADC0808_IN3_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 3);

#define MCFG_ADC0808_IN4_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 4);

#define MCFG_ADC0808_IN5_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 5);

#define MCFG_ADC0808_IN6_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 6);

#define MCFG_ADC0808_IN7_CB(_devcb) \
	downcast<adc0808_device &>(*device).set_in_callback(DEVCB_##_devcb, 7);


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

class adc0808_device : public device_t
{
public:
	// construction/destruction
	adc0808_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	// configuration
	template <class Object> devcb_base &set_eoc_callback(Object &&cb)
	{ return m_eoc_cb.set_callback(std::forward<Object>(cb)); }

	template <class Object> devcb_base &set_eoc_ff_callback(Object &&cb)
	{ return m_eoc_ff_cb.set_callback(std::forward<Object>(cb)); }

	template <class Object> devcb_base &set_in_callback(Object &&cb, int index)
	{ return m_in_cb[index].set_callback(std::forward<Object>(cb)); }

	DECLARE_READ8_MEMBER(data_r);
	DECLARE_WRITE8_MEMBER(address_w);
	DECLARE_WRITE_LINE_MEMBER(start_w);
	DECLARE_READ_LINE_MEMBER(eoc_r);

	// common hookups
	DECLARE_WRITE8_MEMBER(address_offset_start_w); // start and ale connected, address to the address bus
	DECLARE_WRITE8_MEMBER(address_data_start_w); // start and ale connected, address to the data bus

protected:
	adc0808_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

private:
	// callbacks
	devcb_write_line m_eoc_cb;
	devcb_write_line m_eoc_ff_cb;
	devcb_read8 m_in_cb[8];

	enum state : int
	{
		STATE_IDLE,
		STATE_CONVERSION_START,
		STATE_CONVERSION_READY,
		STATE_CONVERSION_RUNNING
	};
	state m_state;

	emu_timer *m_cycle_timer;

	// state
	int m_start;
	int m_address;
	uint8_t m_sar;
	bool m_eoc;
};

class adc0809_device : public adc0808_device
{
public:
	adc0809_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};

class m58990_device : public adc0808_device
{
public:
	m58990_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};


// device type definition
DECLARE_DEVICE_TYPE(ADC0808, adc0808_device)
DECLARE_DEVICE_TYPE(ADC0809, adc0809_device)
DECLARE_DEVICE_TYPE(M58990, m58990_device)

#endif // MAME_DEVICES_MACHINE_ADC0808_H