1 // license:BSD-3-Clause
2 // copyright-holders:F. Ulivi
3 /*********************************************************************
4 
5     phi.h
6 
7     HP PHI (Processor-to-Hpib-Interface) (1AA6-6x04)
8 
9     PHI supports these features of HP-IB:
10     * SH1
11     * AH1
12     * T1/TE1
13     * L1/LE1
14     * SR1
15     * RL2
16     * PP1
17     * DC1
18     * DT1
19     * C1,C2,C3,C4,C5
20     * HP non-standard IDENTIFY sequence
21 
22     Fun fact: PHI has no clock input, its FSMs are driven only by
23     changes in input signals and by a few internal monostables
24 
25     Main reference for this ASIC:
26     HP 12009-90001, sep 82, HP12009A HP-IB Interface Reference Manual
27 
28 *********************************************************************/
29 
30 #include "emu.h"
31 #include "phi.h"
32 
33 // Debugging
34 #include "logmacro.h"
35 #define LOG_NOISY_MASK  (LOG_GENERAL << 1)
36 #define LOG_NOISY(...)  LOGMASKED(LOG_NOISY_MASK, __VA_ARGS__)
37 #define LOG_REG_MASK    (LOG_NOISY_MASK << 1)
38 #define LOG_REG(...)    LOGMASKED(LOG_REG_MASK, __VA_ARGS__)
39 #define LOG_INT_MASK    (LOG_REG_MASK << 1)
40 #define LOG_INT(...)    LOGMASKED(LOG_INT_MASK, __VA_ARGS__)
41 #undef VERBOSE
42 #define VERBOSE LOG_GENERAL
43 
44 // Bit manipulation
45 namespace {
BIT_MASK(unsigned n)46 	template<typename T> constexpr T BIT_MASK(unsigned n)
47 	{
48 		return (T)1U << n;
49 	}
50 
BIT_CLR(T & w,unsigned n)51 	template<typename T> void BIT_CLR(T& w , unsigned n)
52 	{
53 		w &= ~BIT_MASK<T>(n);
54 	}
55 
BIT_SET(T & w,unsigned n)56 	template<typename T> void BIT_SET(T& w , unsigned n)
57 	{
58 		w |= BIT_MASK<T>(n);
59 	}
60 }
61 
62 // Timers
63 enum {
64 	SH_DELAY_TMR_ID,
65 	C_DELAY_TMR_ID
66 };
67 
68 // Register addresses
69 enum {
70 	REG_R_INT_COND = 0, // R 0: Interrupting conditions
71 	REG_W_INT_COND = 0, // W 0: Interrupting conditions
72 	REG_R_INT_MASK = 1, // R 1: Interrupt mask
73 	REG_W_INT_MASK = 1, // W 1: Interrupt mask
74 	REG_R_INBOUND_FIFO = 2, // R 2: Inbound FIFO
75 	REG_W_OUTBOUND_FIFO = 2,// W 2: Outbound FIFO
76 	REG_R_STATUS = 3,   // R 3: Status
77 	REG_W_STATUS = 3,   // W 3: Status
78 	REG_R_CONTROL = 4,  // R 4: Control
79 	REG_W_CONTROL = 4,  // W 4: Control
80 	REG_R_ADDRESS = 5,  // R 5: HPIB address
81 	REG_W_ADDRESS = 5,  // W 5: HPIB address
82 	REG_R_1ST_ID = 6,   // R 6: 1st ID byte
83 	REG_W_1ST_ID = 6,   // W 6: 1st ID byte
84 	REG_R_2ND_ID = 7,   // R 7: 2nd ID byte
85 	REG_W_2ND_ID = 7    // W 7: 2nd ID byte
86 };
87 
88 // All valid bits in registers
89 constexpr uint16_t REG_ALL_MASK = 0xc0ff;
90 
91 // D0 & D1 bits
92 constexpr uint16_t REG_D0D1_MASK    = 0xc000;   // Mask of D0/D1 bits
93 constexpr unsigned REG_D0D1_SHIFT   = 14;   // Position of D0/D1 bits
94 
95 // D8-D15 bits
96 constexpr uint16_t REG_D08D15_MASK  = 0xff; // Mask of D8:D15 bits
97 
98 // Bits in INT_COND & INT_MASK
99 constexpr unsigned REG_INT_DEV_CLEAR_BIT    = 0;    // Device clear
100 constexpr unsigned REG_INT_FIFO_IDLE_BIT    = 1;    // FIFO idle
101 constexpr unsigned REG_INT_FIFO_AV_BIT      = 2;    // FIFO bytes available
102 constexpr unsigned REG_INT_FIFO_ROOM_BIT    = 3;    // FIFO room available
103 constexpr unsigned REG_INT_SRQ_BIT          = 4;    // Service request
104 constexpr unsigned REG_INT_PP_RESPONSE_BIT  = 5;    // PP response
105 constexpr unsigned REG_INT_PROC_ABORT_BIT   = 6;    // Processor handshake abort
106 constexpr unsigned REG_INT_STATUS_CH_BIT    = 7;    // Status change
107 constexpr unsigned REG_INT_PARITY_ERR_BIT   = 14;   // Parity error
108 constexpr unsigned REG_INT_PENDING_BIT      = 15;   // Interrupt pending
109 constexpr uint16_t REG_INT_CLEARABLE_MASK   = 0x40c1;   // Mask of clearable bits
110 constexpr uint16_t REG_INT_STATE_MASK       = 0x803e;   // Mask of "state" bits
111 
112 // Bits in inbound FIFO
113 //constexpr uint16_t REG_IFIFO_NORMAL_MASK  = 0x0000;   // Mask of D0/D1 bits for "normal" bytes
114 constexpr uint16_t REG_IFIFO_CNT_EXP_MASK   = 0x8000;   // Mask for a byte that caused byte count to expire
115 constexpr uint16_t REG_IFIFO_LAST_MASK      = 0xc000;   // Mask for last byte in a record
116 constexpr uint16_t REG_IFIFO_2_ADDR_MASK    = 0x4000;   // Mask for secondary addresses
117 constexpr unsigned REG_IFIFO_TALK_BIT       = 5;        // Bit of "talk" flag
118 
119 // Bits in outbound FIFO
120 constexpr unsigned REG_OFIFO_SPECIAL_BIT    = 14;   // Bit to discriminate between normal bytes and the rest
121 constexpr unsigned REG_OFIFO_END_BIT        = 15;   // Bit of EOI
122 constexpr uint16_t REG_OFIFO_IFCMD_MASK     = 0x4000;   // Mask of interface commands
123 constexpr uint16_t REG_OFIFO_UNCNT_MASK     = 0xc000;   // Mask of uncounted transfer enable
124 constexpr unsigned REG_OFIFO_LF_INH_BIT     = 15;   // Bit of LF detection inhibit
125 
126 // Bits in status register
127 constexpr unsigned REG_STATUS_DATA_FREEZE_BIT   = 0;    // Outbound data freeze
128 constexpr unsigned REG_STATUS_LISTEN_BIT        = 1;    // Addressed to listen
129 constexpr unsigned REG_STATUS_TALK_BIT          = 2;    // Addressed to talk or identify
130 constexpr unsigned REG_STATUS_SYS_CTRL_BIT      = 3;    // System controller
131 constexpr unsigned REG_STATUS_CONTROLLER_BIT    = 4;    // Current controller
132 constexpr unsigned REG_STATUS_REMOTE_BIT        = 5;    // Remote state
133 constexpr unsigned REG_STATUS_D0D1_BIT          = 6;    // D0/D1 bit access
134 constexpr uint16_t REG_STATUS_STATE_MASK        = 0x3e; // Mask of "state" bits
135 
136 // Bits in control register
137 constexpr unsigned REG_CTRL_INIT_OFIFO_BIT  = 0;    // Initialize outbound FIFO
138 constexpr unsigned REG_CTRL_DMA_FIFO_BIT    = 1;    // DMA FIFO selection
139 constexpr unsigned REG_CTRL_SERVICE_REQ_BIT = 2;    // Request service
140 constexpr unsigned REG_CTRL_PP_RESPONSE_BIT = 3;    // Respond to PP
141 constexpr unsigned REG_CTRL_IFC_BIT         = 4;    // IFC value
142 constexpr unsigned REG_CTRL_REN_BIT         = 5;    // REN value
143 constexpr unsigned REG_CTRL_PAR_FREEZE_BIT  = 6;    // Parity freeze
144 constexpr unsigned REG_CTRL_8BIT_PROC_BIT   = 7;    // 8-bit processor
145 
146 // Bits in address register
147 constexpr unsigned REG_ADDR_HPIB_ADDR_BIT   = 0;    // HPIB address LSB
148 constexpr unsigned REG_ADDR_LA_BIT          = 5;    // Listen always
149 constexpr unsigned REG_ADDR_TA_BIT          = 6;    // Talk always
150 constexpr unsigned REG_ADDR_ONLINE_BIT      = 7;    // Online
151 
152 // Interface commands
153 constexpr uint8_t  IFCMD_MASK           = 0x7f; // Mask of interface commands
154 constexpr uint8_t  IFCMD_DCL            = 0x14; // Device clear
155 constexpr uint8_t  IFCMD_GET            = 0x08; // Group execute trigger
156 constexpr uint8_t  IFCMD_GTL            = 0x01; // Go to local
157 constexpr uint8_t  IFCMD_LLO            = 0x11; // Local lock-out
158 constexpr uint8_t  IFCMD_AG_MASK        = 0x60; // Mask of bits identifying address group commands
159 constexpr uint8_t  IFCMD_ADDR_MASK      = 0x1f; // Mask of address in AG commands
160 constexpr uint8_t  IFCMD_LAG_VALUE      = 0x20; // Value of LAG commands
161 constexpr uint8_t  IFCMD_TAG_VALUE      = 0x40; // Value of TAG commands
162 constexpr uint8_t  IFCMD_SCG_VALUE      = 0x60; // Value of SCG commands
163 constexpr uint8_t  IFCMD_PPC            = 0x05; // Parallel poll configure
164 constexpr uint8_t  IFCMD_PPX_MASK       = 0x70; // Mask of PPE/PPD commands
165 constexpr uint8_t  IFCMD_PPE_VALUE      = 0x60; // Parallel poll enable
166 constexpr unsigned IFCMD_PPE_S_BIT      = 3;    // Position of "S" bit in PPE
167 constexpr uint8_t  IFCMD_PPE_PPR_MASK   = 7;    // Mask in PPE of PPR msg no.
168 constexpr uint8_t  IFCMD_PPD_VALUE      = 0x70; // Parallel poll disable
169 constexpr uint8_t  IFCMD_PPU            = 0x15; // Parallel poll unconfigure
170 constexpr uint8_t  IFCMD_SDC            = 0x04; // Selected device clear
171 constexpr uint8_t  IFCMD_SPD            = 0x19; // Serial poll disable
172 constexpr uint8_t  IFCMD_SPE            = 0x18; // Serial poll enable
173 constexpr uint8_t  IFCMD_TCT            = 0x09; // Take control
174 constexpr uint8_t  IFCMD_UNL            = 0x3f; // Unlisten
175 constexpr uint8_t  IFCMD_UNT            = 0x5f; // Untalk
176 
177 // Delays
178 constexpr unsigned DELAY_T1     = 2000; // T1: 2 us
179 constexpr unsigned DELAY_T7     = 500;  // T7: 0.5 us
180 constexpr unsigned DELAY_T9     = 1500; // T9: 1.5 us
181 constexpr unsigned DELAY_T10    = 1500; // T10: 1.5 us
182 
183 // Controller address
184 constexpr uint8_t CONTROLLER_ADDR   = 0x1e; // PHI always has this address when it's a system controller
185 
186 // Device type definition
187 DEFINE_DEVICE_TYPE(PHI, phi_device, "hp_phi", "HP Processor-to-HPIB Interface")
188 
189 // Constructors
phi_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)190 phi_device::phi_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
191 	: device_t(mconfig, type, tag, owner, clock),
192 	  m_dio_read_func(*this),
193 	  m_dio_write_func(*this),
194 	  m_signal_wr_fns(*this),
195 	  m_int_write_func(*this),
196 	  m_dmarq_write_func(*this),
197 	  m_sys_cntrl_read_func(*this)
198 {
199 }
200 
phi_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)201 phi_device::phi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
202 	: phi_device(mconfig, PHI, tag, owner, clock)
203 {
204 }
205 
WRITE_LINE_MEMBER(phi_device::eoi_w)206 WRITE_LINE_MEMBER(phi_device::eoi_w)
207 {
208 	set_ext_signal(PHI_488_EOI , state);
209 }
210 
WRITE_LINE_MEMBER(phi_device::dav_w)211 WRITE_LINE_MEMBER(phi_device::dav_w)
212 {
213 	set_ext_signal(PHI_488_DAV , state);
214 }
215 
WRITE_LINE_MEMBER(phi_device::nrfd_w)216 WRITE_LINE_MEMBER(phi_device::nrfd_w)
217 {
218 	set_ext_signal(PHI_488_NRFD , state);
219 }
220 
WRITE_LINE_MEMBER(phi_device::ndac_w)221 WRITE_LINE_MEMBER(phi_device::ndac_w)
222 {
223 	set_ext_signal(PHI_488_NDAC , state);
224 }
225 
WRITE_LINE_MEMBER(phi_device::ifc_w)226 WRITE_LINE_MEMBER(phi_device::ifc_w)
227 {
228 	set_ext_signal(PHI_488_IFC , state);
229 }
230 
WRITE_LINE_MEMBER(phi_device::srq_w)231 WRITE_LINE_MEMBER(phi_device::srq_w)
232 {
233 	set_ext_signal(PHI_488_SRQ , state);
234 }
235 
WRITE_LINE_MEMBER(phi_device::atn_w)236 WRITE_LINE_MEMBER(phi_device::atn_w)
237 {
238 	set_ext_signal(PHI_488_ATN , state);
239 }
240 
WRITE_LINE_MEMBER(phi_device::ren_w)241 WRITE_LINE_MEMBER(phi_device::ren_w)
242 {
243 	set_ext_signal(PHI_488_REN , state);
244 }
245 
bus_dio_w(uint8_t data)246 void phi_device::bus_dio_w(uint8_t data)
247 {
248 	update_pp();
249 }
250 
set_ext_signal(phi_488_signal_t signal,int state)251 void phi_device::set_ext_signal(phi_488_signal_t signal , int state)
252 {
253 	state = !state;
254 	if (m_ext_signals[ signal ] != state) {
255 		m_ext_signals[ signal ] = state;
256 		LOG_NOISY("EXT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" ,
257 				  m_ext_signals[ PHI_488_EOI ] ,
258 				  m_ext_signals[ PHI_488_DAV ] ,
259 				  m_ext_signals[ PHI_488_NRFD ] ,
260 				  m_ext_signals[ PHI_488_NDAC ] ,
261 				  m_ext_signals[ PHI_488_IFC ] ,
262 				  m_ext_signals[ PHI_488_SRQ ] ,
263 				  m_ext_signals[ PHI_488_ATN ] ,
264 				  m_ext_signals[ PHI_488_REN ]);
265 		update_fsm();
266 	}
267 }
268 
reg16_w(offs_t offset,uint16_t data)269 void phi_device::reg16_w(offs_t offset, uint16_t data)
270 {
271 	int_reg_w(offset , data & REG_ALL_MASK);
272 }
273 
reg16_r(offs_t offset)274 uint16_t phi_device::reg16_r(offs_t offset)
275 {
276 	uint16_t res;
277 
278 	switch (offset) {
279 	case REG_R_INT_COND:
280 		res = m_reg_int_cond & m_reg_int_mask;
281 		break;
282 
283 	case REG_R_INT_MASK:
284 		res = m_reg_int_mask;
285 		break;
286 
287 	case REG_R_INBOUND_FIFO:
288 		if (m_fifo_in.empty()) {
289 			if (m_c_state == PHI_C_CPPS) {
290 				res = get_pp_response();
291 			} else {
292 				BIT_SET(m_reg_int_cond, REG_INT_PROC_ABORT_BIT);
293 				res = 0;
294 			}
295 		} else {
296 			res = m_fifo_in.dequeue();
297 		}
298 		update_fsm();
299 		break;
300 
301 	case REG_R_STATUS:
302 		res = m_reg_status;
303 		break;
304 
305 	case REG_R_CONTROL:
306 		res = m_reg_control;
307 		break;
308 
309 	case REG_R_ADDRESS:
310 		res = m_reg_address;
311 		break;
312 
313 	case REG_R_1ST_ID:
314 		res = m_reg_1st_id;
315 		break;
316 
317 	case REG_R_2ND_ID:
318 		res = m_reg_2nd_id;
319 		break;
320 
321 	default:
322 		res = 0;
323 		LOG("Reading from unmapped address (%u)\n", offset);
324 		break;
325 	};
326 
327 	if (offset != REG_R_STATUS) {
328 		// Store D0/D1 in top bits of status register
329 		m_reg_status = (m_reg_status & ~(3U << REG_STATUS_D0D1_BIT)) |
330 			((res & REG_D0D1_MASK) >> (REG_D0D1_SHIFT - REG_STATUS_D0D1_BIT));
331 	}
332 
333 	LOG_REG("R %u=%04x\n" , offset , res);
334 	return res;
335 }
336 
reg8_w(offs_t offset,uint8_t data)337 void phi_device::reg8_w(offs_t offset, uint8_t data)
338 {
339 	int_reg_w(offset , data);
340 }
341 
reg8_r(offs_t offset)342 uint8_t phi_device::reg8_r(offs_t offset)
343 {
344 	return (uint8_t)reg16_r(offset);
345 }
346 
device_start()347 void phi_device::device_start()
348 {
349 	save_item(NAME(m_dio));
350 	save_item(NAME(m_signals));
351 	save_item(NAME(m_ext_signals));
352 	save_item(NAME(m_sys_controller));
353 	save_item(NAME(m_loopback));
354 	save_item(NAME(m_id_enabled));
355 	save_item(NAME(m_sh_state));
356 	save_item(NAME(m_ah_state));
357 	save_item(NAME(m_t_state));
358 	save_item(NAME(m_t_spms));
359 	save_item(NAME(m_l_state));
360 	save_item(NAME(m_sr_state));
361 	save_item(NAME(m_rl_rems));
362 	save_item(NAME(m_pp_state));
363 	save_item(NAME(m_ppr_msg));
364 	save_item(NAME(m_s_sense));
365 	save_item(NAME(m_c_state));
366 	save_item(NAME(m_sa_state));
367 	save_item(NAME(m_be_counter));
368 	save_item(NAME(m_reg_status));
369 	save_item(NAME(m_reg_int_cond));
370 	save_item(NAME(m_reg_int_mask));
371 	save_item(NAME(m_reg_1st_id));
372 	save_item(NAME(m_reg_2nd_id));
373 	save_item(NAME(m_reg_control));
374 	save_item(NAME(m_reg_address));
375 	save_item(NAME(m_nba_origin));
376 
377 	m_dio_read_func.resolve_safe(0xff);
378 	m_dio_write_func.resolve_safe();
379 	m_signal_wr_fns.resolve_all_safe();
380 	m_int_write_func.resolve_safe();
381 	m_dmarq_write_func.resolve_safe();
382 	m_sys_cntrl_read_func.resolve_safe(0);
383 
384 	m_sh_dly_timer = timer_alloc(SH_DELAY_TMR_ID);
385 	m_c_dly_timer = timer_alloc(C_DELAY_TMR_ID);
386 }
387 
device_reset()388 void phi_device::device_reset()
389 {
390 	m_dio = 0;
391 	for (auto& s : m_signals) {
392 		s = false;
393 	}
394 	for (auto& s : m_ext_signals) {
395 		s = false;
396 	}
397 	m_no_recursion = false;
398 	// The following variables are set "true" because m_reg_address is set to 0
399 	m_sys_controller = true;
400 	m_loopback = true;
401 	m_id_enabled = false;
402 	m_reg_status = 0;
403 	m_reg_int_cond = 0;
404 	m_reg_int_mask = 0;
405 	m_reg_1st_id = 0;
406 	m_reg_2nd_id = 0;
407 	m_reg_control = 0;
408 	m_reg_address = 0;
409 	m_fifo_in.clear();
410 	m_fifo_out.clear();
411 	m_int_line = false;
412 	m_int_write_func(false);
413 	m_dmarq_line = false;
414 	m_dmarq_write_func(false);
415 
416 	pon_msg();
417 	update_488();
418 }
419 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)420 void phi_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
421 {
422 	LOG_NOISY("tmr %d enabled %d\n" , id , timer.enabled());
423 	update_fsm();
424 }
425 
int_reg_w(offs_t offset,uint16_t data)426 void phi_device::int_reg_w(offs_t offset , uint16_t data)
427 {
428 	if (BIT(m_reg_control , REG_CTRL_8BIT_PROC_BIT)) {
429 		// In 8-bit mode, D0/D1 come from status register
430 		data = (data & REG_D08D15_MASK) | ((m_reg_status << (REG_D0D1_SHIFT - REG_STATUS_D0D1_BIT)) & REG_D0D1_MASK);
431 	}
432 
433 	LOG_REG("W %u=%04x\n" , offset , data);
434 
435 	switch (offset) {
436 	case REG_W_INT_COND:
437 		// Bits D1/D8/D9/D15 only are clearable when written to 1
438 		m_reg_int_cond &= ~(data & REG_INT_CLEARABLE_MASK);
439 		update_fsm();
440 		break;
441 
442 	case REG_W_INT_MASK:
443 		m_reg_int_mask = data;
444 		update_fsm();
445 		break;
446 
447 	case REG_W_OUTBOUND_FIFO:
448 		if (m_fifo_out.full()) {
449 			BIT_SET(m_reg_int_cond, REG_INT_PROC_ABORT_BIT);
450 		} else {
451 			m_fifo_out.enqueue(data);
452 		}
453 		update_fsm();
454 		break;
455 
456 	case REG_W_STATUS:
457 		// Copy D0/D1 access bits into status register
458 		m_reg_status = (m_reg_status & ~(3U << REG_STATUS_D0D1_BIT)) |
459 			(data & (3U << REG_STATUS_D0D1_BIT));
460 		if (BIT(data , REG_STATUS_DATA_FREEZE_BIT) && m_fifo_in.empty()) {
461 			BIT_CLR(m_reg_status, REG_STATUS_DATA_FREEZE_BIT);
462 		}
463 		update_fsm();
464 		break;
465 
466 	case REG_W_CONTROL:
467 		// D0/D1/D15 are not mapped into register
468 		m_reg_control = data & 0xfe;
469 		if (BIT(data , REG_CTRL_INIT_OFIFO_BIT)) {
470 			m_fifo_out.clear();
471 			if (m_c_state == PHI_C_CSBS) {
472 				// Take control asynchronously
473 				m_c_state = PHI_C_CSWS;
474 				m_c_dly_timer->adjust(attotime::from_nsec(DELAY_T7));
475 			}
476 		}
477 		if (m_loopback) {
478 			// TODO: better?
479 			m_id_enabled = BIT(m_reg_control , REG_CTRL_PP_RESPONSE_BIT);
480 		}
481 		update_fsm();
482 		break;
483 
484 	case REG_W_ADDRESS:
485 		{
486 			// No D0/D1 in register
487 			data &= REG_D08D15_MASK;
488 			bool prev_ol = BIT(m_reg_address , REG_ADDR_ONLINE_BIT);
489 			m_reg_address = data;
490 			bool current_ol = BIT(m_reg_address , REG_ADDR_ONLINE_BIT);
491 			m_sys_controller = !current_ol || m_sys_cntrl_read_func();
492 			m_loopback = !current_ol;
493 			if (!current_ol) {
494 				// IDENTIFY is enabled by PP_RESPONSE bit in control register
495 				m_id_enabled = BIT(m_reg_control , REG_CTRL_PP_RESPONSE_BIT);
496 			} else if (!prev_ol) {
497 				// Going on-line
498 				pon_msg();
499 				m_id_enabled = BIT(m_reg_control , REG_CTRL_PP_RESPONSE_BIT);
500 			}
501 			configure_pp_response();
502 			if (prev_ol != current_ol) {
503 				update_488();
504 			}
505 			update_fsm();
506 		}
507 		break;
508 
509 	case REG_W_1ST_ID:
510 		// No D0/D1 in register
511 		m_reg_1st_id = data & REG_D08D15_MASK;
512 		update_fsm();
513 		break;
514 
515 	case REG_W_2ND_ID:
516 		// No D0/D1 in register
517 		m_reg_2nd_id = data & REG_D08D15_MASK;
518 		update_fsm();
519 		break;
520 
521 	default:
522 		LOG("Writing to unmapped address (%u)\n", offset);
523 		break;
524 	}
525 }
526 
get_dio(void)527 uint8_t phi_device::get_dio(void)
528 {
529 	if (m_loopback) {
530 		return m_dio;
531 	} else {
532 		return ~m_dio_read_func();
533 	}
534 }
535 
set_dio(uint8_t data)536 void phi_device::set_dio(uint8_t data)
537 {
538 	if (data != m_dio) {
539 		LOG_NOISY("DIO=%02x\n" , data);
540 		m_dio = data;
541 		if (!m_loopback) {
542 			m_dio_write_func(~data);
543 		}
544 	}
545 }
546 
get_signal(phi_488_signal_t signal)547 bool phi_device::get_signal(phi_488_signal_t signal)
548 {
549 	if (m_loopback) {
550 		return m_signals[ signal ];
551 	} else {
552 		return m_ext_signals[ signal ];
553 	}
554 }
555 
set_signal(phi_488_signal_t signal,bool state)556 void phi_device::set_signal(phi_488_signal_t signal , bool state)
557 {
558 	if (state != m_signals[ signal ]) {
559 		m_signals[ signal ] = state;
560 		LOG_NOISY("INT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" ,
561 				  m_signals[ PHI_488_EOI ] ,
562 				  m_signals[ PHI_488_DAV ] ,
563 				  m_signals[ PHI_488_NRFD ] ,
564 				  m_signals[ PHI_488_NDAC ] ,
565 				  m_signals[ PHI_488_IFC ] ,
566 				  m_signals[ PHI_488_SRQ ] ,
567 				  m_signals[ PHI_488_ATN ] ,
568 				  m_signals[ PHI_488_REN ]);
569 		if (!m_loopback) {
570 			m_signal_wr_fns[ signal ](!state);
571 		}
572 	}
573 }
574 
pon_msg(void)575 void phi_device::pon_msg(void)
576 {
577 	m_sh_state = PHI_SH_SIDS;
578 	m_ah_state = PHI_AH_AIDS;
579 	m_t_state = PHI_T_TIDS;
580 	m_t_spms = false;
581 	m_l_state = PHI_L_LIDS;
582 	m_sr_state = PHI_SR_NPRS;
583 	m_rl_rems = false;
584 	m_pp_state = PHI_PP_PPIS;
585 	m_c_state = PHI_C_CIDS;
586 	m_sa_state = PHI_SA_NONE;
587 	m_be_counter = 0;
588 	m_nba_origin = NBA_NONE;
589 }
590 
update_488(void)591 void phi_device::update_488(void)
592 {
593 	if (m_loopback) {
594 		m_dio_write_func(~0);
595 		for (auto& f : m_signal_wr_fns) {
596 			f(1);
597 		}
598 	} else {
599 		m_dio_write_func(~m_dio);
600 		for (unsigned i = 0; i < PHI_488_SIGNAL_COUNT; i++) {
601 			m_signal_wr_fns[ i ](!m_signals[ i ]);
602 		}
603 	}
604 }
605 
update_fsm(void)606 void phi_device::update_fsm(void)
607 {
608 	if (m_no_recursion) {
609 		// Prevent recursion into this function whenever a signal change propagates through
610 		// set_ext_signal
611 		return;
612 	}
613 	m_no_recursion = true;
614 
615 	set_signal(PHI_488_IFC , m_sys_controller && BIT(m_reg_control , REG_CTRL_IFC_BIT));
616 	set_signal(PHI_488_REN , m_sys_controller && BIT(m_reg_control , REG_CTRL_REN_BIT));
617 
618 	// TODO: improve (see SR FSM)
619 	// This is not entirely correct but it works for now (on HP64K, the only system
620 	// where it's relevant)
621 	set_signal(PHI_488_SRQ , BIT(m_reg_control , REG_CTRL_SERVICE_REQ_BIT));
622 
623 	bool changed = true;
624 	int prev_state;
625 	uint8_t new_byte = 0;
626 	bool new_eoi = false;
627 	bool prev_cic = controller_in_charge();
628 	// TODO: SR FSM
629 	// Loop until all changes settle
630 	while (changed) {
631 		LOG_NOISY("SH %d AH %d T %d SPMS %d L %d SR %d PP %d PPR %u S %d C %d SA %d\n" ,
632 				  m_sh_state , m_ah_state , m_t_state , m_t_spms , m_l_state , m_sr_state ,
633 				  m_pp_state , m_ppr_msg , m_s_sense , m_c_state , m_sa_state);
634 		LOG_NOISY("O E/F=%d/%d I E/F=%d/%d\n" , m_fifo_out.empty() , m_fifo_out.full() , m_fifo_in.empty() , m_fifo_in.full());
635 		changed = false;
636 
637 		// SH FSM
638 		prev_state = m_sh_state;
639 		bool sh_reset =
640 			(get_signal(PHI_488_ATN) && !(m_c_state == PHI_C_CACS || m_c_state == PHI_C_CTRS)) ||
641 			(!get_signal(PHI_488_ATN) && !(m_t_state == PHI_T_TACS || m_t_state == PHI_T_SPAS || m_t_state == PHI_T_ID2 || m_t_state == PHI_T_ID4));
642 
643 		if (sh_reset) {
644 			m_sh_state = PHI_SH_SIDS;
645 			m_sh_dly_timer->reset();
646 		} else {
647 			switch (m_sh_state) {
648 			case PHI_SH_SIDS:
649 				if (m_t_state == PHI_T_TACS ||
650 					m_t_state == PHI_T_SPAS ||
651 					m_t_state == PHI_T_ID2 ||
652 					m_t_state == PHI_T_ID4 ||
653 					m_c_state == PHI_C_CACS) {
654 					m_sh_state = PHI_SH_SGNS;
655 				}
656 				break;
657 
658 			case PHI_SH_SGNS:
659 				if ((m_nba_origin = nba_msg(new_byte , new_eoi)) != NBA_NONE) {
660 					m_sh_state = PHI_SH_SDYS;
661 					m_sh_dly_timer->adjust(attotime::from_nsec(DELAY_T1));
662 					LOG_NOISY("SH DLY enabled %d\n" , m_sh_dly_timer->enabled());
663 				}
664 				break;
665 
666 			case PHI_SH_SDYS:
667 				if (!get_signal(PHI_488_NRFD) && !m_sh_dly_timer->enabled()) {
668 					m_sh_state = PHI_SH_STRS;
669 				}
670 				break;
671 
672 			case PHI_SH_STRS:
673 				if (!get_signal(PHI_488_NDAC)) {
674 					LOG("%.6f TX %02x/%d\n" , machine().time().as_double() , m_dio , m_signals[ PHI_488_EOI ]);
675 					m_sh_state = PHI_SH_SGNS;
676 					clear_nba((nba_origin_t)m_nba_origin);
677 				}
678 				break;
679 
680 			default:
681 				logerror("Invalid SH state %d\n" , m_sh_state);
682 				m_sh_state = PHI_SH_SIDS;
683 			}
684 		}
685 		if (m_sh_state != prev_state) {
686 			changed = true;
687 		}
688 
689 		// SH outputs
690 		// EOI is controlled by SH & C FSMs
691 		bool eoi_signal = false;
692 		uint8_t dio_byte = 0;
693 		set_signal(PHI_488_DAV , m_sh_state == PHI_SH_STRS);
694 		if (m_sh_state == PHI_SH_SDYS || m_sh_state == PHI_SH_STRS) {
695 			nba_msg(new_byte , new_eoi);
696 			dio_byte = new_byte;
697 			eoi_signal = new_eoi;
698 		}
699 
700 		// AH FSM
701 		prev_state = m_ah_state;
702 		bool ah_reset = !(get_signal(PHI_488_ATN) || m_l_state == PHI_L_LADS || m_l_state == PHI_L_LACS || m_c_state == PHI_C_CSBS);
703 		if (ah_reset) {
704 			m_ah_state = PHI_AH_AIDS;
705 		} else {
706 			switch (m_ah_state) {
707 			case PHI_AH_AIDS:
708 				m_ah_state = PHI_AH_ANRS;
709 				break;
710 
711 			case PHI_AH_ANRS:
712 				//if (!tcs_msg() && (get_signal(PHI_488_ATN) || rdy_msg())) {
713 				// According to standard either ATN or rdy should also be true, but rdy is always true in PHI
714 				if (!tcs_msg()) {
715 					m_ah_state = PHI_AH_ACRS;
716 				}
717 				break;
718 
719 			case PHI_AH_ACRS:
720 				if (get_signal(PHI_488_DAV)) {
721 					m_ah_state = PHI_AH_ACDS;
722 				}
723 				// rdy is always true
724 				// } else if (!get_signal(PHI_488_ATN) && !rdy_msg()) {
725 				//  m_ah_state = PHI_AH_ANRS;
726 				// }
727 				break;
728 
729 			case PHI_AH_ACDS:
730 				// FSM stays in this state until the acceptor has
731 				// accepted the data byte or the interface command.
732 				if (get_signal(PHI_488_ATN)) {
733 					uint8_t if_cmd = get_dio();
734 					bool parity_ok = odd_parity(if_cmd);
735 					if (!parity_ok) {
736 						BIT_SET(m_reg_int_cond , REG_INT_PARITY_ERR_BIT);
737 					}
738 					if (BIT(m_reg_control , REG_CTRL_PAR_FREEZE_BIT) && !parity_ok) {
739 						// With even parity and PARITY FREEZE set, command is ignored and
740 						// AH FSM freezes in ACDS
741 						m_ah_state = PHI_AH_ACDS_FROZEN;
742 					} else {
743 						// Clear parity bit & process command
744 						if_cmd &= IFCMD_MASK;
745 						if (if_cmd_received(if_cmd)) {
746 							m_ah_state = PHI_AH_AWNS;
747 						}
748 					}
749 				} else if (byte_received(get_dio() , get_signal(PHI_488_EOI))) {
750 					m_ah_state = PHI_AH_AWNS;
751 				}
752 				break;
753 
754 			case PHI_AH_ACDS_FROZEN:
755 			case PHI_AH_AWNS:
756 				if (!get_signal(PHI_488_DAV)) {
757 					m_ah_state = PHI_AH_ANRS;
758 				}
759 				break;
760 
761 			default:
762 				logerror("Invalid AH state %d\n" , m_ah_state);
763 				m_ah_state = PHI_AH_AIDS;
764 			}
765 		}
766 		if (m_ah_state != prev_state) {
767 			changed = true;
768 		}
769 		// AH outputs
770 		set_signal(PHI_488_NRFD , m_ah_state == PHI_AH_ANRS || m_ah_state == PHI_AH_ACDS || m_ah_state == PHI_AH_ACDS_FROZEN || m_ah_state == PHI_AH_AWNS);
771 		set_signal(PHI_488_NDAC , m_ah_state == PHI_AH_ANRS || m_ah_state == PHI_AH_ACRS || m_ah_state == PHI_AH_ACDS || m_ah_state == PHI_AH_ACDS_FROZEN);
772 
773 		// T FSM
774 		prev_state = m_t_state;
775 		if (get_signal(PHI_488_IFC)) {
776 			m_t_state = PHI_T_TIDS;
777 			m_t_spms = false;
778 		} else {
779 			switch (m_t_state) {
780 			case PHI_T_TIDS:
781 				if (ton_msg()) {
782 					m_t_state = PHI_T_TADS;
783 				}
784 				break;
785 
786 			case PHI_T_TADS:
787 				if (!get_signal(PHI_488_ATN)) {
788 					if (m_t_spms) {
789 						m_t_state = PHI_T_SPAS;
790 					} else {
791 						m_t_state = PHI_T_TACS;
792 					}
793 				}
794 				break;
795 
796 			case PHI_T_SPAS:
797 			case PHI_T_TACS:
798 				if (get_signal(PHI_488_ATN)) {
799 					m_t_state = PHI_T_TADS;
800 				}
801 				break;
802 
803 			case PHI_T_ID1:
804 				if (!get_signal(PHI_488_ATN)) {
805 					m_t_state = PHI_T_ID2;
806 				}
807 				break;
808 
809 			case PHI_T_ID2:
810 				if (get_signal(PHI_488_ATN)) {
811 					m_t_state = PHI_T_ID1;
812 				}
813 				break;
814 
815 			case PHI_T_ID3:
816 				if (!get_signal(PHI_488_ATN)) {
817 					m_t_state = PHI_T_ID4;
818 				}
819 				break;
820 
821 			case PHI_T_ID4:
822 				if (get_signal(PHI_488_ATN)) {
823 					m_t_state = PHI_T_ID3;
824 				}
825 				break;
826 
827 			case PHI_T_ID5:
828 				break;
829 
830 			default:
831 				logerror("Invalid T state %d\n" , m_t_state);
832 				m_t_state = PHI_T_TIDS;
833 			}
834 		}
835 		if (m_t_state != prev_state) {
836 			changed = true;
837 		}
838 		// No direct T outputs
839 
840 		// L FSM
841 		prev_state = m_l_state;
842 		if (get_signal(PHI_488_IFC)) {
843 			m_l_state = PHI_L_LIDS;
844 		} else {
845 			switch (m_l_state) {
846 			case PHI_L_LIDS:
847 				if (lon_msg()) {
848 					m_l_state = PHI_L_LADS;
849 				}
850 				break;
851 
852 			case PHI_L_LADS:
853 				if (!get_signal(PHI_488_ATN)) {
854 					m_l_state = PHI_L_LACS;
855 				}
856 				break;
857 
858 			case PHI_L_LACS:
859 				if (get_signal(PHI_488_ATN)) {
860 					m_l_state = PHI_L_LADS;
861 				}
862 				break;
863 
864 			default:
865 				logerror("Invalid L state %d\n" , m_l_state);
866 				m_l_state = PHI_L_LIDS;
867 			}
868 		}
869 		if (m_l_state != prev_state) {
870 			changed = true;
871 		}
872 		// No direct L outputs
873 
874 		// RL FSM
875 		if (!get_signal(PHI_488_REN) && m_rl_rems) {
876 			m_rl_rems = false;
877 			changed = true;
878 		}
879 		// No direct RL outputs
880 
881 		// PP FSM
882 		prev_state = m_pp_state;
883 		switch (m_pp_state) {
884 		case PHI_PP_PPIS:
885 			break;
886 
887 		case PHI_PP_PPSS:
888 			if (get_signal(PHI_488_ATN) && get_signal(PHI_488_EOI)) {
889 				m_pp_state = PHI_PP_PPAS;
890 			}
891 			break;
892 
893 		case PHI_PP_PPAS:
894 			if (!get_signal(PHI_488_ATN) || !get_signal(PHI_488_EOI)) {
895 				m_pp_state = PHI_PP_PPSS;
896 			}
897 			break;
898 
899 		default:
900 			logerror("Invalid PP state %d\n" , m_pp_state);
901 			m_pp_state = PHI_PP_PPIS;
902 		}
903 		if (m_pp_state != prev_state) {
904 			changed = true;
905 		}
906 		// PP outputs
907 		if (m_pp_state == PHI_PP_PPAS && m_s_sense == !!BIT(m_reg_control , REG_CTRL_PP_RESPONSE_BIT)) {
908 			LOG("%.6f PP %u\n" , machine().time().as_double() , m_ppr_msg);
909 			dio_byte |= BIT_MASK<uint8_t>(m_ppr_msg);
910 		}
911 
912 		// C FSM
913 		prev_state = m_c_state;
914 		if (!m_sys_controller && get_signal(PHI_488_IFC)) {
915 			m_c_state = PHI_C_CIDS;
916 			m_c_dly_timer->reset();
917 		} else {
918 			switch (m_c_state) {
919 			case PHI_C_CIDS:
920 				if (m_sys_controller && get_signal(PHI_488_IFC)) {
921 					m_c_state = PHI_C_CADS;
922 				}
923 				break;
924 
925 			case PHI_C_CADS:
926 				if (!get_signal(PHI_488_ATN)) {
927 					m_c_state = PHI_C_CACS;
928 				}
929 				break;
930 
931 			case PHI_C_CACS:
932 				// If there are ifcmds to send, just stay in CACS
933 				// else wait for SH to finish its current transfer then decide what to do
934 				if (nba_msg(new_byte , new_eoi) != NBA_CMD_FROM_OFIFO &&
935 					m_sh_state != PHI_SH_STRS && m_sh_state != PHI_SH_SDYS) {
936 					if (!m_fifo_out.empty()) {
937 						// Possible cases
938 						// D0/D1    Meaning of 1st word of OFIFO
939 						// =====================================
940 						// x0       Counted transfer enable or byte to be sent
941 						// 11       Uncounted transfer enable
942 						// 01       Send interface command (already caught by nba_msg)
943 						m_c_state = PHI_C_CSBS;
944 						m_be_counter = 0;
945 					} else if (rpp_msg()) {
946 						// Start parallel polling
947 						m_c_state = PHI_C_CPPS;
948 					}
949 					// There's no third case: rpp_msg() is true when m_fifo_out.empty() is true
950 				}
951 				break;
952 
953 			case PHI_C_CPPS:
954 				if (!rpp_msg()) {
955 					m_c_state = PHI_C_CAWS;
956 					m_c_dly_timer->adjust(attotime::from_nsec(DELAY_T9));
957 				}
958 				break;
959 
960 			case PHI_C_CSBS:
961 				if (tcs_msg() && m_ah_state == PHI_AH_ANRS) {
962 					m_c_state = PHI_C_CSHS;
963 					m_c_dly_timer->adjust(attotime::from_nsec(DELAY_T10));
964 				}
965 				break;
966 
967 			case PHI_C_CSHS:
968 				// tcs_msg cannot go false here
969 				if (!m_c_dly_timer->enabled()) {
970 					m_c_state = PHI_C_CSWS;
971 					m_c_dly_timer->adjust(attotime::from_nsec(DELAY_T7));
972 				}
973 				break;
974 
975 			case PHI_C_CAWS:
976 				if (rpp_msg()) {
977 					m_c_state = PHI_C_CPPS;
978 					m_c_dly_timer->reset();
979 				} else if (!m_c_dly_timer->enabled()) {
980 					m_c_state = PHI_C_CACS;
981 				}
982 				break;
983 
984 			case PHI_C_CTRS:
985 				if (m_sh_state != PHI_SH_STRS) {
986 					m_c_state = PHI_C_CIDS;
987 				}
988 				break;
989 
990 			case PHI_C_CSWS:
991 				if (m_t_state == PHI_T_TADS || !m_c_dly_timer->enabled()) {
992 					m_c_state = PHI_C_CAWS;
993 					m_c_dly_timer->adjust(attotime::from_nsec(DELAY_T9));
994 				}
995 				break;
996 
997 			default:
998 				logerror("Invalid C state %d\n" , m_c_state);
999 				m_c_state = PHI_C_CIDS;
1000 			}
1001 		}
1002 		if (m_c_state != prev_state) {
1003 			changed = true;
1004 		}
1005 		// C outputs
1006 		set_signal(PHI_488_ATN , m_c_state == PHI_C_CACS ||
1007 				   m_c_state == PHI_C_CPPS || m_c_state == PHI_C_CSWS ||
1008 				   m_c_state == PHI_C_CAWS || m_c_state == PHI_C_CTRS);
1009 		eoi_signal = eoi_signal || m_c_state == PHI_C_CPPS;
1010 		set_signal(PHI_488_EOI , eoi_signal);
1011 		set_dio(dio_byte);
1012 	}
1013 
1014 	// Update status register
1015 	m_reg_status &= ~REG_STATUS_STATE_MASK;
1016 	if (m_l_state != PHI_L_LIDS) {
1017 		BIT_SET(m_reg_status, REG_STATUS_LISTEN_BIT);
1018 	}
1019 	if (m_t_state != PHI_T_TIDS) {
1020 		BIT_SET(m_reg_status, REG_STATUS_TALK_BIT);
1021 	}
1022 	if (m_sys_controller) {
1023 		BIT_SET(m_reg_status, REG_STATUS_SYS_CTRL_BIT);
1024 	}
1025 	if (controller_in_charge()) {
1026 		BIT_SET(m_reg_status, REG_STATUS_CONTROLLER_BIT);
1027 	}
1028 	if (m_rl_rems) {
1029 		BIT_SET(m_reg_status, REG_STATUS_REMOTE_BIT);
1030 	}
1031 
1032 	// Update interrupting condition register and INT signal
1033 	if (prev_cic != controller_in_charge()) {
1034 		BIT_SET(m_reg_int_cond, REG_INT_STATUS_CH_BIT);
1035 	}
1036 	m_reg_int_cond &= ~REG_INT_STATE_MASK;
1037 	if (m_fifo_out.empty()) {
1038 		BIT_SET(m_reg_int_cond , REG_INT_FIFO_IDLE_BIT);
1039 	}
1040 	if (!m_fifo_in.empty()) {
1041 		BIT_SET(m_reg_int_cond, REG_INT_FIFO_AV_BIT);
1042 	}
1043 	if (!m_fifo_out.full()) {
1044 		BIT_SET(m_reg_int_cond, REG_INT_FIFO_ROOM_BIT);
1045 	}
1046 	if (controller_in_charge() && get_signal(PHI_488_SRQ)) {
1047 		BIT_SET(m_reg_int_cond, REG_INT_SRQ_BIT);
1048 	}
1049 	update_pp();
1050 	update_interrupt();
1051 	update_dmarq();
1052 
1053 	m_no_recursion = false;
1054 }
1055 
nba_msg(uint8_t & new_byte,bool & new_eoi) const1056 phi_device::nba_origin_t phi_device::nba_msg(uint8_t& new_byte , bool& new_eoi) const
1057 {
1058 	if (controller_in_charge() && m_c_state == PHI_C_CACS && !m_fifo_out.empty()) {
1059 		uint16_t word = m_fifo_out.peek();
1060 		if ((word & REG_D0D1_MASK) == REG_OFIFO_IFCMD_MASK) {
1061 			// Controller sends an interface command
1062 			new_byte = (uint8_t)(word & IFCMD_MASK);
1063 			if (!odd_parity(new_byte)) {
1064 				BIT_SET(new_byte, 7);
1065 			}
1066 			new_eoi = false;
1067 			return NBA_CMD_FROM_OFIFO;
1068 		}
1069 	}
1070 
1071 	switch (m_t_state) {
1072 	case PHI_T_TACS:
1073 		if (!BIT(m_reg_status , REG_STATUS_DATA_FREEZE_BIT) &&
1074 			!BIT(m_reg_int_cond , REG_INT_DEV_CLEAR_BIT) &&
1075 			!m_fifo_out.empty()) {
1076 			uint16_t word = m_fifo_out.peek();
1077 			if (!BIT(word , REG_OFIFO_SPECIAL_BIT)) {
1078 				// Talker sends a data byte
1079 				new_byte = (uint8_t)word;
1080 				new_eoi = BIT(word , REG_OFIFO_END_BIT);
1081 				return NBA_BYTE_FROM_OFIFO;
1082 			}
1083 		}
1084 		break;
1085 
1086 	case PHI_T_SPAS:
1087 		// Reply to serial poll: STB & RQS
1088 		// TODO: check
1089 		new_byte = m_sr_state == PHI_SR_NPRS ? 0x80 : 0x40;
1090 		new_eoi = false;
1091 		return NBA_FROM_SPAS;
1092 
1093 	case PHI_T_ID2:
1094 		// 1st byte of ID
1095 		new_byte = (uint8_t)m_reg_1st_id;
1096 		new_eoi = false;
1097 		return NBA_FROM_ID2;
1098 
1099 	case PHI_T_ID4:
1100 		// 2nd byte of ID
1101 		new_byte = (uint8_t)m_reg_2nd_id;
1102 		new_eoi = true;
1103 		return NBA_FROM_ID4;
1104 
1105 	default:
1106 		break;
1107 	}
1108 	return NBA_NONE;
1109 }
1110 
clear_nba(nba_origin_t origin)1111 void phi_device::clear_nba(nba_origin_t origin)
1112 {
1113 	switch (origin) {
1114 	case NBA_CMD_FROM_OFIFO:
1115 	case NBA_BYTE_FROM_OFIFO:
1116 		m_fifo_out.dequeue();
1117 		break;
1118 
1119 	case NBA_FROM_ID2:
1120 		m_t_state = PHI_T_ID3;
1121 		break;
1122 
1123 	case NBA_FROM_ID4:
1124 		m_t_state = PHI_T_ID5;
1125 		break;
1126 
1127 	default:
1128 		break;
1129 	}
1130 }
1131 
if_cmd_received(uint8_t byte)1132 bool phi_device::if_cmd_received(uint8_t byte)
1133 {
1134 	LOG("%.6f RX cmd: %02x\n" , machine().time().as_double() , byte);
1135 
1136 	bool accepted = true;
1137 
1138 	if ((byte & IFCMD_AG_MASK) != IFCMD_SCG_VALUE) {
1139 		// Any PCG clears sec. address recognition
1140 		// Exceptions are intercepted below
1141 		m_sa_state = PHI_SA_NONE;
1142 	}
1143 
1144 	// TODO: IFC & non-reflection into controller
1145 	switch (byte) {
1146 	case IFCMD_GTL:
1147 		// Go to local
1148 		if (m_l_state == PHI_L_LADS) {
1149 			m_rl_rems = false;
1150 		}
1151 		break;
1152 
1153 	case IFCMD_SDC:
1154 		// Selected device clear
1155 		if (m_l_state == PHI_L_LADS && !controller_in_charge()) {
1156 			BIT_SET(m_reg_int_cond, REG_INT_DEV_CLEAR_BIT);
1157 		}
1158 		break;
1159 
1160 	case IFCMD_PPC:
1161 		// Parallel poll configure
1162 		if (m_l_state == PHI_L_LADS) {
1163 			m_sa_state = PHI_SA_PACS;
1164 		}
1165 		break;
1166 
1167 	case IFCMD_GET:
1168 		// Group execute trigger
1169 		// TODO:
1170 		break;
1171 
1172 	case IFCMD_TCT:
1173 		// Take control
1174 		if (m_c_state == PHI_C_CIDS && m_t_state == PHI_T_TADS) {
1175 			// Take control
1176 			m_c_state = PHI_C_CADS;
1177 		}
1178 		if (m_c_state == PHI_C_CACS && m_t_state != PHI_T_TADS) {
1179 			// Give control to someone else
1180 			m_c_state = PHI_C_CTRS;
1181 		}
1182 		break;
1183 
1184 	case IFCMD_LLO:
1185 		// Local lock-out
1186 		// Ignored
1187 		break;
1188 
1189 	case IFCMD_DCL:
1190 		// Device clear
1191 		if (!controller_in_charge()) {
1192 			BIT_SET(m_reg_int_cond, REG_INT_DEV_CLEAR_BIT);
1193 		}
1194 		break;
1195 
1196 	case IFCMD_PPU:
1197 		// Parallel poll unconfigure
1198 		if (m_pp_state == PHI_PP_PPSS) {
1199 			m_pp_state = PHI_PP_PPIS;
1200 		}
1201 		break;
1202 
1203 	case IFCMD_SPE:
1204 		// Serial poll enable
1205 		m_t_spms = true;
1206 		break;
1207 
1208 	case IFCMD_SPD:
1209 		// Serial poll disable
1210 		m_t_spms = false;
1211 		break;
1212 
1213 	case IFCMD_UNL:
1214 		// Unlisten
1215 		if (!lon_msg()) {
1216 			m_l_state = PHI_L_LIDS;
1217 		}
1218 		break;
1219 
1220 	case IFCMD_UNT:
1221 		// Untalk
1222 		if (ton_msg()) {
1223 			m_t_state = PHI_T_TADS;
1224 		} else {
1225 			m_t_state = PHI_T_TIDS;
1226 		}
1227 		if (m_id_enabled) {
1228 			m_sa_state = PHI_SA_UNT;
1229 		}
1230 		break;
1231 
1232 	default:
1233 		{
1234 			uint8_t address = byte & IFCMD_ADDR_MASK;
1235 			uint8_t ag = byte & IFCMD_AG_MASK;
1236 			bool my_addr = address == my_address();
1237 
1238 			if (ag == IFCMD_LAG_VALUE) {
1239 				// LAG
1240 				if (my_addr) {
1241 					// MLA
1242 					m_l_state = PHI_L_LADS;
1243 					if (get_signal(PHI_488_REN)) {
1244 						m_rl_rems = true;
1245 					}
1246 					m_sa_state = PHI_SA_LPAS;
1247 				}
1248 			} else if (ag == IFCMD_TAG_VALUE) {
1249 				// TAG
1250 				if (my_addr) {
1251 					// MTA
1252 					m_t_state = PHI_T_TADS;
1253 					m_sa_state = PHI_SA_TPAS;
1254 				} else if (!ton_msg()) {
1255 					// OTA
1256 					m_t_state = PHI_T_TIDS;
1257 				}
1258 			} else if (ag == IFCMD_SCG_VALUE) {
1259 				// SCG
1260 				switch (m_sa_state) {
1261 				case PHI_SA_NONE:
1262 					break;
1263 
1264 				case PHI_SA_PACS:
1265 					if ((byte & IFCMD_PPX_MASK) == IFCMD_PPE_VALUE && m_pp_state == PHI_PP_PPIS) {
1266 						// PPE
1267 						m_s_sense = BIT(byte , IFCMD_PPE_S_BIT);
1268 						m_ppr_msg = byte & IFCMD_PPE_PPR_MASK;
1269 						LOG("PPE s=%d ppr=%u\n" , m_s_sense , m_ppr_msg);
1270 						m_pp_state = PHI_PP_PPSS;
1271 					} else if ((byte & IFCMD_PPX_MASK) == IFCMD_PPD_VALUE && m_pp_state == PHI_PP_PPSS) {
1272 						// PPD
1273 						m_pp_state = PHI_PP_PPIS;
1274 					}
1275 					break;
1276 
1277 				case PHI_SA_TPAS:
1278 				case PHI_SA_LPAS:
1279 					// command is a secondary address after MTA or MLA
1280 					if (m_fifo_in.full() || BIT(m_reg_int_cond , REG_INT_DEV_CLEAR_BIT)) {
1281 						// No room for secondary address in FIFO, stall handshake
1282 						accepted = false;
1283 					} else {
1284 						uint16_t word = REG_IFIFO_2_ADDR_MASK | address;
1285 						if (m_sa_state == PHI_SA_TPAS) {
1286 							BIT_SET(word, REG_IFIFO_TALK_BIT);
1287 						}
1288 						rx_n_data_freeze(word);
1289 					}
1290 					break;
1291 
1292 				case PHI_SA_UNT:
1293 					if (my_addr) {
1294 						// Start IDENTIFY sequence
1295 						m_t_state = PHI_T_ID1;
1296 					} else {
1297 						// Unaddressed by OSA (== UNT)
1298 						if_cmd_received(IFCMD_UNT);
1299 					}
1300 				}
1301 			}
1302 		}
1303 	}
1304 	return accepted;
1305 }
1306 
byte_received(uint8_t byte,bool eoi)1307 bool phi_device::byte_received(uint8_t byte , bool eoi)
1308 {
1309 	// Start with D0/D1 = 00
1310 	uint16_t word = byte;
1311 
1312 	if (eoi) {
1313 		// EOI -> D0/D1 = 11
1314 		word |= REG_IFIFO_LAST_MASK;
1315 	}
1316 
1317 	bool end_of_transfer = false;
1318 
1319 	if (!m_fifo_out.empty() && m_c_state == PHI_C_CSBS && m_t_state != PHI_T_TACS) {
1320 		uint16_t be_word = m_fifo_out.peek();
1321 		// Monitoring bytes being transferred on the bus
1322 		if (eoi) {
1323 			end_of_transfer = true;
1324 		} else if (!BIT(be_word , REG_OFIFO_LF_INH_BIT) && byte == 0x0a) {
1325 			// LF received -> D0/D1 = 11
1326 			word |= REG_IFIFO_LAST_MASK;
1327 			end_of_transfer = true;
1328 		} else if (be_word != REG_OFIFO_UNCNT_MASK && ((m_be_counter + 1) & 0xff) == (be_word & 0xff)) {
1329 			// Byte count expired -> D0/D1 = 10
1330 			word |= REG_IFIFO_CNT_EXP_MASK;
1331 			end_of_transfer = true;
1332 		}
1333 	}
1334 
1335 	LOG("%.6f RX word:%04x\n" , machine().time().as_double() , word);
1336 
1337 	if (m_l_state == PHI_L_LACS) {
1338 		if (m_fifo_in.full() || BIT(m_reg_int_cond , REG_INT_DEV_CLEAR_BIT)) {
1339 			// No room for received byte, stall handshake
1340 			LOG_NOISY("..stalled\n");
1341 			return false;
1342 		} else {
1343 			LOG_NOISY("..OK\n");
1344 			rx_n_data_freeze(word);
1345 		}
1346 	}
1347 	if (end_of_transfer) {
1348 		LOG_NOISY("End of byte transfer enable\n");
1349 		m_fifo_out.dequeue();
1350 		m_be_counter = 0;
1351 	} else {
1352 		m_be_counter++;
1353 	}
1354 
1355 	return true;
1356 }
1357 
rx_n_data_freeze(uint16_t word)1358 void phi_device::rx_n_data_freeze(uint16_t word)
1359 {
1360 	m_fifo_in.enqueue(word);
1361 	if (!controller_in_charge() && m_sh_state != PHI_SH_STRS) {
1362 		// If PHI didn't send this byte to itself, set data freeze
1363 		BIT_SET(m_reg_status, REG_STATUS_DATA_FREEZE_BIT);
1364 	}
1365 }
1366 
ton_msg(void) const1367 bool phi_device::ton_msg(void) const
1368 {
1369 	return BIT(m_reg_address , REG_ADDR_TA_BIT);
1370 }
1371 
lon_msg(void) const1372 bool phi_device::lon_msg(void) const
1373 {
1374 	return BIT(m_reg_address , REG_ADDR_LA_BIT);
1375 }
1376 
odd_parity(uint8_t byte) const1377 bool phi_device::odd_parity(uint8_t byte) const
1378 {
1379 	byte = (byte >> 4) ^ byte;
1380 	byte = (byte >> 2) ^ byte;
1381 	byte = (byte >> 1) ^ byte;
1382 	return (byte & 1) != 0;
1383 }
1384 
my_address(void) const1385 uint8_t phi_device::my_address(void) const
1386 {
1387 	if (m_sys_controller) {
1388 		return CONTROLLER_ADDR;
1389 	} else {
1390 		return (m_reg_address >> REG_ADDR_HPIB_ADDR_BIT) & 0x1f;
1391 	}
1392 }
1393 
tcs_msg(void) const1394 bool phi_device::tcs_msg(void) const
1395 {
1396 	uint8_t new_byte;
1397 	bool new_eoi;
1398 
1399 	// When the CIC takes back control synchronously:
1400 	// * Request to start parallel poll is pending (i.e. OFIFO is empty)
1401 	// * There's an interface command to be sent at head of OFIFO
1402 	return (m_c_state == PHI_C_CSBS || m_c_state == PHI_C_CSHS || m_c_state == PHI_C_CSWS) &&
1403 		(rpp_msg() ||
1404 		 nba_msg(new_byte , new_eoi) == NBA_CMD_FROM_OFIFO);
1405 }
1406 
rpp_msg(void) const1407 bool phi_device::rpp_msg(void) const
1408 {
1409 	return m_fifo_out.empty();
1410 }
1411 
get_pp_response()1412 uint8_t phi_device::get_pp_response()
1413 {
1414 	return (get_dio() ^ m_reg_2nd_id) & m_reg_1st_id;
1415 }
1416 
controller_in_charge(void) const1417 bool phi_device::controller_in_charge(void) const
1418 {
1419 	return m_c_state != PHI_C_CIDS;
1420 }
1421 
configure_pp_response()1422 void phi_device::configure_pp_response()
1423 {
1424 	uint8_t addr = (m_reg_address >> REG_ADDR_HPIB_ADDR_BIT) & 0x1f;
1425 	if (addr <= 7) {
1426 		// If address <= 7, PP is automatically enabled and configured for PPR = ~address
1427 		m_ppr_msg = addr ^ 7;
1428 		m_pp_state = PHI_PP_PPSS;
1429 	} else {
1430 		m_ppr_msg = 0;
1431 		m_pp_state = PHI_PP_PPIS;
1432 	}
1433 	m_s_sense = true;
1434 }
1435 
update_pp()1436 void phi_device::update_pp()
1437 {
1438 	if (m_c_state == PHI_C_CPPS) {
1439 		if (m_fifo_in.empty() && get_pp_response()) {
1440 			BIT_SET(m_reg_int_cond , REG_INT_PP_RESPONSE_BIT);
1441 		} else {
1442 			BIT_CLR(m_reg_int_cond , REG_INT_PP_RESPONSE_BIT);
1443 		}
1444 		update_interrupt();
1445 	}
1446 }
1447 
update_interrupt()1448 void phi_device::update_interrupt()
1449 {
1450 	bool int_pending = (m_reg_int_cond & m_reg_int_mask) != 0;
1451 	bool int_line = false;
1452 	if (int_pending) {
1453 		BIT_SET(m_reg_int_cond, REG_INT_PENDING_BIT);
1454 		if (BIT(m_reg_int_mask , REG_INT_PENDING_BIT)) {
1455 			int_line = true;
1456 		}
1457 	} else {
1458 		BIT_CLR(m_reg_int_cond, REG_INT_PENDING_BIT);
1459 	}
1460 	if (int_line != m_int_line) {
1461 		m_int_line = int_line;
1462 		LOG_INT("INT %d\n" , m_int_line);
1463 		m_int_write_func(m_int_line);
1464 	}
1465 }
1466 
update_dmarq()1467 void phi_device::update_dmarq()
1468 {
1469 	bool new_dmarq_line;
1470 	if (BIT(m_reg_control , REG_CTRL_DMA_FIFO_BIT)) {
1471 		new_dmarq_line = BIT(m_reg_int_cond , REG_INT_FIFO_ROOM_BIT);
1472 	} else {
1473 		new_dmarq_line = BIT(m_reg_int_cond , REG_INT_FIFO_AV_BIT);
1474 	}
1475 	if (new_dmarq_line != m_dmarq_line) {
1476 		m_dmarq_line = new_dmarq_line;
1477 		LOG_INT("DRQ %d\n" , m_dmarq_line);
1478 		m_dmarq_write_func(m_dmarq_line);
1479 	}
1480 }
1481