diff options
Diffstat (limited to 'src/mame/drivers/mattelchess.cpp')
-rw-r--r-- | src/mame/drivers/mattelchess.cpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/mame/drivers/mattelchess.cpp b/src/mame/drivers/mattelchess.cpp new file mode 100644 index 00000000000..6abe760f962 --- /dev/null +++ b/src/mame/drivers/mattelchess.cpp @@ -0,0 +1,219 @@ +// license:BSD-3-Clause +// copyright-holders:hap +// thanks-to:Sean Riddle +/****************************************************************************** + +Mattel Computer Chess + +Hardware notes: +- INS8050 CPU @ 6MHz (4KB internal ROM, 256 bytes internal RAM) +- 2*HLCD0569(also seen with 2*HLCD0601, functionally same?) +- custom LCD screen with chess squares background + +TODO: +- It goes bonkers at computer's turn, it reads from LCD RAM and seems it doesn't + get the data it expects +- add SAVE switch +- internal artwork + +******************************************************************************/ + +#include "emu.h" +#include "cpu/mcs48/mcs48.h" +#include "video/hlcd0515.h" +#include "screen.h" + + +namespace { + +class mchess_state : public driver_device +{ +public: + mchess_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_lcd(*this, "lcd%u", 0), + m_inputs(*this, "IN.%u", 0), + m_out_x(*this, "%u.%u.%u", 0U, 0U, 0U) + { } + + void mchess(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + // devices/pointers + required_device<mcs48_cpu_device> m_maincpu; + required_device_array<hlcd0569_device, 2> m_lcd; + required_ioport_array<3> m_inputs; + output_finder<2, 8, 22> m_out_x; + + u8 m_inp_mux; + u8 m_lcd_control; + + // I/O handlers + template<int Sel> DECLARE_WRITE32_MEMBER(lcd_output_w); + DECLARE_WRITE8_MEMBER(input_w); + DECLARE_READ8_MEMBER(input_r); + DECLARE_WRITE8_MEMBER(lcd_w); + DECLARE_READ8_MEMBER(lcd_r); +}; + +void mchess_state::machine_start() +{ + // resolve handlers + m_out_x.resolve(); + + // zerofill + m_inp_mux = 0; + m_lcd_control = 0; + + // register for savestates + save_item(NAME(m_inp_mux)); + save_item(NAME(m_lcd_control)); +} + + +/****************************************************************************** + Devices, I/O +******************************************************************************/ + +template<int Sel> +WRITE32_MEMBER(mchess_state::lcd_output_w) +{ + // output to x.y.z where x = chip, y = row, z = col + // up to 22 columns used + for (int i = 0; i < 22; i++) + m_out_x[Sel][offset][i] = BIT(data, i); +} + +WRITE8_MEMBER(mchess_state::input_w) +{ + // d0,d5,d6: input mux + m_inp_mux = (~data >> 4 & 6) | (~data & 1); +} + +READ8_MEMBER(mchess_state::input_r) +{ + u8 data = 0; + + // d1-d4,d7: multiplexed inputs + for (int i = 0; i < 3; i++) + if (BIT(m_inp_mux, i)) + data |= m_inputs[i]->read(); + + return ~data; +} + +WRITE8_MEMBER(mchess_state::lcd_w) +{ + // d0: both LCDC VDRIVE + // d1: N/C + + // d3: 1st LCDC _CS + // d6: 2nd LCDC _CS + m_lcd[0]->cs_w(BIT(data, 3)); + m_lcd[1]->cs_w(BIT(data, 6)); + + // d4: both LCDC CLOCK + // d5: both LCDC DATA IN + for (int i = 0; i < 2; i++) + { + m_lcd[i]->clock_w(BIT(data, 4)); + m_lcd[i]->data_w(BIT(data, 5)); + } + + m_lcd_control = data; +} + +READ8_MEMBER(mchess_state::lcd_r) +{ + // d2: 1st LCDC DATA OUT + // d7: 2nd LCDC DATA OUT + u8 r0 = m_lcd[0]->data_r(); + u8 r1 = m_lcd[1]->data_r(); + return (0x84^0xff) | r0 << 2 | r1 << 7; +} + + + +/****************************************************************************** + Input Ports +******************************************************************************/ + +static INPUT_PORTS_START( mchess ) + PORT_START("IN.0") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Player vs. Player") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Machine vs. Machine") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Player vs. Machine") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Level") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("IN.1") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Move") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") + + PORT_START("IN.2") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter Move") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Enter Position") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Color") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Take Back") +INPUT_PORTS_END + + + +/****************************************************************************** + Machine Configs +******************************************************************************/ + +void mchess_state::mchess(machine_config &config) +{ + /* basic machine hardware */ + I8050(config, m_maincpu, 6_MHz_XTAL); + m_maincpu->p1_out_cb().set(FUNC(mchess_state::input_w)); + m_maincpu->p1_in_cb().set(FUNC(mchess_state::input_r)); + m_maincpu->p2_out_cb().set(FUNC(mchess_state::lcd_w)); + m_maincpu->p2_in_cb().set(FUNC(mchess_state::lcd_r)); + + /* video hardware */ + HLCD0569(config, m_lcd[0], 500); // C=0.01uF + m_lcd[0]->write_cols().set(FUNC(mchess_state::lcd_output_w<0>)); + HLCD0569(config, m_lcd[1], 500); // C=0.01uF + m_lcd[1]->write_cols().set(FUNC(mchess_state::lcd_output_w<1>)); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG)); + screen.set_svg_region("svg"); + screen.set_refresh_hz(50); + screen.set_size(977, 1080); + screen.set_visarea_full(); +} + + + +/****************************************************************************** + ROM Definitions +******************************************************************************/ + +ROM_START( mchess ) + ROM_REGION( 0x1000, "maincpu", 0 ) + ROM_LOAD("ins8050-6hwu_n", 0x0000, 0x1000, CRC(de272323) SHA1(9ba323b614504e20b25c86d290c0667f0bbf6c6b) ) + + ROM_REGION( 796334, "svg", 0) + ROM_LOAD( "mchess.svg", 0, 796334, CRC(88792457) SHA1(cc8b654829532a8cbb7447176436c113ac584bba) ) +ROM_END + +} // anonymous namespace + + + +/****************************************************************************** + Drivers +******************************************************************************/ + +// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +CONS( 1980, mchess, 0, 0, mchess, mchess, mchess_state, empty_init, "Mattel", "Computer Chess (Mattel)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW | MACHINE_NOT_WORKING ) |