summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/machine/mm74c922.cpp2
-rw-r--r--src/mame/drivers/tec1.cpp233
2 files changed, 76 insertions, 159 deletions
diff --git a/src/devices/machine/mm74c922.cpp b/src/devices/machine/mm74c922.cpp
index f49b320b41a..a40741d9dcb 100644
--- a/src/devices/machine/mm74c922.cpp
+++ b/src/devices/machine/mm74c922.cpp
@@ -72,7 +72,7 @@ void mm74c922_device::device_start()
// allocate timers
m_scan_timer = timer_alloc();
- m_scan_timer->adjust(attotime::zero, 0, attotime::from_hz(50));
+ m_scan_timer->adjust(attotime::zero, 0, attotime::from_hz(500)); // approximate rate from a 100n capacitor
// register for state saving
save_item(NAME(m_inhibit));
diff --git a/src/mame/drivers/tec1.cpp b/src/mame/drivers/tec1.cpp
index 59a548d0acb..067f6841418 100644
--- a/src/mame/drivers/tec1.cpp
+++ b/src/mame/drivers/tec1.cpp
@@ -61,10 +61,8 @@ and an optional LCD, but the games of the tec1 have been removed.
ToDo:
-- After a Soft Reset, pressing keys can crash the emulation.
-- The 74C923 code may need to be revisited to improve keyboard response.
- Sometimes have to press a key a few times before it registers.
-- The 10ms debounce is not emulated.
+- Save state support
+
JMON ToDo:
@@ -76,8 +74,11 @@ JMON ToDo:
#include "emu.h"
#include "cpu/z80/z80.h"
#include "imagedev/cassette.h"
+#include "machine/mm74c922.h"
+#include "machine/rescap.h"
#include "sound/spkrdev.h"
#include "speaker.h"
+#include "video/pwm.h"
#include "tec1.lh"
@@ -90,13 +91,10 @@ public:
, m_maincpu(*this, "maincpu")
, m_speaker(*this, "speaker")
, m_cass(*this, "cassette")
+ , m_kb(*this, "keyboard")
, m_key_pressed(0)
- , m_io_line0(*this, "LINE0")
- , m_io_line1(*this, "LINE1")
- , m_io_line2(*this, "LINE2")
- , m_io_line3(*this, "LINE3")
, m_io_shift(*this, "SHIFT")
- , m_digits(*this, "digit%u", 0U)
+ , m_display(*this, "display")
{ }
void tec1(machine_config &config);
@@ -108,28 +106,19 @@ private:
required_device<cpu_device> m_maincpu;
required_device<speaker_sound_device> m_speaker;
optional_device<cassette_image_device> m_cass;
+ required_device<mm74c923_device> m_kb;
bool m_key_pressed;
- required_ioport m_io_line0;
- required_ioport m_io_line1;
- required_ioport m_io_line2;
- required_ioport m_io_line3;
required_ioport m_io_shift;
- output_finder<6> m_digits;
- emu_timer *m_kbd_timer;
- DECLARE_READ8_MEMBER( tec1_kbd_r );
- DECLARE_READ8_MEMBER( latch_r );
- DECLARE_WRITE8_MEMBER( tec1_digit_w );
- DECLARE_WRITE8_MEMBER( tecjmon_digit_w );
- DECLARE_WRITE8_MEMBER( tec1_segment_w );
- uint8_t m_kbd;
- uint8_t m_segment;
+ required_device<pwm_display_device> m_display;
+
+ DECLARE_READ8_MEMBER(kbd_r);
+ DECLARE_READ8_MEMBER(latch_r);
+ DECLARE_WRITE8_MEMBER(tec1_digit_w);
+ DECLARE_WRITE8_MEMBER(tecjmon_digit_w);
+ DECLARE_WRITE8_MEMBER(segment_w);
+ DECLARE_WRITE_LINE_MEMBER(da_w);
+ uint8_t m_seg;
uint8_t m_digit;
- uint8_t m_kbd_row;
- uint8_t m_refresh[6];
- uint8_t tec1_convert_col_to_bin( uint8_t col, uint8_t row );
- virtual void machine_reset() override;
- virtual void machine_start() override;
- TIMER_CALLBACK_MEMBER(tec1_kbd_callback);
void tec1_io(address_map &map);
void tec1_map(address_map &map);
@@ -146,7 +135,7 @@ private:
***************************************************************************/
-WRITE8_MEMBER( tec1_state::tec1_segment_w )
+WRITE8_MEMBER( tec1_state::segment_w )
{
/* d7 segment d
d6 segment e
@@ -157,7 +146,8 @@ WRITE8_MEMBER( tec1_state::tec1_segment_w )
d1 segment f
d0 segment a */
- m_segment = bitswap<8>(data, 4, 2, 1, 6, 7, 5, 3, 0);
+ m_seg = bitswap<8>(data, 4, 2, 1, 6, 7, 5, 3, 0);
+ m_display->matrix(m_digit, m_seg);
}
WRITE8_MEMBER( tec1_state::tec1_digit_w )
@@ -173,7 +163,8 @@ WRITE8_MEMBER( tec1_state::tec1_digit_w )
m_speaker->level_w(BIT(data, 7));
- m_digit = data & 0x3f;
+ m_digit = data;
+ m_display->matrix(m_digit, m_seg);
}
WRITE8_MEMBER( tec1_state::tecjmon_digit_w )
@@ -189,7 +180,8 @@ WRITE8_MEMBER( tec1_state::tecjmon_digit_w )
m_speaker->level_w(BIT(data, 7));
m_cass->output(BIT(data, 7) ? -1.0 : +1.0);
- m_digit = data & 0x3f;
+ m_digit = data;
+ m_display->matrix(m_digit, m_seg);
}
@@ -211,100 +203,15 @@ READ8_MEMBER( tec1_state::latch_r )
}
-READ8_MEMBER( tec1_state::tec1_kbd_r )
-{
- m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
- return m_kbd | m_io_shift->read();
-}
-
-uint8_t tec1_state::tec1_convert_col_to_bin( uint8_t col, uint8_t row )
+READ8_MEMBER( tec1_state::kbd_r )
{
- uint8_t data = row;
-
- if (BIT(col, 1))
- data |= 4;
- else
- if (BIT(col, 2))
- data |= 8;
- else
- if (BIT(col, 3))
- data |= 12;
- else
- if (BIT(col, 4))
- data |= 16;
-
- return data;
+ return m_kb->read() | m_io_shift->read();
}
-TIMER_CALLBACK_MEMBER(tec1_state::tec1_kbd_callback)
+WRITE_LINE_MEMBER( tec1_state::da_w )
{
- uint8_t i;
-
- // Display the digits. Blank any digits that haven't been refreshed for a while.
- // This will fix the problem reported by a user.
- for (i = 0; i < 6; i++)
- {
- if (BIT(m_digit, i))
- {
- m_refresh[i] = 1;
- m_digits[i] = m_segment;
- }
- else
- if (m_refresh[i] == 0x80)
- {
- m_digits[i] = 0;
- m_refresh[i] = 0;
- }
- else
- if (m_refresh[i])
- m_refresh[i]++;
- }
-
- // 74C923 4 by 5 key encoder.
-
- /* Look at old row */
- if (m_kbd_row == 0)
- i = m_io_line0->read();
- else
- if (m_kbd_row == 1)
- i = m_io_line1->read();
- else
- if (m_kbd_row == 2)
- i = m_io_line2->read();
- else
- if (m_kbd_row == 3)
- i = m_io_line3->read();
-
- /* if previous key is still held, bail out */
- if (i)
- if (tec1_convert_col_to_bin(i, m_kbd_row) == m_kbd)
- return;
-
- m_kbd_row++;
- m_kbd_row &= 3;
-
- /* Look at a new row */
- if (m_kbd_row == 0)
- i = m_io_line0->read();
- else
- if (m_kbd_row == 1)
- i = m_io_line1->read();
- else
- if (m_kbd_row == 2)
- i = m_io_line2->read();
- else
- if (m_kbd_row == 3)
- i = m_io_line3->read();
-
- /* see if a key pressed */
- if (i)
- {
- m_kbd = tec1_convert_col_to_bin(i, m_kbd_row);
- m_maincpu->set_input_line(INPUT_LINE_NMI, HOLD_LINE);
- m_key_pressed = true;
- }
- else
- m_key_pressed = false;
+ m_key_pressed = state;
+ m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE);
}
@@ -314,18 +221,6 @@ TIMER_CALLBACK_MEMBER(tec1_state::tec1_kbd_callback)
***************************************************************************/
-void tec1_state::machine_start()
-{
- m_digits.resolve();
- m_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tec1_state::tec1_kbd_callback),this));
- m_kbd_timer->adjust( attotime::zero, 0, attotime::from_hz(500) );
-}
-
-void tec1_state::machine_reset()
-{
- m_kbd = 0;
-}
-
/***************************************************************************
@@ -345,9 +240,9 @@ void tec1_state::tec1_map(address_map &map)
void tec1_state::tec1_io(address_map &map)
{
map.global_mask(0x07);
- map(0x00, 0x00).r(FUNC(tec1_state::tec1_kbd_r));
+ map(0x00, 0x00).r(FUNC(tec1_state::kbd_r));
map(0x01, 0x01).w(FUNC(tec1_state::tec1_digit_w));
- map(0x02, 0x02).w(FUNC(tec1_state::tec1_segment_w));
+ map(0x02, 0x02).w(FUNC(tec1_state::segment_w));
}
@@ -362,9 +257,9 @@ void tec1_state::tecjmon_map(address_map &map)
void tec1_state::tecjmon_io(address_map &map)
{
map.global_mask(0xff);
- map(0x00, 0x00).r(FUNC(tec1_state::tec1_kbd_r));
+ map(0x00, 0x00).r(FUNC(tec1_state::kbd_r));
map(0x01, 0x01).w(FUNC(tec1_state::tecjmon_digit_w));
- map(0x02, 0x02).w(FUNC(tec1_state::tec1_segment_w));
+ map(0x02, 0x02).w(FUNC(tec1_state::segment_w));
map(0x03, 0x03).r(FUNC(tec1_state::latch_r));
//map(0x04, 0x04).w(FUNC(tec1_state::lcd_en_w));
//map(0x84, 0x84).w(FUNC(tec1_state::lcd_2nd_w));
@@ -379,32 +274,32 @@ void tec1_state::tecjmon_io(address_map &map)
static INPUT_PORTS_START( tec1 )
PORT_START("LINE0") /* KEY ROW 0 */
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4')
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8')
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_UP) PORT_CHAR('^')
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4')
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8')
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_UP) PORT_CHAR('^')
PORT_START("LINE1") /* KEY ROW 1 */
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1')
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5')
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9')
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_DOWN) PORT_CHAR('V')
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1')
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5')
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9')
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_DOWN) PORT_CHAR('V')
PORT_START("LINE2") /* KEY ROW 2 */
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2')
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6')
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A')
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("GO") PORT_CODE(KEYCODE_X) PORT_CHAR('X')
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2')
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6')
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A')
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("GO") PORT_CODE(KEYCODE_X) PORT_CHAR('X')
PORT_START("LINE3") /* KEY ROW 3 */
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3')
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7')
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("AD") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3')
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7')
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AD") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
PORT_START("SHIFT")
PORT_BIT(0x1f, IP_ACTIVE_HIGH, IPT_UNUSED)
@@ -436,6 +331,17 @@ void tec1_state::tec1(machine_config &config)
/* video hardware */
config.set_default_layout(layout_tec1);
+ PWM_DISPLAY(config, m_display).set_size(6, 8);
+ m_display->set_segmask(0x3f, 0xff);
+
+ MM74C923(config, m_kb, 0);
+ m_kb->set_cap_osc(CAP_N(100));
+ m_kb->set_cap_debounce(CAP_U(1));
+ m_kb->da_wr_callback().set(FUNC(tec1_state::da_w));
+ m_kb->x1_rd_callback().set_ioport("LINE0");
+ m_kb->x2_rd_callback().set_ioport("LINE1");
+ m_kb->x3_rd_callback().set_ioport("LINE2");
+ m_kb->x4_rd_callback().set_ioport("LINE3");
/* sound hardware */
SPEAKER(config, "mono").front_center();
@@ -451,6 +357,17 @@ void tec1_state::tecjmon(machine_config &config)
/* video hardware */
config.set_default_layout(layout_tec1);
+ PWM_DISPLAY(config, m_display).set_size(6, 8);
+ m_display->set_segmask(0x3f, 0xff);
+
+ MM74C923(config, m_kb, 0);
+ m_kb->set_cap_osc(CAP_N(100));
+ m_kb->set_cap_debounce(CAP_U(1));
+ m_kb->da_wr_callback().set(FUNC(tec1_state::da_w));
+ m_kb->x1_rd_callback().set_ioport("LINE0");
+ m_kb->x2_rd_callback().set_ioport("LINE1");
+ m_kb->x3_rd_callback().set_ioport("LINE2");
+ m_kb->x4_rd_callback().set_ioport("LINE3");
/* sound hardware */
SPEAKER(config, "mono").front_center();