1 // license:LGPL-2.1+ 2 // copyright-holders:Michael Zapf 3 /**************************************************************************** 4 5 Geneve main board components. 6 See genboard.c for documentation. 7 8 Michael Zapf 9 10 February 2012: Rewritten as class 11 12 *****************************************************************************/ 13 #ifndef MAME_BUS_TI99_INTERNAL_GENBOARD_H 14 #define MAME_BUS_TI99_INTERNAL_GENBOARD_H 15 16 #pragma once 17 18 #include "bus/ti99/peb/peribox.h" 19 #include "video/v9938.h" 20 #include "cpu/tms9900/tms9995.h" 21 #include "sound/sn76496.h" 22 #include "machine/mm58274c.h" 23 #include "machine/at29x.h" 24 #include "machine/ram.h" 25 #include "bus/pc_kbd/pc_kbdc.h" 26 27 enum 28 { 29 GENEVE_GM_TURBO = 1, 30 GENEVE_GM_TIM = 2 31 }; 32 33 enum 34 { 35 GENEVE_EPROM = 0, 36 GENEVE_PFM512, 37 GENEVE_PFM512A 38 }; 39 40 #define GENEVE_GATE_ARRAY_TAG "gatearray" 41 #define GENMOD_DECODER_TAG "genmod" 42 #define GENEVE_PAL_TAG "pal" 43 #define GENEVE_MOUSE_TAG "gmouse" 44 #define GENEVE_PFM512_TAG "pfm512" 45 #define GENEVE_PFM512A_TAG "pfm512a" 46 #define GENEVE_KEYBOARD_CONN_TAG "keybconn" 47 48 namespace bus { namespace ti99 { namespace internal { 49 50 /*****************************************************************************/ 51 52 class geneve_pal_device; 53 class genmod_decoder_device; 54 55 class geneve_gate_array_device : public device_t 56 { 57 // friend class genmod_decoder_device; 58 59 public: 60 geneve_gate_array_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 61 62 // Set the internal state and output lines according to the address 63 void setaddress(offs_t offset, uint8_t busctrl); 64 65 // Access to Gate Array-internal registers. Depends on the previous 66 // call of setaddress 67 // - Mapper 68 // - Keyboard 69 // - Grom address counter 70 // - Cartridge bank switch 71 void readz(uint8_t& value); 72 void write(uint8_t data); 73 74 // Inputs 75 DECLARE_WRITE_LINE_MEMBER( clock_in ); 76 DECLARE_WRITE_LINE_MEMBER( dbin_in ); 77 DECLARE_WRITE_LINE_MEMBER( extready_in ); 78 DECLARE_WRITE_LINE_MEMBER( sndready_in ); 79 void cru_sstep_write(offs_t offset, uint8_t data); 80 void cru_ctrl_write(offs_t offset, uint8_t data); 81 82 // Outputs 83 DECLARE_READ_LINE_MEMBER( csr_out ); 84 DECLARE_READ_LINE_MEMBER( csw_out ); 85 DECLARE_READ_LINE_MEMBER( rtcen_out ); 86 DECLARE_READ_LINE_MEMBER( romen_out ); 87 DECLARE_READ_LINE_MEMBER( ramen_out ); 88 DECLARE_READ_LINE_MEMBER( ramenx_out ); 89 DECLARE_READ_LINE_MEMBER( snden_out ); 90 DECLARE_READ_LINE_MEMBER( dben_out ); 91 DECLARE_READ_LINE_MEMBER( gaready_out ); 92 93 int get_prefix(int lines); 94 bool accessing_dram(); 95 static bool accessing_dram_s(int function); 96 static bool accessing_sram_s(int function); 97 static bool accessing_box_s(int function, bool genmod); 98 static bool accessing_devs_s(int function); 99 100 bool accessing_grom(); 101 offs_t get_dram_address(); 102 103 // Keyboard support 104 DECLARE_WRITE_LINE_MEMBER( set_keyboard_clock ); 105 DECLARE_WRITE_LINE_MEMBER( enable_shift_register ); 106 DECLARE_WRITE_LINE_MEMBER( kbdclk ); 107 DECLARE_WRITE_LINE_MEMBER( kbddata ); kbdint_cb()108 auto kbdint_cb() { return m_keyint.bind(); } 109 110 // Miscellaneous set_debug(bool deb)111 void set_debug(bool deb) { m_debug = deb; } geneve_mode()112 bool geneve_mode() { return m_geneve_mode; } get_function()113 int get_function() { return m_debug? m_decdebug.function : m_decoded.function; } 114 115 private: 116 geneve_gate_array_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); 117 void common_reset(); 118 119 // Mapper function 120 typedef struct 121 { 122 bool read; // Reading 123 int function; // must be a fundamental type to be saveable 124 offs_t offset; // Logical address 125 int physpage; // Physical page 126 } decdata; 127 128 // Functions 129 void decode_logical(decdata* dec); 130 void get_page(decdata* dec); 131 void decode_physical(decdata* dec); 132 133 /* 134 Constants for mapper decoding. Naming scheme: 135 M=Mapper, L=Logical space; P=Physical space 136 */ 137 typedef enum 138 { 139 MUNDEF=0, 140 141 MLVIDEO, 142 MLMAPPER, 143 MLKEY, 144 MLSOUND, 145 MLCLOCK, 146 MLEXT, 147 MLGROM, 148 MLGROMAD, 149 MLCARTROM, 150 MLCARTBANK, 151 152 MPDRAM, 153 MPEXP, 154 MPEPROM, 155 MPSRAM, 156 MPSRAMX, 157 MBOX, 158 159 CARTPROT 160 161 } decfunct_t; 162 163 void device_start() override; 164 virtual void device_reset() override; 165 166 // Wait state creation 167 bool m_have_waitstate; 168 bool m_have_extra_waitstate; 169 bool m_enable_extra_waitstates; 170 bool m_extready; 171 bool m_sndready; 172 173 // Cartridge and GROM support 174 int m_grom_address; 175 bool m_cartridge_banked; 176 bool m_cartridge_secondpage; 177 bool m_cartridge6_writable; 178 bool m_cartridge7_writable; 179 bool m_load_lsb; 180 void increase_grom_address(); 181 182 // Global modes 183 bool m_geneve_mode; 184 bool m_direct_mode; 185 186 // Mapper file 187 int m_map[8]; 188 189 // The result of decoding 190 decdata m_decoded; 191 decdata m_decdebug; 192 193 // ====== Decoding ============ 194 195 // Static decoder entry for the logical space 196 // Not all entries apply for native mode, e.g. there is no GROM in native 197 // mode. In that case the base and mask are 0000, and the entry must be 198 // skipped. Speech is accessible in the physical space in native mode. 199 // All entries have a wait state count of 1. 200 typedef struct 201 { 202 offs_t genbase; // Base address in native mode 203 int genmask; // Bits that also match this entry 204 offs_t tibase; // Base address in TI mode 205 int timask; // Bits that also match this entry 206 int writeoff; // Additional offset in TI mode for writing 207 decfunct_t function; // Decoded function 208 const char* description; // Good for logging 209 } logentry_t; 210 211 // Static decoder entry for the physical space 212 // There are no differences between native mode and TI mode. 213 typedef struct 214 { 215 offs_t base; // Base page 216 int mask; // Bits that also match this entry 217 decfunct_t function; // Decoded function 218 const char* description; // Good for logging 219 } physentry_t; 220 221 // Tables 222 static const geneve_gate_array_device::logentry_t s_logmap[]; 223 static const geneve_gate_array_device::physentry_t s_physmap[]; 224 225 // Keyboard support 226 devcb_write_line m_keyint; 227 uint16_t m_keyboard_shift_reg; 228 line_state m_keyboard_last_clock; 229 line_state m_keyboard_data_in; 230 bool m_shift_reg_enabled; 231 void shift_reg_changed(); 232 233 // Devices 234 required_device<geneve_pal_device> m_pal; 235 required_device<bus::ti99::peb::peribox_device> m_peribox; 236 required_device<pc_kbdc_device> m_keyb_conn; 237 238 // Emulation-specific: Is the debugger active? 239 bool m_debug; 240 }; 241 242 /*****************************************************************************/ 243 244 /* 245 PAL circuit, controlling the READY line to the CPU and MEMEN/WE 246 to the peribox 247 */ 248 249 class geneve_pal_device : public device_t 250 { 251 public: 252 geneve_pal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 253 254 DECLARE_WRITE_LINE_MEMBER( gaready_in ); 255 DECLARE_WRITE_LINE_MEMBER( csw_in ); 256 DECLARE_WRITE_LINE_MEMBER( csr_in ); 257 DECLARE_WRITE_LINE_MEMBER( memen ); 258 DECLARE_WRITE_LINE_MEMBER( vwaiten ); // pin 19 259 DECLARE_WRITE_LINE_MEMBER( sysspeed ); // pin 5 260 DECLARE_WRITE_LINE_MEMBER( clock_in ); 261 ready_cb()262 auto ready_cb() { return m_ready.bind(); } 263 264 private: 265 void device_start() override; 266 void set_ready(); 267 268 // Pins 269 bool m_pin3; 270 bool m_pin4; 271 bool m_pin5; 272 bool m_pin9; 273 bool m_pin19; 274 bool m_pin14d,m_pin14q; 275 bool m_pin15d,m_pin15q; 276 bool m_pin16d,m_pin16q; 277 bool m_pin17d,m_pin17q; 278 279 // Debugging 280 int m_prev_ready; 281 282 required_device<bus::ti99::peb::peribox_device> m_peribox; 283 284 // Ready line to the CPU 285 devcb_write_line m_ready; 286 }; 287 288 class genmod_decoder_device : public device_t 289 { 290 public: 291 genmod_decoder_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 292 293 // Set the internal state and output lines according to the address 294 void set_function(int func, int page); set_debug(bool deb)295 void set_debug(bool deb) { m_debug = deb; } set_turbo(bool turbo)296 void set_turbo(bool turbo) { m_turbo = turbo; } set_timode(bool timode)297 void set_timode(bool timode) { m_timode = timode; } 298 299 DECLARE_READ_LINE_MEMBER( gaready_out ); 300 DECLARE_READ_LINE_MEMBER( dben_out ); 301 DECLARE_WRITE_LINE_MEMBER( gaready_in ); 302 DECLARE_WRITE_LINE_MEMBER( extready_in ); 303 DECLARE_WRITE_LINE_MEMBER( sndready_in ); 304 305 private: 306 void device_start() override; 307 308 // Emulation-specific: Is the debugger active? 309 bool m_debug; 310 bool m_turbo; 311 bool m_timode; 312 int m_function; 313 int m_function_debug; 314 int m_page; 315 int m_page_debug; 316 int m_gaready; 317 int m_extready; 318 int m_sndready; 319 }; 320 321 } } } // end namespace bus::ti99::internal 322 323 DECLARE_DEVICE_TYPE_NS(GENEVE_GATE_ARRAY, bus::ti99::internal, geneve_gate_array_device) 324 DECLARE_DEVICE_TYPE_NS(GENEVE_PAL, bus::ti99::internal, geneve_pal_device) 325 DECLARE_DEVICE_TYPE_NS(GENMOD_DECODER, bus::ti99::internal, genmod_decoder_device) 326 327 #endif // MAME_BUS_TI99_INTERNAL_GENBOARD_H 328