1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:Berger, yoyo_chessboard
4 /******************************************************************************
5
6 Fidelity 68000-based Elite Avant Garde driver
7 For 6502-based EAG, see fidel_elite.cpp
8
9 Excel 68000 I/O is very similar to EAG, so it's handled in this driver as well
10
11 TODO:
12 - unemulated waitstates with DTACK
13 - EAG USART is not emulated
14 - V10 CPU emulation is too slow, MAME 68040 opcode timing is same as 68030 but in
15 reality it is much faster, same goes for V11 of course (see note below)
16 - V11 CPU should be M68EC060, not yet emulated. Now using M68EC040 in its place
17 - V11 beeper is too high pitched, related to wrong CPU type too?
18 maybe waitstates or clock divider on I/O access.
19
20 Currently(May 2020) when compared to the real chesscomputers, to get closer to the
21 actual speed, overclock V10 and V11 to 230%. This can be done by starting MAME
22 with the -cheat option and going to the Slider Controls menu, hold Ctrl and press
23 Right to overclock maincpu.
24
25 *******************************************************************************
26
27 Excel 68000 (model 6094) overview:
28 - 16KB RAM(2*SRM2264C-10 @ U8/U9), 64KB ROM(2*AT27C256-15DC @ U6/U7)
29 - HD68HC000P12 CPU, 12MHz XTAL
30 - PCB label 510-1129A01
31 - PCB has edge connector for module, but no external slot
32
33 There's room for 2 SIMMs at U22 and U23, unpopulated in Excel 68000 and Mach III.
34 Mach II has 2*64KB DRAM with a MB1422A DRAM controller @ 25MHz.
35 Mach III has wire mods from U22/U23 to U8/U9(2*8KB + 2*32KB piggybacked).
36 Mach IV has 2*256KB DRAM, and a daughterboard(510.1123B01) for the 68020 + 32KB RAM.
37
38 I/O is via TTL, overall very similar to EAG.
39
40 fex68km4 continuously tests RAM at boot and displays "512", this is normal.
41 To start, hold New Game or Clear.
42
43 *******************************************************************************
44
45 Elite Avant Garde (EAG, model 6114)
46 -----------------------------------
47
48 There are 5 versions of model 6114(V1 to V5):
49
50 V1: 128KB DRAM, no EEPROM
51 V2: 128KB DRAM
52 V3: 512KB DRAM
53 V4: 1MB DRAM
54 V5: 128KB+16KB DRAM, dual-CPU! (2*68K @ 16MHz)
55
56 V6-V11 are on model 6117. Older 1986 model 6081/6088/6089 uses a 6502 CPU.
57
58 Hardware info:
59 --------------
60 - MC68HC000P12F 16MHz CPU, 16MHz XTAL
61 - MB1422A DRAM Controller, 25MHz XTAL near, 4 DRAM slots
62 (V2: slot 2 & 3 64KB, V3: slot 2 & 3 256KB)
63 - 2*27C512 64KB EPROM, 2*KM6264AL-10 8KB SRAM, 2*AT28C64X 8KB EEPROM
64 - OKI M82C51A-2 USART, 4.9152MHz XTAL
65 - other special: magnet sensors, external module slot, serial port
66
67 IRQ source is a 4,9152MHz quartz crystal (Y3) connected to a 74HC4060 (U8,
68 ripple counter/divider). From Q13 output (counter=8192) we obtain the IRQ signal
69 applied to IPL1 of 68000 (pin 24) 4,9152 MHz / 8192 = 600 Hz.
70
71 The module slot pinout is different from SCC series. The data on those appears
72 to be compatible with EAG though and will load fine with an adapter.
73
74 The USART allows for a serial connection between the chess computer and another
75 device, for example a PC. Fidelity released a DOS tool called EAGLINK which
76 featured PC printer support, complete I/O control, detailed information while
77 the program is 'thinking', etc.
78
79 Memory map: (of what is known)
80 -----------
81 000000-01FFFF: 128KB ROM
82 104000-107FFF: 16KB SRAM
83 200000-2FFFFF: hashtable DRAM (max. 1MB)
84 300000-30000F W hi d0: NE591: 7seg data
85 300000-30000F W lo d0: NE591: LED data
86 300000-30000F R lo d7: 74259: keypad rows 0-7
87 400000-400007 W lo d0: 74259,74145/7442: led/keypad mux, buzzer out
88 400000-4????? R hi: external module slot
89 700002-700003 R lo d7: 74251: keypad row 8
90 604000-607FFF: 16KB EEPROM
91
92 *******************************************************************************
93
94 Elite Avant Garde (EAG, model 6117)
95 -----------------------------------
96
97 There are 6 versions of model 6117(V6 to V11). From a programmer's point of view,
98 the hardware is very similar to model 6114.
99
100 V6: 68020, 512KB hashtable RAM
101 V7: 68020, 1MB h.RAM
102 V8: 2*68020, 512KB+128KB h.RAM
103 V9: 68030, 1MB h.RAM
104 V10: 68040, 1MB h.RAM
105 V11: 68060, 2MB h.RAM, high speed
106
107 V7 Hardware info:
108 -----------------
109 - MC68020RC25E CPU, 25MHz XTAL - this PCB was overclocked, original was 20MHz so let's use that
110 - 4*AS7C164-20PC 8KB SRAM, 2*KM684000ALG-7L 512KB CMOS SRAM
111 - 2*27C512? 64KB EPROM, 2*HM6264LP-15 8KB SRAM, 2*AT28C64B 8KB EEPROM, 2*GAL16V8C
112 - same as 6114: M82C51A, NE555, SN74HC4060, module slot, chessboard, ..
113
114 V7 Memory map:
115 --------------
116 000000-01FFFF: 128KB ROM
117 104000-107FFF: 16KB SRAM (unused?)
118 200000-2FFFFF: hashtable SRAM
119 300000-30000x: see model 6114
120 400000-40000x: see model 6114
121 700000-70000x: see model 6114
122 604000-607FFF: 16KB EEPROM
123 800000-807FFF: 32KB SRAM
124
125 V10 Hardware info:
126 ------------------
127 - 68040 CPU, 25MHz
128 - other: assume same or very similar to V11(see below)
129
130 The ROM dump came from the V11(see below). Built-in factory test proves
131 that this program is a V10. Hold TB button immediately after power-on and
132 press it for a sequence of tests:
133 1) all LEDs on
134 2) F40C: V10 program version
135 3) 38b9: V10 ROM checksum
136 4) xxxx: external module ROM checksum (0000 if no module present)
137 5) xxxx: user settings (stored in EEPROM)
138 6) xxxx: "
139 7) 1024: hashtable RAM size
140 8) return to game
141
142 V11 Hardware info:
143 ------------------
144 - MC68EC060RC75 CPU, 36MHz XTAL(36MHz bus, 72MHz CPU), CPU cooler required
145 - 4*CXK5863AP-20 8KB SRAM, 4*K6X4008C1F-DF55 512KB CMOS SRAM
146 - 4*M27C256B 32KB EPROM, 2*AT28C64 8KB EEPROM, 5*GAL16V8D
147 - NEC D71051C USART, assume 8MHz, on quick glance it's same as the OKI USART
148 - same as 6114: NE555, SN74HC4060, module slot, chessboard, ..
149
150 This is a custom overclocked V10, manufactured by Wilfried Bucke. PCB is marked:
151 "CHESS HW DESIGN COPYRIGHT 22-10-2002: REVA03 510.1136A01/510.1144B01 COMPONENT SIDE"
152 There are two versions of this, one with a 66MHz CPU, one with a 72MHz CPU.
153 Maybe other differences too?
154
155 V1x Memory map:
156 ---------------
157 000000-01FFFF: 128KB ROM
158 200000-3FFFFF: hashtable SRAM (less on V10?)
159 B0000x-xxxxxx: see V7, -800000
160
161 ******************************************************************************/
162
163 #include "emu.h"
164 #include "cpu/m68000/m68000.h"
165 #include "machine/gen_latch.h"
166 #include "machine/ram.h"
167 #include "machine/nvram.h"
168 #include "machine/timer.h"
169 #include "machine/sensorboard.h"
170 #include "sound/dac.h"
171 #include "video/pwm.h"
172 #include "bus/generic/slot.h"
173 #include "bus/generic/carts.h"
174
175 #include "softlist.h"
176 #include "speaker.h"
177
178 // internal artwork
179 #include "fidel_ex_68k.lh" // clickable
180 #include "fidel_eag_68k.lh" // clickable
181
182
183 namespace {
184
185 // EAG / shared
186
187 class eag_state : public driver_device
188 {
189 public:
eag_state(const machine_config & mconfig,device_type type,const char * tag)190 eag_state(const machine_config &mconfig, device_type type, const char *tag) :
191 driver_device(mconfig, type, tag),
192 m_maincpu(*this, "maincpu"),
193 m_irq_on(*this, "irq_on"),
194 m_ram(*this, "ram"),
195 m_board(*this, "board"),
196 m_display(*this, "display"),
197 m_dac(*this, "dac"),
198 m_inputs(*this, "IN.%u", 0),
199 m_rotate(true)
200 { }
201
202 // machine configs
203 void eagv2(machine_config &config);
204 void eagv3(machine_config &config);
205 void eagv5(machine_config &config);
206 void eagv7(machine_config &config);
207 void eagv9(machine_config &config);
208 void eagv10(machine_config &config);
209 void eagv11(machine_config &config);
210
211 void init_eag();
212
213 protected:
214 virtual void machine_start() override;
215 void eag_base(machine_config &config);
216
217 // devices/pointers
218 required_device<m68000_base_device> m_maincpu;
219 optional_device<timer_device> m_irq_on;
220 optional_device<ram_device> m_ram;
221 required_device<sensorboard_device> m_board;
222 required_device<pwm_display_device> m_display;
223 required_device<dac_bit_interface> m_dac;
224 optional_ioport_array<2> m_inputs;
225
226 // address maps
227 void eag_map(address_map &map);
228 void eagv7_map(address_map &map);
229 void eagv10_map(address_map &map);
230
231 // periodic interrupts
TIMER_DEVICE_CALLBACK_MEMBER(irq_on)232 template<int Line> TIMER_DEVICE_CALLBACK_MEMBER(irq_on) { m_maincpu->set_input_line(Line, ASSERT_LINE); }
TIMER_DEVICE_CALLBACK_MEMBER(irq_off)233 template<int Line> TIMER_DEVICE_CALLBACK_MEMBER(irq_off) { m_maincpu->set_input_line(Line, CLEAR_LINE); }
234
235 // I/O handlers
236 void update_display();
237 virtual void mux_w(offs_t offset, u8 data);
238 u8 input1_r(offs_t offset);
239 u8 input2_r();
240 void leds_w(offs_t offset, u8 data);
241 void digit_w(offs_t offset, u8 data);
242
243 bool m_rotate;
244 u8 m_select = 0;
245 u8 m_7seg_data = 0;
246 u8 m_led_data = 0;
247 };
248
machine_start()249 void eag_state::machine_start()
250 {
251 // register for savestates
252 save_item(NAME(m_select));
253 save_item(NAME(m_7seg_data));
254 save_item(NAME(m_led_data));
255 }
256
257 // EAG V5
258
259 class eagv5_state : public eag_state
260 {
261 public:
eagv5_state(const machine_config & mconfig,device_type type,const char * tag)262 eagv5_state(const machine_config &mconfig, device_type type, const char *tag) :
263 eag_state(mconfig, type, tag),
264 m_subcpu(*this, "subcpu"),
265 m_mainlatch(*this, "mainlatch"),
266 m_sublatch(*this, "sublatch")
267 { }
268
269 // machine configs
270 void eagv5(machine_config &config);
271
272 private:
273 // devices/pointers
274 required_device<cpu_device> m_subcpu;
275 required_device<generic_latch_8_device> m_mainlatch;
276 required_device<generic_latch_8_device> m_sublatch;
277
278 // address maps
279 void main_map(address_map &map);
280 void sub_map(address_map &map);
281
282 // I/O handlers
283 void reset_subcpu_w(u8 data);
284 u8 main_ack_r();
285 u8 sub_ack_r();
286 };
287
288 // Excel 68000
289
290 class excel68k_state : public eag_state
291 {
292 public:
excel68k_state(const machine_config & mconfig,device_type type,const char * tag)293 excel68k_state(const machine_config &mconfig, device_type type, const char *tag) :
294 eag_state(mconfig, type, tag)
295 {
296 m_rotate = false;
297 }
298
299 // machine configs
300 void fex68k(machine_config &config);
301 void fex68km2(machine_config &config);
302 void fex68km3(machine_config &config);
303 void fex68km4(machine_config &config);
304
305 private:
306 // address maps
307 void fex68k_map(address_map &map);
308 void fex68km2_map(address_map &map);
309 void fex68km3_map(address_map &map);
310 void fex68km4_map(address_map &map);
311 };
312
313
314
315 /******************************************************************************
316 I/O
317 ******************************************************************************/
318
319 // TTL/generic
320
update_display()321 void eag_state::update_display()
322 {
323 // Excel 68000: 4*7seg leds, 8*8 chessboard leds
324 // EAG: 8*7seg leds(2 panels), (8+1)*8 chessboard leds
325 u8 seg_data = bitswap<8>(m_7seg_data,0,1,3,2,7,5,6,4);
326 m_display->matrix(1 << m_select, m_led_data << 8 | seg_data);
327 }
328
mux_w(offs_t offset,u8 data)329 void eag_state::mux_w(offs_t offset, u8 data)
330 {
331 // a1-a3,d0: 74259
332 u8 mask = 1 << offset;
333 m_select = (m_select & ~mask) | ((data & 1) ? mask : 0);
334
335 // 74259 Q0-Q3: 74145 A-D (Q4-Q7 N/C)
336 m_select &= 0xf;
337
338 // 74145 0-8: input mux, digit/led select
339 // 74145 9: speaker out
340 m_dac->write(BIT(1 << m_select, 9));
341 update_display();
342 }
343
input1_r(offs_t offset)344 u8 eag_state::input1_r(offs_t offset)
345 {
346 u8 data = 0;
347
348 // a1-a3,d7: multiplexed inputs (active low)
349 // read chessboard sensors
350 if (m_select < 8)
351 {
352 // EAG chessboard is rotated 90 degrees
353 if (m_rotate)
354 data = m_board->read_rank(m_select, true);
355 else
356 data = m_board->read_file(m_select);
357 }
358
359 // read button panel
360 else if (m_select == 8)
361 data = m_inputs[0]->read();
362
363 return (data >> offset & 1) ? 0 : 0x80;
364 }
365
input2_r()366 u8 eag_state::input2_r()
367 {
368 // d7: 3 more buttons on EAG
369 return (BIT(m_inputs[1]->read(), m_select)) ? 0x80 : 0;
370 }
371
leds_w(offs_t offset,u8 data)372 void eag_state::leds_w(offs_t offset, u8 data)
373 {
374 // a1-a3,d0: led data
375 m_led_data = (m_led_data & ~(1 << offset)) | ((data & 1) << offset);
376 update_display();
377 }
378
digit_w(offs_t offset,u8 data)379 void eag_state::digit_w(offs_t offset, u8 data)
380 {
381 // a1-a3,d0(d8): digit segment data
382 m_7seg_data = (m_7seg_data & ~(1 << offset)) | ((data & 1) << offset);
383 update_display();
384 }
385
386
387 // EAG V5
388
reset_subcpu_w(u8 data)389 void eagv5_state::reset_subcpu_w(u8 data)
390 {
391 // reset subcpu, from trigger to monostable 555 (R1=47K, C1=1uF)
392 m_subcpu->pulse_input_line(INPUT_LINE_RESET, attotime::from_msec(52));
393 }
394
main_ack_r()395 u8 eagv5_state::main_ack_r()
396 {
397 // d8,d9: latches ack state
398 return (m_mainlatch->pending_r() << 1 ^ 2) | m_sublatch->pending_r();
399 }
400
sub_ack_r()401 u8 eagv5_state::sub_ack_r()
402 {
403 // d8,d9: latches ack state
404 return (m_sublatch->pending_r() << 1 ^ 2) | m_mainlatch->pending_r();
405 }
406
407
408
409 /******************************************************************************
410 Address Maps
411 ******************************************************************************/
412
413 // Excel 68000
414
fex68k_map(address_map & map)415 void excel68k_state::fex68k_map(address_map &map)
416 {
417 map(0x000000, 0x00ffff).rom();
418 map(0x000000, 0x00000f).mirror(0x00fff0).w(FUNC(excel68k_state::leds_w)).umask16(0x00ff);
419 map(0x000000, 0x00000f).mirror(0x00fff0).w(FUNC(excel68k_state::digit_w)).umask16(0xff00);
420 map(0x044000, 0x047fff).ram();
421 map(0x100000, 0x10000f).mirror(0x03fff0).r(FUNC(excel68k_state::input1_r)).umask16(0x00ff);
422 map(0x140000, 0x14000f).mirror(0x03fff0).w(FUNC(excel68k_state::mux_w)).umask16(0x00ff);
423 }
424
fex68km2_map(address_map & map)425 void excel68k_state::fex68km2_map(address_map &map)
426 {
427 fex68k_map(map);
428 map(0x200000, 0x21ffff).ram();
429 }
430
fex68km3_map(address_map & map)431 void excel68k_state::fex68km3_map(address_map &map)
432 {
433 fex68k_map(map);
434 map(0x200000, 0x20ffff).ram();
435 }
436
fex68km4_map(address_map & map)437 void excel68k_state::fex68km4_map(address_map &map)
438 {
439 map(0x00000000, 0x0000ffff).rom();
440 map(0x00000000, 0x0000000f).mirror(0x00fff0).w(FUNC(excel68k_state::leds_w)).umask32(0x00ff00ff);
441 map(0x00000000, 0x0000000f).mirror(0x00fff0).w(FUNC(excel68k_state::digit_w)).umask32(0xff00ff00);
442 map(0x00044000, 0x00047fff).ram(); // unused?
443 map(0x00100000, 0x0010000f).mirror(0x03fff0).r(FUNC(excel68k_state::input1_r)).umask32(0x00ff00ff);
444 map(0x00140000, 0x0014000f).mirror(0x03fff0).w(FUNC(excel68k_state::mux_w)).umask32(0x00ff00ff);
445 map(0x00200000, 0x0027ffff).ram();
446 map(0x00400000, 0x00407fff).ram();
447 }
448
449
450 // EAG
451
init_eag()452 void eag_state::init_eag()
453 {
454 // eag_map: DRAM slots at $200000-$2fffff - V1/V2/V5: 128K, V3: 512K, V4: 1M
455 m_maincpu->space(AS_PROGRAM).install_ram(0x200000, 0x200000 + m_ram->size() - 1, m_ram->pointer());
456 }
457
eag_map(address_map & map)458 void eag_state::eag_map(address_map &map)
459 {
460 map(0x000000, 0x01ffff).rom();
461 map(0x104000, 0x107fff).ram();
462 map(0x300000, 0x30000f).mirror(0x000010).w(FUNC(eag_state::digit_w)).umask16(0xff00).nopr();
463 map(0x300000, 0x30000f).mirror(0x000010).rw(FUNC(eag_state::input1_r), FUNC(eag_state::leds_w)).umask16(0x00ff);
464 map(0x400000, 0x400007).w(FUNC(eag_state::mux_w)).umask16(0x00ff);
465 map(0x400000, 0x407fff).r("cartslot", FUNC(generic_slot_device::read_rom)).umask16(0xff00);
466 map(0x604000, 0x607fff).ram().share("nvram");
467 map(0x700003, 0x700003).r(FUNC(eag_state::input2_r));
468 }
469
main_map(address_map & map)470 void eagv5_state::main_map(address_map &map)
471 {
472 eag_map(map);
473 map(0x500000, 0x500000).r(m_sublatch, FUNC(generic_latch_8_device::read)).w(m_mainlatch, FUNC(generic_latch_8_device::write));
474 map(0x500002, 0x500002).rw(FUNC(eagv5_state::main_ack_r), FUNC(eagv5_state::reset_subcpu_w));
475 }
476
sub_map(address_map & map)477 void eagv5_state::sub_map(address_map &map)
478 {
479 map(0x000000, 0x00ffff).rom();
480 map(0x000001, 0x000001).mirror(0x00fffe).w(m_sublatch, FUNC(generic_latch_8_device::write));
481 map(0x044000, 0x047fff).ram();
482 map(0x140000, 0x140000).r(FUNC(eagv5_state::sub_ack_r));
483 map(0x140001, 0x140001).r(m_mainlatch, FUNC(generic_latch_8_device::read));
484 }
485
eagv7_map(address_map & map)486 void eag_state::eagv7_map(address_map &map)
487 {
488 map(0x000000, 0x01ffff).rom();
489 map(0x104000, 0x107fff).ram();
490 map(0x200000, 0x2fffff).ram();
491 map(0x300000, 0x30000f).mirror(0x000010).w(FUNC(eag_state::digit_w)).umask32(0xff00ff00).nopr();
492 map(0x300000, 0x30000f).mirror(0x000010).rw(FUNC(eag_state::input1_r), FUNC(eag_state::leds_w)).umask32(0x00ff00ff);
493 map(0x400000, 0x400007).w(FUNC(eag_state::mux_w)).umask32(0x00ff00ff);
494 map(0x400000, 0x407fff).r("cartslot", FUNC(generic_slot_device::read_rom)).umask32(0xff00ff00);
495 map(0x604000, 0x607fff).ram().share("nvram");
496 map(0x700003, 0x700003).r(FUNC(eag_state::input2_r));
497 map(0x800000, 0x807fff).ram();
498 }
499
eagv10_map(address_map & map)500 void eag_state::eagv10_map(address_map &map)
501 {
502 map(0x00000000, 0x0001ffff).rom();
503 map(0x00200000, 0x003fffff).ram();
504 map(0x00b00000, 0x00b0000f).mirror(0x00000010).w(FUNC(eag_state::digit_w)).umask32(0xff00ff00).nopr();
505 map(0x00b00000, 0x00b0000f).mirror(0x00000010).rw(FUNC(eag_state::input1_r), FUNC(eag_state::leds_w)).umask32(0x00ff00ff);
506 map(0x00c00000, 0x00c00007).w(FUNC(eag_state::mux_w)).umask32(0x00ff00ff);
507 map(0x00c00000, 0x00c07fff).r("cartslot", FUNC(generic_slot_device::read_rom)).umask32(0xff00ff00);
508 map(0x00e04000, 0x00e07fff).ram().share("nvram");
509 map(0x00f00003, 0x00f00003).r(FUNC(eag_state::input2_r));
510 map(0x01000000, 0x0101ffff).ram();
511 }
512
513
514
515 /******************************************************************************
516 Input Ports
517 ******************************************************************************/
518
519 static INPUT_PORTS_START( excel68k )
520 PORT_START("IN.0")
PORT_CODE(KEYCODE_DEL)521 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear")
522 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Move / Pawn")
523 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Hint / Knight")
524 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Take Back / Bishop")
525 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Level / Rook")
526 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Options / Queen")
527 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Verify / King")
528 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_N) PORT_NAME("New Game")
529 INPUT_PORTS_END
530
531 static INPUT_PORTS_START( eag )
532 PORT_START("IN.0")
533 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("PB / King")
534 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("PV / Queen")
535 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("TM / Rook")
536 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("ST / Bishop")
537 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("TB / Knight")
538 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("LV / Pawn")
539 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_O) PORT_NAME("Option")
540 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_NAME("RV")
541
542 PORT_START("IN.1")
543 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("CL")
544 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("DM")
545 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_N) PORT_NAME("New Game")
546 INPUT_PORTS_END
547
548
549
550 /******************************************************************************
551 Machine Configs
552 ******************************************************************************/
553
554 void excel68k_state::fex68k(machine_config &config)
555 {
556 /* basic machine hardware */
557 M68000(config, m_maincpu, 12_MHz_XTAL); // HD68HC000P12
558 m_maincpu->set_addrmap(AS_PROGRAM, &excel68k_state::fex68k_map);
559
560 const attotime irq_period = attotime::from_hz(600); // 556 timer (22nF, 91K + 20K POT @ 14.8K, 0.1K), ideal is 600Hz (measured 580Hz, 604Hz, 632Hz)
561 TIMER(config, m_irq_on).configure_periodic(FUNC(excel68k_state::irq_on<M68K_IRQ_2>), irq_period);
562 m_irq_on->set_start_delay(irq_period - attotime::from_nsec(1528)); // active for 1.525us
563 TIMER(config, "irq_off").configure_periodic(FUNC(excel68k_state::irq_off<M68K_IRQ_2>), irq_period);
564
565 SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
566 m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
567 m_board->set_delay(attotime::from_msec(150));
568
569 /* video hardware */
570 PWM_DISPLAY(config, m_display).set_size(8, 16);
571 m_display->set_segmask(0x55, 0x7f);
572 config.set_default_layout(layout_fidel_ex_68k);
573
574 /* sound hardware */
575 SPEAKER(config, "speaker").front_center();
576 DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
577 }
578
fex68km2(machine_config & config)579 void excel68k_state::fex68km2(machine_config &config)
580 {
581 fex68k(config);
582
583 /* basic machine hardware */
584 m_maincpu->set_addrmap(AS_PROGRAM, &excel68k_state::fex68km2_map);
585 }
586
fex68km3(machine_config & config)587 void excel68k_state::fex68km3(machine_config &config)
588 {
589 fex68k(config);
590
591 /* basic machine hardware */
592 m_maincpu->set_clock(16_MHz_XTAL); // factory overclock
593 m_maincpu->set_addrmap(AS_PROGRAM, &excel68k_state::fex68km3_map);
594 }
595
fex68km4(machine_config & config)596 void excel68k_state::fex68km4(machine_config &config)
597 {
598 fex68k(config);
599
600 /* basic machine hardware */
601 M68020(config.replace(), m_maincpu, 20_MHz_XTAL); // XC68020RC16 or MC68020RC20E
602 m_maincpu->set_addrmap(AS_PROGRAM, &excel68k_state::fex68km4_map);
603
604 m_irq_on->set_start_delay(attotime::from_hz(600) - attotime::from_usec(10)); // irq active for 10us
605 }
606
eag_base(machine_config & config)607 void eag_state::eag_base(machine_config &config)
608 {
609 /* basic machine hardware */
610 M68000(config, m_maincpu, 16_MHz_XTAL);
611 m_maincpu->disable_interrupt_mixer();
612 m_maincpu->set_addrmap(AS_PROGRAM, &eag_state::eag_map);
613
614 const attotime irq_period = attotime::from_hz(4.9152_MHz_XTAL/0x2000); // 4060 Q13, 600Hz
615 TIMER(config, m_irq_on).configure_periodic(FUNC(eag_state::irq_on<M68K_IRQ_IPL1>), irq_period);
616 m_irq_on->set_start_delay(irq_period - attotime::from_nsec(8250)); // active for 8.25us
617 TIMER(config, "irq_off").configure_periodic(FUNC(eag_state::irq_off<M68K_IRQ_IPL1>), irq_period);
618
619 NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
620
621 SENSORBOARD(config, m_board).set_type(sensorboard_device::MAGNETS);
622 m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
623 m_board->set_delay(attotime::from_msec(150));
624
625 /* video hardware */
626 PWM_DISPLAY(config, m_display).set_size(9, 16);
627 m_display->set_segmask(0x1ef, 0x7f);
628 config.set_default_layout(layout_fidel_eag_68k);
629
630 /* sound hardware */
631 SPEAKER(config, "speaker").front_center();
632 DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
633
634 /* cartridge */
635 GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "fidel_scc");
636 SOFTWARE_LIST(config, "cart_list").set_original("fidel_scc");
637 }
638
eagv2(machine_config & config)639 void eag_state::eagv2(machine_config &config)
640 {
641 eag_base(config);
642
643 /* basic machine hardware */
644 RAM(config, m_ram).set_extra_options("128K, 512K, 1M");
645 m_ram->set_default_size("128K");
646 }
647
eagv3(machine_config & config)648 void eag_state::eagv3(machine_config &config)
649 {
650 eagv2(config);
651
652 /* basic machine hardware */
653 m_ram->set_default_size("512K");
654 }
655
eagv5(machine_config & config)656 void eagv5_state::eagv5(machine_config &config)
657 {
658 eagv2(config);
659
660 /* basic machine hardware */
661 m_maincpu->set_addrmap(AS_PROGRAM, &eagv5_state::main_map);
662
663 M68000(config, m_subcpu, 16_MHz_XTAL);
664 m_subcpu->set_addrmap(AS_PROGRAM, &eagv5_state::sub_map);
665 m_subcpu->set_periodic_int(FUNC(eagv5_state::irq2_line_hold), attotime::from_hz(16_MHz_XTAL/0x4000)); // 4060 Q14, ~1kHz
666
667 GENERIC_LATCH_8(config, m_mainlatch);
668 GENERIC_LATCH_8(config, m_sublatch);
669 m_sublatch->data_pending_callback().set_inputline(m_maincpu, M68K_IRQ_IPL0);
670
671 // gen_latch syncs on write, but this is still needed with tight cpu comms
672 // (not that it locks up or anything, but it will calculate moves much slower if timing is off)
673 config.set_perfect_quantum(m_maincpu);
674 }
675
eagv7(machine_config & config)676 void eag_state::eagv7(machine_config &config)
677 {
678 eag_base(config);
679
680 /* basic machine hardware */
681 M68020(config.replace(), m_maincpu, 20_MHz_XTAL); // also seen with 25MHz XTAL
682 m_maincpu->disable_interrupt_mixer();
683 m_maincpu->set_addrmap(AS_PROGRAM, &eag_state::eagv7_map);
684 }
685
eagv9(machine_config & config)686 void eag_state::eagv9(machine_config &config)
687 {
688 eagv7(config);
689
690 /* basic machine hardware */
691 M68030(config.replace(), m_maincpu, 32_MHz_XTAL); // also seen with 40MHz XTAL
692 m_maincpu->disable_interrupt_mixer();
693 m_maincpu->set_addrmap(AS_PROGRAM, &eag_state::eagv7_map);
694 }
695
eagv10(machine_config & config)696 void eag_state::eagv10(machine_config &config)
697 {
698 eagv7(config);
699
700 /* basic machine hardware */
701 M68040(config.replace(), m_maincpu, 25_MHz_XTAL);
702 m_maincpu->disable_interrupt_mixer();
703 m_maincpu->set_addrmap(AS_PROGRAM, &eag_state::eagv10_map);
704 }
705
eagv11(machine_config & config)706 void eag_state::eagv11(machine_config &config)
707 {
708 eagv7(config);
709
710 /* basic machine hardware */
711 M68EC040(config.replace(), m_maincpu, 36_MHz_XTAL*2); // wrong! should be M68EC060
712 m_maincpu->set_addrmap(AS_PROGRAM, &eag_state::eagv10_map);
713 m_maincpu->set_periodic_int(FUNC(eag_state::irq2_line_hold), attotime::from_hz(600));
714
715 config.device_remove("irq_on"); // 8.25us is too long
716 config.device_remove("irq_off");
717 }
718
719
720
721 /******************************************************************************
722 ROM Definitions
723 ******************************************************************************/
724
725 ROM_START( fex68k ) // model 6094, PCB label 510.1120B01
726 ROM_REGION16_BE( 0x10000, "maincpu", 0 )
727 ROM_LOAD16_BYTE("e3_yellow.u6", 0x00000, 0x08000, CRC(a8a27714) SHA1(bc42a561eb39dd389c7831f1a25ad260510085d8) ) // AT27C256-15
728 ROM_LOAD16_BYTE("o4_red.u7", 0x00001, 0x08000, CRC(560a14b7) SHA1(11f2375255bfa229314697f103e891ba1cf0c715) ) // "
729 ROM_END
730
731 ROM_START( fex68ka )
732 ROM_REGION16_BE( 0x10000, "maincpu", 0 )
733 ROM_LOAD16_BYTE("e3_yellow.u6", 0x00000, 0x08000, CRC(7dc60d05) SHA1(e47b4d4e64c4cac6c5a94a900c9f2dd017f849ce) )
734 ROM_LOAD16_BYTE("o4_red.u7", 0x00001, 0x08000, CRC(4b738583) SHA1(ff506296ea460c7ed852339d2ab24aaae01730d8) )
735 ROM_END
736
737 ROM_START( fex68kb )
738 ROM_REGION16_BE( 0x10000, "maincpu", 0 )
739 ROM_LOAD16_BYTE("e3_yellow.u6", 0x00000, 0x08000, CRC(d9f252f5) SHA1(205cdbadb58a4cdd486d4e40d2fe6a5209d2f8a4) )
740 ROM_LOAD16_BYTE("o4_red.u7", 0x00001, 0x08000, CRC(3bf8b3d7) SHA1(6ce419c63159501d2349abfd1e142e38e5466fbc) )
741 ROM_END
742
743 ROM_START( fex68km2 ) // model 6097, PCB label 510.1120B01
744 ROM_REGION16_BE( 0x10000, "maincpu", 0 )
745 ROM_LOAD16_BYTE("e6_yellow.u6", 0x00000, 0x08000, CRC(2e65e7ad) SHA1(4f3aec12041c9014d5d700909bac66bae1f9eadf) ) // 27c256
746 ROM_LOAD16_BYTE("o7_red.u7", 0x00001, 0x08000, CRC(4c20334a) SHA1(2e575b88c41505cc89599d2fc13e1e84fe474469) ) // "
747 ROM_END
748
749 ROM_START( fex68km2a ) // model 6097, PCB label 510.1120B01
750 ROM_REGION16_BE( 0x10000, "maincpu", 0 )
751 ROM_LOAD16_BYTE("e7_yellow.u6", 0x00000, 0x08000, CRC(7c88f53b) SHA1(80fdeed90f1388053110c3bc385bc50c2884b11a) ) // 27c256
752 ROM_LOAD16_BYTE("o8_red.u7", 0x00001, 0x08000, CRC(26da3424) SHA1(e0cec467bf1249ce89a27c45f5013859e6581ecd) ) // "
753 ROM_END
754
755 ROM_START( fex68km3 ) // model 6098, PCB label 510.1120B01
756 ROM_REGION16_BE( 0x10000, "maincpu", 0 )
757 ROM_LOAD16_BYTE("me_white.u6", 0x00000, 0x08000, CRC(4b14cd9f) SHA1(4d41196900a71bf0699dae50f4726acc0ed3dced) ) // 27c256
758 ROM_LOAD16_BYTE("mo_yellow.u7", 0x00001, 0x08000, CRC(b96b0b5f) SHA1(281145be802efb38ed764aecb26b511dcd71cb87) ) // "
759 ROM_END
760
761 ROM_START( fex68km4 ) // model 6110, PCB label 510.1120B01
762 ROM_REGION( 0x10000, "maincpu", 0 )
763 ROM_LOAD16_BYTE("68020_even_master_2325.u6", 0x00000, 0x08000, CRC(13ea816c) SHA1(98d00fc382ddcbccb0a47c3f8d7fc73f30a15fbd) )
764 ROM_LOAD16_BYTE("68020_odd_master_2325.u7", 0x00001, 0x08000, CRC(d24c7b54) SHA1(3204fd600786792a618965715990c44890cc7119) )
765 ROM_END
766
767
768 ROM_START( feagv2 )
769 ROM_REGION16_BE( 0x20000, "maincpu", 0 )
770 ROM_LOAD16_BYTE("6114_e5_yellow.u22", 0x00000, 0x10000, CRC(f9c7bada) SHA1(60e545f829121b9a4f1100d9e85ac83797715e80) ) // 27c512
771 ROM_LOAD16_BYTE("6114_o5_green.u19", 0x00001, 0x10000, CRC(04f97b22) SHA1(8b2845dd115498f7b385e8948eca6a5893c223d1) ) // "
772 ROM_END
773
774 ROM_START( feagv3 )
775 ROM_REGION16_BE( 0x20000, "maincpu", 0 )
776 ROM_LOAD16_BYTE("elite_1.6_e.u22", 0x00000, 0x10000, CRC(c8b89ccc) SHA1(d62e0a72f54b793ab8853468a81255b62f874658) )
777 ROM_LOAD16_BYTE("elite_1.6_o.u19", 0x00001, 0x10000, CRC(904c7061) SHA1(742110576cf673321440bc81a4dae4c949b49e38) )
778 ROM_END
779
780 ROM_START( feagv5 )
781 ROM_REGION16_BE( 0x20000, "maincpu", 0 ) // PCB label 510.1136A01
782 ROM_LOAD16_BYTE("master_e", 0x00000, 0x10000, CRC(e424bddc) SHA1(ff03656addfe5c47f06df2efb4602f43a9e19d96) )
783 ROM_LOAD16_BYTE("master_o", 0x00001, 0x10000, CRC(33a00894) SHA1(849460332b1ac10d452ca3631eb99f5597511b73) )
784
785 ROM_REGION16_BE( 0x10000, "subcpu", 0 ) // PCB label 510.1138B01
786 ROM_LOAD16_BYTE("slave_e", 0x00000, 0x08000, CRC(eea4de52) SHA1(a64ca8a44b431e2fa7f00e44cab7e6aa2d4a9403) )
787 ROM_LOAD16_BYTE("slave_o", 0x00001, 0x08000, CRC(35fe2fdf) SHA1(731da12ee290bad9bc03cffe281c8cc48e555dfb) )
788 ROM_END
789
790 ROM_START( feagv7 )
791 ROM_REGION( 0x20000, "maincpu", 0 )
792 ROM_LOAD16_BYTE("eag-v7b", 0x00000, 0x10000, CRC(f2f68b63) SHA1(621e5073e9c5083ac9a9b467f3ef8aa29beac5ac) )
793 ROM_LOAD16_BYTE("eag-v7a", 0x00001, 0x10000, CRC(506b688f) SHA1(0a091c35d0f01166b57f964b111cde51c5720d58) )
794 ROM_END
795
796 ROM_START( feagv7a )
797 ROM_REGION( 0x20000, "maincpu", 0 )
798 ROM_LOAD16_BYTE("eag-v7b", 0x00000, 0x10000, CRC(44baefbf) SHA1(dbc24340d7e3013cc8f111ebb2a59169c5dcb8e8) )
799 ROM_LOAD16_BYTE("eag-v7a", 0x00001, 0x10000, CRC(951a7857) SHA1(dad21b049fd4f411a79d4faefb922c1277569c0e) )
800 ROM_END
801
802 ROM_START( feagv9 )
803 ROM_REGION( 0x20000, "maincpu", 0 )
804 ROM_LOAD16_BYTE("eag-v9b", 0x00000, 0x10000, CRC(60523199) SHA1(a308eb6b782732af1ab2fd0ed8b046de7a8dd24b) )
805 ROM_LOAD16_BYTE("eag-v9a", 0x00001, 0x10000, CRC(255c63c0) SHA1(8aa0397bdb3731002f5b066cd04ec62531267e22) )
806 ROM_END
807
808 ROM_START( feagv10 )
809 ROM_REGION( 0x20000, "maincpu", 0 )
810 ROM_LOAD32_BYTE("16", 0x00000, 0x08000, CRC(8375d61f) SHA1(e042f6f01480c59ee09a458cf34f135664479824) ) // 27c256
811 ROM_LOAD32_BYTE("17", 0x00001, 0x08000, CRC(bfd14916) SHA1(115af6dfd29ddd8ad6d2ce390f8ecc4d60de6fce) ) // "
812 ROM_LOAD32_BYTE("18", 0x00002, 0x08000, CRC(9341dcaf) SHA1(686bd4799e89ffaf11a813d4cf5a2aedd4c2d97a) ) // "
813 ROM_LOAD32_BYTE("19", 0x00003, 0x08000, CRC(a70c5468) SHA1(7f6b4f46577d5cfdaa84d387c7ce35d941e5bbc7) ) // "
814 ROM_END
815
816 ROM_START( feagv11 )
817 ROM_REGION( 0x20000, "maincpu", 0 )
818 ROM_LOAD32_BYTE("16", 0x00000, 0x08000, CRC(8375d61f) SHA1(e042f6f01480c59ee09a458cf34f135664479824) ) // 27c256
819 ROM_LOAD32_BYTE("17", 0x00001, 0x08000, CRC(bfd14916) SHA1(115af6dfd29ddd8ad6d2ce390f8ecc4d60de6fce) ) // "
820 ROM_LOAD32_BYTE("18", 0x00002, 0x08000, CRC(9341dcaf) SHA1(686bd4799e89ffaf11a813d4cf5a2aedd4c2d97a) ) // "
821 ROM_LOAD32_BYTE("19", 0x00003, 0x08000, CRC(a70c5468) SHA1(7f6b4f46577d5cfdaa84d387c7ce35d941e5bbc7) ) // "
822 ROM_END
823
824 } // anonymous namespace
825
826
827 /******************************************************************************
828 Drivers
829 ******************************************************************************/
830
831 // YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
832 CONS( 1987, fex68k, 0, 0, fex68k, excel68k, excel68k_state, empty_init, "Fidelity Electronics", "Excel 68000 (set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
833 CONS( 1987, fex68ka, fex68k, 0, fex68k, excel68k, excel68k_state, empty_init, "Fidelity Electronics", "Excel 68000 (set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
834 CONS( 1987, fex68kb, fex68k, 0, fex68k, excel68k, excel68k_state, empty_init, "Fidelity Electronics", "Excel 68000 (set 3)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
835 CONS( 1988, fex68km2, fex68k, 0, fex68km2, excel68k, excel68k_state, empty_init, "Fidelity Electronics", "Excel 68000 Mach II (rev. C+, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
836 CONS( 1988, fex68km2a, fex68k, 0, fex68km2, excel68k, excel68k_state, empty_init, "Fidelity Electronics", "Excel 68000 Mach II (rev. C+, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
837 CONS( 1988, fex68km3, fex68k, 0, fex68km3, excel68k, excel68k_state, empty_init, "Fidelity Electronics", "Excel 68000 Mach III Master", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
838 CONS( 1989, fex68km4, fex68k, 0, fex68km4, excel68k, excel68k_state, empty_init, "Fidelity Electronics", "Excel 68000 Mach IV 68020 Master 2325", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
839
840 CONS( 1989, feagv2, 0, 0, eagv2, eag, eag_state, init_eag, "Fidelity Electronics", "Elite Avant Garde (model 6114-2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
841 CONS( 1989, feagv3, feagv2, 0, eagv3, eag, eag_state, init_eag, "Fidelity Electronics", "Elite Avant Garde (model 6114-3)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
842 CONS( 1989, feagv5, feagv2, 0, eagv5, eag, eagv5_state, init_eag, "Fidelity Electronics", "Elite Avant Garde (model 6114-5)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
843 CONS( 1990, feagv7, feagv2, 0, eagv7, eag, eag_state, empty_init, "Fidelity Electronics", "Elite Avant Garde (model 6117-7, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
844 CONS( 1990, feagv7a, feagv2, 0, eagv7, eag, eag_state, empty_init, "Fidelity Electronics", "Elite Avant Garde (model 6117-7, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
845 CONS( 1990, feagv9, feagv2, 0, eagv9, eag, eag_state, empty_init, "Fidelity Electronics", "Elite Avant Garde (model 6117-9)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
846 CONS( 1990, feagv10, feagv2, 0, eagv10, eag, eag_state, empty_init, "Fidelity Electronics", "Elite Avant Garde (model 6117-10)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_TIMING )
847 CONS( 2002, feagv11, feagv2, 0, eagv11, eag, eag_state, empty_init, "hack (Wilfried Bucke)", "Elite Avant Garde (model 6117-11)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_TIMING )
848