summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/i8251.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-09-13 08:41:44 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2015-09-13 08:41:44 +0200
commitf88cefad27a1737c76e09d99c9fb43e173506081 (patch)
tree2d8167d03579c46e226471747eb4407bd00ed6fa /src/emu/machine/i8251.c
parente92ac9e0fa8e99869894bea00589bbb526be30aa (diff)
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/emu/machine/i8251.c')
-rw-r--r--src/emu/machine/i8251.c788
1 files changed, 0 insertions, 788 deletions
diff --git a/src/emu/machine/i8251.c b/src/emu/machine/i8251.c
deleted file mode 100644
index 7008fe394a3..00000000000
--- a/src/emu/machine/i8251.c
+++ /dev/null
@@ -1,788 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:smf
-/*********************************************************************
-
- i8251.c
-
- Intel 8251 Universal Synchronous/Asynchronous Receiver Transmitter code
- NEC uPD71051 is a clone
-
- The V53/V53A use a customized version with only the Asynchronous mode
- and a split command / mode register
-
-
-
-*********************************************************************/
-
-#include "emu.h"
-#include "i8251.h"
-
-
-/***************************************************************************
- MACROS
-***************************************************************************/
-
-#define VERBOSE 0
-
-#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
-
-//**************************************************************************
-// DEVICE DEFINITIONS
-//**************************************************************************
-
-const device_type I8251 = &device_creator<i8251_device>;
-const device_type V53_SCU = &device_creator<v53_scu_device>;
-
-//-------------------------------------------------
-// i8251_device - constructor
-//-------------------------------------------------
-
-i8251_device::i8251_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname)
- : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
- device_serial_interface(mconfig, *this),
- m_txd_handler(*this),
- m_dtr_handler(*this),
- m_rts_handler(*this),
- m_rxrdy_handler(*this),
- m_txrdy_handler(*this),
- m_txempty_handler(*this),
- m_syndet_handler(*this),
- m_cts(1),
- m_dsr(1),
- m_rxd(0),
- m_rxc(0),
- m_txc(0)
-{
-}
-
-i8251_device::i8251_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : device_t(mconfig, I8251, "8251 USART", tag, owner, clock, "i8251", __FILE__),
- device_serial_interface(mconfig, *this),
- m_txd_handler(*this),
- m_dtr_handler(*this),
- m_rts_handler(*this),
- m_rxrdy_handler(*this),
- m_txrdy_handler(*this),
- m_txempty_handler(*this),
- m_syndet_handler(*this),
- m_cts(1),
- m_dsr(1),
- m_rxd(0),
- m_rxc(0),
- m_txc(0)
-{
-}
-
-v53_scu_device::v53_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : i8251_device(mconfig, V53_SCU, "V53 SCU", tag, owner, clock, "v53_scu")
-{
-}
-
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void i8251_device::device_start()
-{
- // resolve callbacks
- m_txd_handler.resolve_safe();
- m_rts_handler.resolve_safe();
- m_dtr_handler.resolve_safe();
- m_rxrdy_handler.resolve_safe();
- m_txrdy_handler.resolve_safe();
- m_txempty_handler.resolve_safe();
- save_item(NAME(m_flags));
- save_item(NAME(m_sync_byte_offset));
- save_item(NAME(m_sync_byte_count));
- save_item(NAME(m_sync_bytes));
- save_item(NAME(m_status));
- save_item(NAME(m_command));
- save_item(NAME(m_mode_byte));
- save_item(NAME(m_cts));
- save_item(NAME(m_dsr));
- save_item(NAME(m_rxd));
- save_item(NAME(m_rxc));
- save_item(NAME(m_txc));
- save_item(NAME(m_rxc_count));
- save_item(NAME(m_txc_count));
- save_item(NAME(m_br_factor));
- save_item(NAME(m_rx_data));
- save_item(NAME(m_tx_data));
- save_item(NAME(m_tx_busy));
- save_item(NAME(m_disable_tx_pending));
- device_serial_interface::register_save_state(machine().save(), this);
-}
-
-
-
-
-/*-------------------------------------------------
- update_rx_ready
--------------------------------------------------*/
-
-void i8251_device::update_rx_ready()
-{
- int state;
-
- state = m_status & I8251_STATUS_RX_READY;
-
- /* masked? */
- if ((m_command & (1<<2))==0)
- {
- state = 0;
- }
-
- m_rxrdy_handler(state != 0);
-}
-
-
-
-/*-------------------------------------------------
- receive_clock
--------------------------------------------------*/
-
-void i8251_device::receive_clock()
-{
- m_rxc_count++;
-
- if (m_rxc_count == m_br_factor)
- m_rxc_count = 0;
- else
- return;
-
- /* receive enable? */
- if (m_command & (1<<2))
- {
- //logerror("I8251\n");
- /* get bit received from other side and update receive register */
- receive_register_update_bit(m_rxd);
-
- if (is_receive_register_full())
- {
- receive_register_extract();
- receive_character(get_received_char());
- }
- }
-}
-
-
-
-/*-------------------------------------------------
- transmit_clock
--------------------------------------------------*/
-
-void i8251_device::transmit_clock()
-{
- m_txc_count++;
-
- if (m_txc_count == m_br_factor)
- m_txc_count = 0;
- else
- return;
-
- /* transmit enabled? */
- if (m_command & (1<<0))
- {
- /* do we have a character to send? */
- if ((m_status & I8251_STATUS_TX_READY)==0)
- {
- /* is diserial ready for it? */
- if (is_transmit_register_empty())
- {
- /* set it up */
- transmit_register_setup(m_tx_data);
- /* i8251 transmit reg now empty */
- m_status |=I8251_STATUS_TX_EMPTY;
- /* ready for next transmit */
- m_status |=I8251_STATUS_TX_READY;
-
- update_tx_empty();
- update_tx_ready();
- }
- }
-
- /* if diserial has bits to send, make them so */
- if (!is_transmit_register_empty())
- {
- UINT8 data = transmit_register_get_data_bit();
- m_tx_busy = true;
- m_txd_handler(data);
- }
-
- // is transmitter totally done?
- if ((m_status & I8251_STATUS_TX_READY) && is_transmit_register_empty())
- {
- m_tx_busy = false;
-
- if (m_disable_tx_pending)
- {
- LOG(("Applying pending disable\n"));
- m_disable_tx_pending = false;
- m_command &= ~(1<<0);
- m_txd_handler(1);
- update_tx_ready();
- }
- }
- }
-
-#if 0
- /* hunt mode? */
- /* after each bit has been shifted in, it is compared against the current sync byte */
- if (m_command & (1<<7))
- {
- /* data matches sync byte? */
- if (m_data == m_sync_bytes[m_sync_byte_offset])
- {
- /* sync byte matches */
- /* update for next sync byte? */
- m_sync_byte_offset++;
-
- /* do all sync bytes match? */
- if (m_sync_byte_offset == m_sync_byte_count)
- {
- /* ent hunt mode */
- m_command &=~(1<<7);
- }
- }
- else
- {
- /* if there is no match, reset */
- m_sync_byte_offset = 0;
- }
- }
-#endif
-}
-
-
-
-/*-------------------------------------------------
- update_tx_ready
--------------------------------------------------*/
-
-void i8251_device::update_tx_ready()
-{
- /* clear tx ready state */
- int tx_ready;
-
- /* tx ready output is set if:
- DB Buffer Empty &
- CTS is set &
- Transmit enable is 1
- */
-
- tx_ready = 0;
-
- /* transmit enable? */
- if ((m_command & (1<<0))!=0)
- {
- /* other side has rts set (comes in as CTS at this side) */
- if (!m_cts)
- {
- if (m_status & I8251_STATUS_TX_EMPTY)
- {
- /* enable transfer */
- tx_ready = 1;
- }
- }
- }
-
- m_txrdy_handler(tx_ready);
-}
-
-
-
-/*-------------------------------------------------
- update_tx_empty
--------------------------------------------------*/
-
-void i8251_device::update_tx_empty()
-{
- if (m_status & I8251_STATUS_TX_EMPTY)
- {
- /* tx is in marking state (high) when tx empty! */
- m_txd_handler(1);
- }
-
- m_txempty_handler((m_status & I8251_STATUS_TX_EMPTY) != 0);
-}
-
-
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void i8251_device::device_reset()
-{
- LOG(("I8251: Reset\n"));
-
- /* what is the default setup when the 8251 has been reset??? */
-
- /* i8251 datasheet explains the state of tx pin at reset */
- /* tx is set to 1 */
- m_txd_handler(1);
-
- /* assumption */
- m_rts_handler(1);
- m_dtr_handler(1);
-
- transmit_register_reset();
- receive_register_reset();
- m_flags = 0;
- /* expecting mode byte */
- m_flags |= I8251_EXPECTING_MODE;
- /* not expecting a sync byte */
- m_flags &= ~I8251_EXPECTING_SYNC_BYTE;
-
- /* no character to read by cpu */
- /* transmitter is ready and is empty */
- m_status = I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY;
- m_mode_byte = 0;
- m_command = 0;
- m_rx_data = 0;
- m_tx_data = 0;
- m_rxc_count = m_txc_count = 0;
- m_br_factor = 1;
- m_tx_busy = m_disable_tx_pending = false;
-
- /* update tx empty pin output */
- update_tx_empty();
- /* update rx ready pin output */
- update_rx_ready();
- /* update tx ready pin output */
- update_tx_ready();
-}
-
-
-
-/*-------------------------------------------------
- control_w
--------------------------------------------------*/
-
-WRITE8_MEMBER(i8251_device::command_w)
-{
- /* command */
- LOG(("I8251: Command byte\n"));
-
- m_command = data;
-
- LOG(("Command byte: %02x\n", data));
-
- if (data & (1<<7))
- {
- LOG(("hunt mode\n"));
- }
-
- if (data & (1<<5))
- {
- LOG(("/rts set to 0\n"));
- }
- else
- {
- LOG(("/rts set to 1\n"));
- }
-
- if (data & (1<<2))
- {
- LOG(("receive enable\n"));
- }
- else
- {
- LOG(("receive disable\n"));
- }
-
- if (data & (1<<1))
- {
- LOG(("/dtr set to 0\n"));
- }
- else
- {
- LOG(("/dtr set to 1\n"));
- }
-
- if (data & (1<<0))
- {
- LOG(("transmit enable\n"));
-
- /* if we get a tx enable with a disable pending, cancel the disable */
- m_disable_tx_pending = false;
- }
- else
- {
- if (m_tx_busy)
- {
- if (!m_disable_tx_pending)
- {
- LOG(("Tx busy, set pending disable\n"));
- }
- m_disable_tx_pending = true;
- m_command |= (1<<0);
- }
- else
- {
- LOG(("transmit disable\n"));
- if ((data & (1<<0))==0)
- {
- /* held in high state when transmit disable */
- m_txd_handler(1);
- }
- }
- }
-
-
- /* bit 7:
- 0 = normal operation
- 1 = hunt mode
- bit 6:
- 0 = normal operation
- 1 = internal reset
- bit 5:
- 0 = /RTS set to 1
- 1 = /RTS set to 0
- bit 4:
- 0 = normal operation
- 1 = reset error flag
- bit 3:
- 0 = normal operation
- 1 = send break character
- bit 2:
- 0 = receive disable
- 1 = receive enable
- bit 1:
- 0 = /DTR set to 1
- 1 = /DTR set to 0
- bit 0:
- 0 = transmit disable
- 1 = transmit enable
- */
-
- m_rts_handler(!BIT(data, 5));
- m_dtr_handler(!BIT(data, 1));
-
- if (data & (1<<4))
- {
- m_status &= ~(I8251_STATUS_PARITY_ERROR | I8251_STATUS_OVERRUN_ERROR | I8251_STATUS_FRAMING_ERROR);
- }
-
- if (data & (1<<6))
- {
- // datasheet says "returns to mode format", not
- // completely resets the chip. behavior of DEC Rainbow
- // backs this up.
- m_flags |= I8251_EXPECTING_MODE;
- }
-
- update_rx_ready();
- update_tx_ready();
-}
-
-WRITE8_MEMBER(i8251_device::mode_w)
-{
- LOG(("I8251: Mode byte\n"));
-
- m_mode_byte = data;
-
- /* Synchronous or Asynchronous? */
- if ((data & 0x03) != 0)
- {
- /* Asynchronous
-
- bit 7,6: stop bit length
- 0 = inhibit
- 1 = 1 bit
- 2 = 1.5 bits
- 3 = 2 bits
- bit 5: parity type
- 0 = parity odd
- 1 = parity even
- bit 4: parity test enable
- 0 = disable
- 1 = enable
- bit 3,2: character length
- 0 = 5 bits
- 1 = 6 bits
- 2 = 7 bits
- 3 = 8 bits
- bit 1,0: baud rate factor
- 0 = defines command byte for synchronous or asynchronous
- 1 = x1
- 2 = x16
- 3 = x64
- */
-
- LOG(("I8251: Asynchronous operation\n"));
-
- LOG(("Character length: %d\n", (((data >> 2) & 0x03) + 5)));
-
- parity_t parity;
-
- if (data & (1 << 4))
- {
- LOG(("enable parity checking\n"));
-
- if (data & (1 << 5))
- {
- LOG(("even parity\n"));
- parity = PARITY_EVEN;
- }
- else
- {
- LOG(("odd parity\n"));
- parity = PARITY_ODD;
- }
- }
- else
- {
- LOG(("parity check disabled\n"));
- parity = PARITY_NONE;
- }
-
- stop_bits_t stop_bits;
-
- switch ((data >> 6) & 0x03)
- {
- case 0:
- default:
- stop_bits = STOP_BITS_0;
- LOG(("stop bit: inhibit\n"));
- break;
-
- case 1:
- stop_bits = STOP_BITS_1;
- LOG(("stop bit: 1 bit\n"));
- break;
-
- case 2:
- stop_bits = STOP_BITS_1_5;
- LOG(("stop bit: 1.5 bits\n"));
- break;
-
- case 3:
- stop_bits = STOP_BITS_2;
- LOG(("stop bit: 2 bits\n"));
- break;
- }
-
- int data_bits_count = ((data >> 2) & 0x03) + 5;
-
- set_data_frame(1, data_bits_count, parity, stop_bits);
- receive_register_reset();
-
- switch (data & 0x03)
- {
- case 1: m_br_factor = 1; break;
- case 2: m_br_factor = 16; break;
- case 3: m_br_factor = 64; break;
- }
-
- m_rxc_count = m_txc_count = 0;
-
-#if 0
- /* data bits */
- m_receive_char_length = (((data >> 2) & 0x03) + 5);
-
- if (data & (1 << 4))
- {
- /* parity */
- m_receive_char_length++;
- }
-
- /* stop bits */
- m_receive_char_length++;
-
- m_receive_flags &= ~I8251_TRANSFER_RECEIVE_SYNCHRONISED;
- m_receive_flags |= I8251_TRANSFER_RECEIVE_WAITING_FOR_START_BIT;
-#endif
- /* not expecting mode byte now */
- m_flags &= ~I8251_EXPECTING_MODE;
- // m_status = I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY;
- }
- else
- {
- /* bit 7: Number of sync characters
- 0 = 1 character
- 1 = 2 character
- bit 6: Synchronous mode
- 0 = Internal synchronisation
- 1 = External synchronisation
- bit 5: parity type
- 0 = parity odd
- 1 = parity even
- bit 4: parity test enable
- 0 = disable
- 1 = enable
- bit 3,2: character length
- 0 = 5 bits
- 1 = 6 bits
- 2 = 7 bits
- 3 = 8 bits
- bit 1,0 = 0
- */
- LOG(("I8251: Synchronous operation\n"));
-
- /* setup for sync byte(s) */
- m_flags |= I8251_EXPECTING_SYNC_BYTE;
- m_sync_byte_offset = 0;
- if (data & 0x07)
- {
- m_sync_byte_count = 1;
- }
- else
- {
- m_sync_byte_count = 2;
- }
-
- }
-}
-
-WRITE8_MEMBER(i8251_device::control_w)
-{
- if (m_flags & I8251_EXPECTING_MODE)
- {
- if (m_flags & I8251_EXPECTING_SYNC_BYTE)
- {
- LOG(("I8251: Sync byte\n"));
-
- LOG(("Sync byte: %02x\n", data));
- /* store sync byte written */
- m_sync_bytes[m_sync_byte_offset] = data;
- m_sync_byte_offset++;
-
- if (m_sync_byte_offset == m_sync_byte_count)
- {
- /* finished transfering sync bytes, now expecting command */
- m_flags &= ~(I8251_EXPECTING_MODE | I8251_EXPECTING_SYNC_BYTE);
- m_sync_byte_offset = 0;
- // m_status = I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY;
- }
- }
- else
- {
- mode_w(space, offset, data);
- }
- }
- else
- {
- command_w(space, offset, data);
- }
-}
-
-
-
-/*-------------------------------------------------
- status_r
--------------------------------------------------*/
-
-READ8_MEMBER(i8251_device::status_r)
-{
- UINT8 status = (m_dsr << 7) | m_status;
-
- LOG(("status: %02x\n", status));
- return status;
-}
-
-
-
-/*-------------------------------------------------
- data_w
--------------------------------------------------*/
-
-WRITE8_MEMBER(i8251_device::data_w)
-{
- m_tx_data = data;
-
- LOG(("data_w %02x\n" , data));
-// printf("i8251 transmit char: %02x\n",data);
-
- /* writing clears */
- m_status &=~I8251_STATUS_TX_READY;
- m_status &=~I8251_STATUS_TX_EMPTY;
-
- /* if transmitter is active, then tx empty will be signalled */
-
- update_tx_ready();
- update_tx_empty();
-}
-
-
-
-/*-------------------------------------------------
- receive_character - called when last
- bit of data has been received
--------------------------------------------------*/
-
-void i8251_device::receive_character(UINT8 ch)
-{
- m_rx_data = ch;
-
- /* char has not been read and another has arrived! */
- if (m_status & I8251_STATUS_RX_READY)
- {
- m_status |= I8251_STATUS_OVERRUN_ERROR;
- }
- m_status |= I8251_STATUS_RX_READY;
-
- update_rx_ready();
-}
-
-
-
-/*-------------------------------------------------
- data_r - read data
--------------------------------------------------*/
-
-READ8_MEMBER(i8251_device::data_r)
-{
- LOG(("read data: %02x, STATUS=%02x\n",m_rx_data,m_status));
- /* reading clears */
- m_status &= ~I8251_STATUS_RX_READY;
-
- update_rx_ready();
- return m_rx_data;
-}
-
-
-void i8251_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- device_serial_interface::device_timer(timer, id, param, ptr);
-}
-
-
-WRITE_LINE_MEMBER(i8251_device::write_rxd)
-{
- m_rxd = state;
-// device_serial_interface::rx_w(state);
-}
-
-WRITE_LINE_MEMBER(i8251_device::write_cts)
-{
- m_cts = state;
-}
-
-WRITE_LINE_MEMBER(i8251_device::write_dsr)
-{
- m_dsr = !state;
-}
-
-WRITE_LINE_MEMBER(i8251_device::write_rxc)
-{
- if (m_rxc != state)
- {
- m_rxc = state;
-
- if (m_rxc)
- receive_clock();
- }
-}
-
-WRITE_LINE_MEMBER(i8251_device::write_txc)
-{
- if (m_txc != state)
- {
- m_txc = state;
-
- if (!m_txc)
- transmit_clock();
- }
-}