diff options
Diffstat (limited to 'src/devices/machine/z80sio.h')
-rw-r--r-- | src/devices/machine/z80sio.h | 267 |
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 |