1 // license:BSD-3-Clause
2 // copyright-holders:Patrick Mackinlay
3 
4 /*
5  * Sony CXD1185 SCSI 1 Protocol Controller.
6  *
7  * Sources:
8  *  - https://datasheetspdf.com/pdf-file/199633/SonyCorporation/CXD1185CQ/1
9  *
10  * TODO:
11  *  - target mode
12  *  - cq/aq variants
13  *  - synchronous mode
14  */
15 
16 #include "emu.h"
17 #include "cxd1185.h"
18 
19 #define LOG_GENERAL (1U << 0)
20 #define LOG_CMD     (1U << 1)
21 #define LOG_REG     (1U << 2)
22 #define LOG_STATE   (1U << 3)
23 #define LOG_CONFIG  (1U << 4)
24 #define LOG_INT     (1U << 5)
25 #define LOG_SCSI    (1U << 6)
26 #define LOG_DMA     (1U << 7)
27 
28 //#define VERBOSE (LOG_GENERAL|LOG_CMD|LOG_REG|LOG_STATE|LOG_CONFIG|LOG_INT|LOG_SCSI|LOG_DMA)
29 
30 #include "logmacro.h"
31 
32 DEFINE_DEVICE_TYPE(CXD1185, cxd1185_device, "cxd1185", "Sony CXD1185 SCSI 1 Protocol Controller")
33 
34 static char const *const nscsi_phase[] = { "DATA OUT", "DATA IN", "COMMAND", "STATUS", "*", "*", "MESSAGE OUT", "MESSAGE IN" };
35 
36 // FIXME: would be better to reuse from nscsi_full_device
37 static unsigned const SCSI_ARB_DELAY  =  2'400;
38 static unsigned const SCSI_BUS_CLEAR  =    800;
39 static unsigned const SCSI_BUS_FREE   =    800;
40 static unsigned const SCSI_BUS_SETTLE =    400;
41 static unsigned const SCSI_BUS_SKEW   =     10;
42 static unsigned const SCSI_RST_HOLD   = 25'000;
43 
44 ALLOW_SAVE_TYPE(cxd1185_device::state);
45 
cxd1185_device(machine_config const & mconfig,char const * tag,device_t * owner,u32 clock)46 cxd1185_device::cxd1185_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
47 	: nscsi_device(mconfig, CXD1185, tag, owner, clock)
48 	, nscsi_slot_card_interface(mconfig, *this, DEVICE_SELF)
49 	, m_irq_out_cb(*this)
50 	, m_drq_out_cb(*this)
51 	, m_port_out_cb(*this)
52 {
53 }
54 
map(address_map & map)55 void cxd1185_device::map(address_map &map)
56 {
57 	map(0x0, 0x0).rw(FUNC(cxd1185_device::status_r), FUNC(cxd1185_device::command_w));
58 	map(0x1, 0x1).rw(FUNC(cxd1185_device::scsi_data_r), FUNC(cxd1185_device::scsi_data_w));
59 	map(0x2, 0x2).r(FUNC(cxd1185_device::int_req_r<0>));
60 	map(0x3, 0x3).rw(FUNC(cxd1185_device::int_req_r<1>), FUNC(cxd1185_device::environ_w));
61 	map(0x4, 0x4).rw(FUNC(cxd1185_device::scsi_ctrl_monitor_r), FUNC(cxd1185_device::timer_w));
62 	map(0x5, 0x5).r(FUNC(cxd1185_device::fifo_status_r));
63 	map(0x6, 0x6).rw(FUNC(cxd1185_device::scsi_id_r), FUNC(cxd1185_device::scsi_id_w));
64 	map(0x7, 0x7).rw(FUNC(cxd1185_device::count_r<0>), FUNC(cxd1185_device::count_w<0>));
65 	map(0x8, 0x8).rw(FUNC(cxd1185_device::count_r<1>), FUNC(cxd1185_device::count_w<1>));
66 	map(0x9, 0x9).rw(FUNC(cxd1185_device::count_r<2>), FUNC(cxd1185_device::count_w<2>));
67 	map(0xa, 0xa).rw(FUNC(cxd1185_device::int_auth_r<0>), FUNC(cxd1185_device::int_auth_w<0>));
68 	map(0xb, 0xb).rw(FUNC(cxd1185_device::int_auth_r<1>), FUNC(cxd1185_device::int_auth_w<1>));
69 	map(0xc, 0xc).rw(FUNC(cxd1185_device::mode_r), FUNC(cxd1185_device::mode_w));
70 	map(0xd, 0xd).rw(FUNC(cxd1185_device::sync_ctrl_r), FUNC(cxd1185_device::sync_ctrl_w));
71 	map(0xe, 0xe).rw(FUNC(cxd1185_device::scsi_ctrl_r), FUNC(cxd1185_device::scsi_ctrl_w));
72 	map(0xf, 0xf).rw(FUNC(cxd1185_device::ioport_r), FUNC(cxd1185_device::ioport_w));
73 }
74 
device_start()75 void cxd1185_device::device_start()
76 {
77 	m_irq_out_cb.resolve_safe();
78 	m_drq_out_cb.resolve_safe();
79 	m_port_out_cb.resolve_safe();
80 
81 	save_item(NAME(m_state));
82 	save_item(NAME(m_irq_asserted));
83 	save_item(NAME(m_drq_asserted));
84 	save_item(NAME(m_pio_data_mode));
85 	save_item(NAME(m_pio_ctrl_mode));
86 	//save_item(NAME(m_fifo));
87 	save_item(NAME(m_scsi_ctrl_state));
88 
89 	save_item(NAME(m_status));
90 	save_item(NAME(m_command));
91 	save_item(NAME(m_int_req));
92 	save_item(NAME(m_environ));
93 	save_item(NAME(m_sel_time));
94 	save_item(NAME(m_rst_time));
95 	save_item(NAME(m_scsi_id));
96 	save_item(NAME(m_int_auth));
97 	save_item(NAME(m_mode));
98 	save_item(NAME(m_count));
99 	save_item(NAME(m_sync_ctrl));
100 	save_item(NAME(m_scsi_ctrl));
101 	save_item(NAME(m_ioport));
102 
103 	m_state_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cxd1185_device::state_timer), this));
104 	m_state = IDLE;
105 
106 	m_irq_asserted = false;
107 	m_drq_asserted = false;
108 
109 	// monitor all scsi bus control lines
110 	scsi_bus->ctrl_wait(scsi_refid, S_ALL, S_ALL);
111 }
112 
device_reset()113 void cxd1185_device::device_reset()
114 {
115 	m_environ = 0;
116 
117 	reset_chip();
118 }
119 
reset_chip()120 void cxd1185_device::reset_chip()
121 {
122 	m_pio_data_mode = false;
123 	m_pio_ctrl_mode = false;
124 
125 	// clear all except environment register
126 	m_status = 0;
127 	m_command = 0;
128 	m_int_req[0] = 0;
129 	m_int_req[1] = 0;
130 	m_sel_time = 0;
131 	m_rst_time = 0;
132 	m_scsi_id = 0;
133 	m_int_auth[0] = 0;
134 	m_int_auth[1] = 0;
135 	m_mode = 0;
136 	m_count = 0;
137 	m_sync_ctrl = 0;
138 	m_scsi_ctrl = 0;
139 	m_ioport = 0;
140 
141 	// clear drq and irq
142 	reset_fifo();
143 	int_check();
144 
145 	// clear scsi bus
146 	scsi_bus->data_w(scsi_refid, 0);
147 	scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
148 }
149 
reset_fifo()150 void cxd1185_device::reset_fifo()
151 {
152 	m_fifo.clear();
153 	set_drq(false);
154 }
155 
status_r()156 u8 cxd1185_device::status_r()
157 {
158 	u8 const data = (scsi_bus->ctrl_r() & S_RST) ? MRST : 0;
159 
160 	LOGMASKED(LOG_REG, "status_r 0x%02x\n", data | m_status);
161 
162 	return data | m_status;
163 }
164 
scsi_data_r()165 u8 cxd1185_device::scsi_data_r()
166 {
167 	u8 data = 0;
168 
169 	if (!m_pio_data_mode)
170 	{
171 		if (!machine().side_effects_disabled())
172 		{
173 			data = m_fifo.dequeue();
174 
175 			if (m_state != IDLE && !m_state_timer->enabled())
176 				m_state_timer->adjust(attotime::zero);
177 		}
178 		else
179 			data = m_fifo.peek();
180 	}
181 	else
182 		data = scsi_bus->data_r();
183 
184 	LOGMASKED(LOG_REG, "scsi_data_r 0x%02x (%s)\n", data, machine().describe_context());
185 
186 	return data;
187 }
188 
int_req_r()189 template <unsigned Register> u8 cxd1185_device::int_req_r()
190 {
191 	u8 const data = m_int_req[Register];
192 
193 	if (!machine().side_effects_disabled())
194 	{
195 		LOGMASKED(LOG_REG, "int_req_r<%d> 0x%02x\n", Register, data);
196 
197 		m_int_req[Register] = 0;
198 		int_check();
199 	}
200 
201 	return data;
202 }
203 
scsi_ctrl_monitor_r()204 u8 cxd1185_device::scsi_ctrl_monitor_r()
205 {
206 	u32 const ctrl = scsi_bus->ctrl_r();
207 
208 	u8 const data =
209 		((ctrl & S_BSY) ? MBSY : 0) |
210 		((ctrl & S_SEL) ? MSEL : 0) |
211 		((ctrl & S_MSG) ? MMSG : 0) |
212 		((ctrl & S_CTL) ? MCD : 0) |
213 		((ctrl & S_INP) ? MIO : 0) |
214 		((ctrl & S_REQ) ? MREQ : 0) |
215 		((ctrl & S_ACK) ? MACK : 0) |
216 		((ctrl & S_ATN) ? MATN : 0);
217 
218 	LOGMASKED(LOG_REG, "scsi_ctrl_monitor_r 0x%02x\n", data);
219 
220 	return data;
221 }
222 
fifo_status_r()223 u8 cxd1185_device::fifo_status_r()
224 {
225 	u8 const data =
226 		(m_fifo.empty() ? FIE : 0) |
227 		(m_fifo.full() ? FIF : 0) |
228 		(m_fifo.queue_length() & FC);
229 
230 	LOGMASKED(LOG_REG, "fifo_status_r 0x%02x\n", data);
231 
232 	return data;
233 }
234 
command_w(u8 data)235 void cxd1185_device::command_w(u8 data)
236 {
237 	LOGMASKED(LOG_REG, "command_w 0x%02x\n", data);
238 
239 	// check command in progress
240 	if ((m_status & CIP) && (data != CMD_RESET))
241 		return;
242 
243 	// check command mode/category
244 	switch (data & CAT)
245 	{
246 	case 0x00:
247 		// commands valid in any state
248 		break;
249 	case 0x40:
250 		// commands valid in disconnected state
251 		if (m_status & (INIT | TARG))
252 			return;
253 		break;
254 	case 0x80:
255 		// commands valid in target state
256 		if ((m_status & (INIT | TARG)) != TARG)
257 			return;
258 		fatalerror("cxd1185_device: target mode not implemented\n");
259 		break;
260 	case 0xc0:
261 		// commands valid in initiator state
262 		if ((m_status & (INIT | TARG)) != INIT)
263 			return;
264 		break;
265 	}
266 
267 	m_command = data;
268 	m_status |= CIP;
269 
270 	switch (data & (CAT | CMD))
271 	{
272 	case 0x00:
273 		LOGMASKED(LOG_CMD, "no operation\n");
274 		break;
275 	case 0x01:
276 		LOGMASKED(LOG_CMD, "reset chip\n");
277 		reset_chip();
278 		break;
279 	case 0x02:
280 		LOGMASKED(LOG_CMD, "assert scsi reset\n");
281 		m_state = BUS_RESET;
282 		break;
283 	case 0x03:
284 		LOGMASKED(LOG_CMD, "flush fifo\n");
285 		reset_fifo();
286 		break;
287 	case 0x04:
288 		LOGMASKED(LOG_CMD, "assert scsi control\n");
289 		m_pio_ctrl_mode = true;
290 		m_scsi_ctrl = 0;
291 		if ((m_status & (INIT | TARG)) == TARG)
292 			scsi_bus->ctrl_w(scsi_refid, 0, S_ALL & ~S_BSY);
293 		break;
294 	case 0x05:
295 		LOGMASKED(LOG_CMD, "deassert scsi control\n");
296 		m_pio_ctrl_mode = false;
297 		break;
298 	case 0x06:
299 		LOGMASKED(LOG_CMD, "assert scsi data\n");
300 		m_pio_data_mode = true;
301 		break;
302 	case 0x07:
303 		LOGMASKED(LOG_CMD, "deassert scsi data\n");
304 		m_pio_data_mode = false;
305 		break;
306 
307 	case 0x40: LOGMASKED(LOG_CMD, "reselect\n"); break;
308 	case 0x41:
309 		LOGMASKED(LOG_CMD, "select target %d without atn\n", (m_scsi_id & TID) >> 5);
310 		m_status |= INIT;
311 		m_state = ARB_BUS_FREE;
312 		break;
313 	case 0x42:
314 		LOGMASKED(LOG_CMD, "select target %d with atn\n", (m_scsi_id & TID) >> 5);
315 		m_status |= INIT;
316 		m_state = ARB_BUS_FREE;
317 		break;
318 	case 0x43: LOGMASKED(LOG_CMD, "enable selection/reselection\n"); break;
319 	case 0x44: LOGMASKED(LOG_CMD, "disable selection/reselection\n"); break;
320 
321 		// TODO: not implemented
322 	case 0x80: LOGMASKED(LOG_CMD, "send message\n"); break;
323 	case 0x81: LOGMASKED(LOG_CMD, "send status\n"); break;
324 	case 0x82: LOGMASKED(LOG_CMD, "send data\n"); break;
325 	case 0x83: LOGMASKED(LOG_CMD, "disconnect\n"); break;
326 	case 0x84: LOGMASKED(LOG_CMD, "receive message out\n"); break;
327 	case 0x85: LOGMASKED(LOG_CMD, "receive command\n"); break;
328 	case 0x86: LOGMASKED(LOG_CMD, "receive data\n"); break;
329 
330 	case 0xc0:
331 		LOGMASKED(LOG_CMD, "transfer information\n");
332 		m_state = XFR_INFO;
333 		break;
334 	case 0xc1:
335 		LOGMASKED(LOG_CMD, "transfer pad\n");
336 		m_state = XFR_INFO;
337 		break;
338 	case 0xc2:
339 		LOGMASKED(LOG_CMD, "deassert ack\n");
340 		scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
341 		break;
342 	case 0xc3:
343 		LOGMASKED(LOG_CMD, "assert atn\n");
344 		scsi_bus->ctrl_w(scsi_refid, S_ATN, S_ATN);
345 		break;
346 	case 0xc4:
347 		LOGMASKED(LOG_CMD, "deassert atn\n");
348 		scsi_bus->ctrl_w(scsi_refid, 0, S_ATN);
349 		break;
350 	}
351 
352 	if (m_state == IDLE)
353 	{
354 		// command completes immediately
355 		LOGMASKED(LOG_CMD, "command complete immediate\n");
356 
357 		m_command = 0;
358 		m_status &= ~CIP;
359 
360 		if (data != CMD_RESET)
361 		{
362 			m_int_req[1] |= FNC;
363 			int_check();
364 		}
365 	}
366 	else
367 		m_state_timer->adjust(attotime::zero);
368 }
369 
scsi_data_w(u8 data)370 void cxd1185_device::scsi_data_w(u8 data)
371 {
372 	LOGMASKED(LOG_REG, "scsi_data_w 0x%02x (%s)\n", data, machine().describe_context());
373 
374 	if (!m_pio_data_mode)
375 	{
376 		m_fifo.enqueue(data);
377 
378 		if (m_state != IDLE && !m_state_timer->enabled())
379 			m_state_timer->adjust(attotime::zero);
380 	}
381 	else
382 	{
383 		u32 const ctrl = scsi_bus->ctrl_r();
384 
385 		if (!(m_int_req[1] & PHC) &&
386 			(((m_status & (INIT | TARG)) == INIT && !(ctrl & S_INP)) ||
387 			((m_status & (INIT | TARG)) == TARG && (ctrl & S_INP))))
388 			scsi_bus->data_w(scsi_refid, data);
389 	}
390 }
391 
environ_w(u8 data)392 void cxd1185_device::environ_w(u8 data)
393 {
394 	bool const polarity = (data ^ m_environ) & SIRM;
395 
396 	LOGMASKED(LOG_REG, "environ_w 0x%02x\n", data);
397 	if (data ^ m_environ)
398 		LOGMASKED(LOG_CONFIG, "%s mode, %s data bus parity, %s irq polarity, divider %d\n",
399 			(data & DIFE) ? "differential" : "single-ended",
400 			(data & DPEN) ? ((data & SDPM) ? "even" : "odd") : "no",
401 			(data & SIRM) ? "negative" : "positive",
402 			(data & FS) ? ((data & FS1) ? 2 : 3) : 4);
403 
404 	m_environ = data;
405 
406 	// update irq line if polarity changed
407 	if (polarity)
408 		m_irq_out_cb((m_environ & SIRM) ? !m_irq_asserted : m_irq_asserted);
409 }
410 
timer_w(u8 data)411 void cxd1185_device::timer_w(u8 data)
412 {
413 	LOGMASKED(LOG_REG, "timer_w 0x%02x\n", data);
414 
415 	unsigned const divisor = (m_environ & FS) ? ((m_environ & FS1) ? 2 : 3) : 4;
416 	if (m_mode & TMSL)
417 	{
418 		m_rst_time = double(divisor * (32 * data + 38)) / clock() * 1E+9;
419 
420 		LOGMASKED(LOG_CONFIG, "reset timer %d ns\n", m_rst_time);
421 	}
422 	else
423 	{
424 		m_sel_time = double(divisor * (data + 1) * 8192) / clock() * 1E+9;
425 
426 		LOGMASKED(LOG_CONFIG, "selection timer %d ns\n", m_sel_time);
427 	}
428 }
429 
int_auth_w(u8 data)430 template <unsigned Register> void cxd1185_device::int_auth_w(u8 data)
431 {
432 	LOGMASKED(LOG_REG, "int_auth_w<%d> 0x%02x\n", Register, data);
433 
434 	m_int_auth[Register] = data;
435 
436 	int_check();
437 }
438 
scsi_ctrl_w(u8 data)439 void cxd1185_device::scsi_ctrl_w(u8 data)
440 {
441 	LOGMASKED(LOG_REG, "scsi_ctrl_w 0x%02x (%s)\n", data, machine().describe_context());
442 
443 	if (m_pio_ctrl_mode)
444 	{
445 		u32 nscsi_mask = S_BSY | S_SEL;
446 
447 		if ((m_status & (INIT | TARG)) == TARG)
448 			nscsi_mask |= S_MSG | S_CTL | S_INP | S_REQ;
449 		else if ((m_status & (INIT | TARG)) == INIT)
450 			nscsi_mask |= S_ACK | S_ATN;
451 
452 		u32 const nscsi_data =
453 			((data & ABSY) ? S_BSY : 0) |
454 			((data & ASEL) ? S_SEL : 0) |
455 			((data & AMSG) ? S_MSG : 0) |
456 			((data & ACD) ? S_CTL : 0) |
457 			((data & AIO) ? S_INP : 0) |
458 			((data & AREQ) ? S_REQ : 0) |
459 			((data & AACK) ? S_ACK : 0) |
460 			((data & AATN) ? S_ATN : 0);
461 
462 		scsi_bus->ctrl_w(scsi_refid, nscsi_data, nscsi_mask);
463 	}
464 	else
465 		m_scsi_ctrl = data;
466 }
467 
ioport_w(u8 data)468 void cxd1185_device::ioport_w(u8 data)
469 {
470 	LOGMASKED(LOG_REG, "ioport_w 0x%02x\n", data);
471 
472 	// update direction bits first
473 	m_ioport &= ~PCN;
474 	m_ioport |= data & PCN;
475 
476 	u8 const mask = (m_ioport & PCN) >> 4;
477 
478 	// update output bits
479 	m_ioport &= ~mask;
480 	m_ioport |= data & mask;
481 
482 	m_port_out_cb(0, m_ioport & mask, mask);
483 }
484 
state_timer(void * ptr,s32 param)485 void cxd1185_device::state_timer(void *ptr, s32 param)
486 {
487 	// step state machine
488 	int delay = state_step();
489 
490 	// check for interrupts
491 	int_check();
492 
493 	// check for data stall
494 	if (delay < 0)
495 		return;
496 
497 	if (m_state == IDLE)
498 	{
499 		LOGMASKED(LOG_CMD, "command complete\n");
500 		m_status &= ~CIP;
501 		m_command = 0;
502 	}
503 	else
504 		m_state_timer->adjust(attotime::from_nsec(delay));
505 }
506 
state_step()507 int cxd1185_device::state_step()
508 {
509 	int delay = 0;
510 
511 	u8 const oid = 1 << ((m_scsi_id & OID) >> 0);
512 	u8 const tid = 1 << ((m_scsi_id & TID) >> 5);
513 
514 	switch (m_state)
515 	{
516 	case IDLE:
517 		break;
518 
519 	case ARB_BUS_FREE:
520 		LOGMASKED(LOG_STATE, "arbitration: waiting for bus free\n");
521 		if (!(scsi_bus->ctrl_r() & (S_SEL | S_BSY | S_RST)))
522 		{
523 			m_state = ARB_START;
524 			delay = SCSI_BUS_FREE;
525 		}
526 		break;
527 	case ARB_START:
528 		LOGMASKED(LOG_STATE, "arbitration: started\n");
529 		m_state = ARB_EVALUATE;
530 		delay = SCSI_ARB_DELAY;
531 
532 		// assert own ID and BSY
533 		scsi_bus->data_w(scsi_refid, oid);
534 		scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
535 		break;
536 	case ARB_EVALUATE:
537 		// check if SEL asserted, or if there's a higher ID on the bus
538 		if ((scsi_bus->ctrl_r() & S_SEL) || (scsi_bus->data_r() & ~((oid - 1) | oid)))
539 		{
540 			LOGMASKED(LOG_STATE, "arbitration: lost\n");
541 			m_status &= ~INIT;
542 			m_int_req[0] |= ARBF;
543 
544 			m_state = COMPLETE;
545 
546 			// clear data and BSY
547 			scsi_bus->data_w(scsi_refid, 0);
548 			scsi_bus->ctrl_w(scsi_refid, 0, S_BSY);
549 		}
550 		else
551 		{
552 			LOGMASKED(LOG_STATE, "arbitration: won\n");
553 			m_state = SEL_START;
554 			delay = SCSI_BUS_CLEAR + SCSI_BUS_SETTLE;
555 		}
556 		break;
557 
558 	case SEL_START:
559 		LOGMASKED(LOG_STATE, "selection: SEL asserted\n");
560 		m_state = SEL_DELAY;
561 		delay = SCSI_BUS_SKEW * 2;
562 
563 		// assert own and target ID and SEL
564 		scsi_bus->data_w(scsi_refid, oid | tid);
565 		scsi_bus->ctrl_w(scsi_refid, S_SEL, S_SEL);
566 		break;
567 	case SEL_DELAY:
568 		LOGMASKED(LOG_STATE, "selection: BSY cleared\n");
569 		m_state = SEL_WAIT_BSY;
570 		delay = std::max(m_sel_time, SCSI_BUS_SETTLE);
571 
572 		// clear BSY, optionally assert ATN
573 		if (m_command == CMD_SEL_ATN)
574 			scsi_bus->ctrl_w(scsi_refid, S_ATN, S_BSY | S_ATN);
575 		else
576 			scsi_bus->ctrl_w(scsi_refid, 0, S_BSY);
577 		break;
578 	case SEL_WAIT_BSY:
579 		if (scsi_bus->ctrl_r() & S_BSY)
580 		{
581 			LOGMASKED(LOG_STATE, "selection: BSY asserted by target\n");
582 			m_state = SEL_COMPLETE;
583 			delay = SCSI_BUS_SKEW * 2;
584 		}
585 		else
586 		{
587 			LOGMASKED(LOG_STATE, "selection: timed out\n");
588 			m_status &= ~INIT;
589 			m_int_req[0] |= STO;
590 			m_state = COMPLETE;
591 
592 			scsi_bus->ctrl_w(scsi_refid, 0, S_ATN | S_SEL);
593 		}
594 		break;
595 	case SEL_COMPLETE:
596 		LOGMASKED(LOG_STATE, "selection: complete\n");
597 		m_state = COMPLETE;
598 
599 		// clear data and SEL
600 		scsi_bus->data_w(scsi_refid, 0);
601 		scsi_bus->ctrl_w(scsi_refid, 0, S_SEL);
602 		break;
603 
604 	case XFR_INFO:
605 		LOGMASKED(LOG_STATE, "transfer: count %d waiting for REQ\n", (m_command & TRBE) ? m_count : 1);
606 		if (scsi_bus->ctrl_r() & S_REQ)
607 			m_state = scsi_bus->ctrl_r() & S_INP ? XFR_IN : XFR_OUT;
608 		break;
609 	case XFR_IN:
610 		// FIXME: datasheet says ACK should be asserted when TRBE & FIF
611 		if (!m_fifo.full())
612 		{
613 			u8 const data = ((m_command & CMD) == (CMD_XFR_PAD & CMD)) ? 0 : scsi_bus->data_r();
614 			LOGMASKED(LOG_STATE, "transfer in: data 0x%02x\n", data);
615 
616 			m_fifo.enqueue(data);
617 			if (m_command & TRBE)
618 				m_count--;
619 
620 			m_state = XFR_IN_NEXT;
621 
622 			// assert ACK
623 			scsi_bus->ctrl_w(scsi_refid, S_ACK, S_ACK);
624 		}
625 		else
626 		{
627 			delay = -1;
628 			if (m_command & DMA)
629 				set_drq(true);
630 		}
631 		break;
632 	case XFR_IN_NEXT:
633 		if (!(scsi_bus->ctrl_r() & S_REQ))
634 		{
635 			LOGMASKED(LOG_STATE, "transfer in: count %d\n", (m_command & TRBE) ? m_count : 0);
636 			if (!(m_command & TRBE) || !m_count)
637 			{
638 				if (m_command & TRBE)
639 					m_status |= TRBZ;
640 
641 				m_state = XFR_IN_DRAIN;
642 			}
643 			else
644 				m_state = XFR_IN_REQ;
645 
646 			// clear ACK except for single-byte message-in
647 			if (!((scsi_bus->ctrl_r() & S_PHASE_MASK) == S_PHASE_MSG_IN && !(m_command & TRBE)))
648 				scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
649 		}
650 		break;
651 	case XFR_IN_REQ:
652 		if (scsi_bus->ctrl_r() & S_REQ)
653 		{
654 			// check if target changed phase
655 			if (m_int_req[1] & PHC)
656 			{
657 				if (m_command & DMA)
658 					set_drq(false);
659 
660 				m_state = XFR_INFO_DONE;
661 			}
662 			else
663 				m_state = XFR_IN;
664 		}
665 		break;
666 	case XFR_IN_DRAIN:
667 		if (!m_fifo.empty() && (m_command & DMA))
668 			set_drq(true);
669 		m_state = XFR_INFO_DONE;
670 		break;
671 	case XFR_OUT:
672 		if (!m_fifo.empty() || (m_command & CMD) == (CMD_XFR_PAD & CMD))
673 		{
674 			u8 const data = ((m_command & CMD) == (CMD_XFR_PAD & CMD)) ? 0 : m_fifo.dequeue();
675 
676 			LOGMASKED(LOG_STATE, "transfer out: data 0x%02x\n", data);
677 			m_state = XFR_OUT_NEXT;
678 
679 			// assert data and ACK
680 			scsi_bus->data_w(scsi_refid, data);
681 			scsi_bus->ctrl_w(scsi_refid, S_ACK, S_ACK);
682 		}
683 		else
684 		{
685 			delay = -1;
686 			if (m_command & DMA)
687 				set_drq(true);
688 		}
689 		break;
690 	case XFR_OUT_NEXT:
691 		if (!(scsi_bus->ctrl_r() & S_REQ))
692 		{
693 			LOGMASKED(LOG_STATE, "transfer out: data ACK\n");
694 			if (m_command & TRBE)
695 			{
696 				if (!--m_count)
697 				{
698 					m_status |= TRBZ;
699 					m_state = XFR_INFO_DONE;
700 				}
701 				else
702 					m_state = XFR_OUT_REQ;
703 			}
704 			else
705 				m_state = XFR_INFO_DONE;
706 
707 			// clear data and ACK
708 			scsi_bus->data_w(scsi_refid, 0);
709 			scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
710 		}
711 		break;
712 	case XFR_OUT_REQ:
713 		LOGMASKED(LOG_STATE, "transfer out: count %d waiting for REQ\n", m_count);
714 		if (scsi_bus->ctrl_r() & S_REQ)
715 		{
716 			// check if target changed phase
717 			if (m_int_req[1] & PHC)
718 			{
719 				if (m_command & DMA)
720 					set_drq(false);
721 
722 				m_state = XFR_INFO_DONE;
723 			}
724 			else
725 				m_state = XFR_OUT;
726 		}
727 		break;
728 	case XFR_INFO_DONE:
729 		LOGMASKED(LOG_STATE, "transfer: complete\n");
730 		m_state = COMPLETE;
731 		break;
732 
733 	case BUS_RESET:
734 		LOGMASKED(LOG_STATE, "bus reset: asserted\n");
735 		m_status &= ~(INIT | TARG);
736 		m_int_req[1] |= SRST;
737 
738 		m_state = BUS_RESET_DONE;
739 		delay = (m_mode & TMSL) ? m_rst_time : SCSI_RST_HOLD;
740 
741 		// clear data and assert RST
742 		scsi_bus->data_w(scsi_refid, 0);
743 		scsi_bus->ctrl_w(scsi_refid, S_RST, S_ALL);
744 		break;
745 	case BUS_RESET_DONE:
746 		LOGMASKED(LOG_STATE, "bus reset: complete\n");
747 		if (m_mode & TMSL)
748 			m_int_req[0] |= STO;
749 		m_state = COMPLETE;
750 
751 		// clear RST
752 		scsi_bus->ctrl_w(scsi_refid, 0, S_RST);
753 		break;
754 
755 	case COMPLETE:
756 		LOGMASKED(LOG_STATE, "function complete\n");
757 		m_int_req[1] |= FNC;
758 		m_state = IDLE;
759 		break;
760 	}
761 
762 	return delay;
763 }
764 
scsi_ctrl_changed()765 void cxd1185_device::scsi_ctrl_changed()
766 {
767 	u32 const ctrl = scsi_bus->ctrl_r();
768 
769 	if ((ctrl & S_BSY) && !(ctrl & S_SEL))
770 		LOGMASKED(LOG_SCSI, "scsi_ctrl_changed 0x%x phase %s%s%s\n", ctrl, nscsi_phase[ctrl & S_PHASE_MASK],
771 			ctrl & S_REQ ? " REQ" : "", ctrl & S_ACK ? " ACK" : "");
772 	else if (ctrl & S_BSY)
773 		LOGMASKED(LOG_SCSI, "scsi_ctrl_changed 0x%x arbitration/selection\n", ctrl);
774 	else if (ctrl & S_RST)
775 		LOGMASKED(LOG_SCSI, "scsi_ctrl_changed 0x%x BUS RESET\n", ctrl);
776 	else
777 		LOGMASKED(LOG_SCSI, "scsi_ctrl_changed 0x%x BUS FREE\n", ctrl);
778 
779 	if (ctrl & S_RST)
780 	{
781 		m_status &= ~(INIT | TARG);
782 		m_int_req[1] |= SRST;
783 
784 		// clear data and ctrl
785 		scsi_bus->data_w(scsi_refid, 0);
786 		scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
787 	}
788 	else if ((m_status & (TARG | INIT)) == INIT)
789 	{
790 		if ((ctrl & S_SEL) && !(m_scsi_ctrl_state & S_BSY) && (ctrl & S_BSY))
791 		{
792 			LOGMASKED(LOG_SCSI, "target selected\n");
793 
794 			// truncate selection delay
795 			m_state_timer->adjust(attotime::zero);
796 		}
797 		else if ((m_scsi_ctrl_state & S_BSY) && !(ctrl & S_BSY))
798 		{
799 			LOGMASKED(LOG_SCSI, "target disconnected\n");
800 
801 			m_status &= ~INIT;
802 			m_int_req[1] |= DCNT;
803 		}
804 		else if ((ctrl ^ m_scsi_ctrl_state) & S_PHASE_MASK)
805 		{
806 			if (ctrl & S_REQ)
807 			{
808 				LOGMASKED(LOG_SCSI, "target changed phase\n");
809 
810 				m_int_req[1] |= PHC;
811 				if (ctrl & S_MSG)
812 					m_int_req[1] |= RMSG;
813 			}
814 			else
815 				// ignore until req asserted
816 				return;
817 		}
818 	}
819 	else if ((m_status & (TARG | INIT)) == TARG)
820 	{
821 		if (!(m_scsi_ctrl_state & S_ATN) && (ctrl & S_ATN))
822 		{
823 			LOGMASKED(LOG_SCSI, "initiator asserted attention\n");
824 
825 			m_int_req[1] |= DATN;
826 		}
827 	}
828 
829 	// record state
830 	m_scsi_ctrl_state = ctrl;
831 
832 	int_check();
833 }
834 
int_check()835 void cxd1185_device::int_check()
836 {
837 	bool irq_asserted = false;
838 
839 	// update mirq
840 	if (m_int_req[0] || m_int_req[1])
841 	{
842 		m_status |= MIRQ;
843 
844 		irq_asserted = (m_int_req[0] & m_int_auth[0]) || (m_int_req[1] & m_int_auth[1]);
845 	}
846 	else
847 		m_status &= ~MIRQ;
848 
849 	// update irq line
850 	if (m_irq_asserted != irq_asserted)
851 	{
852 		LOGMASKED(LOG_INT, "irq_check interrupt %s\n", irq_asserted ? "asserted" : "cleared");
853 
854 		m_irq_asserted = irq_asserted;
855 		m_irq_out_cb((m_environ & SIRM) ? !m_irq_asserted : m_irq_asserted);
856 	}
857 }
858 
set_drq(bool asserted)859 void cxd1185_device::set_drq(bool asserted)
860 {
861 	if (m_drq_asserted != asserted)
862 	{
863 		LOGMASKED(LOG_DMA, "set_drq %s\n", asserted ? "asserted" : "deasserted");
864 		m_drq_asserted = asserted;
865 		m_drq_out_cb(m_drq_asserted);
866 	}
867 }
868 
dma_r()869 u8 cxd1185_device::dma_r()
870 {
871 	u8 const data = m_fifo.dequeue();
872 
873 	LOGMASKED(LOG_DMA, "dma_r 0x%02x\n", data);
874 
875 	if (m_fifo.empty())
876 	{
877 		set_drq(false);
878 
879 		if (m_count)
880 			m_state_timer->adjust(attotime::zero);
881 	}
882 
883 	return data;
884 }
885 
dma_w(u8 data)886 void cxd1185_device::dma_w(u8 data)
887 {
888 	LOGMASKED(LOG_DMA, "dma_w 0x%02x\n", data);
889 
890 	m_fifo.enqueue(data);
891 
892 	if (m_fifo.full() || m_fifo.queue_length() >= m_count)
893 	{
894 		set_drq(false);
895 
896 		if (m_count)
897 			m_state_timer->adjust(attotime::zero);
898 	}
899 }
900 
port_w(u8 data)901 void cxd1185_device::port_w(u8 data)
902 {
903 	u8 const mask = ~(PCN | ((m_ioport & PCN) >> 4));
904 
905 	LOGMASKED(LOG_GENERAL, "port_w 0x%02x mask 0x%02x\n", data, mask);
906 
907 	m_ioport &= ~mask;
908 	m_ioport |= data & mask;
909 }
910