1 // license:BSD-3-Clause 2 // copyright-holders:Miodrag Milanovic, R.Belmont 3 /*************************************************************************** 4 5 HP DIO and DIO-II bus devices 6 7 DIO is 16-bit, essentially the MC68000 bus 8 DIO-II extends to 32-bit for 68020/030/040 machines 9 10 16-bit DIO cards fit and work in either 16 or 32 bit systems, much like 8-bit ISA. 11 32-bit DIO-II cards only work in 32 bit DIO-II systems. 12 13 ***************************************************************************/ 14 15 #ifndef MAME_BUS_HPDIO_HPDIO_H 16 #define MAME_BUS_HPDIO_HPDIO_H 17 18 #pragma once 19 20 namespace bus { namespace hp_dio { 21 22 //************************************************************************** 23 // TYPE DEFINITIONS 24 //************************************************************************** 25 26 class device_dio16_card_interface; 27 class dio16_device; 28 29 class dio16_slot_device : public device_t, public device_slot_interface 30 { 31 public: 32 // construction/destruction 33 template <typename T, typename U> dio16_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,T && dio_tag,U && opts,const char * dflt,bool fixed)34 dio16_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&dio_tag, U &&opts, const char *dflt, bool fixed) : 35 dio16_slot_device(mconfig, tag, owner, clock) 36 { 37 set_dio(std::forward<T>(dio_tag)); 38 option_reset(); 39 opts(*this); 40 set_default_option(dflt); 41 set_fixed(fixed); 42 } 43 dio16_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 44 45 // inline configuration set_dio(T && dio_tag)46 template <typename T> void set_dio(T &&dio_tag) { m_dio.set_tag(std::forward<T>(dio_tag)); } 47 48 protected: 49 dio16_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 50 51 // device-level overrides 52 virtual void device_resolve_objects() override; 53 virtual void device_validity_check(validity_checker &valid) const override; 54 virtual void device_start() override; 55 56 // configuration 57 required_device<dio16_device> m_dio; 58 }; 59 60 // ======================> dio16_device 61 class dio16_device : public device_t 62 { 63 public: 64 // construction/destruction 65 dio16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 66 // inline configuration set_program_space(T && tag,int spacenum)67 template <typename T> void set_program_space(T &&tag, int spacenum) { m_prgspace.set_tag(std::forward<T>(tag), spacenum); } 68 69 // callback configuration dmar0_out_cb()70 auto dmar0_out_cb() { return m_dmar0_out_cb.bind(); } dmar1_out_cb()71 auto dmar1_out_cb() { return m_dmar1_out_cb.bind(); } irq1_out_cb()72 auto irq1_out_cb() { return m_irq1_out_cb.bind(); } irq2_out_cb()73 auto irq2_out_cb() { return m_irq2_out_cb.bind(); } irq3_out_cb()74 auto irq3_out_cb() { return m_irq3_out_cb.bind(); } irq4_out_cb()75 auto irq4_out_cb() { return m_irq4_out_cb.bind(); } irq5_out_cb()76 auto irq5_out_cb() { return m_irq5_out_cb.bind(); } irq6_out_cb()77 auto irq6_out_cb() { return m_irq6_out_cb.bind(); } irq7_out_cb()78 auto irq7_out_cb() { return m_irq7_out_cb.bind(); } 79 80 template<typename R, typename W> void install_memory(offs_t start, offs_t end, R rhandler, W whandler); 81 82 // DANGER: these will currently produce different results for a DIO-I card on DIO-I and DIO-II systems 83 // due to the varying bus widths. Using all install_memory() shields you from this problem. 84 // Either know what you're doing (m_prgwidth is available to cards for this purpose) or 85 // only use these for 32-bit DIO-II cards. 86 void install_bank(offs_t start, offs_t end, const char *tag, uint8_t *data); 87 void install_rom(offs_t start, offs_t end, const char *tag, uint8_t *data); 88 89 void unmap_bank(offs_t start, offs_t end); 90 void unmap_rom(offs_t start, offs_t end); program_space()91 address_space &program_space() { return *m_prgspace; } 92 93 // IRQs 1, 2, and 7 are reserved for non-bus usage. 94 95 // input lines DECLARE_WRITE_LINE_MEMBER(dmar0_in)96 DECLARE_WRITE_LINE_MEMBER(dmar0_in) { set_dmar(m_bus_index, 0, state); } DECLARE_WRITE_LINE_MEMBER(dmar1_in)97 DECLARE_WRITE_LINE_MEMBER(dmar1_in) { set_dmar(m_bus_index, 1, state); } DECLARE_WRITE_LINE_MEMBER(irq1_in)98 DECLARE_WRITE_LINE_MEMBER(irq1_in) { set_irq(m_bus_index, 0, state); } DECLARE_WRITE_LINE_MEMBER(irq2_in)99 DECLARE_WRITE_LINE_MEMBER(irq2_in) { set_irq(m_bus_index, 1, state); } DECLARE_WRITE_LINE_MEMBER(irq3_in)100 DECLARE_WRITE_LINE_MEMBER(irq3_in) { set_irq(m_bus_index, 2, state); } DECLARE_WRITE_LINE_MEMBER(irq4_in)101 DECLARE_WRITE_LINE_MEMBER(irq4_in) { set_irq(m_bus_index, 3, state); } DECLARE_WRITE_LINE_MEMBER(irq5_in)102 DECLARE_WRITE_LINE_MEMBER(irq5_in) { set_irq(m_bus_index, 4, state); } DECLARE_WRITE_LINE_MEMBER(irq6_in)103 DECLARE_WRITE_LINE_MEMBER(irq6_in) { set_irq(m_bus_index, 5, state); } DECLARE_WRITE_LINE_MEMBER(irq7_in)104 DECLARE_WRITE_LINE_MEMBER(irq7_in) { set_irq(m_bus_index, 6, state); } 105 DECLARE_WRITE_LINE_MEMBER(reset_in); 106 107 // output lines DECLARE_READ_LINE_MEMBER(irq1_out)108 DECLARE_READ_LINE_MEMBER(irq1_out) const { return (m_irq[0] & ~m_bus_index) ? 1 : 0; } DECLARE_READ_LINE_MEMBER(irq2_out)109 DECLARE_READ_LINE_MEMBER(irq2_out) const { return (m_irq[1] & ~m_bus_index) ? 1 : 0; } DECLARE_READ_LINE_MEMBER(irq3_out)110 DECLARE_READ_LINE_MEMBER(irq3_out) const { return (m_irq[2] & ~m_bus_index) ? 1 : 0; } DECLARE_READ_LINE_MEMBER(irq4_out)111 DECLARE_READ_LINE_MEMBER(irq4_out) const { return (m_irq[3] & ~m_bus_index) ? 1 : 0; } DECLARE_READ_LINE_MEMBER(irq5_out)112 DECLARE_READ_LINE_MEMBER(irq5_out) const { return (m_irq[4] & ~m_bus_index) ? 1 : 0; } DECLARE_READ_LINE_MEMBER(irq6_out)113 DECLARE_READ_LINE_MEMBER(irq6_out) const { return (m_irq[5] & ~m_bus_index) ? 1 : 0; } DECLARE_READ_LINE_MEMBER(irq7_out)114 DECLARE_READ_LINE_MEMBER(irq7_out) const { return (m_irq[6] & ~m_bus_index) ? 1 : 0; } DECLARE_READ_LINE_MEMBER(dmar0_out)115 DECLARE_READ_LINE_MEMBER(dmar0_out) const { return dmar0_r(); } DECLARE_READ_LINE_MEMBER(dmar1_out)116 DECLARE_READ_LINE_MEMBER(dmar1_out) const { return dmar1_r(); } 117 dmar0_r()118 bool dmar0_r() const { return (m_dmar[0] & ~m_bus_index) ? 1 : 0; } dmar1_r()119 bool dmar1_r() const { return (m_dmar[1] & ~m_bus_index) ? 1 : 0; } 120 121 uint8_t dmack_r_out(int index, int channel); 122 void dmack_w_out(int index, int channel, uint8_t data); 123 124 int m_prgwidth; 125 126 unsigned add_card(device_dio16_card_interface & card); 127 void set_irq(unsigned int index, unsigned int num, int state); 128 void set_dmar(unsigned int index, unsigned int num, int state); 129 130 protected: 131 dio16_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 132 void install_space(int spacenum, offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler); 133 134 // device-level overrides 135 virtual void device_start() override; 136 virtual void device_reset() override; 137 138 // internal state 139 std::list<device_dio16_card_interface *> m_cards; 140 141 // address spaces 142 required_address_space m_prgspace; 143 int m_bus_index; 144 145 // packed line states 146 u16 m_irq[7]; 147 u16 m_dmar[2]; 148 149 devcb_write_line m_irq1_out_cb; 150 devcb_write_line m_irq2_out_cb; 151 devcb_write_line m_irq3_out_cb; 152 devcb_write_line m_irq4_out_cb; 153 devcb_write_line m_irq5_out_cb; 154 devcb_write_line m_irq6_out_cb; 155 devcb_write_line m_irq7_out_cb; 156 157 devcb_write_line m_dmar0_out_cb; 158 devcb_write_line m_dmar1_out_cb; 159 }; 160 161 // ======================> device_dio16_card_interface 162 163 // class representing interface-specific live dio16 card 164 class device_dio16_card_interface : public device_interface 165 { 166 friend class dio16_device; 167 template <class ElementType> friend class simple_list; 168 public: 169 // construction/destruction 170 virtual ~device_dio16_card_interface(); 171 next()172 device_dio16_card_interface *next() const { return m_next; } 173 // inline configuration set_diobus(dio16_device & dio_device)174 void set_diobus(dio16_device &dio_device) { 175 m_dio_dev = &dio_device; 176 m_index = m_dio_dev->add_card(*this); 177 } 178 protected: 179 device_dio16_card_interface(const machine_config &mconfig, device_t &device); dio()180 dio16_device &dio() { 181 assert(m_dio_dev); 182 return *m_dio_dev; 183 } 184 185 virtual void interface_pre_start() override; 186 get_index()187 int get_index() { return m_index; }; program_space()188 address_space &program_space() { return m_dio_dev->program_space(); } 189 DECLARE_WRITE_LINE_MEMBER(irq1_out)190 DECLARE_WRITE_LINE_MEMBER(irq1_out) { m_dio_dev->set_irq(m_index, 0, state); } DECLARE_WRITE_LINE_MEMBER(irq2_out)191 DECLARE_WRITE_LINE_MEMBER(irq2_out) { m_dio_dev->set_irq(m_index, 1, state); } DECLARE_WRITE_LINE_MEMBER(irq3_out)192 DECLARE_WRITE_LINE_MEMBER(irq3_out) { m_dio_dev->set_irq(m_index, 2, state); } DECLARE_WRITE_LINE_MEMBER(irq4_out)193 DECLARE_WRITE_LINE_MEMBER(irq4_out) { m_dio_dev->set_irq(m_index, 3, state); } DECLARE_WRITE_LINE_MEMBER(irq5_out)194 DECLARE_WRITE_LINE_MEMBER(irq5_out) { m_dio_dev->set_irq(m_index, 4, state); } DECLARE_WRITE_LINE_MEMBER(irq6_out)195 DECLARE_WRITE_LINE_MEMBER(irq6_out) { m_dio_dev->set_irq(m_index, 5, state); } DECLARE_WRITE_LINE_MEMBER(irq7_out)196 DECLARE_WRITE_LINE_MEMBER(irq7_out) { m_dio_dev->set_irq(m_index, 6, state); } DECLARE_WRITE_LINE_MEMBER(dmar0_out)197 DECLARE_WRITE_LINE_MEMBER(dmar0_out) { m_dio_dev->set_dmar(m_index, 0, state); } DECLARE_WRITE_LINE_MEMBER(dmar1_out)198 DECLARE_WRITE_LINE_MEMBER(dmar1_out) { m_dio_dev->set_dmar(m_index, 1, state); } 199 DECLARE_WRITE_LINE_MEMBER(irq1_in)200 virtual DECLARE_WRITE_LINE_MEMBER(irq1_in) {} DECLARE_WRITE_LINE_MEMBER(irq2_in)201 virtual DECLARE_WRITE_LINE_MEMBER(irq2_in) {} DECLARE_WRITE_LINE_MEMBER(irq3_in)202 virtual DECLARE_WRITE_LINE_MEMBER(irq3_in) {} DECLARE_WRITE_LINE_MEMBER(irq4_in)203 virtual DECLARE_WRITE_LINE_MEMBER(irq4_in) {} DECLARE_WRITE_LINE_MEMBER(irq5_in)204 virtual DECLARE_WRITE_LINE_MEMBER(irq5_in) {} DECLARE_WRITE_LINE_MEMBER(irq6_in)205 virtual DECLARE_WRITE_LINE_MEMBER(irq6_in) {} DECLARE_WRITE_LINE_MEMBER(irq7_in)206 virtual DECLARE_WRITE_LINE_MEMBER(irq7_in) {} DECLARE_WRITE_LINE_MEMBER(dmar0_in)207 virtual DECLARE_WRITE_LINE_MEMBER(dmar0_in) {} DECLARE_WRITE_LINE_MEMBER(dmar1_in)208 virtual DECLARE_WRITE_LINE_MEMBER(dmar1_in) {} 209 dmack_r_out(int channel)210 virtual uint8_t dmack_r_out(int channel) { return m_dio_dev->dmack_r_out(m_index, channel); } dmack_w_out(int channel,uint8_t data)211 virtual void dmack_w_out(int channel, uint8_t data) { m_dio_dev->dmack_w_out(m_index, channel, data); } dmack_r_in(int channel)212 virtual uint8_t dmack_r_in(int channel) { return 0xff; } dmack_w_in(int channel,uint8_t data)213 virtual void dmack_w_in(int channel, uint8_t data) {} 214 DECLARE_WRITE_LINE_MEMBER(reset_in)215 virtual DECLARE_WRITE_LINE_MEMBER(reset_in) {} 216 dmar0_r()217 bool dmar0_r() const { return m_dio_dev->dmar0_r(); } dmar1_r()218 bool dmar1_r() const { return m_dio_dev->dmar1_r(); } 219 220 dio16_device *m_dio_dev; 221 222 private: 223 void set_bus(dio16_device & bus); 224 device_dio16_card_interface *m_next; 225 unsigned int m_index; 226 }; 227 228 class dio32_device; 229 230 class dio32_slot_device : public dio16_slot_device 231 { 232 public: 233 // construction/destruction 234 template <typename T, typename U> dio32_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,T && dio_tag,U && opts,const char * dflt,bool fixed)235 dio32_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&dio_tag, U &&opts, const char *dflt, bool fixed) : 236 dio32_slot_device(mconfig, tag, owner, clock) 237 { 238 set_dio(std::forward<T>(dio_tag)); 239 option_reset(); 240 opts(*this); 241 set_default_option(dflt); 242 set_fixed(fixed); 243 } 244 dio32_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 245 246 protected: 247 // device-level overrides 248 virtual void device_start() override; 249 }; 250 251 // ======================> dio32_device 252 class dio32_device : public dio16_device 253 { 254 public: 255 // construction/destruction 256 dio32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 257 258 void install16_device(offs_t start, offs_t end, read16_delegate rhandler, write16_delegate whandler); 259 260 protected: 261 // device-level overrides 262 virtual void device_start() override; 263 }; 264 265 // ======================> device_dio32_card_interface 266 267 // class representing interface-specific live dio32 card 268 class device_dio32_card_interface : public device_dio16_card_interface 269 { 270 friend class dio32_device; 271 public: 272 // construction/destruction 273 virtual ~device_dio32_card_interface(); 274 275 protected: 276 device_dio32_card_interface(const machine_config &mconfig, device_t &device); 277 278 virtual void interface_pre_start() override; 279 dio()280 dio32_device &dio() { assert(m_dio_dev); return downcast<dio32_device &>(*m_dio_dev); } 281 }; 282 283 } } // namespace bus::hp_dio 284 285 // device type definition 286 DECLARE_DEVICE_TYPE_NS(DIO16_SLOT, bus::hp_dio, dio16_slot_device) 287 DECLARE_DEVICE_TYPE_NS(DIO32, bus::hp_dio, dio32_device) 288 DECLARE_DEVICE_TYPE_NS(DIO32_SLOT, bus::hp_dio, dio32_slot_device) 289 DECLARE_DEVICE_TYPE_NS(DIO16, bus::hp_dio, dio16_device) 290 291 void dio16_cards(device_slot_interface &device); 292 void dio32_cards(device_slot_interface &device); 293 294 #endif // MAME_BUS_HPDIO_HPDIO_H 295