1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles, Nathan Woods
3 /**********************************************************************
4 
5     Motorola 6821 PIA interface and emulation
6 
7     Notes:
8         * port_b_z_mask() gives the caller the bitmask that shows
9           which bits are high-impedance when reading port B, and thus
10           neither 0 or 1. cb2_output_z() returns the same info
11           for the CB2 pin.
12         * The 'alt' interface functions are used when the A0 and A1
13           address bits are swapped.
14         * All 'int' data or return values are bool, and should be
15           converted to bool at some point.
16 
17 **********************************************************************/
18 
19 #ifndef MAME_DEVICES_MACHINE_6821PIA_H
20 #define MAME_DEVICES_MACHINE_6821PIA_H
21 
22 #pragma once
23 
24 
25 
26 
27 /***************************************************************************
28     TYPE DEFINITIONS
29 ***************************************************************************/
30 
31 // ======================> pia6821_device
32 
33 class pia6821_device :  public device_t
34 {
35 public:
36 	// construction/destruction
37 	pia6821_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
38 
39 	// TODO: REMOVE THESE
readpa_handler()40 	auto readpa_handler() { return m_in_a_handler.bind(); }
readpb_handler()41 	auto readpb_handler() { return m_in_b_handler.bind(); }
readca1_handler()42 	auto readca1_handler() { return m_in_ca1_handler.bind(); }
readca2_handler()43 	auto readca2_handler() { return m_in_ca2_handler.bind(); }
readcb1_handler()44 	auto readcb1_handler() { return m_in_cb1_handler.bind(); }
45 
46 	// TODO: CONVERT THESE TO WRITE LINE
writepa_handler()47 	auto writepa_handler() { return m_out_a_handler.bind(); }
writepb_handler()48 	auto writepb_handler() { return m_out_b_handler.bind(); }
49 
ca2_handler()50 	auto ca2_handler() { return m_ca2_handler.bind(); }
cb2_handler()51 	auto cb2_handler() { return m_cb2_handler.bind(); }
irqa_handler()52 	auto irqa_handler() { return m_irqa_handler.bind(); }
irqb_handler()53 	auto irqb_handler() { return m_irqb_handler.bind(); }
54 
55 	uint8_t read(offs_t offset);
56 	void write(offs_t offset, uint8_t data);
read_alt(offs_t offset)57 	uint8_t read_alt(offs_t offset) { return read(((offset << 1) & 0x02) | ((offset >> 1) & 0x01)); }
write_alt(offs_t offset,uint8_t data)58 	void write_alt(offs_t offset, uint8_t data) { write(((offset << 1) & 0x02) | ((offset >> 1) & 0x01), data); }
59 
port_b_z_mask()60 	uint8_t port_b_z_mask() const { return ~m_ddr_b; } // see notes
61 
62 	void porta_w(uint8_t data);
63 	void write_porta_line(int line, bool state);
64 	void set_a_input(uint8_t data);
65 	uint8_t a_output();
set_port_a_input_overrides_output_mask(uint8_t mask)66 	void set_port_a_input_overrides_output_mask(uint8_t mask) { m_a_input_overrides_output_mask = mask; }
67 
DECLARE_WRITE_LINE_MEMBER(pa0_w)68 	DECLARE_WRITE_LINE_MEMBER( pa0_w ) { write_porta_line(0, state); }
DECLARE_WRITE_LINE_MEMBER(pa1_w)69 	DECLARE_WRITE_LINE_MEMBER( pa1_w ) { write_porta_line(1, state); }
DECLARE_WRITE_LINE_MEMBER(pa2_w)70 	DECLARE_WRITE_LINE_MEMBER( pa2_w ) { write_porta_line(2, state); }
DECLARE_WRITE_LINE_MEMBER(pa3_w)71 	DECLARE_WRITE_LINE_MEMBER( pa3_w ) { write_porta_line(3, state); }
DECLARE_WRITE_LINE_MEMBER(pa4_w)72 	DECLARE_WRITE_LINE_MEMBER( pa4_w ) { write_porta_line(4, state); }
DECLARE_WRITE_LINE_MEMBER(pa5_w)73 	DECLARE_WRITE_LINE_MEMBER( pa5_w ) { write_porta_line(5, state); }
DECLARE_WRITE_LINE_MEMBER(pa6_w)74 	DECLARE_WRITE_LINE_MEMBER( pa6_w ) { write_porta_line(6, state); }
DECLARE_WRITE_LINE_MEMBER(pa7_w)75 	DECLARE_WRITE_LINE_MEMBER( pa7_w ) { write_porta_line(7, state); }
76 
77 	DECLARE_WRITE_LINE_MEMBER( ca1_w );
78 
79 	DECLARE_WRITE_LINE_MEMBER( ca2_w );
80 	bool ca2_output();
81 	bool ca2_output_z();
82 
83 	void portb_w(uint8_t data);
84 	void write_portb_line(int line, bool state);
85 	uint8_t b_output();
86 
DECLARE_WRITE_LINE_MEMBER(pb0_w)87 	DECLARE_WRITE_LINE_MEMBER( pb0_w ) { write_portb_line(0, state); }
DECLARE_WRITE_LINE_MEMBER(pb1_w)88 	DECLARE_WRITE_LINE_MEMBER( pb1_w ) { write_portb_line(1, state); }
DECLARE_WRITE_LINE_MEMBER(pb2_w)89 	DECLARE_WRITE_LINE_MEMBER( pb2_w ) { write_portb_line(2, state); }
DECLARE_WRITE_LINE_MEMBER(pb3_w)90 	DECLARE_WRITE_LINE_MEMBER( pb3_w ) { write_portb_line(3, state); }
DECLARE_WRITE_LINE_MEMBER(pb4_w)91 	DECLARE_WRITE_LINE_MEMBER( pb4_w ) { write_portb_line(4, state); }
DECLARE_WRITE_LINE_MEMBER(pb5_w)92 	DECLARE_WRITE_LINE_MEMBER( pb5_w ) { write_portb_line(5, state); }
DECLARE_WRITE_LINE_MEMBER(pb6_w)93 	DECLARE_WRITE_LINE_MEMBER( pb6_w ) { write_portb_line(6, state); }
DECLARE_WRITE_LINE_MEMBER(pb7_w)94 	DECLARE_WRITE_LINE_MEMBER( pb7_w ) { write_portb_line(7, state); }
95 
96 	DECLARE_WRITE_LINE_MEMBER( cb1_w );
97 
98 	DECLARE_WRITE_LINE_MEMBER( cb2_w );
99 	bool cb2_output();
100 	bool cb2_output_z();
101 
irq_a_state()102 	int irq_a_state() const { return m_irq_a_state; }
irq_b_state()103 	int irq_b_state() const { return m_irq_b_state; }
104 
105 protected:
106 	// device-level overrides
107 	virtual void device_start() override;
108 	virtual void device_reset() override;
109 
110 private:
111 
112 	void update_interrupts();
113 
114 	uint8_t get_in_a_value();
115 	uint8_t get_in_b_value();
116 
117 	uint8_t get_out_a_value();
118 	uint8_t get_out_b_value();
119 
120 	void set_out_ca2(int data);
121 	void set_out_cb2(int data);
122 
123 	uint8_t port_a_r();
124 	uint8_t ddr_a_r();
125 	uint8_t control_a_r();
126 
127 	uint8_t port_b_r();
128 	uint8_t ddr_b_r();
129 	uint8_t control_b_r();
130 
131 	void send_to_out_a_func(const char* message);
132 	void send_to_out_b_func(const char* message);
133 
134 	void port_a_w(uint8_t data);
135 	void ddr_a_w(uint8_t data);
136 
137 	void port_b_w(uint8_t data);
138 	void ddr_b_w(uint8_t data);
139 
140 	void control_a_w(uint8_t data);
141 	void control_b_w(uint8_t data);
142 
143 	static bool irq1_enabled(uint8_t c);
144 	static bool c1_low_to_high(uint8_t c);
145 	static bool c1_high_to_low(uint8_t c);
146 	static bool output_selected(uint8_t c);
147 	static bool irq2_enabled(uint8_t c);
148 	static bool strobe_e_reset(uint8_t c);
149 	static bool strobe_c1_reset(uint8_t c);
150 	static bool c2_set(uint8_t c);
151 	static bool c2_low_to_high(uint8_t c);
152 	static bool c2_high_to_low(uint8_t c);
153 	static bool c2_set_mode(uint8_t c);
154 	static bool c2_strobe_mode(uint8_t c);
155 	static bool c2_output(uint8_t c);
156 	static bool c2_input(uint8_t c);
157 
158 	devcb_read8 m_in_a_handler;
159 	devcb_read8 m_in_b_handler;
160 	devcb_read_line m_in_ca1_handler;
161 	devcb_read_line m_in_cb1_handler;
162 	devcb_read_line m_in_ca2_handler;
163 	devcb_write8 m_out_a_handler;
164 	devcb_write8 m_out_b_handler;
165 	devcb_write_line m_ca2_handler;
166 	devcb_write_line m_cb2_handler;
167 	devcb_write_line m_irqa_handler;
168 	devcb_write_line m_irqb_handler;
169 
170 	uint8_t m_in_a;
171 	uint8_t m_in_ca1;
172 	uint8_t m_in_ca2;
173 	uint8_t m_out_a;
174 	uint8_t m_a_input_overrides_output_mask;
175 	uint8_t m_out_ca2;
176 	uint8_t m_ddr_a;
177 	uint8_t m_ctl_a;
178 	uint8_t m_irq_a1;
179 	uint8_t m_irq_a2;
180 	uint8_t m_irq_a_state;
181 
182 	uint8_t m_in_b;
183 	uint8_t m_in_cb1;
184 	uint8_t m_in_cb2;
185 	uint8_t m_out_b;
186 	uint8_t m_out_cb2;
187 	uint8_t m_last_out_cb2_z;
188 	uint8_t m_ddr_b;
189 	uint8_t m_ctl_b;
190 	uint8_t m_irq_b1;
191 	uint8_t m_irq_b2;
192 	uint8_t m_irq_b_state;
193 
194 	// variables that indicate if access a line externally -
195 	// used to for logging purposes ONLY
196 	bool m_in_a_pushed;
197 	bool m_out_a_needs_pulled;
198 	bool m_in_ca1_pushed;
199 	bool m_in_ca2_pushed;
200 	bool m_out_ca2_needs_pulled;
201 	bool m_in_b_pushed;
202 	bool m_out_b_needs_pulled;
203 	bool m_in_cb1_pushed;
204 	bool m_in_cb2_pushed;
205 	bool m_out_cb2_needs_pulled;
206 	bool m_logged_port_a_not_connected;
207 	bool m_logged_port_b_not_connected;
208 	bool m_logged_ca1_not_connected;
209 	bool m_logged_ca2_not_connected;
210 	bool m_logged_cb1_not_connected;
211 	bool m_logged_cb2_not_connected;
212 };
213 
214 
215 // device type definition
216 DECLARE_DEVICE_TYPE(PIA6821, pia6821_device)
217 
218 
219 #endif // MAME_DEVICES_MACHINE_6821PIA_H
220