Exemple #1
0
void acia6850_device::device_reset()
{
	int cts = devcb_call_read_line(&m_in_cts_func);
	int dcd = devcb_call_read_line(&m_in_dcd_func);

	m_status = (cts << 3) | (dcd << 2) | ACIA6850_STATUS_TDRE;
	m_tdr = 0;
	m_rdr = 0;
	m_tx_shift = 0;
	m_rx_shift = 0;
	m_tx_counter = 0;
	m_rx_counter = 0;

	TXD(1);
	m_overrun = 0;
	m_status_read = 0;
	m_brk = 0;

	m_rx_state = START;
	m_tx_state = START;
	m_irq = 0;

	devcb_call_write_line(&m_out_irq_func, 1);

	if (m_first_reset)
	{
		m_first_reset = 0;

		RTS(1);
	}
	else
	{
		RTS(m_rts);
	}
}
Exemple #2
0
READ8_DEVICE_HANDLER_TRAMPOLINE(acia6850, acia6850_data_r)
{
	m_status &= ~(ACIA6850_STATUS_RDRF | ACIA6850_STATUS_IRQ | ACIA6850_STATUS_PE);

	if (m_status_read)
	{
		int dcd = devcb_call_read_line(&m_in_dcd_func);

		m_status_read = 0;
		m_status &= ~(ACIA6850_STATUS_OVRN | ACIA6850_STATUS_DCD);

		if (dcd)
		{
			m_status |= ACIA6850_STATUS_DCD;
		}
	}

	if (m_overrun == 1)
	{
		m_status |= ACIA6850_STATUS_OVRN;
		m_overrun = 0;
	}

	check_interrupts();

	return m_rdr;
}
Exemple #3
0
static UINT8 control_b_r(const device_config *device)
{
	pia6821_state *p = get_token(device);
	UINT8 ret;

	/* update CB1 & CB2 if callback exists, these in turn may update IRQ's */
	if (p->in_cb1_func.read != NULL)
		pia6821_cb1_w(device, 0, devcb_call_read_line(&p->in_cb1_func));
	else if (!p->logged_cb1_not_connected && !p->in_cb1_pushed)
	{
		logerror("PIA #%s: Error! no CB1 read handler. Three-state pin is undefined\n", device->tag);
		p->logged_cb1_not_connected = TRUE;
	}

	if (p->in_cb2_func.read != NULL)
		pia6821_cb2_w(device, 0, devcb_call_read_line(&p->in_cb2_func));
	else if (!p->logged_cb2_not_connected && C2_INPUT(p->ctl_b) && !p->in_cb2_pushed)
	{
		logerror("PIA #%s: Error! No CB2 read handler. Three-state pin is undefined\n", device->tag);
		p->logged_cb2_not_connected = TRUE;
	}

	/* read control register */
	ret = p->ctl_b;

	/* set the IRQ flags if we have pending IRQs */
	if (p->irq_b1)
		ret |= PIA_IRQ1;

	if (p->irq_b2 && C2_INPUT(p->ctl_b))
		ret |= PIA_IRQ2;

	LOG(("PIA #%s: control B read = %02X\n", device->tag, ret));

	return ret;
}
Exemple #4
0
static UINT8 control_a_r(const device_config *device)
{
	pia6821_state *p = get_token(device);
	UINT8 ret;

	/* update CA1 & CA2 if callback exists, these in turn may update IRQ's */
	if (p->in_ca1_func.read != NULL)
		pia6821_ca1_w(device, 0, devcb_call_read_line(&p->in_ca1_func));
	else if (!p->logged_ca1_not_connected && (!p->in_ca1_pushed))
	{
		logerror("PIA #%s: Warning! No CA1 read handler. Assuming pin not connected\n", device->tag);
		p->logged_ca1_not_connected = TRUE;
	}

	if (p->in_ca2_func.read != NULL)
		pia6821_ca2_w(device, 0, devcb_call_read_line(&p->in_ca2_func));
	else if ( !p->logged_ca2_not_connected && C2_INPUT(p->ctl_a) && !p->in_ca2_pushed)
	{
		logerror("PIA #%s: Warning! No CA2 read handler. Assuming pin not connected\n", device->tag);
		p->logged_ca2_not_connected = TRUE;
	}

	/* read control register */
	ret = p->ctl_a;

	/* set the IRQ flags if we have pending IRQs */
	if (p->irq_a1)
		ret |= PIA_IRQ1;

	if (p->irq_a2 && C2_INPUT(p->ctl_a))
		ret |= PIA_IRQ2;

	LOG(("PIA #%s: control A read = %02X\n", device->tag, ret));

	return ret;
}
Exemple #5
0
void acia6850_device::rx_clock_in()
{
	int dcd = devcb_call_read_line(&m_in_dcd_func);

	if (dcd)
	{
		m_status |= ACIA6850_STATUS_DCD;
		check_interrupts();
	}
	else if ((m_status & (ACIA6850_STATUS_DCD|ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD)
	{
		m_status &= ~ACIA6850_STATUS_DCD;
	}

	m_rx_counter ++;

	if ( m_rx_counter > m_divide - 1)
	{
		rx_tick();
		m_rx_counter = 0;
	}
}
Exemple #6
0
void acia6850_device::tx_clock_in()
{
	int _cts = devcb_call_read_line(&m_in_cts_func);

	if (_cts)
	{
		m_status |= ACIA6850_STATUS_CTS;
	}
	else
	{
		m_status &= ~ACIA6850_STATUS_CTS;
	}

	m_tx_counter ++;

	if ( m_tx_counter > m_divide - 1)
	{
		tx_tick();
		m_tx_counter = 0;
	}

}
Exemple #7
0
void acia6850_device::rx_tick()
{
	int dcd = devcb_call_read_line(&m_in_dcd_func);

	if (dcd)
	{
		m_status |= ACIA6850_STATUS_DCD;
		check_interrupts();
	}
	else if ((m_status & (ACIA6850_STATUS_DCD | ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD)
	{
		m_status &= ~ACIA6850_STATUS_DCD;
	}

	if (m_status & ACIA6850_STATUS_DCD)
	{
		m_rx_state = START;
	}
	else
	{
		int rxd = devcb_call_read_line(&m_in_rx_func);

		switch (m_rx_state)
		{
			case START:
			{
				if (rxd == 0)
				{
					if (LOG) logerror("MC6850 '%s': RX START BIT\n", tag());
					m_rx_shift = 0;
					m_rx_parity = 0;
					m_rx_bits = m_bits;
					m_rx_state = DATA;
				}
				break;
			}
			case DATA:
			{
				if (LOG) logerror("MC6850 '%s': RX DATA BIT %x\n", tag(), rxd);
				m_rx_shift |= rxd ? 0x80 : 0;
				m_rx_parity ^= rxd;

				if (--m_rx_bits == 0)
				{
					if (m_status & ACIA6850_STATUS_RDRF)
					{
						m_overrun = 1;
						check_interrupts();
					}

					m_rx_state = m_parity == NONE ? STOP : PARITY;
				}
				else
				{
					m_rx_shift >>= 1;
				}
				break;
			}
			case PARITY:
			{
				if (LOG) logerror("MC6850 '%s': RX PARITY BIT %x\n", tag(), rxd);
				m_rx_parity ^= rxd;

				if (m_parity == EVEN)
				{
					if (m_rx_parity)
					{
						m_status |= ACIA6850_STATUS_PE;
					}
				}
				else
				{
					if (!m_rx_parity)
					{
						m_status |= ACIA6850_STATUS_PE;
					}
				}

				m_rx_state = STOP;
				break;
			}
			case STOP:
			{
				if (rxd == 1)
				{
					if (LOG) logerror("MC6850 '%s': RX STOP BIT\n", tag());
					if (m_stopbits == 1)
					{
						m_status &= ~ACIA6850_STATUS_FE;

						if (!(m_status & ACIA6850_STATUS_RDRF))
						{
							if (LOG) logerror("MC6850 '%s': RX DATA %x\n", tag(), m_rx_shift);
							m_rdr = m_rx_shift;
							m_status |= ACIA6850_STATUS_RDRF;
							check_interrupts();
						}

						m_rx_state = START;
					}
					else
					{
						m_rx_state = STOP2;
					}
				}
				else
				{
					m_status |= ACIA6850_STATUS_FE;
					m_rx_state = START;
				}
				break;
			}
			case STOP2:
			{
				if (rxd == 1)
				{
					if (LOG) logerror("MC6850 '%s': RX STOP BIT\n", tag());
					m_status &= ~ACIA6850_STATUS_FE;

					if (!(m_status & ACIA6850_STATUS_RDRF))
					{
						if (LOG) logerror("MC6850 '%s': RX DATA %x\n", tag(), m_rx_shift);
						m_rdr = m_rx_shift;
						m_status |= ACIA6850_STATUS_RDRF;
						check_interrupts();
					}

					m_rx_state = START;
				}
				else
				{
					m_status |= ACIA6850_STATUS_FE;
					m_rx_state = START;
				}
				break;
			}
		}
	}
}
Exemple #8
0
void acia6850_device::tx_tick()
{
	switch (m_tx_state)
	{
		case START:
		{
			if (m_brk)
			{
				// transmit break

				TXD(0);
			}
			else
			{
				int _cts = devcb_call_read_line(&m_in_cts_func);

				if (_cts)
				{
					m_status |= ACIA6850_STATUS_CTS;
				}
				else
				{
					m_status &= ~ACIA6850_STATUS_CTS;
				}

				check_interrupts();

				if (m_status & ACIA6850_STATUS_TDRE)
				{
					// transmitter idle
					TXD(1);
				}
				else
				{
					// transmit character

					if (LOG) logerror("MC6850 '%s': TX DATA %x\n", tag(), m_tdr);
					if (LOG) logerror("MC6850 '%s': TX START BIT\n", tag());

					TXD(0);

					m_tx_bits = m_bits;
					m_tx_shift = m_tdr;
					m_tx_parity = 0;
					m_tx_state = DATA;
				}
			}
			break;
		}
		case DATA:
		{
			int val = m_tx_shift & 1;
			if (LOG) logerror("MC6850 '%s': TX DATA BIT %x\n", tag(), val);

			TXD(val);
			m_tx_parity ^= val;
			m_tx_shift >>= 1;

			if (--(m_tx_bits) == 0)
			{
				m_tx_state = (m_parity == NONE) ? STOP : PARITY;
			}

			break;
		}
		case PARITY:
		{
			int parity = 0;

			if (m_parity == EVEN)
			{
				parity = (m_tx_parity & 1) ? 1 : 0;
			}
			else
			{
				parity = (m_tx_parity & 1) ? 0 : 1;
			}

			TXD(parity);

			if (LOG) logerror("MC6850 '%s': TX PARITY BIT %x\n", tag(), parity);
			m_tx_state = STOP;
			break;
		}
		case STOP:
		{
			if (LOG) logerror("MC6850 '%s': TX STOP BIT\n", tag());
			TXD(1);

			if (m_stopbits == 1)
			{
				m_tx_state = START;
				m_status |= ACIA6850_STATUS_TDRE;
			}
			else
			{
				m_tx_state = STOP2;
			}
			break;
		}
		case STOP2:
		{
			if (LOG) logerror("MC6850 '%s': TX STOP BIT\n", tag());
			TXD(1);
			m_tx_state = START;
			m_status |= ACIA6850_STATUS_TDRE;
			break;
		}
	}
}