From 136538f624d075ff7eff85324568a4511628670f Mon Sep 17 00:00:00 2001 From: AJR Date: Thu, 18 May 2023 11:19:58 -0400 Subject: dim68k: Various improvements [AJR, Bitsavers] - Replace generic serial keyboard with dump and low level emulation of MCU-based keyboard - Specify correct clocks and XTAL sources for CPU and various other components - Add game control port (untested) --- src/mame/skeleton/dim68k.cpp | 63 +++++------ src/mame/skeleton/dim68k_kbd.cpp | 233 +++++++++++++++++++++++++++++++++++++++ src/mame/skeleton/dim68k_kbd.h | 67 +++++++++++ 3 files changed, 327 insertions(+), 36 deletions(-) create mode 100644 src/mame/skeleton/dim68k_kbd.cpp create mode 100644 src/mame/skeleton/dim68k_kbd.h diff --git a/src/mame/skeleton/dim68k.cpp b/src/mame/skeleton/dim68k.cpp index 20ce27aa011..11404f90c46 100644 --- a/src/mame/skeleton/dim68k.cpp +++ b/src/mame/skeleton/dim68k.cpp @@ -10,19 +10,18 @@ of the emulated systems, or you create any other format you wished. TODO: - - HLE serial keyboard - Graphics display (including colour and video_control options) - RTC (is this a thing? the manual indicates it just uses the DUART's timers to track time) - Centronics printer - Video-high - Video-reset - - Game switches, paddles and timers (which work almost identically to the Apple II) - The plug-in boards - Emulator trap function DUART I/O port bits: INPUT: bit 0 = Centronics RDY + bit 4 = RS-232C DCD OUTPUT: all bits = Centronics data @@ -48,12 +47,14 @@ ****************************************************************************/ #include "emu.h" +#include "dim68k_kbd.h" #include "cpu/m68000/m68000.h" #include "imagedev/floppy.h" #include "machine/mc68681.h" #include "machine/upd765.h" #include "sound/spkrdev.h" #include "video/mc6845.h" +#include "bus/pc_joy/pc_joy.h" #include "bus/rs232/rs232.h" #include "emupal.h" #include "screen.h" @@ -73,6 +74,7 @@ public: , m_speaker(*this, "speaker") , m_fdc(*this, "fdc") , m_floppy(*this, "fdc:%u", 0U) + , m_gamectrl(*this, "gamectrl") , m_ram(*this, "ram") , m_palette(*this, "palette") , m_p_chargen(*this, "chargen") @@ -85,13 +87,12 @@ public: private: void dim68k_palette(palette_device &palette); u16 dim68k_fdc_r(); - u16 dim68k_game_switches_r(); + u8 dim68k_game_switches_r(offs_t offset); u16 dim68k_speaker_r(); u16 dim68k_banksw_r(); void dim68k_banksw_w(u16 data); void dim68k_fdc_w(u16 data); void dim68k_printer_strobe_w(u16 data); - void dim68k_reset_timers_w(u16 data); void dim68k_speaker_w(u16 data); void dim68k_video_control_w(u16 data); void dim68k_video_high_w(u16 data); @@ -113,6 +114,7 @@ private: required_device m_speaker; required_device m_fdc; required_device_array m_floppy; + required_device m_gamectrl; required_shared_ptr m_ram; required_device m_palette; required_region_ptr m_p_chargen; @@ -145,19 +147,22 @@ u16 dim68k_state::dim68k_fdc_r() return 0; } -u16 dim68k_state::dim68k_game_switches_r() +u8 dim68k_state::dim68k_game_switches_r(offs_t offset) // Reading the game port switches // FFCC11 = switch 0; FFCC13 = switch 1, etc to switch 3 // FFCC19 = paddle 0; FFCC1B = paddle 1, etc to paddle 3 { - return 0xffff; + return BIT(m_gamectrl->joy_port_r(), offset ^ 4) ? 0 : 0x80; } u16 dim68k_state::dim68k_speaker_r() // Any read or write of this address will toggle the position of the speaker cone { - m_speaker_bit ^= 1; - m_speaker->level_w(m_speaker_bit); + if (!machine().side_effects_disabled()) + { + m_speaker_bit ^= 1; + m_speaker->level_w(m_speaker_bit); + } return 0; } @@ -229,11 +234,6 @@ void dim68k_state::dim68k_video_reset_w(u16 data) { } -void dim68k_state::dim68k_reset_timers_w(u16 data) -// reset game port timer before reading paddles -{ -} - void dim68k_state::dim68k_printer_strobe_w(u16 data) // anything sent here will trigger a one-shot for a strobe pulse { @@ -280,7 +280,8 @@ void dim68k_state::mem_map(address_map &map) #endif map(0xffc400, 0xffc41f).rw(m_duart, FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0x00ff); map(0xffc800, 0xffc801).rw(FUNC(dim68k_state::dim68k_speaker_r), FUNC(dim68k_state::dim68k_speaker_w)); - map(0xffcc00, 0xffcc1f).rw(FUNC(dim68k_state::dim68k_game_switches_r), FUNC(dim68k_state::dim68k_reset_timers_w)); + map(0xffcc00, 0xffcc00).w(m_gamectrl, FUNC(pc_joy_device::joy_port_w)); + map(0xffcc10, 0xffcc1f).r(FUNC(dim68k_state::dim68k_game_switches_r)).umask16(0x00ff); map(0xffd000, 0xffd003).m(m_fdc, FUNC(upd765a_device::map)).umask16(0x00ff); // NEC uPD765A map(0xffd000, 0xffd000).lr8([this]() -> u8 { return m_fdc_irq; }, "free0"); map(0xffd004, 0xffd005).rw(FUNC(dim68k_state::dim68k_fdc_r), FUNC(dim68k_state::dim68k_fdc_w)); @@ -409,27 +410,16 @@ void dim68k_state::machine_start() save_item(NAME(m_video_control)); } -static DEVICE_INPUT_DEFAULTS_START(keyboard) - DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_300) - DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_300) - DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_8) - DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_NONE) - DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1) -DEVICE_INPUT_DEFAULTS_END - void dim68k_state::dim68k(machine_config &config) { /* basic machine hardware */ - M68000(config, m_maincpu, XTAL(10'000'000)); + M68000(config, m_maincpu, 14.318181_MHz_XTAL / 2); // part rated for 8 MHz; clock verified from manual m_maincpu->set_addrmap(AS_PROGRAM, &dim68k_state::mem_map); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_raw(14.318181_MHz_XTAL, 896, 0, 640, 279, 0, 224); screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - screen.set_size(640, 480); - screen.set_visarea(0, 640-1, 0, 250-1); PALETTE(config, m_palette, FUNC(dim68k_state::dim68k_palette), 16); GFXDECODE(config, "gfxdecode", m_palette, gfx_dim68k); @@ -438,27 +428,28 @@ void dim68k_state::dim68k(machine_config &config) SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); /* Devices */ - UPD765A(config, m_fdc, 4'000'000, true, true); // these options unknown + UPD765A(config, m_fdc, 16_MHz_XTAL / 4, true, true); // clocked through FDC9229BT; options unknown FLOPPY_CONNECTOR(config, m_floppy[0], dim68k_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats); FLOPPY_CONNECTOR(config, m_floppy[1], dim68k_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats); m_fdc->intrq_wr_callback().set(FUNC(dim68k_state::fdc_irq_w)); - MC6845(config, m_crtc, 1790000); + MC6845(config, m_crtc, 14.318181_MHz_XTAL / 8); m_crtc->set_screen("screen"); m_crtc->set_show_border_area(false); m_crtc->set_char_width(8); m_crtc->set_update_row_callback(FUNC(dim68k_state::crtc_update_row)); - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); - rs232_port_device &kbdport(RS232_PORT(config, "kbdport", default_rs232_devices, "keyboard")); - kbdport.set_option_device_input_defaults("keyboard", DEVICE_INPUT_DEFAULTS_NAME(keyboard)); - SCN2681(config, m_duart, 3.6864_MHz_XTAL); - m_duart->a_tx_cb().set(kbdport, FUNC(rs232_port_device::write_txd)); - m_duart->b_tx_cb().set(rs232, FUNC(rs232_port_device::write_txd)); - kbdport.rxd_handler().set(m_duart, FUNC(scn2681_device::rx_a_w)); + DIM68K_KEYBOARD(config, "keyboard").txd_callback().set(m_duart, FUNC(scn2681_device::rx_a_w)); + + PC_JOY(config, m_gamectrl); + + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); rs232.rxd_handler().set(m_duart, FUNC(scn2681_device::rx_b_w)); + rs232.dcd_handler().set(m_duart, FUNC(scn2681_device::ip4_w)); + + m_duart->b_tx_cb().set(rs232, FUNC(rs232_port_device::write_txd)); // software lists SOFTWARE_LIST(config, "flop_list").set_original("dim68k"); diff --git a/src/mame/skeleton/dim68k_kbd.cpp b/src/mame/skeleton/dim68k_kbd.cpp new file mode 100644 index 00000000000..00a522ec3b5 --- /dev/null +++ b/src/mame/skeleton/dim68k_kbd.cpp @@ -0,0 +1,233 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Micro Craft Dimension 68000 84-key keyboard + + This keyboard mimics the layout of early IBM PC keyboards. The + main differences are that \ is to the left of the left Shift key, + the "Retrn" key (thus labeled here) is horizontal rather than + vertical in orientation, and the keypad has an "Enter" key. The + communication is unidirectional asynchronous TTL-level serial at + 300 baud, using ASCII codes only for printable characters. LEDs + are provided for the Caps Lock and Num Lock keys, but not for + Scroll Lock. + + Mysteries: + — Why does the 8048 have to be slightly overclocked to yield the + correct baud rate? + — Keycodes are transmitted with even parity, despite the DUART + configuration and documentation specifying no parity. Framing + errors frequently result, but these might be harmless. + — There are actually two serial outputs generated by the 8048, + one being the complement of the other. + — Due to an apparent bug in CP/M, 2 on the numeric keypad may not + work correctly in numeric mode (likely since the code it sends + is coincidentally the ASCII CR code). + +**********************************************************************/ + +#include "emu.h" +#include "dim68k_kbd.h" + +DEFINE_DEVICE_TYPE(DIM68K_KEYBOARD, dim68k_keyboard_device, "dim68k_kbd", "Dimension 68000 keyboard") + +dim68k_keyboard_device::dim68k_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, DIM68K_KEYBOARD, tag, owner, clock) + , m_mcu(*this, "mcu") + , m_eprom(*this, "eprom") + , m_keys(*this, "KEYS%d", 0U) + , m_capslock_led(*this, "capslock") + , m_numlock_led(*this, "numlock") + , m_txd_callback(*this) + , m_p1_in(0xff) +{ +} + +void dim68k_keyboard_device::device_resolve_objects() +{ + m_capslock_led.resolve(); + m_numlock_led.resolve(); + m_txd_callback.resolve_safe(); +} + +void dim68k_keyboard_device::device_start() +{ + save_item(NAME(m_p1_in)); +} + +u8 dim68k_keyboard_device::p1_r() +{ + return m_p1_in; +} + +void dim68k_keyboard_device::p2_w(u8 data) +{ + m_txd_callback(BIT(data, 5)); + // Bit 4 is complementary output + + m_capslock_led = !BIT(data, 7); + m_numlock_led = !BIT(data, 6); +} + +WRITE_LINE_MEMBER(dim68k_keyboard_device::prog_w) +{ + if (state) + { + u8 j = m_mcu->p1_r() & 0x0f; + if (j < 11) + m_p1_in = m_keys[j]->read(); + else + m_p1_in = 0xff; + } +} + +u8 dim68k_keyboard_device::eprom_r() +{ + return m_eprom[u16(m_mcu->p2_r() & 1) << 8 | m_mcu->p1_r()]; +} + +void dim68k_keyboard_device::ext_map(address_map &map) +{ + map(0x00, 0x00).mirror(0xff).r(FUNC(dim68k_keyboard_device::eprom_r)); +} + +static INPUT_PORTS_START(dim68k_keyboard) + PORT_START("KEYS0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) PORT_CODE(KEYCODE_NUMLOCK) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CHAR(UCHAR_MAMEKEY(LALT)) PORT_CODE(KEYCODE_LALT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_RALT) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CHAR(UCHAR_MAMEKEY(LSHIFT), UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KEYS1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll Lock Break") PORT_CHAR(UCHAR_MAMEKEY(SCRLOCK)) PORT_CODE(KEYCODE_SLASH_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 9 Pg Up") PORT_CHAR(UCHAR_MAMEKEY(PGUP)) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 6 \u2192") PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CODE(KEYCODE_6_PAD) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad . Del") PORT_CHAR(UCHAR_MAMEKEY(DEL)) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 3 Pg Dn") PORT_CHAR(UCHAR_MAMEKEY(PGDN)) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD) + + PORT_START("KEYS2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CHAR(0x08) PORT_CODE(KEYCODE_BACKSPACE) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 7 Home") PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CODE(KEYCODE_5_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 4 \u2190") PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 2 \u2193") PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 0 Ins") PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 1 End") PORT_CHAR(UCHAR_MAMEKEY(END)) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 8 \u2191") PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD) + + PORT_START("KEYS3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_CLOSEBRACE) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Retrn") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) // duplicate of `/~ key? + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("* PrtSc") PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) PORT_CODE(KEYCODE_ASTERISK) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) // generates 0xDC code + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_CODE(KEYCODE_F10) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('`') PORT_CHAR('~') PORT_CODE(KEYCODE_BACKSLASH) + + PORT_START("KEYS4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('0') PORT_CHAR(')') PORT_CODE(KEYCODE_0) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\'') PORT_CHAR('"') PORT_CODE(KEYCODE_QUOTE) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(';') PORT_CHAR(':') PORT_CODE(KEYCODE_COLON) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_OPENBRACE) + + PORT_START("KEYS5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('<') PORT_CODE(KEYCODE_COMMA) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR('(') PORT_CODE(KEYCODE_9) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O) + + PORT_START("KEYS6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('6') PORT_CHAR('^') PORT_CODE(KEYCODE_6) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('7') PORT_CHAR('&') PORT_CODE(KEYCODE_7) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CODE(KEYCODE_F9) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U) + + PORT_START("KEYS7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('3') PORT_CHAR('#') PORT_CODE(KEYCODE_3) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T) + + PORT_START("KEYS8") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('2') PORT_CHAR('@') PORT_CODE(KEYCODE_2) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q) + + PORT_START("KEYS9") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CHAR(0x1b) PORT_CODE(KEYCODE_TILDE) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CHAR(0x09) PORT_CODE(KEYCODE_TAB) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CODE(KEYCODE_F8) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\\') PORT_CHAR('|') PORT_CODE(KEYCODE_BACKSLASH2) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F2) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F7) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F4) + + PORT_START("KEYS10") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F3) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F6) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F5) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E) +INPUT_PORTS_END + +ioport_constructor dim68k_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(dim68k_keyboard); +} + +void dim68k_keyboard_device::device_add_mconfig(machine_config &config) +{ + I8048(config, m_mcu, 4'752'000 /* 4.608_MHz_XTAL */); // NEC 20-08048-399 + 300-107 XTAL + m_mcu->set_addrmap(AS_IO, &dim68k_keyboard_device::ext_map); + m_mcu->p1_in_cb().set(FUNC(dim68k_keyboard_device::p1_r)); + m_mcu->p2_in_cb().set_constant(0xf7); + m_mcu->p2_out_cb().set(FUNC(dim68k_keyboard_device::p2_w)); + m_mcu->prog_out_cb().set(FUNC(dim68k_keyboard_device::prog_w)); +} + +ROM_START(dim68k_keyboard) + ROM_REGION(0x400, "mcu", 0) + ROM_LOAD("20-08048-399.bin", 0x000, 0x400, CRC(558ad86a) SHA1(a0a356e355b4df6c9565d186e2c878a6302de1b8)) + + ROM_REGION(0x1000, "eprom", 0) + ROM_LOAD("mc114_rev-a.bin", 0x0000, 0x1000, CRC(950542e3) SHA1(d1e87c8ccd17e4e2249fe89f13111ec881b7ebae)) // mirrored every 512 bytes +ROM_END + +const tiny_rom_entry *dim68k_keyboard_device::device_rom_region() const +{ + return ROM_NAME(dim68k_keyboard); +} diff --git a/src/mame/skeleton/dim68k_kbd.h b/src/mame/skeleton/dim68k_kbd.h new file mode 100644 index 00000000000..984bffbd7f1 --- /dev/null +++ b/src/mame/skeleton/dim68k_kbd.h @@ -0,0 +1,67 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Micro Craft Dimension 68000 84-key keyboard + +**********************************************************************/ + +#ifndef MAME_SKELETON_DIM68K_KBD_H +#define MAME_SKELETON_DIM68K_KBD_H + +#pragma once + +#include "cpu/mcs48/mcs48.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> dim68k_keyboard_device + +class dim68k_keyboard_device : public device_t +{ +public: + // device type constructor + dim68k_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // callback configuration + auto txd_callback() { return m_txd_callback.bind(); } + +protected: + // device-level overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + // MCU handlers + u8 p1_r(); + void p2_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(prog_w); + u8 eprom_r(); + + // address map + void ext_map(address_map &map); + + // object finders + required_device m_mcu; + required_region_ptr m_eprom; + required_ioport_array<11> m_keys; + output_finder<> m_capslock_led; + output_finder<> m_numlock_led; + + // output callback + devcb_write_line m_txd_callback; + + // internal state + u8 m_p1_in; +}; + +// device type declarations +DECLARE_DEVICE_TYPE(DIM68K_KEYBOARD, dim68k_keyboard_device) + +#endif // MAME_SKELETON_DIM68K_KBD_H -- cgit v1.2.3