summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/i8291a.h
blob: d607ff8f0517fcec7b11f6b380eab86b9d881db7 (plain) (tree)
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408























































































































































































































































































































































































































                                                                                                       
// license:BSD-3-Clause
// copyright-holders: Sven Schnelle
/*********************************************************************

    i8291a.h

    I8291A GPIB controller

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

#ifndef MAME_MACHINE_I8291A_H
#define MAME_MACHINE_I8291A_H


#pragma once


#define MCFG_I8291A_INT_WRITE_CB(_write)                               \
	downcast<i8291a_device &>(*device).set_int_write_cb(DEVCB_##_write);

#define MCFG_I8291A_DREQ_WRITE_CB(_write)                               \
	downcast<i8291a_device &>(*device).set_dreq_write_cb(DEVCB_##_write);

#define MCFG_I8291A_TRIG_WRITE_CB(_write)                               \
	downcast<i8291a_device &>(*device).set_trig_write_cb(DEVCB_##_write);

#define MCFG_I8291A_DIO_READ_CB(_read)             \
	downcast<i8291a_device &>(*device).set_dio_read_cb(DEVCB_##_read);

#define MCFG_I8291A_DIO_WRITE_CB(_write)                   \
	downcast<i8291a_device &>(*device).set_dio_write_cb(DEVCB_##_write);

#define MCFG_I8291A_EOI_WRITE_CB(_write)                               \
	downcast<i8291a_device &>(*device).set_eoi_write_cb(DEVCB_##_write);

#define MCFG_I8291A_DAV_WRITE_CB(_write)                               \
	downcast<i8291a_device &>(*device).set_dav_write_cb(DEVCB_##_write);

#define MCFG_I8291A_NRFD_WRITE_CB(_write)                              \
	downcast<i8291a_device &>(*device).set_nrfd_write_cb(DEVCB_##_write);

#define MCFG_I8291A_NDAC_WRITE_CB(_write)                              \
	downcast<i8291a_device &>(*device).set_ndac_write_cb(DEVCB_##_write);

#define MCFG_I8291A_SRQ_WRITE_CB(_write)                               \
	downcast<i8291a_device &>(*device).set_srq_write_cb(DEVCB_##_write);


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

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

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

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

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

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

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

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

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

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

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

	// Signal inputs
	DECLARE_WRITE_LINE_MEMBER(reset_w);
	DECLARE_WRITE_LINE_MEMBER(dack_w);

	// GPIB port
	DECLARE_WRITE_LINE_MEMBER(eoi_w);
	DECLARE_WRITE_LINE_MEMBER(dav_w);
	DECLARE_WRITE_LINE_MEMBER(nrfd_w);
	DECLARE_WRITE_LINE_MEMBER(ndac_w);
	DECLARE_WRITE_LINE_MEMBER(ifc_w);
	DECLARE_WRITE_LINE_MEMBER(srq_w);
	DECLARE_WRITE_LINE_MEMBER(atn_w);
	DECLARE_WRITE_LINE_MEMBER(ren_w);
	DECLARE_WRITE8_MEMBER(dio_w);

	// register r/w functions

	DECLARE_WRITE8_MEMBER(dout_w);
	DECLARE_WRITE8_MEMBER(ie1_w);
	DECLARE_WRITE8_MEMBER(ie2_w);
	DECLARE_WRITE8_MEMBER(spoll_mode_w);
	DECLARE_WRITE8_MEMBER(addr_mode_w);
	DECLARE_WRITE8_MEMBER(aux_mode_w);
	DECLARE_WRITE8_MEMBER(addr01_w);
	DECLARE_WRITE8_MEMBER(eos_w);

	DECLARE_READ8_MEMBER(din_r);
	DECLARE_READ8_MEMBER(ints1_r);
	DECLARE_READ8_MEMBER(ints2_r);
	DECLARE_READ8_MEMBER(spoll_stat_r);
	DECLARE_READ8_MEMBER(addr_stat_r);
	DECLARE_READ8_MEMBER(cpt_r);
	DECLARE_READ8_MEMBER(addr0_r);
	DECLARE_READ8_MEMBER(addr1_r);
	void map(address_map &map);

private:

	// signal output
	devcb_write_line m_int_write_func;
	devcb_write_line m_dreq_write_func;
	devcb_write_line m_trig_write_func;
	devcb_write_line m_eoi_write_func;
	devcb_write_line m_dav_write_func;
	devcb_write_line m_nrfd_write_func;
	devcb_write_line m_ndac_write_func;
	devcb_write_line m_srq_write_func;

	devcb_write8 m_dio_write_func;
	devcb_read8 m_dio_read_func;

	void set_dav(bool state);
	void set_nrfd(bool state);
	void set_ndac(bool state);
	void set_eoi(bool state);
	void set_srq(bool state);


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

	void update_int();
	void handle_command();
	void run_fsm();
	void run_sh_fsm();
	void run_ah_fsm();
	void run_dt_fsm();
	void run_dc_fsm();
	void run_l_fsm();
	void run_lp_fsm();
	void run_t_fsm();
	void run_tp_fsm();
	void run_tsp_fsm();
	void run_sp_fsm();
	void run_pp_fsm();
	void run_rl_fsm();

	// registers

	uint8_t m_din;
	uint8_t m_dout;
	uint8_t m_ints1;
	uint8_t m_ints2;
	uint8_t m_ie1;
	uint8_t m_ie2;
	uint8_t m_address0;
	uint8_t m_address1;
	uint8_t m_eos;
	uint8_t m_spoll_mode;
	uint8_t m_address_mode;
	uint8_t m_address_status;
	uint8_t m_cpt;

	uint8_t m_auxa;
	uint8_t m_auxb;

	bool m_atn;
	bool m_ren;
	bool m_nrfd;
	bool m_ndac;
	bool m_dav;
	bool m_srq;
	bool m_ifc;
	bool m_eoi;
	uint8_t m_dio;

	bool m_nrfd_out;
	bool m_ndac_out;
	bool m_dav_out;
	bool m_srq_out;
	bool m_eoi_out;

	// internal signals

	bool m_pon;
	bool m_rdy;
	bool m_lpe;
	bool m_ist;
	bool m_rtl;
	bool m_apt_flag;
	bool m_cpt_flag;
	bool m_din_flag;
	bool m_nba;

	bool m_pp_sense;
	uint8_t m_pp_line;

	bool m_send_eoi;

	static constexpr int REG_INTS1_BI = 1 << 0;
	static constexpr int REG_INTS1_BO = 1 << 1;
	static constexpr int REG_INTS1_ERR = 1 << 2;
	static constexpr int REG_INTS1_DEC = 1 << 3;
	static constexpr int REG_INTS1_END = 1 << 4;
	static constexpr int REG_INTS1_GET = 1 << 5;
	static constexpr int REG_INTS1_APT = 1 << 6;
	static constexpr int REG_INTS1_CPT = 1 << 7;

	static constexpr int REG_INTS2_ADSC = 1 << 0;
	static constexpr int REG_INTS2_REMC = 1 << 1;
	static constexpr int REG_INTS2_LLOC = 1 << 2;
	static constexpr int REG_INTS2_SPC = 1 << 3;
	static constexpr int REG_INTS2_REM = 1 << 4;
	static constexpr int REG_INTS2_LLO = 1 << 5;
	static constexpr int REG_INTS2_SPAS = 1 << 6;
	static constexpr int REG_INTS2_INT = 1 << 7;

	static constexpr int REG_IE2_DMAI = 1 << 4;
	static constexpr int REG_IE2_DMAO = 1 << 5;

	static constexpr int REG_ADDRESS01_ARS = 1 << 7;
	static constexpr int REG_ADDRESS0_INT = 1 << 7;
	static constexpr int REG_ADDRESS_DT = 1 << 6;
	static constexpr int REG_ADDRESS_DL = 1 << 5;

	static constexpr int REG_ADDRESS_STATUS_MJMN = 1 << 0;
	static constexpr int REG_ADDRESS_STATUS_TA = 1 << 1;
	static constexpr int REG_ADDRESS_STATUS_LA = 1 << 2;
	static constexpr int REG_ADDRESS_STATUS_TPAS = 1 << 3;
	static constexpr int REG_ADDRESS_STATUS_LPAS = 1 << 4;
	static constexpr int REG_ADDRESS_STATUS_EOI = 1 << 5;
	static constexpr int REG_ADDRESS_STATUS_LON = 1 << 6;
	static constexpr int REG_ADDRESS_STATUS_TON = 1 << 7;

	static constexpr int REG_AUXB_CPT_ENABLE = 1 << 0;
	static constexpr int REG_AUXB_EOI_SPAS_ENABLE = 1 << 1;
	static constexpr int REG_AUXB_HS_TRANSFER = 1 << 2;
	static constexpr int REG_AUXB_INT_ACTIVE_LOW = 1 << 3;
	static constexpr int REG_AUXB_RFD_HOLDOFF_GET_DEC = 1 << 4;

	static constexpr int REG_AUXA_RFD_HOLDOFF_DATA = 1 << 0;
	static constexpr int REG_AUXA_RFD_HOLDOFF_END = 1 << 1;
	static constexpr int REG_AUXA_END_ON_EOS = 1 << 2;
	static constexpr int REG_AUXA_EOI_ON_EOS = 1 << 3;
	static constexpr int REG_AUXA_EOS_8BIT = 1 << 4;

	// AUX CMDs
	static constexpr int AUXCMD_IMMEDIATE_EXEC_PON = 0;
	static constexpr int AUXCMD_CLEAR_PP = 1;
	static constexpr int AUXCMD_CHIP_RESET = 2;
	static constexpr int AUXCMD_FINISH_HANDSHAKE = 3;
	static constexpr int AUXCMD_TRIGGER = 4;
	static constexpr int AUXCMD_CLEAR_RTL = 5;
	static constexpr int AUXCMD_SEND_EOI = 6;
	static constexpr int AUXCMD_NON_VALID_SA = 7;
	static constexpr int AUXCMD_PON = 8;
	static constexpr int AUXCMD_SET_PP = 9;
	static constexpr int AUXCMD_SET_RTL = 13;
	static constexpr int AUXCMD_VALID_SA = 15;

	// Interface commands
	// TODO: stolen from tms9914, move to common header file. PHI also defines this

	static constexpr uint8_t IFCMD_MASK       = 0x7f;  // Mask of valid bits in if. commands
	static constexpr uint8_t IFCMD_ACG_MASK   = 0x70;  // Mask of ACG commands
	static constexpr uint8_t IFCMD_ACG_VALUE  = 0x00;  // Value of ACG commands
	static constexpr uint8_t IFCMD_UCG_MASK   = 0x70;  // Mask of UCG commands
	static constexpr uint8_t IFCMD_UCG_VALUE  = 0x10;  // Value of UCG commands
	static constexpr uint8_t IFCMD_GROUP_MASK = 0x60;  // Mask of group id
	static constexpr uint8_t IFCMD_LAG_VALUE  = 0x20;  // Value of LAG commands
	static constexpr uint8_t IFCMD_TAG_VALUE  = 0x40;  // Value of TAG commands
	static constexpr uint8_t IFCMD_SCG_VALUE  = 0x60;  // Value of SCG commands
	static constexpr uint8_t IFCMD_GTL        = 0x01;  // Go to local
	static constexpr uint8_t IFCMD_SDC        = 0x04;  // Selected device clear
	static constexpr uint8_t IFCMD_GET        = 0x08;  // Group execute trigger
	static constexpr uint8_t IFCMD_TCT        = 0x09;  // Take control
	static constexpr uint8_t IFCMD_LLO        = 0x11;  // Local lock-out
	static constexpr uint8_t IFCMD_DCL        = 0x14;  // Device clear
	static constexpr uint8_t IFCMD_SPE        = 0x18;  // Serial poll enable
	static constexpr uint8_t IFCMD_SPD        = 0x19;  // Serial poll disable
	static constexpr uint8_t IFCMD_UNL        = 0x3f;  // Unlisten
	static constexpr uint8_t IFCMD_UNT        = 0x5f;  // Untalk

	enum class source_handshake_state : uint8_t {
		SIDS,
		SGNS,
		SDYS,
		STRS
	};

	enum class acceptor_handshake_state : uint8_t {
		AIDS,
		ANRS,
		ACRS,
		AWNS,
		ADYS,
		ACDS
	};

	enum class talker_state : uint8_t {
		TIDS,
		TADS,
		SPAS,
		TACS
	};

	enum class talker_primary_state : uint8_t {
		TPIS,
		TPAS
	};

	enum class listener_primary_state : uint8_t {
		LPIS,
		LPAS
	};

	enum class talker_serial_poll_state : uint8_t {
		SPIS,
		SPMS
	};

	enum class serial_poll_state : uint8_t {
		NPRS,
		SRQS,
		APRS
	};

	enum class listener_state : uint8_t {
		LIDS,
		LADS,
		LACS
	};

	enum class remote_local_state : uint8_t {
		LOCS,
		REMS,
		RWLS,
		LWLS
	};

	enum class parallel_poll_state : uint8_t {
		PPIS,
		PPSS,
		PPAS
	};

	enum class device_clear_state : uint8_t {
		DCIS,
		DCAS
	};

	enum class device_trigger_state : uint8_t {
		DTIS,
		DTAS
	};

	static const char *get_state_name(acceptor_handshake_state state);
	static const char *get_state_name(source_handshake_state state);
	static const char *get_state_name(talker_state state);
	static const char *get_state_name(talker_primary_state state);
	static const char *get_state_name(talker_serial_poll_state state);
	static const char *get_state_name(listener_state state);
	static const char *get_state_name(listener_primary_state state);
	static const char *get_state_name(device_clear_state state);
	static const char *get_state_name(device_trigger_state state);
	static const char *get_state_name(parallel_poll_state state);
	static const char *get_state_name(serial_poll_state state);
	static const char *get_state_name(remote_local_state state);

	template<typename T> void update_state(T &name, T state);

	source_handshake_state m_sh_state;
	acceptor_handshake_state m_ah_state;
	talker_state m_t_state;
	talker_primary_state m_tp_state;
	talker_serial_poll_state m_tsp_state;
	listener_state m_l_state;
	listener_primary_state m_lp_state;
	remote_local_state m_rl_state;
	serial_poll_state m_sp_state;
	parallel_poll_state m_pp_state;
	device_clear_state m_dc_state;
	device_trigger_state m_dt_state;
	bool m_state_changed;
	bool m_ignore_ext_signals;
	bool m_intr_out;
	bool m_dreq_out;
};

// device type definition
DECLARE_DEVICE_TYPE(I8291A, i8291a_device)

#endif // MAME_MACHINE_I8291A_H