1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
|
// license:LGPL-2.1+
// copyright-holders:Michael Zapf
/****************************************************************************
Geneve main board components.
See genboard.c for documentation.
Michael Zapf
February 2012: Rewritten as class
*****************************************************************************/
#ifndef MAME_BUS_TI99_INTERNAL_GENBOARD_H
#define MAME_BUS_TI99_INTERNAL_GENBOARD_H
#pragma once
#include "bus/ti99/ti99defs.h"
#include "bus/ti99/peb/peribox.h"
#include "video/v9938.h"
#include "cpu/tms9900/tms9995.h"
#include "sound/sn76496.h"
#include "machine/mm58274c.h"
#include "machine/at29x.h"
#include "machine/ram.h"
enum
{
GENEVE_GM_TURBO = 1,
GENEVE_GM_TIM = 2
};
enum
{
GENEVE_EPROM = 0,
GENEVE_PFM512,
GENEVE_PFM512A
};
#define GENEVE_KEYBOARD_TAG "gkeyboard"
#define GENEVE_MAPPER_TAG "gmapper"
#define GENEVE_MOUSE_TAG "gmouse"
#define GENEVE_CLOCK_TAG "mm58274c"
#define GENEVE_PFM512_TAG "pfm512"
#define GENEVE_PFM512A_TAG "pfm512a"
#define GENEVE_SRAM_TAG "sram"
#define GENEVE_DRAM_TAG "dram"
#define GENEVE_SRAM_PAR_TAG ":sram"
#define GENEVE_DRAM_PAR_TAG ":dram"
namespace bus { namespace ti99 { namespace internal {
/*****************************************************************************/
class geneve_keyboard_device : public device_t
{
public:
geneve_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_WRITE_LINE_MEMBER( reset_line );
DECLARE_WRITE_LINE_MEMBER( send_scancodes );
DECLARE_WRITE_LINE_MEMBER( clock_control );
uint8_t get_recent_key();
auto int_cb() { return m_interrupt.bind(); }
protected:
void device_start() override;
void device_reset() override;
ioport_constructor device_input_ports() const override;
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
devcb_write_line m_interrupt; // Keyboard interrupt to console
required_ioport_array<8> m_keys;
private:
static constexpr unsigned KEYQUEUESIZE = 256;
static constexpr unsigned MAXKEYMSGLENGTH = 10;
static constexpr unsigned KEYAUTOREPEATDELAY = 30;
static constexpr unsigned KEYAUTOREPEATRATE = 6;
void post_in_key_queue(int keycode);
void signal_when_key_available();
void poll();
bool m_key_reset;
int m_key_queue_length;
uint8_t m_key_queue[KEYQUEUESIZE];
int m_key_queue_head;
bool m_key_in_buffer;
uint32_t m_key_state_save[4];
bool m_key_numlock_state;
int m_key_ctrl_state;
int m_key_alt_state;
int m_key_real_shift_state;
bool m_key_fake_shift_state;
bool m_key_fake_unshift_state;
int m_key_autorepeat_key;
int m_key_autorepeat_timer;
bool m_keep_keybuf;
bool m_keyboard_clock;
emu_timer* m_timer;
};
/*****************************************************************************/
class geneve_mapper_device : public device_t
{
public:
geneve_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void set_geneve_mode(bool geneve);
void set_direct_mode(bool direct);
void set_cartridge_size(int size);
void set_cartridge_writable(int base, bool write);
void set_video_waitstates(bool wait);
void set_extra_waitstates(bool wait);
uint8_t readm(offs_t offset);
void writem(offs_t offset, uint8_t data);
uint8_t setoffset(offs_t offset);
DECLARE_INPUT_CHANGED_MEMBER( settings_changed );
DECLARE_WRITE_LINE_MEMBER( clock_in );
DECLARE_WRITE_LINE_MEMBER( dbin_in );
// PFM support
DECLARE_WRITE_LINE_MEMBER( pfm_select_lsb );
DECLARE_WRITE_LINE_MEMBER( pfm_select_msb );
DECLARE_WRITE_LINE_MEMBER( pfm_output_enable );
auto ready_cb() { return m_ready.bind(); }
protected:
geneve_mapper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
void device_start() override;
virtual void device_reset() override;
void common_reset();
// GROM simulation
bool m_gromwaddr_LSB;
bool m_gromraddr_LSB;
int m_grom_address;
uint8_t read_grom(offs_t offset);
void write_grom(offs_t offset, uint8_t data);
// wait states
void set_wait(int min);
void set_video_waitcount(int min);
bool m_video_waitstates;
bool m_extra_waitstates;
bool m_ready_asserted;
bool m_read_mode;
bool m_debug_no_ws;
bool m_geneve_mode;
bool m_direct_mode;
int m_cartridge_size;
bool m_cartridge_secondpage;
bool m_cartridge6_writable;
bool m_cartridge7_writable;
int m_map[8];
/*
Constants for mapper decoding. Naming scheme:
M=Mapper, L=Logical space; P=Physical space
*/
typedef enum
{
MUNDEF=0,
MLVIDEO,
MLMAPPER,
MLKEY,
MLSOUND,
MLCLOCK,
MLGROM,
MPDRAM,
MPEXP,
MPEPROM,
MPSRAM,
MBOX
} decfunct_t;
// Mapper function
typedef struct
{
int function; // must be a fundamental type to be saveable
offs_t offset; // Logical address
offs_t physaddr; // Physical address
int wait; // Wait states
} decdata;
// The result of decoding
decdata m_decoded;
// Static decoder entry for the logical space
// Not all entries apply for native mode, e.g. there is no GROM in native
// mode. In that case the base and mask are 0000, and the entry must be
// skipped. Speech is accessible in the physical space in native mode.
// All entries have a wait state count of 1.
typedef struct
{
offs_t genbase; // Base address in native mode
int genmask; // Bits that also match this entry
offs_t tibase; // Base address in TI mode
int timask; // Bits that also match this entry
int writeoff; // Additional offset in TI mode for writing
decfunct_t function; // Decoded function
const char* description; // Good for logging
} logentry_t;
logentry_t m_logmap[7] =
{
{ 0xf100, 0x000e, 0x8800, 0x03fe, 0x0400, MLVIDEO, "video" },
{ 0xf110, 0x0007, 0x8000, 0x0007, 0x0000, MLMAPPER, "mapper" },
{ 0xf118, 0x0007, 0x8008, 0x0007, 0x0000, MLKEY, "keyboard" },
{ 0xf120, 0x000e, 0x8400, 0x03fe, 0x0000, MLSOUND, "sound" },
{ 0xf130, 0x000f, 0x8010, 0x000f, 0x0000, MLCLOCK, "clock" },
{ 0x0000, 0x0000, 0x9000, 0x03fe, 0x0400, MBOX, "speech (in P-Box)" },
{ 0x0000, 0x0000, 0x9800, 0x03fe, 0x0400, MLGROM, "GROM" },
};
// Static decoder entry for the physical space
// There are no differences between native mode and TI mode.
typedef struct
{
offs_t base; // Base address
int mask; // Bits that also match this entry
decfunct_t function; // Decoded function
int wait; // Wait states
const char* description; // Good for logging
} physentry_t;
physentry_t m_physmap[4] =
{
{ 0x000000, 0x07ffff, MPDRAM, 1, "DRAM" },
{ 0x080000, 0x07ffff, MPEXP, 1, "on-board expansion" },
{ 0x1e0000, 0x01ffff, MPEPROM, 0, "EPROM" },
{ 0x180000, 0x07ffff, MPSRAM, 0, "SRAM" }
};
void decode_logical(bool reading, decdata* dec);
void map_address(bool reading, decdata* dec);
void decode_physical(decdata* dec);
// This is the hook for Genmod. The normal Geneve just does nothing here.
virtual void decode_mod(decdata* dec) { };
// PFM mod (0 = none, 1 = AT29C040, 2 = AT29C040A)
uint8_t boot_rom(offs_t offset);
void write_to_pfm(offs_t offset, uint8_t data);
int m_boot_rom;
int m_pfm_bank;
bool m_pfm_output_enable;
int m_pbox_prefix;
// SRAM access
int m_sram_mask;
int m_sram_val;
// Ready line to the CPU
devcb_write_line m_ready;
// Counter for the wait states.
int m_waitcount;
int m_video_waitcount;
// Devices
required_device<mm58274c_device> m_clock;
required_device<tms9995_device> m_cpu;
required_device<at29c040_device> m_pfm512;
required_device<at29c040a_device> m_pfm512a;
required_device<sn76496_base_device> m_sound;
required_device<bus::ti99::internal::geneve_keyboard_device> m_keyboard;
required_device<v9938_device> m_video;
required_device<bus::ti99::peb::peribox_device> m_peribox;
uint8_t* m_eprom;
required_device<ram_device> m_sram;
required_device<ram_device> m_dram;
};
class genmod_mapper_device : public geneve_mapper_device
{
public:
genmod_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void decode_mod(decdata* dec) override;
void device_reset() override;
DECLARE_INPUT_CHANGED_MEMBER( setgm_changed );
private:
// Genmod modifications
bool m_gm_timode;
bool m_turbo;
};
} } } // end namespace bus::ti99::internal
DECLARE_DEVICE_TYPE_NS(GENEVE_KEYBOARD, bus::ti99::internal, geneve_keyboard_device)
DECLARE_DEVICE_TYPE_NS(GENEVE_MAPPER, bus::ti99::internal, geneve_mapper_device)
DECLARE_DEVICE_TYPE_NS(GENMOD_MAPPER, bus::ti99::internal, genmod_mapper_device)
#endif // MAME_BUS_TI99_INTERNAL_GENBOARD_H
|