// license:BSD-3-Clause // copyright-holders:Peter Trauner, Kevin Thacker /********************************************************************** pckeybrd.c PC-style keyboard emulation This emulation is decoupled from the AT 8042 emulation used in the IBM ATs and above **********************************************************************/ /* Todo: (added by KT 22-Jun-2000 1. Check scancodes I have added are the actual scancodes for set 2 or 3. 2. Check how codes are changed based on Shift/Control states for those sets that require it - info in Help PC! */ #include "emu.h" #include "pckeybrd.h" #include "natkeyboard.h" /* AT keyboard documentation comes from www.beyondlogic.org and HelpPC documentation */ /* to enable logging of keyboard read/writes */ #define LOG_KEYBOARD 0 /* The PS/2 models have three make/break scan code sets. The first set matches the PC & XT make/break scan code set and is the one listed here. Scan code sets are selected by writing the value F0 to the keyboard via the ~8042~ (port 60h). The following is a brief description of the scan code sets (see the PS/2 Technical Reference manuals for more information on scan code sets 2 and 3): * set 1, each key has a base scan code. Some keys generate extra scan codes to generate artificial shift states. This is similar to the standard scan code set used on the PC and XT. * set 2, each key sends one make scan code and two break scan codes bytes (F0 followed by the make code). This scan code set is available on the IBM AT also. * set 3, each key sends one make scan code and two break scan codes bytes (F0 followed by the make code) and no keys are altered by Shift/Alt/Ctrl keys. * typematic scan codes are the same as the make scan code */ /* using the already existing input port definitions, this table re-maps to scancode set 3. I don't have the details for scan-code set 2,3 but they sound very similar to the scancode set I have here. - KT 22/Jun/2000 */ /* key set 3 */ const int at_keyboard_device::m_scancode_set_2_3[]= { 0, 0x076, 0x016, 0x01e, 0x026, 0x025, 0x02e, 0x036, 0x03d, 0x03e, 0x046, 0x045, 0x04e, 0x055, 0x066, 0x00d, 0x015, 0x01d, 0x024, 0x02d, 0x02c, 0x035, 0x03c, 0x043, 0x044, 0x04d, 0x054, 0x05b, 0x05a, 0x014, 0x01c, 0x01b, 0x023, 0x02b, 0x034, 0x033, 0x03b, 0x042, 0x04b, 0x04c, 0x052, 0x00e, 0x012, 0x05d, 0x01a, 0x022, 0x021, 0x02a, 0x032, 0x031, 0x03a, 0x041, 0x049, 0x04a, 0x059, 0x000, 0x011, 0x029, 0x058, 0x05, 0x06, 0x04, 0x0c, 0x03, 0x0b, 0x083, 0x0a, 0x01, 0x09, 0x077, 0x07e, 0x06c, 0x075, 0x07d, 0x07b, 0x06b, 0x073, 0x074, 0x079, 0x069, 0x072, 0x07a, 0x070, 0x071, 0x00, 0x00, 0x078, 0x07, 0x05a, 0x014, 0x04a, 0x000, 0x011, 0x06c, 0x075, 0x07d, 0x06b, 0x074, 0x069, 0x072, 0x07a, 0x070, 0x071, 0x000, 0x000, 0x000 }; const at_keyboard_device::extended_keyboard_code at_keyboard_device::m_mf2_code[0x10][2/*numlock off, on*/]={ { { "\xe0\x1c", "\xe0\x9c" } }, // keypad enter { { "\xe0\x1d", "\xe0\x9d" } }, // right control { { "\xe0\x35", "\xe0\xb5" } }, { { "\xe0\x37", "\xe0\xb7" } }, { { "\xe0\x38", "\xe0\xb8" } }, { { "\xe0\x47", "\xe0\xc7" }, { "\xe0\x2a\xe0\x47", "\xe0\xc7\xe0\xaa" } }, { { "\xe0\x48", "\xe0\xc8" }, { "\xe0\x2a\xe0\x48", "\xe0\xc8\xe0\xaa" } }, { { "\xe0\x49", "\xe0\xc9" }, { "\xe0\x2a\xe0\x49", "\xe0\xc9\xe0\xaa" } }, { { "\xe0\x4b", "\xe0\xcb" }, { "\xe0\x2a\xe0\x4b", "\xe0\xcb\xe0\xaa" } }, { { "\xe0\x4d", "\xe0\xcd" }, { "\xe0\x2a\xe0\x4d", "\xe0\xcd\xe0\xaa" } }, { { "\xe0\x4f", "\xe0\xcf" }, { "\xe0\x2a\xe0\x4f", "\xe0\xcf\xe0\xaa" } }, { { "\xe0\x50", "\xe0\xd0" }, { "\xe0\x2a\xe0\x50", "\xe0\xd0\xe0\xaa" } }, { { "\xe0\x51", "\xe0\xd1" }, { "\xe0\x2a\xe0\x51", "\xe0\xd1\xe0\xaa" } }, { { "\xe0\x52", "\xe0\xd2" }, { "\xe0\x2a\xe0\x52", "\xe0\xd2\xe0\xaa" } }, { { "\xe0\x53", "\xe0\xd3" }, { "\xe0\x2a\xe0\x53", "\xe0\xd3\xe0\xaa" } }, { { "\xe1\x1d\x45\xe1\x9d\xc5" }, { "\xe0\x2a\xe1\x1d\x45\xe1\x9d\xc5" } } }; /* I don't think these keys change if num-lock is active! */ /* pc-at extended keyboard make/break codes for code set 3 */ const at_keyboard_device::extended_keyboard_code at_keyboard_device::m_extended_codes_set_2_3[]= { /*keypad enter */ { "\xe0\x5a", "\xe0\xf0\x5a" }, /* right control */ { "\xe0\x14", "\xe0\xf0\x14" }, /* keypad slash */ { "\xe0\x4a", "\xe0\xf0\x4a" }, /* print screen */ { "\xe0\x12\xe0\x7c", nullptr, /* I don't know the break sequence */ }, /* right alt */ { "\xe0\x11", "\xe0\xf0\x11" }, /* home */ { "\xe0\x6c", "\xe0\xf0\x6c" }, /* cursor up */ { "\xe0\x75", "\xe0\xf0\x75" }, /* page up */ { "\xe0\x7d", "\xe0\xf0\x7d" }, /* cursor left */ { "\xe0\x6b", "\xe0\xf0\x6b", }, /* cursor right */ { "\xe0\x74", "\xe0\xf0\x74" }, /* end */ { "\xe0\x69", "\xe0\xf0\x69", }, /* cursor down */ { "\xe0\x72", "\xe0\xf0\x72" }, /* page down */ { "\xe0\x7a", "\xe0\xf0\x7a" }, /* insert */ { "\xe0\x70", "\xe0\xf0\x70", }, /* delete */ { "\xe0\x71", "\xe0\xf0\x71" }, /* pause */ { "\xe1\x14\x77\xe1\xf0\x14\xf0\x77", nullptr, /*?? I don't know the break sequence */ } }; DEFINE_DEVICE_TYPE(PC_KEYB, pc_keyboard_device, "pc_keyb", "PC Keyboard") DEFINE_DEVICE_TYPE(AT_KEYB, at_keyboard_device, "at_keyb", "AT Keyboard") pc_keyboard_device::pc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pc_keyboard_device(mconfig, PC_KEYB, tag, owner, clock) { m_type = KEYBOARD_TYPE::PC; } pc_keyboard_device::pc_keyboard_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), m_ioport(*this, ":pc_keyboard_%u", 0), m_out_keypress_func(*this) { } at_keyboard_device::at_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pc_keyboard_device(mconfig, AT_KEYB, tag, owner, clock), m_leds(*this, "led%u", 0U), m_scan_code_set(1) { m_type = KEYBOARD_TYPE::AT; } void pc_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { polling(); if(!charqueue_empty()) m_out_keypress_func(1); } void pc_keyboard_device::device_start() { save_item(NAME(m_delay)); save_item(NAME(m_repeat)); save_item(NAME(m_numlock)); save_item(NAME(m_on)); save_item(NAME(m_head)); save_item(NAME(m_tail)); save_pointer(NAME(m_queue), ARRAY_LENGTH(m_queue)); save_pointer(NAME(m_make), ARRAY_LENGTH(m_make)); memset(m_make, 0, sizeof(m_make)); machine().ioport().natkeyboard().configure( ioport_queue_chars_delegate(&pc_keyboard_device::queue_chars, this), ioport_accept_char_delegate(&pc_keyboard_device::accept_char, this), ioport_charqueue_empty_delegate(&pc_keyboard_device::charqueue_empty, this)); m_out_keypress_func.resolve_safe(); m_keyboard_timer = timer_alloc(); } void at_keyboard_device::device_start() { save_item(NAME(m_scan_code_set)); save_item(NAME(m_input_state)); pc_keyboard_device::device_start(); m_leds.resolve(); } void pc_keyboard_device::device_reset() { m_delay = 60; m_repeat = 8; m_numlock = 0; m_on = true; m_head = m_tail = 0; queue_insert(0xaa); m_keyboard_timer->adjust(attotime::from_msec(5), 0, attotime::from_hz(60)); } void at_keyboard_device::device_reset() { m_input_state = 0; pc_keyboard_device::device_reset(); /* set default led state */ m_leds[2] = 0; m_leds[0] = 0; m_leds[1] = 0; } WRITE_LINE_MEMBER(pc_keyboard_device::enable) { if(state && !m_on) { if(m_type == KEYBOARD_TYPE::PC) reset(); else m_keyboard_timer->adjust(attotime::from_msec(5), 0, attotime::from_hz(60)); } else if(!state) m_keyboard_timer->adjust(attotime::never); m_on = state ? true : false; } /* insert a code into the buffer */ void pc_keyboard_device::queue_insert(uint8_t data) { if (LOG_KEYBOARD) logerror("keyboard queueing %.2x\n",data); m_queue[m_head] = data; m_head++; m_head %= ARRAY_LENGTH(m_queue); } int pc_keyboard_device::queue_size(void) { int queue_size; queue_size = m_head - m_tail; if (queue_size < 0) queue_size += ARRAY_LENGTH(m_queue); return queue_size; } void pc_keyboard_device::standard_scancode_insert(int our_code, int pressed) { if (!pressed) { /* adjust code for break code */ our_code|=0x080; } queue_insert(our_code); } /* add codes for standard keys */ void at_keyboard_device::standard_scancode_insert(int our_code, int pressed) { int scancode; switch (m_scan_code_set) { case 1: default: { /* the original code was designed for this set, and there is a 1:1 correspondance for the scancodes */ scancode = our_code; if (!pressed) { /* adjust code for break code */ scancode|=0x080; } } break; case 2: case 3: { /* lookup scancode */ scancode = m_scancode_set_2_3[our_code]; if (!pressed) { /* break code */ queue_insert(0x0f0); } } break; } queue_insert(scancode); } void at_keyboard_device::extended_scancode_insert(int code, int pressed) { code = code - 0x060; switch (m_scan_code_set) { case 1: default: { if (pressed) { if (m_mf2_code[code][m_numlock].pressed) helper(m_mf2_code[code][m_numlock].pressed); else helper(m_mf2_code[code][0].pressed); } else { if (m_mf2_code[code][m_numlock].released) helper(m_mf2_code[code][m_numlock].released); else if (m_mf2_code[code][0].released) helper(m_mf2_code[code][0].released); } } break; case 2: case 3: { const extended_keyboard_code *key = &m_extended_codes_set_2_3[code]; if (pressed) { if (key->pressed) { helper(key->pressed); } } else { if (key->released) { helper(key->released); } } } break; } } /* add a list of codes to the keyboard buffer */ void at_keyboard_device::helper(const char *codes) { int i; for (i = 0; codes[i]; i++) queue_insert(codes[i]); } /************************************************************************** * scan keys and stuff make/break codes **************************************************************************/ uint32_t pc_keyboard_device::readport(int port) { if ((m_ioport.size() > port) && m_ioport[port].found()) return m_ioport[port]->read(); else return 0; } void pc_keyboard_device::polling(void) { int i; if (m_on) { /* add codes for keys that are set */ for( i = 0x01; i < 0x80; i++ ) { if (i==0x60) i+=0x10; // keys 0x60..0x6f need special handling if( readport(i/16) & (1 << (i & 15)) ) { if( m_make[i] == 0 ) { m_make[i] = 1; if (i==0x45) m_numlock^=1; standard_scancode_insert(i,1); } else if((i != 0x45) && (i != 0x3a)) // don't send repeats for caps or num lock { m_make[i] += 1; if( m_make[i] == m_delay ) { standard_scancode_insert(i, 1); } else { if( m_make[i] == m_delay + m_repeat ) { m_make[i] = m_delay; standard_scancode_insert(i, 1); } } } } else { if( m_make[i] ) { m_make[i] = 0; standard_scancode_insert(i, 0); } } } if(m_type != KEYBOARD_TYPE::PC) { /* extended scan-codes */ for( i = 0x60; i < 0x70; i++ ) { if( readport(i/16) & (1 << (i & 15)) ) { if( m_make[i] == 0 ) { m_make[i] = 1; extended_scancode_insert(i,1); } else { m_make[i] += 1; if( m_make[i] == m_delay ) { extended_scancode_insert(i, 1); } else { if( m_make[i] == m_delay + m_repeat ) { m_make[i]=m_delay; extended_scancode_insert(i, 1); } } } } else { if( m_make[i] ) { m_make[i] = 0; extended_scancode_insert(i,0); } } } } } } READ8_MEMBER(pc_keyboard_device::read) { int data; if (m_tail == m_head) return 0; data = m_queue[m_tail]; if (LOG_KEYBOARD) logerror("read(): Keyboard Read 0x%02x\n",data); m_tail++; m_tail %= ARRAY_LENGTH(m_queue); return data; } void pc_keyboard_device::clear_buffer(void) { m_head = m_tail = 0; } void at_keyboard_device::clear_buffer_and_acknowledge(void) { clear_buffer(); queue_insert(0x0fa); } /* From Ralf Browns Interrupt list: Values for keyboard commands (data also goes to PORT 0060h): Value Count Description EDh double set/reset mode indicators Caps Num Scrl bit 2 = CapsLk, bit 1 = NumLk, bit 0 = ScrlLk all other bits must be zero. EEh sngl diagnostic echo. returns EEh. EFh sngl NOP (No OPeration). reserved for future use EF+26h double [Cherry MF2 G80-1501HAD] read 256 bytes of chipcard data keyboard must be disabled before this and has to be enabled after finished. F0h double get/set scan code set 00h get current set 01h scancode set 1 (PCs and PS/2 mod 30, except Type 2 ctrlr) 02h scancode set 2 (ATs, PS/2, default) 03h scancode set 3 F2h sngl read keyboard ID (read two ID bytes) AT keyboards returns FA (ACK) MF2 returns AB 41 (translation) or AB 83 (pass through) F3h double set typematic rate/delay format of the second byte: bit7=0 : reserved bit6-5 : typemativ delay 00b=250ms 10b= 750ms 01b=500ms 11b=1000ms bit4-0 : typematic rate (see #P050) F4h sngl enable keyboard F5h sngl disable keyboard. set default parameters (no keyboard scanning) F6h sngl set default parameters F7h sngl [MCA] set all keys to typematic (scancode set 3) F8h sngl [MCA] set all keys to make/release F9h sngl [MCA] set all keys to make only FAh sngl [MCA] set all keys to typematic/make/release FBh sngl [MCA] set al keys to typematic FCh double [MCA] set specific key to make/release FDh double [MCA] set specific key to make only FEh sngl resend last scancode FFh sngl perform internal power-on reset function Note: each command is acknowledged by FAh (ACK), if not mentioned otherwise. See PORT 0060h-R for details. SeeAlso: #P046 */ WRITE8_MEMBER(at_keyboard_device::write) { if (LOG_KEYBOARD) logerror("keyboard write %.2x\n",data); switch (m_input_state) { case 0: switch (data) { case 0xed: // leds schalten /* acknowledge */ queue_insert(0x0fa); /* now waiting for code... */ m_input_state=1; break; case 0xee: // echo /* echo code with no acknowledge */ queue_insert(0xee); break; case 0xf0: // scancodes adjust /* acknowledge */ clear_buffer_and_acknowledge(); /* waiting for data */ m_input_state=2; break; case 0xf2: // identify keyboard /* ack and two byte keyboard id */ queue_insert(0xfa); /* send keyboard code */ if (m_type == KEYBOARD_TYPE::MF2) { queue_insert(0xab); queue_insert(0x41); } else { /* from help-pc docs */ queue_insert(0x0ab); queue_insert(0x083); } break; case 0xf3: // adjust rates /* acknowledge */ queue_insert(0x0fa); m_input_state=3; break; case 0xf4: // activate clear_buffer_and_acknowledge(); enable(1); break; case 0xf5: /* acknowledge */ clear_buffer_and_acknowledge(); // standardvalues enable(0); break; case 0xf6: clear_buffer_and_acknowledge(); // standardvalues enable(1); break; case 0xfe: // resend // should not happen, for now send 0 queue_insert(0); //m_last_code); break; case 0xff: // reset /* it doesn't state this in the docs I have read, but I assume that the keyboard input buffer is cleared. The PCW16 sends &ff, and requires that 0x0fa is the first byte to be read */ reset(); clear_buffer_and_acknowledge(); queue_insert(0xaa); break; } break; case 1: /* code received */ m_input_state=0; /* command? */ if (data & 0x080) { /* command received instead of code - execute command */ write(space, offset, data); } else { /* send acknowledge */ queue_insert(0x0fa); /* led bits */ /* bits: 0 scroll lock, 1 num lock, 2 capslock */ /* led's in same order as my keyboard leds. */ /* num lock, caps lock, scroll lock */ m_leds[2] = BIT(data, 0); m_leds[0] = BIT(data, 1); m_leds[1] = BIT(data, 2); } break; case 2: m_input_state=0; /* command? */ if (data & 0x080) { /* command received instead of code - execute command */ write(space, offset, data); } else { /* 00 return byte indicating scan code set in use 01 select scan code set 1 (used on PC & XT) 02 select scan code set 2 03 select scan code set 3 */ if (data == 0x00) { queue_insert(m_scan_code_set); } else { if(data && (data <= 3)) m_scan_code_set = data; } } break; case 3: /* 6,5: 250ms, 500ms, 750ms, 1s */ /* 4..0: 30 26.7 .... 2 chars/s*/ /* command? */ m_input_state=0; if (data & 0x080) { /* command received instead of code - execute command */ write(space, offset, data); } else { /* received keyboard repeat */ } break; } } /*************************************************************************** unicode_char_to_at_keycode ***************************************************************************/ uint8_t pc_keyboard_device::unicode_char_to_at_keycode(char32_t ch) { uint8_t b; switch(ch) { case '\033': b = 1; break; case '1': b = 2; break; case '2': b = 3; break; case '3': b = 4; break; case '4': b = 5; break; case '5': b = 6; break; case '6': b = 7; break; case '7': b = 8; break; case '8': b = 9; break; case '9': b = 10; break; case '0': b = 11; break; case '-': b = 12; break; case '=': b = 13; break; case '\010': b = 14; break; case '\t': b = 15; break; case 'q': b = 16; break; case 'w': b = 17; break; case 'e': b = 18; break; case 'r': b = 19; break; case 't': b = 20; break; case 'y': b = 21; break; case 'u': b = 22; break; case 'i': b = 23; break; case 'o': b = 24; break; case 'p': b = 25; break; case '[': b = 26; break; case ']': b = 27; break; case '\r': b = 28; break; case UCHAR_MAMEKEY(CAPSLOCK): b = 29; break; case 'a': b = 30; break; case 's': b = 31; break; case 'd': b = 32; break; case 'f': b = 33; break; case 'g': b = 34; break; case 'h': b = 35; break; case 'j': b = 36; break; case 'k': b = 37; break; case 'l': b = 38; break; case ';': b = 39; break; case '\'': b = 40; break; case '`': b = 41; break; case '\\': b = 43; break; case 'z': b = 44; break; case 'x': b = 45; break; case 'c': b = 46; break; case 'v': b = 47; break; case 'b': b = 48; break; case 'n': b = 49; break; case 'm': b = 50; break; case ',': b = 51; break; case '.': b = 52; break; case '/': b = 53; break; case ' ': b = 0x39; break; case UCHAR_MAMEKEY(F1): b = 0x3b; break; case UCHAR_MAMEKEY(F2): b = 0x3c; break; case UCHAR_MAMEKEY(F3): b = 0x3d; break; case UCHAR_MAMEKEY(F4): b = 0x3e; break; case UCHAR_MAMEKEY(F5): b = 0x3f; break; case UCHAR_MAMEKEY(F6): b = 0x40; break; case UCHAR_MAMEKEY(F7): b = 0x41; break; case UCHAR_MAMEKEY(F8): b = 0x42; break; case UCHAR_MAMEKEY(F9): b = 0x43; break; case UCHAR_MAMEKEY(F10): b = 0x44; break; case UCHAR_MAMEKEY(NUMLOCK): b = 0x45; break; case UCHAR_MAMEKEY(SCRLOCK): b = 0x46; break; case UCHAR_MAMEKEY(7_PAD): b = 0x47; break; case UCHAR_MAMEKEY(8_PAD): b = 0x48; break; case UCHAR_MAMEKEY(9_PAD): b = 0x49; break; case UCHAR_MAMEKEY(MINUS_PAD): b = 0x4a; break; case UCHAR_MAMEKEY(4_PAD): b = 0x4b; break; case UCHAR_MAMEKEY(5_PAD): b = 0x4c; break; case UCHAR_MAMEKEY(6_PAD): b = 0x4d; break; case UCHAR_MAMEKEY(PLUS_PAD): b = 0x4e; break; case UCHAR_MAMEKEY(1_PAD): b = 0x4f; break; case UCHAR_MAMEKEY(2_PAD): b = 0x50; break; case UCHAR_MAMEKEY(3_PAD): b = 0x51; break; case UCHAR_MAMEKEY(0_PAD): b = 0x52; break; case UCHAR_MAMEKEY(DEL_PAD): b = 0x53; break; case UCHAR_MAMEKEY(F11): b = 0x57; break; case UCHAR_MAMEKEY(F12): b = 0x58; break; case '~': b = 0x81; break; case '!': b = 0x82; break; case '@': b = 0x83; break; case '#': b = 0x84; break; case '$': b = 0x85; break; case '%': b = 0x86; break; case '^': b = 0x87; break; case '&': b = 0x88; break; case '*': b = 0x89; break; case '(': b = 0x8a; break; case ')': b = 0x8b; break; case '_': b = 0x8c; break; case '+': b = 0x8d; break; case 'Q': b = 0x90; break; case 'W': b = 0x91; break; case 'E': b = 0x92; break; case 'R': b = 0x93; break; case 'T': b = 0x94; break; case 'Y': b = 0x95; break; case 'U': b = 0x96; break; case 'I': b = 0x97; break; case 'O': b = 0x98; break; case 'P': b = 0x99; break; case '{': b = 0x9a; break; case '}': b = 0x9b; break; case 'A': b = 0x9e; break; case 'S': b = 0x9f; break; case 'D': b = 0xa0; break; case 'F': b = 0xa1; break; case 'G': b = 0xa2; break; case 'H': b = 0xa3; break; case 'J': b = 0xa4; break; case 'K': b = 0xa5; break; case 'L': b = 0xa6; break; case ':': b = 0xa7; break; case '\"': b = 0xa8; break; case '|': b = 0xab; break; case 'Z': b = 0xac; break; case 'X': b = 0xad; break; case 'C': b = 0xae; break; case 'V': b = 0xaf; break; case 'B': b = 0xb0; break; case 'N': b = 0xb1; break; case 'M': b = 0xb2; break; case '<': b = 0xb3; break; case '>': b = 0xb4; break; case '?': b = 0xb5; break; default: b = 0; break; } return b; } /*************************************************************************** queue_chars ***************************************************************************/ int pc_keyboard_device::queue_chars(const char32_t *text, size_t text_len) { int i; uint8_t b; for (i = 0; (i < text_len) && ((queue_size()) + 4 < sizeof(m_queue)); i++) { b = unicode_char_to_at_keycode(text[i]); if (b) { if (b & 0x80) standard_scancode_insert(0x36, 1); standard_scancode_insert(b & 0x7f, 1); standard_scancode_insert(b & 0x7f, 0); if (b & 0x80) standard_scancode_insert(0x36, 0); } } return i; } /*************************************************************************** Keyboard declaration ***************************************************************************/ INPUT_PORTS_START( pc_keyboard ) PORT_START("pc_keyboard_0") PORT_BIT ( 0x0001, 0x0000, IPT_UNUSED ) /* unused scancode 0 */ PORT_BIT( 0x0002, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) /* Esc 01 81 */ PORT_BIT( 0x0004, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') /* 1 02 82 */ PORT_BIT( 0x0008, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') /* 2 03 83 */ PORT_BIT( 0x0010, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') /* 3 04 84 */ PORT_BIT( 0x0020, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') /* 4 05 85 */ PORT_BIT( 0x0040, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') /* 5 06 86 */ PORT_BIT( 0x0080, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') /* 6 07 87 */ PORT_BIT( 0x0100, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') /* 7 08 88 */ PORT_BIT( 0x0200, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') /* 8 09 89 */ PORT_BIT( 0x0400, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') /* 9 0A 8A */ PORT_BIT( 0x0800, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') /* 0 0B 8B */ PORT_BIT( 0x1000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') /* - 0C 8C */ PORT_BIT( 0x2000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') /* = 0D 8D */ PORT_BIT( 0x4000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) /* Backspace 0E 8E */ PORT_BIT( 0x8000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) /* Tab 0F 8F */ PORT_START("pc_keyboard_1") PORT_BIT( 0x0001, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') /* Q 10 90 */ PORT_BIT( 0x0002, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') /* W 11 91 */ PORT_BIT( 0x0004, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') /* E 12 92 */ PORT_BIT( 0x0008, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') /* R 13 93 */ PORT_BIT( 0x0010, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') /* T 14 94 */ PORT_BIT( 0x0020, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') /* Y 15 95 */ PORT_BIT( 0x0040, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') /* U 16 96 */ PORT_BIT( 0x0080, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') /* I 17 97 */ PORT_BIT( 0x0100, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') /* O 18 98 */ PORT_BIT( 0x0200, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') /* P 19 99 */ PORT_BIT( 0x0400, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') /* [ 1A 9A */ PORT_BIT( 0x0800, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') /* ] 1B 9B */ PORT_BIT( 0x1000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) /* Enter 1C 9C */ PORT_BIT( 0x2000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) /* Left Ctrl 1D 9D */ PORT_BIT( 0x4000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') /* A 1E 9E */ PORT_BIT( 0x8000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') /* S 1F 9F */ PORT_START("pc_keyboard_2") PORT_BIT( 0x0001, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') /* D 20 A0 */ PORT_BIT( 0x0002, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') /* F 21 A1 */ PORT_BIT( 0x0004, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') /* G 22 A2 */ PORT_BIT( 0x0008, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') /* H 23 A3 */ PORT_BIT( 0x0010, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') /* J 24 A4 */ PORT_BIT( 0x0020, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') /* K 25 A5 */ PORT_BIT( 0x0040, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') /* L 26 A6 */ PORT_BIT( 0x0080, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') /* ; 27 A7 */ PORT_BIT( 0x0100, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"') /* ' 28 A8 */ PORT_BIT( 0x0200, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') /* ` 29 A9 */ PORT_BIT( 0x0400, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_MAMEKEY(LSHIFT)) /* Left Shift 2A AA */ PORT_BIT( 0x0800, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') /* \ 2B AB */ PORT_BIT( 0x1000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') /* Z 2C AC */ PORT_BIT( 0x2000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') /* X 2D AD */ PORT_BIT( 0x4000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') /* C 2E AE */ PORT_BIT( 0x8000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') /* V 2F AF */ PORT_START("pc_keyboard_3") PORT_BIT( 0x0001, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') /* B 30 B0 */ PORT_BIT( 0x0002, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') /* N 31 B1 */ PORT_BIT( 0x0004, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') /* M 32 B2 */ PORT_BIT( 0x0008, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') /* , 33 B3 */ PORT_BIT( 0x0010, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') /* . 34 B4 */ PORT_BIT( 0x0020, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') /* / 35 B5 */ PORT_BIT( 0x0040, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) /* Right Shift 36 B6 */ PORT_BIT( 0x0080, 0x0000, IPT_KEYBOARD) PORT_NAME("KP * (PrtScr)") PORT_CODE(KEYCODE_ASTERISK) /* Keypad * (PrtSc) 37 B7 */ PORT_BIT( 0x0100, 0x0000, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT) /* Left Alt 38 B8 */ PORT_BIT( 0x0200, 0x0000, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') /* Space 39 B9 */ PORT_BIT( 0x0400, 0x0000, IPT_KEYBOARD) PORT_NAME("Caps") PORT_CODE(KEYCODE_CAPSLOCK) /* Caps Lock 3A BA */ PORT_BIT( 0x0800, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) /* F1 3B BB */ PORT_BIT( 0x1000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) /* F2 3C BC */ PORT_BIT( 0x2000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) /* F3 3D BD */ PORT_BIT( 0x4000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) /* F4 3E BE */ PORT_BIT( 0x8000, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) /* F5 3F BF */ PORT_START("pc_keyboard_4") PORT_BIT( 0x0001, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) /* F6 40 C0 */ PORT_BIT( 0x0002, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) /* F7 41 C1 */ PORT_BIT( 0x0004, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) /* F8 42 C2 */ PORT_BIT( 0x0008, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) /* F9 43 C3 */ PORT_BIT( 0x0010, 0x0000, IPT_KEYBOARD) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) /* F10 44 C4 */ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NumLock") PORT_CODE(KEYCODE_NUMLOCK) /* Num Lock 45 C5 */ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ScrLock") PORT_CODE(KEYCODE_SCRLOCK) /* Scroll Lock 46 C6 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 7 (Home)") PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_HOME ) /* Keypad 7 (Home) 47 C7 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 8 (Up)") PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_UP ) /* Keypad 8 (Up arrow) 48 C8 */ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 9 (PgUp)") PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_PGUP) /* Keypad 9 (PgUp) 49 C9 */ PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) /* Keypad - 4A CA */ PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 4 (Left)") PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_LEFT ) /* Keypad 4 (Left arrow) 4B CB */ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) /* Keypad 5 4C CC */ PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 6 (Right)") PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_RIGHT ) /* Keypad 6 (Right arrow) 4D CD */ PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP +") PORT_CODE(KEYCODE_PLUS_PAD) /* Keypad + 4E CE */ PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 1 (End)") PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_END ) /* Keypad 1 (End) 4F CF */ PORT_START("pc_keyboard_5") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 2 (Down)") PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_DOWN ) /* Keypad 2 (Down arrow) 50 D0 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 3 (PgDn)") PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_PGDN ) /* Keypad 3 (PgDn) 51 D1 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 0 (Ins)") PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_INSERT ) /* Keypad 0 (Ins) 52 D2 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP . (Del)") PORT_CODE(KEYCODE_DEL_PAD) PORT_CODE(KEYCODE_DEL ) /* Keypad . (Del) 53 D3 */ PORT_BIT ( 0x0030, 0x0000, IPT_UNUSED ) PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(84/102)\\") PORT_CODE(KEYCODE_BACKSLASH2) /* Backslash 2 56 D6 */ PORT_BIT ( 0xff80, 0x0000, IPT_UNUSED ) INPUT_PORTS_END INPUT_PORTS_START( at_keyboard ) PORT_START("pc_keyboard_0") PORT_BIT ( 0x0001, 0x0000, IPT_UNUSED ) /* unused scancode 0 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) /* Esc 01 81 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) /* 1 02 82 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) /* 2 03 83 */ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) /* 3 04 84 */ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) /* 4 05 85 */ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) /* 5 06 86 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) /* 6 07 87 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) /* 7 08 88 */ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) /* 8 09 89 */ PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) /* 9 0A 8A */ PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) /* 0 0B 8B */ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) /* - 0C 8C */ PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) /* = 0D 8D */ PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("<--") PORT_CODE(KEYCODE_BACKSPACE) /* Backspace 0E 8E */ PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) /* Tab 0F 8F */ PORT_START("pc_keyboard_1") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) /* Q 10 90 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) /* W 11 91 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) /* E 12 92 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) /* R 13 93 */ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) /* T 14 94 */ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) /* Y 15 95 */ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) /* U 16 96 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) /* I 17 97 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) /* O 18 98 */ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) /* P 19 99 */ PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) /* [ 1A 9A */ PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) /* ] 1B 9B */ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) /* Enter 1C 9C */ PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L-Ctrl") PORT_CODE(KEYCODE_LCONTROL) /* Left Ctrl 1D 9D */ PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) /* A 1E 9E */ PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) /* S 1F 9F */ PORT_START("pc_keyboard_2") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) /* D 20 A0 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) /* F 21 A1 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) /* G 22 A2 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) /* H 23 A3 */ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) /* J 24 A4 */ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) /* K 25 A5 */ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) /* L 26 A6 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) /* ; 27 A7 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) /* ' 28 A8 */ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("` ~") PORT_CODE(KEYCODE_TILDE) /* ` 29 A9 */ PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L-Shift") PORT_CODE(KEYCODE_LSHIFT) /* Left Shift 2A AA */ PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) /* \ 2B AB */ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) /* Z 2C AC */ PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) /* X 2D AD */ PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) /* C 2E AE */ PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) /* V 2F AF */ PORT_START("pc_keyboard_3") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) /* B 30 B0 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) /* N 31 B1 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) /* M 32 B2 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) /* , 33 B3 */ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) /* . 34 B4 */ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) /* / 35 B5 */ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R-Shift") PORT_CODE(KEYCODE_RSHIFT) /* Right Shift 36 B6 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP * (PrtScr)") PORT_CODE(KEYCODE_ASTERISK ) /* Keypad * (PrtSc) 37 B7 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT) /* Left Alt 38 B8 */ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) /* Space 39 B9 */ PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps") PORT_CODE(KEYCODE_CAPSLOCK) /* Caps Lock 3A BA */ PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) /* F1 3B BB */ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) /* F2 3C BC */ PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) /* F3 3D BD */ PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) /* F4 3E BE */ PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) /* F5 3F BF */ PORT_START("pc_keyboard_4") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) /* F6 40 C0 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) /* F7 41 C1 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) /* F8 42 C2 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) /* F9 43 C3 */ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) /* F10 44 C4 */ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NumLock") PORT_CODE(KEYCODE_NUMLOCK) /* Num Lock 45 C5 */ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ScrLock") PORT_CODE(KEYCODE_SCRLOCK) /* Scroll Lock 46 C6 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 7 (Home)") PORT_CODE(KEYCODE_7_PAD ) /* Keypad 7 (Home) 47 C7 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 8 (Up)") PORT_CODE(KEYCODE_8_PAD ) /* Keypad 8 (Up arrow) 48 C8 */ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 9 (PgUp)") PORT_CODE(KEYCODE_9_PAD ) /* Keypad 9 (PgUp) 49 C9 */ PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) /* Keypad - 4A CA */ PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 4 (Left)") PORT_CODE(KEYCODE_4_PAD ) /* Keypad 4 (Left arrow) 4B CB */ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) /* Keypad 5 4C CC */ PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 6 (Right)") PORT_CODE(KEYCODE_6_PAD ) /* Keypad 6 (Right arrow) 4D CD */ PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP +") PORT_CODE(KEYCODE_PLUS_PAD) /* Keypad + 4E CE */ PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 1 (End)") PORT_CODE(KEYCODE_1_PAD ) /* Keypad 1 (End) 4F CF */ PORT_START("pc_keyboard_5") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 2 (Down)") PORT_CODE(KEYCODE_2_PAD ) /* Keypad 2 (Down arrow) 50 D0 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 3 (PgDn)") PORT_CODE(KEYCODE_3_PAD ) /* Keypad 3 (PgDn) 51 D1 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 0 (Ins)") PORT_CODE(KEYCODE_0_PAD ) /* Keypad 0 (Ins) 52 D2 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP . (Del)") PORT_CODE(KEYCODE_DEL_PAD ) /* Keypad . (Del) 53 D3 */ PORT_BIT ( 0x0030, 0x0000, IPT_UNUSED ) PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(84/102)\\") PORT_CODE(KEYCODE_BACKSLASH2) /* Backslash 2 56 D6 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)F11") PORT_CODE(KEYCODE_F11) /* F11 57 D7 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)F12") PORT_CODE(KEYCODE_F12) /* F12 58 D8 */ PORT_BIT ( 0xfe00, 0x0000, IPT_UNUSED ) PORT_START("pc_keyboard_6") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)KP Enter") PORT_CODE(KEYCODE_ENTER_PAD) /* PAD Enter 60 e0 */ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Right Control") PORT_CODE(KEYCODE_RCONTROL) /* Right Control 61 e1 */ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)KP /") PORT_CODE(KEYCODE_SLASH_PAD) /* PAD Slash 62 e2 */ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)PRTSCR") PORT_CODE(KEYCODE_PRTSCR) /* Print Screen 63 e3 */ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)ALTGR") PORT_CODE(KEYCODE_RALT) /* ALTGR 64 e4 */ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Home") PORT_CODE(KEYCODE_HOME) /* Home 66 e6 */ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Cursor Up") PORT_CODE(KEYCODE_UP) /* Up 67 e7 */ PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Page Up") PORT_CODE(KEYCODE_PGUP) /* Page Up 68 e8 */ PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Cursor Left") PORT_CODE(KEYCODE_LEFT) /* Left 69 e9 */ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Cursor Right") PORT_CODE(KEYCODE_RIGHT) /* Right 6a ea */ PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)End") PORT_CODE(KEYCODE_END) /* End 6b eb */ PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Cursor Down") PORT_CODE(KEYCODE_DOWN) /* Down 6c ec */ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Page Down") PORT_CODE(KEYCODE_PGDN) /* Page Down 6d ed */ PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Insert") PORT_CODE(KEYCODE_INSERT) /* Insert 6e ee */ PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Delete") PORT_CODE(KEYCODE_DEL) /* Delete 6f ef */ PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(MF2)Pause") PORT_CODE(KEYCODE_PAUSE) /* Pause 65 e5 */ PORT_START("pc_keyboard_7") PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Print Screen") PORT_CODE(KEYCODE_PRTSCR) /* Print Screen alternate 77 f7 */ PORT_BIT ( 0xfffe, 0x0000, IPT_UNUSED ) INPUT_PORTS_END /*************************************************************************** Inputx stuff ***************************************************************************/ bool pc_keyboard_device::accept_char(char32_t ch) { return unicode_char_to_at_keycode(ch) != 0; } bool pc_keyboard_device::charqueue_empty() { return queue_size() == 0; }