diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 202cde39c35..2695224e692 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1454,6 +1454,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 m_p_videoram; + required_device m_maincpu; + required_device m_nvram; + required_device m_pic8259; + required_device m_i8251line; + required_device m_rs232; + required_device m_i8251kbd; + required_device m_keyboard; + required_device m_i8251prn; + required_device m_printer; + required_device m_t_hblank; + required_device m_t_vblank; + required_device m_t_color; + required_device m_t_iface; + required_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; + +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 ") 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 static devcb_base &set_tx_handler(device_t &device, _Object wr) { return downcast(device).m_tx_handler.set_callback(wr); } + template static devcb_base &set_rts_handler(device_t &device, _Object wr) { return downcast(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 m_maincpu; + required_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 baa9538b3c8..4aabf46734e 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -33287,6 +33287,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 504c1851b47..d9d3e1ce422 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -532,6 +532,7 @@ sitcom.cpp slc1.cpp slicer.cpp sm1800.cpp +sm7238.cpp smc777.cpp sms.cpp snes.cpp