1 // license:BSD-3-Clause 2 // copyright-holders:Curt Coder 3 /********************************************************************** 4 5 Commodore IEC Serial Bus emulation 6 7 **********************************************************************/ 8 9 #ifndef MAME_BUS_CBMIEC_CBMIEC_H 10 #define MAME_BUS_CBMIEC_CBMIEC_H 11 12 #pragma once 13 14 15 16 17 //************************************************************************** 18 // MACROS / CONSTANTS 19 //************************************************************************** 20 21 #define CBM_IEC_TAG "iec_bus" 22 23 24 DECLARE_DEVICE_TYPE(CBM_IEC, cbm_iec_device) 25 DECLARE_DEVICE_TYPE(CBM_IEC_SLOT, cbm_iec_slot_device) 26 27 void cbm_iec_devices(device_slot_interface &device); 28 29 //************************************************************************** 30 // TYPE DEFINITIONS 31 //************************************************************************** 32 33 // ======================> cbm_iec_device 34 35 class cbm_iec_slot_device; 36 class device_cbm_iec_interface; 37 38 class cbm_iec_device : public device_t 39 { 40 public: 41 // construction/destruction 42 cbm_iec_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 43 srq_callback()44 auto srq_callback() { return m_write_srq.bind(); } atn_callback()45 auto atn_callback() { return m_write_atn.bind(); } clk_callback()46 auto clk_callback() { return m_write_clk.bind(); } data_callback()47 auto data_callback() { return m_write_data.bind(); } reset_callback()48 auto reset_callback() { return m_write_reset.bind(); } 49 50 void add_device(cbm_iec_slot_device *slot, device_t *target); 51 52 // reads for both host and peripherals DECLARE_READ_LINE_MEMBER(srq_r)53 DECLARE_READ_LINE_MEMBER( srq_r ) { return get_signal(SRQ); } DECLARE_READ_LINE_MEMBER(atn_r)54 DECLARE_READ_LINE_MEMBER( atn_r ) { return get_signal(ATN); } DECLARE_READ_LINE_MEMBER(clk_r)55 DECLARE_READ_LINE_MEMBER( clk_r ) { return get_signal(CLK); } DECLARE_READ_LINE_MEMBER(data_r)56 DECLARE_READ_LINE_MEMBER( data_r ) { return get_signal(DATA); } DECLARE_READ_LINE_MEMBER(reset_r)57 DECLARE_READ_LINE_MEMBER( reset_r ) { return get_signal(RESET); } 58 59 // writes for host (driver_device) DECLARE_WRITE_LINE_MEMBER(host_srq_w)60 DECLARE_WRITE_LINE_MEMBER( host_srq_w ) { set_signal(this, SRQ, state); } DECLARE_WRITE_LINE_MEMBER(host_atn_w)61 DECLARE_WRITE_LINE_MEMBER( host_atn_w ) { set_signal(this, ATN, state); } DECLARE_WRITE_LINE_MEMBER(host_clk_w)62 DECLARE_WRITE_LINE_MEMBER( host_clk_w ) { set_signal(this, CLK, state); } DECLARE_WRITE_LINE_MEMBER(host_data_w)63 DECLARE_WRITE_LINE_MEMBER( host_data_w ) { set_signal(this, DATA, state); } DECLARE_WRITE_LINE_MEMBER(host_reset_w)64 DECLARE_WRITE_LINE_MEMBER( host_reset_w ) { set_signal(this, RESET, state); } 65 66 // writes for peripherals (device_t) srq_w(device_t * device,int state)67 void srq_w(device_t *device, int state) { set_signal(device, SRQ, state); } atn_w(device_t * device,int state)68 void atn_w(device_t *device, int state) { set_signal(device, ATN, state); } clk_w(device_t * device,int state)69 void clk_w(device_t *device, int state) { set_signal(device, CLK, state); } data_w(device_t * device,int state)70 void data_w(device_t *device, int state) { set_signal(device, DATA, state); } reset_w(device_t * device,int state)71 void reset_w(device_t *device, int state) { set_signal(device, RESET, state); } 72 73 protected: 74 enum 75 { 76 SRQ = 0, 77 ATN, 78 CLK, 79 DATA, 80 RESET, 81 SIGNAL_COUNT 82 }; 83 84 // device-level overrides 85 virtual void device_start() override; 86 virtual void device_reset() override; 87 virtual void device_stop() override; 88 89 class daisy_entry 90 { 91 public: 92 daisy_entry(device_t *device); next()93 daisy_entry *next() const { return m_next; } 94 95 daisy_entry * m_next; // next device 96 device_t * m_device; // associated device 97 device_cbm_iec_interface * m_interface; // associated device's daisy interface 98 99 int m_line[SIGNAL_COUNT]; 100 }; 101 102 simple_list<daisy_entry> m_device_list; 103 104 private: 105 devcb_write_line m_write_srq; 106 devcb_write_line m_write_atn; 107 devcb_write_line m_write_clk; 108 devcb_write_line m_write_data; 109 devcb_write_line m_write_reset; 110 111 void set_signal(device_t *device, int signal, int state); 112 int get_signal(int signal); 113 114 int m_line[SIGNAL_COUNT]; 115 }; 116 117 118 // ======================> cbm_iec_slot_device 119 120 class cbm_iec_slot_device : public device_t, 121 public device_slot_interface 122 { 123 public: 124 // construction/destruction 125 template <typename T> cbm_iec_slot_device(machine_config const & mconfig,char const * tag,device_t * owner,int address,T && opts,char const * dflt)126 cbm_iec_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, int address, T &&opts, char const *dflt) 127 : cbm_iec_slot_device(mconfig, tag, owner, (uint32_t)0) 128 { 129 option_reset(); 130 opts(*this); 131 set_default_option(dflt); 132 set_fixed(false); 133 set_address(address); 134 } 135 cbm_iec_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 136 add(machine_config & config,T && _bus_tag,const char * _default_drive)137 template <typename T> static void add(machine_config &config, T &&_bus_tag, const char *_default_drive) 138 { 139 CBM_IEC_SLOT(config, "iec4", 4, cbm_iec_devices, nullptr); 140 CBM_IEC_SLOT(config, "iec8", 8, cbm_iec_devices, _default_drive); 141 CBM_IEC_SLOT(config, "iec9", 9, cbm_iec_devices, nullptr); 142 CBM_IEC_SLOT(config, "iec10", 10, cbm_iec_devices, nullptr); 143 CBM_IEC_SLOT(config, "iec11", 11, cbm_iec_devices, nullptr); 144 145 CBM_IEC(config, std::forward<T>(_bus_tag), 0); 146 } 147 set_address(int address)148 void set_address(int address) { m_address = address; } get_address()149 int get_address() { return m_address; } 150 151 // device-level overrides 152 virtual void device_start() override; 153 154 protected: 155 int m_address; 156 }; 157 158 159 // ======================> device_cbm_iec_interface 160 161 class device_cbm_iec_interface : public device_interface 162 { 163 friend class cbm_iec_device; 164 165 public: 166 // construction/destruction 167 virtual ~device_cbm_iec_interface(); 168 next()169 device_cbm_iec_interface *next() const { return m_next; } 170 device_cbm_iec_interface *m_next; 171 172 // optional operation overrides cbm_iec_srq(int state)173 virtual void cbm_iec_srq(int state) { } cbm_iec_atn(int state)174 virtual void cbm_iec_atn(int state) { } cbm_iec_clk(int state)175 virtual void cbm_iec_clk(int state) { } cbm_iec_data(int state)176 virtual void cbm_iec_data(int state) { } cbm_iec_reset(int state)177 virtual void cbm_iec_reset(int state) { } 178 179 protected: 180 device_cbm_iec_interface(const machine_config &mconfig, device_t &device); 181 182 cbm_iec_device *m_bus; 183 cbm_iec_slot_device *m_slot; 184 }; 185 186 #endif // MAME_BUS_CBMIEC_CBMIEC_H 187