diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 51161745726..8df945d71ea 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1366,6 +1366,7 @@ function linkProjects_mame_mess(_target, _subtarget) "swtpc", "synertek", "ta", + "tab", "tandberg", "tangerin", "tasc", @@ -3799,6 +3800,13 @@ files { MAME_DIR .. "src/mame/drivers/alphatro.cpp", } +createMESSProjects(_target, _subtarget, "tab") +files { + MAME_DIR .. "src/mame/drivers/tabe22.cpp", + MAME_DIR .. "src/mame/machine/e22_kbd.cpp", + MAME_DIR .. "src/mame/machine/e22_kbd.h", +} + createMESSProjects(_target, _subtarget, "tandberg") files { MAME_DIR .. "src/mame/drivers/tdv2324.cpp", diff --git a/src/mame/drivers/cit220.cpp b/src/mame/drivers/cit220.cpp index 390c744f391..98db1b8242f 100644 --- a/src/mame/drivers/cit220.cpp +++ b/src/mame/drivers/cit220.cpp @@ -51,12 +51,9 @@ private: void cit220p_io_map(address_map &map); void vp122_mem_map(address_map &map); void vp122_io_map(address_map &map); - void e22_mem_map(address_map &map); - void e22_io_map(address_map &map); void char_map(address_map &map); void attr_map(address_map &map); - void e22_char_map(address_map &map); required_device m_maincpu; required_device m_screen; @@ -125,22 +122,6 @@ void cit220_state::vp122_io_map(address_map &map) map(0x70, 0x73).w("pit", FUNC(pit8253_device::write)); } -void cit220_state::e22_mem_map(address_map &map) -{ - map(0x0000, 0xbfff).rom().region("maincpu", 0); - map(0xc000, 0xcfff).ram().share("charram"); - map(0xd000, 0xffff).ram(); -} - -void cit220_state::e22_io_map(address_map &map) -{ - map(0x00, 0x0f).rw("duart", FUNC(scn2681_device::read), FUNC(scn2681_device::write)); - map(0x20, 0x27).rw(m_avdc, FUNC(scn2674_device::read), FUNC(scn2674_device::write)); - map(0x40, 0x41).rw("usart", FUNC(i8251_device::read), FUNC(i8251_device::write)); - map(0x60, 0x60).nopw(); - map(0x61, 0x61).nopw(); -} - SCN2674_DRAW_CHARACTER_MEMBER(cit220_state::draw_character) { @@ -171,11 +152,6 @@ void cit220_state::attr_map(address_map &map) map(0x0000, 0x2fff).ram(); } -void cit220_state::e22_char_map(address_map &map) -{ - map(0x0000, 0x0fff).ram().share("charram"); -} - static INPUT_PORTS_START( cit220p ) INPUT_PORTS_END @@ -247,36 +223,6 @@ void cit220_state::vp122(machine_config &config) // Input clocks are video-related and should differ for 80-column and 132-column modes } -// TODO: similar devices, but usage seems different enough from others for this to warrant its own driver -void cit220_state::tabe22(machine_config &config) -{ - I8085A(config, m_maincpu, 10_MHz_XTAL); - m_maincpu->set_addrmap(AS_PROGRAM, &cit220_state::e22_mem_map); - m_maincpu->set_addrmap(AS_IO, &cit220_state::e22_io_map); - - //NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_raw(21.7566_MHz_XTAL, 918, 0, 720, 395, 0, 378); - //m_screen->set_raw(35.8344_MHz_XTAL, 1512, 0, 1188, 395, 0, 378); - m_screen->set_screen_update(m_avdc, FUNC(scn2674_device::screen_update)); - - SCN2674(config, m_avdc, 21.7566_MHz_XTAL / 9); - m_avdc->intr_callback().set_inputline(m_maincpu, I8085_RST75_LINE); - m_avdc->set_character_width(9); - m_avdc->set_display_callback(FUNC(cit220_state::draw_character)); - m_avdc->set_addrmap(0, &cit220_state::e22_char_map); - m_avdc->set_screen("screen"); - - scn2681_device &duart(SCN2681(config, "duart", 3.6864_MHz_XTAL)); - duart.irq_cb().set_inputline(m_maincpu, I8085_RST65_LINE); - duart.outport_cb().set("usart", FUNC(i8251_device::write_txc)).bit(3); - duart.outport_cb().append("usart", FUNC(i8251_device::write_rxc)).bit(3); - - i8251_device &usart(I8251(config, "usart", 10_MHz_XTAL / 4)); // divider guessed - usart.rxrdy_handler().set_inputline(m_maincpu, I8085_RST55_LINE); -} - ROM_START(cit220p) ROM_REGION(0x8000, "maincpu", 0) @@ -308,15 +254,6 @@ ROM_START(vp122) ROM_LOAD("223-48700.uk4", 0x0000, 0x2000, CRC(4dbab4bd) SHA1(18e9a23ba22e2096fa529541fa329f5a56740e62)) ROM_END -ROM_START(tabe22) - ROM_REGION(0xc000, "maincpu", 0) - ROM_LOAD("e22_u3__2.17.86__v2.00.bin", 0x0000, 0x8000, CRC(fd931bc5) SHA1(013d5a5ed759bb9684bff18a3e848fa6d1167e10)) - ROM_LOAD("e22_u2__2.17.86__v2.00.bin", 0x8000, 0x4000, CRC(45d5e895) SHA1(a2b4e04dbc881230462a38de98ed843d5683c1b9)) - - ROM_REGION(0x2000, "chargen", 0) - ROM_LOAD("e22_u43__char_gen.bin", 0x0000, 0x2000, CRC(33880908) SHA1(7f26dede2feaf3591312d67e3dabfc1ad8bb3181)) -ROM_END COMP(1984, cit220p, 0, 0, cit220p, cit220p, cit220_state, empty_init, "C. Itoh Electronics", "CIT-220+ Video Terminal", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND) COMP(1985, vp122, 0, 0, vp122, cit220p, cit220_state, empty_init, "ADDS", "Viewpoint 122", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND) -COMP(1986, tabe22, 0, 0, tabe22, cit220p, cit220_state, empty_init, "Tab Products", "E-22 Display Terminal", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND) diff --git a/src/mame/drivers/tabe22.cpp b/src/mame/drivers/tabe22.cpp new file mode 100644 index 00000000000..35524d15c9e --- /dev/null +++ b/src/mame/drivers/tabe22.cpp @@ -0,0 +1,326 @@ +// license: BSD-3-Clause +// copyright-holders: AJR, Dirk Best +/*************************************************************************** + + Tab Products "E22" Terminal + + VT52/VT100/VT220 + + Hardware: + - P8085AH + - SCN2674B with SCB2675T + - SCN2681 + - P8251A + - 3x HM6264LP-12 (8k) + - 3x HM6116LP-2 (2k) + - XTAL: 3.6864 MHz, 10.0000 MHz, 21.7566 MHz, 35.8344 MHz + + TODO: + - Dump keyboard controller and emulate it (currently HLE'd) + - NVRAM / memory layout + - Needs a hack to send out data on the RS232 port: + Set $f7a3 = 0 after startup + + Notes: + - The hardware has some similarities to cit220.cpp + - Everything here is guessed (including the system name), no docs available + +***************************************************************************/ + +#include "emu.h" +#include "cpu/i8085/i8085.h" +#include "machine/bankdev.h" +#include "machine/e22_kbd.h" +#include "machine/i8251.h" +#include "machine/mc68681.h" +#include "machine/nvram.h" +#include "video/scn2674.h" +#include "bus/rs232/rs232.h" +#include "bus/rs232/printer.h" +#include "emupal.h" +#include "screen.h" + + +namespace { + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class tabe22_state : public driver_device +{ +public: + tabe22_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_avdc(*this, "avdc"), + m_chargen(*this, "chargen"), + m_vram_bank(*this, "vrambank") + { } + + void tabe22(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + void mem_map(address_map &map); + void io_map(address_map &map); + void vram_map(address_map &map); + + void char_map(address_map &map); + void attr_map(address_map &map); + + required_device m_maincpu; + required_device m_screen; + required_device m_palette; + required_device m_avdc; + required_region_ptr m_chargen; + optional_device m_vram_bank; + + void video_ctrl_w(uint8_t data); + void crt_brightness_w(uint8_t data); + SCN2674_DRAW_CHARACTER_MEMBER(draw_character); + void palette(palette_device &palette) const; + + bool m_screen_light; +}; + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +void tabe22_state::mem_map(address_map &map) +{ + map(0x0000, 0xbfff).rom().region("maincpu", 0); + map(0xc000, 0xcfff).rw(m_vram_bank, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xd000, 0xdfff).ram(); + map(0xe000, 0xffff).ram(); +} + +void tabe22_state::vram_map(address_map &map) +{ + map(0x0000, 0x0fff).ram().share("charram"); + map(0x1000, 0x1fff).ram().share("attrram"); +} + +void tabe22_state::io_map(address_map &map) +{ + map(0x00, 0x0f).rw("duart", FUNC(scn2681_device::read), FUNC(scn2681_device::write)); + map(0x20, 0x27).rw(m_avdc, FUNC(scn2674_device::read), FUNC(scn2674_device::write)); + map(0x40, 0x41).rw("usart", FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0x60, 0x60).w(FUNC(tabe22_state::video_ctrl_w)); + map(0x61, 0x61).w(FUNC(tabe22_state::crt_brightness_w)); +} + + +//************************************************************************** +// VIDEO EMULATION +//************************************************************************** + +void tabe22_state::char_map(address_map &map) +{ + map(0x0000, 0x0fff).ram().share("charram"); +} + +void tabe22_state::attr_map(address_map &map) +{ + map(0x0000, 0x0fff).ram().share("attrram"); +} + +void tabe22_state::video_ctrl_w(uint8_t data) +{ + // 7------- unknown + // -6------ screen light/dark + // --5----- char ram/attribute ram switch + // ---4---- unknown + // ----3--- 80/132 col switch + // -----210 unknown + + m_screen_light = bool(BIT(data, 6)); + m_vram_bank->set_bank(BIT(data, 5)); + m_avdc->set_unscaled_clock(BIT(data, 3) ? 35.8344_MHz_XTAL / 9 : 21.7566_MHz_XTAL / 9); +} + +void tabe22_state::crt_brightness_w(uint8_t data) +{ + // unknown algorithm for the brightness + // default value is 7, range is 15 (off) to 0 (brightest) + m_screen->set_brightness(0xff - ((data & 0x0f) * 6)); +} + +SCN2674_DRAW_CHARACTER_MEMBER( tabe22_state::draw_character ) +{ + uint16_t data = m_chargen[charcode << 4 | linecount] << 2; + const pen_t *const pen = m_palette->pens(); + + // 76------ unknown + // --5----- shaded + // ---4---- unknown + // ----3--- bold + // -----2-- blink + // ------1- underline + // -------0 reverse + + if (ul && (BIT(attrcode, 1))) + data = 0x1ff; + + if (blink && (BIT(attrcode, 2))) + data = 0x000; + + if (BIT(attrcode, 0)) + data = ~data; + + if (cursor) + data = ~data; + + // foreground/background colors + rgb_t fg = BIT(attrcode, 5) ? pen[1] : BIT(attrcode, 3) ? pen[3] : pen[2]; + rgb_t bg = m_screen_light ? pen[1] : pen[0]; + + // draw 9 pixels of the character + for (int i = 0; i < 9; i++) + bitmap.pix(y, x + i) = BIT(data, 8 - i) ? fg : bg; +} + +static const gfx_layout char_layout = +{ + 8,16, + RGN_FRAC(1,1), + 1, + { 0 }, + { STEP8(0,1) }, + { STEP16(0,8) }, + 8*16 +}; + +static GFXDECODE_START(chars) + GFXDECODE_ENTRY("chargen", 0, char_layout, 0, 1) +GFXDECODE_END + +void tabe22_state::palette(palette_device &palette) const +{ + static constexpr rgb_t pens[4] = + { + { 0x00, 0x00, 0x00 }, // black + { 0x7f, 0x7f, 0x7f }, // gray + { 0xcf, 0xcf, 0xcf }, // white + { 0xff, 0xff, 0xff }, // highlight + }; + + palette.set_pen_colors(0, pens); +} + + +//************************************************************************** +// MACHINE EMULATION +//************************************************************************** + +void tabe22_state::machine_start() +{ + // register for save states + save_item(NAME(m_screen_light)); +} + + +//************************************************************************** +// MACHINE DEFINTIONS +//************************************************************************** + +void printer_devices(device_slot_interface &device) +{ + device.option_add("printer", SERIAL_PRINTER); +} + +static DEVICE_INPUT_DEFAULTS_START( printer_defaults ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_4800 ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_4800 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_ODD ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END + +void tabe22_state::tabe22(machine_config &config) +{ + I8085A(config, m_maincpu, 10_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &tabe22_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &tabe22_state::io_map); + + ADDRESS_MAP_BANK(config, m_vram_bank, 0); + m_vram_bank->set_map(&tabe22_state::vram_map); + m_vram_bank->set_addr_width(13); + m_vram_bank->set_data_width(8); + m_vram_bank->set_stride(0x1000); + +// NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_color(rgb_t::amber()); + m_screen->set_raw(21.7566_MHz_XTAL, 918, 0, 720, 395, 0, 378); // 80 column mode +// m_screen->set_raw(35.8344_MHz_XTAL, 1494, 0, 1188, 395, 0, 378); // 132 column mode + m_screen->set_screen_update(m_avdc, FUNC(scn2674_device::screen_update)); + + PALETTE(config, m_palette, FUNC(tabe22_state::palette), 4); + + GFXDECODE(config, "gfxdecode", m_palette, chars); + + SCN2674(config, m_avdc, 21.7566_MHz_XTAL / 9); + m_avdc->intr_callback().set_inputline(m_maincpu, I8085_RST75_LINE); + m_avdc->set_character_width(9); + m_avdc->set_display_callback(FUNC(tabe22_state::draw_character)); + m_avdc->set_addrmap(0, &tabe22_state::char_map); + m_avdc->set_addrmap(1, &tabe22_state::attr_map); + m_avdc->set_screen("screen"); + + scn2681_device &duart(SCN2681(config, "duart", 3.6864_MHz_XTAL)); + duart.irq_cb().set_inputline(m_maincpu, I8085_RST65_LINE); + duart.a_tx_cb().set("printer", FUNC(rs232_port_device::write_txd)); + duart.b_tx_cb().set("host", FUNC(rs232_port_device::write_txd)); + duart.outport_cb().set("usart", FUNC(i8251_device::write_txc)).bit(3); + duart.outport_cb().append("usart", FUNC(i8251_device::write_rxc)).bit(3); + + rs232_port_device &rs232_host(RS232_PORT(config, "host", default_rs232_devices, nullptr)); + rs232_host.rxd_handler().set("duart", FUNC(scn2681_device::rx_b_w)); + rs232_host.cts_handler().set("duart", FUNC(scn2681_device::ip1_w)); + + rs232_port_device &rs232_printer(RS232_PORT(config, "printer", printer_devices, nullptr)); + rs232_printer.set_option_device_input_defaults("printer", DEVICE_INPUT_DEFAULTS_NAME(printer_defaults)); + + i8251_device &usart(I8251(config, "usart", 10_MHz_XTAL / 4)); // divider guessed + usart.rxrdy_handler().set_inputline(m_maincpu, I8085_RST55_LINE); + usart.txd_handler().set("kbd", FUNC(e22_kbd_hle_device::rx_w)); + + e22_kbd_hle_device &kbd(E22_KBD_HLE(config, "kbd")); + kbd.tx_handler().set("usart", FUNC(i8251_device::write_rxd)); + kbd.cts_handler().set("usart", FUNC(i8251_device::write_cts)); +} + + +//************************************************************************** +// ROM DEFINITIONS +//************************************************************************** + +ROM_START(tabe22) + ROM_REGION(0xc000, "maincpu", 0) + ROM_LOAD("e22_u3__2.17.86__v2.00.bin", 0x0000, 0x8000, CRC(fd931bc5) SHA1(013d5a5ed759bb9684bff18a3e848fa6d1167e10)) + ROM_LOAD("e22_u2__2.17.86__v2.00.bin", 0x8000, 0x4000, CRC(45d5e895) SHA1(a2b4e04dbc881230462a38de98ed843d5683c1b9)) + + ROM_REGION(0x2000, "chargen", 0) + ROM_LOAD("e22_u43__char_gen.bin", 0x0000, 0x2000, CRC(33880908) SHA1(7f26dede2feaf3591312d67e3dabfc1ad8bb3181)) +ROM_END + + +} // anonymous namespace + + +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1986, tabe22, 0, 0, tabe22, 0, tabe22_state, empty_init, "Tab Products", "E-22 Display Terminal", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/machine/e22_kbd.cpp b/src/mame/machine/e22_kbd.cpp new file mode 100644 index 00000000000..61cfafd9b94 --- /dev/null +++ b/src/mame/machine/e22_kbd.cpp @@ -0,0 +1,307 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Tab Products E22 Keyboard (HLE) + + Notes: + - Everything here is guessed, no picture of the keyboard available + +***************************************************************************/ + +#include "emu.h" +#include "e22_kbd.h" +#include "machine/keyboard.ipp" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(E22_KBD_HLE, e22_kbd_hle_device, "e22_kbd_hle", "Tab E22 Keyboard (HLE)") + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +static INPUT_PORTS_START( keyboard ) + PORT_START("row_0") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 00 */ PORT_NAME("00") + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 01 */ PORT_CODE(KEYCODE_SCRLOCK) PORT_NAME("Hold") + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 02 */ PORT_CODE(KEYCODE_PRTSCR) PORT_NAME("Print") + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 03 */ PORT_CODE(KEYCODE_ASTERISK) PORT_NAME("Setup") + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 04 */ PORT_NAME("04") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 05 */ PORT_NAME("05") + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 06 */ PORT_NAME("06") + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 07 */ PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 08 */ PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 09 */ PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 0a */ PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 0b */ PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 0c */ PORT_NAME("0c") + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 0d */ PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 0e */ PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 0f */ PORT_CODE(KEYCODE_F13) PORT_CHAR(UCHAR_MAMEKEY(F13)) + + PORT_START("row_1") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 10 */ PORT_CODE(KEYCODE_F14) PORT_CHAR(UCHAR_MAMEKEY(F14)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 11 */ PORT_NAME("11") + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 12 */ PORT_CODE(KEYCODE_F15) PORT_CHAR(UCHAR_MAMEKEY(F15)) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 13 */ PORT_CODE(KEYCODE_F16) PORT_CHAR(UCHAR_MAMEKEY(F16)) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 14 */ PORT_NAME("14") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 15 */ PORT_NAME("15") + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 16 */ PORT_CODE(KEYCODE_F17) PORT_CHAR(UCHAR_MAMEKEY(F17)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 17 */ PORT_CODE(KEYCODE_F18) PORT_CHAR(UCHAR_MAMEKEY(F18)) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 18 */ PORT_CODE(KEYCODE_F19) PORT_CHAR(UCHAR_MAMEKEY(F19)) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 19 */ PORT_CODE(KEYCODE_F20) PORT_CHAR(UCHAR_MAMEKEY(F20)) + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 1a */ PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 1b */ PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 1c */ PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 1d */ PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 1e */ PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 1f */ PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + + PORT_START("row_2") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 20 */ PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 21 */ PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 22 */ PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 23 */ PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 24 */ PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 25 */ PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 26 */ PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 27 */ PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 28 */ PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 29 */ PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 2a */ PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 2b */ PORT_CODE(KEYCODE_F2) PORT_NAME("F2 (Insert)") + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 2c */ PORT_CODE(KEYCODE_F3) PORT_NAME("F3 (Remove Clear)") + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 2d */ PORT_NAME("PF1") + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 2e */ PORT_NAME("PF2") + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 2f */ PORT_NAME("PF3") + + PORT_START("row_3") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 30 */ PORT_NAME("PF4") + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 31 */ PORT_NAME("31") + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 32 */ PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 33 */ PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 34 */ PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 35 */ PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 36 */ PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 37 */ PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 38 */ PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 39 */ PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 3a */ PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 3b */ PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 3c */ PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 3d */ PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 3e */ PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 3f */ PORT_NAME("3f") + + PORT_START("row_4") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 40 */ PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('<') PORT_CHAR('>') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 41 */ PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 42 */ PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 43 */ PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 44 */ PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 45 */ PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 46 */ PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 47 */ PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 48 */ PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 49 */ PORT_NAME("49") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 4a */ PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 4b */ PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 4c */ PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 4d */ PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 4e */ PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 4f */ PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + + PORT_START("row_5") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 50 */ PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 51 */ PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 52 */ PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 53 */ PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 54 */ PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 55 */ PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 56 */ PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 57 */ PORT_NAME("57") + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 58 */ PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 59 */ PORT_NAME("59") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 5a */ PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 5b */ PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 5c */ PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 5d */ PORT_CODE(KEYCODE_COMMA_PAD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 5e */ PORT_NAME("5e") + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 5f */ PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + + PORT_START("row_6") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 60 */ PORT_NAME("60") + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 61 */ PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 62 */ PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 63 */ PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 64 */ PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 65 */ PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 66 */ PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 67 */ PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 68 */ PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 69 */ PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 6a */ PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 6b */ PORT_NAME("6b") + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 6c */ PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 6d */ PORT_NAME("LF") + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 6e */ PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 6f */ PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + + PORT_START("row_7") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 70 */ PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 71 */ PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 72 */ PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 73 */ PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 74 */ PORT_NAME("74") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 75 */ PORT_NAME("75") + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 76 */ PORT_NAME("76") + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 77 */ PORT_NAME("77") + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 78 */ PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 79 */ PORT_NAME("79") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 7a */ PORT_NAME("7a") + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 7b */ PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 7c */ PORT_NAME("7c") + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 7d */ PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("Keypad .") + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 7e */ PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) /* 7f */ PORT_NAME("7f") +INPUT_PORTS_END + +ioport_constructor e22_kbd_hle_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( keyboard ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// e22_kbd_hle_device - constructor +//------------------------------------------------- + +e22_kbd_hle_device::e22_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, E22_KBD_HLE, tag, owner, clock), + device_buffered_serial_interface(mconfig, *this), + device_matrix_keyboard_interface(mconfig, *this, "row_0", "row_1", "row_2", "row_3", "row_4", "row_5", "row_6", "row_7"), + m_tx_handler(*this), + m_cts_handler(*this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void e22_kbd_hle_device::device_start() +{ + // resolve callbacks + m_tx_handler.resolve_safe(); + m_cts_handler.resolve_safe(); + + // signal ready + m_cts_handler(0); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void e22_kbd_hle_device::device_reset() +{ + clear_fifo(); + + receive_register_reset(); + transmit_register_reset(); + + set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); + set_rcv_rate(1200); + set_tra_rate(1200); + + reset_key_state(); + start_processing(attotime::from_hz(1200)); + typematic_stop(); +} + +//------------------------------------------------- +// tra_callback - send bit to host +//------------------------------------------------- + +void e22_kbd_hle_device::tra_callback() +{ + m_tx_handler(transmit_register_get_data_bit()); +} + +//------------------------------------------------- +// received_byte - handle received byte +//------------------------------------------------- + +void e22_kbd_hle_device::received_byte(uint8_t byte) +{ + logerror("Received from host: %02x\n", byte); + + switch (byte) + { + case 0x02: break; // keyclick on + case 0x06: transmit_byte(0x01); break; // can't be 0x00 + case 0x07: transmit_byte(0x02); break; // can't be 0x00 + case 0x09: break; // bell? + case 0x12: break; // keyclick off + } +} + +//------------------------------------------------- +// key_make - handle a key being pressed +//------------------------------------------------- + +void e22_kbd_hle_device::key_make(uint8_t row, uint8_t column) +{ + // send the code + uint8_t code = row * 16 + column; + + transmit_byte(code); + + // no typematic for modifier keys + if (code != 0x48 && code != 0x5f && code != 0x6c) + typematic_start(row, column, attotime::from_msec(750), attotime::from_msec(50)); +} + +//------------------------------------------------- +// key_break - handle a key being released +//------------------------------------------------- + +void e22_kbd_hle_device::key_break(uint8_t row, uint8_t column) +{ + // send the break code (only for modifier keys: ctrl and shift) + uint8_t code = row * 16 + column; + + if (code == 0x48 || code == 0x5f || code == 0x6c) + transmit_byte(0x80 | code); + + if (typematic_is(row, column)) + typematic_stop(); +} + +//------------------------------------------------- +// key_repeat - handle a key being repeated +//------------------------------------------------- + +void e22_kbd_hle_device::key_repeat(u8 row, u8 column) +{ + uint8_t code = row * 16 + column; + transmit_byte(code); +} + +//------------------------------------------------- +// rx_w - receive bit from host +//------------------------------------------------- + +void e22_kbd_hle_device::rx_w(int state) +{ + device_buffered_serial_interface::rx_w(state); +} diff --git a/src/mame/machine/e22_kbd.h b/src/mame/machine/e22_kbd.h new file mode 100644 index 00000000000..a3bac1d98d6 --- /dev/null +++ b/src/mame/machine/e22_kbd.h @@ -0,0 +1,62 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Tab Products E22 Keyboard (HLE) + +***************************************************************************/ + +#ifndef MAME_MACHINE_E22_KBD_H +#define MAME_MACHINE_E22_KBD_H + +#pragma once + +#include "machine/keyboard.h" +#include "diserial.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> e22_kbd_hle_device + +class e22_kbd_hle_device : public device_t, + public device_buffered_serial_interface<16>, + protected device_matrix_keyboard_interface<8> +{ +public: + // construction/destruction + e22_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + // callbacks + auto tx_handler() { return m_tx_handler.bind(); } + auto cts_handler() { return m_cts_handler.bind(); } + + // from host + void rx_w(int state); + +protected: + // device_t overrides + virtual ioport_constructor device_input_ports() const override; + virtual void device_start() override; + virtual void device_reset() override; + + // device_buffered_serial_interface overrides + virtual void tra_callback() override; + virtual void received_byte(uint8_t byte) override; + + // device_matrix_keyboard_interface overrides + virtual void key_make(uint8_t row, uint8_t column) override; + virtual void key_break(uint8_t row, uint8_t column) override; + virtual void key_repeat(uint8_t row, uint8_t column) override; + +private: + devcb_write_line m_tx_handler; + devcb_write_line m_cts_handler; +}; + +// device type definition +DECLARE_DEVICE_TYPE(E22_KBD_HLE, e22_kbd_hle_device) + +#endif // MAME_MACHINE_E22_KBD_H diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 16358e82305..430c0fcecef 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -10407,7 +10407,6 @@ cit101xl // @source:cit220.cpp cit220p // (c) 1984 C. Itoh -tabe22 // vp122 // @source:cit1500.cpp @@ -39465,6 +39464,9 @@ tturfbl // (c) 1989 (Datsu bootleg) wb3bbl // bootleg wb3bble // bootleg +@source:tabe22.cpp +tabe22 // (c) Tab Products + @source:tagteam.cpp bigprowr // TA-0007 (c) 1983 tagteam // TA-0007 (c) 1983 + Data East license diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 022d3008603..3832a298ddf 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -984,6 +984,7 @@ sys2900.cpp sys9002.cpp systec.cpp systel1.cpp +tabe22.cpp talkingbb.cpp talkingfb.cpp tamag1.cpp