diff --git a/src/device/kbc_xt.c b/src/device/kbc_xt.c index a9fa8bf6c..c1a3aee5c 100644 --- a/src/device/kbc_xt.c +++ b/src/device/kbc_xt.c @@ -85,6 +85,7 @@ typedef struct xtkbd_t { uint8_t type; uint8_t pravetz_flags; uint8_t cpu_speed; + uint8_t ignore; pc_timer_t send_delay_timer; } xtkbd_t; @@ -96,6 +97,8 @@ static int is_tandy = 0; static int is_t1x00 = 0; static int is_amstrad = 0; +#define kbd_adddata kbd_adddata_xt_common + #ifdef ENABLE_KEYBOARD_XT_LOG int keyboard_xt_do_log = ENABLE_KEYBOARD_XT_LOG; @@ -117,7 +120,6 @@ kbd_log(const char *fmt, ...) static uint8_t get_fdd_switch_settings(void) { - uint8_t fdd_count = 0; for (uint8_t i = 0; i < FDD_NUM; i++) { @@ -134,7 +136,6 @@ get_fdd_switch_settings(void) static uint8_t get_videomode_switch_settings(void) { - if (video_is_mda()) return 0x30; else if (video_is_cga()) @@ -172,8 +173,8 @@ kbd_poll(void *priv) } } -static void -kbd_adddata(uint16_t val) +void +kbd_adddata_xt_common(uint16_t val) { /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ if (is_t1x00) { @@ -257,6 +258,98 @@ kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)) } } +void +kbd_adddata_process_10x(uint16_t val, void (*adddata)(uint16_t val)) +{ + uint8_t fake_shift[4] = { 0 }; + uint8_t num_lock = 0; + uint8_t shift_states = 0; + + if (!adddata) + return; + + keyboard_get_states(NULL, &num_lock, NULL, NULL); + shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; + + switch (val) { + case FAKE_LSHIFT_ON: + kbd_log("%s: Fake left shift on, scan code: ", dev->name); + if (num_lock) { + if (shift_states) { + kbd_log("N/A (one or both shifts on)\n"); + break; + } else { + /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ + kbd_log("E0 2A\n"); + fake_shift[0] = 0xe0; + fake_shift[1] = 0x2a; + for (int i = 0; i < 2; i++) + adddata(fake_shift[0]); + } + } else { + if (shift_states & STATE_LSHIFT) { + /* Num lock off and left shift pressed. */ + kbd_log("E0 AA\n"); + fake_shift[0] = 0xe0; + fake_shift[1] = 0xaa; + for (int i = 0; i < 2; i++) + adddata(fake_shift[0]); + } + if (shift_states & STATE_RSHIFT) { + /* Num lock off and right shift pressed. */ + kbd_log("E0 B6\n"); + fake_shift[0] = 0xe0; + fake_shift[1] = 0xb6; + for (int i = 0; i < 2; i++) + adddata(fake_shift[0]); + } + kbd_log(shift_states ? "" : "N/A (both shifts off)\n"); + } + break; + + case FAKE_LSHIFT_OFF: + kbd_log("%s: Fake left shift on, scan code: ", dev->name); + if (num_lock) { + if (shift_states) { + kbd_log("N/A (one or both shifts on)\n"); + break; + } else { + /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ + kbd_log("E0 AA\n"); + fake_shift[0] = 0xe0; + fake_shift[1] = 0xaa; + for (int i = 0; i < 2; i++) + adddata(fake_shift[0]); + } + } else { + if (shift_states & STATE_LSHIFT) { + /* Num lock off and left shift pressed. */ + kbd_log("E0 2A\n"); + fake_shift[0] = 0xe0; + fake_shift[1] = 0x2a; + for (int i = 0; i < 2; i++) + adddata(fake_shift[0]); + break; + } + if (shift_states & STATE_RSHIFT) { + /* Num lock off and right shift pressed. */ + kbd_log("E0 36\n"); + fake_shift[0] = 0xe0; + fake_shift[1] = 0x36; + for (int i = 0; i < 2; i++) + adddata(fake_shift[0]); + break; + } + kbd_log(shift_states ? "" : "N/A (both shifts off)\n"); + } + break; + + default: + adddata(val); + break; + } +} + static void kbd_adddata_ex(uint16_t val) { diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index d6fdaf4b7..fd8d11503 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -5342,6 +5342,46 @@ add_data_vals(atkbc_dev_t *dev, uint8_t *val, uint8_t len) kbc_at_dev_queue_add(dev, val[i], 1); } +static void +add_data_kbd_84(uint16_t val) +{ + atkbc_dev_t *dev = SavedKbd; + uint8_t fake_shift = 0; + uint8_t num_lock = 0; + uint8_t shift_states = 0; + + keyboard_get_states(NULL, &num_lock, NULL, NULL); + shift_states = keyboard_get_shift() & STATE_LSHIFT; + + /* If NumLock is on, invert the left shift state so we can always check for + the the same way flag being set (and with NumLock on that then means it + is actually *NOT* set). */ + if (num_lock) + shift_states ^= STATE_LSHIFT; + + switch (val) { + case FAKE_LSHIFT_ON: + /* If NumLock is on, fake shifts are sent when shift is *NOT* presed, + if NumLock is off, fake shifts are sent when shift is pressed. */ + if (shift_states) { + /* Send fake shift. */ + fake_shift = num_lock ? 0x2a : 0xaa; + add_data_vals(dev, &fake_shift, 1); + } + break; + case FAKE_LSHIFT_OFF: + if (shift_states) { + /* Send fake shift. */ + fake_shift = num_lock ? 0xaa : 0x2a; + add_data_vals(dev, &fake_shift, 1); + } + break; + default: + kbc_at_dev_queue_add(dev, val, 1); + break; + } +} + static void add_data_kbd(uint16_t val) { @@ -5975,7 +6015,10 @@ keyboard_at_init(const device_t *info) bat_counter = 0x0000; } - keyboard_send = add_data_kbd; + if ((dev->type & FLAG_TYPE_MASK) > KBD_84_KEY) + keyboard_send = add_data_kbd; + else + keyboard_send = add_data_kbd_84; SavedKbd = dev; keyboard_update_states(0, 0, 0, 0); diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index 41f8937e5..0ac25b061 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -557,6 +557,18 @@ typedef struct { int type; } kbd_t; +static void +kbd_adddata_xt(uint16_t val) +{ + kbd_adddata_process(val, kbd_adddata_xt_common); +} + +static void +kbd_adddata_xt_10x(uint16_t val) +{ + kbd_adddata_process_10x(val, kbd_adddata_xt_common); +} + static void * kbd_init(const device_t *info) { @@ -564,10 +576,13 @@ kbd_init(const device_t *info) dev->type = device_get_config_int("keys"); - if (dev->type == KBD_83_KEY) + if (dev->type == KBD_83_KEY) { keyboard_set_table(scancode_xt); - else + keyboard_send = kbd_adddata_xt; + } else { keyboard_set_table(scancode_set1); + keyboard_send = kbd_adddata_xt_10x; + } return dev; } diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 78714986c..8b32851bb 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -165,7 +165,9 @@ extern uint16_t scancode_map[768]; extern uint16_t scancode_config_map[768]; extern void (*keyboard_send)(uint16_t val); +extern void kbd_adddata_xt_common(uint16_t val); extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)); +extern void kbd_adddata_process_10x(uint16_t val, void (*adddata)(uint16_t val)); extern const scancode scancode_xt[512]; @@ -211,6 +213,7 @@ extern void keyboard_close(void); extern void keyboard_set_table(const scancode *ptr); extern void keyboard_poll_host(void); extern void keyboard_process(void); +extern void keyboard_process_10x(void); extern uint16_t keyboard_convert(int ch); extern void keyboard_input(int down, uint16_t scan); extern void keyboard_all_up(void);