From ba38575a003326016c6e360b6233b36327adfd2c Mon Sep 17 00:00:00 2001 From: hap Date: Tue, 27 Apr 2021 17:47:35 +0200 Subject: slc1: more faithful emulation --- src/mame/drivers/lc80.cpp | 10 ++-- src/mame/drivers/slc1.cpp | 135 ++++++++++++++++++++-------------------------- src/mame/layout/slc1.lay | 12 ++--- 3 files changed, 70 insertions(+), 87 deletions(-) diff --git a/src/mame/drivers/lc80.cpp b/src/mame/drivers/lc80.cpp index 00d886b2de5..4bd81c9a52e 100644 --- a/src/mame/drivers/lc80.cpp +++ b/src/mame/drivers/lc80.cpp @@ -86,8 +86,8 @@ public: void lc80e(machine_config &config); void lc80_2(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER( trigger_reset ); - DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi ); + DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); + DECLARE_INPUT_CHANGED_MEMBER(trigger_nmi); protected: virtual void machine_start() override; @@ -164,12 +164,12 @@ void lc80_state::lc80_io(address_map &map) // Input Ports -INPUT_CHANGED_MEMBER( lc80_state::trigger_reset ) +INPUT_CHANGED_MEMBER(lc80_state::trigger_reset) { m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? CLEAR_LINE : ASSERT_LINE); } -INPUT_CHANGED_MEMBER( lc80_state::trigger_nmi ) +INPUT_CHANGED_MEMBER(lc80_state::trigger_nmi) { m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); } @@ -211,7 +211,7 @@ static INPUT_PORTS_START( lc80 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("DAT") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ADR") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') - PORT_START("IN.6") + PORT_START("RESET") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RES") PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, lc80_state, trigger_reset, 0) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NMI") PORT_CODE(KEYCODE_F2) PORT_CHANGED_MEMBER(DEVICE_SELF, lc80_state, trigger_nmi, 0) INPUT_PORTS_END diff --git a/src/mame/drivers/slc1.cpp b/src/mame/drivers/slc1.cpp index 75798ecdddd..baabf1378bf 100644 --- a/src/mame/drivers/slc1.cpp +++ b/src/mame/drivers/slc1.cpp @@ -1,9 +1,10 @@ // license:BSD-3-Clause -// copyright-holders:Robbbert +// copyright-holders:Robbbert, hap /*************************************************************************** 2011-JUL-16 SLC1 skeleton driver [Robbbert] 2011-DEC-29 Working [Robbbert] +2021-APR-27 And stuff [Stuff doer] reference: http://www.jens-mueller.org/jkcemu/slc1.html @@ -43,15 +44,16 @@ Test Paste: Now press O to confirm the data has been entered. TODO: - - Make emulation more faithful, io_w doesn't make much sense from - a TTL wiring point of view. - Pasting doesn't work, probably too slow. ***************************************************************************/ #include "emu.h" + #include "cpu/z80/z80.h" #include "sound/spkrdev.h" +#include "video/pwm.h" + #include "speaker.h" #include "slc1.lh" @@ -67,106 +69,76 @@ public: , m_maincpu(*this, "maincpu") , m_speaker(*this, "speaker") , m_inputs(*this, "IN.%u", 0U) - , m_display(*this, "digit%u", 0U) + , m_display(*this, "display") , m_busyled(*this, "busyled") { } void slc1(machine_config &config); + DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); + protected: virtual void machine_start() override; - virtual void machine_reset() override; private: - u8 io_r(offs_t offset); - void io_w(offs_t offset, u8 data); - - void mem_map(address_map &map); - void io_map(address_map &map); - - u8 m_digit = 0; - required_device m_maincpu; required_device m_speaker; required_ioport_array<3> m_inputs; - output_finder<8> m_display; + required_device m_display; output_finder<> m_busyled; -}; + void mem_map(address_map &map); + void io_map(address_map &map); -/*************************************************************************** - Display -***************************************************************************/ - -void slc1_state::io_w(offs_t offset, u8 data) -{ - bool const segonoff = BIT(data, 7); - bool const busyled = BIT(data, 4); - data &= 15; - - if (data < 8) - m_digit = data; - else if (data < 12) - { - m_speaker->level_w(BIT(data, 1)); - return; - } - else if (offset == 0x2f07) - return; - - u8 segdata = m_display[m_digit]; - u8 const segnum = offset & 7; - u8 const segmask = 1 << segnum; - - if (segonoff) - segdata |= segmask; - else - segdata &= ~segmask; - - m_display[m_digit] = segdata; - - m_busyled = busyled; -} - + u8 io_r(offs_t offset); + void io_w(offs_t offset, u8 data); -/*************************************************************************** - Keyboard -***************************************************************************/ + u8 m_select = 0; + u8 m_segment = 0; +}; -u8 slc1_state::io_r(offs_t offset) +void slc1_state::machine_start() { - u8 data = 0, upper = (offset >> 8) & 7; - - if (1) - { - if (upper == 3) - data = m_inputs[0]->read(); - else - if (upper == 4) - data = m_inputs[1]->read(); - else - if (upper == 5) - data = m_inputs[2]->read(); - } + m_busyled.resolve(); - return data << 4 ^ 0xff; + save_item(NAME(m_select)); + save_item(NAME(m_segment)); } /*************************************************************************** - Machine + I/O ***************************************************************************/ -void slc1_state::machine_start() +void slc1_state::io_w(offs_t offset, u8 data) { - m_display.resolve(); - m_busyled.resolve(); - - save_item(NAME(m_digit)); + // d0-d3: 7442 or equivalent + m_select = data & 0xf; + u16 sel = 1 << m_select; + + // 7442 0-1,3-6: digit select + // 7442 3-5: keypad select + // 7442 9: speaker out + m_speaker->level_w(BIT(sel, 9)); + + // a0-a2+d7: digit segment data + u8 mask = 1 << (offset & 7); + m_segment = (m_segment & ~mask) | ((data & 0x80) ? mask : 0); + m_display->matrix(sel, m_segment); + + // d4: busy led + m_busyled = BIT(data, 4); } -void slc1_state::machine_reset() +u8 slc1_state::io_r(offs_t offset) { + u8 data = 0; + + // read keypad + if (m_select >= 3 && m_select <= 5) + data |= m_inputs[m_select - 3]->read(); + + return data << 4 ^ 0xff; } @@ -183,7 +155,8 @@ void slc1_state::mem_map(address_map &map) void slc1_state::io_map(address_map &map) { - map(0x0000, 0xffff).rw(FUNC(slc1_state::io_r), FUNC(slc1_state::io_w)); + map.global_mask(0x07); + map(0x00, 0x07).rw(FUNC(slc1_state::io_r), FUNC(slc1_state::io_w)); } @@ -191,6 +164,11 @@ void slc1_state::io_map(address_map &map) Keyboard Layout ***************************************************************************/ +INPUT_CHANGED_MEMBER(slc1_state::trigger_reset) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? CLEAR_LINE : ASSERT_LINE); +} + static INPUT_PORTS_START( slc1 ) PORT_START("IN.0") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D 4 / T / 3 B") PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') @@ -209,6 +187,9 @@ static INPUT_PORTS_START( slc1 ) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A / +/- 1 / SS") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("St / Fu / DP") PORT_CODE(KEYCODE_S) PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_DEL) PORT_CHAR('S') PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z / ADR / BP") PORT_CODE(KEYCODE_Z) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR('Z') + + PORT_START("RESET") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, slc1_state, trigger_reset, 0) INPUT_PORTS_END @@ -224,11 +205,13 @@ void slc1_state::slc1(machine_config &config) m_maincpu->set_addrmap(AS_IO, &slc1_state::io_map); /* video hardware */ + PWM_DISPLAY(config, m_display).set_size(7, 7); + m_display->set_segmask(0x7b, 0x7f); config.set_default_layout(layout_slc1); /* sound hardware */ SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); } diff --git a/src/mame/layout/slc1.lay b/src/mame/layout/slc1.lay index 5f5a09e5288..e63ee935739 100644 --- a/src/mame/layout/slc1.lay +++ b/src/mame/layout/slc1.lay @@ -26,22 +26,22 @@ license:CC0 - + - + - + - + - + - + -- cgit v1.2.3