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