summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2025-01-22 17:40:43 +0100
committer hap <happppp@users.noreply.github.com>2025-01-22 18:55:24 +0100
commitb2ac7b291f8f91bf7d968423c652418a12a86a5b (patch)
tree082cfec20e45e822d4eab3a70b8dc749c73dde26
parentb4698518fffba04a4d21783efe17a9701bede8e0 (diff)
New working systems
------------------- Pocketchess (CXG) [hap, Sean Riddle]
-rw-r--r--src/mame/cxg/computachess.cpp3
-rw-r--r--src/mame/cxg/junior.cpp20
-rw-r--r--src/mame/cxg/pchess.cpp220
-rw-r--r--src/mame/handheld/hh_hmcs40.cpp6
-rw-r--r--src/mame/layout/cxg_pchess.lay74
-rw-r--r--src/mame/mame.lst3
6 files changed, 313 insertions, 13 deletions
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<int N>
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<int N>
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<hmcs40_cpu_device> m_maincpu;
+ required_device<pwm_display_device> m_display;
+ required_device<dac_1bit_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<int N> 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<int N>
+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 @@
+<?xml version="1.0"?>
+<!--
+license:CC0-1.0
+authors:hap
+-->
+<mamelayout version="2">
+
+<!-- NOTE: no chesspieces simulation here -->
+
+<!-- define elements -->
+
+ <element name="gray"><rect><color red="0.2" green="0.2" blue="0.2" /></rect></element>
+ <element name="lcdm"><rect><color red="0.54" green="0.57" blue="0.58" /></rect></element>
+
+ <element name="but" defstate="0">
+ <rect state="0"><color red="0.65" green="0.65" blue="0.66" /></rect>
+ <rect state="1"><color red="0.65" green="0.65" blue="0.66" alpha="0.7" /></rect>
+ </element>
+
+ <element name="text_ba"><text string="A1"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_bb"><text string="B2"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_bc"><text string="C3"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_bd"><text string="D4"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_be"><text string="E5"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_bf"><text string="F6"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_bg"><text string="G7"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_bh"><text string="H8"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_b1"><text string="CE"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_b2"><text string="LV"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_b3"><text string="MO"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+ <element name="text_b4"><text string="EN"><color red="0.8" green="0.8" blue="0.8" /></text></element>
+
+
+<!-- build screen -->
+
+ <view name="Internal Layout">
+ <bounds left="-1.5" right="20.5" top="-12.034" bottom="14" />
+
+ <screen index="0"><bounds x="5" y="-10.534" width="9" height="4.284" /></screen>
+ <element ref="lcdm" blend="multiply"><bounds x="4" y="-11" width="11" height="6" /></element>
+
+ <!-- buttons -->
+ <element ref="but" inputtag="IN.0" inputmask="0x01"><bounds x="0" y="0" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.1" inputmask="0x01"><bounds x="5" y="0" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.2" inputmask="0x01"><bounds x="10" y="0" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.3" inputmask="0x01"><bounds x="15" y="0" width="4" height="0.75" /></element>
+
+ <element ref="but" inputtag="IN.0" inputmask="0x02"><bounds x="0" y="3.5" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.1" inputmask="0x02"><bounds x="5" y="3.5" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.2" inputmask="0x02"><bounds x="10" y="3.5" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.3" inputmask="0x02"><bounds x="15" y="3.5" width="4" height="0.75" /></element>
+
+ <element ref="but" inputtag="IN.3" inputmask="0x04"><bounds x="0" y="10.5" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.0" inputmask="0x04"><bounds x="5" y="10.5" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.1" inputmask="0x04"><bounds x="10" y="10.5" width="4" height="0.75" /></element>
+ <element ref="but" inputtag="IN.2" inputmask="0x04"><bounds x="15" y="10.5" width="4" height="0.75" /></element>
+
+ <element ref="text_ba"><bounds x="0" y="-1.4" width="4" height="1.1" /></element>
+ <element ref="text_bb"><bounds x="5" y="-1.4" width="4" height="1.1" /></element>
+ <element ref="text_bc"><bounds x="10" y="-1.4" width="4" height="1.1" /></element>
+ <element ref="text_bd"><bounds x="15" y="-1.4" width="4" height="1.1" /></element>
+
+ <element ref="text_be"><bounds x="0" y="2.1" width="4" height="1.1" /></element>
+ <element ref="text_bf"><bounds x="5" y="2.1" width="4" height="1.1" /></element>
+ <element ref="text_bg"><bounds x="10" y="2.1" width="4" height="1.1" /></element>
+ <element ref="text_bh"><bounds x="15" y="2.1" width="4" height="1.1" /></element>
+
+ <element ref="text_b1"><bounds x="0" y="9.1" width="4" height="1.1" /></element>
+ <element ref="text_b2"><bounds x="5" y="9.1" width="4" height="1.1" /></element>
+ <element ref="text_b3"><bounds x="10" y="9.1" width="4" height="1.1" /></element>
+ <element ref="text_b4"><bounds x="15" y="9.1" width="4" height="1.1" /></element>
+ </view>
+
+</mamelayout>
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