1 // license:BSD-3-Clause 2 // copyright-holders:F. Ulivi 3 /********************************************************************* 4 5 phi.h 6 7 HP PHI (Processor-to-Hpib-Interface) (1AA6-6x04) 8 9 *********************************************************************/ 10 11 #ifndef MAME_MACHINE_PHI_H 12 #define MAME_MACHINE_PHI_H 13 14 15 class phi_device : public device_t 16 { 17 public: 18 // construction/destruction 19 phi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 20 21 // See ieee488.h 22 enum phi_488_signal_t 23 { 24 PHI_488_EOI, 25 PHI_488_DAV, 26 PHI_488_NRFD, 27 PHI_488_NDAC, 28 PHI_488_IFC, 29 PHI_488_SRQ, 30 PHI_488_ATN, 31 PHI_488_REN, 32 PHI_488_SIGNAL_COUNT 33 }; 34 35 // Set read and write callbacks to access DIO bus on IEEE-488 dio_read_cb()36 auto dio_read_cb() { return m_dio_read_func.bind(); } dio_write_cb()37 auto dio_write_cb() { return m_dio_write_func.bind(); } 38 // Set write callbacks to access uniline signals on IEEE-488 eoi_write_cb()39 auto eoi_write_cb() { return m_signal_wr_fns[ PHI_488_EOI ].bind(); } dav_write_cb()40 auto dav_write_cb() { return m_signal_wr_fns[ PHI_488_DAV ].bind(); } nrfd_write_cb()41 auto nrfd_write_cb() { return m_signal_wr_fns[ PHI_488_NRFD ].bind(); } ndac_write_cb()42 auto ndac_write_cb() { return m_signal_wr_fns[ PHI_488_NDAC ].bind(); } ifc_write_cb()43 auto ifc_write_cb() { return m_signal_wr_fns[ PHI_488_IFC ].bind(); } srq_write_cb()44 auto srq_write_cb() { return m_signal_wr_fns[ PHI_488_SRQ ].bind(); } atn_write_cb()45 auto atn_write_cb() { return m_signal_wr_fns[ PHI_488_ATN ].bind(); } ren_write_cb()46 auto ren_write_cb() { return m_signal_wr_fns[ PHI_488_REN ].bind(); } 47 // Set write callback for INT signal int_write_cb()48 auto int_write_cb() { return m_int_write_func.bind(); } 49 // Set write callback for DMARQ signal dmarq_write_cb()50 auto dmarq_write_cb() { return m_dmarq_write_func.bind(); } 51 // Set read callback for SYS_CNTRL signal sys_cntrl_read_cb()52 auto sys_cntrl_read_cb() { return m_sys_cntrl_read_func.bind(); } 53 54 DECLARE_WRITE_LINE_MEMBER(eoi_w); 55 DECLARE_WRITE_LINE_MEMBER(dav_w); 56 DECLARE_WRITE_LINE_MEMBER(nrfd_w); 57 DECLARE_WRITE_LINE_MEMBER(ndac_w); 58 DECLARE_WRITE_LINE_MEMBER(ifc_w); 59 DECLARE_WRITE_LINE_MEMBER(srq_w); 60 DECLARE_WRITE_LINE_MEMBER(atn_w); 61 DECLARE_WRITE_LINE_MEMBER(ren_w); 62 63 void bus_dio_w(uint8_t data); 64 65 void set_ext_signal(phi_488_signal_t signal , int state); 66 67 // Register read/write 68 // Mapping of PHI register bits: 69 // Reg. bit PHI bit 70 // ================= 71 // 15 0 72 // 14 1 73 // 13 =0= 74 // 12 =0= 75 // 11 =0= 76 // 10 =0= 77 // 9 =0= 78 // 8 =0= 79 // 7 8 80 // 6 9 81 // 5 10 82 // 4 11 83 // 3 12 84 // 2 13 85 // 1 14 86 // 0 15 87 void reg16_w(offs_t offset, uint16_t data); 88 uint16_t reg16_r(offs_t offset); 89 void reg8_w(offs_t offset, uint8_t data); 90 uint8_t reg8_r(offs_t offset); 91 92 protected: 93 phi_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 94 95 // device-level overrides 96 virtual void device_start() override; 97 virtual void device_reset() override; 98 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; 99 100 private: 101 // Depth of inbound/outbound FIFOs 102 static constexpr unsigned FIFO_SIZE = 8; 103 104 devcb_read8 m_dio_read_func; 105 devcb_write8 m_dio_write_func; 106 devcb_write_line::array<PHI_488_SIGNAL_COUNT> m_signal_wr_fns; 107 devcb_write_line m_int_write_func; 108 devcb_write_line m_dmarq_write_func; 109 devcb_read_line m_sys_cntrl_read_func; 110 bool m_int_line; 111 bool m_dmarq_line; 112 113 // Internal copy of bus signals 114 // These signals have the "right" polarity (i.e. the opposite of bus signals, 1=L) 115 uint8_t m_dio; 116 bool m_signals[ PHI_488_SIGNAL_COUNT ]; 117 bool m_ext_signals[ PHI_488_SIGNAL_COUNT ]; 118 119 bool m_no_recursion; 120 121 bool m_sys_controller; 122 bool m_loopback; 123 bool m_id_enabled; 124 125 // SH (Source Handshake) states 126 enum { 127 PHI_SH_SIDS, // & SIWS 128 PHI_SH_SGNS, // & SWNS 129 PHI_SH_SDYS, 130 PHI_SH_STRS 131 }; 132 133 int m_sh_state; 134 135 // AH (Acceptor Handshake) states 136 enum { 137 PHI_AH_AIDS, 138 PHI_AH_ANRS, 139 PHI_AH_ACRS, 140 PHI_AH_ACDS, 141 PHI_AH_ACDS_FROZEN, // Non-standard state: IF CMD rejected because of even parity 142 PHI_AH_AWNS 143 }; 144 145 int m_ah_state; 146 147 // T (Talker) states 148 enum { 149 PHI_T_TIDS, 150 PHI_T_TADS, 151 PHI_T_SPAS, 152 PHI_T_TACS, 153 // The following are non-standard states for IDENTIFY sequencing 154 PHI_T_ID1, // Addressed by secondary address 155 PHI_T_ID2, // Sending 1st byte 156 PHI_T_ID3, // Waiting to send 2nd byte 157 PHI_T_ID4, // Sending 2nd byte 158 PHI_T_ID5 // 2nd byte sent, end of sequence 159 }; 160 161 int m_t_state; 162 bool m_t_spms; // False: SPIS, true: SPMS 163 164 // L (Listener) states 165 enum { 166 PHI_L_LIDS, 167 PHI_L_LADS, 168 PHI_L_LACS 169 }; 170 171 int m_l_state; 172 173 // SR (Service Request) states 174 enum { 175 PHI_SR_NPRS, 176 PHI_SR_SRQS, 177 PHI_SR_APRS 178 }; 179 180 int m_sr_state; 181 182 // RL (Remote Local) states 183 bool m_rl_rems; // false: LOCS, true: REMS 184 185 // PP (Parallel poll) states 186 enum { 187 PHI_PP_PPIS, 188 PHI_PP_PPSS, 189 PHI_PP_PPAS 190 }; 191 192 int m_pp_state; 193 uint8_t m_ppr_msg; 194 bool m_s_sense; 195 196 // C (Controller) states 197 enum { 198 PHI_C_CIDS, 199 PHI_C_CADS, 200 PHI_C_CACS, 201 PHI_C_CPPS, 202 PHI_C_CSBS, 203 PHI_C_CSHS, 204 PHI_C_CAWS, 205 PHI_C_CTRS, 206 PHI_C_CSWS 207 }; 208 209 int m_c_state; 210 211 // Secondary address decoder states 212 enum { 213 PHI_SA_NONE, 214 PHI_SA_PACS, 215 PHI_SA_TPAS, 216 PHI_SA_LPAS, 217 PHI_SA_UNT 218 }; 219 220 int m_sa_state; 221 222 uint8_t m_be_counter; 223 uint16_t m_reg_status; 224 uint16_t m_reg_int_cond; 225 uint16_t m_reg_int_mask; 226 uint16_t m_reg_1st_id; 227 uint16_t m_reg_2nd_id; 228 uint16_t m_reg_control; 229 uint16_t m_reg_address; 230 util::fifo<uint16_t , FIFO_SIZE> m_fifo_in; 231 util::fifo<uint16_t , FIFO_SIZE> m_fifo_out; 232 233 typedef enum { 234 NBA_NONE, 235 NBA_CMD_FROM_OFIFO, 236 NBA_BYTE_FROM_OFIFO, 237 NBA_FROM_SPAS, 238 NBA_FROM_ID2, 239 NBA_FROM_ID4 240 } nba_origin_t; 241 242 int m_nba_origin; 243 244 // Timers 245 emu_timer *m_sh_dly_timer; 246 emu_timer *m_c_dly_timer; 247 248 void int_reg_w(offs_t offset , uint16_t data); 249 250 uint8_t get_dio(void); 251 void set_dio(uint8_t data); 252 bool get_signal(phi_488_signal_t signal); 253 void set_signal(phi_488_signal_t signal , bool state); 254 255 void pon_msg(void); 256 void update_488(void); 257 void update_fsm(void); 258 nba_origin_t nba_msg(uint8_t& new_byte , bool& new_eoi) const; 259 void clear_nba(nba_origin_t origin); 260 bool if_cmd_received(uint8_t byte); 261 bool byte_received(uint8_t byte , bool eoi); 262 void rx_n_data_freeze(uint16_t word); 263 bool ton_msg(void) const; 264 bool lon_msg(void) const; 265 bool odd_parity(uint8_t byte) const; 266 uint8_t my_address(void) const; 267 bool tcs_msg(void) const; 268 bool rpp_msg(void) const; 269 uint8_t get_pp_response(); 270 bool controller_in_charge(void) const; 271 void configure_pp_response(); 272 void update_pp(); 273 void update_interrupt(); 274 void update_dmarq(); 275 }; 276 277 // device type definition 278 DECLARE_DEVICE_TYPE(PHI, phi_device) 279 280 #endif // MAME_MACHINE_PHI_H 281