1 // license:LGPL-2.1+ 2 // copyright-holders:Michael Zapf 3 /**************************************************************************** 4 5 Peripheral expansion box 6 See peribox.cpp for documentation 7 8 Michael Zapf 9 10 February 2012: Rewritten as class 11 12 *****************************************************************************/ 13 14 #ifndef MAME_BUS_TI99_PEB_PERIBOX_H 15 #define MAME_BUS_TI99_PEB_PERIBOX_H 16 17 #pragma once 18 19 #include "bus/ti99/internal/ioport.h" 20 21 #define TI_PERIBOX_TAG "peb" 22 #define TI99_DSRROM "dsrrom" 23 24 namespace bus { namespace ti99 { namespace peb { 25 26 class peribox_slot_device; 27 class device_ti99_peribox_card_interface; 28 29 /***************************************************************************** 30 The overall Peripheral Expansion Box. 31 ******************************************************************************/ 32 33 class peribox_device : public bus::ti99::internal::ioport_attached_device 34 { 35 friend class peribox_slot_device; 36 public: 37 peribox_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 38 39 // Next eight methods are called from the console 40 void readz(offs_t offset, uint8_t *value) override; 41 void write(offs_t offset, uint8_t data) override; 42 void setaddress_dbin(offs_t offset, int state) override; 43 44 void crureadz(offs_t offset, uint8_t *value) override; 45 void cruwrite(offs_t offset, uint8_t data) override; 46 47 DECLARE_WRITE_LINE_MEMBER(senila); 48 DECLARE_WRITE_LINE_MEMBER(senilb); 49 50 DECLARE_WRITE_LINE_MEMBER( memen_in ) override; 51 DECLARE_WRITE_LINE_MEMBER( msast_in ) override; 52 53 DECLARE_WRITE_LINE_MEMBER( clock_in ) override; 54 DECLARE_WRITE_LINE_MEMBER( reset_in ) override; 55 56 // Part of configuration set_prefix(int prefix)57 void set_prefix(int prefix) { m_address_prefix = prefix; } 58 59 // Callbacks inta_cb()60 auto inta_cb() { return m_slot1_inta.bind(); } intb_cb()61 auto intb_cb() { return m_slot1_intb.bind(); } ready_cb()62 auto ready_cb() { return m_slot1_ready.bind(); } lcp_cb()63 auto lcp_cb() { return m_slot1_lcp.bind(); } 64 65 protected: 66 peribox_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 67 68 virtual void device_start() override; 69 virtual void device_config_complete() override; 70 71 virtual void device_add_mconfig(machine_config &config) override; 72 73 // Next three methods call back the console via slot 1 74 devcb_write_line m_slot1_inta; // INTA line (Box to console) 75 devcb_write_line m_slot1_intb; // INTB line 76 devcb_write_line m_slot1_lcp; // For EVPC with SGCPU only 77 devcb_write_line m_slot1_ready; // READY line (to the datamux) 78 79 void set_slot_loaded(int slot, peribox_slot_device* slotdev); 80 peribox_slot_device *m_slot[9]; // for the sake of simplicity we donate the first two positions (0,1) 81 82 required_device<peribox_slot_device> m_slot2; 83 required_device<peribox_slot_device> m_slot3; 84 required_device<peribox_slot_device> m_slot4; 85 required_device<peribox_slot_device> m_slot5; 86 required_device<peribox_slot_device> m_slot6; 87 required_device<peribox_slot_device> m_slot7; 88 required_device<peribox_slot_device> m_slot8; 89 90 // Propagators for the slot signals. All signals are active low, and 91 // if any one slot asserts the line, the joint line is asserted. 92 void inta_join(int slot, int state); 93 void intb_join(int slot, int state); 94 void lcp_join(int slot, int state); 95 void ready_join(int slot, int state); 96 97 int m_inta_flag; 98 int m_intb_flag; 99 int m_lcp_flag; 100 int m_ready_flag; 101 102 // The TI-99/4(A) Flex Cable Interface (slot 1) pulls up the AMA/AMB/AMC lines to 1/1/1. 103 int m_address_prefix; 104 105 // Most significant address byte strobe. Defined by TI-99/8. 106 bool m_msast; 107 108 // Memory enable. 109 bool m_memen; 110 111 // Configured as a slot device (of the ioport) 112 bool m_ioport_connected; 113 }; 114 115 /************************************************************************ 116 Specific Box compositions 117 ************************************************************************/ 118 119 /* 120 Variation for SGCPU (TI-99/4P). We put the EVPC and the HSGPL in slots 2 and 3. 121 */ 122 class peribox_sg_device : public peribox_device 123 { 124 public: 125 peribox_sg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 126 127 protected: 128 void device_add_mconfig(machine_config &config) override; 129 }; 130 131 /* 132 Variation for ti99_4ev. We put the EVPC in slot 2. 133 */ 134 class peribox_ev_device : public peribox_device 135 { 136 public: 137 peribox_ev_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 138 139 protected: 140 void device_add_mconfig(machine_config &config) override; 141 }; 142 143 144 /* 145 Variation for Geneve. 146 */ 147 class peribox_gen_device : public peribox_device 148 { 149 public: 150 peribox_gen_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 151 152 protected: 153 peribox_gen_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 154 virtual void device_add_mconfig(machine_config &config) override; 155 }; 156 157 /* 158 Variation for Geneve with Genmod 159 */ 160 class peribox_genmod_device : public peribox_gen_device 161 { 162 public: 163 peribox_genmod_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 164 165 protected: 166 void device_add_mconfig(machine_config &config) override; 167 }; 168 169 /***************************************************************************** 170 The parent class for all expansion cards. 171 ******************************************************************************/ 172 173 class device_ti99_peribox_card_interface : public device_interface 174 { 175 friend class peribox_slot_device; 176 177 public: 178 virtual void readz(offs_t offset, uint8_t *value) = 0; 179 virtual void write(offs_t offset, uint8_t data) = 0; 180 virtual void crureadz(offs_t offset, uint8_t *value) = 0; 181 virtual void cruwrite(offs_t offset, uint8_t data) = 0; setaddress_dbin(offs_t offset,int state)182 virtual void setaddress_dbin(offs_t offset, int state) { }; 183 DECLARE_WRITE_LINE_MEMBER(clock_in)184 virtual DECLARE_WRITE_LINE_MEMBER(clock_in) { } DECLARE_WRITE_LINE_MEMBER(reset_in)185 virtual DECLARE_WRITE_LINE_MEMBER(reset_in) { } 186 set_senila(int state)187 void set_senila(int state) { m_senila = state; } set_senilb(int state)188 void set_senilb(int state) { m_senilb = state; } 189 190 protected: 191 device_ti99_peribox_card_interface(const machine_config &mconfig, device_t &device); 192 virtual void interface_config_complete() override; 193 194 peribox_slot_device *m_slot; // using a link to the slot for callbacks 195 int m_senila; 196 int m_senilb; 197 198 // When true, card is accessible. Indicated by a LED. 199 bool m_selected; 200 201 // CRU base. Used to configure the address by which a card is selected. 202 int m_cru_base; 203 204 // Methods to decide whether we are acccessing the 4000-5fff region (DSR) 205 // or the cartridge region 206 static bool in_dsr_space(offs_t offset, bool amadec); 207 static bool in_cart_space(offs_t offset, bool amadec); 208 }; 209 210 /***************************************************************************** 211 A single slot in the box. 212 ******************************************************************************/ 213 214 class peribox_slot_device : public device_t, public device_single_card_slot_interface<device_ti99_peribox_card_interface> 215 { 216 friend class peribox_device; 217 public: 218 template <typename U> peribox_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,int slot,U && opts,const char * dflt)219 peribox_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, int slot, U &&opts, const char *dflt) 220 : peribox_slot_device(mconfig, tag, owner, 0) 221 { 222 option_reset(); 223 opts(*this); 224 set_default_option(dflt); 225 set_fixed(false); 226 m_slotnumber = slot; 227 } 228 229 peribox_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 230 231 // Called from the box (direction to card) 232 void readz(offs_t offset, uint8_t *value); 233 void write(offs_t offset, uint8_t data); 234 void setaddress_dbin(offs_t offset, int state); 235 236 DECLARE_WRITE_LINE_MEMBER(senila); 237 DECLARE_WRITE_LINE_MEMBER(senilb); 238 DECLARE_WRITE_LINE_MEMBER(clock_in); 239 DECLARE_WRITE_LINE_MEMBER(reset_in); 240 241 // Called from the card (direction to box) 242 DECLARE_WRITE_LINE_MEMBER( set_inta ); 243 DECLARE_WRITE_LINE_MEMBER( set_intb ); 244 DECLARE_WRITE_LINE_MEMBER( lcp_line ); 245 DECLARE_WRITE_LINE_MEMBER( set_ready ); 246 247 void crureadz(offs_t offset, uint8_t *value); 248 void cruwrite(offs_t offset, uint8_t data); 249 250 // called from the box itself set_number(int number)251 void set_number(int number) { m_slotnumber = number; } 252 253 protected: 254 void device_start() override; 255 void device_config_complete() override; 256 257 private: 258 int get_index_from_tagname(); 259 device_ti99_peribox_card_interface *m_card; 260 int m_slotnumber; card_name()261 const char* card_name() { return m_card->device().tag(); } 262 }; 263 264 } } } // end namespace bus::ti99::peb 265 266 DECLARE_DEVICE_TYPE_NS(TI99_PERIBOX, bus::ti99::peb, peribox_device) 267 DECLARE_DEVICE_TYPE_NS(TI99_PERIBOX_EV, bus::ti99::peb, peribox_ev_device) 268 DECLARE_DEVICE_TYPE_NS(TI99_PERIBOX_SLOT, bus::ti99::peb, peribox_slot_device) 269 DECLARE_DEVICE_TYPE_NS(TI99_PERIBOX_SG, bus::ti99::peb, peribox_sg_device) 270 DECLARE_DEVICE_TYPE_NS(TI99_PERIBOX_GEN, bus::ti99::peb, peribox_gen_device) 271 DECLARE_DEVICE_TYPE_NS(TI99_PERIBOX_GENMOD, bus::ti99::peb, peribox_genmod_device) 272 273 void ti99_peribox_slot_standard(device_slot_interface &device); 274 void ti99_peribox_slot_evpc(device_slot_interface &device); 275 void ti99_peribox_slot_geneve(device_slot_interface &device); 276 void ti99_peribox_slot_sgcpu(device_slot_interface &device); 277 278 #endif // MAME_BUS_TI99_PEB_PERIBOX_H 279