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

#include "emu.h"


struct upd71071_reg
{
	UINT8 initialise;
	UINT8 channel;
	UINT16 count_current[4];
	UINT16 count_base[4];
	UINT32 address_current[4];
	UINT32 address_base[4];
	UINT16 device_control;
	UINT8 mode_control[4];
	UINT8 status;
	UINT8 temp_l;
	UINT8 temp_h;
	UINT8 request;
	UINT8 mask;
};

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

	static void static_set_cpu_tag(device_t &device, std::string 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_*/