1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:Berger
4 /******************************************************************************
5 
6 SciSys / Novag Chess Champion: Super System III (aka MK III), distributed by
7 both SciSys and Novag. Which company was responsible for which part of the
8 manufacturing chain is unknown. The software is by SciSys (no mention of Novag
9 in the ROM, it has "COPYRIGHT SCISYS LTD 1979").
10 
11 This is their 1st original product. MK II was licensed from Peter Jennings, and
12 MK I was, to put it bluntly, a bootleg. The chess engine is by Mike Johnson,
13 with support from David Levy.
14 
15 Hardware notes (Master Unit):
16 - Synertek 6502A @ 2MHz (4MHz XTAL)
17 - Synertek 6522 VIA
18 - 8KB ROM (2*Synertek 2332)
19 - 1KB RAM (2*HM472114P-3)
20 - MD4332BE + a bunch of TTL for the LCD
21 - 13 buttons, 4 switches, no leds or sensorboard
22 - connectors for: PSU, Power Pack, Chess Unit, Printer Unit
23 
24 Chess Unit:
25 - PCB label: Radofin XM-2057-0C
26 - Fairchild F6808P CPU @ ~6.8MHz (M6808 compatible)
27 - Fairchild F6821P PIA
28 - 2KB ROM(2316), 128x8 RAM(F6810P)
29 - 2*HLCD0438, chessboard LCD
30 
31 Printer Unit:
32 - unknown hardware, assume own CPU like the chess unit
33 
34 PSU ("permanent storage unit"?) is just a 256x4 battery-backed RAM (TC5501P)
35 module, not sure why it was so expensive (~180DM).
36 A chess clock accessory was also announced but unreleased.
37 
38 SciSys Super System IV (AKA MK IV) is on similar hardware. It was supposed to
39 be a modular chesscomputer, not only with accessory hardware like MK III, but
40 also a module slot for the program. The box mentions other modules, such as a
41 reversi program called "The Moor". The chesscomputer was discontinued soon after
42 release, and none of the accessories or other games came out.
43 
44 TODO:
45 - 6522 ACR register is initialized with 0xe3. Meaning: PA and PB inputs are set
46   to latch mode, but the program then never clocks the latch, it functions as if
47   it meant to write 0xe0. Maybe 6522 CA1 pin emulation is wrong? Documentation
48   says it's edge-triggered, but here it's tied to VCC. I added a trivial hack to
49   work around this, see rom defs.
50 - 2nd 7474 /2 clock divider on each 4000-7fff access, this also applies to 6522 clock
51   (doesn't affect chess calculation speed, only I/O access, eg. beeper pitch).
52   Should be doable to add, but 6522 device doesn't support live clock changes.
53 - LCD TC pin? connects to the display, source is a 50hz timer(from power supply),
54   probably to keep refreshing the LCD when inactive, there is no need to emulate it
55 - dump/add printer unit
56 - dump/add ssystem3 1980 program revision, were the BTANB fixed?
57 - ssystem4 softwarelist if a prototype cartridge is ever dumped
58 
59 BTANB (ssystem3):
60 - If the TIME switch is held up, it will sometimes recognize the wrong input when
61   another button is pressed. I assume they noticed this bug too late and tried to
62   lessen the chance by adding a spring to the switch.
63 - Similar to the TIME switch bug, pressing 2 buttons simultaneously can cause it
64   to malfunction, eg. press A+CE or C+CE and an "8" appears in the display.
65 - chess unit screen briefly flickers at power-on and when the subcpu receives an
66   NMI in the middle of updating the LCD, it is mentioned in the manual
67 
68 ******************************************************************************/
69 
70 #include "emu.h"
71 
72 #include "cpu/m6502/m6502.h"
73 #include "cpu/m6800/m6800.h"
74 #include "machine/6522via.h"
75 #include "machine/6821pia.h"
76 #include "machine/nvram.h"
77 #include "sound/dac.h"
78 #include "video/hlcd0438.h"
79 #include "video/md4330b.h"
80 #include "video/pwm.h"
81 
82 #include "screen.h"
83 #include "speaker.h"
84 
85 // internal artwork
86 #include "saitek_ssystem3.lh" // clickable
87 #include "saitek_ssystem4.lh" // clickable
88 
89 
90 namespace {
91 
92 class ssystem3_state : public driver_device
93 {
94 public:
ssystem3_state(const machine_config & mconfig,device_type type,const char * tag)95 	ssystem3_state(const machine_config &mconfig, device_type type, const char *tag) :
96 		driver_device(mconfig, type, tag),
97 		m_maincpu(*this, "maincpu"),
98 		m_subcpu(*this, "subcpu"),
99 		m_via(*this, "via"),
100 		m_pia(*this, "pia"),
101 		m_lcd1(*this, "lcd1"),
102 		m_lcd2(*this, "lcd2_%u", 0),
103 		m_display(*this, "display%u", 0),
104 		m_dac(*this, "dac"),
105 		m_nvram(*this, "nvram"),
106 		m_inputs(*this, "IN.%u", 0),
107 		m_out_lcd2(*this, "s%u.%u", 0U, 0U)
108 	{ }
109 
110 	DECLARE_INPUT_CHANGED_MEMBER(cu_plug);
111 
112 	// machine configs
113 	void ssystem3(machine_config &config);
114 	void ssystem4(machine_config &config);
115 
init_ssystem3()116 	void init_ssystem3() { m_xor_kludge = true; }
117 
118 protected:
119 	virtual void machine_start() override;
120 
121 private:
122 	// devices/pointers
123 	required_device<cpu_device> m_maincpu;
124 	optional_device<cpu_device> m_subcpu;
125 	required_device<via6522_device> m_via;
126 	optional_device<pia6821_device> m_pia;
127 	required_device<md4332b_device> m_lcd1;
128 	optional_device_array<hlcd0438_device, 2> m_lcd2;
129 	optional_device_array<pwm_display_device, 2> m_display;
130 	required_device<dac_bit_interface> m_dac;
131 	optional_shared_ptr<u8> m_nvram;
132 	optional_ioport_array<4+3> m_inputs;
133 	output_finder<8, 48> m_out_lcd2;
134 
135 	// address maps
136 	void ssystem3_map(address_map &map);
137 	void ssystem4_map(address_map &map);
138 	void chessunit_map(address_map &map);
139 
140 	// I/O handlers
lcd1_output_w(u32 data)141 	void lcd1_output_w(u32 data) { m_lcd1_data = data; }
142 	void input_w(u8 data);
143 	u8 input_r();
144 	void control_w(u8 data);
145 	u8 control_r();
146 
147 	void nvram_w(offs_t offset, u8 data);
148 	u8 nvram_r(offs_t offset);
149 
150 	void lcd2_pwm_w(offs_t offset, u8 data);
151 	void lcd2_update();
152 	template<int N> void lcd2_output_w(offs_t offset, u32 data);
153 	void cu_pia_a_w(u8 data);
154 	u8 cu_pia_a_r();
155 	void cu_pia_b_w(u8 data);
156 	u8 cu_pia_b_r();
157 
158 	u8 m_inp_mux = 0;
159 	u8 m_control = 0;
160 	u8 m_shift = 0;
161 	u32 m_lcd1_data = 0;
162 	u64 m_lcd2_data = 0;
163 	u8 m_lcd2_select = 0;
164 	bool m_xor_kludge = false;
165 };
166 
machine_start()167 void ssystem3_state::machine_start()
168 {
169 	m_out_lcd2.resolve();
170 
171 	// register for savestates
172 	save_item(NAME(m_inp_mux));
173 	save_item(NAME(m_control));
174 	save_item(NAME(m_shift));
175 	save_item(NAME(m_lcd1_data));
176 	save_item(NAME(m_lcd2_data));
177 	save_item(NAME(m_lcd2_select));
178 }
179 
180 
181 
182 /******************************************************************************
183     I/O
184 ******************************************************************************/
185 
186 // Master Unit
187 
input_w(u8 data)188 void ssystem3_state::input_w(u8 data)
189 {
190 	// PA0-PA7: input mux
191 	m_inp_mux = ~data;
192 }
193 
input_r()194 u8 ssystem3_state::input_r()
195 {
196 	u8 data = m_inp_mux;
197 
198 	// PA1-PA3: multiplexed inputs from PA4-PA7
199 	// PA0: blocked by diodes
200 	for (int i = 0; i < 4; i++)
201 		if (BIT(m_inp_mux, i+4))
202 			data |= m_inputs[i]->read() & 0xe;
203 
204 	// PA4-PA7: multiplexed inputs from PA0-PA3
205 	for (int i = 0; i < 4; i++)
206 		if (m_inp_mux & m_inputs[i]->read())
207 			data |= 1 << (i+4);
208 
209 	// PA5-PA7: freq sel from _PA0
210 	if (~m_inp_mux & 1)
211 		data |= m_inputs[5]->read() & 0xe0;
212 
213 	return ~data;
214 }
215 
control_w(u8 data)216 void ssystem3_state::control_w(u8 data)
217 {
218 	// PB0: speaker out
219 	m_dac->write(~data & m_inputs[4]->read() & 1);
220 
221 	// PB1: LCD DI
222 	// PB2: LCD CLK
223 	m_lcd1->di_w(BIT(data, 1));
224 	m_lcd1->clk_w(BIT(data, 2));
225 
226 	// PB2 also clocks a 4015B
227 	// DA: LCD DO, DB: Q3A
228 	if (data & ~m_control & 4)
229 	{
230 		m_shift = m_shift << 1 | m_lcd1->do_r();
231 
232 		// weird TTL maze, I assume it's a hw kludge to fix a bug after the maskroms were already manufactured
233 		u8 xorval = m_xor_kludge && (BIT(m_shift, 3) & ~(BIT(m_shift, 1) ^ BIT(m_shift, 4)) & ~(BIT(m_lcd1_data, 7) & BIT(m_lcd1_data, 23))) ? 0x12 : 0;
234 
235 		// update display
236 		for (int i = 0; i < 4; i++)
237 			m_display[0]->write_row(i, m_lcd1_data >> (8*i) & 0xff);
238 		m_display[0]->write_row(4, (m_shift ^ xorval) | 0x100);
239 		m_display[0]->update();
240 	}
241 
242 	// PB3: device serial out
243 	if (m_inputs[5]->read() & 2)
244 		m_pia->ca1_w(BIT(~data, 3));
245 
246 	// PB7: tied to PB6 (pulse timer 2)
247 	m_via->write_pb6(BIT(data, 7));
248 
249 	m_control = data;
250 }
251 
control_r()252 u8 ssystem3_state::control_r()
253 {
254 	u8 data = 0;
255 
256 	// PB4: device busy (unused on chess unit)
257 	// PB5: device attached
258 	if (m_inputs[5]->read() & 2)
259 		data ^= 0x30;
260 
261 	return ~data;
262 }
263 
264 
265 // PSU
266 
nvram_w(offs_t offset,u8 data)267 void ssystem3_state::nvram_w(offs_t offset, u8 data)
268 {
269 	// nvram is only d0-d3
270 	if (m_inputs[5]->read() & 1)
271 		m_nvram[offset] = data & 0x0f;
272 }
273 
nvram_r(offs_t offset)274 u8 ssystem3_state::nvram_r(offs_t offset)
275 {
276 	return (m_inputs[5]->read() & 1) ? (m_nvram[offset] & 0x0f) : 0;
277 }
278 
279 
280 // Chess Unit
281 
INPUT_CHANGED_MEMBER(ssystem3_state::cu_plug)282 INPUT_CHANGED_MEMBER(ssystem3_state::cu_plug)
283 {
284 	m_subcpu->set_input_line(INPUT_LINE_RESET, newval ? CLEAR_LINE : ASSERT_LINE);
285 
286 	if (newval)
287 		m_pia->reset();
288 	else
289 		m_display[1]->clear();
290 }
291 
lcd2_pwm_w(offs_t offset,u8 data)292 void ssystem3_state::lcd2_pwm_w(offs_t offset, u8 data)
293 {
294 	m_out_lcd2[offset & 0x3f][offset >> 6] = data;
295 }
296 
lcd2_update()297 void ssystem3_state::lcd2_update()
298 {
299 	if (m_inputs[5]->read() & 2)
300 		m_display[1]->matrix(1 << m_lcd2_select, m_lcd2_data);
301 }
302 
303 template<int N>
lcd2_output_w(offs_t offset,u32 data)304 void ssystem3_state::lcd2_output_w(offs_t offset, u32 data)
305 {
306 	if (!offset)
307 		data = 0;
308 
309 	m_lcd2_data = u64(data) << 32 | m_lcd2_data >> 32;
310 
311 	if (N == 1)
312 		lcd2_update();
313 }
314 
cu_pia_a_w(u8 data)315 void ssystem3_state::cu_pia_a_w(u8 data)
316 {
317 	// PA0-PA2: CD4051 to LCD column
318 	m_lcd2_select = data & 7;
319 	lcd2_update();
320 }
321 
cu_pia_a_r()322 u8 ssystem3_state::cu_pia_a_r()
323 {
324 	// PA7: serial data in
325 	return ~m_control << 4 & 0x80;
326 }
327 
cu_pia_b_w(u8 data)328 void ssystem3_state::cu_pia_b_w(u8 data)
329 {
330 	// PB3: LCD LOAD (both)
331 	// PB4: LCD LCD (both) + CD4051 COM OUT/IN
332 	// PB6: LCD CLOCK (both)
333 	// PB7: LCD DATA IN (1st)
334 	m_lcd2[0]->data_w(BIT(data, 7));
335 
336 	for (int i = 0; i < 2; i++)
337 		m_lcd2[i]->clock_w(BIT(data, 6));
338 
339 	for (int i = 0; i < 2; i++)
340 		m_lcd2[i]->load_w(BIT(~data, 3));
341 
342 	for (int i = 0; i < 2; i++)
343 		m_lcd2[i]->lcd_w(BIT(data, 4));
344 }
345 
cu_pia_b_r()346 u8 ssystem3_state::cu_pia_b_r()
347 {
348 	// PB5: look switch
349 	return m_inputs[6]->read() << 5 & 0x20;
350 }
351 
352 
353 
354 /******************************************************************************
355     Address Maps
356 ******************************************************************************/
357 
ssystem3_map(address_map & map)358 void ssystem3_state::ssystem3_map(address_map &map)
359 {
360 	map(0x0000, 0x03ff).mirror(0x3c00).ram();
361 	map(0x4000, 0x40ff).mirror(0x1f00).ram().rw(FUNC(ssystem3_state::nvram_r), FUNC(ssystem3_state::nvram_w)).share("nvram");
362 	map(0x6000, 0x600f).mirror(0x1ff0).m(m_via, FUNC(via6522_device::map));
363 	map(0x8000, 0x9fff).mirror(0x6000).rom();
364 }
365 
ssystem4_map(address_map & map)366 void ssystem3_state::ssystem4_map(address_map &map)
367 {
368 	map(0x0000, 0x03ff).ram();
369 	map(0x4400, 0x440f).m(m_via, FUNC(via6522_device::map));
370 	map(0x4800, 0x48ff).noprw(); // no nvram
371 	map(0xd000, 0xffff).rom();
372 }
373 
chessunit_map(address_map & map)374 void ssystem3_state::chessunit_map(address_map &map)
375 {
376 	map(0x3000, 0x307f).mirror(0x0f80).ram();
377 	map(0x4000, 0x47ff).mirror(0xb800).rom();
378 	map(0x8000, 0x8003).mirror(0x3ffc).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write));
379 }
380 
381 
382 
383 /******************************************************************************
384     Input Ports
385 ******************************************************************************/
386 
387 static INPUT_PORTS_START( ssystem4 )
388 	PORT_START("IN.0")
389 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_CODE(KEYCODE_9)390 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9 / EP / C.Square")
391 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
392 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0 / MD / C.Board")
393 
394 	PORT_START("IN.1")
395 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED)
396 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_F) PORT_NAME("F 6 / Knight / Clock")
397 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_LEFT) PORT_NAME("E 5 / Bishop / Left")
398 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_I) PORT_NAME("CE / Interrupt")
399 
400 	PORT_START("IN.2")
401 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("New Game")
402 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("G 7 / Pawn / Right")
403 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_D) PORT_NAME("D 4 / Rook / #")
404 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_A) PORT_NAME("A 1 / White")
405 
406 	PORT_START("IN.3")
407 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_TOGGLE PORT_CODE(KEYCODE_T) PORT_NAME("Time")
408 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_H) PORT_NAME("H 8 / Black")
409 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_C) PORT_NAME("C 3 / Queen / #50")
410 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_B) PORT_NAME("B 2 / King / FP")
411 
412 	PORT_START("IN.4") // switches
413 	PORT_CONFNAME( 0x01, 0x01, "Sound" )
414 	PORT_CONFSETTING(    0x00, DEF_STR( Off ) )
415 	PORT_CONFSETTING(    0x01, DEF_STR( On ) )
416 	PORT_CONFNAME( 0x02, 0x02, "LCD 1 Light" )
417 	PORT_CONFSETTING(    0x00, DEF_STR( Off ) )
418 	PORT_CONFSETTING(    0x02, DEF_STR( On ) )
419 
420 	PORT_START("IN.5") // accessories/diodes
421 	PORT_BIT(0xff, IP_ACTIVE_HIGH, IPT_UNUSED)
422 INPUT_PORTS_END
423 
424 static INPUT_PORTS_START( ssystem3 )
425 	PORT_INCLUDE( ssystem4 )
426 
427 	PORT_MODIFY("IN.0")
428 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9 / EP / C SQ")
429 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0 / MD / C Board")
430 
431 	PORT_MODIFY("IN.3")
432 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Time") // spring-loaded
433 
434 	PORT_MODIFY("IN.4") // switches
435 	PORT_CONFNAME( 0x04, 0x04, "LCD 2 Light" )
436 	PORT_CONFSETTING(    0x00, DEF_STR( Off ) )
437 	PORT_CONFSETTING(    0x04, DEF_STR( On ) )
438 
439 	PORT_MODIFY("IN.5") // accessories/diodes
440 	PORT_CONFNAME( 0x01, 0x01, "Memory Unit" )
441 	PORT_CONFSETTING(    0x00, DEF_STR( Off ) )
442 	PORT_CONFSETTING(    0x01, DEF_STR( On ) )
443 	PORT_CONFNAME( 0x02, 0x02, "Chess Unit" ) PORT_CHANGED_MEMBER(DEVICE_SELF, ssystem3_state, cu_plug, 0)
444 	PORT_CONFSETTING(    0x00, DEF_STR( Off ) )
445 	PORT_CONFSETTING(    0x02, DEF_STR( On ) )
446 	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_CUSTOM)
447 
448 	PORT_START("IN.6") // chess unit
449 	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_TOGGLE PORT_CODE(KEYCODE_O) PORT_NAME("Look")
450 INPUT_PORTS_END
451 
452 
453 
454 /******************************************************************************
455     Machine Configs
456 ******************************************************************************/
457 
458 void ssystem3_state::ssystem4(machine_config &config)
459 {
460 	/* basic machine hardware */
461 	M6502(config, m_maincpu, 4_MHz_XTAL / 2);
462 	m_maincpu->set_addrmap(AS_PROGRAM, &ssystem3_state::ssystem4_map);
463 
464 	VIA6522(config, m_via, 4_MHz_XTAL / 2);
465 	m_via->writepa_handler().set(FUNC(ssystem3_state::input_w));
466 	m_via->readpa_handler().set(FUNC(ssystem3_state::input_r));
467 	m_via->writepb_handler().set(FUNC(ssystem3_state::control_w));
468 	m_via->readpb_handler().set(FUNC(ssystem3_state::control_r));
469 
470 	/* video hardware */
471 	MD4332B(config, m_lcd1);
472 	m_lcd1->write_q().set(FUNC(ssystem3_state::lcd1_output_w));
473 
474 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
475 	screen.set_refresh_hz(60);
476 	screen.set_size(1920/2, 729/2);
477 	screen.set_visarea_full();
478 
479 	PWM_DISPLAY(config, m_display[0]).set_size(5, 9);
480 	m_display[0]->set_bri_levels(0.25);
481 
482 	config.set_default_layout(layout_saitek_ssystem4);
483 
484 	/* sound hardware */
485 	SPEAKER(config, "speaker").front_center();
486 	DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
487 }
488 
ssystem3(machine_config & config)489 void ssystem3_state::ssystem3(machine_config &config)
490 {
491 	ssystem4(config);
492 
493 	/* basic machine hardware */
494 	m_maincpu->set_addrmap(AS_PROGRAM, &ssystem3_state::ssystem3_map);
495 
496 	M6808(config, m_subcpu, 6800000); // LC circuit, measured
497 	m_subcpu->set_addrmap(AS_PROGRAM, &ssystem3_state::chessunit_map);
498 
499 	config.set_perfect_quantum(m_maincpu);
500 
501 	PIA6821(config, m_pia, 0);
502 	m_pia->irqa_handler().set_inputline(m_subcpu, INPUT_LINE_NMI);
503 	m_pia->writepa_handler().set(FUNC(ssystem3_state::cu_pia_a_w));
504 	m_pia->readpa_handler().set(FUNC(ssystem3_state::cu_pia_a_r));
505 	m_pia->writepb_handler().set(FUNC(ssystem3_state::cu_pia_b_w));
506 	m_pia->readpb_handler().set(FUNC(ssystem3_state::cu_pia_b_r));
507 	m_pia->cb2_handler().set(m_pia, FUNC(pia6821_device::cb1_w));
508 	m_pia->cb2_handler().append(m_pia, FUNC(pia6821_device::ca2_w));
509 
510 	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
511 
512 	/* video hardware */
513 	HLCD0438(config, m_lcd2[0], 0);
514 	m_lcd2[0]->write_segs().set(FUNC(ssystem3_state::lcd2_output_w<0>));
515 	m_lcd2[0]->write_data().set(m_lcd2[1], FUNC(hlcd0438_device::data_w));
516 
517 	HLCD0438(config, m_lcd2[1], 0);
518 	m_lcd2[1]->write_segs().set(FUNC(ssystem3_state::lcd2_output_w<1>));
519 
520 	screen_device &screen(SCREEN(config, "chessunit", SCREEN_TYPE_SVG));
521 	screen.set_refresh_hz(60);
522 	screen.set_size(1060/1.5, 1080/1.5);
523 	screen.set_visarea_full();
524 
525 	PWM_DISPLAY(config, m_display[1]).set_size(8, 48);
526 	m_display[1]->output_x().set(FUNC(ssystem3_state::lcd2_pwm_w));
527 
528 	m_display[0]->set_segmask(0xf, 0x7f); // 7segs are at expected positions
529 	config.set_default_layout(layout_saitek_ssystem3);
530 }
531 
532 
533 
534 /******************************************************************************
535     ROM Definitions
536 ******************************************************************************/
537 
538 ROM_START( ssystem3 )
539 	ROM_REGION(0x10000, "maincpu", 0)
540 	ROM_LOAD("c19081e_ss-3-lrom.u4", 0x8000, 0x1000, CRC(9ea46ed3) SHA1(34eef85b356efbea6ddac1d1705b104fc8e2731a) ) // 2332
541 	ROM_LOAD("c19082_ss-3-hrom.u5",  0x9000, 0x1000, CRC(52741e0b) SHA1(2a7b950f9810c5a14a1b9d5e6b2bd93da621662e) ) // "
542 
543 	// HACK! 6522 ACR register setup
544 	ROM_FILL(0x946d, 1, 0xe0) // was 0xe3
545 
546 	ROM_REGION(0x10000, "subcpu", 0)
547 	ROM_LOAD("c28a97m_ss-3l-rom", 0x4000, 0x0800, CRC(bf0b2a84) SHA1(286f56aca2e50b78ac1fae4a89413659aceb71d9) ) // 2316
548 
549 	ROM_REGION(0x100, "nvram", 0) // default settings
550 	ROM_LOAD("nvram", 0, 0x100, CRC(b5dddc7b) SHA1(3be9ec8359cc9ef16a04f28dfd24f9ffe1a2fca9) )
551 
552 	ROM_REGION(53552, "screen", 0)
553 	ROM_LOAD("ssystem3.svg", 0, 53552, CRC(6047f88f) SHA1(2ff9cfce01cd3811a3f46f84b47fdc4ea2cf2ba8) )
554 
555 	ROM_REGION(748939, "chessunit", 0)
556 	ROM_LOAD("chessunit.svg", 0, 748939, CRC(713a46fd) SHA1(6119162fb7c00f81aeca0dfe274475dc8575dd70) )
557 ROM_END
558 
559 ROM_START( ssystem4 )
560 	ROM_REGION(0x10000, "maincpu", 0) // roms in a cartridge
561 	ROM_LOAD("c45021_ss4-lrom", 0xd000, 0x1000, CRC(fc86a4fc) SHA1(ee292925165d4bf7b948c60a81d95f7a4064e797) ) // 2332
562 	ROM_LOAD("c45022_ss4-mrom", 0xe000, 0x1000, CRC(c6110af1) SHA1(4b63454a23b2fe6b5c8f3fa6718eb49770cb6907) ) // "
563 	ROM_LOAD("c45023_ss4-hrom", 0xf000, 0x1000, CRC(ab4a4343) SHA1(6eeee7168e13dc1115cb5833f1938a8ea8c01d69) ) // "
564 
565 	// HACK! 6522 ACR register setup
566 	ROM_FILL(0xd05b, 1, 0xe0) // was 0xe3
567 
568 	ROM_REGION(53552, "screen", 0) // looks same, but different pinout
569 	ROM_LOAD("ssystem4.svg", 0, 53552, CRC(b69b12e3) SHA1(c2e39d015397d403309f1c23619fe8abc3745d87) )
570 ROM_END
571 
572 } // anonymous namespace
573 
574 
575 
576 /******************************************************************************
577     Drivers
578 ******************************************************************************/
579 
580 //    YEAR  NAME      PARENT CMP MACHINE   INPUT     STATE           INIT           COMPANY, FULLNAME, FLAGS
581 CONS( 1979, ssystem3, 0,      0, ssystem3, ssystem3, ssystem3_state, init_ssystem3, "SciSys / Novag", "Chess Champion: Super System III", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
582 CONS( 1980, ssystem4, 0,      0, ssystem4, ssystem4, ssystem3_state, empty_init,    "SciSys", "Chess Champion: Super System IV", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
583