1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:bataais
4 /******************************************************************************
5 
6 Applied Concepts Great Game Machine (GGM), electronic board game computer.
7 2nd source distribution: Modular Game System (MGS), by Chafitz.
8 
9 Hardware notes:
10 - 6502A 2MHz (unknown XTAL, label "5-80"), SYP6522 VIA
11 - 2KB RAM(4*HM472114AP-2), no ROM on main PCB
12 - 2*74164 shift register, 3*6118P VFD driver
13 - 8-digit 14seg VFD panel (same one as in Speak & Spell)
14 - 5*4 keypad(unlabeled by default), 1-bit sound
15 
16 Games are on separate cartridges, each came with a keypad overlay.
17 There were also some standalone machines, eg. Morphy Encore, Odin Encore.
18 
19 Known chess cartridges (*denotes not dumped):
20 - Chess/Boris 2.5 (aka Sargon 2.5)
21 - *Gruenfeld Edition - Master Chess Openings
22 - *Morphy Edition - Master Chess
23 - Capablanca Edition - Master Chess Endgame
24 - Sandy Edition - Master Chess (German language version of Morphy)
25 - Steinitz Edition-4 - Master Chess
26 - *Monitor Edition - Master Kriegspiel
27 
28 The opening/endgame cartridges are meant to be ejected/inserted while
29 playing (put the power switch in "MEM" first).
30 
31 Other games:
32 - *Borchek Edition - Master Checkers
33 - *Odin Edition - Master Reversi
34 - *Las Vegas 21
35 - *Wits End (unreleased?)
36 - *Lunar Lander (unreleased?)
37 
38 TODO:
39 - what's VIA PB0 for? game toggles it once per irq
40 - identify XTAL (2MHz CPU/VIA is correct, compared to video reference)
41 - confirm display AP segment, is it used anywhere?
42 - verify cartridge pinout, right now assume A0-A15 (max known cart size is 24KB).
43   Boris/Sargon cartridge is A0-A11 and 2 CS lines, Steinitz uses the whole range.
44 
45 ******************************************************************************/
46 
47 #include "emu.h"
48 #include "cpu/m6502/m6502.h"
49 #include "machine/6522via.h"
50 #include "machine/nvram.h"
51 #include "machine/timer.h"
52 #include "video/pwm.h"
53 #include "sound/dac.h"
54 #include "bus/generic/slot.h"
55 #include "bus/generic/carts.h"
56 
57 #include "speaker.h"
58 #include "softlist.h"
59 
60 // internal artwork
61 #include "aci_ggm.lh" // clickable
62 
63 
64 namespace {
65 
66 class ggm_state : public driver_device
67 {
68 public:
ggm_state(const machine_config & mconfig,device_type type,const char * tag)69 	ggm_state(const machine_config &mconfig, device_type type, const char *tag) :
70 		driver_device(mconfig, type, tag),
71 		m_maincpu(*this, "maincpu"),
72 		m_via(*this, "via"),
73 		m_display(*this, "display"),
74 		m_dac(*this, "dac"),
75 		m_cart(*this, "cartslot"),
76 		m_ca1_off(*this, "ca1_off"),
77 		m_inputs(*this, "IN.%u", 0)
78 	{ }
79 
80 	void ggm(machine_config &config);
81 
DECLARE_INPUT_CHANGED_MEMBER(reset_switch)82 	DECLARE_INPUT_CHANGED_MEMBER(reset_switch) { update_reset(newval); }
DECLARE_CUSTOM_INPUT_MEMBER(overlay_r)83 	DECLARE_CUSTOM_INPUT_MEMBER(overlay_r) { u8 data = m_inputs[5]->read(); return (data == 0xf) ? m_overlay : data; }
84 
85 protected:
86 	virtual void machine_start() override;
87 	virtual void machine_reset() override;
88 
89 private:
90 	// devices/pointers
91 	required_device<cpu_device> m_maincpu;
92 	required_device<via6522_device> m_via;
93 	required_device<pwm_display_device> m_display;
94 	required_device<dac_bit_interface> m_dac;
95 	required_device<generic_slot_device> m_cart;
96 	required_device<timer_device> m_ca1_off;
97 	required_ioport_array<4+3> m_inputs;
98 
99 	void main_map(address_map &map);
100 
101 	void update_reset(ioport_value state);
102 	void update_display();
TIMER_DEVICE_CALLBACK_MEMBER(ca1_off)103 	TIMER_DEVICE_CALLBACK_MEMBER(ca1_off) { m_via->write_ca1(0); }
104 
105 	DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cartridge);
106 	u8 cartridge_r(offs_t offset);
107 
108 	void select_w(u8 data);
109 	void control_w(u8 data);
110 	u8 input_r();
111 
112 	void shift_clock_w(int state);
113 	void shift_data_w(int state);
114 
115 	u8 m_inp_mux = 0;
116 	u16 m_digit_data = 0;
117 	u8 m_shift_data = 0;
118 	u8 m_shift_clock = 0;
119 
120 	u32 m_cart_mask = 0;
121 	u8 m_overlay = 0;
122 };
123 
machine_start()124 void ggm_state::machine_start()
125 {
126 	// register for savestates
127 	save_item(NAME(m_inp_mux));
128 	save_item(NAME(m_digit_data));
129 	save_item(NAME(m_shift_data));
130 	save_item(NAME(m_shift_clock));
131 }
132 
machine_reset()133 void ggm_state::machine_reset()
134 {
135 	// it determines whether it's a cold boot or warm boot ("MEM" switch), with CA1
136 	if (~m_inputs[4]->read() & 2)
137 	{
138 		m_via->write_ca1(1);
139 		m_ca1_off->adjust(attotime::from_msec(10));
140 	}
141 	else
142 		update_reset(1);
143 }
144 
update_reset(ioport_value state)145 void ggm_state::update_reset(ioport_value state)
146 {
147 	// assume that the MEM switch puts the system in reset state (just like Boris)
148 	m_maincpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE);
149 
150 	if (state)
151 	{
152 		m_via->reset();
153 		m_display->clear();
154 	}
155 }
156 
157 
158 
159 /******************************************************************************
160     I/O
161 ******************************************************************************/
162 
163 // cartridge
164 
DEVICE_IMAGE_LOAD_MEMBER(ggm_state::cartridge)165 DEVICE_IMAGE_LOAD_MEMBER(ggm_state::cartridge)
166 {
167 	u32 size = m_cart->common_get_size("rom");
168 	m_cart_mask = ((1 << (31 - count_leading_zeros(size))) - 1) & 0xffff;
169 
170 	m_cart->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
171 	m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom");
172 
173 	// keypad overlay
174 	const char *overlay = image.get_feature("overlay");
175 	m_overlay = overlay ? strtoul(overlay, nullptr, 0) & 0xf : 0;
176 
177 	// extra ram (optional)
178 	if (image.get_feature("ram"))
179 		m_maincpu->space(AS_PROGRAM).install_ram(0x0800, 0x0fff, nullptr);
180 
181 	return image_init_result::PASS;
182 }
183 
cartridge_r(offs_t offset)184 u8 ggm_state::cartridge_r(offs_t offset)
185 {
186 	return m_cart->read_rom(offset & m_cart_mask);
187 }
188 
189 
190 // 6522 ports
191 
update_display()192 void ggm_state::update_display()
193 {
194 	u16 data = bitswap<16>(m_digit_data,15,7,2,11,10,3,1,9,6,14,12,5,0,4,13,8);
195 	m_display->matrix(m_inp_mux, data);
196 }
197 
shift_clock_w(int state)198 void ggm_state::shift_clock_w(int state)
199 {
200 	// shift display segment data on rising edge
201 	if (state && !m_shift_clock)
202 	{
203 		m_digit_data = m_digit_data << 1 | (m_shift_data & 1);
204 		update_display();
205 	}
206 
207 	m_shift_clock = state;
208 }
209 
shift_data_w(int state)210 void ggm_state::shift_data_w(int state)
211 {
212 	m_shift_data = state;
213 }
214 
select_w(u8 data)215 void ggm_state::select_w(u8 data)
216 {
217 	// PA0-PA7: input mux, digit select
218 	m_inp_mux = data;
219 	update_display();
220 }
221 
control_w(u8 data)222 void ggm_state::control_w(u8 data)
223 {
224 	// PB0: ?
225 
226 	// PB7: speaker out
227 	m_dac->write(BIT(data, 7));
228 }
229 
input_r()230 u8 ggm_state::input_r()
231 {
232 	u8 data = 0;
233 
234 	// PB1-PB5: multiplexed inputs
235 	for (int i = 0; i < 4; i++)
236 		if (BIT(m_inp_mux, i))
237 			data |= m_inputs[i]->read();
238 
239 	data = ~data << 1 & 0x3e;
240 
241 	// PB6: hardware version
242 	return 0x81 | data | (m_inputs[4]->read() << 6 & 0x40);
243 }
244 
245 
246 
247 /******************************************************************************
248     Address Maps
249 ******************************************************************************/
250 
main_map(address_map & map)251 void ggm_state::main_map(address_map &map)
252 {
253 	// external slot has potential bus conflict with RAM/VIA
254 	map(0x0000, 0xffff).r(FUNC(ggm_state::cartridge_r));
255 	map(0x0000, 0x07ff).ram().share("nvram");
256 	map(0x8000, 0x800f).m(m_via, FUNC(via6522_device::map));
257 }
258 
259 
260 
261 /******************************************************************************
262     Input Ports
263 ******************************************************************************/
264 
265 #define OVERLAY(val) \
266 	PORT_CONDITION("IN.6", 0x0f, EQUALS, val)
267 
268 static INPUT_PORTS_START( overlay_boris ) // actually most of the Chess games have a similar overlay
269 	PORT_MODIFY("IN.0")
PORT_CODE(KEYCODE_0)270 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
271 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("A.1 / Pawn")
272 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("B.2 / Knight")
273 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("C.3 / Bishop")
274 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("D.4 / Rook")
275 
276 	PORT_MODIFY("IN.1")
277 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("E.5 / Queen")
278 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("F.6 / King")
279 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("G.7")
280 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("H.8")
281 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
282 
283 	PORT_MODIFY("IN.2")
284 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_SPACE) PORT_CODE(KEYCODE_MINUS) PORT_NAME("-")
285 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_W) PORT_NAME("B/W")
286 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_K) PORT_NAME("Rank")
287 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_T) PORT_NAME("Time")
288 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CE")
289 
290 	PORT_MODIFY("IN.3")
291 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_L) PORT_NAME("Level")
292 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_I) PORT_NAME("Halt / Hint")
293 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_S) PORT_NAME("Best")
294 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_R) PORT_NAME("Restore")
295 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
296 INPUT_PORTS_END
297 
298 static INPUT_PORTS_START( overlay_morphy ) // only changed "9" to "Audio"
299 	PORT_MODIFY("IN.0")
300 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
301 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("A.1 / Pawn")
302 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("B.2 / Knight")
303 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("C.3 / Bishop")
304 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("D.4 / Rook")
305 
306 	PORT_MODIFY("IN.1")
307 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("E.5 / Queen")
308 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("F.6 / King")
309 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("G.7")
310 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("H.8")
311 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_U) PORT_NAME("Audio")
312 
313 	PORT_MODIFY("IN.2")
314 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_SPACE) PORT_CODE(KEYCODE_MINUS) PORT_NAME("-")
315 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_W) PORT_NAME("B/W")
316 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_K) PORT_NAME("Rank")
317 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_T) PORT_NAME("Time")
318 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CE")
319 
320 	PORT_MODIFY("IN.3")
321 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_L) PORT_NAME("Level")
322 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_I) PORT_NAME("Halt / Hint")
323 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_S) PORT_NAME("Best")
324 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_R) PORT_NAME("Restore")
325 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x02) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
326 INPUT_PORTS_END
327 
328 static INPUT_PORTS_START( overlay_steinitz )
329 	PORT_MODIFY("IN.0")
330 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_Y) PORT_NAME("Display / 0")
331 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("A.1 / Pawn")
332 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("B.2 / Knight")
333 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("C.3 / Bishop")
334 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("D.4 / Rook")
335 
336 	PORT_MODIFY("IN.1")
337 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("E.5 / Queen")
338 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("F.6 / King")
339 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("G.7")
340 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("H.8")
341 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_U) PORT_NAME("Audio / 9")
342 
343 	PORT_MODIFY("IN.2")
344 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_V) PORT_CODE(KEYCODE_LEFT) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Review / Left / Right")
345 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_W) PORT_NAME("B/W")
346 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_K) PORT_NAME("Rank")
347 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_T) PORT_NAME("Time / Change")
348 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CE")
349 
350 	PORT_MODIFY("IN.3")
351 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_L) PORT_NAME("Level")
352 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_I) PORT_NAME("Halt / Hint / Look")
353 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_S) PORT_NAME("Best / Score")
354 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_R) PORT_NAME("Restore / Timing")
355 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x03) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
356 INPUT_PORTS_END
357 
358 static INPUT_PORTS_START( ggm )
359 	PORT_START("IN.0")
360 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_X) PORT_NAME("Keypad 4-2")
361 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_S) PORT_NAME("Keypad 3-2")
362 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_D) PORT_NAME("Keypad 3-3")
363 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_F) PORT_NAME("Keypad 3-4")
364 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_W) PORT_NAME("Keypad 2-2")
365 
366 	PORT_START("IN.1")
367 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_E) PORT_NAME("Keypad 2-3")
368 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_R) PORT_NAME("Keypad 2-4")
369 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_2) PORT_NAME("Keypad 1-2")
370 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_3) PORT_NAME("Keypad 1-3")
371 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_4) PORT_NAME("Keypad 1-4")
372 
373 	PORT_START("IN.2")
374 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_C) PORT_NAME("Keypad 4-3")
375 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_V) PORT_NAME("Keypad 4-4")
376 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_G) PORT_NAME("Keypad 3-5")
377 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_T) PORT_NAME("Keypad 2-5")
378 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_5) PORT_NAME("Keypad 1-5")
379 
380 	PORT_START("IN.3")
381 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_Z) PORT_NAME("Keypad 4-1")
382 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_Q) PORT_NAME("Keypad 2-1")
383 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_A) PORT_NAME("Keypad 3-1")
384 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_1) PORT_NAME("Keypad 1-1")
385 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_B) PORT_NAME("Keypad 4-5")
386 
387 	PORT_INCLUDE( overlay_boris )
388 	PORT_INCLUDE( overlay_morphy )
389 	PORT_INCLUDE( overlay_steinitz )
390 
391 	PORT_START("IN.4")
392 	PORT_CONFNAME( 0x01, 0x00, "Version" ) // factory-set
393 	PORT_CONFSETTING(    0x00, "GGS (Applied Concepts)" )
394 	PORT_CONFSETTING(    0x01, "MGS (Chafitz)" )
395 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, ggm_state, reset_switch, 0) PORT_NAME("Memory Switch")
396 
397 	PORT_START("IN.5")
398 	PORT_CONFNAME( 0x0f, 0x0f, "Keypad Overlay" )
399 	PORT_CONFSETTING(    0x00, "None" )
400 	PORT_CONFSETTING(    0x0f, "Auto" ) // get param from softwarelist
401 	PORT_CONFSETTING(    0x01, "Boris 2.5" )
402 	PORT_CONFSETTING(    0x02, "Morphy" )
403 	PORT_CONFSETTING(    0x03, "Steinitz" )
404 
405 	PORT_START("IN.6")
406 	PORT_BIT(0x0f, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_CUSTOM_MEMBER(ggm_state, overlay_r)
407 INPUT_PORTS_END
408 
409 
410 
411 /******************************************************************************
412     Machine Configs
413 ******************************************************************************/
414 
415 void ggm_state::ggm(machine_config &config)
416 {
417 	/* basic machine hardware */
418 	M6502(config, m_maincpu, 2000000);
419 	m_maincpu->set_addrmap(AS_PROGRAM, &ggm_state::main_map);
420 
421 	VIA6522(config, m_via, 2000000); // DDRA = 0xff, DDRB = 0x81
422 	m_via->writepa_handler().set(FUNC(ggm_state::select_w));
423 	m_via->writepb_handler().set(FUNC(ggm_state::control_w));
424 	m_via->readpb_handler().set(FUNC(ggm_state::input_r));
425 	m_via->irq_handler().set_inputline(m_maincpu, M6502_IRQ_LINE);
426 	m_via->cb1_handler().set(FUNC(ggm_state::shift_clock_w));
427 	m_via->cb2_handler().set(FUNC(ggm_state::shift_data_w));
428 	TIMER(config, m_ca1_off).configure_generic(FUNC(ggm_state::ca1_off));
429 
430 	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
431 
432 	/* video hardware */
433 	PWM_DISPLAY(config, m_display).set_size(8, 16);
434 	m_display->set_segmask(0xff, 0x3fff);
435 	m_display->set_bri_levels(0.05);
436 	config.set_default_layout(layout_aci_ggm);
437 
438 	/* sound hardware */
439 	SPEAKER(config, "speaker").front_center();
440 	DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
441 
442 	/* cartridge */
443 	GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "ggm");
444 	m_cart->set_device_load(FUNC(ggm_state::cartridge));
445 	m_cart->set_must_be_loaded(true);
446 
447 	SOFTWARE_LIST(config, "cart_list").set_original("ggm");
448 }
449 
450 
451 
452 /******************************************************************************
453     ROM Definitions
454 ******************************************************************************/
455 
456 ROM_START( ggm )
457 	ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 )
458 	// nothing here, ROM is on cartridge
459 ROM_END
460 
461 } // anonymous namespace
462 
463 
464 
465 /******************************************************************************
466     Drivers
467 ******************************************************************************/
468 
469 //    YEAR  NAME  PARENT CMP MACHINE INPUT CLASS      INIT        COMPANY, FULLNAME, FLAGS
470 CONS( 1980, ggm,  0,      0, ggm,    ggm,  ggm_state, empty_init, "Applied Concepts", "Great Game Machine", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
471