diff options
author | Miodrag Milanović <mmicko@gmail.com> | 2014-11-05 08:11:13 +0100 |
---|---|---|
committer | Miodrag Milanović <mmicko@gmail.com> | 2014-11-05 08:11:13 +0100 |
commit | 42014bab0b680eb3547b269017430d3f401bd323 (patch) | |
tree | d9d72167525eceba2870db37f451bf6ee5391840 | |
parent | ecbc6c810e5ec97948c36da7f8ae2e3017867a04 (diff) | |
parent | e7492ad4bed32153e4eb2d1dde75ba2f6d97871c (diff) |
Merge pull request #34 from shattered/_664d68d
dvk_ksm: DEC VT52-compatible video terminal
-rw-r--r-- | src/emu/drivers/xtal.h | 1 | ||||
-rw-r--r-- | src/mess/drivers/dvk_ksm.c | 416 | ||||
-rw-r--r-- | src/mess/machine/ms7004.c | 498 | ||||
-rw-r--r-- | src/mess/machine/ms7004.h | 83 | ||||
-rw-r--r-- | src/mess/mess.lst | 1 | ||||
-rw-r--r-- | src/mess/mess.mak | 1 |
6 files changed, 1000 insertions, 0 deletions
diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h index 7aed2542f26..032f91fc466 100644 --- a/src/emu/drivers/xtal.h +++ b/src/emu/drivers/xtal.h @@ -133,6 +133,7 @@ enum XTAL_14_7456MHz = 14745600, /* Namco System 12 & System Super 22/23 for JVS */ XTAL_15MHz = 15000000, /* Sinclair QL, Amusco Poker */ XTAL_15_36MHz = 15360000, /* Visual 1050 */ + XTAL_15_4MHz = 15400000, /* DVK KSM */ XTAL_15_468MHz = 15468480, /* Bank Panic h/w, Sega G80 */ XTAL_15_8976MHz = 15897600, /* IAI Swyft */ XTAL_16MHz = 16000000, /* Extremely common, used on 100's of PCBs */ diff --git a/src/mess/drivers/dvk_ksm.c b/src/mess/drivers/dvk_ksm.c new file mode 100644 index 00000000000..778cc6b6ba1 --- /dev/null +++ b/src/mess/drivers/dvk_ksm.c @@ -0,0 +1,416 @@ +/*************************************************************************** + + KSM (Kontroller Simvolnogo Monitora = Character Display Controller), + a single-board replacement for standalone 15IE-00-013 terminal (ie15.c) + in later-model DVK desktops. + + MPI (Q-Bus clone) board, consumes only power from the bus. + Interfaces with MS7004 (DEC LK201 workalike) keyboard and monochrome CRT. + + Hardware revisions (XXX verify everything): + - 7.102.076 -- has DIP switches, SRAM at 0x2000, model name "KSM" + - 7.102.228 -- no DIP switches, SRAM at 0x2100, model name "KSM-01" + + Emulates a VT52 without copier (ESC Z response is ESC / M), with + Hold Screen mode and Graphics character set (but it is unique and + mapped to a different range -- 100..137). + + F4 + 0..9 on numeric keypad = setup mode. 0 changes serial port speed, + 1..9 toggle one of mode bits: + + 1 XON/XOFF 0: Off 1: On + 2 Character set 0: N0/N1 2: N2 + 3 Auto LF 0: Off 1: On + 4 Auto repeat 0: On 1: Off + 5 Auto wraparound 0: On 1: Off + 6 Interpret controls 0: Interpret 1: Display + 7 Parity check 0: Off 1: On + 8 Parity bits 0: None 1: Even + 9 Stop bits + + N0/N1 charset has regular ASCII in C0 page and Cyrillic in C1 page, + switching between them via SI/SO. N2 charset has uppercase Cyrillic + chars in place of lowercase Latin ones. + + F1 toggles Hold Screen mode. + F9 resets terminal (clears memory). + F20 toggles on/off-line mode. + + Terminfo description would be something like + +ksm|DVK KSM, + am, bw, dch1=\EP, ich1=\EQ, + acsc=hRiTjXkClJmFnNqUtEuPv\174wKxW.M\054Q\055S\053\136~_{@}Z0\177, + use=vt52, + + To do: + - make Caps Lock work + - verify if pixel stretching is done by hw + - verify details of hw revisions + - baud rate selection (missing feature in bitbanger) + +****************************************************************************/ + +#include "emu.h" + +#include "bus/rs232/rs232.h" +#include "cpu/i8085/i8085.h" +#include "machine/clock.h" +#include "machine/i8251.h" +#include "machine/i8255.h" +#include "machine/ms7004.h" +#include "machine/pic8259.h" + +#define SCREEN_PAGE (80*48) + +#define KSM_TOTAL_HORZ 1000 +#define KSM_DISP_HORZ 800 +#define KSM_HORZ_START 200 + +#define KSM_TOTAL_VERT 28*11 +#define KSM_DISP_VERT 25*11 +#define KSM_VERT_START 2*11 + +#define KSM_STATUSLINE_TOTAL 11 +#define KSM_STATUSLINE_VRAM 0xF8B0 + +#define VERBOSE_DBG 0 /* 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 ksm_state : public driver_device +{ +public: + ksm_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_pic8259(*this, "pic8259"), + m_i8251line(*this, "i8251line"), + m_rs232(*this, "rs232"), + m_i8251kbd(*this, "i8251kbd"), + m_ms7004(*this, "ms7004"), + m_screen(*this, "screen") + { } + + virtual void machine_reset(); + virtual void video_start(); + UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_DEVICE_CALLBACK_MEMBER( scanline_callback ); + + DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock); + DECLARE_WRITE_LINE_MEMBER(write_line_clock); + + DECLARE_WRITE8_MEMBER(ksm_ppi_porta_w); + DECLARE_WRITE8_MEMBER(ksm_ppi_portc_w); + +private: + UINT32 draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline); + rectangle m_tmpclip; + bitmap_ind16 m_tmpbmp; + + const UINT8 *m_p_chargen; + struct { + UINT8 line; + UINT16 ptr; + } m_video; + +protected: + required_shared_ptr<UINT8> m_p_videoram; + required_device<cpu_device> m_maincpu; + 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<ms7004_device> m_ms7004; + required_device<screen_device> m_screen; +}; + +static ADDRESS_MAP_START( ksm_mem, AS_PROGRAM, 8, ksm_state ) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE (0x0000, 0x0fff) AM_ROM + AM_RANGE (0x2000, 0x21ff) AM_RAM + AM_RANGE (0xc000, 0xffff) AM_RAM AM_SHARE("videoram") +ADDRESS_MAP_END + +static ADDRESS_MAP_START( ksm_io, AS_IO, 8, ksm_state ) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE (0x5e, 0x5f) AM_DEVREADWRITE("pic8259", pic8259_device, read, write) + AM_RANGE (0x6e, 0x6e) AM_DEVREADWRITE("i8251kbd", i8251_device, data_r, data_w) + AM_RANGE (0x6f, 0x6f) AM_DEVREADWRITE("i8251kbd", i8251_device, status_r, control_w) + AM_RANGE (0x76, 0x76) AM_DEVREADWRITE("i8251line", i8251_device, data_r, data_w) + AM_RANGE (0x77, 0x77) AM_DEVREADWRITE("i8251line", i8251_device, status_r, control_w) + AM_RANGE (0x78, 0x7b) AM_DEVREADWRITE("ppi8255", i8255_device, read, write) +ADDRESS_MAP_END + +/* Input ports */ +static INPUT_PORTS_START( ksm ) + PORT_START("SA1") + PORT_DIPNAME(0x01, 0x01, "Stop bits") + PORT_DIPSETTING(0x00, "2 bits") + PORT_DIPSETTING(0x01, "1 bit") + PORT_DIPNAME(0x02, 0x00, "Parity bits") + PORT_DIPSETTING(0x00, "0 bits") + PORT_DIPSETTING(0x02, "1 bit") + PORT_DIPNAME(0x04, 0x00, "Parity check") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x04, "On") + PORT_DIPNAME(0x08, 0x00, "Interpret controls") + PORT_DIPSETTING(0x00, "Interpret") + PORT_DIPSETTING(0x08, "Display") + PORT_DIPNAME(0x10, 0x00, "Auto wraparound") + PORT_DIPSETTING(0x00, "On") + PORT_DIPSETTING(0x10, "Off") + PORT_DIPNAME(0x20, 0x00, "Auto repeat") + PORT_DIPSETTING(0x00, "On") + PORT_DIPSETTING(0x20, "Off") + PORT_DIPNAME(0x40, 0x00, "Auto CR/LF") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x40, "On") + PORT_DIPNAME(0x80, 0x00, "Character set") + PORT_DIPSETTING(0x00, "KOI-8 N0/N1") + PORT_DIPSETTING(0x80, "KOI-8 N2") + PORT_START("SA2") + PORT_DIPNAME(0x01, 0x00, "XON/XOFF") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x01, "On") + PORT_DIPNAME(0x0E, 0x00, "Baud rate") + PORT_DIPSETTING(0x00, "9600") + PORT_DIPSETTING(0x02, "4800") + PORT_DIPSETTING(0x04, "2400") + PORT_DIPSETTING(0x06, "1200") + PORT_DIPSETTING(0x08, "600") + PORT_DIPSETTING(0x0A, "300") + PORT_DIPSETTING(0x0C, "150") + PORT_DIPSETTING(0x0E, "75") +INPUT_PORTS_END + +void ksm_state::machine_reset() +{ + memset(&m_video, 0, sizeof(m_video)); +} + +void ksm_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(ksm_state::ksm_ppi_porta_w) +{ + DBG_LOG(1,"PPI port A", ("line %d\n", data)); + m_video.line = data; +} + +WRITE8_MEMBER(ksm_state::ksm_ppi_portc_w) +{ + DBG_LOG(1,"PPI port C", ("blink %d speed %d\n", BIT(data, 7), ((data >> 4) & 7) )); +} + +WRITE_LINE_MEMBER(ksm_state::write_keyboard_clock) +{ +// KSM never sends data to keyboard +// m_i8251kbd->write_txc(state); + m_i8251kbd->write_rxc(state); +} + +WRITE_LINE_MEMBER(ksm_state::write_line_clock) +{ + m_i8251line->write_txc(state); + m_i8251line->write_rxc(state); +} + +/* + Raster size is 28x11 scan lines. + XXX VBlank is active for 2 topmost on-screen rows and 1 at the bottom. + + Usable raster is 800 x 275 pixels (80 x 25 characters). 24 lines are + available to the user and 25th (topmost) line is the status line. + Status line displays current serial port speed and 9 setup bits. + + No character attributes are available, but in 'display controls' mode + control characters stored in memory are shown as blinking chars. + + Character cell is 10 x 11; character generator provides 7 x 8 of that. + 3 extra horizontal pixels are always XXX blank. Blinking XXX cursor may be + displayed on 3 extra scan lines. +*/ + +UINT32 ksm_state::draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline) +{ + UINT8 gfx, fg, bg, ra, blink; + UINT16 x, chr; + + bg = 0; fg = 1; ra = scanline % 8; + blink = (m_screen->frame_number() % 10) > 4; + if (scanline > 7) { + offset -= 0x2000; + } + + for (x = offset; x < offset + 80; x++) + { + chr = m_p_videoram[x] << 3; + gfx = m_p_chargen[chr | ra]; + + if ((scanline > 7 && blink) || ((chr < (0x20<<3)) && !blink)) + gfx = 0; + + *p++ = BIT(gfx, 6) ? fg : bg; + *p++ = BIT(gfx, 5) ? fg : bg; + *p++ = BIT(gfx, 4) ? fg : bg; + *p++ = BIT(gfx, 3) ? fg : bg; + *p++ = BIT(gfx, 2) ? fg : bg; + *p++ = BIT(gfx, 1) ? fg : bg; + *p++ = BIT(gfx, 0) ? fg : bg; + *p++ = bg; + *p++ = bg; + *p++ = bg; + } + return 0; +} + +TIMER_DEVICE_CALLBACK_MEMBER(ksm_state::scanline_callback) +{ + UINT16 y = m_screen->vpos(); + UINT16 offset; + + DBG_LOG(2,"scanline_cb", + ("addr %02x frame %" I64FMT "d x %.4d y %.3d row %.2d\n", + m_video.line, m_screen->frame_number(), m_screen->hpos(), y, y%11)); + + if (y < KSM_VERT_START) return; + y -= KSM_VERT_START; + if (y >= KSM_DISP_VERT) return; + + if (y < KSM_STATUSLINE_TOTAL) { + offset = KSM_STATUSLINE_VRAM - 0xC000; + } else { + offset = 0x2000 + 0x30 + (((m_video.line + y/11 - 1) % 48) << 7); + } + + draw_scanline(&m_tmpbmp.pix16(y), offset, y%11); +} + +UINT32 ksm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + copybitmap(bitmap, m_tmpbmp, 0, 0, KSM_HORZ_START, KSM_VERT_START, cliprect); + return 0; +} + + +/* F4 Character Displayer */ +static const gfx_layout ksm_charlayout = +{ + 7, 8, /* 7x8 pixels in 10x11 cell */ + 256, /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 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 /* every char takes 8 bytes */ +}; + +static GFXDECODE_START( ksm ) + GFXDECODE_ENTRY("chargen", 0x0000, ksm_charlayout, 0, 1) +GFXDECODE_END + +static MACHINE_CONFIG_START( ksm, ksm_state ) + MCFG_CPU_ADD("maincpu", I8080, XTAL_15_4MHz/10) + MCFG_CPU_PROGRAM_MAP(ksm_mem) + MCFG_CPU_IO_MAP(ksm_io) + MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259", pic8259_device, inta_cb) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("scantimer", ksm_state, scanline_callback, attotime::from_hz(50*28*11)) + MCFG_TIMER_START_DELAY(attotime::from_hz(XTAL_15_4MHz/KSM_HORZ_START)) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_UPDATE_DRIVER(ksm_state, screen_update) + MCFG_SCREEN_RAW_PARAMS(XTAL_15_4MHz, KSM_TOTAL_HORZ, KSM_HORZ_START, + KSM_HORZ_START+KSM_DISP_HORZ, KSM_TOTAL_VERT, KSM_VERT_START, + KSM_VERT_START+KSM_DISP_VERT); + + MCFG_SCREEN_PALETTE("palette") + + MCFG_GFXDECODE_ADD("gfxdecode", "palette", ksm) + MCFG_PALETTE_ADD_MONOCHROME_GREEN("palette") + + MCFG_PIC8259_ADD( "pic8259", INPUTLINE("maincpu", 0), VCC, NULL ) + + MCFG_DEVICE_ADD("ppi8255", I8255, 0) + MCFG_I8255_OUT_PORTA_CB(WRITE8(ksm_state, ksm_ppi_porta_w)) + MCFG_I8255_IN_PORTB_CB(IOPORT("SA1")) + MCFG_I8255_IN_PORTC_CB(IOPORT("SA2")) + MCFG_I8255_OUT_PORTC_CB(WRITE8(ksm_state, ksm_ppi_portc_w)) + + // 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, ir3_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)) + + MCFG_DEVICE_ADD("line_clock", CLOCK, 9600*16) // 8251 is set to /16 on the clock input + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(ksm_state, write_line_clock)) + + // serial connection to MS7004 keyboard + MCFG_DEVICE_ADD( "i8251kbd", I8251, 0) + MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("pic8259", pic8259_device, ir1_w)) + + MCFG_DEVICE_ADD("ms7004", MS7004, 0) + MCFG_MS7004_TX_HANDLER(DEVWRITELINE("i8251kbd", i8251_device, write_rxd)) + + // baud rate is supposed to be 4800 but keyboard is slightly faster + MCFG_DEVICE_ADD("keyboard_clock", CLOCK, 4960*16) + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(ksm_state, write_keyboard_clock)) +MACHINE_CONFIG_END + + +/* + Assumes that SRAM is at 0x2000, which is where technical manual puts it. + Chargen has 1 missing pixel in 'G' character. +*/ +ROM_START( dvk_ksm ) + ROM_REGION(0x1000, "maincpu", ROMREGION_ERASE00) + ROM_LOAD( "ksm_04_rom0_d32.bin", 0x0000, 0x0800, CRC(6ad62715) SHA1(20f8f95119bc7fc6e0f16c67864e339a86edb44d)) + ROM_LOAD( "ksm_05_rom1_d33.bin", 0x0800, 0x0800, CRC(5b29bcd2) SHA1(1f4f82c2f88f1e8615ec02076559dc606497e654)) + + ROM_REGION(0x0800, "chargen", ROMREGION_ERASE00) + ROM_LOAD("ksm_03_cg_d31.bin", 0x0000, 0x0800, CRC(98853aa7) SHA1(09b8e1b5b10a00c0b0ae7e36ad1328113d31230a)) +ROM_END + +/* + Assumes that SRAM is at 0x2100, otherwise identical. + Chargen has no missing pixels in 'G' character. +*/ +ROM_START( dvk_ksm01 ) + ROM_REGION(0x1000, "maincpu", ROMREGION_ERASE00) + ROM_LOAD( "ksm_04_rom0_d32.bin", 0x0000, 0x0800, CRC(5276dc9a) SHA1(dd41dfb4cb3f1cf22d96d95f1ff6a27fe4eb9a38)) + ROM_LOAD( "ksm_05_rom1_d33.bin", 0x0800, 0x0800, CRC(5b29bcd2) SHA1(1f4f82c2f88f1e8615ec02076559dc606497e654)) + + ROM_REGION(0x0800, "chargen", ROMREGION_ERASE00) + ROM_LOAD("ksm_03_cg_d31.bin", 0x0000, 0x0800, CRC(98853aa7) SHA1(c7871a96f135db05c3c8d718fbdf1728e22e72b7)) +ROM_END + +/* Driver */ + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ +COMP( 1986, dvk_ksm, 0, 0, ksm, ksm, driver_device, 0, "USSR", "DVK KSM", 0) +COMP( 198?, dvk_ksm01,0 , 0, ksm, ksm, driver_device, 0, "USSR", "DVK KSM-01", 0) diff --git a/src/mess/machine/ms7004.c b/src/mess/machine/ms7004.c new file mode 100644 index 00000000000..b145479db2b --- /dev/null +++ b/src/mess/machine/ms7004.c @@ -0,0 +1,498 @@ +/* + Electronika MS 7004 keyboard (DEC LK-201 workalike with extra keys + for Cyrillic characters). + + To do: + - debug keymap + - receive data from host (not used by KSM but used by other boards) + - connect LEDs and speaker +*/ + +#include "emu.h" +#include "ms7004.h" + +#define VERBOSE_DBG 1 /* 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 MS7004_CPU_TAG "i8048" +#define MS7004_SPK_TAG "beeper" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type MS7004 = &device_creator<ms7004_device>; + +ROM_START( ms7004 ) + ROM_REGION (0x800, MS7004_CPU_TAG, 0) + ROM_LOAD ("mc7004_keyboard_original.rom", 0x0000, 0x800, CRC(69fcab53) SHA1(2d7cc7cd182f2ee09ecf2c539e33db3c2195f778)) +ROM_END + +//------------------------------------------------- +// ADDRESS_MAP +//------------------------------------------------- + +static ADDRESS_MAP_START( ms7004_map, AS_IO, 8, ms7004_device ) + AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(p1_w) + AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(p2_w) + AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_r) + AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_DEVWRITE("i8243", i8243_device, i8243_prog_w) +ADDRESS_MAP_END + +//------------------------------------------------- +// MACHINE_CONFIG +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( ms7004 ) + MCFG_CPU_ADD(MS7004_CPU_TAG, I8048, XTAL_4_608MHz) + MCFG_CPU_IO_MAP(ms7004_map) + + MCFG_I8243_ADD("i8243", NOOP, WRITE8(ms7004_device, i8243_port_w)) + + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD(MS7004_SPK_TAG, BEEP, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor ms7004_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( ms7004 ); +} + +const rom_entry *ms7004_device::device_rom_region() const +{ + return ROM_NAME( ms7004 ); +} + +//------------------------------------------------- +// INPUT_PORTS( ms7004 ) +//------------------------------------------------- +/* +bit sig XSn ВРn +--- --- --- --- +0 8 16 15 +1 9 15 14 +2 10 14 13 +3 11 13 12 +4 12 19 16 +5 13 12 11 +6 14 11 10 +7 15 10 9 +8 16 9 8 +9 17 8 7 +10 18 7 6 +11 19 6 5 +12 20 3 1 +13 21 1 2 +14 22 4 3 +15 23 5 4 + +0xc9 KEY_LANGLE_RANGLE 'резервная клавиша' +0xbc KEY_DELETE ЗБ +0xbd KEY_RETURN ВК +0xbf KEY_TILDE '; +' +0xc4 - 'Ъ' +0xca - '/ ?' +0xed KEY_PERIOD 'Ю @' +0xf1 - '_' +<...> + +0x56 KEY_F1 СТОП КАДР +0x57 KEY_F2 ПЕЧАТЬ КАДРА +0x58 KEY_F3 ПАУЗА +0x59 KEY_F4 УСТ РЕЖИМА +0x5a KEY_F5 Ф5 + +0x64 KEY_F6 ПРЕРЫВ +0x65 KEY_F7 ПРОДОЛЖ +0x66 KEY_F8 ОТМЕН +0x67 KEY_F9 ОСНОВН КАДР +0x69 KEY_F10 ВЫХОД + +0x71 KEY_F11 Ф11 (АР2) +0x72 KEY_F12 Ф12 (ВШ) +0x73 KEY_F13 Ф13 (ПС) +0x74 KEY_F14 ДОП ВАРИАНТ + +0x7c KEY_HELP ПМ +0x7d KEY_MENU ИСП + +0x80 KEY_F17 Ф17 +0x81 KEY_F18 Ф18 +0x82 KEY_F19 Ф19 +0x83 KEY_F20 Ф20 + +0xb0 KEY_LOCK ФКС +0xae KEY_SHIFT ВР +0xaf KEY_CTRL СУ + +0xb1 KEY_META КМП +0xb2 - РУС/ЛАТ + +0x8a KEY_FIND НТ +0x8b KEY_INSERT_HERE ВСТ +0x8c KEY_REMOVE УДАЛ +0x8d KEY_SELECT ВЫБР +0x8e KEY_PREV_SCREEN ПРЕД КАДР +0x8f KEY_NEXT_SCREEN СЛЕД КАДР + +nothing sends '@' or '`' + +`/~ sends ^/~ +2/@ sends 2/" +6/^ sends 6/& +7/& sends 7/' +8/ * sends 8/( +9/( sends 9/) +0/) sends 0/0 +-/_ sends _/_ ++/= sends -/= +;/: sends ;/+ +'/" sends :/ * + +F10 sends ^C +F11 sends ESC +F12 sends ^H +*/ +INPUT_PORTS_START( ms7004 ) + PORT_START("KBD12") // vertical row 1 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Print Screen (F2)") PORT_CODE(KEYCODE_F2) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Hold Screen (F1)") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // '{' / '|' + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) // '+' + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) // what + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LShift") PORT_CODE(KEYCODE_LSHIFT) + + PORT_START("KBD13") // vertical row 2 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Setup (F3)") PORT_CODE(KEYCODE_F3) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Data / Talk (F4)") PORT_CODE(KEYCODE_F4) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1") PORT_CODE(KEYCODE_1) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Rus/Lat") PORT_CODE(KEYCODE_ESC) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Compose") PORT_CODE(KEYCODE_LALT) + + PORT_START("KBD14") // vertical row 3 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break (F5)") PORT_CODE(KEYCODE_F5) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2") PORT_CODE(KEYCODE_2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U") PORT_CODE(KEYCODE_U) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tilde") PORT_CODE(KEYCODE_TILDE) // ^ + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("KBD15") // vertical row 4 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3") PORT_CODE(KEYCODE_3) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4") PORT_CODE(KEYCODE_4) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W") PORT_CODE(KEYCODE_W) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S") PORT_CODE(KEYCODE_S) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("KBD11") // vertical row 5 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Interrupt (F6)") PORT_CODE(KEYCODE_F6) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5") PORT_CODE(KEYCODE_5) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P") PORT_CODE(KEYCODE_P) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("KBD10") // vertical row 6 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Resume (F7)") PORT_CODE(KEYCODE_F7) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6") PORT_CODE(KEYCODE_6) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R") PORT_CODE(KEYCODE_R) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T") PORT_CODE(KEYCODE_T) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) + + PORT_START("KBD9") // vertical row 7 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cancel (F8)") PORT_CODE(KEYCODE_F8) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Main Screen (F9)") PORT_CODE(KEYCODE_F9) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7") PORT_CODE(KEYCODE_7) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X") PORT_CODE(KEYCODE_X) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B) + + PORT_START("KBD8") // vertical row 8 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Exit (F10)") PORT_CODE(KEYCODE_F10) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9") PORT_CODE(KEYCODE_9) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8") PORT_CODE(KEYCODE_8) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) // '@' + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) + + PORT_START("KBD7") // vertical row 9 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC (F11)") PORT_CODE(KEYCODE_F11) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0") PORT_CODE(KEYCODE_0) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("H") PORT_CODE(KEYCODE_H) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V") PORT_CODE(KEYCODE_V) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) + + PORT_START("KBD6") // vertical row 10 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BS (F12)") PORT_CODE(KEYCODE_F12) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LF (F13)") PORT_CODE(KEYCODE_PRTSCR) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // '}' + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("'") PORT_CODE(KEYCODE_QUOTE) // ':' + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) // 'ъ' + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) + + PORT_START("KBD5") // vertical row 11 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Additional Options (F14)") PORT_CODE(KEYCODE_PAUSE) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Delete <X") PORT_CODE(KEYCODE_BACKSPACE) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) // ??? + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RShift") PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("KBD3") // vertical row 12 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Help (F15)") PORT_CODE(KEYCODE_RALT) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Insert Here") PORT_CODE(KEYCODE_HOME) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Find") PORT_CODE(KEYCODE_INSERT) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Select") PORT_CODE(KEYCODE_DEL) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("KBD2") // vertical row 13 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Remove") PORT_CODE(KEYCODE_PGUP) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Next [v]") PORT_CODE(KEYCODE_PGDN) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Previous [^]") PORT_CODE(KEYCODE_END) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("KBD1") // vertical row 14 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Do (F16)") PORT_CODE(KEYCODE_RCONTROL) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF1") PORT_CODE(KEYCODE_NUMLOCK) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 7") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 4") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 1") PORT_CODE(KEYCODE_1_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 2") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 0") PORT_CODE(KEYCODE_0_PAD) + + PORT_START("KBD0") // vertical row 15 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F17") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F18") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF2") PORT_CODE(KEYCODE_SLASH_PAD) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF3") PORT_CODE(KEYCODE_ASTERISK) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 8") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 5") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 6") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 3") PORT_CODE(KEYCODE_3_PAD) + + PORT_START("KBD4") // vertical row 16 + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F19") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F20") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PF4") PORT_CODE(KEYCODE_MINUS_PAD) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num 9") PORT_CODE(KEYCODE_9_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num ,") PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num -") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num .") PORT_CODE(KEYCODE_DEL_PAD) // "." on num.pad + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER_PAD) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor ms7004_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( ms7004 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// ms7004_device - constructor +//------------------------------------------------- + +ms7004_device::ms7004_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MS7004, "MS7004 keyboard", tag, owner, clock, "ms7004", __FILE__), +// device_serial_interface(mconfig, *this), + m_maincpu(*this, MS7004_CPU_TAG), + m_speaker(*this, MS7004_SPK_TAG), + m_i8243(*this, "i8243"), + 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) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ms7004_device::device_start() +{ + m_tx_handler.resolve_safe(); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void ms7004_device::device_reset() +{ +} + + +//------------------------------------------------- +// p1_w - +//------------------------------------------------- + +WRITE8_MEMBER( ms7004_device::p1_w ) +{ + /* + bit description + + 0 Matrix row bit 0 + 1 Matrix row bit 1 + 2 Matrix row bit 2 + 3 Speaker + 4 -STROBE (to matrix mux) + 5 LED "Latin" + 6 + 7 Serial TX + */ + DBG_LOG(1,0,( "%s: p1_w %02x = send %d\n", tag(), data, BIT(data, 7))); + + m_p1 = data; + m_tx_handler(BIT(data, 7)); +} + + +//------------------------------------------------- +// p2_w - +//------------------------------------------------- + +WRITE8_MEMBER( ms7004_device::p2_w ) +{ + /* + bit description + + 0 Matrix columns, to 8243 (port 4) + 1 Matrix columns, to 8243 (port 5) + 2 Matrix columns, to 8243 (port 6) + 3 Matrix columns, to 8243 (port 7) + 4 LED "Wait" + 5 LED "Compose" + 6 LED "Caps" + 7 LED "Hold" + */ + DBG_LOG(2,0,( "%s: p2_w %02x = col %d\n", tag(), data, data&15)); + + m_p2 = data; + m_i8243->i8243_p2_w(space, offset, data); +} + + +//------------------------------------------------- +// prog_w - +//------------------------------------------------- + +WRITE8_MEMBER( ms7004_device::i8243_port_w ) +{ + int sense = 0; + + DBG_LOG(2,0,( "%s: 8243 port %d data %02xH\n", + tag(), offset + 4, data)); + + if (data) { + switch(offset << 4 | data) { + case 0x01: sense = m_kbd0->read(); break; + case 0x02: sense = m_kbd1->read(); break; + case 0x04: sense = m_kbd2->read(); break; + case 0x08: sense = m_kbd3->read(); break; + case 0x11: sense = m_kbd4->read(); break; + case 0x12: sense = m_kbd5->read(); break; + case 0x14: sense = m_kbd6->read(); break; + case 0x18: sense = m_kbd7->read(); break; + case 0x21: sense = m_kbd8->read(); break; + case 0x22: sense = m_kbd9->read(); break; + case 0x24: sense = m_kbd10->read(); break; + case 0x28: sense = m_kbd11->read(); break; + case 0x31: sense = m_kbd12->read(); break; + case 0x32: sense = m_kbd13->read(); break; + case 0x34: sense = m_kbd14->read(); break; + case 0x38: sense = m_kbd15->read(); break; + } + m_keylatch = BIT(sense, (m_p1 & 7)); + DBG_LOG(2,0,( "%s: row %d col %02x t1 %d\n", + tag(), (m_p1 & 7), (offset << 4 | data), m_keylatch)); + } +} + + +//------------------------------------------------- +// t1_r - +//------------------------------------------------- + +READ8_MEMBER( ms7004_device::t1_r ) +{ + if (!BIT(m_p1,4)) + return m_keylatch; + else + return 0; +} diff --git a/src/mess/machine/ms7004.h b/src/mess/machine/ms7004.h new file mode 100644 index 00000000000..1602320d5ea --- /dev/null +++ b/src/mess/machine/ms7004.h @@ -0,0 +1,83 @@ +#pragma once + +#ifndef __MS7004_H__ +#define __MS7004_H__ + +#include "emu.h" +#include "cpu/mcs48/mcs48.h" +#include "machine/i8243.h" +#include "sound/beep.h" + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_MS7004_TX_HANDLER(_cb) \ + devcb = &ms7004_device::set_tx_handler(*device, DEVCB_##_cb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> ms7004_device + +class ms7004_device : public device_t //, public device_serial_interface +{ +public: + // construction/destruction + ms7004_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<ms7004_device &>(device).m_tx_handler.set_callback(wr); } + + DECLARE_WRITE8_MEMBER( p1_w ); + DECLARE_WRITE8_MEMBER( p2_w ); + DECLARE_READ8_MEMBER( t1_r ); + DECLARE_WRITE8_MEMBER( i8243_port_w ); + +protected: + // device-level overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + virtual ioport_constructor device_input_ports() const; + virtual void device_start(); + virtual void device_reset(); + +private: + required_device<cpu_device> m_maincpu; + required_device<beep_device> m_speaker; + required_device<i8243_device> m_i8243; + + 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; + + devcb_write_line m_tx_handler; +}; + +// device type definition +extern const device_type MS7004; + +#endif diff --git a/src/mess/mess.lst b/src/mess/mess.lst index ece11427185..110903f6dfa 100644 --- a/src/mess/mess.lst +++ b/src/mess/mess.lst @@ -2478,6 +2478,7 @@ itt3030 vax785 ms0515 ie15 +dvk_ksm asmapro asma2k altos5 diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 4f3aade4f92..caa554cd408 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -1180,6 +1180,7 @@ $(MESSOBJ)/einis.a: \ $(MESSOBJ)/elektrka.a: \ $(MESS_DRIVERS)/bk.o $(MESS_MACHINE)/bk.o $(MESS_VIDEO)/bk.o \ + $(MESS_DRIVERS)/dvk_ksm.o $(MESS_MACHINE)/ms7004.o \ $(MESS_DRIVERS)/mk85.o \ $(MESS_DRIVERS)/mk90.o \ |