summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/z80sio.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/z80sio.h')
-rw-r--r--src/devices/machine/z80sio.h267
1 files changed, 94 insertions, 173 deletions
diff --git a/src/devices/machine/z80sio.h b/src/devices/machine/z80sio.h
index 06d65128b76..782ea9bcb0e 100644
--- a/src/devices/machine/z80sio.h
+++ b/src/devices/machine/z80sio.h
@@ -126,17 +126,15 @@
class z80sio_device;
-class z80sio_channel : public device_t, public device_serial_interface
+class z80sio_channel : public device_t
{
friend class z80sio_device;
+ friend class i8274_new_device;
+ friend class upd7201_new_device;
public:
z80sio_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // device_serial_interface overrides
- virtual void tra_callback() override;
- virtual void tra_complete() override;
-
// read register handlers
uint8_t do_sioreg_rr0();
uint8_t do_sioreg_rr1();
@@ -160,8 +158,6 @@ public:
void data_write(uint8_t data);
void receive_reset();
- void receive_data();
- void advance_rx_fifo();
DECLARE_WRITE_LINE_MEMBER( write_rx ) { m_rxd = state; }
DECLARE_WRITE_LINE_MEMBER( cts_w );
@@ -174,7 +170,6 @@ public:
// read registers enum
uint8_t m_rr0; // REG_RR0_STATUS
uint8_t m_rr1; // REG_RR1_SPEC_RCV_COND
- uint8_t m_rr2; // REG_RR2_INTERRUPT_VECT
// write registers enum
uint8_t m_wr0; // REG_WR0_COMMAND_REGPT
uint8_t m_wr1; // REG_WR1_INT_DMA_ENABLE
@@ -185,15 +180,12 @@ public:
uint8_t m_wr6; // REG_WR6_SYNC_OR_SDLC_A
uint8_t m_wr7; // REG_WR7_SYNC_OR_SDLC_F
- int m_variant; // Set in device
-
protected:
enum
{
INT_TRANSMIT = 0,
INT_EXTERNAL,
- INT_RECEIVE,
- INT_SPECIAL
+ INT_RECEIVE
};
enum
@@ -224,136 +216,13 @@ protected:
REG_WR7_SYNC_OR_SDLC_F = 7
};
- enum
- {
- RR0_RX_CHAR_AVAILABLE = 0x01,
- RR0_INTERRUPT_PENDING = 0x02,
- RR0_TX_BUFFER_EMPTY = 0x04,
- RR0_DCD = 0x08,
- RR0_SYNC_HUNT = 0x10,
- RR0_CTS = 0x20,
- RR0_TX_UNDERRUN = 0x40,
- RR0_BREAK_ABORT = 0x80
- };
-
- enum
- {
- RR1_ALL_SENT = 0x01,
- RR1_RESIDUE_CODE_MASK = 0x0e,
- RR1_PARITY_ERROR = 0x10,
- RR1_RX_OVERRUN_ERROR = 0x20,
- RR1_CRC_FRAMING_ERROR = 0x40,
- RR1_END_OF_FRAME = 0x80
- };
-
- enum
- {
- RR2_INT_VECTOR_MASK = 0xff,
- RR2_INT_VECTOR_V1 = 0x02,
- RR2_INT_VECTOR_V2 = 0x04,
- RR2_INT_VECTOR_V3 = 0x08
- };
-
- enum
- {
- WR0_REGISTER_MASK = 0x07,
- WR0_COMMAND_MASK = 0x38,
- WR0_NULL = 0x00,
- WR0_SEND_ABORT = 0x08,
- WR0_RESET_EXT_STATUS = 0x10,
- WR0_CHANNEL_RESET = 0x18,
- WR0_ENABLE_INT_NEXT_RX = 0x20,
- WR0_RESET_TX_INT = 0x28,
- WR0_ERROR_RESET = 0x30,
- WR0_RETURN_FROM_INT = 0x38,
- WR0_CRC_RESET_CODE_MASK = 0xc0,
- WR0_CRC_RESET_NULL = 0x00,
- WR0_CRC_RESET_RX = 0x40,
- WR0_CRC_RESET_TX = 0x80,
- WR0_CRC_RESET_TX_UNDERRUN = 0xc0
- };
-
- enum
- {
- WR1_EXT_INT_ENABLE = 0x01,
- WR1_TX_INT_ENABLE = 0x02,
- WR1_STATUS_VECTOR = 0x04,
- WR1_RX_INT_MODE_MASK = 0x18,
- WR1_RX_INT_DISABLE = 0x00,
- WR1_RX_INT_FIRST = 0x08,
- WR1_RX_INT_ALL_PARITY = 0x10,
- WR1_RX_INT_ALL = 0x18,
- WR1_WRDY_ON_RX_TX = 0x20,
- WR1_WRDY_FUNCTION = 0x40, // WAIT not supported
- WR1_WRDY_ENABLE = 0x80
- };
-
- enum
- {
- WR2_DATA_XFER_INT = 0x00, // not supported
- WR2_DATA_XFER_DMA_INT = 0x01, // not supported
- WR2_DATA_XFER_DMA = 0x02, // not supported
- WR2_DATA_XFER_ILLEGAL = 0x03, // not supported
- WR2_DATA_XFER_MASK = 0x03, // not supported
- WR2_PRIORITY = 0x04, // not supported
- WR2_MODE_8085_1 = 0x00, // not supported
- WR2_MODE_8085_2 = 0x08, // not supported
- WR2_MODE_8086_8088 = 0x10, // not supported
- WR2_MODE_ILLEGAL = 0x18, // not supported
- WR2_MODE_MASK = 0x18, // not supported
- WR2_VECTORED_INT = 0x20, // not supported
- WR2_PIN10_SYNDETB_RTSB = 0x80 // not supported
- };
-
- enum
- {
- WR3_RX_ENABLE = 0x01,
- WR3_SYNC_CHAR_LOAD_INHIBIT= 0x02, // not supported
- WR3_ADDRESS_SEARCH_MODE = 0x04, // not supported
- WR3_RX_CRC_ENABLE = 0x08, // not supported
- WR3_ENTER_HUNT_PHASE = 0x10, // not supported
- WR3_AUTO_ENABLES = 0x20,
- WR3_RX_WORD_LENGTH_MASK = 0xc0,
- WR3_RX_WORD_LENGTH_5 = 0x00,
- WR3_RX_WORD_LENGTH_7 = 0x40,
- WR3_RX_WORD_LENGTH_6 = 0x80,
- WR3_RX_WORD_LENGTH_8 = 0xc0
- };
-
- enum
- {
- WR4_PARITY_ENABLE = 0x01,
- WR4_PARITY_EVEN = 0x02,
- WR4_STOP_BITS_MASK = 0x0c,
- WR4_STOP_BITS_1 = 0x04,
- WR4_STOP_BITS_1_5 = 0x08, // not supported
- WR4_STOP_BITS_2 = 0x0c,
- WR4_SYNC_MODE_MASK = 0x30, // not supported
- WR4_SYNC_MODE_8_BIT = 0x00, // not supported
- WR4_SYNC_MODE_16_BIT = 0x10, // not supported
- WR4_SYNC_MODE_SDLC = 0x20, // not supported
- WR4_SYNC_MODE_EXT = 0x30, // not supported
- WR4_CLOCK_RATE_MASK = 0xc0,
- WR4_CLOCK_RATE_X1 = 0x00,
- WR4_CLOCK_RATE_X16 = 0x40,
- WR4_CLOCK_RATE_X32 = 0x80,
- WR4_CLOCK_RATE_X64 = 0xc0
- };
-
- enum
- {
- WR5_TX_CRC_ENABLE = 0x01, // not supported
- WR5_RTS = 0x02,
- WR5_CRC16 = 0x04, // not supported
- WR5_TX_ENABLE = 0x08,
- WR5_SEND_BREAK = 0x10,
- WR5_TX_WORD_LENGTH_MASK = 0x60,
- WR5_TX_WORD_LENGTH_5 = 0x00,
- WR5_TX_WORD_LENGTH_6 = 0x40,
- WR5_TX_WORD_LENGTH_7 = 0x20,
- WR5_TX_WORD_LENGTH_8 = 0x60,
- WR5_DTR = 0x80
- };
+ z80sio_channel(
+ const machine_config &mconfig,
+ device_type type,
+ const char *tag,
+ device_t *owner,
+ uint32_t clock,
+ uint8_t rr1_auto_reset);
// device-level overrides
virtual void device_resolve_objects() override;
@@ -361,15 +230,14 @@ protected:
virtual void device_reset() override;
void update_serial();
- void update_rts();
+ void update_dtr_rts_break();
void set_dtr(int state);
void set_rts(int state);
- void set_ready(bool ready);
int get_clock_mode();
- stop_bits_t get_stop_bits();
int get_rx_word_length();
- int get_tx_word_length();
+ int get_tx_word_length() const;
+ int get_tx_word_length(uint8_t data) const;
// receiver state
int m_rx_fifo_depth;
@@ -387,21 +255,66 @@ protected:
int m_rxd;
int m_sh; // sync hunt
- int m_cts; // clear to send latch
- int m_dcd; // data carrier detect latch
// transmitter state
- uint8_t m_tx_data; // transmit data register
- int m_tx_clock; // transmit clock pulse count
-
+ uint8_t m_tx_data;
+
+ int m_tx_clock; // transmit clock line state
+ int m_tx_count; // clocks until next bit transition
+ int m_tx_bits; // remaining bits in shift register
+ int m_tx_parity; // parity enable/disable
+ int m_tx_framing; // currnetly transmitting framing bits
+ int m_tx_special; // special conditions (SDLC FCS/abort)
+ uint16_t m_tx_sr; // transmit shift register
+ uint16_t m_tx_crc; // calculated transmit checksum
+ uint8_t m_tx_hist; // transmit history (for bitstuffing)
+
+ int m_txd;
int m_dtr; // data terminal ready
int m_rts; // request to send
+ // external/status monitoring
+ int m_ext_latched; // changed data lines
+ int m_cts; // clear to send line state
+ int m_dcd; // data carrier detect line state
+ int m_sync; // sync line state
+
// synchronous state
- uint16_t m_sync; // sync character
int m_index;
z80sio_device *m_uart;
+
+private:
+ // helpers
+ void out_txd_cb(int state);
+ void out_rts_cb(int state);
+ void out_dtr_cb(int state);
+ bool transmit_allowed() const;
+
+ void receive_data();
+ void advance_rx_fifo();
+
+ void transmit_enable();
+ void transmit_complete();
+ void async_tx_setup();
+ void sdlc_tx_sr_empty();
+ void tx_setup(uint16_t data, int bits, int parity, int framing);
+ void tx_setup_flag();
+
+ void reset_ext_status();
+ void read_ext();
+ void trigger_ext_int();
+
+ uint8_t const m_rr1_auto_reset;
+};
+
+
+// ======================> i8274_channel
+
+class i8274_channel : public z80sio_channel
+{
+public:
+ i8274_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
@@ -454,7 +367,7 @@ public:
DECLARE_WRITE8_MEMBER( cb_w ) { m_chanB->control_write(data); }
// interrupt acknowledge
- int m1_r();
+ virtual int m1_r();
DECLARE_WRITE_LINE_MEMBER( rxa_w ) { m_chanA->write_rx(state); }
DECLARE_WRITE_LINE_MEMBER( rxb_w ) { m_chanB->write_rx(state); }
@@ -471,7 +384,7 @@ public:
DECLARE_WRITE_LINE_MEMBER( syncb_w ) { m_chanB->sync_w(state); }
protected:
- z80sio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant);
+ z80sio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_resolve_objects() override;
@@ -487,18 +400,13 @@ protected:
// internal interrupt management
void check_interrupts();
void reset_interrupts();
- int get_interrupt_prio(int index, int type);
- uint8_t modify_vector(int index, int type);
- void trigger_interrupt(int index, int state);
- int get_channel_index(z80sio_channel *ch) { return (ch == m_chanA) ? 0 : 1; }
+ void trigger_interrupt(int index, int type);
+ void clear_interrupt(int index, int type);
+ void return_from_interrupt();
+ virtual uint8_t read_vector();
+ virtual int const *interrupt_priorities() const;
- // CPU types that has slightly different behaviour
- enum
- {
- TYPE_Z80SIO = 0x001,
- TYPE_UPD7201 = 0x002,
- TYPE_I8274 = 0x004
- };
+ int get_channel_index(z80sio_channel const *ch) const { return (ch == m_chanA) ? 0 : 1; }
enum
{
@@ -530,26 +438,39 @@ protected:
int m_int_state[8]; // interrupt state
int m_int_source[8]; // interrupt source
- int m_variant;
const char *m_cputag;
};
-class upd7201_new_device : public z80sio_device
+class i8274_new_device : public z80sio_device
{
public:
- upd7201_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8274_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual int m1_r() override;
+
+protected:
+ i8274_new_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device_t overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ // device_z80daisy_interface overrides
+ virtual int z80daisy_irq_ack() override;
+ virtual void z80daisy_irq_reti() override;
+
+ virtual uint8_t read_vector() override;
+ virtual int const *interrupt_priorities() const override;
};
-class i8274_new_device : public z80sio_device
+class upd7201_new_device : public i8274_new_device
{
public:
- i8274_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ upd7201_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
-// device type definition
+// device type declaration
DECLARE_DEVICE_TYPE(Z80SIO, z80sio_device)
-DECLARE_DEVICE_TYPE(Z80SIO_CHANNEL, z80sio_channel)
-DECLARE_DEVICE_TYPE(UPD7201_NEW, upd7201_new_device)
DECLARE_DEVICE_TYPE(I8274_NEW, i8274_new_device)
+DECLARE_DEVICE_TYPE(UPD7201_NEW, upd7201_new_device)
#endif // MAME_MACHINE_Z80SIO_H