1 // license:BSD-3-Clause
2 // copyright-holders:Robbbert
3 /* ay31015.h
4 
5     Written for MESS by Robbbert on May 29th, 2008.
6 
7 */
8 
9 #ifndef MAME_MACHINE_AY31015_H
10 #define MAME_MACHINE_AY31015_H
11 
12 #pragma once
13 
14 /***************************************************************************
15     DEVICE INTERFACE
16 ***************************************************************************/
17 
18 class ay31015_device : public device_t
19 {
20 public:
21 	ay31015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
22 
set_auto_rdav(bool auto_rdav)23 	void set_auto_rdav(bool auto_rdav) { m_auto_rdav = auto_rdav; }
24 
read_si_callback()25 	auto read_si_callback() { return m_read_si_cb.bind(); }
write_so_callback()26 	auto write_so_callback() { return m_write_so_cb.bind(); }
write_pe_callback()27 	auto write_pe_callback() { return m_write_pe_cb.bind(); }
write_fe_callback()28 	auto write_fe_callback() { return m_write_fe_cb.bind(); }
write_or_callback()29 	auto write_or_callback() { return m_write_or_cb.bind(); }
write_dav_callback()30 	auto write_dav_callback() { return m_write_dav_cb.bind(); }
write_tbmt_callback()31 	auto write_tbmt_callback() { return m_write_tbmt_cb.bind(); }
write_eoc_callback()32 	auto write_eoc_callback() { return m_write_eoc_cb.bind(); }
33 
34 	/* Set an input pin */
DECLARE_WRITE_LINE_MEMBER(write_swe)35 	DECLARE_WRITE_LINE_MEMBER(write_swe) { set_input_pin(SWE, state); }
DECLARE_WRITE_LINE_MEMBER(write_rcp)36 	DECLARE_WRITE_LINE_MEMBER(write_rcp) { set_input_pin(RCP, state); }
DECLARE_WRITE_LINE_MEMBER(write_rdav)37 	DECLARE_WRITE_LINE_MEMBER(write_rdav) { set_input_pin(RDAV, state); }
DECLARE_WRITE_LINE_MEMBER(write_si)38 	DECLARE_WRITE_LINE_MEMBER(write_si) { set_input_pin(SI, state); }
DECLARE_WRITE_LINE_MEMBER(write_xr)39 	DECLARE_WRITE_LINE_MEMBER(write_xr) { set_input_pin(XR, state); }
DECLARE_WRITE_LINE_MEMBER(write_cs)40 	DECLARE_WRITE_LINE_MEMBER(write_cs) { set_input_pin(CS, state); }
DECLARE_WRITE_LINE_MEMBER(write_np)41 	DECLARE_WRITE_LINE_MEMBER(write_np) { set_input_pin(NP, state); }
DECLARE_WRITE_LINE_MEMBER(write_tsb)42 	DECLARE_WRITE_LINE_MEMBER(write_tsb) { set_input_pin(TSB, state); }
DECLARE_WRITE_LINE_MEMBER(write_nb2)43 	DECLARE_WRITE_LINE_MEMBER(write_nb2) { set_input_pin(NB2, state); }
DECLARE_WRITE_LINE_MEMBER(write_nb1)44 	DECLARE_WRITE_LINE_MEMBER(write_nb1) { set_input_pin(NB1, state); }
DECLARE_WRITE_LINE_MEMBER(write_eps)45 	DECLARE_WRITE_LINE_MEMBER(write_eps) { set_input_pin(EPS, state); }
DECLARE_WRITE_LINE_MEMBER(write_tcp)46 	DECLARE_WRITE_LINE_MEMBER(write_tcp) { set_input_pin(TCP, state); }
47 
48 	/* Get an output pin */
DECLARE_READ_LINE_MEMBER(pe_r)49 	DECLARE_READ_LINE_MEMBER(pe_r) { return get_output_pin(PE); }
DECLARE_READ_LINE_MEMBER(fe_r)50 	DECLARE_READ_LINE_MEMBER(fe_r) { return get_output_pin(FE); }
DECLARE_READ_LINE_MEMBER(or_r)51 	DECLARE_READ_LINE_MEMBER(or_r) { return get_output_pin(OR); }
DECLARE_READ_LINE_MEMBER(dav_r)52 	DECLARE_READ_LINE_MEMBER(dav_r) { return get_output_pin(DAV); }
DECLARE_READ_LINE_MEMBER(tbmt_r)53 	DECLARE_READ_LINE_MEMBER(tbmt_r) { return get_output_pin(TBMT); }
DECLARE_READ_LINE_MEMBER(eoc_r)54 	DECLARE_READ_LINE_MEMBER(eoc_r) { return get_output_pin(EOC); }
DECLARE_READ_LINE_MEMBER(so_r)55 	DECLARE_READ_LINE_MEMBER(so_r) { return get_output_pin(SO); }
56 
57 	/* Read the received data */
58 	/* The received data is available on RD8-RD1 (pins 5-12) */
59 	uint8_t receive();
60 
61 	/* Set the transmitter buffer */
62 	/* The data to transmit is set on DB1-DB8 (pins 26-33) */
63 	void transmit( uint8_t data );
64 
65 protected:
66 	enum input_pin
67 	{
68 		SWE = 16,       // -SWE  - Pin 16 - Status word enable
69 		RCP = 17,       //  RCP  - Pin 17 - Receiver clock pulse
70 		RDAV = 18,      // -RDAV - Pin 18 - Reset data available
71 		SI = 20,        //  SI   - Pin 20 - Serial input
72 		XR = 21,        //  XR   - Pin 21 - External reset
73 		CS = 34,        //  CS   - Pin 34 - Control strobe
74 		NP = 35,        //  NP   - Pin 35 - No parity
75 		TSB = 36,       //  TSB  - Pin 36 - Number of stop bits
76 		NB2 = 37,       //  NB2  - Pin 37 - Number of bits #2
77 		NB1 = 38,       //  NB1  - Pin 38 - Number of bits #1
78 		EPS = 39,       //  EPS  - Pin 39 - Odd/Even parity select
79 		TCP = 40        //  TCP  - Pin 40 - Transmitter clock pulse
80 	};
81 
82 	enum output_pin
83 	{
84 		PE = 13,        // PE   - Pin 13 - Parity error
85 		FE = 14,        // FE   - Pin 14 - Framing error
86 		OR = 15,        // OR   - Pin 15 - Over-run
87 		DAV = 19,       // DAV  - Pin 19 - Data available
88 		TBMT = 22,      // TBMT - Pin 22 - Transmit buffer empty
89 		EOC = 24,       // EOC  - Pin 24 - End of character
90 		SO = 25         // SO   - Pin 25 - Serial output
91 	};
92 
93 	enum state_t : u8
94 	{
95 		IDLE,
96 		START_BIT,
97 		PROCESSING,
98 		PARITY_BIT,
99 		FIRST_STOP_BIT,
100 		SECOND_STOP_BIT,
101 		PREP_TIME
102 	};
103 
104 	ay31015_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
105 
106 	// device-level overrides
107 	virtual void device_resolve_objects() override;
108 	virtual void device_start() override;
109 	virtual void device_reset() override;
110 
111 	void rx_process();
112 	void tx_process();
113 	virtual void internal_reset();
114 
115 	// internal state
116 	inline uint8_t get_si();
117 	inline void set_so(int data);
118 	inline void update_status_pin(uint8_t reg_bit, output_pin pin, devcb_write_line &write_cb);
119 	void update_status_pins();
120 	void transfer_control_pins();
121 	void set_input_pin(input_pin pin, int data);
122 	int get_output_pin(output_pin pin);
123 
124 	int m_pins[41];
125 
126 	uint8_t m_control_reg;
127 	uint8_t m_status_reg;
128 	uint16_t m_second_stop_bit; // 0, 8, 16
129 	uint16_t m_total_pulses;    // bits * 16
130 	uint8_t m_internal_sample;
131 
132 	state_t m_rx_state;
133 	uint8_t m_rx_data;      // byte being received
134 	uint8_t m_rx_buffer;    // received byte waiting to be accepted by computer
135 	uint8_t m_rx_bit_count;
136 	uint8_t m_rx_parity;
137 	uint16_t m_rx_pulses;   // total pulses left
138 
139 	state_t m_tx_state;
140 	uint8_t m_tx_data;      // byte being sent
141 	uint8_t m_tx_buffer;    // next byte to send
142 	uint8_t m_tx_parity;
143 	uint16_t m_tx_pulses;   // total pulses left
144 
145 	devcb_read_line m_read_si_cb;           // SI - pin 20 - This will be called whenever the SI pin is sampled. Optional
146 	devcb_write_line m_write_so_cb;         // SO - pin 25 - This will be called whenever data is put on the SO pin. Optional
147 	devcb_write_line m_write_pe_cb;         // PE - pin 13 - This will be called whenever the PE pin may have changed. Optional
148 	devcb_write_line m_write_fe_cb;         // FE - pin 14 - This will be called whenever the FE pin may have changed. Optional
149 	devcb_write_line m_write_or_cb;         // OR - pin 15 - This will be called whenever the OR pin may have changed. Optional
150 	devcb_write_line m_write_dav_cb;        // DAV - pin 19 - This will be called whenever the DAV pin may have changed. Optional
151 	devcb_write_line m_write_tbmt_cb;       // TBMT - pin 22 - This will be called whenever the TBMT pin may have changed. Optional
152 	devcb_write_line m_write_eoc_cb;        // EOC - pin 24 - This will be called whenever the EOC pin may have changed. Optional
153 
154 	bool m_auto_rdav;                       // true if RDAV (pin 18) is tied to RDE (pin 4)
155 };
156 
157 class ay51013_device : public ay31015_device
158 {
159 public:
160 	ay51013_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
161 
162 protected:
163 	virtual void internal_reset() override;
164 
165 };
166 
167 ALLOW_SAVE_TYPE(ay31015_device::state_t);
168 
169 DECLARE_DEVICE_TYPE(AY31015, ay31015_device)   // For AY-3-1014A, AY-3-1015(D) and HD6402 variants
170 DECLARE_DEVICE_TYPE(AY51013, ay51013_device)   // For AY-3-1014, AY-5-1013 and AY-6-1013 variants
171 
172 #endif // MAME_MACHINE_AY31015_H
173