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