From 9e76c4c65a7bd7fd55d1a58c5a34bebfa1d81a80 Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 1 May 2022 23:07:52 +0200 Subject: New working machines -------------------- Scrabble Lexor - Computer Word Game [hap, Sean Riddle] --- scripts/target/mame/mess.lua | 6 ++ src/mame/drivers/scrablex.cpp | 237 ++++++++++++++++++++++++++++++++++++++++++ src/mame/layout/scrablex.lay | 21 ++++ src/mame/mame.lst | 3 + src/mame/mess.flt | 1 + 5 files changed, 268 insertions(+) create mode 100644 src/mame/drivers/scrablex.cpp create mode 100644 src/mame/layout/scrablex.lay diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 2f49b9994dc..e53e9a96958 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1403,6 +1403,7 @@ function linkProjects_mame_mess(_target, _subtarget) "sanyo", "saturn", "segacons", + "selchow", "sequential", "sgi", "sharp", @@ -3689,6 +3690,11 @@ files { MAME_DIR .. "src/mame/machine/megacdcd.h", } +createMESSProjects(_target, _subtarget, "selchow") +files { + MAME_DIR .. "src/mame/drivers/scrablex.cpp", +} + createMESSProjects(_target, _subtarget, "sequential") files { MAME_DIR .. "src/mame/drivers/prophet600.cpp", diff --git a/src/mame/drivers/scrablex.cpp b/src/mame/drivers/scrablex.cpp new file mode 100644 index 00000000000..5f64d9a511f --- /dev/null +++ b/src/mame/drivers/scrablex.cpp @@ -0,0 +1,237 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Sean Riddle +/******************************************************************************* + +Selchow & Righter Scrabble Lexor +It's a tabletop scrabble game/scorekeeper. + +Hardware notes: +- PCB label: PB-074 +- Fujitsu MB8841 MCU +- 8-digit 14-seg LEDs, 2-bit sound + +There's also a version of this game on a Panasonic MN1405 MCU. + +*******************************************************************************/ + +#include "emu.h" +#include "cpu/mb88xx/mb88xx.h" +#include "sound/spkrdev.h" +#include "video/pwm.h" +#include "speaker.h" + +#include "scrablex.lh" + + +namespace { + +class scrablex_state : public driver_device +{ +public: + scrablex_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_speaker(*this, "speaker"), + m_inputs(*this, "IN.%u", 0) + { } + + void scrablex(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + required_device m_maincpu; + required_device m_display; + required_device m_speaker; + required_ioport_array<5> m_inputs; + + void write_o(u8 data); + void write_p(u8 data); + template u8 read_r(); + template void write_r(u8 data); + + u8 m_inp_mux = 0; + u8 m_r[4] = { }; +}; + +void scrablex_state::machine_start() +{ + // register for savestates + save_item(NAME(m_inp_mux)); + save_item(NAME(m_r)); +} + + + +/******************************************************************************* + I/O +*******************************************************************************/ + +void scrablex_state::write_o(u8 data) +{ + // O0-O7: digit select (uses index 8-15) + m_display->write_my((1 << (data & 0xf)) >> 8); +} + +void scrablex_state::write_p(u8 data) +{ + // P0-P3: input mux part + m_inp_mux = (m_inp_mux & ~0xf) | (~data & 0xf); +} + +template +u8 scrablex_state::read_r() +{ + u16 data = 0; + + // R0-R8: multiplexed inputs + for (int i = 0; i < 5; i++) + if (BIT(m_inp_mux, i)) + data |= m_inputs[i]->read(); + + return ~data >> (N * 4) & 0xf; +} + +template +void scrablex_state::write_r(u8 data) +{ + // R0-R13: digit segments + m_r[N] = ~data & 0xf; + + u16 digit_data = 0; + for (int i = 0; i < 4; i++) + digit_data = (digit_data << 4) | (m_r[i ^ 3]); + + digit_data = bitswap<14>(digit_data,10,8,6,12,11,7,9,13,5,4,3,2,1,0); + m_display->write_mx(digit_data); + + // R14,R15: speaker out + // R15: input mux part + if (N == 3) + { + m_speaker->level_w(data >> 2 & 3); + m_inp_mux = (m_inp_mux & 0xf) | (~data << 1 & 0x10); + } +} + + + +/******************************************************************************* + Input Ports +*******************************************************************************/ + +static INPUT_PORTS_START( scrablex ) + PORT_START("IN.0") + PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + + PORT_START("IN.1") + PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT( 0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + + PORT_START("IN.2") + PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT( 0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT( 0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT( 0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR('*') + + PORT_START("IN.3") + PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("Double") + PORT_BIT( 0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_NAME("Triple") + PORT_BIT( 0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_NAME("Word") + PORT_BIT( 0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_NAME("Bonus") + PORT_BIT( 0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_NAME("Minus") + PORT_BIT( 0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_NAME("Clear") + PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_NAME("Enter") + PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.4") + PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_NAME("Flash") + PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_NAME("Solo") + PORT_BIT( 0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_NAME("Score") + PORT_BIT( 0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT( 0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT( 0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT( 0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_NAME("Timer") + PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME("Review") +INPUT_PORTS_END + + + +/******************************************************************************* + Machine Configs +*******************************************************************************/ + +void scrablex_state::scrablex(machine_config &config) +{ + // basic machine hardware + MB8841(config, m_maincpu, 500000); // approximation - RC osc. R=15K, C=100pF + m_maincpu->write_o().set(FUNC(scrablex_state::write_o)); + m_maincpu->write_p().set(FUNC(scrablex_state::write_p)); + m_maincpu->read_r<0>().set(FUNC(scrablex_state::read_r<0>)); + m_maincpu->read_r<1>().set(FUNC(scrablex_state::read_r<1>)); + m_maincpu->read_r<2>().set(FUNC(scrablex_state::read_r<2>)); + m_maincpu->read_r<3>().set(FUNC(scrablex_state::read_r<3>)); + m_maincpu->write_r<0>().set(FUNC(scrablex_state::write_r<0>)); + m_maincpu->write_r<1>().set(FUNC(scrablex_state::write_r<1>)); + m_maincpu->write_r<2>().set(FUNC(scrablex_state::write_r<2>)); + m_maincpu->write_r<3>().set(FUNC(scrablex_state::write_r<3>)); + + // video hardware + PWM_DISPLAY(config, m_display).set_size(8, 14); + m_display->set_segmask(0xff, 0x3fff); + config.set_default_layout(layout_scrablex); + + // sound hardware + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker); + static const double speaker_levels[4] = { 0.0, 1.0, -1.0, 0.0 }; + m_speaker->set_levels(4, speaker_levels); + m_speaker->add_route(ALL_OUTPUTS, "mono", 0.125); +} + + + +/******************************************************************************* + ROM Definitions +*******************************************************************************/ + +ROM_START( scrablex ) + ROM_REGION( 0x0800, "maincpu", 0 ) + ROM_LOAD( "mb8841_320m", 0x0000, 0x0800, CRC(bef4ab5a) SHA1(44e385225c5e8818ed93c3654a294aa412042e34) ) +ROM_END + +} // anonymous namespace + + + +/******************************************************************************* + Drivers +*******************************************************************************/ + +// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +CONS( 1980, scrablex, 0, 0, scrablex, scrablex, scrablex_state, empty_init, "Selchow & Righter", "Scrabble Lexor - Computer Word Game", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/layout/scrablex.lay b/src/mame/layout/scrablex.lay new file mode 100644 index 00000000000..11a41ed9fd3 --- /dev/null +++ b/src/mame/layout/scrablex.lay @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 131b0096c4d..ec036773395 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -37580,6 +37580,9 @@ scorpio // @source:scotrsht.cpp scotrsht // GX545 (c) 1985 +@source:scrablex.cpp +scrablex // Selchow & Righter + @source:scramble.cpp 800fath // (c) 1981 Amenip + U.S. Billiards license 800fatha // (c) 1981 Amenip + U.S. Billiards license diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 27eab2769e2..76456ecece3 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -950,6 +950,7 @@ sbrain.cpp sc2.cpp scopus.cpp scorpion.cpp +scrablex.cpp scv.cpp sdk51.cpp sdk80.cpp -- cgit v1.2.3