From eaf550d56b5a3d59fa16852f6735932a41d067df Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 2 Jan 2018 17:18:12 -0500 Subject: [PATCH] vt100: Split out keyboard as separate device (nw) --- scripts/target/mame/mess.lua | 2 + src/mame/drivers/vt100.cpp | 186 ++-------------------- src/mame/machine/vt100_kbd.cpp | 282 +++++++++++++++++++++++++++++++++ src/mame/machine/vt100_kbd.h | 69 ++++++++ 4 files changed, 365 insertions(+), 174 deletions(-) create mode 100644 src/mame/machine/vt100_kbd.cpp create mode 100644 src/mame/machine/vt100_kbd.h diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index fe1934b229b..82680e46bdf 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1866,6 +1866,8 @@ files { MAME_DIR .. "src/mame/machine/dec_lk201.h", MAME_DIR .. "src/mame/machine/rx01.cpp", MAME_DIR .. "src/mame/machine/rx01.h", + MAME_DIR .. "src/mame/machine/vt100_kbd.cpp", + MAME_DIR .. "src/mame/machine/vt100_kbd.h", MAME_DIR .. "src/mame/video/vtvideo.cpp", MAME_DIR .. "src/mame/video/vtvideo.h", } diff --git a/src/mame/drivers/vt100.cpp b/src/mame/drivers/vt100.cpp index d408e5b2745..e2f903d9694 100644 --- a/src/mame/drivers/vt100.cpp +++ b/src/mame/drivers/vt100.cpp @@ -7,7 +7,6 @@ 29/04/2009 Preliminary driver. TODO: keyboard doesn't work properly, kb uart comms issue? - TODO: split keyboard off as a synchronous serial device? TODO: vt100 gives a '2' error on startup indicating bad nvram checksum adding the serial nvram support should fix this TODO: support for the on-AVO character set roms @@ -27,11 +26,9 @@ #include "machine/com8116.h" #include "machine/er1400.h" #include "machine/i8251.h" -#include "machine/timer.h" -#include "sound/beep.h" +#include "machine/vt100_kbd.h" #include "video/vtvideo.h" #include "screen.h" -#include "speaker.h" #include "vt100.lh" @@ -46,7 +43,7 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_crtc(*this, "vt100_video"), - m_speaker(*this, "beeper"), + m_keyboard(*this, "keyboard"), m_uart(*this, "i8251"), m_dbrg(*this, COM5016T_TAG), m_nvr(*this, "nvr"), @@ -56,11 +53,12 @@ public: required_device m_maincpu; required_device m_crtc; - required_device m_speaker; + required_device m_keyboard; required_device m_uart; required_device m_dbrg; required_device m_nvr; DECLARE_READ8_MEMBER(vt100_flags_r); + DECLARE_WRITE_LINE_MEMBER(keyboard_int_w); DECLARE_WRITE8_MEMBER(vt100_keyboard_w); DECLARE_READ8_MEMBER(vt100_keyboard_r); DECLARE_WRITE8_MEMBER(vt100_baud_rate_w); @@ -71,15 +69,11 @@ public: bool m_keyboard_int; bool m_receiver_int; bool m_vertical_int; - bool m_key_scan; - uint8_t m_key_code; virtual void machine_start() override; virtual void machine_reset() override; uint32_t screen_update_vt100(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(vt100_vertical_interrupt); - TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback); IRQ_CALLBACK_MEMBER(vt100_irq_callback); - uint8_t bit_sel(uint8_t data); }; @@ -126,57 +120,21 @@ READ8_MEMBER( vt100_state::vt100_flags_r ) return ret; } -uint8_t vt100_state::bit_sel(uint8_t data) +WRITE_LINE_MEMBER(vt100_state::keyboard_int_w) { - if (!BIT(data,7)) return 0x70; - if (!BIT(data,6)) return 0x60; - if (!BIT(data,5)) return 0x50; - if (!BIT(data,4)) return 0x40; - if (!BIT(data,3)) return 0x30; - if (!BIT(data,2)) return 0x20; - if (!BIT(data,1)) return 0x10; - if (!BIT(data,0)) return 0x00; - return 0; + m_keyboard_int = state; + if (state) + m_maincpu->set_input_line(0, HOLD_LINE); } -TIMER_DEVICE_CALLBACK_MEMBER(vt100_state::keyboard_callback) -{ - uint8_t i, code; - char kbdrow[8]; - if (m_key_scan) - { - for(i = 0; i < 16; i++) - { - sprintf(kbdrow,"LINE%X", i); - code = ioport(kbdrow)->read(); - if (code < 0xff) - { - m_keyboard_int = 1; - m_key_code = i | bit_sel(code); - m_maincpu->set_input_line(0, HOLD_LINE); - break; - } - } - } -} - - WRITE8_MEMBER( vt100_state::vt100_keyboard_w ) { - output().set_value("online_led",BIT(data, 5) ? 0 : 1); - output().set_value("local_led", BIT(data, 5)); - output().set_value("locked_led",BIT(data, 4) ? 0 : 1); - output().set_value("l1_led", BIT(data, 3) ? 0 : 1); - output().set_value("l2_led", BIT(data, 2) ? 0 : 1); - output().set_value("l3_led", BIT(data, 1) ? 0 : 1); - output().set_value("l4_led", BIT(data, 0) ? 0 : 1); - m_key_scan = BIT(data, 6); - m_speaker->set_state(BIT(data, 7)); + m_keyboard->control_w(data); } READ8_MEMBER( vt100_state::vt100_keyboard_r ) { - return m_key_code; + return m_keyboard->key_code_r(); } WRITE8_MEMBER( vt100_state::vt100_baud_rate_w ) @@ -226,120 +184,6 @@ ADDRESS_MAP_END /* Input ports */ static INPUT_PORTS_START( vt100 ) - PORT_START("LINE0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 7") PORT_CODE(KEYCODE_7_PAD) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 8") PORT_CODE(KEYCODE_8_PAD) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num .") PORT_CODE(KEYCODE_DEL_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 9") PORT_CODE(KEYCODE_9_PAD) - PORT_START("LINE1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF3") PORT_CODE(KEYCODE_F3) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF4") PORT_CODE(KEYCODE_F4) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num Enter") PORT_CODE(KEYCODE_ENTER_PAD) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num ,") PORT_CODE(KEYCODE_PLUS_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 3") PORT_CODE(KEYCODE_3_PAD) - PORT_START("LINE2") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF1") PORT_CODE(KEYCODE_F1) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF2") PORT_CODE(KEYCODE_F2) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 2") PORT_CODE(KEYCODE_2_PAD) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 5") PORT_CODE(KEYCODE_5_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 6") PORT_CODE(KEYCODE_6_PAD) - PORT_START("LINE3") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Delete") PORT_CODE(KEYCODE_DEL) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_F6) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 0") PORT_CODE(KEYCODE_0_PAD) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 1") PORT_CODE(KEYCODE_1_PAD) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 4") PORT_CODE(KEYCODE_4_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num -") PORT_CODE(KEYCODE_MINUS_PAD) - PORT_START("LINE4") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num Return") PORT_CODE(KEYCODE_ENTER_PAD) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("~") PORT_CODE(KEYCODE_TILDE) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line feed") PORT_CODE(KEYCODE_RALT) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_START("LINE5") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) - PORT_START("LINE6") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("'") PORT_CODE(KEYCODE_QUOTE) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) - PORT_START("LINE7") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_Y) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) - PORT_START("LINE8") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) - PORT_START("LINE9") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) - PORT_START("LINEA") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("No scroll") PORT_CODE(KEYCODE_LALT) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) - PORT_START("LINEB") - PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Setup") PORT_CODE(KEYCODE_F5) - PORT_START("LINEC") - PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) - PORT_START("LINED") - PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) - PORT_START("LINEE") - PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Caps lock") PORT_CODE(KEYCODE_CAPSLOCK) - PORT_START("LINEF") - PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) // Always return 0x7f on last scan line INPUT_PORTS_END uint32_t vt100_state::screen_update_vt100(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -378,8 +222,6 @@ void vt100_state::machine_reset() output().set_value("l3_led", 1); output().set_value("l4_led", 1); - m_key_scan = 0; - vt100_nvr_latch_w(machine().dummy_space(), 0, 0); } @@ -459,12 +301,8 @@ static MACHINE_CONFIG_START( vt100 ) MCFG_DEVICE_ADD("nvr", ER1400, 0) - /* audio hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("beeper", BEEP, 786) // 7.945us per serial clock = ~125865.324hz, / 160 clocks per char = ~ 786 hz - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) - - MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard_timer", vt100_state, keyboard_callback, attotime::from_hz(800)) + MCFG_DEVICE_ADD("keyboard", VT100_KEYBOARD, 0) + MCFG_VT100_KEYBOARD_INT_CALLBACK(WRITELINE(vt100_state, keyboard_int_w)) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( vt180, vt100 ) diff --git a/src/mame/machine/vt100_kbd.cpp b/src/mame/machine/vt100_kbd.cpp new file mode 100644 index 00000000000..4c165350815 --- /dev/null +++ b/src/mame/machine/vt100_kbd.cpp @@ -0,0 +1,282 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu +/*************************************************************************** + + DEC VT100 keyboard emulation + + TODO: rewrite as externally clocked serial device + +***************************************************************************/ + +#include "emu.h" +#include "machine/vt100_kbd.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(VT100_KEYBOARD, vt100_keyboard_device, "vt100_kbd", "VT100 Keyboard") + +static INPUT_PORTS_START(vt100_kbd) + PORT_START("LINE0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 7") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 8") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num .") PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 9") PORT_CODE(KEYCODE_9_PAD)\ + + PORT_START("LINE1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF3") PORT_CODE(KEYCODE_F3) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF4") PORT_CODE(KEYCODE_F4) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num Enter") PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num ,") PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 3") PORT_CODE(KEYCODE_3_PAD) + + PORT_START("LINE2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF1") PORT_CODE(KEYCODE_F1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF2") PORT_CODE(KEYCODE_F2) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 2") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 5") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 6") PORT_CODE(KEYCODE_6_PAD) + + PORT_START("LINE3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Delete") PORT_CODE(KEYCODE_DEL) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_F6) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 0") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 1") PORT_CODE(KEYCODE_1_PAD) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num 4") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num -") PORT_CODE(KEYCODE_MINUS_PAD) + + PORT_START("LINE4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Num Return") PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("~") PORT_CODE(KEYCODE_TILDE) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line feed") PORT_CODE(KEYCODE_RALT) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("LINE5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) + + PORT_START("LINE6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("'") PORT_CODE(KEYCODE_QUOTE) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) + + PORT_START("LINE7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_Y) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) + + PORT_START("LINE8") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) + + PORT_START("LINE9") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) + + PORT_START("LINEA") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("No scroll") PORT_CODE(KEYCODE_LALT) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) + + PORT_START("LINEB") + PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Setup") PORT_CODE(KEYCODE_F5) + + PORT_START("LINEC") + PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) + + PORT_START("LINED") + PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) + + PORT_START("LINEE") + PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Caps lock") PORT_CODE(KEYCODE_CAPSLOCK) + + PORT_START("LINEF") + PORT_BIT(0x7F, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) // Always return 0x7f on last scan line +INPUT_PORTS_END + + +//------------------------------------------------- +// vt100_keyboard_device - constructor +//------------------------------------------------- + +vt100_keyboard_device::vt100_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, VT100_KEYBOARD, tag, owner, clock) + , m_int_cb(*this) + , m_speaker(*this, "beeper") + , m_key_row(*this, "LINE%X", 0) + , m_key_scan(false) + , m_key_code(0) +{ +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER(vt100_keyboard_device::device_add_mconfig) + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("beeper", BEEP, 786) // 7.945us per serial clock = ~125865.324hz, / 160 clocks per char = ~ 786 hz + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("scan_timer", vt100_keyboard_device, scan_callback, attotime::from_hz(800)) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor vt100_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(vt100_kbd); +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void vt100_keyboard_device::device_resolve_objects() +{ + m_int_cb.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void vt100_keyboard_device::device_start() +{ + save_item(NAME(m_key_scan)); + save_item(NAME(m_key_code)); +} + + +//------------------------------------------------- +// control_w - handle data from CPU to keyboard +// (FIXME: this is received through a UART) +//------------------------------------------------- + +void vt100_keyboard_device::control_w(u8 data) +{ + machine().output().set_value("online_led",BIT(data, 5) ? 0 : 1); + machine().output().set_value("local_led", BIT(data, 5)); + machine().output().set_value("locked_led",BIT(data, 4) ? 0 : 1); + machine().output().set_value("l1_led", BIT(data, 3) ? 0 : 1); + machine().output().set_value("l2_led", BIT(data, 2) ? 0 : 1); + machine().output().set_value("l3_led", BIT(data, 1) ? 0 : 1); + machine().output().set_value("l4_led", BIT(data, 0) ? 0 : 1); + m_key_scan = BIT(data, 6); + m_speaker->set_state(BIT(data, 7)); +} + + +//------------------------------------------------- +// key_code_r - return the code of the active key +// (FIXME: this is delivered through a UART) +//------------------------------------------------- + +u8 vt100_keyboard_device::key_code_r() +{ + return m_key_code; +} + + +//------------------------------------------------- +// bit_sel - +//------------------------------------------------- + +u8 vt100_keyboard_device::bit_sel(u8 data) +{ + if (!BIT(data,7)) return 0x70; + if (!BIT(data,6)) return 0x60; + if (!BIT(data,5)) return 0x50; + if (!BIT(data,4)) return 0x40; + if (!BIT(data,3)) return 0x30; + if (!BIT(data,2)) return 0x20; + if (!BIT(data,1)) return 0x10; + if (!BIT(data,0)) return 0x00; + return 0; +} + + +//------------------------------------------------- +// scan_callback - handle the key scan timer +//------------------------------------------------- + +TIMER_DEVICE_CALLBACK_MEMBER(vt100_keyboard_device::scan_callback) +{ + if (m_key_scan) + { + for (int i = 0; i < 16; i++) + { + u8 code = m_key_row[i]->read(); + if (code < 0xff) + { + m_key_code = i | bit_sel(code); + m_int_cb(1); + break; + } + } + } +} diff --git a/src/mame/machine/vt100_kbd.h b/src/mame/machine/vt100_kbd.h new file mode 100644 index 00000000000..f3c924c7134 --- /dev/null +++ b/src/mame/machine/vt100_kbd.h @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu +/*************************************************************************** + + DEC VT100 keyboard emulation + +***************************************************************************/ + +#ifndef MAME_MACHINE_VT100_KBD_H +#define MAME_MACHINE_VT100_KBD_H + +#pragma once + +#include "machine/timer.h" +#include "sound/beep.h" +#include "speaker.h" + + +//************************************************************************** +// CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_VT100_KEYBOARD_INT_CALLBACK(_devcb) \ + devcb = &vt100_keyboard_device::set_int_callback(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> vt100_keyboard_device + +class vt100_keyboard_device : public device_t +{ +public: + // construction/destruction + vt100_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // static configuration + template static devcb_base &set_int_callback(device_t &device, Object &&cb) { return downcast(device).m_int_cb.set_callback(std::forward(cb)); } + + // accessors (for now) + void control_w(u8 data); + u8 key_code_r(); + +protected: + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + +private: + // internal helpers + static u8 bit_sel(u8 data); + + TIMER_DEVICE_CALLBACK_MEMBER(scan_callback); + + devcb_write_line m_int_cb; + + required_device m_speaker; + required_ioport_array<16> m_key_row; + bool m_key_scan; + u8 m_key_code; +}; + +// device type definition +DECLARE_DEVICE_TYPE(VT100_KEYBOARD, vt100_keyboard_device) + +#endif // MAME_MACHINE_VT100_KBD_H