1 // license:BSD-3-Clause
2 // copyright-holders:F. Ulivi
3 /*********************************************************************
4 
5     tms9914.cpp
6 
7     Texas Instruments TMS9914(A) GPIB Controller
8 
9     TODO:
10     - A few interface commands
11     - A few auxiliary commands
12 
13     Main reference for this IC:
14     TI, jun 89, TMS9914A GPIB Controller - Data Manual
15 
16 **********************************************************************/
17 
18 #include "emu.h"
19 #include "tms9914.h"
20 
21 // Debugging
22 #define LOG_NOISY_MASK  (LOG_GENERAL << 1)
23 #define LOG_NOISY(...)  LOGMASKED(LOG_NOISY_MASK, __VA_ARGS__)
24 #define LOG_REG_MASK    (LOG_NOISY_MASK << 1)
25 #define LOG_REG(...)    LOGMASKED(LOG_REG_MASK, __VA_ARGS__)
26 #define LOG_INT_MASK    (LOG_REG_MASK << 1)
27 #define LOG_INT(...)    LOGMASKED(LOG_INT_MASK, __VA_ARGS__)
28 //#define VERBOSE (LOG_GENERAL)
29 #include "logmacro.h"
30 
31 // Bit manipulation
32 namespace {
BIT_MASK(unsigned n)33 	template<typename T> constexpr T BIT_MASK(unsigned n)
34 	{
35 		return (T)1U << n;
36 	}
37 
BIT_CLR(T & w,unsigned n)38 	template<typename T> void BIT_CLR(T& w , unsigned n)
39 	{
40 		w &= ~BIT_MASK<T>(n);
41 	}
42 
BIT_SET(T & w,unsigned n)43 	template<typename T> void BIT_SET(T& w , unsigned n)
44 	{
45 		w |= BIT_MASK<T>(n);
46 	}
47 }
48 
49 // Registers
50 enum {
51 	REG_R_INT_STAT0 = 0,    // R 0: Interrupt status 0
52 	REG_R_INT_STAT1 = 1,    // R 1: Interrupt status 1
53 	REG_R_ADDR_STAT = 2,    // R 2: Address status
54 	REG_R_BUS_STAT = 3,     // R 3: Bus status
55 	REG_R_CMD_PT = 6,       // R 6: Command pass-through
56 	REG_R_DI = 7,           // R 7: Data input
57 	REG_W_INT_MASK0 = 0,    // W 0: Interrupt mask 0
58 	REG_W_INT_MASK1 = 1,    // W 1: Interrupt mask 1
59 	REG_W_AUX_CMD = 3,      // W 3: Auxiliary command
60 	REG_W_ADDRESS = 4,      // W 4: Address
61 	REG_W_SERIAL_P = 5,     // W 5: Serial poll
62 	REG_W_PARALLEL_P = 6,   // W 6: Parallel poll
63 	REG_W_DO = 7            // W 7: Data output
64 };
65 
66 // Interrupt status/mask 0
67 constexpr unsigned REG_INT0_MAC_BIT = 0;    // My Address status Changed
68 constexpr unsigned REG_INT0_RLC_BIT = 1;    // Remote/Local status Changed
69 constexpr unsigned REG_INT0_SPAS_BIT = 2;   // Polled by serial poll
70 constexpr unsigned REG_INT0_END_BIT = 3;    // EOI received
71 constexpr unsigned REG_INT0_BO_BIT = 4;     // Byte Out interrupt
72 constexpr unsigned REG_INT0_BI_BIT = 5;     // Byte In interrupt
73 constexpr unsigned REG_INT0_INT1_BIT = 6;   // Interrupt(s) pending from INT1 register
74 constexpr unsigned REG_INT0_INT0_BIT = 7;   // Interrupt(s) pending from INT0 register
75 constexpr uint8_t  REG_INT0_INT_MASK = 0x3f;    // Mask of actual interrupt bits
76 
77 // Interrupt status/mask 1
78 constexpr unsigned REG_INT1_IFC_BIT = 0;    // IFC received
79 constexpr unsigned REG_INT1_SRQ_BIT = 1;    // SRQ asserted
80 constexpr unsigned REG_INT1_MA_BIT = 2;     // My address received
81 constexpr unsigned REG_INT1_DCAS_BIT = 3;   // DCAS state active
82 constexpr unsigned REG_INT1_APT_BIT = 4;    // Address Pass-Through
83 constexpr unsigned REG_INT1_UNC_BIT = 5;    // Unrecognized command
84 constexpr unsigned REG_INT1_ERR_BIT = 6;    // Source handshake error
85 constexpr unsigned REG_INT1_GET_BIT = 7;    // Group Execute Trigger
86 
87 // Address status register
88 constexpr unsigned REG_AS_ULPA_BIT = 0;     // LSB of last recognized address
89 constexpr unsigned REG_AS_TADS_BIT = 1;     // Addressed to talk
90 constexpr unsigned REG_AS_LADS_BIT = 2;     // Addressed to listen
91 constexpr unsigned REG_AS_TPAS_BIT = 3;     // TPAS state active
92 constexpr unsigned REG_AS_LPAS_BIT = 4;     // LPAS state active
93 constexpr unsigned REG_AS_ATN_BIT = 5;      // ATN asserted
94 constexpr unsigned REG_AS_LLO_BIT = 6;      // Local lockout enabled
95 constexpr unsigned REG_AS_REM_BIT = 7;      // Remote state enabled
96 
97 // Bus status register
98 constexpr unsigned REG_BS_REN_BIT = 0;
99 constexpr unsigned REG_BS_IFC_BIT = 1;
100 constexpr unsigned REG_BS_SRQ_BIT = 2;
101 constexpr unsigned REG_BS_EOI_BIT = 3;
102 constexpr unsigned REG_BS_NRFD_BIT = 4;
103 constexpr unsigned REG_BS_NDAC_BIT = 5;
104 constexpr unsigned REG_BS_DAV_BIT = 6;
105 constexpr unsigned REG_BS_ATN_BIT = 7;
106 
107 // Auxiliary command register
108 constexpr uint8_t  REG_AUXCMD_CMD_MASK = 0x1f;  // Mask of auxiliary command
109 constexpr unsigned REG_AUXCMD_CS_BIT = 7;       // Clear/set bit
110 
111 // Auxiliary commands
112 enum {
113 	AUXCMD_SWRST = 0x00,
114 	AUXCMD_DACR = 0x01,
115 	AUXCMD_RHDF = 0x02,
116 	AUXCMD_HDFA = 0x03,
117 	AUXCMD_HDFE = 0x04,
118 	AUXCMD_NBAF = 0x05,
119 	AUXCMD_FGET = 0x06,
120 	AUXCMD_RTL = 0x07,
121 	AUXCMD_FEOI = 0x08,
122 	AUXCMD_LON = 0x09,
123 	AUXCMD_TON = 0x0a,
124 	AUXCMD_GTS = 0x0b,
125 	AUXCMD_TCA = 0x0c,
126 	AUXCMD_TCS = 0x0d,
127 	AUXCMD_RPP = 0x0e,
128 	AUXCMD_SIC = 0x0f,
129 	AUXCMD_SRE = 0x10,
130 	AUXCMD_RQC = 0x11,
131 	AUXCMD_RLC = 0x12,
132 	AUXCMD_DAI = 0x13,
133 	AUXCMD_PTS = 0x14,
134 	AUXCMD_STDL = 0x15,
135 	AUXCMD_SHDW = 0x16,
136 	AUXCMD_VSTDL = 0x17,
137 	AUXCMD_RSV2 = 0x18
138 };
139 
140 // Address register
141 constexpr uint8_t  REG_ADDR_ADDR_MASK = 0x1f;   // Address mask
142 constexpr unsigned REG_ADDR_DAT_BIT = 5;        // Disable talker
143 constexpr unsigned REG_ADDR_DAL_BIT = 6;        // Disable listener
144 constexpr unsigned REG_ADDR_EDPA_BIT = 7;       // Dual primary address mode
145 
146 // Serial poll register
147 constexpr uint8_t  REG_SERIAL_P_MASK = 0xbf;    // Serial status mask
148 constexpr unsigned REG_SERIAL_P_RSV1_BIT = 6;   // Request service 1
149 
150 // Interface commands
151 constexpr uint8_t IFCMD_MASK       = 0x7f;  // Mask of valid bits in if. commands
152 constexpr uint8_t IFCMD_ACG_MASK   = 0x70;  // Mask of ACG commands
153 constexpr uint8_t IFCMD_ACG_VALUE  = 0x00;  // Value of ACG commands
154 constexpr uint8_t IFCMD_UCG_MASK   = 0x70;  // Mask of UCG commands
155 constexpr uint8_t IFCMD_UCG_VALUE  = 0x10;  // Value of UCG commands
156 constexpr uint8_t IFCMD_GROUP_MASK = 0x60;  // Mask of group id
157 constexpr uint8_t IFCMD_LAG_VALUE  = 0x20;  // Value of LAG commands
158 constexpr uint8_t IFCMD_TAG_VALUE  = 0x40;  // Value of TAG commands
159 constexpr uint8_t IFCMD_SCG_VALUE  = 0x60;  // Value of SCG commands
160 constexpr uint8_t IFCMD_GTL        = 0x01;  // Go to local
161 constexpr uint8_t IFCMD_SDC        = 0x04;  // Selected device clear
162 constexpr uint8_t IFCMD_GET        = 0x08;  // Group execute trigger
163 constexpr uint8_t IFCMD_TCT        = 0x09;  // Take control
164 constexpr uint8_t IFCMD_LLO        = 0x11;  // Local lock-out
165 constexpr uint8_t IFCMD_DCL        = 0x14;  // Device clear
166 constexpr uint8_t IFCMD_SPE        = 0x18;  // Serial poll enable
167 constexpr uint8_t IFCMD_SPD        = 0x19;  // Serial poll disable
168 constexpr uint8_t IFCMD_UNL        = 0x3f;  // Unlisten
169 constexpr uint8_t IFCMD_UNT        = 0x5f;  // Untalk
170 
171 // Device type definition
172 DEFINE_DEVICE_TYPE(TMS9914, tms9914_device, "tms9914", "TMS9914 GPIB Controller")
173 
174 // Constructors
tms9914_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)175 tms9914_device::tms9914_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
176 	: device_t(mconfig , TMS9914 , tag , owner , clock),
177 	  m_dio_read_func(*this),
178 	  m_dio_write_func(*this),
179 	  m_signal_wr_fns(*this),
180 	  m_int_write_func(*this),
181 	  m_accrq_write_func(*this)
182 {
183 	// Silence compiler complaints about unused variables
184 	(void)REG_INT1_IFC_BIT;
185 	(void)REG_INT1_GET_BIT;
186 }
187 
188 // Signal inputs
WRITE_LINE_MEMBER(tms9914_device::eoi_w)189 WRITE_LINE_MEMBER(tms9914_device::eoi_w)
190 {
191 	set_ext_signal(IEEE_488_EOI , state);
192 }
193 
WRITE_LINE_MEMBER(tms9914_device::dav_w)194 WRITE_LINE_MEMBER(tms9914_device::dav_w)
195 {
196 	set_ext_signal(IEEE_488_DAV , state);
197 }
198 
WRITE_LINE_MEMBER(tms9914_device::nrfd_w)199 WRITE_LINE_MEMBER(tms9914_device::nrfd_w)
200 {
201 	set_ext_signal(IEEE_488_NRFD , state);
202 }
203 
WRITE_LINE_MEMBER(tms9914_device::ndac_w)204 WRITE_LINE_MEMBER(tms9914_device::ndac_w)
205 {
206 	set_ext_signal(IEEE_488_NDAC , state);
207 }
208 
WRITE_LINE_MEMBER(tms9914_device::ifc_w)209 WRITE_LINE_MEMBER(tms9914_device::ifc_w)
210 {
211 	set_ext_signal(IEEE_488_IFC , state);
212 }
213 
WRITE_LINE_MEMBER(tms9914_device::srq_w)214 WRITE_LINE_MEMBER(tms9914_device::srq_w)
215 {
216 	bool prev_srq = get_signal(IEEE_488_SRQ);
217 	set_ext_signal(IEEE_488_SRQ , state);
218 	if (cont_r() && !prev_srq && get_signal(IEEE_488_SRQ)) {
219 		set_int1_bit(REG_INT1_SRQ_BIT);
220 	}
221 }
222 
WRITE_LINE_MEMBER(tms9914_device::atn_w)223 WRITE_LINE_MEMBER(tms9914_device::atn_w)
224 {
225 	set_ext_signal(IEEE_488_ATN , state);
226 }
227 
WRITE_LINE_MEMBER(tms9914_device::ren_w)228 WRITE_LINE_MEMBER(tms9914_device::ren_w)
229 {
230 	set_ext_signal(IEEE_488_REN , state);
231 }
232 
233 // Register I/O
write(offs_t offset,uint8_t data)234 void tms9914_device::write(offs_t offset, uint8_t data)
235 {
236 	LOG_REG("W %u=%02x\n" , offset , data);
237 
238 	switch (offset) {
239 	case REG_W_INT_MASK0:
240 		m_reg_int0_mask = data & REG_INT0_INT_MASK;
241 		update_int();
242 		break;
243 
244 	case REG_W_INT_MASK1:
245 		m_reg_int1_mask = data;
246 		update_int();
247 		break;
248 
249 	case REG_W_AUX_CMD:
250 		do_aux_cmd(data & REG_AUXCMD_CMD_MASK , BIT(data , REG_AUXCMD_CS_BIT));
251 		break;
252 
253 	case REG_W_ADDRESS:
254 		{
255 			uint8_t diff = m_reg_address ^ data;
256 			m_reg_address = data;
257 			if (BIT(diff , REG_ADDR_DAT_BIT) || BIT(diff , REG_ADDR_DAL_BIT)) {
258 				update_fsm();
259 			}
260 		}
261 		break;
262 
263 	case REG_W_SERIAL_P:
264 		{
265 			uint8_t diff = m_reg_2nd_serial_p ^ data;
266 			m_reg_2nd_serial_p = data;
267 			if (BIT(diff , REG_SERIAL_P_RSV1_BIT)) {
268 				update_fsm();
269 			}
270 		}
271 		break;
272 
273 	case REG_W_PARALLEL_P:
274 		m_reg_2nd_parallel_p = data;
275 		break;
276 
277 	case REG_W_DO:
278 		m_reg_do = data;
279 
280 		if (m_next_eoi) {
281 			m_next_eoi = false;
282 			if (!m_swrst) {
283 				if (m_t_eoi_state == FSM_T_ENIS) {
284 					m_t_eoi_state = FSM_T_ENRS;
285 				} else if (m_t_eoi_state == FSM_T_ENAS) {
286 					m_t_eoi_state = FSM_T_ERAS;
287 				}
288 			}
289 
290 		}
291 
292 		set_accrq(false);
293 		if (!m_swrst) {
294 			BIT_CLR(m_reg_int0_status , REG_INT0_BO_BIT);
295 			update_int();
296 			if (m_t_eoi_state == FSM_T_ENRS) {
297 				m_t_eoi_state = FSM_T_ERAS;
298 			} else if (m_t_eoi_state == FSM_T_ENAS) {
299 				m_t_eoi_state = FSM_T_ENIS;
300 			}
301 			bool update = sh_active();
302 			if (m_sh_shfs) {
303 				m_sh_shfs = false;
304 				update = true;
305 			}
306 			if (update) {
307 				update_fsm();
308 			}
309 		}
310 		break;
311 
312 	default:
313 		LOG("Write to unmapped reg %u\n" , offset);
314 		break;
315 	}
316 }
317 
read(offs_t offset)318 uint8_t tms9914_device::read(offs_t offset)
319 {
320 	uint8_t res;
321 
322 	switch (offset) {
323 	case REG_R_INT_STAT0:
324 		res = m_reg_int0_status;
325 		m_reg_int0_status = 0;
326 		update_int();
327 		break;
328 
329 	case REG_R_INT_STAT1:
330 		res = m_reg_int1_status;
331 		m_reg_int1_status = 0;
332 		update_int();
333 		break;
334 
335 	case REG_R_ADDR_STAT:
336 		res = 0;
337 		if (m_reg_ulpa) {
338 			BIT_SET(res , REG_AS_ULPA_BIT);
339 		}
340 		if (m_t_state != FSM_T_TIDS) {
341 			BIT_SET(res , REG_AS_TADS_BIT);
342 		}
343 		if (m_l_state != FSM_L_LIDS) {
344 			BIT_SET(res , REG_AS_LADS_BIT);
345 		}
346 		if (m_t_tpas) {
347 			BIT_SET(res , REG_AS_TPAS_BIT);
348 		}
349 		if (m_l_lpas) {
350 			BIT_SET(res , REG_AS_LPAS_BIT);
351 		}
352 		if (get_signal(IEEE_488_ATN)) {
353 			BIT_SET(res , REG_AS_ATN_BIT);
354 		}
355 		if (m_rl_state == FSM_RL_RWLS || m_rl_state == FSM_RL_LWLS) {
356 			BIT_SET(res , REG_AS_LLO_BIT);
357 		}
358 		if (m_rl_state == FSM_RL_REMS || m_rl_state == FSM_RL_RWLS) {
359 			BIT_SET(res , REG_AS_REM_BIT);
360 		}
361 		break;
362 
363 	case REG_R_BUS_STAT:
364 		res = 0;
365 		if (get_signal(IEEE_488_REN)) {
366 			BIT_SET(res , REG_BS_REN_BIT);
367 		}
368 		if (get_ifcin()) {
369 			BIT_SET(res , REG_BS_IFC_BIT);
370 		}
371 		if (get_signal(IEEE_488_SRQ)) {
372 			BIT_SET(res , REG_BS_SRQ_BIT);
373 		}
374 		if (get_signal(IEEE_488_EOI)) {
375 			BIT_SET(res , REG_BS_EOI_BIT);
376 		}
377 		if (get_signal(IEEE_488_NRFD)) {
378 			BIT_SET(res , REG_BS_NRFD_BIT);
379 		}
380 		if (get_signal(IEEE_488_NDAC)) {
381 			BIT_SET(res , REG_BS_NDAC_BIT);
382 		}
383 		if (get_signal(IEEE_488_DAV)) {
384 			BIT_SET(res , REG_BS_DAV_BIT);
385 		}
386 		if (get_signal(IEEE_488_ATN)) {
387 			BIT_SET(res , REG_BS_ATN_BIT);
388 		}
389 		break;
390 
391 	case REG_R_CMD_PT:
392 		res = get_dio();
393 		break;
394 
395 	case REG_R_DI:
396 		res = m_reg_di;
397 		BIT_CLR(m_reg_int0_status , REG_INT0_BI_BIT);
398 		update_int();
399 		set_accrq(false);
400 		if (!m_hdfa && m_ah_anhs) {
401 			m_ah_anhs = false;
402 			update_fsm();
403 		}
404 		// TODO: ACRS -> ANRS ?
405 		break;
406 
407 	default:
408 		LOG("Read from unmapped reg %u\n" , offset);
409 		res = 0;
410 		break;
411 	}
412 
413 	LOG_REG("R %u=%02x\n" , offset , res);
414 	return res;
415 }
416 
READ_LINE_MEMBER(tms9914_device::cont_r)417 READ_LINE_MEMBER(tms9914_device::cont_r)
418 {
419 	return m_c_state != FSM_C_CIDS && m_c_state != FSM_C_CADS;
420 }
421 
422 // device-level overrides
device_start()423 void tms9914_device::device_start()
424 {
425 	save_item(NAME(m_int_line));
426 	save_item(NAME(m_accrq_line));
427 	save_item(NAME(m_dio));
428 	save_item(NAME(m_signals));
429 	save_item(NAME(m_ext_signals));
430 	save_item(NAME(m_no_reflection));
431 	save_item(NAME(m_ext_state_change));
432 	save_item(NAME(m_reg_int0_status));
433 	save_item(NAME(m_reg_int0_mask));
434 	save_item(NAME(m_reg_int1_status));
435 	save_item(NAME(m_reg_int1_mask));
436 	save_item(NAME(m_reg_address));
437 	save_item(NAME(m_reg_serial_p));
438 	save_item(NAME(m_reg_2nd_serial_p));
439 	save_item(NAME(m_reg_parallel_p));
440 	save_item(NAME(m_reg_2nd_parallel_p));
441 	save_item(NAME(m_reg_di));
442 	save_item(NAME(m_reg_do));
443 	save_item(NAME(m_reg_ulpa));
444 	save_item(NAME(m_swrst));
445 	save_item(NAME(m_hdfa));
446 	save_item(NAME(m_hdfe));
447 	save_item(NAME(m_rtl));
448 	save_item(NAME(m_gts));
449 	save_item(NAME(m_rpp));
450 	save_item(NAME(m_sic));
451 	save_item(NAME(m_sre));
452 	save_item(NAME(m_dai));
453 	save_item(NAME(m_pts));
454 	save_item(NAME(m_stdl));
455 	save_item(NAME(m_shdw));
456 	save_item(NAME(m_vstdl));
457 	save_item(NAME(m_rsvd2));
458 	save_item(NAME(m_ah_state));
459 	save_item(NAME(m_ah_adhs));
460 	save_item(NAME(m_ah_anhs));
461 	save_item(NAME(m_sh_state));
462 	save_item(NAME(m_sh_shfs));
463 	save_item(NAME(m_sh_vsts));
464 	save_item(NAME(m_t_state));
465 	save_item(NAME(m_t_tpas));
466 	save_item(NAME(m_t_spms));
467 	save_item(NAME(m_t_eoi_state));
468 	save_item(NAME(m_l_state));
469 	save_item(NAME(m_l_lpas));
470 	save_item(NAME(m_sr_state));
471 	save_item(NAME(m_rl_state));
472 	save_item(NAME(m_pp_ppas));
473 	save_item(NAME(m_c_state));
474 	save_item(NAME(m_next_eoi));
475 
476 	m_dio_read_func.resolve_safe(0xff);
477 	m_dio_write_func.resolve_safe();
478 	m_signal_wr_fns.resolve_all_safe();
479 	m_int_write_func.resolve_safe();
480 	m_accrq_write_func.resolve_safe();
481 
482 	m_sh_dly_timer = timer_alloc(SH_DELAY_TMR_ID);
483 	m_ah_dly_timer = timer_alloc(AH_DELAY_TMR_ID);
484 	m_c_dly_timer = timer_alloc(C_DELAY_TMR_ID);
485 }
486 
device_reset()487 void tms9914_device::device_reset()
488 {
489 	m_no_reflection = false;
490 	m_ext_state_change = false;
491 	m_swrst = true;
492 	m_hdfa = false;
493 	m_hdfe = false;
494 	m_rtl = false;
495 	m_rpp = false;
496 	m_sic = false;
497 	m_sre = false;
498 	m_dai = false;
499 	m_pts = false;
500 	m_stdl = false;
501 	m_shdw = false;
502 	m_vstdl = false;
503 	m_accrq_line = true;    // Ensure change is propagated
504 
505 	m_reg_serial_p = 0;
506 	m_reg_2nd_serial_p = 0;
507 	m_reg_parallel_p = 0;
508 	m_reg_2nd_parallel_p = 0;
509 
510 	m_reg_ulpa = false;
511 	std::fill(std::begin(m_ext_signals), std::end(m_ext_signals), false);
512 
513 	do_swrst();
514 	update_fsm();
515 	update_int();
516 	update_ifc();
517 	update_ren();
518 }
519 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)520 void tms9914_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
521 {
522 	LOG_NOISY("tmr %d\n" , id);
523 	update_fsm();
524 }
525 
get_dio()526 uint8_t tms9914_device::get_dio()
527 {
528 	return ~m_dio_read_func();
529 }
530 
set_dio(uint8_t data)531 void tms9914_device::set_dio(uint8_t data)
532 {
533 	if (data != m_dio) {
534 		LOG_NOISY("DIO=%02x\n" , data);
535 		m_dio = data;
536 		m_dio_write_func(~data);
537 	}
538 }
539 
get_signal(ieee_488_signal_t signal) const540 bool tms9914_device::get_signal(ieee_488_signal_t signal) const
541 {
542 	return m_ext_signals[ signal ];
543 }
544 
get_ifcin() const545 bool tms9914_device::get_ifcin() const
546 {
547 	return get_signal(IEEE_488_IFC) && !m_sic;
548 }
549 
set_ext_signal(ieee_488_signal_t signal,int state)550 void tms9914_device::set_ext_signal(ieee_488_signal_t signal , int state)
551 {
552 	state = !state;
553 	if (m_ext_signals[ signal ] != state) {
554 		m_ext_signals[ signal ] = state;
555 		LOG_NOISY("EXT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" ,
556 				  m_ext_signals[ IEEE_488_EOI ] ,
557 				  m_ext_signals[ IEEE_488_DAV ] ,
558 				  m_ext_signals[ IEEE_488_NRFD ] ,
559 				  m_ext_signals[ IEEE_488_NDAC ] ,
560 				  m_ext_signals[ IEEE_488_IFC ] ,
561 				  m_ext_signals[ IEEE_488_SRQ ] ,
562 				  m_ext_signals[ IEEE_488_ATN ] ,
563 				  m_ext_signals[ IEEE_488_REN ]);
564 		update_fsm();
565 	}
566 }
567 
set_signal(ieee_488_signal_t signal,bool state)568 void tms9914_device::set_signal(ieee_488_signal_t signal , bool state)
569 {
570 	if (state != m_signals[ signal ]) {
571 		m_signals[ signal ] = state;
572 		LOG_NOISY("INT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" ,
573 				  m_signals[ IEEE_488_EOI ] ,
574 				  m_signals[ IEEE_488_DAV ] ,
575 				  m_signals[ IEEE_488_NRFD ] ,
576 				  m_signals[ IEEE_488_NDAC ] ,
577 				  m_signals[ IEEE_488_IFC ] ,
578 				  m_signals[ IEEE_488_SRQ ] ,
579 				  m_signals[ IEEE_488_ATN ] ,
580 				  m_signals[ IEEE_488_REN ]);
581 		m_signal_wr_fns[ signal ](!state);
582 	}
583 }
584 
do_swrst()585 void tms9914_device::do_swrst()
586 {
587 	m_reg_int0_status = 0;
588 	m_reg_int1_status = 0;
589 
590 	m_ah_state = FSM_AH_AIDS;
591 	m_ah_adhs = false;
592 	m_ah_anhs = false;
593 	m_ah_aehs = false;
594 	m_sh_state = FSM_SH_SIDS;
595 	m_sh_shfs = true;
596 	m_sh_vsts = false;
597 	m_t_state = FSM_T_TIDS;
598 	m_t_tpas = false;
599 	m_t_spms = false;
600 	m_t_eoi_state = FSM_T_ENIS;
601 	m_l_state = FSM_L_LIDS;
602 	m_l_lpas = false;
603 	m_sr_state = FSM_SR_NPRS;
604 	m_rl_state = FSM_RL_LOCS;
605 	m_pp_ppas = false;
606 	m_c_state = FSM_C_CIDS;
607 	m_gts = false;
608 
609 	update_int();
610 	set_accrq(false);
611 }
612 
listener_reset() const613 bool tms9914_device::listener_reset() const
614 {
615 	return m_swrst || BIT(m_reg_address , REG_ADDR_DAL_BIT) || m_sic || get_ifcin();
616 }
617 
talker_reset() const618 bool tms9914_device::talker_reset() const
619 {
620 	return m_swrst || BIT(m_reg_address , REG_ADDR_DAT_BIT) || m_sic || get_ifcin();
621 }
622 
controller_reset() const623 bool tms9914_device::controller_reset() const
624 {
625 	return m_swrst || get_ifcin();
626 }
627 
sh_active() const628 bool tms9914_device::sh_active() const
629 {
630 	return m_sh_state == FSM_SH_SDYS || m_sh_state == FSM_SH_STRS || m_sh_state == FSM_SH_SERS;
631 }
632 
update_fsm()633 void tms9914_device::update_fsm()
634 {
635 	if (m_no_reflection) {
636 		return;
637 	}
638 
639 	m_no_reflection = true;
640 
641 	bool changed = true;
642 	int prev_state;
643 	// Loop until all changes settle
644 	while (changed) {
645 		LOG_NOISY("SH %d SHFS %d AH %d T %d TPAS %d L %d LPAS %d PP %d C %d\n" ,
646 				  m_sh_state , m_sh_shfs , m_ah_state , m_t_state , m_t_tpas ,
647 				  m_l_state , m_l_lpas , m_pp_ppas , m_c_state);
648 		changed = m_ext_state_change;
649 		m_ext_state_change = false;
650 
651 		// SH FSM
652 		prev_state = m_sh_state;
653 		bool sh_reset = m_swrst ||
654 			(get_signal(IEEE_488_ATN) && m_c_state != FSM_C_CACS) ||
655 			(!get_signal(IEEE_488_ATN) && !(m_t_state == FSM_T_TACS || m_t_state == FSM_T_SPAS));
656 
657 		if (get_signal(IEEE_488_ATN) || !m_vstdl) {
658 			m_sh_vsts = false;
659 		}
660 		if (sh_reset) {
661 			m_sh_state = FSM_SH_SIDS;
662 			m_sh_dly_timer->reset();
663 		} else {
664 			switch (m_sh_state) {
665 			case FSM_SH_SIDS:
666 				if (m_t_state == FSM_T_TACS ||
667 					m_t_state == FSM_T_SPAS ||
668 					m_c_state == FSM_C_CACS) {
669 					m_sh_state = FSM_SH_SGNS;
670 				}
671 				break;
672 
673 			case FSM_SH_SGNS:
674 				if (!m_sh_shfs || m_t_state == FSM_T_SPAS) {
675 					m_sh_state = FSM_SH_SDYS;
676 					unsigned clocks = m_sh_vsts ? 4 : (m_stdl ? 8 : 12);
677 					m_sh_dly_timer->adjust(clocks_to_attotime(clocks));
678 					LOG_NOISY("SH DLY %u\n" , clocks);
679 				}
680 				break;
681 
682 			case FSM_SH_SDYS:
683 				if (!m_t_spms) {
684 					if (m_t_eoi_state == FSM_T_ENRS) {
685 						m_t_eoi_state = FSM_T_ENIS;
686 					} else if (m_t_eoi_state == FSM_T_ERAS) {
687 						m_t_eoi_state = FSM_T_ENAS;
688 					}
689 				}
690 				if (!m_sh_dly_timer->enabled() && !get_signal(IEEE_488_NRFD)) {
691 					if (get_signal(IEEE_488_NDAC)) {
692 						m_sh_state = FSM_SH_STRS;
693 					} else {
694 						m_sh_state = FSM_SH_SERS;
695 						set_int1_bit(REG_INT1_ERR_BIT);
696 					}
697 				}
698 				break;
699 
700 			case FSM_SH_SERS:
701 				if (get_signal(IEEE_488_NDAC)) {
702 					m_sh_state = FSM_SH_STRS;
703 				}
704 				break;
705 
706 			case FSM_SH_STRS:
707 				if (m_t_state != FSM_T_SPAS) {
708 					m_sh_shfs = true;
709 				}
710 				if (!get_signal(IEEE_488_ATN) && m_vstdl) {
711 					m_sh_vsts = true;
712 				}
713 				if (!get_signal(IEEE_488_NDAC)) {
714 					if (VERBOSE & LOG_GENERAL) {
715 						bool const iscmd = m_signals[IEEE_488_ATN];
716 						char cmd[16] = "";
717 						if (iscmd) {
718 							uint8_t tmp = m_dio & 0x7f;
719 							if (tmp >= 0x20 && tmp <= 0x3f)
720 								snprintf(cmd, 16, "MLA%d", tmp & 0x1f);
721 							else if (tmp >= 0x40 && tmp <= 0x5f)
722 								snprintf(cmd, 16, "MTA%d", tmp & 0x1f);
723 							else if (tmp >= 0x60 && tmp <= 0x7f)
724 								snprintf(cmd, 16, "MSA%d", tmp & 0x1f);
725 						}
726 						LOG("%.6f TX %s %02X/%d %s\n" , machine().time().as_double() , m_signals[IEEE_488_ATN] ? "C" : "D", m_dio , m_signals[ IEEE_488_EOI ], cmd);
727 					}
728 					m_sh_state = FSM_SH_SGNS;
729 				}
730 				break;
731 
732 			default:
733 				LOG("Invalid SH state %d\n" , m_sh_state);
734 				m_sh_state = FSM_SH_SIDS;
735 			}
736 		}
737 		if (m_sh_state != prev_state) {
738 			changed = true;
739 			if (m_sh_state == FSM_SH_SGNS && m_sh_shfs &&
740 				m_t_state != FSM_T_SPAS) {
741 				// BO interrupt is raised when SGNS state is entered
742 				set_int0_bit(REG_INT0_BO_BIT);
743 			}
744 			if (prev_state == FSM_SH_STRS && m_t_state == FSM_T_SPAS &&
745 				(m_sr_state == FSM_SR_APRS1 || m_sr_state == FSM_SR_APRS2)) {
746 				set_int0_bit(REG_INT0_SPAS_BIT);
747 			}
748 		}
749 		// SH outputs
750 		// EOI is controlled by SH & C FSMs
751 		// DIO is controlled by SH & PP FSMs
752 		bool eoi_signal = false;
753 		uint8_t dio_byte = 0;
754 		set_signal(IEEE_488_DAV , m_sh_state == FSM_SH_STRS);
755 		if (sh_active()) {
756 			if (m_t_state == FSM_T_SPAS) {
757 				dio_byte = m_reg_serial_p & REG_SERIAL_P_MASK;
758 				if (m_sr_state == FSM_SR_APRS1 || m_sr_state == FSM_SR_APRS2) {
759 					// Set RQS
760 					BIT_SET(dio_byte , 6);
761 				}
762 			} else {
763 				dio_byte = m_reg_do;
764 			}
765 			eoi_signal = m_t_eoi_state == FSM_T_ERAS || m_t_eoi_state == FSM_T_ENAS;
766 		}
767 
768 		// AH FSM
769 		prev_state = m_ah_state;
770 		bool ah_reset = m_swrst ||
771 			(get_signal(IEEE_488_ATN) && cont_r()) ||
772 			(!get_signal(IEEE_488_ATN) && m_l_state != FSM_L_LADS && m_l_state != FSM_L_LACS);
773 		if (ah_reset) {
774 			m_ah_state = FSM_AH_AIDS;
775 			m_ah_dly_timer->reset();
776 		} else {
777 			switch (m_ah_state) {
778 			case FSM_AH_AIDS:
779 				m_ah_state = FSM_AH_ANRS;
780 				break;
781 
782 			case FSM_AH_ANRS:
783 				// See also the reading of DI register & RHDF command
784 				if (m_c_state != FSM_C_CWAS &&
785 					!get_signal(IEEE_488_DAV) &&
786 					(get_signal(IEEE_488_ATN) ||
787 					 (!m_ah_anhs && !m_ah_aehs))) {
788 					m_ah_state = FSM_AH_ACRS;
789 					m_ah_dly_timer->adjust(clocks_to_attotime(1));
790 				} else if (get_signal(IEEE_488_DAV)) {
791 					m_ah_state = FSM_AH_AWNS;
792 				}
793 				break;
794 
795 			case FSM_AH_ACRS:
796 				if (!get_signal(IEEE_488_ATN) &&
797 					(m_ah_anhs || m_ah_aehs)) {
798 					m_ah_state = FSM_AH_ANRS;
799 					m_ah_dly_timer->reset();
800 				} else if (!m_ah_dly_timer->enabled() && get_signal(IEEE_488_DAV)) {
801 					m_ah_state = FSM_AH_ACDS1;
802 					m_ah_dly_timer->adjust(clocks_to_attotime(get_signal(IEEE_488_ATN) ? 5 : 1));
803 				}
804 				break;
805 
806 			case FSM_AH_ACDS1:
807 				if (!get_signal(IEEE_488_DAV)) {
808 					m_ah_state = FSM_AH_ACRS;
809 					m_ah_dly_timer->adjust(clocks_to_attotime(1));
810 				} else if (!m_ah_dly_timer->enabled()) {
811 					m_ah_state = FSM_AH_ACDS2;
812 					if (get_signal(IEEE_488_ATN)) {
813 						// Got a command
814 						uint8_t if_cmd = get_dio();
815 						if_cmd_received(if_cmd & IFCMD_MASK);
816 					} else {
817 						// Got a DAB
818 						dab_received(get_dio() , get_signal(IEEE_488_EOI));
819 					}
820 				}
821 				break;
822 
823 			case FSM_AH_ACDS2:
824 				if (!m_ah_adhs || !get_signal(IEEE_488_ATN)) {
825 					m_ah_state = FSM_AH_AWNS;
826 				} else if (!get_signal(IEEE_488_DAV)) {
827 					m_ah_state = FSM_AH_ANRS;
828 				}
829 				break;
830 
831 			case FSM_AH_AWNS:
832 				if (!get_signal(IEEE_488_DAV)) {
833 					m_ah_state = FSM_AH_ANRS;
834 				}
835 				break;
836 
837 			default:
838 				LOG("Invalid AH state %d\n" , m_ah_state);
839 				m_ah_state = FSM_AH_AIDS;
840 			}
841 		}
842 		if (m_ah_state != prev_state) {
843 			changed = true;
844 		}
845 		// AH outputs
846 		set_signal(IEEE_488_NRFD , m_ah_state == FSM_AH_ANRS || m_ah_state == FSM_AH_ACDS1 || m_ah_state == FSM_AH_ACDS2 || m_ah_state == FSM_AH_AWNS);
847 		set_signal(IEEE_488_NDAC , m_ah_state == FSM_AH_ANRS || m_ah_state == FSM_AH_ACRS || m_ah_state == FSM_AH_ACDS1 || m_ah_state == FSM_AH_ACDS2);
848 
849 		// T FSM
850 		prev_state = m_t_state;
851 		if (talker_reset()) {
852 			m_t_state = FSM_T_TIDS;
853 		} else {
854 			switch (m_t_state) {
855 			case FSM_T_TIDS:
856 				break;
857 
858 			case FSM_T_TADS:
859 				if (!get_signal(IEEE_488_ATN)) {
860 					if (m_t_spms) {
861 						m_t_state = FSM_T_SPAS;
862 						// When entering SPAS, serial poll register is copied into the
863 						// register that is actually output (as it's double buffered)
864 						m_reg_serial_p = m_reg_2nd_serial_p;
865 					} else {
866 						m_t_state = FSM_T_TACS;
867 					}
868 				}
869 				break;
870 
871 			case FSM_T_TACS:
872 			case FSM_T_SPAS:
873 				if (get_signal(IEEE_488_ATN)) {
874 					m_t_state = FSM_T_TADS;
875 				}
876 				break;
877 
878 			default:
879 				LOG("Invalid T state %d\n" , m_t_state);
880 				m_t_state = FSM_T_TIDS;
881 			}
882 		}
883 		if (m_t_state != prev_state) {
884 			changed = true;
885 		}
886 		if (m_t_spms && (m_swrst || get_ifcin() || cont_r())) {
887 			m_t_spms = false;
888 			changed = true;
889 		}
890 		// No direct T outputs
891 
892 		// L FSM
893 		prev_state = m_l_state;
894 		if (listener_reset()) {
895 			m_l_state = FSM_L_LIDS;
896 		} else {
897 			switch (m_l_state) {
898 			case FSM_L_LIDS:
899 				break;
900 
901 			case FSM_L_LADS:
902 				if (!get_signal(IEEE_488_ATN)) {
903 					m_l_state = FSM_L_LACS;
904 				}
905 				break;
906 
907 			case FSM_L_LACS:
908 				if (get_signal(IEEE_488_ATN)) {
909 					m_l_state = FSM_L_LADS;
910 				}
911 				break;
912 
913 			default:
914 				LOG("Invalid L state %d\n" , m_l_state);
915 				m_l_state = FSM_L_LIDS;
916 			}
917 		}
918 		if (m_l_state != prev_state) {
919 			changed = true;
920 		}
921 		// No direct L outputs
922 
923 		// PP FSM
924 		if (!m_pp_ppas) {
925 			// PPSS
926 			if (!m_swrst && get_signal(IEEE_488_ATN) && get_signal(IEEE_488_EOI) && !cont_r()) {
927 				m_pp_ppas = true;
928 				changed = true;
929 				// Copy m_reg_2nd_parallel_p when entering PPAS
930 				m_reg_parallel_p = m_reg_2nd_parallel_p;
931 			}
932 		} else {
933 			// PPAS
934 			if (m_swrst || !get_signal(IEEE_488_ATN) || !get_signal(IEEE_488_EOI) || cont_r()) {
935 				m_pp_ppas = false;
936 				changed = true;
937 			}
938 		}
939 		// PP output
940 		if (m_pp_ppas) {
941 			dio_byte |= m_reg_parallel_p;
942 		}
943 
944 		// SR FSM
945 		prev_state = m_sr_state;
946 		if (m_swrst) {
947 			m_sr_state = FSM_SR_NPRS;
948 		} else {
949 			switch (m_sr_state) {
950 			case FSM_SR_NPRS:
951 				if (m_t_state != FSM_T_SPAS &&
952 					(BIT(m_reg_2nd_serial_p , REG_SERIAL_P_RSV1_BIT) || m_rsvd2)) {
953 					m_sr_state = FSM_SR_SRQS;
954 				}
955 				break;
956 
957 			case FSM_SR_SRQS:
958 				if (m_t_state == FSM_T_SPAS) {
959 					m_sr_state = FSM_SR_APRS1;
960 				} else if (!BIT(m_reg_2nd_serial_p , REG_SERIAL_P_RSV1_BIT) && !m_rsvd2) {
961 					m_sr_state = FSM_SR_NPRS;
962 				}
963 				break;
964 
965 			case FSM_SR_APRS1:
966 				if (m_t_state == FSM_T_SPAS && m_sh_state == FSM_SH_STRS) {
967 					m_rsvd2 = false;
968 				}
969 				if (!BIT(m_reg_2nd_serial_p , REG_SERIAL_P_RSV1_BIT) && !m_rsvd2) {
970 					m_sr_state = FSM_SR_APRS2;
971 				}
972 				break;
973 
974 			case FSM_SR_APRS2:
975 				if (m_t_state == FSM_T_SPAS) {
976 					if (m_sh_state == FSM_SH_STRS) {
977 						m_rsvd2 = false;
978 					}
979 				} else {
980 					m_sr_state = FSM_SR_NPRS;
981 				}
982 				break;
983 
984 			default:
985 				LOG("Invalid SR state %d\n" , m_sr_state);
986 				m_sr_state = FSM_SR_NPRS;
987 			}
988 		}
989 		if (m_sr_state != prev_state) {
990 			changed = true;
991 		}
992 		// SR outputs
993 		set_signal(IEEE_488_SRQ , m_sr_state == FSM_SR_SRQS);
994 
995 		// RL FSM
996 		if (m_rl_state != FSM_RL_LOCS && (m_swrst || !get_signal(IEEE_488_REN))) {
997 			m_rl_state = FSM_RL_LOCS;
998 			changed = true;
999 		}
1000 		// No direct RL outputs
1001 
1002 		// C outputs
1003 		prev_state = m_c_state;
1004 		if (controller_reset()) {
1005 			m_c_state = FSM_C_CIDS;
1006 			m_gts = false;
1007 			m_c_dly_timer->reset();
1008 		} else {
1009 			switch (m_c_state) {
1010 			case FSM_C_CIDS:
1011 				// See also sic & rqc aux commands
1012 				if (m_sic) {
1013 					m_c_state = FSM_C_CADS;
1014 				}
1015 				break;
1016 
1017 			case FSM_C_CADS:
1018 				if (!get_signal(IEEE_488_ATN)) {
1019 					m_c_state = FSM_C_CACS;
1020 				}
1021 				break;
1022 
1023 			case FSM_C_CACS:
1024 				if (m_rpp) {
1025 					m_c_state = FSM_C_CPWS;
1026 					m_gts = false;
1027 				} else if (m_gts && !sh_active()) {
1028 					m_c_state = FSM_C_CSBS;
1029 					m_gts = false;
1030 					// This ensures a BO interrupt is generated if TACS is active
1031 					m_sh_state = FSM_SH_SIDS;
1032 				}
1033 				break;
1034 
1035 			case FSM_C_CSBS:
1036 				// tcs -> CWAS
1037 				// tca -> CSHS
1038 				break;
1039 
1040 			case FSM_C_CWAS:
1041 				if (m_ah_state == FSM_AH_ANRS) {
1042 					m_c_state = FSM_C_CSHS;
1043 					m_c_dly_timer->adjust(clocks_to_attotime(8));
1044 				}
1045 				break;
1046 
1047 			case FSM_C_CSHS:
1048 				if (!m_c_dly_timer->enabled()) {
1049 					m_c_state = FSM_C_CSWS;
1050 					m_c_dly_timer->adjust(clocks_to_attotime(2));
1051 				}
1052 				break;
1053 
1054 			case FSM_C_CSWS:
1055 				if (!m_c_dly_timer->enabled()) {
1056 					m_c_state = FSM_C_CAWS;
1057 					m_c_dly_timer->adjust(clocks_to_attotime(8));
1058 				}
1059 				break;
1060 
1061 			case FSM_C_CAWS:
1062 				if (!m_c_dly_timer->enabled()) {
1063 					m_c_state = FSM_C_CACS;
1064 				}
1065 				break;
1066 
1067 			case FSM_C_CPWS:
1068 				if (!m_rpp) {
1069 					m_c_state = FSM_C_CAWS;
1070 					m_c_dly_timer->adjust(clocks_to_attotime(8));
1071 				}
1072 				break;
1073 
1074 			default:
1075 				LOG("Invalid C state %d\n" , m_c_state);
1076 				m_c_state = FSM_C_CIDS;
1077 			}
1078 		}
1079 		if (m_c_state != prev_state) {
1080 			changed = true;
1081 		}
1082 		set_signal(IEEE_488_ATN , m_c_state == FSM_C_CACS ||
1083 				   m_c_state == FSM_C_CSWS || m_c_state == FSM_C_CAWS ||
1084 				   m_c_state == FSM_C_CPWS);
1085 		eoi_signal = eoi_signal || m_c_state == FSM_C_CPWS;
1086 		set_signal(IEEE_488_EOI , eoi_signal);
1087 		set_dio(dio_byte);
1088 	}
1089 
1090 	m_no_reflection = false;
1091 }
1092 
is_my_address(uint8_t addr)1093 bool tms9914_device::is_my_address(uint8_t addr)
1094 {
1095 	uint8_t diff = (addr ^ m_reg_address) & REG_ADDR_ADDR_MASK;
1096 	if (BIT(m_reg_address , REG_ADDR_EDPA_BIT)) {
1097 		// If dual-address mode is enabled, difference in LSB of address is ignored
1098 		BIT_CLR(diff , 0);
1099 	}
1100 	if (diff == 0) {
1101 		m_reg_ulpa = BIT(addr , 0);
1102 	}
1103 	return diff == 0;
1104 }
1105 
do_LAF()1106 void tms9914_device::do_LAF()
1107 {
1108 	if (m_l_state == FSM_L_LIDS) {
1109 		m_l_state = FSM_L_LADS;
1110 		m_ext_state_change = true;
1111 	}
1112 	if (m_t_state != FSM_T_TIDS) {
1113 		m_t_state = FSM_T_TIDS;
1114 		m_ext_state_change = true;
1115 	}
1116 	if (m_rl_state == FSM_RL_LWLS) {
1117 		m_rl_state = FSM_RL_RWLS;
1118 		set_int0_bit(REG_INT0_RLC_BIT);
1119 	} else if (m_rl_state == FSM_RL_LOCS && !m_rtl && get_signal(IEEE_488_REN)) {
1120 		m_rl_state = FSM_RL_REMS;
1121 		set_int0_bit(REG_INT0_RLC_BIT);
1122 	}
1123 }
1124 
do_TAF()1125 void tms9914_device::do_TAF()
1126 {
1127 	if (m_t_state == FSM_T_TIDS) {
1128 		m_t_state = FSM_T_TADS;
1129 		m_ext_state_change = true;
1130 	}
1131 	if (m_l_state != FSM_L_LIDS) {
1132 		m_l_state = FSM_L_LIDS;
1133 		m_ext_state_change = true;
1134 	}
1135 }
1136 
if_cmd_received(uint8_t if_cmd)1137 void tms9914_device::if_cmd_received(uint8_t if_cmd)
1138 {
1139 	LOG("%.6f RX cmd:%02x\n" , machine().time().as_double() , if_cmd);
1140 
1141 	bool sahf = false;
1142 
1143 	// Any PCG command that is not MLA nor MTA clears LPAS & TPAS
1144 	if ((if_cmd & IFCMD_GROUP_MASK) != IFCMD_SCG_VALUE) {
1145 		m_l_lpas = false;
1146 		m_t_tpas = false;
1147 	}
1148 
1149 	switch (if_cmd) {
1150 	case IFCMD_GTL:
1151 		if (m_l_state == FSM_L_LADS) {
1152 			if (m_rl_state == FSM_RL_REMS) {
1153 				m_rl_state = FSM_RL_LOCS;
1154 				set_int0_bit(REG_INT0_RLC_BIT);
1155 			} else if (m_rl_state == FSM_RL_RWLS) {
1156 				m_rl_state = FSM_RL_LWLS;
1157 				set_int0_bit(REG_INT0_RLC_BIT);
1158 			}
1159 		}
1160 		break;
1161 
1162 	case IFCMD_SDC:
1163 		if (m_l_state == FSM_L_LADS) {
1164 			set_int1_bit(REG_INT1_DCAS_BIT);
1165 			sahf = BIT(m_reg_int1_mask , REG_INT1_DCAS_BIT);
1166 		}
1167 		break;
1168 
1169 	case IFCMD_GET:
1170 		// TODO:
1171 		break;
1172 
1173 	case IFCMD_TCT:
1174 		if (m_t_state == FSM_T_TADS) {
1175 			set_int1_bit(REG_INT1_UNC_BIT);
1176 			sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1177 		}
1178 		break;
1179 
1180 	case IFCMD_LLO:
1181 		if (m_rl_state == FSM_RL_LOCS && get_signal(IEEE_488_REN)) {
1182 			m_rl_state = FSM_RL_LWLS;
1183 		} else if (m_rl_state == FSM_RL_REMS) {
1184 			m_rl_state = FSM_RL_RWLS;
1185 		}
1186 		break;
1187 
1188 	case IFCMD_DCL:
1189 		set_int1_bit(REG_INT1_DCAS_BIT);
1190 		sahf = BIT(m_reg_int1_mask , REG_INT1_DCAS_BIT);
1191 		break;
1192 
1193 	case IFCMD_SPE:
1194 		if (!get_ifcin() && !m_t_spms) {
1195 			m_t_spms = true;
1196 			m_ext_state_change = true;
1197 		}
1198 		break;
1199 
1200 	case IFCMD_SPD:
1201 		if (m_t_spms) {
1202 			m_t_spms = false;
1203 			m_ext_state_change = true;
1204 		}
1205 		break;
1206 
1207 	case IFCMD_UNL:
1208 		if (m_l_state != FSM_L_LIDS) {
1209 			m_l_state = FSM_L_LIDS;
1210 			set_int0_bit(REG_INT0_MAC_BIT);
1211 		}
1212 		break;
1213 
1214 	case IFCMD_UNT:
1215 		if (m_t_state != FSM_T_TIDS) {
1216 			m_t_state = FSM_T_TIDS;
1217 			set_int0_bit(REG_INT0_MAC_BIT);
1218 		}
1219 		break;
1220 
1221 	default:
1222 		if ((if_cmd & IFCMD_ACG_MASK) == IFCMD_ACG_VALUE) {
1223 			// ACG
1224 			if (m_l_state == FSM_L_LADS) {
1225 				set_int1_bit(REG_INT1_UNC_BIT);
1226 				sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1227 			}
1228 		} else if ((if_cmd & IFCMD_UCG_MASK) == IFCMD_UCG_VALUE) {
1229 			// UCG
1230 			set_int1_bit(REG_INT1_UNC_BIT);
1231 			sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1232 		} else if ((if_cmd & IFCMD_GROUP_MASK) == IFCMD_LAG_VALUE) {
1233 			// LAG
1234 			if (is_my_address(if_cmd)) {
1235 				// MLA
1236 				m_l_lpas = true;
1237 				if (!BIT(m_reg_int1_mask , REG_INT1_APT_BIT)) {
1238 					// Not using secondary addressing
1239 					if (!listener_reset()) {
1240 						if (m_l_state != FSM_L_LADS) {
1241 							set_int0_bit(REG_INT0_MAC_BIT);
1242 						}
1243 						do_LAF();
1244 					}
1245 					if (!m_t_spms) {
1246 						set_int1_bit(REG_INT1_MA_BIT);
1247 						sahf = BIT(m_reg_int1_mask , REG_INT1_MA_BIT);
1248 					}
1249 				}
1250 			}
1251 		} else if ((if_cmd & IFCMD_GROUP_MASK) == IFCMD_TAG_VALUE) {
1252 			// TAG
1253 			if (is_my_address(if_cmd)) {
1254 				// MTA
1255 				m_t_tpas = true;
1256 				if (!BIT(m_reg_int1_mask , REG_INT1_APT_BIT)) {
1257 					// Not using secondary addressing
1258 					if (!talker_reset()) {
1259 						if (m_t_state != FSM_T_TADS) {
1260 							set_int0_bit(REG_INT0_MAC_BIT);
1261 						}
1262 						do_TAF();
1263 					}
1264 					if (!m_t_spms) {
1265 						set_int1_bit(REG_INT1_MA_BIT);
1266 						sahf = BIT(m_reg_int1_mask , REG_INT1_MA_BIT);
1267 					}
1268 				}
1269 			} else {
1270 				// OTA
1271 				if (m_t_state != FSM_T_TIDS) {
1272 					set_int0_bit(REG_INT0_MAC_BIT);
1273 				}
1274 				m_t_state = FSM_T_TIDS;
1275 			}
1276 		} else {
1277 			// SCG
1278 			if (m_pts) {
1279 				set_int1_bit(REG_INT1_UNC_BIT);
1280 				sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1281 				m_pts = false;
1282 			} else if (m_l_lpas || m_t_tpas) {
1283 				set_int1_bit(REG_INT1_APT_BIT);
1284 				sahf = BIT(m_reg_int1_mask , REG_INT1_APT_BIT);
1285 			}
1286 		}
1287 		break;
1288 	}
1289 
1290 	if (sahf) {
1291 		m_ah_adhs = true;
1292 	}
1293 }
1294 
dab_received(uint8_t dab,bool eoi)1295 void tms9914_device::dab_received(uint8_t dab , bool eoi)
1296 {
1297 	LOG("%.6f RX DAB:%02x/%d\n" , machine().time().as_double() , dab , eoi);
1298 	m_reg_di = dab;
1299 	if (!m_shdw) {
1300 		m_ah_anhs = true;
1301 		set_int0_bit(REG_INT0_BI_BIT);
1302 		if (eoi) {
1303 			set_int0_bit(REG_INT0_END_BIT);
1304 		}
1305 	}
1306 	if (m_hdfe && eoi) {
1307 		m_ah_aehs = true;
1308 	}
1309 }
1310 
do_aux_cmd(unsigned cmd,bool set_bit)1311 void tms9914_device::do_aux_cmd(unsigned cmd , bool set_bit)
1312 {
1313 	switch (cmd) {
1314 	case AUXCMD_SWRST:
1315 		if (set_bit && !m_swrst) {
1316 			do_swrst();
1317 		}
1318 		if (m_swrst != set_bit) {
1319 			m_swrst = set_bit;
1320 			update_fsm();
1321 		}
1322 		break;
1323 
1324 	case AUXCMD_DACR:
1325 		if (m_ah_adhs) {
1326 			m_ah_adhs = false;
1327 			if (BIT(m_reg_int1_mask , REG_INT1_APT_BIT)) {
1328 				// Using secondary addressing
1329 				if (set_bit && !listener_reset() && m_l_lpas) {
1330 					do_LAF();
1331 				}
1332 				if (!set_bit && m_t_state == FSM_T_TADS && m_t_tpas) {
1333 					m_t_state = FSM_T_TIDS;
1334 					m_ext_state_change = true;
1335 				}
1336 				if (set_bit && !talker_reset() && m_t_tpas) {
1337 					do_TAF();
1338 				}
1339 			}
1340 			update_fsm();
1341 		}
1342 		break;
1343 
1344 	case AUXCMD_RHDF:
1345 		// TODO: ACRS -> ANRS
1346 		if (m_ah_anhs || m_ah_aehs) {
1347 			m_ah_anhs = false;
1348 			m_ah_aehs = false;
1349 			update_fsm();
1350 		}
1351 		break;
1352 
1353 	case AUXCMD_HDFA:
1354 		if (!m_swrst) {
1355 			m_hdfa = set_bit;
1356 		}
1357 		break;
1358 
1359 	case AUXCMD_HDFE:
1360 		if (!m_swrst) {
1361 			m_hdfe = set_bit;
1362 		}
1363 		break;
1364 
1365 	case AUXCMD_NBAF:
1366 		m_t_eoi_state = FSM_T_ENIS;
1367 		if (!m_sh_shfs) {
1368 			m_sh_shfs = true;
1369 			update_fsm();
1370 		}
1371 		break;
1372 
1373 	case AUXCMD_FGET:
1374 		LOG("Unimplemented FGET cmd\n");
1375 		break;
1376 
1377 	case AUXCMD_RTL:
1378 		m_rtl = set_bit;
1379 		if (m_rtl && m_rl_state == FSM_RL_REMS) {
1380 			m_rl_state = FSM_RL_LOCS;
1381 			set_int0_bit(REG_INT0_RLC_BIT);
1382 		}
1383 		break;
1384 
1385 	case AUXCMD_FEOI:
1386 		m_next_eoi = true;
1387 		break;
1388 
1389 	case AUXCMD_LON:
1390 		if (set_bit) {
1391 			if (!listener_reset()) {
1392 				do_LAF();
1393 			}
1394 		} else {
1395 			m_l_state = FSM_L_LIDS;
1396 			m_ext_state_change = true;
1397 		}
1398 		update_fsm();
1399 		break;
1400 
1401 	case AUXCMD_TON:
1402 		if (set_bit) {
1403 			if (!talker_reset()) {
1404 				do_TAF();
1405 			}
1406 		} else {
1407 			m_t_state = FSM_T_TIDS;
1408 			m_ext_state_change = true;
1409 		}
1410 		update_fsm();
1411 		break;
1412 
1413 	case AUXCMD_GTS:
1414 		if (m_c_state == FSM_C_CACS) {
1415 			m_gts = true;
1416 			update_fsm();
1417 		}
1418 		break;
1419 
1420 	case AUXCMD_TCA:
1421 		if (m_c_state == FSM_C_CSBS) {
1422 			m_c_state = FSM_C_CSHS;
1423 			m_ext_state_change = true;
1424 			// Manual says delay is 8 clock cycles, but 10 at least are needed
1425 			// to pass diagb hpib diagnostic
1426 			//m_c_dly_timer->adjust(clocks_to_attotime(8));
1427 			m_c_dly_timer->adjust(clocks_to_attotime(10));
1428 			update_fsm();
1429 		}
1430 		break;
1431 
1432 	case AUXCMD_TCS:
1433 		if (m_c_state == FSM_C_CSBS) {
1434 			m_c_state = FSM_C_CWAS;
1435 			m_ext_state_change = true;
1436 			update_fsm();
1437 		}
1438 		break;
1439 
1440 	case AUXCMD_RPP:
1441 		if (!m_swrst && m_rpp != set_bit) {
1442 			m_rpp = set_bit;
1443 			update_fsm();
1444 		}
1445 		break;
1446 
1447 	case AUXCMD_SIC:
1448 		if (m_sic != set_bit) {
1449 			m_sic = set_bit;
1450 			update_ifc();
1451 			if (!controller_reset() && m_sic && m_c_state == FSM_C_CIDS) {
1452 				m_c_state = FSM_C_CADS;
1453 				m_ext_state_change = true;
1454 			}
1455 			update_fsm();
1456 		}
1457 		break;
1458 
1459 	case AUXCMD_SRE:
1460 		m_sre = set_bit;
1461 		update_ren();
1462 		break;
1463 
1464 	case AUXCMD_RQC:
1465 		if (!controller_reset() && m_c_state == FSM_C_CIDS) {
1466 			m_c_state = FSM_C_CADS;
1467 			m_ext_state_change = true;
1468 			update_fsm();
1469 		}
1470 		break;
1471 
1472 	case AUXCMD_RLC:
1473 		if (m_c_state != FSM_C_CIDS) {
1474 			m_c_state = FSM_C_CIDS;
1475 			m_ext_state_change = true;
1476 			update_fsm();
1477 		}
1478 		break;
1479 
1480 	case AUXCMD_DAI:
1481 		m_dai = set_bit;
1482 		update_int();
1483 		break;
1484 
1485 	case AUXCMD_PTS:
1486 		m_pts = true;
1487 		break;
1488 
1489 	case AUXCMD_STDL:
1490 		LOG("Unimplemented STDL=%d cmd\n" , set_bit);
1491 		break;
1492 
1493 	case AUXCMD_SHDW:
1494 		if (!m_swrst) {
1495 			m_shdw = set_bit;
1496 			if (m_shdw && m_ah_anhs) {
1497 				m_ah_anhs = false;
1498 				update_fsm();
1499 			}
1500 		}
1501 		break;
1502 
1503 	case AUXCMD_VSTDL:
1504 		LOG("Unimplemented VSTDL=%d cmd\n" , set_bit);
1505 		break;
1506 
1507 	case AUXCMD_RSV2:
1508 		if (set_bit != m_rsvd2) {
1509 			m_rsvd2 = set_bit;
1510 			update_fsm();
1511 		}
1512 		break;
1513 
1514 	default:
1515 		LOG("Unrecognized aux cmd %u\n" , cmd);
1516 		break;
1517 	}
1518 }
1519 
set_int0_bit(unsigned bit_no)1520 void tms9914_device::set_int0_bit(unsigned bit_no)
1521 {
1522 	BIT_SET(m_reg_int0_status , bit_no);
1523 	update_int();
1524 	if (bit_no == REG_INT0_BI_BIT || (bit_no == REG_INT0_BO_BIT && m_c_state != FSM_C_CACS)) {
1525 		set_accrq(true);
1526 	}
1527 }
1528 
set_int1_bit(unsigned bit_no)1529 void tms9914_device::set_int1_bit(unsigned bit_no)
1530 {
1531 	BIT_SET(m_reg_int1_status , bit_no);
1532 	update_int();
1533 }
1534 
update_int()1535 void tms9914_device::update_int()
1536 {
1537 	bool new_int_line = false;
1538 	m_reg_int0_status &= REG_INT0_INT_MASK;
1539 	if (m_reg_int0_status & m_reg_int0_mask) {
1540 		BIT_SET(m_reg_int0_status , REG_INT0_INT0_BIT);
1541 		new_int_line = true;
1542 	}
1543 	if (m_reg_int1_status & m_reg_int1_mask) {
1544 		BIT_SET(m_reg_int0_status , REG_INT0_INT1_BIT);
1545 		new_int_line = true;
1546 	}
1547 	if (m_dai) {
1548 		new_int_line = false;
1549 	}
1550 	if (new_int_line != m_int_line) {
1551 		LOG_INT("INT=%d\n" , new_int_line);
1552 		m_int_line = new_int_line;
1553 		m_int_write_func(m_int_line);
1554 	}
1555 }
1556 
update_ifc()1557 void tms9914_device::update_ifc()
1558 {
1559 	set_signal(IEEE_488_IFC , m_sic);
1560 }
1561 
update_ren()1562 void tms9914_device::update_ren()
1563 {
1564 	set_signal(IEEE_488_REN , m_sre);
1565 }
1566 
set_accrq(bool state)1567 void tms9914_device::set_accrq(bool state)
1568 {
1569 	if (state != m_accrq_line) {
1570 		LOG_INT("ACCRQ=%d\n" , state);
1571 		m_accrq_line = state;
1572 		m_accrq_write_func(m_accrq_line);
1573 	}
1574 }
1575