// license:BSD-3-Clause // copyright-holders:Barry Rodewald,Vas Crabb #include "emu.h" #include "machine/x68k_kbd.h" #include "machine/keyboard.ipp" x68k_keyboard_device::x68k_keyboard_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : buffered_rs232_device(mconfig, X68K_KEYBOARD, tag, owner, 0) , device_matrix_keyboard_interface(mconfig, *this, "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6", "LINE7", "LINE8", "LINE9", "LINEA", "LINEB", "LINEC", "LINED", "LINEE") { } void x68k_keyboard_device::received_byte(uint8_t data) { /* Keyboard control commands: 00xxxxxx - TV Control Not of much use as yet 01000xxy - y = Mouse control signal 01001xxy - y = Keyboard enable 010100xy - y = Sharp X1 display compatibility mode 010101xx - xx = LED brightness (00 = bright, 11 = dark) 010110xy - y = Display control enable 010111xy - y = Display control via the Opt. 2 key enable 0110xxxx - xxxx = Key delay (default 500ms) 100 * (delay time) + 200ms 0111xxxx - xxxx = Key repeat rate (default 110ms) (repeat rate)^2*5 + 30ms 1xxxxxxx - xxxxxxx = keyboard LED status b6 = fullwidth b5 = hiragana b4 = insert b3 = caps b2 = code input b1 = romaji b0 = kana */ if (data & 0x80) // LED status { machine().output().set_value("key_led_kana", data & 0x01); machine().output().set_value("key_led_romaji", data & 0x02); machine().output().set_value("key_led_code", data & 0x04); machine().output().set_value("key_led_caps", data & 0x08); machine().output().set_value("key_led_insert", data & 0x10); machine().output().set_value("key_led_hiragana", data & 0x20); machine().output().set_value("key_led_fullsize", data & 0x40); logerror("KB: LED status set to %02x\n", data & 0x7f); } if ((data & 0xc0) == 0) // TV control { // nothing for now } if ((data & 0xf8) == 0x48) // Keyboard enable { m_enabled = data & 0x01; if (m_enabled) start_processing(attotime::from_hz(2'400)); else stop_processing(); logerror("KB: Keyboard enable bit = %i\n", m_enabled); } if ((data & 0xf0) == 0x60) // Key delay time { m_delay = ((data & 0x0f) * 100) + 200; logerror("KB: Keypress delay time is now %ims\n", m_delay); } if ((data & 0xf0) == 0x70) // Key repeat rate { m_repeat = (((data & 0x0f)^2) * 5) + 30; logerror("KB: Keypress repeat rate is now %ims\n", m_repeat); } } void x68k_keyboard_device::key_make(uint8_t row, uint8_t column) { // TODO: work out which keys actually repeat (this assumes it's anything other than ctrl/opt/shift) if (row != 0x0eU) typematic_start(row, column, attotime::from_msec(m_delay), attotime::from_msec(m_repeat)); else typematic_restart(attotime::from_msec(m_delay), attotime::from_msec(m_repeat)); transmit_byte((row << 3) | column); } void x68k_keyboard_device::key_repeat(uint8_t row, uint8_t column) { transmit_byte((row << 3) | column); } void x68k_keyboard_device::key_break(uint8_t row, uint8_t column) { device_matrix_keyboard_interface::key_break(row, column); transmit_byte(0x80U | (row << 3) | column); } static INPUT_PORTS_START( x68k_keyboard ) PORT_START("LINE0") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED) // unused PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) // Escape PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 ! \xE3\x81\xAC") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') // 1 ! ぬ (nu) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 \" \xE3\x81\xB5") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') // 2 " ふ (fu) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 # \xE3\x81\x82 \xE3\x81\x81") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') // 3 # あ ぁ (a) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 $ \xE3\x81\x86 \xE3\x81\x85") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') // 4 $ う ぅ (u) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 % \xE3\x81\x88 \xE3\x81\x87") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') // 5 % え ぇ (e) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 & \xE3\x81\x8A \xE3\x81\x89") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') // 6 & お ぉ (o) PORT_START("LINE1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 \' \xE3\x82\x84 \xE3\x82\x83") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') // 7 ' や ゃ (ya) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 ( \xE3\x82\x86 \xE3\x82\x85") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') // 8 ( ゆ ゅ (yu) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 ) \xE3\x82\x88 \xE3\x82\x87") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') // 9 ) よ ょ (yo) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 \xE3\x82\x8F \xE3\x82\x92") PORT_CODE(KEYCODE_0) PORT_CHAR('0') // 0 わ を (wa wo) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- = \xE3\x81\xBB") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') // - = ほ (ho) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("^ \xE3\x81\xB8") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') // ^ へ (he) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xC2\xA5 | \xE3\x83\xBC") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|') // Yen | ー (sound extension) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) // BS (backspace) PORT_START("LINE2") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) // TAB PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q \xE3\x81\x9F") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') // Q た (ta) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W \xE3\x81\xA6") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') // W て (te) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E \xE3\x81\x84 \xE3\x81\x83") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') // E い ぃ (i) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R \xE3\x81\x99") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') // R す (su) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T \xE3\x81\x8B") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') // T か (ka) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y \xE3\x82\x93") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') // Y ん (n) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U \xE3\x81\xAA") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') // U な (na) PORT_START("LINE3") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I \xE3\x81\xAB") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') // I に (ni) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O \xE3\x82\x89") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') // O ら (ra) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P \xE3\x81\x9B") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') // P せ (se) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@ ` \xE3\x82\x9B") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') PORT_CHAR('`') // @ ` ゛ (dakuten) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ { \xE3\x82\x9C \xE3\x80\x8C") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') PORT_CHAR('{') // [ { ゜ 「 (handakuten kagikakko) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) // Return PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A \xE3\x81\xA1") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') // A ち (chi) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S \xE3\x81\xA8") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') // S と (to) PORT_START("LINE4") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D \xE3\x81\x97") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') // D し (shi) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F \xE3\x81\xAF") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') // F は (ha) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G \xE3\x81\x8D") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') // G き (ki) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("H \xE3\x81\x8F") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') // H く (ku) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J \xE3\x81\xBE") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') // J ま (ma) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K \xE3\x81\xAE") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') // K の (no) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L \xE3\x82\x8A") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') // L り (ri) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; + \xE3\x82\x8C") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') // ; + れ (re) PORT_START("LINE5") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(": * \xE3\x81\x91") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') // : * け (ke) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("] } \xE3\x82\x80 \xE3\x80\x8D") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') PORT_CHAR('}') // ] } む 」 (mu kagikakko) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z \xE3\x81\xA4 \xE3\x81\xA3") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') // Z つ っ (tsu) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X \xE3\x81\x95") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') // X さ (sa) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C \xE3\x81\x9D") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') // C そ (so) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V \xE3\x81\xB2") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') // V ひ (hi) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B \xE3\x81\x93") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') // B こ (ko) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N \xE3\x81\xBF") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') // N み (mi) PORT_START("LINE6") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M \xE3\x82\x82") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') // M も (mo) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", < \xE3\x81\xAD \xE3\x80\x81") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') // , < ね 、 (ne comma) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". > \xE3\x82\x8B \xE3\x80\x82") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') // . > る 。 (ru stop) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ? \xE3\x82\x81 \xE3\x83\xBB") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') // / ? め ・ (me interpunct) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("_ \xE3\x82\x8D") PORT_CHAR('_') // Underscore (shifted only?) ろ (ro) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') // Space PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("HOME") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) // HOME PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) // DEL PORT_START("LINE7") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ROLL UP") PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(PGUP)) // ROLL UP PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ROLL DOWN") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN)) // ROLL DOWN PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("UNDO") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END)) // UNDO PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cursor Left") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) // Left PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cursor Up") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) // Up PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cursor Right") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) // Right PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cursor Down") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) // Down PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey CLR") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) // CLR (clear) PORT_START("LINE8") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey /") PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) // / (numpad) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey *") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) // * (numpad) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) // - (numpad) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) // 7 (numpad) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) // 8 (numpad) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) // 9 (numpad) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey +") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) // + (numpad) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) // 4 (numpad) PORT_START("LINE9") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) // 5 (numpad) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) // 6 (numpad) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey =") // = (numpad) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) // 1 (numpad) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) // 2 (numpad) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) // 3 (numpad) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey ENTER") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) // Enter (numpad) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) // 0 (numpad) PORT_START("LINEA") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey ,") // , (numpad) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tenkey .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) // . (numpad) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xE8\xA8\x98\xE5\x8F\xB7\xE5\x85\xA5\xE5\x8A\x9B (Symbol input)") // 記号入力 (Kigou nyuuryoku - Symbol input) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xE7\x99\xBB\xE9\x8C\xB2 (Register)") // 登録 (Touroku - Register) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Help") // Help PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("XF1") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) // XF1 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("XF2") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) // XF2 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("XF3") // XF3 PORT_START("LINEB") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("XF4") // XF4 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("XF5") PORT_CODE(KEYCODE_RALT) // XF5 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xE3\x81\x8B\xE3\x81\xAA (Kana)") // かな (Kana) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x9E\xE5\xAD\x97 (Romaji)") // ローマ字 (Romaji) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x89\xE5\x85\xA5\xE5\x8A\x9B (Code input)") // コード入力 (Code nyuuryoku - Code input) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) // CAPS (Caps lock) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("INS") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) // INS (Insert) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xE3\x81\xB2\xE3\x82\x89\xE3\x81\x8C\xE3\x81\xAA (Hiragana)") PORT_CODE(KEYCODE_LALT) // ひらがな (Hiragana) PORT_START("LINEC") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\xE5\x85\xA8\xE8\xA7\x92 (Fullwidth)") PORT_CODE(KEYCODE_RCONTROL) // 全角 (Zenkaku - Fullwidth) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break") /* Break */ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Copy") /* Copy */ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) // F1 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) // F2 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) // F3 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) // F4 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) // F5 PORT_START("LINED") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) // F6 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) // F7 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) // F8 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) // F9 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) // F10 // 0x6d reserved // 0x6e reserved // 0x6f reserved PORT_START("LINEE") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // Shift PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) // Control PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("OPT.1") PORT_CODE(KEYCODE_PRTSCR) // Opt1 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("OPT.2") PORT_CODE(KEYCODE_PAUSE) // Opt2 INPUT_PORTS_END ioport_constructor x68k_keyboard_device::device_input_ports() const { return INPUT_PORTS_NAME(x68k_keyboard); } void x68k_keyboard_device::device_start() { buffered_rs232_device::device_start(); save_item(NAME(m_delay)); save_item(NAME(m_repeat)); save_item(NAME(m_enabled)); } void x68k_keyboard_device::device_reset() { buffered_rs232_device::device_reset(); set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); set_rate(38'400); // TODO: Should be 2400 but MC68901 doesn't support divide by 16 receive_register_reset(); transmit_register_reset(); m_enabled = 0; m_delay = 500; // 3*100+200 m_repeat = 110; // 4^2*5+30 stop_processing(); reset_key_state(); typematic_stop(); clear_fifo(); output_dcd(0); output_dsr(0); output_cts(0); output_rxd(1); } DEFINE_DEVICE_TYPE(X68K_KEYBOARD, x68k_keyboard_device, "x68k_keyboard", "Sharp X68000 Keyboard") #if 0 void x68k_state::x68k_keyboard_push_scancode(unsigned char code) { m_keynum++; if(m_keynum >= 1) { // keyboard buffer full if(m_enabled != 0) { //m_mfp.rsr |= 0x80; // Buffer full //if(ioport("options")->read() & 0x01) //{ // m_current_vector[6] = 0x4c; // m_maincpu->set_input_line(6,ASSERT_LINE); // logerror("MFP: Receive buffer full IRQ sent\n"); //} } } m_buffer[m_headpos++] = code; if(m_headpos > 15) { m_headpos = 0; m_current_vector[6] = 0x4b; } } TIMER_CALLBACK_MEMBER(x68k_state::x68k_keyboard_poll) { int x; static const char *const keynames[] = { "key1", "key2", "key3", "key4" }; for(x=0;x<0x80;x++) { // adjust delay/repeat timers if(m_keytime[x] > 0) { m_keytime[x] -= 5; } if(!(ioport(keynames[x / 32])->read() & (1 << (x % 32)))) { if(m_keyon[x] != 0) { x68k_keyboard_push_scancode(0x80 + x); m_keytime[x] = 0; m_keyon[x] = 0; m_last_pressed = 0; logerror("KB: Released key 0x%02x\n",x); } } // check to see if a key is being held if(m_keyon[x] != 0 && m_keytime[x] == 0 && m_last_pressed == x) { if(ioport(keynames[m_last_pressed / 32])->read() & (1 << (m_last_pressed % 32))) { x68k_keyboard_push_scancode(m_last_pressed); m_keytime[m_last_pressed] = (m_repeat^2)*5+30; logerror("KB: Holding key 0x%02x\n",m_last_pressed); } } if((ioport(keynames[x / 32])->read() & (1 << (x % 32)))) { if(m_keyon[x] == 0) { x68k_keyboard_push_scancode(x); m_keytime[x] = m_delay * 100 + 200; m_keyon[x] = 1; m_last_pressed = x; logerror("KB: Pushed key 0x%02x\n",x); } } } } struct { unsigned char led_status; // keyboard LED status unsigned char buffer[16]; int headpos; // scancodes are added here int tailpos; // scancodes are read from here int keynum; // number of scancodes in buffer int keytime[0x80]; // time until next keypress int keyon[0x80]; // is 1 if key is pressed, used to determine if the key state has changed from 1 to 0 int last_pressed; // last key pressed, for repeat key handling } m_keyboard; TIMER_CALLBACK_MEMBER(x68k_led_callback); TIMER_CALLBACK_MEMBER(x68k_keyboard_poll); void x68k_keyboard_ctrl_w(int data); int x68k_keyboard_pop_scancode(); void x68k_keyboard_push_scancode(unsigned char code); #endif