summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Sergey Svishchev <shattered@users.noreply.github.com>2016-07-14 01:32:45 +0300
committer Sergey Svishchev <shattered@users.noreply.github.com>2016-07-18 00:54:34 +0300
commit19302429888de333937360bcb6ac16510e57e0c1 (patch)
tree44e83533284a10947fd26a7ed4f5fce9c4e3cd64
parentd7768f8875824270ccc2a6477259da5fef7f3d34 (diff)
sm7238: new NOT_WORKING driver: SM 7238 (aka T3300) serial terminal
-rw-r--r--scripts/target/mame/mess.lua3
-rw-r--r--src/emu/drivers/xtal.h2
-rw-r--r--src/mame/drivers/sm7238.cpp433
-rw-r--r--src/mame/machine/km035.cpp415
-rw-r--r--src/mame/machine/km035.h94
-rw-r--r--src/mame/mame.lst3
-rw-r--r--src/mame/mess.flt1
7 files changed, 951 insertions, 0 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 2fd3be42aae..926ab4777bb 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -1448,6 +1448,9 @@ files {
MAME_DIR .. "src/mame/video/pk8020.cpp",
MAME_DIR .. "src/mame/drivers/pyl601.cpp",
MAME_DIR .. "src/mame/drivers/sm1800.cpp",
+ MAME_DIR .. "src/mame/drivers/sm7238.cpp",
+ MAME_DIR .. "src/mame/machine/km035.cpp",
+ MAME_DIR .. "src/mame/machine/km035.h",
MAME_DIR .. "src/mame/drivers/uknc.cpp",
MAME_DIR .. "src/mame/drivers/unior.cpp",
MAME_DIR .. "src/mame/drivers/ut88.cpp",
diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h
index f9e56c65931..5cb8b901db8 100644
--- a/src/emu/drivers/xtal.h
+++ b/src/emu/drivers/xtal.h
@@ -144,6 +144,7 @@ enum
XTAL_15_8976MHz = 15897600, /* IAI Swyft */
XTAL_16MHz = 16000000, /* Extremely common, used on 100's of PCBs */
XTAL_16_384MHz = 16384000,
+ XTAL_16_5888MHz = 16588800, /* SM 7238 */
XTAL_16_9344MHz = 16934400, /* Usually used to drive 90's Yamaha OPL/FM chips (44100 * 384) */
XTAL_17_36MHz = 17360000, /* OMTI Series 10 SCSI controller */
XTAL_17_73447MHz = 17734470, /* (~4x PAL subcarrier) */
@@ -159,6 +160,7 @@ enum
XTAL_20MHz = 20000000,
XTAL_20_16MHz = 20160000, /* Nintendo 8080 */
XTAL_20_079MHz = 20790000, /* Blockade-hardware Gremlin games */
+ XTAL_20_625MHz = 20625000, /* SM 7238 */
XTAL_21MHz = 21000000, /* Lock-On pixel clock */
XTAL_21_3MHz = 21300000,
XTAL_21_4772MHz = 21477272, /* BMC bowling, some Data East 90's games, Vtech Socrates; (6x NTSC subcarrier) */
diff --git a/src/mame/drivers/sm7238.cpp b/src/mame/drivers/sm7238.cpp
new file mode 100644
index 00000000000..8d29c6baa3e
--- /dev/null
+++ b/src/mame/drivers/sm7238.cpp
@@ -0,0 +1,433 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/***************************************************************************
+
+ SM 7238 (aka T3300) color/mono text terminal, compatible with DEC VT 240.
+ Graphics option adds Tek 401x and DEC ReGIS support on a 512x250 bitmap.
+
+ Technical manual and schematics: http://doc.pdp-11.org.ru/Terminals/CM7238/
+
+ To do:
+ - handle more text_control_w bits
+ - more character attributes incl. double width and height, color
+ - 80/132 columns switching on the fly, reverse video
+ - smooth scroll
+ - graphics option
+ - run vblank from timer output?
+ - document hardware and ROM variants, verify if pixel stretching is done
+
+****************************************************************************/
+
+#include "emu.h"
+
+#include "bus/rs232/rs232.h"
+#include "cpu/i8085/i8085.h"
+#include "machine/clock.h"
+#include "machine/i8251.h"
+#include "machine/pit8253.h"
+#include "machine/pic8259.h"
+#include "machine/km035.h"
+#include "machine/nvram.h"
+
+#define KSM_COLUMNS 80 // or 132
+
+#define KSM_TOTAL_HORZ KSM_COLUMNS*10
+#define KSM_DISP_HORZ KSM_COLUMNS*8
+#define KSM_HORZ_START KSM_COLUMNS
+
+#define KSM_TOTAL_VERT 260
+#define KSM_DISP_VERT 250
+#define KSM_VERT_START 5
+
+#define VERBOSE_DBG 1 /* general debug messages */
+
+#define DBG_LOG(N,M,A) \
+ do { \
+ if(VERBOSE_DBG>=N) \
+ { \
+ if( M ) \
+ logerror("%11.6f at %s: %-24s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
+ logerror A; \
+ } \
+ } while (0)
+
+
+class sm7238_state : public driver_device
+{
+public:
+ sm7238_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_p_videoram(*this, "videoram"),
+ m_maincpu(*this, "maincpu"),
+ m_nvram(*this, "nvram"),
+ m_pic8259(*this, "pic8259"),
+ m_i8251line(*this, "i8251line"),
+ m_rs232(*this, "rs232"),
+ m_i8251kbd(*this, "i8251kbd"),
+ m_keyboard(*this, "keyboard"),
+ m_i8251prn(*this, "i8251prn"),
+ m_printer(*this, "prtr"),
+ m_t_hblank(*this, "t_hblank"),
+ m_t_vblank(*this, "t_vblank"),
+ m_t_color(*this, "t_color"),
+ m_t_iface(*this, "t_iface"),
+ m_screen(*this, "screen")
+ { }
+
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+ UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void screen_eof(screen_device &screen, bool state);
+ TIMER_DEVICE_CALLBACK_MEMBER( scanline_callback );
+ DECLARE_PALETTE_INIT(sm7238);
+
+ DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock);
+ DECLARE_WRITE_LINE_MEMBER(write_printer_clock);
+
+ DECLARE_WRITE8_MEMBER(control_w);
+ DECLARE_WRITE8_MEMBER(text_control_w);
+
+private:
+ UINT32 draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline);
+ rectangle m_tmpclip;
+ bitmap_ind16 m_tmpbmp;
+
+ void text_memory_clear();
+ void recompute_parameters();
+
+ const UINT8 *m_p_chargen;
+ struct {
+ UINT8 control;
+ UINT8 stride;
+ UINT16 ptr;
+ } m_video;
+
+protected:
+ required_shared_ptr<UINT8> m_p_videoram;
+ required_device<cpu_device> m_maincpu;
+ required_device<nvram_device> m_nvram;
+ required_device<pic8259_device> m_pic8259;
+ required_device<i8251_device> m_i8251line;
+ required_device<rs232_port_device> m_rs232;
+ required_device<i8251_device> m_i8251kbd;
+ required_device<km035_device> m_keyboard;
+ required_device<i8251_device> m_i8251prn;
+ required_device<rs232_port_device> m_printer;
+ required_device<pit8253_device> m_t_hblank;
+ required_device<pit8253_device> m_t_vblank;
+ required_device<pit8253_device> m_t_color;
+ required_device<pit8253_device> m_t_iface;
+ required_device<screen_device> m_screen;
+};
+
+static ADDRESS_MAP_START( sm7238_mem, AS_PROGRAM, 8, sm7238_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE (0x0000, 0x9fff) AM_ROM
+ AM_RANGE (0xa000, 0xa7ff) AM_RAM
+ AM_RANGE (0xb000, 0xb3ff) AM_RAM AM_SHARE("nvram")
+ AM_RANGE (0xb800, 0xb800) AM_WRITE(text_control_w)
+ AM_RANGE (0xbc00, 0xbc00) AM_WRITE(control_w)
+ AM_RANGE (0xc000, 0xcfff) AM_RAM // chargen
+ AM_RANGE (0xe000, 0xffff) AM_RAM AM_SHARE("videoram") // e000 -- chars, f000 -- attrs
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( sm7238_io, AS_IO, 8, sm7238_state )
+ ADDRESS_MAP_UNMAP_HIGH
+// AM_RANGE (0x40, 0x4f) AM_RAM // LUT
+ AM_RANGE (0xa0, 0xa0) AM_DEVREADWRITE("i8251line", i8251_device, data_r, data_w)
+ AM_RANGE (0xa1, 0xa1) AM_DEVREADWRITE("i8251line", i8251_device, status_r, control_w)
+ AM_RANGE (0xa4, 0xa4) AM_DEVREADWRITE("i8251kbd", i8251_device, data_r, data_w)
+ AM_RANGE (0xa5, 0xa5) AM_DEVREADWRITE("i8251kbd", i8251_device, status_r, control_w)
+ AM_RANGE (0xa8, 0xab) AM_DEVREADWRITE("t_color", pit8253_device, read, write)
+ AM_RANGE (0xac, 0xad) AM_DEVREADWRITE("pic8259", pic8259_device, read, write)
+ AM_RANGE (0xb0, 0xb3) AM_DEVREADWRITE("t_hblank", pit8253_device, read, write)
+ AM_RANGE (0xb4, 0xb7) AM_DEVREADWRITE("t_vblank", pit8253_device, read, write)
+ AM_RANGE (0xb8, 0xb8) AM_DEVREADWRITE("i8251prn", i8251_device, data_r, data_w)
+ AM_RANGE (0xb9, 0xb9) AM_DEVREADWRITE("i8251prn", i8251_device, status_r, control_w)
+ AM_RANGE (0xbc, 0xbf) AM_DEVREADWRITE("t_iface", pit8253_device, read, write)
+ADDRESS_MAP_END
+
+void sm7238_state::machine_reset()
+{
+ memset(&m_video, 0, sizeof(m_video));
+}
+
+void sm7238_state::video_start()
+{
+ m_p_chargen = memregion("chargen")->base();
+
+ m_tmpclip = rectangle(0, KSM_DISP_HORZ-1, 0, KSM_DISP_VERT-1);
+ m_tmpbmp.allocate(KSM_DISP_HORZ, KSM_DISP_VERT);
+}
+
+WRITE8_MEMBER(sm7238_state::control_w)
+{
+ DBG_LOG(1,"Control Write", ("%02xh: lut %d nvram %d c2 %d iack %d\n",
+ data, BIT(data, 0), BIT(data, 2), BIT(data, 3), BIT(data, 5)));
+}
+
+WRITE8_MEMBER(sm7238_state::text_control_w)
+{
+ if (data ^ m_video.control)
+ DBG_LOG(1,"Text Control Write", ("%02xh: 80/132 %d dma %d clr %d dlt %d inv %d ?? %d\n",
+ data, BIT(data, 0), BIT(data, 1), BIT(data, 2), BIT(data, 3), BIT(data, 4), BIT(data, 5)));
+
+ if (!BIT(data, 2) && !BIT(data, 3))
+ text_memory_clear();
+
+ if (BIT((data ^ m_video.control), 0)) {
+ m_video.stride = BIT(data, 0) ? 80 : 132;
+// recompute_parameters();
+ }
+
+ m_video.control = data;
+}
+
+WRITE_LINE_MEMBER(sm7238_state::write_keyboard_clock)
+{
+ m_i8251kbd->write_txc(state);
+ m_i8251kbd->write_rxc(state);
+}
+
+WRITE_LINE_MEMBER(sm7238_state::write_printer_clock)
+{
+ m_i8251prn->write_txc(state);
+ m_i8251prn->write_rxc(state);
+}
+
+UINT32 sm7238_state::draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline)
+{
+ UINT8 attr, fg, bg, ra, gfx;
+ UINT16 x, chr;
+ int dw;
+
+ ra = scanline % 10;
+
+ for (x = offset; x < offset + m_video.stride; x++)
+ {
+ chr = m_p_videoram[x] << 4;
+ attr = m_p_videoram[x + 0x1000];
+ gfx = m_p_chargen[chr | ra] ^ 255;
+
+ bg = 0; fg = 1;
+
+ /* Process attributes */
+ if ((BIT(attr, 1)) && (ra == 9))
+ {
+ gfx = 0xff; // underline
+ }
+ // 2 = blink
+ if (BIT(attr, 3))
+ {
+ gfx ^= 0xff; // reverse video
+ }
+ if (BIT(attr, 4))
+ fg = 2; // highlight
+ else
+ fg = 1;
+
+ dw = 0; // BIT(attr, 4);
+ *p++ = BIT(gfx, 7) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 7) ? fg : bg;
+ *p++ = BIT(gfx, 6) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 6) ? fg : bg;
+ *p++ = BIT(gfx, 5) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 5) ? fg : bg;
+ *p++ = BIT(gfx, 4) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 4) ? fg : bg;
+ *p++ = BIT(gfx, 3) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 3) ? fg : bg;
+ *p++ = BIT(gfx, 2) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 2) ? fg : bg;
+ *p++ = BIT(gfx, 1) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 1) ? fg : bg;
+ *p++ = BIT(gfx, 0) ? fg : bg;
+ if (dw)
+ *p++ = BIT(gfx, 0) ? fg : bg;
+ }
+ return 0;
+}
+
+TIMER_DEVICE_CALLBACK_MEMBER(sm7238_state::scanline_callback)
+{
+ UINT16 y = m_screen->vpos();
+ UINT16 o = m_video.ptr;
+
+ if (y < KSM_VERT_START) return;
+ y -= KSM_VERT_START;
+ if (y >= KSM_DISP_VERT) return;
+
+ if (y == 0)
+ m_video.ptr = 0;
+ else if (y%10 == 0) {
+ m_video.ptr = m_p_videoram[m_video.ptr + m_video.stride + 1] |
+ (m_p_videoram[m_video.ptr + 0x1000 + m_video.stride + 1] << 8);
+ m_video.ptr &= 0x0fff;
+ DBG_LOG(2,"scanline_cb",("y %d row %d old ptr %04x new ptr %04x\n", y, y%10, o, m_video.ptr));
+ }
+
+ draw_scanline(&m_tmpbmp.pix16(y), m_video.ptr, y%10);
+}
+
+void sm7238_state::text_memory_clear()
+{
+ int y = 0, ptr = 0;
+
+ do {
+ memset(&m_p_videoram[ptr], 0x20, m_video.stride);
+ memset(&m_p_videoram[ptr + 0x1000], 0x20, m_video.stride);
+ ptr = m_p_videoram[ptr + m_video.stride + 1] | (m_p_videoram[ptr + 0x1000 + m_video.stride + 1] << 8);
+ ptr &= 0x0fff;
+ y++;
+ } while (y<26);
+}
+
+void sm7238_state::recompute_parameters()
+{
+ rectangle visarea;
+ int horiz_pix_total = m_video.stride * 8;
+
+ visarea.set(0, horiz_pix_total - 1, 0, KSM_DISP_VERT - 1);
+ machine().first_screen()->configure(horiz_pix_total, KSM_DISP_VERT, visarea,
+ HZ_TO_ATTOSECONDS((m_video.stride == 80) ? 60 : 57.1 ));
+}
+
+UINT32 sm7238_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (BIT(m_video.control, 3))
+ copybitmap(bitmap, m_tmpbmp, 0, 0, KSM_HORZ_START, KSM_VERT_START, cliprect);
+ return 0;
+}
+
+void sm7238_state::screen_eof(screen_device &screen, bool state)
+{
+ m_pic8259->ir2_w(state);
+}
+
+
+/* F4 Character Displayer */
+static const gfx_layout sm7238_charlayout =
+{
+ 8, 12, /* most chars use 8x10 pixels */
+ 256, /* 256 characters */
+ 1, /* 1 bits per pixel */
+ { 0 }, /* no bitplanes */
+ /* x offsets */
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ /* y offsets */
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 },
+ 16*8 /* every char takes 16 bytes */
+};
+
+static GFXDECODE_START( sm7238 )
+ GFXDECODE_ENTRY("chargen", 0x0000, sm7238_charlayout, 0, 1)
+GFXDECODE_END
+
+PALETTE_INIT_MEMBER(sm7238_state, sm7238)
+{
+ palette.set_pen_color(0, rgb_t::black); // black
+ palette.set_pen_color(1, 0x00, 0xc0, 0x00); // green
+ palette.set_pen_color(2, 0x00, 0xff, 0x00); // highlight
+}
+
+static MACHINE_CONFIG_START( sm7238, sm7238_state )
+ MCFG_CPU_ADD("maincpu", I8080, XTAL_16_5888MHz/9)
+ MCFG_CPU_PROGRAM_MAP(sm7238_mem)
+ MCFG_CPU_IO_MAP(sm7238_io)
+ MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259", pic8259_device, inta_cb)
+
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", sm7238_state, scanline_callback, "screen", 0, 1)
+
+ MCFG_NVRAM_ADD_0FILL("nvram")
+
+ MCFG_SCREEN_ADD("screen", RASTER)
+#if KSM_COLUMNS == 80
+ MCFG_SCREEN_RAW_PARAMS(XTAL_12_5MHz,
+ KSM_TOTAL_HORZ, KSM_HORZ_START, KSM_HORZ_START+KSM_DISP_HORZ,
+ KSM_TOTAL_VERT, KSM_VERT_START, KSM_VERT_START+KSM_DISP_VERT);
+#else
+ MCFG_SCREEN_RAW_PARAMS(XTAL_20_625MHz,
+ KSM_TOTAL_HORZ, KSM_HORZ_START, KSM_HORZ_START+KSM_DISP_HORZ,
+ KSM_TOTAL_VERT, KSM_VERT_START, KSM_VERT_START+KSM_DISP_VERT);
+#endif
+ MCFG_SCREEN_UPDATE_DRIVER(sm7238_state, screen_update)
+ MCFG_SCREEN_VBLANK_DRIVER(sm7238_state, screen_eof)
+ MCFG_SCREEN_PALETTE("palette")
+
+ MCFG_PALETTE_ADD("palette", 3)
+ MCFG_PALETTE_INIT_OWNER(sm7238_state, sm7238)
+ MCFG_GFXDECODE_ADD("gfxdecode", "palette", sm7238)
+
+ MCFG_PIC8259_ADD( "pic8259", INPUTLINE("maincpu", 0), VCC, NOOP)
+
+ MCFG_DEVICE_ADD("t_hblank", PIT8253, 0)
+ MCFG_PIT8253_CLK1(XTAL_16_384MHz/9) // XXX workaround -- keyboard is slower and doesn't sync otherwise
+ MCFG_PIT8253_OUT1_HANDLER(WRITELINE(sm7238_state, write_keyboard_clock))
+
+ MCFG_DEVICE_ADD("t_vblank", PIT8253, 0)
+ MCFG_PIT8253_CLK2(XTAL_16_5888MHz/9)
+ MCFG_PIT8253_OUT2_HANDLER(WRITELINE(sm7238_state, write_printer_clock))
+
+ MCFG_DEVICE_ADD("t_color", PIT8253, 0)
+
+ MCFG_DEVICE_ADD("t_iface", PIT8253, 0)
+ MCFG_PIT8253_CLK1(XTAL_16_5888MHz/9)
+ MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("i8251line", i8251_device, write_txc))
+ MCFG_PIT8253_CLK2(XTAL_16_5888MHz/9)
+ MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("i8251line", i8251_device, write_rxc))
+
+ // serial connection to host
+ MCFG_DEVICE_ADD("i8251line", I8251, 0)
+ MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd))
+ MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr))
+ MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts))
+ MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("pic8259", pic8259_device, ir1_w))
+
+ MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "null_modem")
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE("i8251line", i8251_device, write_rxd))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE("i8251line", i8251_device, write_cts))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE("i8251line", i8251_device, write_dsr))
+
+ // serial connection to KM-035 keyboard
+ MCFG_DEVICE_ADD("i8251kbd", I8251, 0)
+ MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", km035_device, write_rxd))
+ MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("pic8259", pic8259_device, ir3_w))
+
+ MCFG_DEVICE_ADD("keyboard", KM035, 0)
+ MCFG_KM035_TX_HANDLER(DEVWRITELINE("i8251kbd", i8251_device, write_rxd))
+ MCFG_KM035_RTS_HANDLER(DEVWRITELINE("i8251kbd", i8251_device, write_cts))
+
+ // serial connection to printer
+ MCFG_DEVICE_ADD("i8251prn", I8251, 0)
+ MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("pic8259", pic8259_device, ir3_w))
+
+ MCFG_RS232_PORT_ADD("prtr", default_rs232_devices, 0)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE("i8251prn", i8251_device, write_rxd))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE("i8251prn", i8251_device, write_cts))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE("i8251prn", i8251_device, write_dsr))
+MACHINE_CONFIG_END
+
+ROM_START( sm7238 )
+ ROM_REGION(0xa000, "maincpu", ROMREGION_ERASE00)
+ // version 1.0
+ ROM_LOAD( "01_6.064", 0x0000, 0x2000, CRC(10f98d90) SHA1(cbed0b92d8beb558ce27ccd8256e1b3ab7351a58))
+ ROM_LOAD( "02_6.064", 0x2000, 0x2000, CRC(b22c0202) SHA1(68a5c45697c4a541a182f0762904d36f4496e344))
+ ROM_LOAD( "03_6.064", 0x4000, 0x2000, CRC(3e9d37ad) SHA1(26eb257733a88bd5665a9601813934da27219bc2))
+ ROM_LOAD( "04_6.064", 0x6000, 0x2000, CRC(7b8c9e06) SHA1(537bd35749c15ef66656553d9e7ec6a1f9671f98))
+ // version 1.1 undumped
+
+ ROM_REGION(0x2000, "chargen", ROMREGION_ERASE00)
+ ROM_LOAD( "bsk1_00_2.064", 0x0000, 0x2000, CRC(1e3d5885) SHA1(5afdc10f775f424473c2a78de62e3bfc82bdddd1))
+ROM_END
+
+/* Driver */
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
+COMP( 1989, sm7238, 0, 0, sm7238, 0, driver_device, 0, "USSR", "SM 7238", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_KEYBOARD)
diff --git a/src/mame/machine/km035.cpp b/src/mame/machine/km035.cpp
new file mode 100644
index 00000000000..dcef3bfa3b0
--- /dev/null
+++ b/src/mame/machine/km035.cpp
@@ -0,0 +1,415 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/*
+ KM-035 keyboard (DEC LK-201 workalike with extra keys for Cyrillic characters).
+
+ To do:
+ - connect LEDs and speaker
+*/
+
+#include "emu.h"
+#include "km035.h"
+
+#define VERBOSE_DBG 0 /* general debug messages */
+
+#define DBG_LOG(N,M,A) \
+ do { \
+ if(VERBOSE_DBG>=N) \
+ { \
+ logerror("%11.6f at %s: ",machine().time().as_double(),machine().describe_context()); \
+ logerror A; \
+ } \
+ } while (0)
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define KM035_CPU_TAG "i8048"
+#define KM035_SPK_TAG "beeper"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type KM035 = &device_creator<km035_device>;
+
+ROM_START( km035 )
+ ROM_REGION (0x800, KM035_CPU_TAG, 0)
+ ROM_LOAD ("km035.rf2", 0x0000, 0x800, CRC(881a67e1) SHA1(cfbf54f7e831b3fc0b8502a5eeb03b8618bb32b0))
+ROM_END
+
+//-------------------------------------------------
+// ADDRESS_MAP
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( km035_map, AS_PROGRAM, 8, km035_device )
+ AM_RANGE(0x0000, 0x07ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( km035_iomap, AS_IO, 8, km035_device )
+ AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_WRITE(bus_w)
+ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(p1_r, p1_w)
+ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_r, p2_w)
+ AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_r)
+ AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_r)
+ADDRESS_MAP_END
+
+//-------------------------------------------------
+// MACHINE_CONFIG
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( km035 )
+ MCFG_CPU_ADD(KM035_CPU_TAG, I8035, XTAL_4_608MHz)
+ MCFG_CPU_PROGRAM_MAP(km035_map)
+ MCFG_CPU_IO_MAP(km035_iomap)
+
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD(KM035_SPK_TAG, BEEP, 3250)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor km035_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( km035 );
+}
+
+const rom_entry *km035_device::device_rom_region() const
+{
+ return ROM_NAME( km035 );
+}
+
+//-------------------------------------------------
+// INPUT_PORTS( km035 )
+//-------------------------------------------------
+INPUT_PORTS_START( km035 )
+ PORT_START("KBD0")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Compose") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD1")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Alf") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) // Cyr/Lat
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break (F5)") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) // XXX
+
+ PORT_START("KBD2")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("} ]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('}') PORT_CHAR(']')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('@') // @ / `
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Line Feed")
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Do (F16)") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Data / Talk (F4)") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4))
+
+ PORT_START("KBD3")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF1") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Hold Screen (F1)") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
+
+ PORT_START("KBD4")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Backspace")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Delete <X") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num -")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F20")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Setup (F3)") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))
+
+ PORT_START("KBD5")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("hardsign _") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('_') // XXX
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F19")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Print Screen (F2)") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))
+
+ PORT_START("KBD6")
+ 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("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("| \\") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('|') PORT_CHAR('\\')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F18")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC (F11)") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11))
+
+ PORT_START("KBD7")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F17")
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Exit (F10)") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10))
+
+ PORT_START("KBD8")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num ,") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF4") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Resume (F7)") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7))
+
+ PORT_START("KBD9")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(TAB))
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Select") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Find") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD10")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) // "." on num.pad
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF3") PORT_CODE(KEYCODE_ASTERISK)
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Interrupt (F6)") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6))
+
+ PORT_START("KBD11")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF2") PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("KBD12")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("~ ^") PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('~') PORT_CHAR('^')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Next [v]") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Remove") PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(PGUP))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LF (F13)") PORT_CODE(KEYCODE_PRTSCR) PORT_CHAR(UCHAR_MAMEKEY(PRTSCR))
+
+ PORT_START("KBD13")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 '") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("{ [") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('{') PORT_CHAR('[')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Insert Here") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Help (F15)") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Main Screen (F9)") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9))
+
+ PORT_START("KBD14")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Previous [^]") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END))
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BS (F12)") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12))
+
+ PORT_START("KBD15")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Additional Options (F14)") PORT_CODE(KEYCODE_PAUSE) PORT_CHAR(UCHAR_MAMEKEY(PAUSE))
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cancel (F8)") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8))
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor km035_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( km035 );
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// km035_device - constructor
+//-------------------------------------------------
+
+km035_device::km035_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, KM035, "KM035 keyboard", tag, owner, clock, "km035", __FILE__),
+ m_maincpu(*this, KM035_CPU_TAG),
+ m_speaker(*this, KM035_SPK_TAG),
+ m_kbd0(*this, "KBD0"),
+ m_kbd1(*this, "KBD1"),
+ m_kbd2(*this, "KBD2"),
+ m_kbd3(*this, "KBD3"),
+ m_kbd4(*this, "KBD4"),
+ m_kbd5(*this, "KBD5"),
+ m_kbd6(*this, "KBD6"),
+ m_kbd7(*this, "KBD7"),
+ m_kbd8(*this, "KBD8"),
+ m_kbd9(*this, "KBD9"),
+ m_kbd10(*this, "KBD10"),
+ m_kbd11(*this, "KBD11"),
+ m_kbd12(*this, "KBD12"),
+ m_kbd13(*this, "KBD13"),
+ m_kbd14(*this, "KBD14"),
+ m_kbd15(*this, "KBD15"),
+ m_tx_handler(*this),
+ m_rts_handler(*this)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void km035_device::device_start()
+{
+ m_tx_handler.resolve_safe();
+ m_rts_handler.resolve_safe();
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void km035_device::device_reset()
+{
+ m_rts_handler(0);
+}
+
+
+WRITE_LINE_MEMBER( km035_device::write_rxd )
+{
+ DBG_LOG(1,0,("write_rxd %d\n", state));
+ m_maincpu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE);
+ m_rx = state;
+}
+
+//-------------------------------------------------
+// p1_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( km035_device::p1_w )
+{
+ int sense = 0;
+
+ /*
+ bit description
+
+ 0 Matrix column bit 0
+ 1 Matrix column bit 1
+ 2 Matrix column bit 2
+ 3 Serial TX
+ 4 Matrix row bit 0
+ 5 Matrix row bit 1
+ 6 Matrix row bit 2
+ 7 Matrix row bit 3
+ */
+ DBG_LOG(2,0,( "p1_w %02x = row %d col %d tx %d\n", data, (data>>4)&15, data&7, !BIT(data, 3)));
+ m_p1 = data;
+
+ switch((data>>4)&15) {
+ case 0x0: sense = m_kbd0->read(); break;
+ case 0x1: sense = m_kbd1->read(); break;
+ case 0x2: sense = m_kbd2->read(); break;
+ case 0x3: sense = m_kbd3->read(); break;
+ case 0x4: sense = m_kbd4->read(); break;
+ case 0x5: sense = m_kbd5->read(); break;
+ case 0x6: sense = m_kbd6->read(); break;
+ case 0x7: sense = m_kbd7->read(); break;
+ case 0x8: sense = m_kbd8->read(); break;
+ case 0x9: sense = m_kbd9->read(); break;
+ case 0xa: sense = m_kbd10->read(); break;
+ case 0xb: sense = m_kbd11->read(); break;
+ case 0xc: sense = m_kbd12->read(); break;
+ case 0xd: sense = m_kbd13->read(); break;
+ case 0xe: sense = m_kbd14->read(); break;
+ case 0xf: sense = m_kbd15->read(); break;
+ }
+ m_keylatch = BIT(sense, (data & 7));
+ if (m_keylatch)
+ DBG_LOG(1,0,( "keypress at row %d col %d\n", (data>>4)&15, data&7));
+
+ m_tx_handler(!BIT(data, 3));
+}
+
+WRITE8_MEMBER( km035_device::p2_w )
+{
+ DBG_LOG(2,0,( "p2_w %02x\n", data ));
+
+ m_p2 = data;
+}
+
+READ8_MEMBER( km035_device::p1_r )
+{
+ return m_p1;
+}
+
+READ8_MEMBER( km035_device::p2_r )
+{
+ return m_p2;
+}
+
+//-------------------------------------------------
+// bus_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( km035_device::bus_w )
+{
+ DBG_LOG(2,0,( "bus_w %02x\n", data));
+}
+
+//-------------------------------------------------
+// t0_r -
+//-------------------------------------------------
+
+READ8_MEMBER( km035_device::t0_r )
+{
+ return m_keylatch;
+}
+
+//-------------------------------------------------
+// t1_r -
+//-------------------------------------------------
+
+READ8_MEMBER( km035_device::t1_r )
+{
+ return m_rx;
+}
diff --git a/src/mame/machine/km035.h b/src/mame/machine/km035.h
new file mode 100644
index 00000000000..d7ec021926b
--- /dev/null
+++ b/src/mame/machine/km035.h
@@ -0,0 +1,94 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+#pragma once
+
+#ifndef __KM035_H__
+#define __KM035_H__
+
+#include "emu.h"
+#include "cpu/mcs48/mcs48.h"
+#include "sound/beep.h"
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_KM035_TX_HANDLER(_cb) \
+ devcb = &km035_device::set_tx_handler(*device, DEVCB_##_cb);
+
+#define MCFG_KM035_RTS_HANDLER(_cb) \
+ devcb = &km035_device::set_rts_handler(*device, DEVCB_##_cb);
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> km035_device
+
+class km035_device : public device_t
+{
+public:
+ // construction/destruction
+ km035_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ template<class _Object> static devcb_base &set_tx_handler(device_t &device, _Object wr) { return downcast<km035_device &>(device).m_tx_handler.set_callback(wr); }
+ template<class _Object> static devcb_base &set_rts_handler(device_t &device, _Object wr) { return downcast<km035_device &>(device).m_rts_handler.set_callback(wr); }
+
+ DECLARE_WRITE8_MEMBER( bus_w );
+ DECLARE_WRITE8_MEMBER( p1_w );
+ DECLARE_WRITE8_MEMBER( p2_w );
+ DECLARE_READ8_MEMBER( p1_r );
+ DECLARE_READ8_MEMBER( p2_r );
+ DECLARE_READ8_MEMBER( t0_r );
+ DECLARE_READ8_MEMBER( t1_r );
+
+ DECLARE_WRITE_LINE_MEMBER( write_rxd );
+
+protected:
+ // device-level overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual const rom_entry *device_rom_region() const override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<beep_device> m_speaker;
+
+ required_ioport m_kbd0;
+ required_ioport m_kbd1;
+ required_ioport m_kbd2;
+ required_ioport m_kbd3;
+ required_ioport m_kbd4;
+ required_ioport m_kbd5;
+ required_ioport m_kbd6;
+ required_ioport m_kbd7;
+ required_ioport m_kbd8;
+ required_ioport m_kbd9;
+ required_ioport m_kbd10;
+ required_ioport m_kbd11;
+ required_ioport m_kbd12;
+ required_ioport m_kbd13;
+ required_ioport m_kbd14;
+ required_ioport m_kbd15;
+
+ int m_keylatch; // keyboard row latch
+ UINT8 m_p1;
+ UINT8 m_p2;
+ UINT8 m_rx;
+
+ devcb_write_line m_tx_handler;
+ devcb_write_line m_rts_handler;
+};
+
+// device type definition
+extern const device_type KM035;
+
+#endif
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index ec2fc50cbeb..120b11998a7 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -33277,6 +33277,9 @@ spielbud // (c) 1985 ADP
@source:sm1800.cpp
sm1800 //
+@source:sm7238.cpp
+sm7238 //
+
@source:smc777.cpp
smc777 //
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 0d4155e2a4a..bd43758a30b 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -531,6 +531,7 @@ sitcom.cpp
slc1.cpp
slicer.cpp
sm1800.cpp
+sm7238.cpp
smc777.cpp
sms.cpp
snes.cpp