diff options
author | 2015-09-13 08:41:44 +0200 | |
---|---|---|
committer | 2015-09-13 08:41:44 +0200 | |
commit | f88cefad27a1737c76e09d99c9fb43e173506081 (patch) | |
tree | 2d8167d03579c46e226471747eb4407bd00ed6fa /src/emu/machine/i8251.c | |
parent | e92ac9e0fa8e99869894bea00589bbb526be30aa (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.c | 788 |
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(); - } -} |