From b2ac7b291f8f91bf7d968423c652418a12a86a5b Mon Sep 17 00:00:00 2001 From: hap Date: Wed, 22 Jan 2025 17:40:43 +0100 Subject: [PATCH] New working systems ------------------- Pocketchess (CXG) [hap, Sean Riddle] --- src/mame/cxg/computachess.cpp | 3 +- src/mame/cxg/junior.cpp | 20 +-- src/mame/cxg/pchess.cpp | 220 ++++++++++++++++++++++++++++++++ src/mame/handheld/hh_hmcs40.cpp | 6 +- src/mame/layout/cxg_pchess.lay | 74 +++++++++++ src/mame/mame.lst | 3 + 6 files changed, 313 insertions(+), 13 deletions(-) create mode 100644 src/mame/cxg/pchess.cpp create mode 100644 src/mame/layout/cxg_pchess.lay diff --git a/src/mame/cxg/computachess.cpp b/src/mame/cxg/computachess.cpp index ddbdb10362e..bac4e749c31 100644 --- a/src/mame/cxg/computachess.cpp +++ b/src/mame/cxg/computachess.cpp @@ -124,7 +124,8 @@ template void computachess_state::mux_w(u8 data) { // R2x,R3x: input mux, led data - m_inp_mux = (m_inp_mux & ~(0xf << (N*4))) | (data << (N*4)); + const u8 shift = N * 4; + m_inp_mux = (m_inp_mux & ~(0xf << shift)) | (data << shift); m_display->write_mx(m_inp_mux); } diff --git a/src/mame/cxg/junior.cpp b/src/mame/cxg/junior.cpp index d28706a7ebf..2291efe401a 100644 --- a/src/mame/cxg/junior.cpp +++ b/src/mame/cxg/junior.cpp @@ -21,14 +21,14 @@ Hardware notes: Sphinx Junior: - PCB label: CXG 237 600-002 - Hitachi HD614140H, 8MHz XTAL -- LCD with 4 7segs and custom segments (same as the one in CXG Pocket Chess) +- LCD with 4 7segs and custom segments (same as the one in CXG Pocketchess) - embedded non-electronic chessboard, piezo Fidelity Micro Chess Challenger (16 buttons): - PCB label: CXG 249 600-001 - rest is similar to Sphinx Junior -Fidelity MCC 12-button version has a HD44820 MCU instead. +Fidelity MCC 12-button version has a HD44820 MCU instead (see pchess.cpp). HD614140HA27 MCU is used in: - CXG Sphinx Junior @@ -111,14 +111,15 @@ INPUT_CHANGED_MEMBER(junior_state::on_button) void junior_state::update_lcd() { - m_lcd_pwm->write_row(0, m_lcd_com ? ~m_lcd_segs : m_lcd_segs); + const u32 lcd_segs = bitswap<30>(m_lcd_segs,4,12,13,5,27,20,17,9,1,24,15,7,29,22,18,10,2,25,14,6,28,21,16,8,0,23,19,11,3,26); + m_lcd_pwm->write_row(0, m_lcd_com ? ~lcd_segs : lcd_segs); } template void junior_state::lcd_segs_w(u8 data) { // R0x-R4x: LCD segment data, input mux - const u8 shift = N * 4 + 10; + const u8 shift = N * 4; m_lcd_segs = (m_lcd_segs & ~(0xf << shift)) | (data << shift); update_lcd(); } @@ -129,7 +130,8 @@ void junior_state::control_w(u16 data) m_lcd_com = data & 1; // D4-D13: LCD segment data - m_lcd_segs = (m_lcd_segs & ~0x3ff) | (data >> 4 & 0x3ff); + const u32 mask = 0x3ff << 20; + m_lcd_segs = (m_lcd_segs & ~mask) | (data << 16 & mask); update_lcd(); // D14: speaker out @@ -141,11 +143,11 @@ u16 junior_state::input_r() u16 data = 0; // D1: read buttons from R03-R43 - if ((m_lcd_segs >> 13 & 0x1ffff) & m_inputs->read()) + if ((m_lcd_segs >> 3 & 0x1ffff) & m_inputs->read()) data |= 2; // D2: R30 (freq sel) - data |= BIT(m_lcd_segs, 23) << 2; + data |= BIT(~m_lcd_segs, 12) << 2; return data | 9; } @@ -230,8 +232,8 @@ ROM_START( sjunior ) ROM_REGION( 0x2000, "maincpu", 0 ) ROM_LOAD("1988_newcrest_614140ha27", 0x0000, 0x2000, CRC(9eb77d94) SHA1(84306ee39986847f9ae82a1117dc6fb8bd309bab) ) - ROM_REGION( 57384, "screen", 0 ) - ROM_LOAD("sjunior.svg", 0, 57384, CRC(1b3d450f) SHA1(1b55bb2fe23d2e719258be196663ea117158cd35) ) + ROM_REGION( 57412, "screen", 0 ) + ROM_LOAD("cpchess.svg", 0, 57412, CRC(7859b1ac) SHA1(518c5cd08fa8562628345e8e28048c01c9e4edd6) ) ROM_END } // anonymous namespace diff --git a/src/mame/cxg/pchess.cpp b/src/mame/cxg/pchess.cpp new file mode 100644 index 00000000000..6c5936b8457 --- /dev/null +++ b/src/mame/cxg/pchess.cpp @@ -0,0 +1,220 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Sean Riddle +/******************************************************************************* + +CXG Pocketchess (model 219) + +It says "Pocket Chess" on the front of the handheld itself, "Pocketchess" on the +backside label, manual, box, and advertising. + +TODO: +- save switch does not work since MCU emulation doesn't support NVRAM + +Hardware notes: +- PCB label: CXG 219 600 001 +- Hitachi HD44820 @ ~400kHz (100K resistor on Fidelity MCC) +- LCD with 4 7segs and custom segments, piezo + +HD44820B63 MCU is used in: +- CXG Pocketchess +- Fidelity Micro Chess Challenger (12 buttons) (Fidelity brand Pocketchess) + +*******************************************************************************/ + +#include "emu.h" + +#include "cpu/hmcs40/hmcs40.h" +#include "sound/dac.h" +#include "video/pwm.h" + +#include "screen.h" +#include "speaker.h" + +// internal artwork +#include "cxg_pchess.lh" + + +namespace { + +class pchess_state : public driver_device +{ +public: + pchess_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_display(*this, "display"), + m_dac(*this, "dac"), + m_inputs(*this, "IN.%u", 0) + { } + + void pchess(machine_config &config); + +protected: + virtual void machine_start() override ATTR_COLD; + +private: + // devices/pointers + required_device m_maincpu; + required_device m_display; + required_device m_dac; + required_ioport_array<4> m_inputs; + + u8 m_inp_mux = 0; + u8 m_lcd_com = 0; + u32 m_lcd_segs = 0; + + // I/O handlers + void update_lcd(); + template void seg_w(u8 data); + u16 input_r(); + void control_w(u16 data); +}; + +void pchess_state::machine_start() +{ + // register for savestates + save_item(NAME(m_inp_mux)); + save_item(NAME(m_lcd_com)); + save_item(NAME(m_lcd_segs)); +} + + + +/******************************************************************************* + I/O +*******************************************************************************/ + +void pchess_state::update_lcd() +{ + // LCD common is analog (voltage level) + const u8 com = population_count_32(m_lcd_com & 3); + const u64 data = (com == 0) ? m_lcd_segs : (com == 2) ? ~m_lcd_segs : 0; + m_display->write_row(0, data); +} + +template +void pchess_state::seg_w(u8 data) +{ + // R0x-R6x: LCD segments + const u8 shift = N * 4; + m_lcd_segs = (m_lcd_segs & ~(0xf << shift)) | (data << shift); + update_lcd(); +} + +u16 pchess_state::input_r() +{ + u16 data = 0; + + // D13-D15: read buttons + for (int i = 0; i < 4; i++) + if (BIT(m_inp_mux, i)) + data |= m_inputs[i]->read() << 13; + + return ~data; +} + +void pchess_state::control_w(u16 data) +{ + // D1: speaker out + m_dac->write(BIT(data, 1)); + + // D3,D4: LCD common + m_lcd_com = data >> 3 & 3; + + // D7,D8: 2 more LCD segments + const u32 mask = 3 << 28; + m_lcd_segs = (m_lcd_segs & ~mask) | (data << 21 & mask); + update_lcd(); + + // D9-D12: input mux + m_inp_mux = ~data >> 9 & 0xf; +} + + + +/******************************************************************************* + Input Ports +*******************************************************************************/ + +static INPUT_PORTS_START( pchess ) + PORT_START("IN.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("A1") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("E5") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("LV") + + PORT_START("IN.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("B2") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("F6") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("MO") + + PORT_START("IN.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("C3") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("G7") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("EN") + + PORT_START("IN.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("D4") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("H8") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CE") +INPUT_PORTS_END + + + +/******************************************************************************* + Machine Configs +*******************************************************************************/ + +void pchess_state::pchess(machine_config &config) +{ + // basic machine hardware + HD44820(config, m_maincpu, 400'000); // approximation + m_maincpu->write_r<0>().set(FUNC(pchess_state::seg_w<0>)); + m_maincpu->write_r<1>().set(FUNC(pchess_state::seg_w<1>)); + m_maincpu->write_r<2>().set(FUNC(pchess_state::seg_w<2>)); + m_maincpu->write_r<3>().set(FUNC(pchess_state::seg_w<3>)); + m_maincpu->write_r<4>().set(FUNC(pchess_state::seg_w<4>)); + m_maincpu->write_r<5>().set(FUNC(pchess_state::seg_w<5>)); + m_maincpu->write_r<6>().set(FUNC(pchess_state::seg_w<6>)); + m_maincpu->write_d().set(FUNC(pchess_state::control_w)); + m_maincpu->read_d().set(FUNC(pchess_state::input_r)); + + // video hardware + PWM_DISPLAY(config, m_display).set_size(1, 30); + m_display->set_bri_levels(0.05); + config.set_default_layout(layout_cxg_pchess); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG)); + screen.set_refresh_hz(60); + screen.set_size(1920/4, 914/4); + screen.set_visarea_full(); + + // sound hardware + SPEAKER(config, "speaker").front_center(); + DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25); +} + + + +/******************************************************************************* + ROM Definitions +*******************************************************************************/ + +ROM_START( cpchess ) + ROM_REGION( 0x2000, "maincpu", 0 ) + ROM_LOAD("1985_white_and_allcock_hd44820b63", 0x0000, 0x2000, CRC(8decfb8f) SHA1(ac216663fe72cc98607ce44c033bc4b13b309ad1) ) + + ROM_REGION( 57412, "screen", 0 ) + ROM_LOAD("cpchess.svg", 0, 57412, CRC(7859b1ac) SHA1(518c5cd08fa8562628345e8e28048c01c9e4edd6) ) +ROM_END + +} // anonymous namespace + + + +/******************************************************************************* + Drivers +*******************************************************************************/ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +SYST( 1986, cpchess, 0, 0, pchess, pchess, pchess_state, empty_init, "CXG Systems / Newcrest Technology / Intelligent Software", "Pocketchess (CXG)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/handheld/hh_hmcs40.cpp b/src/mame/handheld/hh_hmcs40.cpp index d876e2ed056..39db0fd63bb 100644 --- a/src/mame/handheld/hh_hmcs40.cpp +++ b/src/mame/handheld/hh_hmcs40.cpp @@ -74,7 +74,7 @@ known chips: A50 HD44801 1981, CXG Sensor Computachess -> cxg/computachess.cpp A75 HD44801 1982, Alpha 8201 protection MCU -> alpha/alpha8201.* A85 HD44801 1982, SciSys Travel Sensor Chess -> saitek/tschess.cpp - *A92 HD44801 1982, SciSys Play Bridge Computer + *A92 HD44801 1982, SciSys Play Bridge Computer (have dump) B35 HD44801 1983, Alpha 8302 protection MCU (see 8201) B42 HD44801 1983, Alpha 8303 protection MCU (see 8201) *B43 HD44801 1983, Alpha 8304 protection MCU (see 8201) @@ -83,13 +83,13 @@ known chips: *A86 HD44820 1983, Chess King Pocket Micro / Mighty Midget *B46 HD44820 1984, Chess King Pocket Micro / Mighty Midget - *B63 HD44820 1985, CXG Pocket Chess (12 buttons) + B63 HD44820 1986, CXG Pocketchess -> cxg/pchess.cpp *A13 HD44840 1982, CXG Computachess II *A14 HD44840 1982, CXG Computachess II / Advanced Portachess B29 HD44860 1987, Diamond Bridge Computer -> handheld/dbridgec.cpp - *B55 HD44860 1987, Saitek Pro Bridge 100 + *B55 HD44860 1987, Saitek Pro Bridge 100 (have dump) *A04 HD44868 1984, SciSys Rapier A07 HD44868 1984, Chess King Pocket Micro De-Luxe -> chessking/pmicrodx.cpp diff --git a/src/mame/layout/cxg_pchess.lay b/src/mame/layout/cxg_pchess.lay new file mode 100644 index 00000000000..87b0789bdca --- /dev/null +++ b/src/mame/layout/cxg_pchess.lay @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 85991641d90..47c123956a3 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -16721,6 +16721,9 @@ sgalaxy sgalaxya sgalaxyb +@source:cxg/pchess.cpp +cpchess + @source:cxg/professor.cpp scprof