From 106bbe0f5a815ac53eca83e0a473853c459f7b08 Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 5 Nov 2023 13:56:28 +0100 Subject: exchess: rename driver to exechess to prevent confusion with expchess New working systems ------------------- Chess Companion II [hap, Sean Riddle] New working clones ------------------ Explorer Chess [hap, Sean Riddle] --- src/mame/handheld/hh_hmcs40.cpp | 2 +- src/mame/layout/saitek_ccompan.lay | 8 +- src/mame/layout/saitek_ccompan2.lay | 599 ++++++++++++++++++++++++++++++++++++ src/mame/layout/saitek_exchess.lay | 145 --------- src/mame/layout/saitek_exechess.lay | 146 +++++++++ src/mame/layout/saitek_expchess.lay | 532 ++++++++++++++++++++++++++++++++ src/mame/mame.lst | 8 +- src/mame/novag/micro2.cpp | 8 +- src/mame/saitek/ccompan2.cpp | 346 +++++++++++++++++++++ src/mame/saitek/exchess.cpp | 271 ---------------- src/mame/saitek/exechess.cpp | 271 ++++++++++++++++ 11 files changed, 1908 insertions(+), 428 deletions(-) create mode 100644 src/mame/layout/saitek_ccompan2.lay delete mode 100644 src/mame/layout/saitek_exchess.lay create mode 100644 src/mame/layout/saitek_exechess.lay create mode 100644 src/mame/layout/saitek_expchess.lay create mode 100644 src/mame/saitek/ccompan2.cpp delete mode 100644 src/mame/saitek/exchess.cpp create mode 100644 src/mame/saitek/exechess.cpp diff --git a/src/mame/handheld/hh_hmcs40.cpp b/src/mame/handheld/hh_hmcs40.cpp index d583dbdadb4..0910725cadc 100644 --- a/src/mame/handheld/hh_hmcs40.cpp +++ b/src/mame/handheld/hh_hmcs40.cpp @@ -91,7 +91,7 @@ known chips: *A04 HD44868 1984, SciSys Rapier *A07 HD44868 1984, Chess King Pocket Micro Deluxe - *A12 HD44868 1985, SciSys MK 10 / Pocket Chess + *A12 HD44868 1985, SciSys MK 10 / Pocket Chess / Electronic Trio *A14 HD44868 1985, SciSys Kasparov Plus *A16 HD44868 1988, Saitek Pocket Checkers diff --git a/src/mame/layout/saitek_ccompan.lay b/src/mame/layout/saitek_ccompan.lay index b685c4241a4..75e0b273fc7 100644 --- a/src/mame/layout/saitek_ccompan.lay +++ b/src/mame/layout/saitek_ccompan.lay @@ -17,7 +17,7 @@ license:CC0-1.0 - + @@ -578,11 +578,9 @@ license:CC0-1.0 - + - - - + diff --git a/src/mame/layout/saitek_ccompan2.lay b/src/mame/layout/saitek_ccompan2.lay new file mode 100644 index 00000000000..68758955fa8 --- /dev/null +++ b/src/mame/layout/saitek_ccompan2.lay @@ -0,0 +1,599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/saitek_exchess.lay b/src/mame/layout/saitek_exchess.lay deleted file mode 100644 index 207ecd62fcf..00000000000 --- a/src/mame/layout/saitek_exchess.lay +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mame/layout/saitek_exechess.lay b/src/mame/layout/saitek_exechess.lay new file mode 100644 index 00000000000..4a368f47db6 --- /dev/null +++ b/src/mame/layout/saitek_exechess.lay @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/saitek_expchess.lay b/src/mame/layout/saitek_expchess.lay new file mode 100644 index 00000000000..211ec0a6280 --- /dev/null +++ b/src/mame/layout/saitek_expchess.lay @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index fbb8f438051..4360b462f11 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -38319,6 +38319,10 @@ sage2 @source:saitek/ccompan.cpp ccompan +@source:saitek/ccompan2.cpp +ccompan2 +expchess + @source:saitek/chesstrv.cpp chesstrv chesstrvi @@ -38334,8 +38338,8 @@ cp2000 @source:saitek/delta1.cpp ccdelta1 -@source:saitek/exchess.cpp -exchess +@source:saitek/exechess.cpp +exechess @source:saitek/intchess.cpp intchess diff --git a/src/mame/novag/micro2.cpp b/src/mame/novag/micro2.cpp index 29eedd69220..c78b14108cc 100644 --- a/src/mame/novag/micro2.cpp +++ b/src/mame/novag/micro2.cpp @@ -70,15 +70,13 @@ public: // machine configs void micro2(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER(cpu_freq) { set_cpu_freq(); } + DECLARE_INPUT_CHANGED_MEMBER(change_cpu_freq) { set_cpu_freq(); } protected: virtual void machine_start() override; virtual void machine_reset() override { set_cpu_freq(); } private: - void set_cpu_freq(); - // devices/pointers required_device m_maincpu; required_device m_display; @@ -92,6 +90,8 @@ private: void control_w(u8 data); u8 input_r(); + void set_cpu_freq(); + bool m_kp_select = false; u8 m_inp_mux = 0; u8 m_led_select = 0; @@ -181,7 +181,7 @@ static INPUT_PORTS_START( micro2 ) PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Go") PORT_START("FAKE") - PORT_CONFNAME( 0x01, 0x00, "CPU Frequency" ) PORT_CHANGED_MEMBER(DEVICE_SELF, micro2_state, cpu_freq, 0) // factory set + PORT_CONFNAME( 0x01, 0x00, "CPU Frequency" ) PORT_CHANGED_MEMBER(DEVICE_SELF, micro2_state, change_cpu_freq, 0) // factory set PORT_CONFSETTING( 0x00, "6MHz (original)" ) PORT_CONFSETTING( 0x01, "12MHz (Octo)" ) INPUT_PORTS_END diff --git a/src/mame/saitek/ccompan2.cpp b/src/mame/saitek/ccompan2.cpp new file mode 100644 index 00000000000..2f7d2a92045 --- /dev/null +++ b/src/mame/saitek/ccompan2.cpp @@ -0,0 +1,346 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Sean Riddle +/******************************************************************************* + +SciSys Chess Companion II family + +The chess engine is LogiChess (ported from Z80 to 6800), by Kaare Danielsen. +CXG Enterprise "S" / Star Chess is probably on similar hardware. + +TODO: +- standby/battery save mode + +******************************************************************************** + +Hardware notes: + +Chess Companion II: +- PCB label: Y01B-01 REV.B +- Hitachi HD6301V1 (0609V171) @ ~3MHz (LC oscillator) +- chessboard buttons, 16+5 leds, piezo + +Explorer Chess: +- slightly different UI (12 buttons instead of 14, but same functionality) +- portable, peg board instead of button board +- rest is same as ccompan2 + +Concord II: +- PCB label: SCISYS ST3 REV.E +- MCU clock frequency is twice higher than Concord +- rest is same as ccompan2, it just has the buttons/status leds at the bottom + instead of at the right + +Explorer Chess and Chess Companion II / Concord are on the same MCU, pin P23 is +either VCC or GND to distinguish between the two. + +0609V171 MCU is used in: +- SciSys Chess Companion II (2 revisions) +- SciSys Olympiade (French) +- SciSys Explorer Chess +- SciSys Concord +- SciSys Concord II +- SciSys Electronic Chess Mark 8 +- Tandy 1650 Portable Sensory Chess (Tandy brand Explorer Chess) +- Tandy 1650 Fast Response Time: Computerized Chess (Tandy brand Concord II) + +*******************************************************************************/ + +#include "emu.h" + +#include "cpu/m6800/m6801.h" +#include "machine/sensorboard.h" +#include "sound/dac.h" +#include "video/pwm.h" + +#include "speaker.h" + +// internal artwork +#include "saitek_ccompan2.lh" +#include "saitek_expchess.lh" + + +namespace { + +class ccompan2_state : public driver_device +{ +public: + ccompan2_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_board(*this, "board"), + m_display(*this, "display"), + m_dac(*this, "dac"), + m_inputs(*this, "IN.%u", 0) + { } + + void ccompan2(machine_config &config); + void expchess(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(change_cpu_freq) { set_cpu_freq(); } + +protected: + virtual void machine_start() override; + virtual void machine_reset() override { set_cpu_freq(); } + DECLARE_MACHINE_RESET(expchess) { ; } + +private: + // devices/pointers + required_device m_maincpu; + required_device m_board; + required_device m_display; + required_device m_dac; + required_ioport_array<8+1> m_inputs; + + // address maps + void main_map(address_map &map); + + // I/O handlers + u8 input1_r(); + u8 input2_r(); + void speaker_w(u8 data); + void mux_w(u8 data); + u8 battery_r(); + void led_w(u8 data); + + void set_cpu_freq(); + + u8 m_inp_mux = 0; +}; + +void ccompan2_state::machine_start() +{ + // register for savestates + save_item(NAME(m_inp_mux)); +} + +void ccompan2_state::set_cpu_freq() +{ + // Concord II MCU speed is twice higher + m_maincpu->set_unscaled_clock((ioport("FAKE")->read() & 1) ? 6000000 : 3000000); +} + + + +/******************************************************************************* + I/O +*******************************************************************************/ + +u8 ccompan2_state::input1_r() +{ + u8 data = 0; + + // P10-P17: read chessboard + for (int i = 0; i < 8; i++) + if (BIT(m_inp_mux, i)) + data |= m_board->read_file(i ^ 7); + + return ~data; +} + +u8 ccompan2_state::input2_r() +{ + u8 data = 0; + + // P21,P22: read buttons + for (int i = 0; i < 8; i++) + if (BIT(m_inp_mux, i)) + data |= m_inputs[i]->read() << 1 & 6; + + // P23: button configuration + data |= m_inputs[8]->read() << 3 & 8; + + return ~data; +} + +void ccompan2_state::speaker_w(u8 data) +{ + // P20: speaker out + m_dac->write(data & 1); +} + +void ccompan2_state::mux_w(u8 data) +{ + // P30-P37: input mux, led data + m_inp_mux = data ^ 0xff; + m_display->write_mx(m_inp_mux); +} + +u8 ccompan2_state::battery_r() +{ + // P40: battery status (only reads it at boot) + return 0; +} + +void ccompan2_state::led_w(u8 data) +{ + // P41-P45: direct leds + // P46,P47: board leds + m_display->write_my(~data >> 1 & 0x7f); +} + + + +/******************************************************************************* + Address Maps +*******************************************************************************/ + +void ccompan2_state::main_map(address_map &map) +{ + map(0x0000, 0x0014).m(m_maincpu, FUNC(hd6301v1_cpu_device::m6801_io)); + map(0x0080, 0x00ff).ram(); // internal + map(0xf000, 0xffff).rom(); +} + + + +/******************************************************************************* + Input Ports +*******************************************************************************/ + +static INPUT_PORTS_START( ccompan2 ) + PORT_START("IN.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("IN.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Sound") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Level") + + PORT_START("IN.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Color") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Multi Move") + + PORT_START("IN.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("King") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Queen") + + PORT_START("IN.4") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Rook") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_O) PORT_NAME("Play") + + PORT_START("IN.5") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Bishop") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Enter Position") + + PORT_START("IN.6") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Knight") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Take Back") + + PORT_START("IN.7") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Pawn") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("New Game") + + PORT_START("IN.8") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_CUSTOM) // button config + + PORT_START("FAKE") + PORT_CONFNAME( 0x01, 0x00, "CPU Frequency" ) PORT_CHANGED_MEMBER(DEVICE_SELF, ccompan2_state, change_cpu_freq, 0) // factory set + PORT_CONFSETTING( 0x00, "3MHz (original)" ) + PORT_CONFSETTING( 0x01, "6MHz (Concord II)" ) +INPUT_PORTS_END + +static INPUT_PORTS_START( expchess ) + PORT_START("IN.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Rook") + + PORT_START("IN.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Bishop") + + PORT_START("IN.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("White/Black") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Take Back") + + PORT_START("IN.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("New Game / Clear Board") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Level / Sound") + + PORT_START("IN.4") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("2nd F") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_O) PORT_NAME("Play / PVP") + + PORT_START("IN.5") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Knight") + + PORT_START("IN.6") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Pawn") + + PORT_START("IN.7") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("King") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Queen") + + PORT_START("IN.8") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_CUSTOM) // button config +INPUT_PORTS_END + + + +/******************************************************************************* + Machine Configs +*******************************************************************************/ + +void ccompan2_state::ccompan2(machine_config &config) +{ + // basic machine hardware + HD6301V1(config, m_maincpu, 3000000); // approximation, no XTAL + m_maincpu->set_addrmap(AS_PROGRAM, &ccompan2_state::main_map); + m_maincpu->in_p1_cb().set(FUNC(ccompan2_state::input1_r)); + m_maincpu->in_p2_cb().set(FUNC(ccompan2_state::input2_r)); + m_maincpu->out_p2_cb().set(FUNC(ccompan2_state::speaker_w)); + m_maincpu->out_p3_cb().set(FUNC(ccompan2_state::mux_w)); + m_maincpu->in_p4_cb().set(FUNC(ccompan2_state::battery_r)); + m_maincpu->out_p4_cb().set(FUNC(ccompan2_state::led_w)); + + SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS); + m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess)); + m_board->set_delay(attotime::from_msec(150)); + + // video hardware + PWM_DISPLAY(config, m_display).set_size(5+2, 8); + m_display->set_interpolation(0.25); + config.set_default_layout(layout_saitek_ccompan2); + + // sound hardware + SPEAKER(config, "speaker").front_center(); + DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25); +} + +void ccompan2_state::expchess(machine_config &config) +{ + ccompan2(config); + + MCFG_MACHINE_RESET_OVERRIDE(ccompan2_state, expchess) + config.set_default_layout(layout_saitek_expchess); +} + + + +/******************************************************************************* + ROM Definitions +*******************************************************************************/ + +ROM_START( ccompan2 ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD("1983_te-1_scisys-w_0609v171.u1", 0xf000, 0x1000, CRC(a26632fd) SHA1(fb83dc2476500acaabd949d749e58adca01012ea) ) +ROM_END + +ROM_START( expchess ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD("1983_te-1_scisys-w_0609v171.u1", 0xf000, 0x1000, CRC(a26632fd) SHA1(fb83dc2476500acaabd949d749e58adca01012ea) ) +ROM_END + +} // anonymous namespace + + + +/******************************************************************************* + Drivers +*******************************************************************************/ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +SYST( 1983, ccompan2, 0, 0, ccompan2, ccompan2, ccompan2_state, empty_init, "SciSys", "Chess Companion II", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) +SYST( 1983, expchess, ccompan2, 0, expchess, expchess, ccompan2_state, empty_init, "SciSys", "Explorer Chess", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/saitek/exchess.cpp b/src/mame/saitek/exchess.cpp deleted file mode 100644 index 102d9db3490..00000000000 --- a/src/mame/saitek/exchess.cpp +++ /dev/null @@ -1,271 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:hap -// thanks-to:Sean Riddle -/******************************************************************************* - -SciSys Executive Chess, handheld chesscomputer. -Also known as Senator Chess in Germany. - -Hardware notes: -- Fairchild 3870 MCU (variant with 4KB internal ROM) -- 1KB RAM (2*TC5514P) -- HLCD0538, HLCD0539, LCD screen - -*******************************************************************************/ - -#include "emu.h" - -#include "cpu/f8/f8.h" -#include "machine/f3853.h" -#include "video/hlcd0538.h" -#include "video/pwm.h" - -#include "screen.h" - -// internal artwork -#include "saitek_exchess.lh" - - -namespace { - -class exchess_state : public driver_device -{ -public: - exchess_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_lcd1(*this, "lcd1"), - m_lcd2(*this, "lcd2"), - m_display(*this, "display"), - m_battery(*this, "battery"), - m_inputs(*this, "IN.%u", 0) - { } - - void exchess(machine_config &config); - - // battery status indicator is not software controlled - DECLARE_INPUT_CHANGED_MEMBER(battery) { m_battery = newval; } - -protected: - virtual void machine_start() override; - -private: - // devices/pointers - required_device m_maincpu; - required_device m_lcd1; - required_device m_lcd2; - required_device m_display; - output_finder<> m_battery; - required_ioport_array<4> m_inputs; - - // address maps - void main_map(address_map &map); - void main_io(address_map &map); - - // I/O handlers - template void lcd_output_w(u64 data); - void lcd_data_w(u8 data); - - u16 ram_address() { return (m_ram_address[1] << 8 | m_ram_address[0]) & 0x3ff; } - template u8 ram_address_r(); - template void ram_address_w(u8 data); - u8 ram_data_r(); - void ram_data_w(u8 data); - - std::unique_ptr m_ram; - u8 m_ram_address[2] = { }; - u64 m_lcd_data[2] = { }; -}; - -void exchess_state::machine_start() -{ - m_battery.resolve(); - m_ram = make_unique_clear(0x400); - - // register for savestates - save_pointer(NAME(m_ram), 0x400); - save_item(NAME(m_ram_address)); - save_item(NAME(m_lcd_data)); -} - - - -/******************************************************************************* - I/O -*******************************************************************************/ - -// LCD - -template -void exchess_state::lcd_output_w(u64 data) -{ - m_lcd_data[N] = data; - m_display->matrix(m_lcd_data[0] & 0xff, m_lcd_data[1] << 26 | m_lcd_data[0] >> 8); -} - -void exchess_state::lcd_data_w(u8 data) -{ - // P40: HLCD0539 data - // P44: HLCD0538 data - m_lcd1->data_w(BIT(data, 4)); - m_lcd2->data_w(BIT(data, 0)); - - if (~m_ram_address[1] & 4) - { - m_lcd1->clk_w(1); m_lcd1->clk_w(0); - m_lcd2->clk_w(1); m_lcd2->clk_w(0); - } -} - - -// 1KB RAM (port-mapped) - -template -void exchess_state::ram_address_w(u8 data) -{ - // P00-P07: RAM A0-A7 - // P10-P11: RAM A8-A9 - // P12: RAM CE - m_ram_address[N] = data; -} - -template -u8 exchess_state::ram_address_r() -{ - u8 data = m_ram_address[N]; - - // P13: Enter button - return (N) ? data | (m_inputs[0]->read() & 8) : data; -} - -void exchess_state::ram_data_w(u8 data) -{ - if (m_ram_address[1] & 4) - m_ram[ram_address()] = data; -} - -u8 exchess_state::ram_data_r() -{ - return (m_ram_address[1] & 4) ? m_ram[ram_address()] : 0; -} - - - -/******************************************************************************* - Address Maps -*******************************************************************************/ - -void exchess_state::main_map(address_map &map) -{ - map.global_mask(0xfff); - map(0x0000, 0x0fff).rom(); -} - -void exchess_state::main_io(address_map &map) -{ - map(0x00, 0x00).rw(FUNC(exchess_state::ram_address_r<0>), FUNC(exchess_state::ram_address_w<0>)); - map(0x01, 0x01).rw(FUNC(exchess_state::ram_address_r<1>), FUNC(exchess_state::ram_address_w<1>)); - map(0x04, 0x07).rw("psu", FUNC(f38t56_device::read), FUNC(f38t56_device::write)); -} - - - -/******************************************************************************* - Input Ports -*******************************************************************************/ - -static INPUT_PORTS_START( exchess ) - PORT_START("IN.0") - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") - PORT_BIT(0xf7, IP_ACTIVE_HIGH, IPT_UNUSED) - - PORT_START("IN.1") - PORT_BIT(0x01, 0x01, IPT_CUSTOM) PORT_CONDITION("IN.2", 0x51, NOTEQUALS, 0x00) - PORT_BIT(0x02, 0x02, IPT_CUSTOM) PORT_CONDITION("IN.2", 0x32, NOTEQUALS, 0x00) - PORT_BIT(0x04, 0x04, IPT_CUSTOM) PORT_CONDITION("IN.2", 0xa4, NOTEQUALS, 0x00) - PORT_BIT(0x08, 0x08, IPT_CUSTOM) PORT_CONDITION("IN.2", 0xc8, NOTEQUALS, 0x00) - PORT_BIT(0x30, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("New Game") - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_F) PORT_NAME("2nd F") - - PORT_START("IN.2") // square 'd-pad' (8-way, so define joystick) - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Cursor Left") - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP) PORT_CODE(KEYCODE_UP) PORT_NAME("Cursor Up") - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Cursor Right") - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Cursor Down") - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) // ul - PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) // ur - PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) // dl - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) // dr - - PORT_START("IN.3") - PORT_CONFNAME( 0x01, 0x00, "Battery Status" ) PORT_CHANGED_MEMBER(DEVICE_SELF, exchess_state, battery, 0) - PORT_CONFSETTING( 0x01, "Low" ) - PORT_CONFSETTING( 0x00, DEF_STR( Normal ) ) -INPUT_PORTS_END - - - -/******************************************************************************* - Machine Configs -*******************************************************************************/ - -void exchess_state::exchess(machine_config &config) -{ - // basic machine hardware - F8(config, m_maincpu, 4500000/2); // measured - m_maincpu->set_addrmap(AS_PROGRAM, &exchess_state::main_map); - m_maincpu->set_addrmap(AS_IO, &exchess_state::main_io); - m_maincpu->set_irq_acknowledge_callback("psu", FUNC(f38t56_device::int_acknowledge)); - - f38t56_device &psu(F38T56(config, "psu", 4500000/2)); - psu.set_int_vector(0x0020); - psu.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); - psu.read_a().set(FUNC(exchess_state::ram_data_r)); - psu.write_a().set(FUNC(exchess_state::ram_data_w)); - psu.write_a().append(FUNC(exchess_state::lcd_data_w)); - psu.read_b().set_ioport("IN.1"); - - // video hardware - HLCD0538(config, m_lcd1, 310); // measured - m_lcd1->write_cols().set(FUNC(exchess_state::lcd_output_w<0>)); - m_lcd1->write_interrupt().set(m_lcd2, FUNC(hlcd0539_device::lcd_w)); - - HLCD0539(config, m_lcd2, 0); - m_lcd2->write_cols().set(FUNC(exchess_state::lcd_output_w<1>)); - m_lcd2->write_interrupt().set("psu", FUNC(f38t56_device::ext_int_w)).invert(); - - PWM_DISPLAY(config, m_display).set_size(8, 26+34); - m_display->set_interpolation(0.2); - config.set_default_layout(layout_saitek_exchess); - - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG)); - screen.set_refresh_hz(60); - screen.set_size(1020/1.5, 1080/1.5); - screen.set_visarea_full(); -} - - - -/******************************************************************************* - ROM Definitions -*******************************************************************************/ - -ROM_START( exchess ) - ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD("sl90553", 0x0000, 0x1000, CRC(a61b0c7e) SHA1(a13b11a93f78236223c5c0b9879a93284b7f7525) ) - - ROM_REGION( 852610, "screen", 0 ) - ROM_LOAD("exchess.svg", 0, 852610, CRC(cb36f9d3) SHA1(83be9b5d906d185b7cf6895f50992e7eea390c7a) ) -ROM_END - -} // anonymous namespace - - - -/******************************************************************************* - Drivers -*******************************************************************************/ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS -SYST( 1981, exchess, 0, 0, exchess, exchess, exchess_state, empty_init, "SciSys", "Executive Chess", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/saitek/exechess.cpp b/src/mame/saitek/exechess.cpp new file mode 100644 index 00000000000..006e592def6 --- /dev/null +++ b/src/mame/saitek/exechess.cpp @@ -0,0 +1,271 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Sean Riddle +/******************************************************************************* + +SciSys Executive Chess, handheld chesscomputer. +Also known as Senator Chess in Germany. + +Hardware notes: +- Fairchild 3870 MCU (variant with 4KB internal ROM) +- 1KB RAM (2*TC5514P) +- HLCD0538, HLCD0539, LCD screen + +*******************************************************************************/ + +#include "emu.h" + +#include "cpu/f8/f8.h" +#include "machine/f3853.h" +#include "video/hlcd0538.h" +#include "video/pwm.h" + +#include "screen.h" + +// internal artwork +#include "saitek_exechess.lh" + + +namespace { + +class exechess_state : public driver_device +{ +public: + exechess_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_lcd1(*this, "lcd1"), + m_lcd2(*this, "lcd2"), + m_display(*this, "display"), + m_battery(*this, "battery"), + m_inputs(*this, "IN.%u", 0) + { } + + void exechess(machine_config &config); + + // battery status indicator is not software controlled + DECLARE_INPUT_CHANGED_MEMBER(battery) { m_battery = newval; } + +protected: + virtual void machine_start() override; + +private: + // devices/pointers + required_device m_maincpu; + required_device m_lcd1; + required_device m_lcd2; + required_device m_display; + output_finder<> m_battery; + required_ioport_array<4> m_inputs; + + // address maps + void main_map(address_map &map); + void main_io(address_map &map); + + // I/O handlers + template void lcd_output_w(u64 data); + void lcd_data_w(u8 data); + + u16 ram_address() { return (m_ram_address[1] << 8 | m_ram_address[0]) & 0x3ff; } + template u8 ram_address_r(); + template void ram_address_w(u8 data); + u8 ram_data_r(); + void ram_data_w(u8 data); + + std::unique_ptr m_ram; + u8 m_ram_address[2] = { }; + u64 m_lcd_data[2] = { }; +}; + +void exechess_state::machine_start() +{ + m_battery.resolve(); + m_ram = make_unique_clear(0x400); + + // register for savestates + save_pointer(NAME(m_ram), 0x400); + save_item(NAME(m_ram_address)); + save_item(NAME(m_lcd_data)); +} + + + +/******************************************************************************* + I/O +*******************************************************************************/ + +// LCD + +template +void exechess_state::lcd_output_w(u64 data) +{ + m_lcd_data[N] = data; + m_display->matrix(m_lcd_data[0] & 0xff, m_lcd_data[1] << 26 | m_lcd_data[0] >> 8); +} + +void exechess_state::lcd_data_w(u8 data) +{ + // P40: HLCD0539 data + // P44: HLCD0538 data + m_lcd1->data_w(BIT(data, 4)); + m_lcd2->data_w(BIT(data, 0)); + + if (~m_ram_address[1] & 4) + { + m_lcd1->clk_w(1); m_lcd1->clk_w(0); + m_lcd2->clk_w(1); m_lcd2->clk_w(0); + } +} + + +// 1KB RAM (port-mapped) + +template +void exechess_state::ram_address_w(u8 data) +{ + // P00-P07: RAM A0-A7 + // P10-P11: RAM A8-A9 + // P12: RAM CE + m_ram_address[N] = data; +} + +template +u8 exechess_state::ram_address_r() +{ + u8 data = m_ram_address[N]; + + // P13: Enter button + return (N) ? data | (m_inputs[0]->read() & 8) : data; +} + +void exechess_state::ram_data_w(u8 data) +{ + if (m_ram_address[1] & 4) + m_ram[ram_address()] = data; +} + +u8 exechess_state::ram_data_r() +{ + return (m_ram_address[1] & 4) ? m_ram[ram_address()] : 0; +} + + + +/******************************************************************************* + Address Maps +*******************************************************************************/ + +void exechess_state::main_map(address_map &map) +{ + map.global_mask(0xfff); + map(0x0000, 0x0fff).rom(); +} + +void exechess_state::main_io(address_map &map) +{ + map(0x00, 0x00).rw(FUNC(exechess_state::ram_address_r<0>), FUNC(exechess_state::ram_address_w<0>)); + map(0x01, 0x01).rw(FUNC(exechess_state::ram_address_r<1>), FUNC(exechess_state::ram_address_w<1>)); + map(0x04, 0x07).rw("psu", FUNC(f38t56_device::read), FUNC(f38t56_device::write)); +} + + + +/******************************************************************************* + Input Ports +*******************************************************************************/ + +static INPUT_PORTS_START( exechess ) + PORT_START("IN.0") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") + PORT_BIT(0xf7, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("IN.1") + PORT_BIT(0x01, 0x01, IPT_CUSTOM) PORT_CONDITION("IN.2", 0x51, NOTEQUALS, 0x00) + PORT_BIT(0x02, 0x02, IPT_CUSTOM) PORT_CONDITION("IN.2", 0x32, NOTEQUALS, 0x00) + PORT_BIT(0x04, 0x04, IPT_CUSTOM) PORT_CONDITION("IN.2", 0xa4, NOTEQUALS, 0x00) + PORT_BIT(0x08, 0x08, IPT_CUSTOM) PORT_CONDITION("IN.2", 0xc8, NOTEQUALS, 0x00) + PORT_BIT(0x30, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("New Game") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_F) PORT_NAME("2nd F") + + PORT_START("IN.2") // square 'd-pad' (8-way, so define joystick) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Cursor Left") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP) PORT_CODE(KEYCODE_UP) PORT_NAME("Cursor Up") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Cursor Right") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Cursor Down") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) // ul + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) // ur + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) // dl + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) // dr + + PORT_START("IN.3") + PORT_CONFNAME( 0x01, 0x00, "Battery Status" ) PORT_CHANGED_MEMBER(DEVICE_SELF, exechess_state, battery, 0) + PORT_CONFSETTING( 0x01, "Low" ) + PORT_CONFSETTING( 0x00, DEF_STR( Normal ) ) +INPUT_PORTS_END + + + +/******************************************************************************* + Machine Configs +*******************************************************************************/ + +void exechess_state::exechess(machine_config &config) +{ + // basic machine hardware + F8(config, m_maincpu, 4500000/2); // measured + m_maincpu->set_addrmap(AS_PROGRAM, &exechess_state::main_map); + m_maincpu->set_addrmap(AS_IO, &exechess_state::main_io); + m_maincpu->set_irq_acknowledge_callback("psu", FUNC(f38t56_device::int_acknowledge)); + + f38t56_device &psu(F38T56(config, "psu", 4500000/2)); + psu.set_int_vector(0x0020); + psu.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); + psu.read_a().set(FUNC(exechess_state::ram_data_r)); + psu.write_a().set(FUNC(exechess_state::ram_data_w)); + psu.write_a().append(FUNC(exechess_state::lcd_data_w)); + psu.read_b().set_ioport("IN.1"); + + // video hardware + HLCD0538(config, m_lcd1, 310); // measured + m_lcd1->write_cols().set(FUNC(exechess_state::lcd_output_w<0>)); + m_lcd1->write_interrupt().set(m_lcd2, FUNC(hlcd0539_device::lcd_w)); + + HLCD0539(config, m_lcd2, 0); + m_lcd2->write_cols().set(FUNC(exechess_state::lcd_output_w<1>)); + m_lcd2->write_interrupt().set("psu", FUNC(f38t56_device::ext_int_w)).invert(); + + PWM_DISPLAY(config, m_display).set_size(8, 26+34); + m_display->set_interpolation(0.2); + config.set_default_layout(layout_saitek_exechess); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG)); + screen.set_refresh_hz(60); + screen.set_size(1020/1.5, 1080/1.5); + screen.set_visarea_full(); +} + + + +/******************************************************************************* + ROM Definitions +*******************************************************************************/ + +ROM_START( exechess ) + ROM_REGION( 0x1000, "maincpu", 0 ) + ROM_LOAD("sl90553", 0x0000, 0x1000, CRC(a61b0c7e) SHA1(a13b11a93f78236223c5c0b9879a93284b7f7525) ) + + ROM_REGION( 852610, "screen", 0 ) + ROM_LOAD("exechess.svg", 0, 852610, CRC(cb36f9d3) SHA1(83be9b5d906d185b7cf6895f50992e7eea390c7a) ) +ROM_END + +} // anonymous namespace + + + +/******************************************************************************* + Drivers +*******************************************************************************/ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +SYST( 1981, exechess, 0, 0, exechess, exechess, exechess_state, empty_init, "SciSys", "Executive Chess", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) -- cgit v1.2.3