예제 #1
0
void ppi8255_device::ppi8255_input(int port, UINT8 data)
{
	int changed = 0;

	m_read[port] = data;

	/* port C is special */
	if (port == 2)
	{
		if (((m_group_a_mode == 1) && (m_port_a_dir == 0)) || (m_group_a_mode == 2))
		{
			/* is !ACKA asserted? */
			if (m_obf_a && !(data & 0x40))
			{
				m_obf_a = 0;
				changed = 1;
			}
		}

		if (((m_group_a_mode == 1) && (m_port_a_dir == 1)) || (m_group_a_mode == 2))
		{
			/* is !STBA asserted? */
			if (!m_ibf_a && !(data & 0x10))
			{
				m_ibf_a = 1;
				changed = 1;
			}
		}

		if ((m_group_b_mode == 1) && (m_port_b_dir == 0))
		{
			/* is !ACKB asserted? */
			if (m_obf_b && !(data & 0x04))
			{
				m_obf_b = 0;
				changed = 1;
			}
		}

		if ((m_group_b_mode == 1) && (m_port_b_dir == 1))
		{
			/* is !STBB asserted? */
			if (!m_ibf_b && !(data & 0x04))
			{
				m_ibf_b = 1;
				changed = 1;
			}
		}

		if (changed)
		{
			ppi8255_write_port(2);
		}
	}
}
예제 #2
0
static void ppi8255_input(running_device *device, int port, UINT8 data)
{
	ppi8255_t	*ppi8255 = get_safe_token(device);
	int changed = 0;

	ppi8255->read[port] = data;

	/* port C is special */
	if (port == 2)
	{
		if (((ppi8255->group_a_mode == 1) && (ppi8255->port_a_dir == 0)) || (ppi8255->group_a_mode == 2))
		{
			/* is !ACKA asserted? */
			if (ppi8255->obf_a && !(data & 0x40))
			{
				ppi8255->obf_a = 0;
				changed = 1;
			}
		}

		if (((ppi8255->group_a_mode == 1) && (ppi8255->port_a_dir == 1)) || (ppi8255->group_a_mode == 2))
		{
			/* is !STBA asserted? */
			if (!ppi8255->ibf_a && !(data & 0x10))
			{
				ppi8255->ibf_a = 1;
				changed = 1;
			}
		}

		if ((ppi8255->group_b_mode == 1) && (ppi8255->port_b_dir == 0))
		{
			/* is !ACKB asserted? */
			if (ppi8255->obf_b && !(data & 0x04))
			{
				ppi8255->obf_b = 0;
				changed = 1;
			}
		}

		if ((ppi8255->group_b_mode == 1) && (ppi8255->port_b_dir == 1))
		{
			/* is !STBB asserted? */
			if (!ppi8255->ibf_b && !(data & 0x04))
			{
				ppi8255->ibf_b = 1;
				changed = 1;
			}
		}

		if (changed)
			ppi8255_write_port(device, 2);
	}
}
예제 #3
0
static void set_mode(running_device *device, int data, int call_handlers)
{
	ppi8255_t	*ppi8255 = get_safe_token(device);
	int i;

	/* parse out mode */
	ppi8255->group_a_mode = (data >> 5) & 3;
	ppi8255->group_b_mode = (data >> 2) & 1;
	ppi8255->port_a_dir = (data >> 4) & 1;
	ppi8255->port_b_dir = (data >> 1) & 1;
	ppi8255->port_ch_dir = (data >> 3) & 1;
	ppi8255->port_cl_dir = (data >> 0) & 1;

	/* normalize group_a_mode */
	if (ppi8255->group_a_mode == 3)
		ppi8255->group_a_mode = 2;

	/* Port A direction */
	if (ppi8255->group_a_mode == 2)
		ppi8255->in_mask[0] = 0xFF, ppi8255->out_mask[0] = 0xFF;	/* bidirectional */
	else
		if (ppi8255->port_a_dir)
			ppi8255->in_mask[0] = 0xFF, ppi8255->out_mask[0] = 0x00;	/* input */
		else
			ppi8255->in_mask[0] = 0x00, ppi8255->out_mask[0] = 0xFF;	/* output */

	/* Port B direction */
	if (ppi8255->port_b_dir)
		ppi8255->in_mask[1] = 0xFF, ppi8255->out_mask[1] = 0x00;	/* input */
	else
		ppi8255->in_mask[1] = 0x00, ppi8255->out_mask[1] = 0xFF;	/* output */

	/* Port C upper direction */
	if (ppi8255->port_ch_dir)
		ppi8255->in_mask[2] = 0xF0, ppi8255->out_mask[2] = 0x00;	/* input */
	else
		ppi8255->in_mask[2] = 0x00, ppi8255->out_mask[2] = 0xF0;	/* output */

	/* Port C lower direction */
	if (ppi8255->port_cl_dir)
		ppi8255->in_mask[2] |= 0x0F;	/* input */
	else
		ppi8255->out_mask[2] |= 0x0F;	/* output */

	/* now depending on the group modes, certain Port C lines may be replaced
     * with varying control signals */
	switch(ppi8255->group_a_mode)
	{
		case 0:	/* Group A mode 0 */
			/* no changes */
			break;

		case 1:	/* Group A mode 1 */
			/* bits 5-3 are reserved by Group A mode 1 */
			ppi8255->in_mask[2] &= ~0x38;
			ppi8255->out_mask[2] &= ~0x38;
			break;

		case 2: /* Group A mode 2 */
			/* bits 7-3 are reserved by Group A mode 2 */
			ppi8255->in_mask[2] &= ~0xF8;
			ppi8255->out_mask[2] &= ~0xF8;
			break;
	}

	switch(ppi8255->group_b_mode)
	{
		case 0:	/* Group B mode 0 */
			/* no changes */
			break;

		case 1:	/* Group B mode 1 */
			/* bits 2-0 are reserved by Group B mode 1 */
			ppi8255->in_mask[2] &= ~0x07;
			ppi8255->out_mask[2] &= ~0x07;
			break;
	}

	/* KT: 25-Dec-99 - 8255 resets latches when mode set */
	ppi8255->latch[0] = ppi8255->latch[1] = ppi8255->latch[2] = 0;

	if (call_handlers)
	{
		for (i = 0; i < 3; i++)
			ppi8255_write_port(device, i);
	}

	/* reset flip-flops */
	ppi8255->obf_a = ppi8255->ibf_a = 0;
	ppi8255->obf_b = ppi8255->ibf_b = 0;
	ppi8255->inte_a = ppi8255->inte_b = ppi8255->inte_1 = ppi8255->inte_2 = 0;

	/* store control word */
	ppi8255->control = data;
}
예제 #4
0
WRITE8_DEVICE_HANDLER_TRAMPOLINE(ppi8255, ppi8255_w)
{
	offset %= 4;

	switch( offset )
	{
		case 0: /* Port A write */
		case 1: /* Port B write */
		case 2: /* Port C write */
			m_latch[offset] = data;
			ppi8255_write_port(offset);

			switch(offset)
			{
				case 0:
					if (!m_port_a_dir && (m_group_a_mode != 0))
					{
						m_obf_a = 1;
						ppi8255_write_port(2);
					}
					break;

				case 1:
					if (!m_port_b_dir && (m_group_b_mode != 0))
					{
						m_obf_b = 1;
						ppi8255_write_port(2);
					}
					break;
			}
			break;

		case 3: /* Control word */
			if (data & 0x80)
			{
				set_mode(data & 0x7f, 1);
			}
			else
			{
				/* bit set/reset */
				int bit = (data >> 1) & 0x07;

				if (data & 1)
				{
					m_latch[2] |= (1 << bit);	/* set bit */
				}
				else
				{
					m_latch[2] &= ~(1 << bit);	/* reset bit */
				}

				if (m_group_b_mode == 1)
				{
					if (bit == 2)
					{
						m_inte_b = data & 1;
					}
				}

				if (m_group_a_mode == 1)
				{
					if (bit == 4 && m_port_a_dir)
					{
						m_inte_a = data & 1;
					}
					if (bit == 6 && !m_port_a_dir)
					{
						m_inte_a = data & 1;
					}
				}

				if (m_group_a_mode == 2)
				{
					if (bit == 4)
					{
						m_inte_2 = data & 1;
					}
					if (bit == 6)
					{
						m_inte_1 = data & 1;
					}
				}

				ppi8255_write_port(2);
			}
			break;
	}
}