mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
mc68901: Improve USART behavior for polled operation
This commit is contained in:
parent
6a290e3eeb
commit
b0ff0b7c70
@ -211,10 +211,6 @@ inline void mc68901_device::rx_error()
|
||||
{
|
||||
take_interrupt(IR_RCV_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx_buffer_full();
|
||||
}
|
||||
}
|
||||
|
||||
inline void mc68901_device::timer_count(int index)
|
||||
@ -414,7 +410,7 @@ void mc68901_device::device_start()
|
||||
save_item(NAME(m_transmit_buffer));
|
||||
save_item(NAME(m_transmit_pending));
|
||||
save_item(NAME(m_receive_buffer));
|
||||
save_item(NAME(m_receive_pending));
|
||||
save_item(NAME(m_overrun_pending));
|
||||
save_item(NAME(m_gpio_input));
|
||||
save_item(NAME(m_gpio_output));
|
||||
save_item(NAME(m_rsr_read));
|
||||
@ -429,7 +425,8 @@ void mc68901_device::device_start()
|
||||
void mc68901_device::device_reset()
|
||||
{
|
||||
m_tsr = 0;
|
||||
m_transmit_pending = 0;
|
||||
m_transmit_pending = false;
|
||||
m_overrun_pending = false;
|
||||
|
||||
// Avoid read-before-write
|
||||
m_ipr = m_imr = 0;
|
||||
@ -496,7 +493,7 @@ void mc68901_device::tra_complete()
|
||||
if (m_transmit_pending)
|
||||
{
|
||||
transmit_register_setup(m_transmit_buffer);
|
||||
m_transmit_pending = 0;
|
||||
m_transmit_pending = false;
|
||||
m_tsr |= TSR_BUFFER_EMPTY;
|
||||
|
||||
if (m_ier & IR_XMIT_BUFFER_EMPTY)
|
||||
@ -524,10 +521,16 @@ void mc68901_device::tra_complete()
|
||||
void mc68901_device::rcv_complete()
|
||||
{
|
||||
receive_register_extract();
|
||||
m_receive_buffer = get_received_char();
|
||||
//if (m_receive_pending) TODO: error?
|
||||
|
||||
m_receive_pending = 1;
|
||||
if (m_rsr & RSR_BUFFER_FULL)
|
||||
{
|
||||
m_overrun_pending = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_receive_buffer = get_received_char();
|
||||
m_rsr |= RSR_BUFFER_FULL;
|
||||
LOG("Received Character: %02x\n", m_receive_buffer);
|
||||
}
|
||||
rx_buffer_full();
|
||||
}
|
||||
|
||||
@ -565,19 +568,34 @@ READ8_MEMBER( mc68901_device::read )
|
||||
|
||||
case REGISTER_SCR: return m_scr;
|
||||
case REGISTER_UCR: return m_ucr;
|
||||
case REGISTER_RSR: return m_rsr;
|
||||
case REGISTER_RSR:
|
||||
{
|
||||
uint8_t rsr = m_rsr;
|
||||
if (!machine().side_effect_disabled())
|
||||
m_rsr &= ~RSR_OVERRUN_ERROR;
|
||||
return rsr;
|
||||
}
|
||||
|
||||
case REGISTER_TSR:
|
||||
{
|
||||
/* clear UE bit (in reality, this won't be cleared until one full clock cycle of the transmitter has passed since the bit was set) */
|
||||
uint8_t tsr = m_tsr;
|
||||
m_tsr &= ~TSR_UNDERRUN_ERROR;
|
||||
|
||||
if (!machine().side_effect_disabled())
|
||||
m_tsr &= ~TSR_UNDERRUN_ERROR;
|
||||
return tsr;
|
||||
}
|
||||
|
||||
case REGISTER_UDR:
|
||||
m_receive_pending = 0;
|
||||
if (!machine().side_effect_disabled())
|
||||
{
|
||||
m_rsr &= ~RSR_BUFFER_FULL;
|
||||
if (m_overrun_pending)
|
||||
{
|
||||
m_overrun_pending = false;
|
||||
m_rsr |= RSR_OVERRUN_ERROR;
|
||||
rx_error();
|
||||
}
|
||||
}
|
||||
return m_receive_buffer;
|
||||
|
||||
default: return 0;
|
||||
@ -966,6 +984,7 @@ void mc68901_device::register_w(offs_t offset, uint8_t data)
|
||||
}
|
||||
|
||||
set_data_frame(start_bits, data_bit_count, parity, stop_bits);
|
||||
receive_register_reset();
|
||||
|
||||
m_ucr = data;
|
||||
}
|
||||
@ -1052,22 +1071,23 @@ void mc68901_device::register_w(offs_t offset, uint8_t data)
|
||||
if (m_transmit_pending && is_transmit_register_empty())
|
||||
{
|
||||
transmit_register_setup(m_transmit_buffer);
|
||||
m_transmit_pending = 0;
|
||||
m_tsr |= TSR_BUFFER_EMPTY;
|
||||
m_transmit_pending = false;
|
||||
}
|
||||
if (!m_transmit_pending)
|
||||
m_tsr |= TSR_BUFFER_EMPTY;
|
||||
}
|
||||
break;
|
||||
|
||||
case REGISTER_UDR:
|
||||
LOG("MC68901 UDR %x\n", data);
|
||||
m_transmit_buffer = data;
|
||||
m_transmit_pending = 1;
|
||||
m_transmit_pending = true;
|
||||
m_tsr &= ~TSR_BUFFER_EMPTY;
|
||||
|
||||
if ((m_tsr & TSR_XMIT_ENABLE) && is_transmit_register_empty())
|
||||
{
|
||||
transmit_register_setup(m_transmit_buffer);
|
||||
m_transmit_pending = 0;
|
||||
m_transmit_pending = false;
|
||||
m_tsr |= TSR_BUFFER_EMPTY;
|
||||
}
|
||||
break;
|
||||
|
@ -279,9 +279,9 @@ private:
|
||||
uint8_t m_tsr; /* transmitter status register */
|
||||
uint8_t m_rsr; /* receiver status register */
|
||||
uint8_t m_transmit_buffer; /* USART data register */
|
||||
int m_transmit_pending;
|
||||
bool m_transmit_pending;
|
||||
uint8_t m_receive_buffer;
|
||||
int m_receive_pending;
|
||||
bool m_overrun_pending;
|
||||
uint8_t m_gpio_input;
|
||||
uint8_t m_gpio_output;
|
||||
|
||||
|
@ -213,6 +213,7 @@ WRITE_LINE_MEMBER(device_serial_interface::rx_w)
|
||||
receive_register_update_bit(state);
|
||||
if(m_rcv_flags & RECEIVE_REGISTER_SYNCHRONISED)
|
||||
{
|
||||
//device().logerror("Receiver is synchronized\n");
|
||||
if(m_rcv_clock && !(m_rcv_rate.is_never()))
|
||||
// make start delay just a bit longer to make sure we are called after the sender
|
||||
m_rcv_clock->adjust(((m_rcv_rate*3)/2), 0, m_rcv_rate);
|
||||
@ -266,6 +267,7 @@ void device_serial_interface::receive_register_update_bit(int bit)
|
||||
else
|
||||
if (m_rcv_flags & RECEIVE_REGISTER_SYNCHRONISED)
|
||||
{
|
||||
//device().logerror("Received bit %d\n", m_rcv_bit_count_received);
|
||||
m_rcv_bit_count_received++;
|
||||
|
||||
if (!bit && (m_rcv_bit_count_received > (m_rcv_bit_count - m_df_stop_bit_count)))
|
||||
@ -279,7 +281,7 @@ void device_serial_interface::receive_register_update_bit(int bit)
|
||||
m_rcv_bit_count_received = 0;
|
||||
m_rcv_flags &=~RECEIVE_REGISTER_SYNCHRONISED;
|
||||
m_rcv_flags |= RECEIVE_REGISTER_WAITING_FOR_START_BIT;
|
||||
//logerror("receive register full\n");
|
||||
//device().logerror("Receive register full\n");
|
||||
m_rcv_flags |= RECEIVE_REGISTER_FULL;
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ static MACHINE_CONFIG_START( tti )
|
||||
|
||||
MCFG_DEVICE_ADD("mfp", MC68901, 0)
|
||||
MCFG_MC68901_TIMER_CLOCK(XTAL_20MHz / 2) // guess
|
||||
MCFG_MC68901_RX_CLOCK(153000) // for testing
|
||||
MCFG_MC68901_TX_CLOCK(153000) // for testing
|
||||
MCFG_MC68901_RX_CLOCK(9600) // for testing (FIXME: actually 16x)
|
||||
MCFG_MC68901_TX_CLOCK(9600) // for testing (FIXME: actually 16x)
|
||||
MCFG_MC68901_OUT_SO_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd))
|
||||
|
||||
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal")
|
||||
|
Loading…
Reference in New Issue
Block a user