예제 #1
0
파일: z80dma.c 프로젝트: johkelly/MAME_hi
void z80dma_device::write(UINT8 data)
{
	if (LOG) logerror("Z80DMA '%s' Write %02x\n", tag(), data);

	if (m_num_follow == 0)
	{
		m_reset_pointer = 0;

		if ((data & 0x87) == 0) // WR2
		{
			WR2 = data;
			if (data & 0x40)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_TIMING);
		}
		else if ((data & 0x87) == 0x04) // WR1
		{
			WR1 = data;
			if (data & 0x40)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_TIMING);
		}
		else if ((data & 0x80) == 0) // WR0
		{
			WR0 = data;
			if (data & 0x08)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_ADDRESS_L);
			if (data & 0x10)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_ADDRESS_H);
			if (data & 0x20)
				m_regs_follow[m_num_follow++] = GET_REGNUM(BLOCKLEN_L);
			if (data & 0x40)
				m_regs_follow[m_num_follow++] = GET_REGNUM(BLOCKLEN_H);
		}
		else if ((data & 0x83) == 0x80) // WR3
		{
			WR3 = data;
			if (data & 0x08)
				m_regs_follow[m_num_follow++] = GET_REGNUM(MASK_BYTE);
			if (data & 0x10)
				m_regs_follow[m_num_follow++] = GET_REGNUM(MATCH_BYTE);
		}
		else if ((data & 0x83) == 0x81) // WR4
		{
			WR4 = data;
			if (data & 0x04)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_ADDRESS_L);
			if (data & 0x08)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_ADDRESS_H);
			if (data & 0x10)
				m_regs_follow[m_num_follow++] = GET_REGNUM(INTERRUPT_CTRL);
		}
		else if ((data & 0xC7) == 0x82) // WR5
		{
			WR5 = data;
		}
		else if ((data & 0x83) == 0x83) // WR6
		{
			m_dma_enabled = 0;

			WR6 = data;

			switch (data)
			{
				case COMMAND_ENABLE_AFTER_RETI:
					fatalerror("Z80DMA '%s' Unimplemented WR6 command %02x", tag(), data);
					break;
				case COMMAND_READ_STATUS_BYTE:
					if (LOG) logerror("Z80DMA '%s' CMD Read status Byte\n", tag());
        			READ_MASK = 0;
        			break;
				case COMMAND_RESET_AND_DISABLE_INTERRUPTS:
					WR3 &= ~0x20;
					m_ip = 0;
					m_ius = 0;
					m_force_ready = 0;
					m_status |= 0x08;
					break;
				case COMMAND_INITIATE_READ_SEQUENCE:
					if (LOG) logerror("Z80DMA '%s' Initiate Read Sequence\n", tag());
					m_read_cur_follow = m_read_num_follow = 0;
					if(READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
					if(READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = BLOCKLEN_L; } //byte counter (low)
					if(READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = BLOCKLEN_H; } //byte counter (high)
					if(READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = PORTA_ADDRESS_L; } //port A address (low)
					if(READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = PORTA_ADDRESS_H; } //port A address (high)
					if(READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = PORTB_ADDRESS_L; } //port B address (low)
					if(READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = PORTB_ADDRESS_H; } //port B address (high)
					break;
				case COMMAND_RESET:
					if (LOG) logerror("Z80DMA '%s' Reset\n", tag());
					m_dma_enabled = 0;
					m_force_ready = 0;
					m_ip = 0;
					m_ius = 0;
					interrupt_check();
					// Needs six reset commands to reset the DMA
					{
						UINT8 WRi;

						for(WRi=0;WRi<7;WRi++)
							REG(WRi,m_reset_pointer) = 0;

						m_reset_pointer++;
						if(m_reset_pointer >= 6) { m_reset_pointer = 0; }
					}
					m_status = 0x38;
					break;
				case COMMAND_LOAD:
					m_force_ready = 0;
					m_addressA = PORTA_ADDRESS;
					m_addressB = PORTB_ADDRESS;
					m_count = BLOCKLEN;
					m_status |= 0x30;
					if (LOG) logerror("Z80DMA '%s' Load A: %x B: %x N: %x\n", tag(), m_addressA, m_addressB, m_count);
					break;
				case COMMAND_DISABLE_DMA:
					if (LOG) logerror("Z80DMA '%s' Disable DMA\n", tag());
					m_dma_enabled = 0;
					break;
				case COMMAND_ENABLE_DMA:
					if (LOG) logerror("Z80DMA '%s' Enable DMA\n", tag());
					m_dma_enabled = 1;
					update_status();
					break;
				case COMMAND_READ_MASK_FOLLOWS:
					if (LOG) logerror("Z80DMA '%s' Set Read Mask\n", tag());
					m_regs_follow[m_num_follow++] = GET_REGNUM(READ_MASK);
					break;
				case COMMAND_CONTINUE:
					if (LOG) logerror("Z80DMA '%s' Continue\n", tag());
					m_count = BLOCKLEN;
					m_dma_enabled = 1;
					//"match not found" & "end of block" status flags zeroed here
					m_status |= 0x30;
					break;
				case COMMAND_RESET_PORT_A_TIMING:
					if (LOG) logerror("Z80DMA '%s' Reset Port A Timing\n", tag());
					PORTA_TIMING = 0;
					break;
				case COMMAND_RESET_PORT_B_TIMING:
					if (LOG) logerror("Z80DMA '%s' Reset Port B Timing\n", tag());
					PORTB_TIMING = 0;
					break;
				case COMMAND_FORCE_READY:
					if (LOG) logerror("Z80DMA '%s' Force Ready\n", tag());
					m_force_ready = 1;
					update_status();
					break;
				case COMMAND_ENABLE_INTERRUPTS:
					if (LOG) logerror("Z80DMA '%s' Enable IRQ\n", tag());
					WR3 |= 0x20;
					break;
				case COMMAND_DISABLE_INTERRUPTS:
					if (LOG) logerror("Z80DMA '%s' Disable IRQ\n", tag());
					WR3 &= ~0x20;
					break;
				case COMMAND_REINITIALIZE_STATUS_BYTE:
					if (LOG) logerror("Z80DMA '%s' Reinitialize status byte\n", tag());
					m_status |= 0x30;
					m_ip = 0;
					break;
				case 0xFB:
					if (LOG) logerror("Z80DMA '%s' undocumented command triggered 0x%02X!\n", tag(), data);
					break;
				default:
					fatalerror("Z80DMA '%s' Unknown WR6 command %02x", tag(), data);
			}
		}
		else
			fatalerror("Z80DMA '%s' Unknown base register %02x", tag(), data);
		m_cur_follow = 0;
	}
	else
	{
		int nreg = m_regs_follow[m_cur_follow];
		m_regs[nreg] = data;
		m_cur_follow++;
		if (m_cur_follow>=m_num_follow)
			m_num_follow = 0;
		if (nreg == REGNUM(4,3))
		{
			m_num_follow=0;
			if (data & 0x08)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PULSE_CTRL);
			if (data & 0x10)
				m_regs_follow[m_num_follow++] = GET_REGNUM(INTERRUPT_VECTOR);
			m_cur_follow = 0;
		}

		m_reset_pointer++;
		if(m_reset_pointer >= 6) { m_reset_pointer = 0; }
	}
}
예제 #2
0
파일: z80dma.cpp 프로젝트: Chintiger/mame
void z80dma_device::write(UINT8 data)
{
	if (m_num_follow == 0)
	{
		m_reset_pointer = 0;

		if ((data & 0x87) == 0) // WR2
		{
			if (LOG) logerror("Z80DMA '%s' WR2 %02x\n", tag(), data);
			WR2 = data;
			if (data & 0x40)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_TIMING);
		}
		else if ((data & 0x87) == 0x04) // WR1
		{
			if (LOG) logerror("Z80DMA '%s' WR1 %02x\n", tag(), data);
			WR1 = data;
			if (data & 0x40)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_TIMING);
		}
		else if ((data & 0x80) == 0) // WR0
		{
			if (LOG) logerror("Z80DMA '%s' WR0 %02x\n", tag(), data);
			WR0 = data;
			if (data & 0x08)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_ADDRESS_L);
			if (data & 0x10)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTA_ADDRESS_H);
			if (data & 0x20)
				m_regs_follow[m_num_follow++] = GET_REGNUM(BLOCKLEN_L);
			if (data & 0x40)
				m_regs_follow[m_num_follow++] = GET_REGNUM(BLOCKLEN_H);
		}
		else if ((data & 0x83) == 0x80) // WR3
		{
			if (LOG) logerror("Z80DMA '%s' WR3 %02x\n", tag(), data);
			WR3 = data;
			if (data & 0x08)
				m_regs_follow[m_num_follow++] = GET_REGNUM(MASK_BYTE);
			if (data & 0x10)
				m_regs_follow[m_num_follow++] = GET_REGNUM(MATCH_BYTE);
		}
		else if ((data & 0x83) == 0x81) // WR4
		{
			if (LOG) logerror("Z80DMA '%s' WR4 %02x\n", tag(), data);
			WR4 = data;
			if (data & 0x04)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_ADDRESS_L);
			if (data & 0x08)
				m_regs_follow[m_num_follow++] = GET_REGNUM(PORTB_ADDRESS_H);
			if (data & 0x10)
				m_regs_follow[m_num_follow++] = GET_REGNUM(INTERRUPT_CTRL);
		}
		else if ((data & 0xC7) == 0x82) // WR5
		{
			if (LOG) logerror("Z80DMA '%s' WR5 %02x\n", tag(), data);
			WR5 = data;
		}
		else if ((data & 0x83) == 0x83) // WR6
		{
			if (LOG) logerror("Z80DMA '%s' WR6 %02x\n", tag(), data);
			m_dma_enabled = 0;

			WR6 = data;

			switch (data)
			{
				case COMMAND_ENABLE_AFTER_RETI:
					fatalerror("Z80DMA '%s' Unimplemented WR6 command %02x\n", tag(), data);
				case COMMAND_READ_STATUS_BYTE:
					if (LOG) logerror("Z80DMA '%s' CMD Read status Byte\n", tag());
					READ_MASK = 1;
					m_read_regs_follow[0] = m_status;
					break;
				case COMMAND_RESET_AND_DISABLE_INTERRUPTS:
					WR3 &= ~0x20;
					m_ip = 0;
					m_ius = 0;
					m_force_ready = 0;
					m_status |= 0x08;
					break;
				case COMMAND_INITIATE_READ_SEQUENCE:
					if (LOG) logerror("Z80DMA '%s' Initiate Read Sequence\n", tag());
					m_read_cur_follow = m_read_num_follow = 0;
					if(READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
					if(READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = m_count & 0xff; } //byte counter (low)
					if(READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = m_count >> 8; } //byte counter (high)
					if(READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = m_addressA & 0xff; } //port A address (low)
					if(READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = m_addressA >> 8; } //port A address (high)
					if(READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = m_addressB & 0xff; } //port B address (low)
					if(READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = m_addressB >> 8; } //port B address (high)