1 // license:BSD-3-Clause
2 // copyright-holders:Couriersud
3 /**********************************************************************
4 
5     Z80 DMA interface and emulation
6 
7     For datasheet http://www.zilog.com/docs/z80/ps0179.pdf
8 
9     2008/01     couriersud
10 
11         - architecture copied from 8257 DMA
12         - significant changes to implementation
13         - This is only a minimum implementation to support dkong3 and mario drivers
14         - Only memory to memory is tested!
15 
16     TODO:
17         - reset command (C3) is handled improperly
18         - rewrite to match documentation
19         - implement missing features
20         - implement more asserts
21         - implement a INPUT_LINE_BUSREQ for Z80. As a workaround,
22           HALT is used. This implies burst mode.
23 
24 **********************************************************************/
25 
26 #include "emu.h"
27 #include "z80dma.h"
28 
29 #define LOG_GENERAL (1U << 0)
30 #define LOG_DMA     (1U << 1)
31 
32 //#define VERBOSE (LOG_GENERAL | LOG_DMA)
33 #include "logmacro.h"
34 
35 #define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__)
36 
37 //**************************************************************************
38 //  CONSTANTS
39 //**************************************************************************
40 
41 enum
42 {
43 	INT_RDY = 0,
44 	INT_MATCH,
45 	INT_END_OF_BLOCK,
46 	INT_MATCH_END_OF_BLOCK
47 };
48 
49 constexpr int COMMAND_RESET                         = 0xc3;
50 constexpr int COMMAND_RESET_PORT_A_TIMING           = 0xc7;
51 constexpr int COMMAND_RESET_PORT_B_TIMING           = 0xcb;
52 constexpr int COMMAND_LOAD                          = 0xcf;
53 constexpr int COMMAND_CONTINUE                      = 0xd3;
54 constexpr int COMMAND_DISABLE_INTERRUPTS            = 0xaf;
55 constexpr int COMMAND_ENABLE_INTERRUPTS             = 0xab;
56 constexpr int COMMAND_RESET_AND_DISABLE_INTERRUPTS  = 0xa3;
57 constexpr int COMMAND_ENABLE_AFTER_RETI             = 0xb7;
58 constexpr int COMMAND_READ_STATUS_BYTE              = 0xbf;
59 constexpr int COMMAND_REINITIALIZE_STATUS_BYTE      = 0x8b;
60 constexpr int COMMAND_INITIATE_READ_SEQUENCE        = 0xa7;
61 constexpr int COMMAND_FORCE_READY                   = 0xb3;
62 constexpr int COMMAND_ENABLE_DMA                    = 0x87;
63 constexpr int COMMAND_DISABLE_DMA                   = 0x83;
64 constexpr int COMMAND_READ_MASK_FOLLOWS             = 0xbb;
65 
66 constexpr int TM_TRANSFER           = 0x01;
67 constexpr int TM_SEARCH             = 0x02;
68 constexpr int TM_SEARCH_TRANSFER    = 0x03;
69 
70 
71 
72 //**************************************************************************
73 //  MACROS
74 //**************************************************************************
75 
76 #define REGNUM(_m, _s)          (((_m)<<3) + (_s))
77 #define GET_REGNUM(_r)          (&(_r) - &(WR0))
78 #define REG(_m, _s)             m_regs[REGNUM(_m,_s)]
79 #define WR0                     REG(0, 0)
80 #define WR1                     REG(1, 0)
81 #define WR2                     REG(2, 0)
82 #define WR3                     REG(3, 0)
83 #define WR4                     REG(4, 0)
84 #define WR5                     REG(5, 0)
85 #define WR6                     REG(6, 0)
86 
87 #define PORTA_ADDRESS_L         REG(0,1)
88 #define PORTA_ADDRESS_H         REG(0,2)
89 
90 #define BLOCKLEN_L              REG(0,3)
91 #define BLOCKLEN_H              REG(0,4)
92 
93 #define PORTA_TIMING            REG(1,1)
94 #define PORTB_TIMING            REG(2,1)
95 
96 #define MASK_BYTE               REG(3,1)
97 #define MATCH_BYTE              REG(3,2)
98 
99 #define PORTB_ADDRESS_L         REG(4,1)
100 #define PORTB_ADDRESS_H         REG(4,2)
101 #define INTERRUPT_CTRL          REG(4,3)
102 #define INTERRUPT_VECTOR        REG(4,4)
103 #define PULSE_CTRL              REG(4,5)
104 
105 #define READ_MASK               REG(6,1)
106 
107 #define PORTA_ADDRESS           ((PORTA_ADDRESS_H<<8) | PORTA_ADDRESS_L)
108 #define PORTB_ADDRESS           ((PORTB_ADDRESS_H<<8) | PORTB_ADDRESS_L)
109 #define BLOCKLEN                ((BLOCKLEN_H<<8) | BLOCKLEN_L)
110 
111 #define PORTA_INC               (WR1 & 0x10)
112 #define PORTB_INC               (WR2 & 0x10)
113 #define PORTA_FIXED             (((WR1 >> 4) & 0x02) == 0x02)
114 #define PORTB_FIXED             (((WR2 >> 4) & 0x02) == 0x02)
115 #define PORTA_MEMORY            (((WR1 >> 3) & 0x01) == 0x00)
116 #define PORTB_MEMORY            (((WR2 >> 3) & 0x01) == 0x00)
117 
118 #define PORTA_CYCLE_LEN         (4-(PORTA_TIMING & 0x03))
119 #define PORTB_CYCLE_LEN         (4-(PORTB_TIMING & 0x03))
120 
121 #define PORTA_IS_SOURCE         ((WR0 >> 2) & 0x01)
122 #define PORTB_IS_SOURCE         (!PORTA_IS_SOURCE)
123 #define TRANSFER_MODE           (WR0 & 0x03)
124 
125 #define MATCH_F_SET             (m_status &= ~0x10)
126 #define MATCH_F_CLEAR           (m_status |= 0x10)
127 #define EOB_F_SET               (m_status &= ~0x20)
128 #define EOB_F_CLEAR             (m_status |= 0x20)
129 
130 #define READY_ACTIVE_HIGH       ((WR5>>3) & 0x01)
131 #define AUTO_RESTART            ((WR5>>5) & 0x01)
132 
133 #define INTERRUPT_ENABLE        (WR3 & 0x20)
134 #define INT_ON_MATCH            (INTERRUPT_CTRL & 0x01)
135 #define INT_ON_END_OF_BLOCK     (INTERRUPT_CTRL & 0x02)
136 #define INT_ON_READY            (INTERRUPT_CTRL & 0x40)
137 #define STATUS_AFFECTS_VECTOR   (INTERRUPT_CTRL & 0x20)
138 
139 
140 
141 //**************************************************************************
142 //  LIVE DEVICE
143 //**************************************************************************
144 
145 // device type definition
146 DEFINE_DEVICE_TYPE(Z80DMA, z80dma_device, "z80dma", "Z80 DMA Controller")
147 
148 //-------------------------------------------------
149 //  z80dma_device - constructor
150 //-------------------------------------------------
151 
z80dma_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)152 z80dma_device::z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
153 	: device_t(mconfig, Z80DMA, tag, owner, clock)
154 	, device_z80daisy_interface(mconfig, *this)
155 	, m_out_busreq_cb(*this)
156 	, m_out_int_cb(*this)
157 	, m_out_ieo_cb(*this)
158 	, m_out_bao_cb(*this)
159 	, m_in_mreq_cb(*this)
160 	, m_out_mreq_cb(*this)
161 	, m_in_iorq_cb(*this)
162 	, m_out_iorq_cb(*this)
163 {
164 }
165 
166 
167 //-------------------------------------------------
168 //  device_start - device-specific startup
169 //-------------------------------------------------
170 
device_start()171 void z80dma_device::device_start()
172 {
173 	// resolve callbacks
174 	m_out_busreq_cb.resolve_safe();
175 	m_out_int_cb.resolve_safe();
176 	m_out_ieo_cb.resolve_safe();
177 	m_out_bao_cb.resolve_safe();
178 	m_in_mreq_cb.resolve_safe(0);
179 	m_out_mreq_cb.resolve_safe();
180 	m_in_iorq_cb.resolve_safe(0);
181 	m_out_iorq_cb.resolve_safe();
182 
183 	// allocate timer
184 	m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(z80dma_device::timerproc), this));
185 
186 	// register for state saving
187 	save_item(NAME(m_regs));
188 	save_item(NAME(m_regs_follow));
189 	save_item(NAME(m_num_follow));
190 	save_item(NAME(m_cur_follow));
191 	save_item(NAME(m_status));
192 	save_item(NAME(m_dma_enabled));
193 	save_item(NAME(m_vector));
194 	save_item(NAME(m_iei));
195 	save_item(NAME(m_ip));
196 	save_item(NAME(m_ius));
197 	save_item(NAME(m_addressA));
198 	save_item(NAME(m_addressB));
199 	save_item(NAME(m_count));
200 	save_item(NAME(m_rdy));
201 	save_item(NAME(m_force_ready));
202 	save_item(NAME(m_is_read));
203 	save_item(NAME(m_cur_cycle));
204 	save_item(NAME(m_latch));
205 }
206 
207 
208 //-------------------------------------------------
209 //  device_reset - device-specific reset
210 //-------------------------------------------------
211 
device_reset()212 void z80dma_device::device_reset()
213 {
214 	m_status = 0;
215 	m_rdy = 0;
216 	m_force_ready = 0;
217 	m_num_follow = 0;
218 	m_dma_enabled = 0;
219 	m_read_num_follow = m_read_cur_follow = 0;
220 	m_reset_pointer = 0;
221 	m_is_read = false;
222 	memset(m_regs, 0, sizeof(m_regs));
223 	memset(m_regs_follow, 0, sizeof(m_regs_follow));
224 
225 	// disable interrupts
226 	WR3 &= ~0x20;
227 	m_ip = 0;
228 	m_ius = 0;
229 	m_vector = 0;
230 
231 	update_status();
232 }
233 
234 
235 
236 //**************************************************************************
237 //  DAISY CHAIN INTERFACE
238 //**************************************************************************
239 
240 //-------------------------------------------------
241 //  z80daisy_irq_state - return the overall IRQ
242 //  state for this device
243 //-------------------------------------------------
244 
z80daisy_irq_state()245 int z80dma_device::z80daisy_irq_state()
246 {
247 	int state = 0;
248 
249 	if (m_ip)
250 	{
251 		// interrupt pending
252 		state = Z80_DAISY_INT;
253 	}
254 	else if (m_ius)
255 	{
256 		// interrupt under service
257 		state = Z80_DAISY_IEO;
258 	}
259 
260 	LOG("Z80DMA Interrupt State: %u\n", state);
261 
262 	return state;
263 }
264 
265 
266 //-------------------------------------------------
267 //  z80daisy_irq_ack - acknowledge an IRQ and
268 //  return the appropriate vector
269 //-------------------------------------------------
270 
z80daisy_irq_ack()271 int z80dma_device::z80daisy_irq_ack()
272 {
273 	if (m_ip)
274 	{
275 		LOG("Z80DMA Interrupt Acknowledge\n");
276 
277 		// clear interrupt pending flag
278 		m_ip = 0;
279 		interrupt_check();
280 
281 		// set interrupt under service flag
282 		m_ius = 1;
283 
284 		return m_vector;
285 	}
286 
287 	//logerror("z80dma_irq_ack: failed to find an interrupt to ack!\n");
288 
289 	return 0;
290 }
291 
292 
293 //-------------------------------------------------
294 //  z80daisy_irq_reti - clear the interrupt
295 //  pending state to allow other interrupts through
296 //-------------------------------------------------
297 
z80daisy_irq_reti()298 void z80dma_device::z80daisy_irq_reti()
299 {
300 	if (m_ius)
301 	{
302 		LOG("Z80DMA Return from Interrupt\n");
303 
304 		// clear interrupt under service flag
305 		m_ius = 0;
306 		interrupt_check();
307 
308 		return;
309 	}
310 
311 	//logerror("z80dma_irq_reti: failed to find an interrupt to clear IEO on!\n");
312 }
313 
314 
315 
316 //**************************************************************************
317 //  INTERNAL STATE MANAGEMENT
318 //**************************************************************************
319 
320 //-------------------------------------------------
321 //  is_ready - ready for DMA transfer?
322 //-------------------------------------------------
323 
is_ready()324 int z80dma_device::is_ready()
325 {
326 	return (m_force_ready) || (m_rdy == READY_ACTIVE_HIGH);
327 }
328 
329 
330 //-------------------------------------------------
331 //  interrupt_check - update IRQ line state
332 //-------------------------------------------------
333 
interrupt_check()334 void z80dma_device::interrupt_check()
335 {
336 	m_out_int_cb(m_ip ? ASSERT_LINE : CLEAR_LINE);
337 	m_out_ieo_cb(m_iei && !m_ip);
338 }
339 
340 
341 //-------------------------------------------------
342 //  trigger_interrupt - trigger DMA interrupt
343 //-------------------------------------------------
344 
trigger_interrupt(int level)345 void z80dma_device::trigger_interrupt(int level)
346 {
347 	if (!m_ius && INTERRUPT_ENABLE)
348 	{
349 		// set interrupt pending flag
350 		m_ip = 1;
351 
352 		// set interrupt vector
353 		if (STATUS_AFFECTS_VECTOR)
354 		{
355 			m_vector = (INTERRUPT_VECTOR & 0xf9) | (level << 1);
356 		}
357 		else
358 		{
359 			m_vector = INTERRUPT_VECTOR;
360 		}
361 
362 		m_status &= ~0x08;
363 
364 		LOG("Z80DMA Interrupt Pending\n");
365 
366 		interrupt_check();
367 	}
368 }
369 
370 
371 //-------------------------------------------------
372 //  do_read - perform DMA read
373 //-------------------------------------------------
374 
do_read()375 void z80dma_device::do_read()
376 {
377 	uint8_t mode;
378 
379 	mode = TRANSFER_MODE;
380 	switch(mode) {
381 		case TM_TRANSFER:
382 		case TM_SEARCH:
383 		case TM_SEARCH_TRANSFER:
384 			if (PORTA_IS_SOURCE)
385 			{
386 				if (PORTA_MEMORY)
387 					m_latch = m_in_mreq_cb(m_addressA);
388 				else
389 					m_latch = m_in_iorq_cb(m_addressA);
390 
391 				LOGDMA("Z80DMA A src: %04x %s -> data: %02x\n", m_addressA, PORTA_MEMORY ? "mem" : "i/o", m_latch);
392 			}
393 			else
394 			{
395 				if (PORTB_MEMORY)
396 					m_latch = m_in_mreq_cb(m_addressB);
397 				else
398 					m_latch = m_in_iorq_cb(m_addressB);
399 
400 				LOGDMA("Z80DMA B src: %04x %s -> data: %02x\n", m_addressB, PORTB_MEMORY ? "mem" : "i/o", m_latch);
401 			}
402 			break;
403 		default:
404 			logerror("z80dma_do_operation: invalid mode %d!\n", mode);
405 			break;
406 	}
407 }
408 
409 
410 //-------------------------------------------------
411 //  do_write - perform DMA write
412 //-------------------------------------------------
413 
do_transfer_write()414 void z80dma_device::do_transfer_write()
415 {
416 	if (PORTA_IS_SOURCE)
417 	{
418 		if (PORTB_MEMORY)
419 			m_out_mreq_cb((offs_t)m_addressB, m_latch);
420 		else
421 			m_out_iorq_cb((offs_t)m_addressB, m_latch);
422 
423 		LOGDMA("Z80DMA B dst: %04x %s\n", m_addressB, PORTB_MEMORY ? "mem" : "i/o");
424 	}
425 	else
426 	{
427 		if (PORTA_MEMORY)
428 			m_out_mreq_cb((offs_t)m_addressA, m_latch);
429 		else
430 			m_out_iorq_cb((offs_t)m_addressA, m_latch);
431 
432 		LOGDMA("Z80DMA A dst: %04x %s\n", m_addressA, PORTA_MEMORY ? "mem" : "i/o");
433 	}
434 }
435 
do_search()436 void z80dma_device::do_search()
437 {
438 	uint8_t load_byte,match_byte;
439 	load_byte = m_latch | MASK_BYTE;
440 	match_byte = MATCH_BYTE | MASK_BYTE;
441 	//LOG("%02x %02x\n",load_byte,match_byte));
442 	if (load_byte == match_byte)
443 	{
444 		if (INT_ON_MATCH)
445 		{
446 			trigger_interrupt(INT_MATCH);
447 		}
448 	}
449 }
450 
do_write()451 int z80dma_device::do_write()
452 {
453 	int done;
454 	uint8_t mode;
455 
456 	mode = TRANSFER_MODE;
457 	if (m_count == 0x0000)
458 	{
459 		//FIXME: Any signal here
460 	}
461 	switch(mode) {
462 		case TM_TRANSFER:
463 			do_transfer_write();
464 			break;
465 
466 		case TM_SEARCH:
467 			do_search();
468 			break;
469 
470 		case TM_SEARCH_TRANSFER:
471 			do_transfer_write();
472 			do_search();
473 			break;
474 
475 		default:
476 			logerror("z80dma_do_operation: invalid mode %d!\n", mode);
477 			break;
478 	}
479 
480 	m_addressA += PORTA_FIXED ? 0 : PORTA_INC ? 1 : -1;
481 	m_addressB += PORTB_FIXED ? 0 : PORTB_INC ? 1 : -1;
482 
483 	m_count--;
484 	done = (m_count == 0xFFFF); //correct?
485 
486 	if (done)
487 	{
488 		//FIXME: interrupt ?
489 	}
490 	return done;
491 }
492 
493 
494 //-------------------------------------------------
495 //  timerproc
496 //-------------------------------------------------
497 
TIMER_CALLBACK_MEMBER(z80dma_device::timerproc)498 TIMER_CALLBACK_MEMBER(z80dma_device::timerproc)
499 {
500 	int done;
501 
502 	if (--m_cur_cycle)
503 	{
504 		return;
505 	}
506 
507 	if (m_is_read && !is_ready()) return;
508 
509 	if (m_is_read)
510 	{
511 		/* TODO: there's a nasty recursion bug with Alpha for Sharp X1 Turbo on the transfers with this function! */
512 		do_read();
513 		done = 0;
514 		m_is_read = false;
515 		m_cur_cycle = (PORTA_IS_SOURCE ? PORTA_CYCLE_LEN : PORTB_CYCLE_LEN);
516 	}
517 	else
518 	{
519 		done = do_write();
520 		m_is_read = true;
521 		m_cur_cycle = (PORTB_IS_SOURCE ? PORTA_CYCLE_LEN : PORTB_CYCLE_LEN);
522 	}
523 
524 	if (done)
525 	{
526 		m_dma_enabled = 0; //FIXME: Correct?
527 		m_status = 0x09;
528 
529 		m_status |= !is_ready() << 1; // ready line status
530 
531 		if(TRANSFER_MODE == TM_TRANSFER)     m_status |= 0x10;   // no match found
532 
533 		update_status();
534 		LOG("Z80DMA End of Block\n");
535 
536 		if (INT_ON_END_OF_BLOCK)
537 		{
538 			trigger_interrupt(INT_END_OF_BLOCK);
539 		}
540 
541 		if (AUTO_RESTART)
542 		{
543 			LOG("Z80DMA Auto Restart\n");
544 
545 			m_dma_enabled = 1;
546 			m_addressA = PORTA_ADDRESS;
547 			m_addressB = PORTB_ADDRESS;
548 			m_count = BLOCKLEN;
549 			m_status |= 0x30;
550 		}
551 	}
552 }
553 
554 
555 //-------------------------------------------------
556 //  update_status - update DMA status
557 //-------------------------------------------------
558 
update_status()559 void z80dma_device::update_status()
560 {
561 	uint16_t pending_transfer;
562 	attotime next;
563 
564 	// no transfer is active right now; is there a transfer pending right now?
565 	pending_transfer = is_ready() & m_dma_enabled;
566 
567 	if (pending_transfer)
568 	{
569 		m_is_read = true;
570 		m_cur_cycle = (PORTA_IS_SOURCE ? PORTA_CYCLE_LEN : PORTB_CYCLE_LEN);
571 		next = attotime::from_hz(clock());
572 		m_timer->adjust(
573 			attotime::zero,
574 			0,
575 			// 1 byte transferred in 4 clock cycles
576 			next);
577 	}
578 	else
579 	{
580 		if (m_is_read)
581 		{
582 			// no transfers active right now
583 			m_timer->reset();
584 		}
585 	}
586 
587 	// set the busreq line
588 	m_out_busreq_cb(pending_transfer ? ASSERT_LINE : CLEAR_LINE);
589 }
590 
591 
592 
593 //**************************************************************************
594 //  READ/WRITE INTERFACES
595 //**************************************************************************
596 
597 //-------------------------------------------------
598 //  read - register read
599 //-------------------------------------------------
600 
read()601 uint8_t z80dma_device::read()
602 {
603 	uint8_t res;
604 
605 	if(m_read_num_follow == 0) // special case: Legend of Kage on X1 Turbo
606 		res = m_status;
607 	else {
608 		res = m_read_regs_follow[m_read_cur_follow];
609 	}
610 
611 	m_read_cur_follow++;
612 
613 	if(m_read_cur_follow >= m_read_num_follow)
614 		m_read_cur_follow = 0;
615 
616 	LOG("Z80DMA Read %02x\n", res);
617 
618 	return res;
619 }
620 
621 
622 //-------------------------------------------------
623 //  write - register write
624 //-------------------------------------------------
625 
write(uint8_t data)626 void z80dma_device::write(uint8_t data)
627 {
628 	if (m_num_follow == 0)
629 	{
630 		m_reset_pointer = 0;
631 
632 		if ((data & 0x87) == 0) // WR2
633 		{
634 			LOG("Z80DMA WR2 %02x\n", data);
635 			WR2 = data;
636 			if (data & 0x40)
637 				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_TIMING);
638 		}
639 		else if ((data & 0x87) == 0x04) // WR1
640 		{
641 			LOG("Z80DMA WR1 %02x\n", data);
642 			WR1 = data;
643 			if (data & 0x40)
644 				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_TIMING);
645 		}
646 		else if ((data & 0x80) == 0) // WR0
647 		{
648 			LOG("Z80DMA WR0 %02x\n", data);
649 			WR0 = data;
650 			if (data & 0x08)
651 				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_ADDRESS_L);
652 			if (data & 0x10)
653 				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_ADDRESS_H);
654 			if (data & 0x20)
655 				m_regs_follow[m_num_follow++] = GET_REGNUM(BLOCKLEN_L);
656 			if (data & 0x40)
657 				m_regs_follow[m_num_follow++] = GET_REGNUM(BLOCKLEN_H);
658 		}
659 		else if ((data & 0x83) == 0x80) // WR3
660 		{
661 			LOG("Z80DMA WR3 %02x\n", data);
662 			WR3 = data;
663 			if (data & 0x08)
664 				m_regs_follow[m_num_follow++] = GET_REGNUM(MASK_BYTE);
665 			if (data & 0x10)
666 				m_regs_follow[m_num_follow++] = GET_REGNUM(MATCH_BYTE);
667 		}
668 		else if ((data & 0x83) == 0x81) // WR4
669 		{
670 			LOG("Z80DMA WR4 %02x\n", data);
671 			WR4 = data;
672 			if (data & 0x04)
673 				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_ADDRESS_L);
674 			if (data & 0x08)
675 				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_ADDRESS_H);
676 			if (data & 0x10)
677 				m_regs_follow[m_num_follow++] = GET_REGNUM(INTERRUPT_CTRL);
678 		}
679 		else if ((data & 0xC7) == 0x82) // WR5
680 		{
681 			LOG("Z80DMA WR5 %02x\n", data);
682 			WR5 = data;
683 		}
684 		else if ((data & 0x83) == 0x83) // WR6
685 		{
686 			LOG("Z80DMA WR6 %02x\n", data);
687 			m_dma_enabled = 0;
688 
689 			WR6 = data;
690 
691 			switch (data)
692 			{
693 				case COMMAND_ENABLE_AFTER_RETI:
694 					fatalerror("Z80DMA '%s' Unimplemented WR6 command %02x\n", tag(), data);
695 				case COMMAND_READ_STATUS_BYTE:
696 					LOG("Z80DMA CMD Read status Byte\n");
697 					READ_MASK = 1;
698 					m_read_regs_follow[0] = m_status;
699 					break;
700 				case COMMAND_RESET_AND_DISABLE_INTERRUPTS:
701 					WR3 &= ~0x20;
702 					m_ip = 0;
703 					m_ius = 0;
704 					m_force_ready = 0;
705 					m_status |= 0x08;
706 					break;
707 				case COMMAND_INITIATE_READ_SEQUENCE:
708 					LOG("Z80DMA Initiate Read Sequence\n");
709 					m_read_cur_follow = m_read_num_follow = 0;
710 					if(READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
711 					if(READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = m_count & 0xff; } //byte counter (low)
712 					if(READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = m_count >> 8; } //byte counter (high)
713 					if(READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = m_addressA & 0xff; } //port A address (low)
714 					if(READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = m_addressA >> 8; } //port A address (high)
715 					if(READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = m_addressB & 0xff; } //port B address (low)
716 					if(READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = m_addressB >> 8; } //port B address (high)
717 					break;
718 				case COMMAND_RESET:
719 					LOG("Z80DMA Reset\n");
720 					m_dma_enabled = 0;
721 					m_force_ready = 0;
722 					m_ip = 0;
723 					m_ius = 0;
724 					interrupt_check();
725 					// Needs six reset commands to reset the DMA
726 					{
727 						uint8_t WRi;
728 
729 						for(WRi=0;WRi<7;WRi++)
730 							REG(WRi,m_reset_pointer) = 0;
731 
732 						m_reset_pointer++;
733 						if(m_reset_pointer >= 6) { m_reset_pointer = 0; }
734 					}
735 					m_status = 0x38;
736 					break;
737 				case COMMAND_LOAD:
738 					m_force_ready = 0;
739 					m_addressA = PORTA_ADDRESS;
740 					m_addressB = PORTB_ADDRESS;
741 					m_count = BLOCKLEN;
742 					m_status |= 0x30;
743 
744 					LOG("Z80DMA Load A: %x B: %x N: %x\n", m_addressA, m_addressB, m_count);
745 					break;
746 				case COMMAND_DISABLE_DMA:
747 					LOG("Z80DMA Disable DMA\n");
748 					m_dma_enabled = 0;
749 					break;
750 				case COMMAND_ENABLE_DMA:
751 					LOG("Z80DMA Enable DMA\n");
752 					m_dma_enabled = 1;
753 					update_status();
754 					break;
755 				case COMMAND_READ_MASK_FOLLOWS:
756 					LOG("Z80DMA Set Read Mask\n");
757 					m_regs_follow[m_num_follow++] = GET_REGNUM(READ_MASK);
758 					break;
759 				case COMMAND_CONTINUE:
760 					LOG("Z80DMA Continue\n");
761 					m_count = BLOCKLEN;
762 					m_dma_enabled = 1;
763 					//"match not found" & "end of block" status flags zeroed here
764 					m_status |= 0x30;
765 					break;
766 				case COMMAND_RESET_PORT_A_TIMING:
767 					LOG("Z80DMA Reset Port A Timing\n");
768 					PORTA_TIMING = 0;
769 					break;
770 				case COMMAND_RESET_PORT_B_TIMING:
771 					LOG("Z80DMA Reset Port B Timing\n");
772 					PORTB_TIMING = 0;
773 					break;
774 				case COMMAND_FORCE_READY:
775 					LOG("Z80DMA Force Ready\n");
776 					m_force_ready = 1;
777 					update_status();
778 					break;
779 				case COMMAND_ENABLE_INTERRUPTS:
780 					LOG("Z80DMA Enable IRQ\n");
781 					WR3 |= 0x20;
782 					break;
783 				case COMMAND_DISABLE_INTERRUPTS:
784 					LOG("Z80DMA Disable IRQ\n");
785 					WR3 &= ~0x20;
786 					break;
787 				case COMMAND_REINITIALIZE_STATUS_BYTE:
788 					LOG("Z80DMA Reinitialize status byte\n");
789 					m_status |= 0x30;
790 					m_ip = 0;
791 					break;
792 				case 0xFB:
793 				case 0xFF: // TODO: p8k triggers this, it probably crashed.
794 					LOG("Z80DMA undocumented command triggered 0x%02X!\n", data);
795 					break;
796 				default:
797 					logerror("Z80DMA Unknown WR6 command %02x\n", data);
798 			}
799 		}
800 		else if(data == 0x8e) //newtype on Sharp X1, unknown purpose
801 			logerror("Z80DMA Unknown base register %02x\n", data);
802 		else
803 			fatalerror("Z80DMA '%s' Unknown base register %02x\n", tag(), data);
804 		m_cur_follow = 0;
805 	}
806 	else
807 	{
808 		LOG("Z80DMA Write %02x\n", data);
809 
810 		int nreg = m_regs_follow[m_cur_follow];
811 		m_regs[nreg] = data;
812 		m_cur_follow++;
813 		if (m_cur_follow>=m_num_follow)
814 			m_num_follow = 0;
815 		if (nreg == REGNUM(4,3))
816 		{
817 			m_num_follow=0;
818 			if (data & 0x08)
819 				m_regs_follow[m_num_follow++] = GET_REGNUM(PULSE_CTRL);
820 			if (data & 0x10)
821 				m_regs_follow[m_num_follow++] = GET_REGNUM(INTERRUPT_VECTOR);
822 			m_cur_follow = 0;
823 		}
824 		else if(m_regs_follow[m_num_follow] == GET_REGNUM(READ_MASK))
825 		{
826 			m_read_cur_follow = m_read_num_follow = 0;
827 
828 			if(READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
829 			if(READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = m_count & 0xff; } //byte counter (low)
830 			if(READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = m_count >> 8; } //byte counter (high)
831 			if(READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = m_addressA & 0xff; } //port A address (low)
832 			if(READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = m_addressA >> 8; } //port A address (high)
833 			if(READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = m_addressB & 0xff; } //port B address (low)
834 			if(READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = m_addressB >> 8; } //port B address (high)
835 		}
836 
837 		m_reset_pointer++;
838 		if(m_reset_pointer >= 6) { m_reset_pointer = 0; }
839 	}
840 }
841 
842 
843 //-------------------------------------------------
844 //  rdy_write_callback - deferred RDY signal write
845 //-------------------------------------------------
846 
TIMER_CALLBACK_MEMBER(z80dma_device::rdy_write_callback)847 TIMER_CALLBACK_MEMBER(z80dma_device::rdy_write_callback)
848 {
849 	// normalize state
850 	m_rdy = param;
851 	m_status = (m_status & 0xFD) | (!is_ready() << 1);
852 
853 	update_status();
854 
855 	if (is_ready() && INT_ON_READY)
856 	{
857 		trigger_interrupt(INT_RDY);
858 	}
859 }
860 
861 
862 //-------------------------------------------------
863 //  rdy_w - ready input
864 //-------------------------------------------------
865 
WRITE_LINE_MEMBER(z80dma_device::rdy_w)866 WRITE_LINE_MEMBER(z80dma_device::rdy_w)
867 {
868 	LOG("Z80DMA RDY: %d Active High: %d\n", state, READY_ACTIVE_HIGH);
869 	machine().scheduler().synchronize(timer_expired_delegate(FUNC(z80dma_device::rdy_write_callback),this), state);
870 }
871 
872 
873 //-------------------------------------------------
874 //  wait_w - wait input
875 //-------------------------------------------------
876 
WRITE_LINE_MEMBER(z80dma_device::wait_w)877 WRITE_LINE_MEMBER(z80dma_device::wait_w)
878 {
879 }
880 
881 
882 //-------------------------------------------------
883 //  bai_w - bus acknowledge input
884 //-------------------------------------------------
885 
WRITE_LINE_MEMBER(z80dma_device::bai_w)886 WRITE_LINE_MEMBER(z80dma_device::bai_w)
887 {
888 }
889