diff options
Diffstat (limited to 'src/devices/machine/i8251.cpp')
-rw-r--r-- | src/devices/machine/i8251.cpp | 173 |
1 files changed, 84 insertions, 89 deletions
diff --git a/src/devices/machine/i8251.cpp b/src/devices/machine/i8251.cpp index 1712796e64d..be7b647b1ee 100644 --- a/src/devices/machine/i8251.cpp +++ b/src/devices/machine/i8251.cpp @@ -23,9 +23,20 @@ To Do: #include "emu.h" #include "i8251.h" -//#define VERBOSE 1 +#define LOG_STAT (1U << 1) +#define LOG_COM (1U << 2) +#define LOG_MODE (1U << 3) +#define LOG_BITS (1U << 4) + +//#define VERBOSE (LOG_BITS|LOG_GENERAL) +//#define LOG_OUTPUT_STREAM std::cout + #include "logmacro.h" +#define LOGSTAT(...) LOGMASKED(LOG_STAT, __VA_ARGS__) +#define LOGCOM(...) LOGMASKED(LOG_COM, __VA_ARGS__) +#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__) +#define LOGBITS(...) LOGMASKED(LOG_BITS, __VA_ARGS__) //************************************************************************** // DEVICE DEFINITIONS @@ -56,7 +67,7 @@ i8251_device::i8251_device( m_syndet_handler(*this), m_cts(1), m_dsr(1), - m_rxd(0), + m_rxd(1), m_rxc(0), m_txc(0) { @@ -69,6 +80,7 @@ i8251_device::i8251_device(const machine_config &mconfig, const char *tag, devic v5x_scu_device::v5x_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : i8251_device(mconfig, V5X_SCU, tag, owner, clock) + , m_sint_handler(*this) { } @@ -79,14 +91,6 @@ v5x_scu_device::v5x_scu_device(const machine_config &mconfig, const char *tag, d 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(); - m_syndet_handler.resolve_safe(); save_item(NAME(m_flags)); save_item(NAME(m_sync_byte_count)); save_item(NAME(m_status)); @@ -123,15 +127,14 @@ void i8251_device::device_start() void i8251_device::update_rx_ready() { - int state = m_status & I8251_STATUS_RX_READY; - - // masked? - if (!BIT(m_command, 2)) - state = 0; - - m_rxrdy_handler(state != 0); + m_rxrdy_handler(rxrdy_r()); } +void v5x_scu_device::update_rx_ready() +{ + i8251_device::update_rx_ready(); + sint_bit_w<0>(rxrdy_r()); +} /*------------------------------------------------- @@ -153,6 +156,7 @@ void i8251_device::receive_clock() //logerror("I8251\n"); /* get bit received from other side and update receive register */ + //LOGBITS("8251: Rx Sampled %d\n", m_rxd); receive_register_update_bit(m_rxd); if (is_receive_register_synchronized()) m_rxc_count = sync ? m_br_factor : (3 * m_br_factor / 2); @@ -316,7 +320,9 @@ bool i8251_device::is_tx_enabled() const void i8251_device::check_for_tx_start() { if (is_tx_enabled() && (m_status & (I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY)) == I8251_STATUS_TX_EMPTY) + { start_tx(); + } } /*------------------------------------------------- @@ -357,6 +363,7 @@ void i8251_device::transmit_clock() if (!is_transmit_register_empty()) { uint8_t data = transmit_register_get_data_bit(); + LOGBITS("8251: Tx Present a %d\n", data); m_txd_handler(data); } } @@ -369,21 +376,20 @@ void i8251_device::transmit_clock() 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 = is_tx_enabled() && (m_status & I8251_STATUS_TX_READY) != 0; - - m_txrdy_handler(tx_ready); + m_txrdy_handler(txrdy_r()); } - +void v5x_scu_device::update_tx_ready() +{ + i8251_device::update_tx_ready(); + sint_bit_w<1>(txrdy_r()); +} /*------------------------------------------------- update_tx_empty @@ -454,6 +460,7 @@ void i8251_device::device_reset() /* no character to read by cpu */ /* transmitter is ready and is empty */ m_status = I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY; + LOGSTAT("status is reset to %02x\n", m_status); m_mode_byte = 0; m_command = 0; m_rx_data = 0; @@ -478,67 +485,26 @@ void i8251_device::device_reset() void i8251_device::command_w(uint8_t data) { /* command */ - LOG("I8251: Command byte\n"); - m_command = data; - LOG("Command byte: %02x\n", data); - - if (BIT(data, 7)) - LOG("hunt mode\n"); - - if (BIT(data, 5)) - LOG("/rts set to 0\n"); - else - LOG("/rts set to 1\n"); - - if (BIT(data, 2)) - LOG("receive enable\n"); - else - LOG("receive disable\n"); - - if (BIT(data, 1)) - LOG("/dtr set to 0\n"); - else - LOG("/dtr set to 1\n"); - - if (BIT(data, 0)) - LOG("transmit enable\n"); - else - LOG("transmit disable\n"); - - - /* 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 - */ + LOG("I8251: Command byte: %02x\n", data); + LOGCOM(" Tx enable: %d\n", data & 0x01 ? 1 : 0); // bit 0: 0 = transmit disable 1 = transmit enable + LOGCOM(" DTR : %d\n", data & 0x02 ? 1 : 0); // bit 1: 0 = /DTR set to 1 1 = /DTR set to 0 + LOGCOM(" Rx enable: %d\n", data & 0x04 ? 1 : 0); // bit 2: 0 = receive disable 1 = receive enable + LOGCOM(" Send BRK : %d\n", data & 0x08 ? 1 : 0); // bit 3: 0 = normal operation 1 = send break character + LOGCOM(" Err reset: %d\n", data & 0x10 ? 1 : 0); // bit 4: 0 = normal operation 1 = reset error flag + LOGCOM(" RTS : %d\n", data & 0x20 ? 1 : 0); // bit 5: 0 = /RTS set to 1 1 = /RTS set to 0 + LOGCOM(" Reset : %d\n", data & 0x40 ? 1 : 0); // bit 6: 0 = normal operation 1 = internal reset + LOGCOM(" Hunt mode: %d\n", data & 0x80 ? 1 : 0); // bit 7: 0 = normal operation 1 = hunt mode m_rts_handler(!BIT(data, 5)); m_dtr_handler(!BIT(data, 1)); if (BIT(data, 4)) + { + LOGSTAT("status errors are reset\n"); m_status &= ~(I8251_STATUS_PARITY_ERROR | I8251_STATUS_OVERRUN_ERROR | I8251_STATUS_FRAMING_ERROR); + } if (BIT(data, 6)) { @@ -596,7 +562,6 @@ void i8251_device::mode_w(uint8_t data) 3 = x64 Synchronous - bit 7: Number of sync characters 0 = 1 character 1 = 2 character @@ -746,6 +711,7 @@ uint8_t i8251_device::status_r() // Syndet always goes off after status read update_syndet(false); + return status; } @@ -763,6 +729,7 @@ void i8251_device::data_w(uint8_t data) /* writing clears */ m_status &=~I8251_STATUS_TX_READY; + LOGSTAT("8251: status cleared TX_READY by data_w\n"); update_tx_ready(); // Store state of tx enable when writing to DB buffer @@ -788,11 +755,17 @@ void i8251_device::receive_character(uint8_t ch) m_rx_data = ch; + LOGSTAT("status RX READY test %02x\n", m_status); /* char has not been read and another has arrived! */ if (m_status & I8251_STATUS_RX_READY) + { m_status |= I8251_STATUS_OVERRUN_ERROR; + LOGSTAT("status overrun set\n"); + } + LOGSTAT("status pre RX READY set %02x\n", m_status); m_status |= I8251_STATUS_RX_READY; + LOGSTAT("status post RX READY set %02x\n", m_status); update_rx_ready(); } @@ -810,6 +783,7 @@ uint8_t i8251_device::data_r() if (!machine().side_effects_disabled()) { m_status &= ~I8251_STATUS_RX_READY; + LOGSTAT("status RX_READY cleared\n"); update_rx_ready(); } return m_rx_data; @@ -833,27 +807,31 @@ void i8251_device::write(offs_t offset, uint8_t data) } -WRITE_LINE_MEMBER(i8251_device::write_rxd) +void i8251_device::write_rxd(int state) { m_rxd = state; -// device_serial_interface::rx_w(state); + LOGBITS("8251: Presented a %d\n", m_rxd); + // device_serial_interface::rx_w(state); } -WRITE_LINE_MEMBER(i8251_device::write_cts) +void i8251_device::write_cts(int state) { m_cts = state; - check_for_tx_start(); - update_tx_ready(); - update_tx_empty(); + if (started()) + { + check_for_tx_start(); + update_tx_ready(); + update_tx_empty(); + } } -WRITE_LINE_MEMBER(i8251_device::write_dsr) +void i8251_device::write_dsr(int state) { m_dsr = !state; } -WRITE_LINE_MEMBER(i8251_device::write_rxc) +void i8251_device::write_rxc(int state) { if (!m_rxc && state) { @@ -869,7 +847,7 @@ WRITE_LINE_MEMBER(i8251_device::write_rxc) m_rxc = state; } -WRITE_LINE_MEMBER(i8251_device::write_txc) +void i8251_device::write_txc(int state) { if (m_txc != state) { @@ -881,7 +859,7 @@ WRITE_LINE_MEMBER(i8251_device::write_txc) } // forcibly kill hunt mode -WRITE_LINE_MEMBER(i8251_device::write_syn) +void i8251_device::write_syn(int state) { if (m_syndet_pin && state) // must be set as input { @@ -891,15 +869,27 @@ WRITE_LINE_MEMBER(i8251_device::write_syn) } } -READ_LINE_MEMBER(i8251_device::txrdy_r) +int i8251_device::txrdy_r() { return is_tx_enabled() && (m_status & I8251_STATUS_TX_READY) != 0; } +int i8251_device::rxrdy_r() +{ + // masked? + if (!BIT(m_command, 2)) + return 0; + + return (m_status & I8251_STATUS_RX_READY) != 0; +} + void v5x_scu_device::device_start() { i8251_device::device_start(); + m_sint = 0; + + save_item(NAME(m_sint)); save_item(NAME(m_simk)); } @@ -911,6 +901,11 @@ void v5x_scu_device::device_reset() i8251_device::device_reset(); } +void v5x_scu_device::update_sint() +{ + m_sint_handler((m_sint & ~m_simk) != 0); +} + u8 v5x_scu_device::read(offs_t offset) { u8 data = 0; |