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