summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/upd71071.h
blob: 4a4b6d1c330c3fbda1f529a34aa44029f467bcda (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
// license:BSD-3-Clause
// copyright-holders:Barry Rodewald
#ifndef __UPD71071_H__
#define __UPD71071_H__



struct upd71071_reg
{
	uint8_t initialise;
	uint8_t channel;
	uint16_t count_current[4];
	uint16_t count_base[4];
	uint32_t address_current[4];
	uint32_t address_base[4];
	uint16_t device_control;
	uint8_t mode_control[4];
	uint8_t status;
	uint8_t temp_l;
	uint8_t temp_h;
	uint8_t request;
	uint8_t mask;
};

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

	static void static_set_cpu_tag(device_t &device, const char *tag) { downcast<upd71071_device &>(device).m_cpu.set_tag(tag); }
	static void set_clock(device_t &device, int clock) { downcast<upd71071_device &>(device).m_upd_clock = clock; }
	template<class _Object> static devcb_base &set_out_hreq_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_out_hreq_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_out_eop_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_out_eop_cb.set_callback(object); }

	template<class _Object> static devcb_base &set_dma_read_0_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_read_0_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_dma_read_1_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_read_1_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_dma_read_2_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_read_2_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_dma_read_3_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_read_3_cb.set_callback(object); }

	template<class _Object> static devcb_base &set_dma_write_0_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_write_0_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_dma_write_1_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_write_1_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_dma_write_2_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_write_2_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_dma_write_3_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_dma_write_3_cb.set_callback(object); }

	template<class _Object> static devcb_base &set_out_dack_0_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_out_dack_0_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_out_dack_1_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_out_dack_1_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_out_dack_2_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_out_dack_2_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_out_dack_3_callback(device_t &device, _Object object) { return downcast<upd71071_device &>(device).m_out_dack_3_cb.set_callback(object); }

	DECLARE_READ8_MEMBER(read);
	DECLARE_WRITE8_MEMBER(write);
	DECLARE_WRITE_LINE_MEMBER(set_hreq);
	DECLARE_WRITE_LINE_MEMBER(set_eop);

	int dmarq(int state, int channel);

protected:
	// device-level overrides
	virtual void device_start() override;

private:
	// internal state
	void soft_reset();
	TIMER_CALLBACK_MEMBER(dma_transfer_timer);

	struct upd71071_reg m_reg;
	int m_selected_channel;
	int m_buswidth;
	int m_dmarq[4];
	emu_timer* m_timer[4];
	//int m_in_progress[4];
	//int m_transfer_size[4];
	int m_base;
	int m_upd_clock;
	devcb_write_line    m_out_hreq_cb;
	devcb_write_line    m_out_eop_cb;
	devcb_read16        m_dma_read_0_cb;
	devcb_read16        m_dma_read_1_cb;
	devcb_read16        m_dma_read_2_cb;
	devcb_read16        m_dma_read_3_cb;
	devcb_write16       m_dma_write_0_cb;
	devcb_write16       m_dma_write_1_cb;
	devcb_write16       m_dma_write_2_cb;
	devcb_write16       m_dma_write_3_cb;
	devcb_write_line   m_out_dack_0_cb;
	devcb_write_line   m_out_dack_1_cb;
	devcb_write_line   m_out_dack_2_cb;
	devcb_write_line   m_out_dack_3_cb;
	int m_hreq;
	int m_eop;
	optional_device<cpu_device> m_cpu;
};

extern const device_type UPD71071;

#define MCFG_UPD71071_CPU(_tag) \
	upd71071_device::static_set_cpu_tag(*device, "^" _tag);

#define MCFG_UPD71071_CLOCK(_clk) \
	upd71071_device::set_clock(*device, _clk);

#define MCFG_UPD71071_OUT_HREQ_CB(_devcb) \
	devcb = &upd71071_device::set_out_hreq_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_OUT_EOP_CB(_devcb) \
	devcb = &upd71071_device::set_out_eop_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_READ_0_CB(_devcb) \
	devcb = &upd71071_device::set_dma_read_0_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_READ_1_CB(_devcb) \
	devcb = &upd71071_device::set_dma_read_1_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_READ_2_CB(_devcb) \
	devcb = &upd71071_device::set_dma_read_2_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_READ_3_CB(_devcb) \
	devcb = &upd71071_device::set_dma_read_3_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_WRITE_0_CB(_devcb) \
	devcb = &upd71071_device::set_dma_write_0_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_WRITE_1_CB(_devcb) \
	devcb = &upd71071_device::set_dma_write_1_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_WRITE_2_CB(_devcb) \
	devcb = &upd71071_device::set_dma_write_2_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_DMA_WRITE_3_CB(_devcb) \
	devcb = &upd71071_device::set_dma_write_3_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_OUT_DACK_0_CB(_devcb) \
	devcb = &upd71071_device::set_out_dack_0_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_OUT_DACK_1_CB(_devcb) \
	devcb = &upd71071_device::set_out_dack_1_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_OUT_DACK_2_CB(_devcb) \
	devcb = &upd71071_device::set_out_dack_2_callback(*device, DEVCB_##_devcb);

#define MCFG_UPD71071_OUT_DACK_3_CB(_devcb) \
	devcb = &upd71071_device::set_out_dack_3_callback(*device, DEVCB_##_devcb);

#endif /*UPD71071_H_*/