From 8727bcc611c07e354750a0b03ddc21b95e4347fa Mon Sep 17 00:00:00 2001 From: hap Date: Fri, 20 Sep 2024 23:55:14 +0200 Subject: New working systems ------------------- Sphinx Royal [hap, Sean Riddle] --- src/mame/cxg/royal.cpp | 290 +++++++++++++++++++ src/mame/layout/cxg_royal.lay | 510 ++++++++++++++++++++++++++++++++++ src/mame/layout/saitek_companion3.lay | 76 ++--- src/mame/mame.lst | 3 + 4 files changed, 841 insertions(+), 38 deletions(-) create mode 100644 src/mame/cxg/royal.cpp create mode 100644 src/mame/layout/cxg_royal.lay diff --git a/src/mame/cxg/royal.cpp b/src/mame/cxg/royal.cpp new file mode 100644 index 00000000000..f565fb5e7bd --- /dev/null +++ b/src/mame/cxg/royal.cpp @@ -0,0 +1,290 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Sean Riddle +/******************************************************************************* + +CXG Sphinx Royal (CXG-240) + +NOTE: Turn the power switch off before exiting MAME, otherwise NVRAM won't save +properly. Only turn power off when it's the user's turn to move. + +TODO: +- actually add nvram (needs to be added to hmcs400) + +Hardware notes: +- HD614042S, 4MHz XTAL +- optional LCD panel(s), see below +- chessboard buttons, 16+4 LEDs, piezo + +Royal has 2 LCD panels, Supra has 1 (D12 pin is low), Granada and others have 0. +The LCD panel has 4 7segs and 2 unused segments: an x in the middle, and a white +square under the first digit. + +The 1992 versions by National Telecommunications System Ltd (Granada CXG-347, +Sierra, Seville) have a lower-speed 3.58MHz XTAL, but since none of them have +LCD panels, users won't notice the slower chess clocks. + +Excluding other brands with the same product name, HD614042SJ02 MCU was used in: +- CXG Sphinx Royal (model 240) +- CXG Sphinx Supra (model 048) +- CXG Sphinx Granada (model 247/347) +- CXG Sphinx Seville (model 807) +- CXG Sphinx Sierra (model 647W) +- CXG Sphinx Alicante (model 328, suspected) +- Excalibur Chess Wizard (model 807E), Excalibur brand Sphinx Seville +- Excalibur Stiletto (model 328E/638E), Excalibur brand Sphinx Alicante (suspected) + +*******************************************************************************/ + +#include "emu.h" + +#include "cpu/hmcs400/hmcs400.h" +#include "machine/sensorboard.h" +#include "sound/dac.h" +#include "video/pwm.h" + +#include "speaker.h" + +// internal artwork +#include "cxg_royal.lh" + + +namespace { + +class royal_state : public driver_device +{ +public: + royal_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_led_pwm(*this, "led_pwm"), + m_lcd_pwm(*this, "lcd_pwm"), + m_dac(*this, "dac"), + m_inputs(*this, "IN.%u", 0), + m_out_digit(*this, "digit%u", 0U) + { } + + void royal(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + // devices/pointers + required_device m_maincpu; + required_device m_board; + required_device m_led_pwm; + required_device m_lcd_pwm; + required_device m_dac; + required_ioport_array<2> m_inputs; + output_finder<8> m_out_digit; + + u8 m_inp_mux = 0; + u8 m_lcd_com = 0; + u16 m_lcd_segs = 0; + u8 m_lcd_select = 0; + + // I/O handlers + void update_lcd(); + template void lcd_segs_w(u8 data); + void lcd_com_w(u8 data); + + template u8 board_r(); + template void input_w(u8 data); + void control_w(u16 data); + u16 input_r(); +}; + +void royal_state::machine_start() +{ + m_out_digit.resolve(); + + // register for savestates + save_item(NAME(m_inp_mux)); + save_item(NAME(m_lcd_com)); + save_item(NAME(m_lcd_segs)); + save_item(NAME(m_lcd_select)); +} + + + +/******************************************************************************* + I/O +*******************************************************************************/ + +// LCD + +void royal_state::update_lcd() +{ + for (int i = 0; i < 2; i++) + { + // LCD common is analog (voltage level) + const u8 com = population_count_32(m_lcd_com >> (i * 2) & 3); + const u16 data = (com == 0) ? m_lcd_segs : (com == 2) ? ~m_lcd_segs : 0; + + // 2 digits per common + for (int j = 0; j < 2; j++) + { + u8 digit = bitswap<8>(data >> (j * 8), 0,1,2,3,4,5,6,7); + m_lcd_pwm->write_row(m_lcd_select * 4 + i * 2 + j, digit); + } + } +} + +template +void royal_state::lcd_segs_w(u8 data) +{ + // R0x,R6x-R8x: LCD segment data + m_lcd_segs = (m_lcd_segs & ~(0xf << (N*4))) | (data << (N*4)); + update_lcd(); +} + +void royal_state::lcd_com_w(u8 data) +{ + // R50-R53: LCD common + m_lcd_com = data; + update_lcd(); +} + + +// misc + +template +u8 royal_state::board_r() +{ + // R1x,R2x: read chessboard + u8 data = 0; + + for (int i = 0; i < 8; i++) + if (BIT(m_inp_mux, i)) + data |= m_board->read_rank(i); + + return data >> (N * 4) & 0xf; +} + +template +void royal_state::input_w(u8 data) +{ + // R3x,R4x: input mux, LED data + m_inp_mux = (m_inp_mux & ~(0xf << (N*4))) | (data << (N*4)); + m_led_pwm->write_mx(~m_inp_mux); +} + +void royal_state::control_w(u16 data) +{ + // D4,D5: LED select + // D6-D9: status LEDs (direct) + m_led_pwm->write_my(data >> 4 & 0x3f); + + // D13: LCD panel select + m_lcd_select = BIT(data, 13); + update_lcd(); + + // D14: speaker out + m_dac->write(BIT(data, 14)); +} + +u16 royal_state::input_r() +{ + u16 data = 0; + + // D0,D1: read buttons + for (int i = 0; i < 2; i++) + if (m_inp_mux & m_inputs[i]->read()) + data |= 1 << i; + + // D10,D11: freq sel + // D12: 1/2 LCD panels + return data | 0x140c; +} + + + +/******************************************************************************* + Input Ports +*******************************************************************************/ + +static INPUT_PORTS_START( royal ) + PORT_START("IN.0") + 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_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Knight") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Bishop") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Rook") + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Queen") + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("King") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("IN.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Take Back") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_POWER_OFF) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("New Game") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Move") + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Level") + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Set-Up") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_O) PORT_NAME("Sound") +INPUT_PORTS_END + + + +/******************************************************************************* + Machine Configs +*******************************************************************************/ + +void royal_state::royal(machine_config &config) +{ + // basic machine hardware + HD614042(config, m_maincpu, 4_MHz_XTAL); + m_maincpu->write_r<0>().set(FUNC(royal_state::lcd_segs_w<0>)); + m_maincpu->read_r<1>().set(FUNC(royal_state::board_r<0>)); + m_maincpu->read_r<2>().set(FUNC(royal_state::board_r<1>)); + m_maincpu->write_r<3>().set(FUNC(royal_state::input_w<0>)); + m_maincpu->write_r<4>().set(FUNC(royal_state::input_w<1>)); + m_maincpu->write_r<5>().set(FUNC(royal_state::lcd_com_w)); + m_maincpu->write_r<6>().set(FUNC(royal_state::lcd_segs_w<3>)); + m_maincpu->write_r<7>().set(FUNC(royal_state::lcd_segs_w<2>)); + m_maincpu->write_r<8>().set(FUNC(royal_state::lcd_segs_w<1>)); + m_maincpu->write_d().set(FUNC(royal_state::control_w)); + m_maincpu->read_d().set(FUNC(royal_state::input_r)); + + 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)); + //m_board->set_nvram_enable(true); + + // video hardware + PWM_DISPLAY(config, m_lcd_pwm).set_size(8, 8); + m_lcd_pwm->set_segmask(0xff, 0x7f); + m_lcd_pwm->output_digit().set([this](offs_t offset, u64 data) { m_out_digit[offset] = data; }); + + PWM_DISPLAY(config, m_led_pwm).set_size(6, 8); + config.set_default_layout(layout_cxg_royal); + + // sound hardware + SPEAKER(config, "speaker").front_center(); + DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25); +} + + + +/******************************************************************************* + ROM Definitions +*******************************************************************************/ + +ROM_START( sroyal ) + ROM_REGION( 0x2000, "maincpu", 0 ) + ROM_LOAD("1988_105_newcrest_hd614042sj02", 0x0000, 0x2000, CRC(47334ac9) SHA1(b4dc930e34926f1b33f6d247af45627c891202ff) ) +ROM_END + +} // anonymous namespace + + + +/******************************************************************************* + Drivers +*******************************************************************************/ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +SYST( 1988, sroyal, 0, 0, royal, royal, royal_state, empty_init, "CXG Systems / Newcrest Technology / Intelligent Chess Software", "Sphinx Royal", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/layout/cxg_royal.lay b/src/mame/layout/cxg_royal.lay new file mode 100644 index 00000000000..3c84bbe556a --- /dev/null +++ b/src/mame/layout/cxg_royal.lay @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/saitek_companion3.lay b/src/mame/layout/saitek_companion3.lay index dae0f4d87d9..88ecbb8e39f 100644 --- a/src/mame/layout/saitek_companion3.lay +++ b/src/mame/layout/saitek_companion3.lay @@ -12,23 +12,23 @@ authors:hap - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -293,7 +293,7 @@ authors:hap - + @@ -308,26 +308,26 @@ authors:hap - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index c235a36400c..ec608ce075f 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -16656,6 +16656,9 @@ sgalaxyb @source:cxg/professor.cpp scprof +@source:cxg/royal.cpp +sroyal + @source:cxg/senterprise.cpp senterp senterpc -- cgit v1.2.3