From c461a310efadb0d0896583443ae6fa3bd100db86 Mon Sep 17 00:00:00 2001 From: hap Date: Fri, 3 Mar 2023 22:42:13 +0100 Subject: New working systems ------------------- My Little Computer [hap, Sean Riddle] --- src/mame/handheld/hh_cop400.cpp | 165 +++++++++++++++++++++++++++++++++++++++- src/mame/layout/lilcomp.lay | 45 +++++++++++ src/mame/mame.lst | 1 + 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 src/mame/layout/lilcomp.lay diff --git a/src/mame/handheld/hh_cop400.cpp b/src/mame/handheld/hh_cop400.cpp index ee173a2a0ac..d865733e080 100644 --- a/src/mame/handheld/hh_cop400.cpp +++ b/src/mame/handheld/hh_cop400.cpp @@ -42,6 +42,7 @@ TODO: #include "lafootb.lh" #include "lchicken.lh" // clickable #include "lightfgt.lh" // clickable +#include "lilcomp.lh" #include "mbaskb2.lh" #include "mdallas.lh" #include "msoccer2.lh" @@ -66,7 +67,8 @@ public: m_inputs(*this, "IN.%u", 0) { } - virtual DECLARE_INPUT_CHANGED_MEMBER(reset_button); + DECLARE_INPUT_CHANGED_MEMBER(reset_button); + DECLARE_INPUT_CHANGED_MEMBER(power_button); protected: virtual void machine_start() override; @@ -87,6 +89,7 @@ protected: u16 m_inp_mux = ~0; // multiplexed inputs mask u16 read_inputs(int columns, u16 colmask = ~0); + void set_power(bool state); }; @@ -105,6 +108,7 @@ void hh_cop400_state::machine_start() void hh_cop400_state::machine_reset() { + set_power(true); } @@ -136,6 +140,19 @@ INPUT_CHANGED_MEMBER(hh_cop400_state::reset_button) m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); } +INPUT_CHANGED_MEMBER(hh_cop400_state::power_button) +{ + set_power((bool)param); +} + +void hh_cop400_state::set_power(bool state) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE); + + if (m_display && !state) + m_display->clear(); +} + /*************************************************************************** @@ -1717,7 +1734,7 @@ ROM_END Milton Bradley Electronic Lightfight * COP421L MCU label /B119 COP421L-HLA/N - * LED matrix, 1-bit sound + * 5*5 leds, 1-bit sound Xbox-shaped electronic game for 2 or more players, with long diagonal buttons next to each outer LED. The main object of the game is to pinpoint a light @@ -2462,6 +2479,148 @@ ROM_END + + +/*************************************************************************** + + Texas Instruments My Little Computer + * PCB label: 1066659-4, 17-92-81 + * COP444L MCU label COP444L 1066666 + * 4*4 leds, 1-bit sound + + It's an educational toy for young children. Overlays were included for the + mini games, MAME external artwork is required for these. + + Strangely, TI didn't use their own brand MCU for this toy. + +***************************************************************************/ + +class lilcomp_state : public hh_cop400_state +{ +public: + lilcomp_state(const machine_config &mconfig, device_type type, const char *tag) : + hh_cop400_state(mconfig, type, tag), + m_power_timer(*this, "power") + { } + + void lilcomp(machine_config &config); + +private: + required_device m_power_timer; + + void update_display(); + void write_d(u8 data); + void write_l(u8 data); + void write_g(u8 data); + u8 read_g(); + DECLARE_WRITE_LINE_MEMBER(write_sk); + + TIMER_DEVICE_CALLBACK_MEMBER(power_off) { set_power(false); } +}; + +// handlers + +void lilcomp_state::update_display() +{ + m_display->matrix(m_l >> 4, ~m_d); +} + +void lilcomp_state::write_d(u8 data) +{ + // D: led data + m_d = data; + update_display(); +} + +void lilcomp_state::write_l(u8 data) +{ + // L0-L2: input mux + // L3: N/C + m_inp_mux = data & 7; + + // L4-L7: led select + m_l = data; + update_display(); +} + +void lilcomp_state::write_g(u8 data) +{ + m_g = data; +} + +u8 lilcomp_state::read_g() +{ + // G: multiplexed inputs + return read_inputs(3, m_g); +} + +WRITE_LINE_MEMBER(lilcomp_state::write_sk) +{ + if (state == m_sk) + return; + + // SK: trigger power off after a short delay + m_power_timer->adjust(state ? attotime::from_msec(100) : attotime::never); + m_sk = state; +} + +// config + +static INPUT_PORTS_START( lilcomp ) + PORT_START("IN.0") // L0 port G + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Cursor Down") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Cursor Right") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_UP) PORT_NAME("Cursor Up") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Cursor Left") + + PORT_START("IN.1") // L1 port G + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POWER_OFF ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Go") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Code 5") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CODE(KEYCODE_X) + + PORT_START("IN.2") // L2 port G + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Code 1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Code 4") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Code 3") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Code 2") + + PORT_START("IN.3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_POWER_ON ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_cop400_state, power_button, true) +INPUT_PORTS_END + +void lilcomp_state::lilcomp(machine_config &config) +{ + // basic machine hardware + COP444L(config, m_maincpu, 800000); // approximation - RC osc. R=46.4K, C=100pF + m_maincpu->set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed + m_maincpu->write_d().set(FUNC(lilcomp_state::write_d)); + m_maincpu->write_l().set(FUNC(lilcomp_state::write_l)); + m_maincpu->write_g().set(FUNC(lilcomp_state::write_g)); + m_maincpu->read_g().set(FUNC(lilcomp_state::read_g)); + m_maincpu->write_sk().set(FUNC(lilcomp_state::write_sk)); + m_maincpu->write_so().set(m_speaker, FUNC(speaker_sound_device::level_w)); + + TIMER(config, "power").configure_generic(FUNC(lilcomp_state::power_off)); + + // video hardware + PWM_DISPLAY(config, m_display).set_size(4, 4); + config.set_default_layout(layout_lilcomp); + + // sound hardware + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); +} + +// roms + +ROM_START( lilcomp ) + ROM_REGION( 0x0800, "maincpu", 0 ) + ROM_LOAD( "cop444l_1066666", 0x0000, 0x0800, CRC(fb4674d2) SHA1(2c38c2f0bd4222166298a50dec88339b06362005) ) +ROM_END + + + } // anonymous namespace /*************************************************************************** @@ -2502,5 +2661,7 @@ COMP( 1984, solution, 0, 0, scat, solution, scat_state, e CONS( 1987, vidchal, 0, 0, vidchal, vidchal, vidchal_state, empty_init, "Select Merchandise", "Video Challenger", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) +CONS( 1989, lilcomp, 0, 0, lilcomp, lilcomp, lilcomp_state, empty_init, "Texas Instruments", "My Little Computer", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK ) + // ***: As far as MAME is concerned, the game is emulated fine. But for it to be playable, it requires interaction // with other, unemulatable, things eg. game board/pieces, book, playing cards, pen & paper, etc. diff --git a/src/mame/layout/lilcomp.lay b/src/mame/layout/lilcomp.lay new file mode 100644 index 00000000000..6394aa5e62f --- /dev/null +++ b/src/mame/layout/lilcomp.lay @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 5fd60cdff59..a167abc1a21 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -18551,6 +18551,7 @@ h2hsoccerc // Coleco lafootb // Mattel lchicken // LJN lightfgt // Milton Bradley +lilcomp // Texas Instruments mbaskb2 // Mattel mdallas // Mattel msoccer2 // Mattel -- cgit v1.2.3