summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i8089/i8089_channel.h
blob: e95975c28c32e9f8eae5dfb90aa7b0dd529b3b26 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// license:GPL-2.0+
// copyright-holders:Dirk Best,Carl
/***************************************************************************

    Intel 8089 I/O Processor

    I/O channel

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

#pragma once

#ifndef __I8089_CHANNEL_H__
#define __I8089_CHANNEL_H__

#include "emu.h"
#include "i8089.h"


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

#define MCFG_I8089_CHANNEL_ADD(_tag) \
	MCFG_DEVICE_ADD(_tag, I8089_CHANNEL, 0)

#define MCFG_I8089_CHANNEL_SINTR(_sintr) \
	downcast<i8089_channel *>(device)->set_sintr_callback(DEVCB_##_sintr);


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

// forward declaration
class i8089_device;

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

	template<class _sintr> void set_sintr_callback(_sintr sintr) { m_write_sintr.set_callback(sintr); }

	// set register
	void set_reg(int reg, uint32_t value, int tag = -1);

	int execute_run();
	void attention();

	// channel status
	bool executing();
	bool transferring();
	bool priority();
	int  chan_prio();
	bool chained();
	bool lock();
	void ca();

	DECLARE_WRITE_LINE_MEMBER( ext_w );
	DECLARE_WRITE_LINE_MEMBER( drq_w );

	// register
	enum
	{
		GA,  // 20-bit general purpose address a
		GB,  // 20-bit general purpose address b
		GC,  // 20-bit general purpose address c
		BC,  // byte count
		TP,  // 20-bit task pointer
		IX,  // byte count
		CC,  // mask compare
		MC,  // channel control

		// internal use register
		CP,  // 20-bit control block pointer
		PP,  // 20-bit parameter pointer
		PSW, // program status word

		NUM_REGS
	};

	struct
	{
		uint32_t w; // 20-bit address
		bool t; // tag-bit
	}
	m_r[11];

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

private:

	// opcodes
	void add_rm(int r, int m, int o);
	void add_mr(int m, int r, int o);
	void addb_rm(int r, int m, int o);
	void addb_mr(int m, int r, int o);
	void addbi_ri(int r, int8_t i);
	void addbi_mi(int m, int8_t i, int o);
	void addi_ri(int r, int16_t i);
	void addi_mi(int m, int16_t i, int o);
	void and_rm(int r, int m, int o);
	void and_mr(int m, int r, int o);
	void andb_rm(int r, int m, int o);
	void andb_mr(int m, int r, int o);
	void andbi_ri(int r, int8_t i);
	void andbi_mi(int m, int8_t i, int o);
	void andi_ri(int r, int16_t i);
	void andi_mi(int m, int16_t i, int o);
	void call(int m, int16_t d, int o);
	void clr(int m, int b, int o);
	void dec_r(int r);
	void dec_m(int m, int o);
	void decb(int m, int o);
	void hlt();
	void inc_r(int r);
	void inc_m(int m, int o);
	void incb(int m, int o);
	void jbt(int m, int b, int16_t d, int o);
	void jmce(int m, int16_t d, int o);
	void jmcne(int m, int16_t d, int o);
	void jnbt(int m, int b, int16_t d, int o);
	void jnz_r(int r, int16_t d);
	void jnz_m(int m, int16_t d, int o);
	void jnzb(int m, int16_t d, int o);
	void jz_r(int r, int16_t d);
	void jz_m(int m, int16_t d, int o);
	void jzb(int m, int16_t d, int o);
	void lpd(int p, int m, int o);
	void lpdi(int p, int s, int o);
	void mov_mr(int m, int r, int o);
	void mov_rm(int r, int m, int o);
	void mov_mm(int m1, int m2, int o1, int o2);
	void movb_mr(int m, int r, int o);
	void movb_rm(int r, int m, int o);
	void movb_mm(int m1, int m2, int o1, int o2);
	void movbi_ri(int r, int8_t i);
	void movbi_mi(int m, int8_t i, int o);
	void movi_ri(int r, int16_t i);
	void movi_mi(int m, int16_t i, int o);
	void movp_mp(int m, int p, int o);
	void movp_pm(int p, int m, int o);
	void nop();
	void not_r(int r);
	void not_m(int m, int o);
	void not_rm(int r, int m, int o);
	void notb_m(int m, int o);
	void notb_rm(int r, int m, int o);
	void or_rm(int r, int m, int o);
	void or_mr(int m, int r, int o);
	void orb_rm(int r, int m, int o);
	void orb_mr(int m, int r, int o);
	void orbi_ri(int r, int8_t i);
	void orbi_mi(int m, int8_t i, int o);
	void ori_ri(int r, int16_t i);
	void ori_mi(int m, int16_t i, int o);
	void setb(int m, int b, int o);
	void sintr();
	void tsl(int m, int8_t i, int8_t d, int o);
	void wid(int s, int d);
	void xfer();
	void invalid(int opc);

	// instruction fetch
	int16_t displacement(int wb);
	uint32_t offset(int aa, int mm, int w);
	int8_t imm8();
	int16_t imm16();

	void examine_ccw(uint8_t ccw);

	devcb_write_line m_write_sintr;

	i8089_device *m_iop;

	int m_icount;

	// dma
	void terminate_dma(int offset);

	bool m_xfer_pending;
	uint16_t m_dma_value;
	int m_dma_state;
	bool m_drq;

	// dma state
	enum
	{
		DMA_IDLE,
		DMA_WAIT_FOR_SOURCE_DRQ,
		DMA_FETCH,
		DMA_TRANSLATE,
		DMA_WAIT_FOR_DEST_DRQ,
		DMA_STORE,
		DMA_STORE_BYTE_HIGH,
		DMA_COMPARE,
		DMA_TERMINATE
	};

	int m_prio;

	// priority
	enum
	{
		PRIO_DMA = 1,
		PRIO_DMA_TERM = 1,
		PRIO_PROG_CHAIN = 1,
		PRIO_CHAN_ATTN,
		PRIO_PROG,
		PRIO_IDLE
	};
};


// device type definition
extern const device_type I8089_CHANNEL;


#endif  /* __I8089_CHANNEL_H__ */