// license:BSD-3-Clause
// copyright-holders:smf
/**********************************************************************
MOS Technology 6551 Asynchronous Communication Interface Adapter
**********************************************************************
_____ _____
GND 1 |* \_/ | 28 R/_W
CS0 2 | | 27 phi2
_CS1 3 | | 26 _IRQ
_RES 4 | | 25 DB7
RxC 5 | | 24 DB6
XTAL1 6 | | 23 DB5
XTAL2 7 | MOS6551 | 22 DB4
_RTS 8 | | 21 DB3
_CTS 9 | | 20 DB2
TxD 10 | | 19 DB1
_DTR 11 | | 18 DB0
RxD 12 | | 17 _DBR
RS0 13 | | 16 _DCD
RS1 14 |_____________| 15 Vcc
**********************************************************************/
#ifndef MAME_MACHINE_MOS6551_H
#define MAME_MACHINE_MOS6551_H
#pragma once
#include "machine/clock.h"
class mos6551_device : public device_t
{
public:
mos6551_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
auto irq_handler() { return m_irq_handler.bind(); }
auto txd_handler() { return m_txd_handler.bind(); }
auto rxc_handler() { return m_rxc_handler.bind(); }
auto rts_handler() { return m_rts_handler.bind(); }
auto dtr_handler() { return m_dtr_handler.bind(); }
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
DECLARE_WRITE_LINE_MEMBER(write_xtal1); // txc
DECLARE_WRITE_LINE_MEMBER(write_rxd);
DECLARE_WRITE_LINE_MEMBER(write_rxc);
DECLARE_WRITE_LINE_MEMBER(write_cts);
DECLARE_WRITE_LINE_MEMBER(write_dsr);
DECLARE_WRITE_LINE_MEMBER(write_dcd);
void set_xtal(uint32_t clock);
void set_xtal(const XTAL &clock) { set_xtal(clock.value()); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
private:
enum
{
SR_PARITY_ERROR = 0x01,
SR_FRAMING_ERROR = 0x02,
SR_OVERRUN = 0x04,
SR_RDRF = 0x08,
SR_TDRE = 0x10,
SR_DCD = 0x20,
SR_DSR = 0x40,
SR_IRQ = 0x80
};
enum
{
PARITY_NONE = 0,
PARITY_ODD = 1,
PARITY_EVEN = 3,
PARITY_MARK = 5,
PARITY_SPACE = 7
};
enum
{
IRQ_DCD = 1,
IRQ_DSR = 2,
IRQ_RDRF = 4,
IRQ_TDRE = 8,
IRQ_CTS = 16
};
enum
{
STATE_START,
STATE_DATA,
STATE_STOP
};
enum
{
OUTPUT_TXD,
OUTPUT_MARK,
OUTPUT_BREAK
};
void output_irq(int irq);
void output_txd(int txd);
void output_rxc(int rxc);
void output_rts(int rts);
void output_dtr(int dtr);
void update_irq();
void update_divider();
uint8_t read_rdr();
uint8_t read_status();
uint8_t read_command();
uint8_t read_control();
void write_tdr(uint8_t data);
void write_reset(uint8_t data);
void write_command(uint8_t data);
void write_control(uint8_t data);
int stoplength();
DECLARE_WRITE_LINE_MEMBER(internal_clock);
DECLARE_WRITE_LINE_MEMBER(receiver_clock);
DECLARE_WRITE_LINE_MEMBER(transmitter_clock);
static const int internal_divider[16];
static const int transmitter_controls[4][3];
required_device<clock_device> m_internal_clock;
devcb_write_line m_irq_handler;
devcb_write_line m_txd_handler;
devcb_write_line m_rxc_handler;
devcb_write_line m_rts_handler;
devcb_write_line m_dtr_handler;
uint8_t m_control;
uint8_t m_command;
uint8_t m_status;
uint8_t m_tdr;
uint8_t m_rdr;
uint8_t m_irq_state;
int m_irq;
int m_txd;
int m_rxc;
int m_rts;
int m_dtr;
uint32_t m_xtal;
int m_divide;
int m_cts;
int m_dsr;
int m_dcd;
int m_rxd;
int m_wordlength;
int m_extrastop;
int m_brk;
int m_echo_mode;
int m_parity;
int m_rx_state;
int m_rx_clock;
int m_rx_bits;
int m_rx_shift;
int m_rx_parity;
int m_rx_counter;
int m_rx_irq_enable;
int m_rx_internal_clock;
int m_tx_state;
int m_tx_output;
int m_tx_clock;
int m_tx_bits;
int m_tx_shift;
int m_tx_parity;
int m_tx_counter;
int m_tx_enable;
int m_tx_irq_enable;
int m_tx_internal_clock;
};
DECLARE_DEVICE_TYPE(MOS6551, mos6551_device)
#endif // MAME_MACHINE_MOS6551_H