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