summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/i8251.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/i8251.cpp')
-rw-r--r--src/devices/machine/i8251.cpp173
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;