From 194918b86aae69ade917693636d7b8e00878efb9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 16 May 2023 00:20:09 +0200 Subject: [PATCH] Some minor keyboard and keyboard controller fixes and three-phased the keyboard and PS/2 mouse BAT. --- src/device/kbc_at.c | 2 ++ src/device/kbc_at_dev.c | 29 ++++++++++++++++------ src/device/keyboard.c | 8 ++++-- src/device/keyboard_at.c | 4 +++ src/device/mouse_ps2.c | 48 +++++++++++++++++++----------------- src/include/86box/keyboard.h | 8 +++--- 6 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index aed771b9e..08c849c85 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -1449,6 +1449,7 @@ kbc_at_process_cmd(void *priv) /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ dev->p1 = dev->p1 & 0xff; write_p2(dev, 0x4b); + picintc(0x1002); } dev->status = (dev->status & 0x0f) | 0x60; @@ -1467,6 +1468,7 @@ kbc_at_process_cmd(void *priv) /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ dev->p1 = dev->p1 & 0xff; write_p2(dev, 0xcf); + picintc(0x0002); } dev->status = (dev->status & 0x0f) | 0x60; diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index 71a0b4e08..976b9e740 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -75,7 +75,7 @@ kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main) uint8_t ret; if (main) - ret = ((dev->queue_end - dev->queue_start) & 0xf); + ret = ((dev->queue_end - dev->queue_start) & dev->fifo_mask); else ret = ((dev->cmd_queue_end - dev->cmd_queue_start) & 0xf); @@ -88,7 +88,7 @@ kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main) if (main) { kbc_at_dev_log("%s: dev->queue[%02X] = %02X;\n", dev->name, dev->queue_end, val); dev->queue[dev->queue_end] = val; - dev->queue_end = (dev->queue_end + 1) & 0xf; + dev->queue_end = (dev->queue_end + 1) & dev->fifo_mask; } else { kbc_at_dev_log("%s: dev->cmd_queue[%02X] = %02X;\n", dev->name, dev->cmd_queue_end, val); dev->cmd_queue[dev->cmd_queue_end] = val; @@ -121,7 +121,7 @@ kbc_at_dev_poll(void *priv) if (*dev->scan && (dev->port->out_new == -1) && (dev->queue_start != dev->queue_end)) { kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]); dev->port->out_new = dev->queue[dev->queue_start]; - dev->queue_start = (dev->queue_start + 1) & 0xf; + dev->queue_start = (dev->queue_start + 1) & dev->fifo_mask; } if (!(*dev->scan) || dev->port->wantcmd) dev->state = DEV_STATE_MAIN_1; @@ -155,6 +155,20 @@ kbc_at_dev_poll(void *priv) dev->port->wantcmd = 0; } break; + case DEV_STATE_EXECUTE_BAT: + dev->state = DEV_STATE_MAIN_OUT; + dev->execute_bat(dev); + break; + case DEV_STATE_MAIN_WANT_EXECUTE_BAT: + /* Output command response and then return to main loop #2. */ + if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) { + kbc_at_dev_log("%s: %02X (CMD ) on channel 1\n", dev->name, dev->cmd_queue[dev->cmd_queue_start]); + dev->port->out_new = dev->cmd_queue[dev->cmd_queue_start]; + dev->cmd_queue_start = (dev->cmd_queue_start + 1) & 0xf; + } + if (dev->cmd_queue_start == dev->cmd_queue_end) + dev->state = DEV_STATE_EXECUTE_BAT; + break; } } @@ -170,12 +184,11 @@ kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa) *dev->scan = 1; - if (do_fa) + if (do_fa) { kbc_at_dev_queue_add(dev, 0xfa, 0); - - dev->state = DEV_STATE_MAIN_OUT; - - dev->execute_bat(dev); + dev->state = DEV_STATE_MAIN_WANT_EXECUTE_BAT; + } else + dev->state = DEV_STATE_EXECUTE_BAT; } atkbc_dev_t * diff --git a/src/device/keyboard.c b/src/device/keyboard.c index cc6469f9d..9d15db79b 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -90,14 +90,18 @@ key_process(uint16_t scan, int down) scancode *codes = scan_table; int c; + if (!codes) + return; + if (!keyboard_scan || (keyboard_send == NULL)) return; oldkey[scan] = down; - if (down && codes[scan].mk[0] == 0) + + if (down && (codes[scan].mk[0] == 0)) return; - if (!down && codes[scan].brk[0] == 0) + if (!down && (codes[scan].brk[0] == 0)) return; /* TODO: The keyboard controller needs to report the AT flag to us here. */ diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 19a754d7b..6129f206d 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -28,6 +28,8 @@ #define FLAG_AT 0x00 /* dev is AT or PS/2 */ #define FLAG_TYPE_MASK 0x07 /* mask for type */ +#define FIFO_SIZE 16 + enum { KBD_84_KEY = 0, KBD_101_KEY, @@ -960,6 +962,8 @@ keyboard_at_init(const device_t *info) dev->scan = &keyboard_scan; + dev->fifo_mask = FIFO_SIZE - 1; + if (dev->port != NULL) kbc_at_dev_reset(dev, 0); diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 7d9730f28..a1afb8afa 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -30,13 +30,15 @@ enum { MODE_ECHO }; -#define FLAG_EXPLORER 0x200 /* Has 5 buttons */ -#define FLAG_5BTN 0x100 /* using Intellimouse Optical mode */ -#define FLAG_INTELLI 0x80 /* device is IntelliMouse */ -#define FLAG_INTMODE 0x40 /* using Intellimouse mode */ -#define FLAG_SCALED 0x20 /* enable delta scaling */ -#define FLAG_ENABLED 0x10 /* dev is enabled for use */ -#define FLAG_CTRLDAT 0x08 /* ctrl or data mode */ +#define FLAG_EXPLORER 0x200 /* Has 5 buttons */ +#define FLAG_5BTN 0x100 /* using Intellimouse Optical mode */ +#define FLAG_INTELLI 0x80 /* device is IntelliMouse */ +#define FLAG_INTMODE 0x40 /* using Intellimouse mode */ +#define FLAG_SCALED 0x20 /* enable delta scaling */ +#define FLAG_ENABLED 0x10 /* dev is enabled for use */ +#define FLAG_CTRLDAT 0x08 /* ctrl or data mode */ + +#define FIFO_SIZE 16 int mouse_scan = 0; @@ -73,7 +75,7 @@ ps2_report_coordinates(atkbc_dev_t *dev, int main) int temp_z; if (dev->x > 255) { - dev->x = 255; + dev->x = 255; buff[0] |= 0x40; } if (dev->x < -256) { @@ -97,14 +99,7 @@ ps2_report_coordinates(atkbc_dev_t *dev, int main) buff[0] |= 0x10; if (dev->y < 0) buff[0] |= 0x20; - if (mouse_buttons & 0x01) - buff[0] |= 0x01; - if (mouse_buttons & 0x02) - buff[0] |= 0x02; - if (dev->flags & FLAG_INTELLI) { - if (mouse_buttons & 0x04) - buff[0] |= 0x04; - } + buff[0] |= (dev->b & ((dev->flags & FLAG_INTELLI) ? 0x07 : 0x03)); buff[1] = (dev->x & 0xff); buff[2] = (dev->y & 0xff); @@ -317,19 +312,26 @@ static int ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv) { atkbc_dev_t *dev = (atkbc_dev_t *) priv; + int packet_size = (dev->flags & FLAG_INTMODE) ? 4 : 3; if (!mouse_scan || (!x && !y && !z && (b == dev->b))) return (0xff); - dev->x += x; - dev->y -= y; - dev->z -= z; - if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < 13)) { + if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size))) { + dev->x = x; + dev->y = -y; + dev->z = -z; + dev->b = b; + } else { + dev->x += x; + dev->y -= y; + dev->z -= z; dev->b = b; - - ps2_report_coordinates(dev, 1); } + if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size))) + ps2_report_coordinates(dev, 1); + return (0); } @@ -367,6 +369,8 @@ mouse_ps2_init(const device_t *info) dev->scan = &mouse_scan; + dev->fifo_mask = FIFO_SIZE - 1; + if (dev->port != NULL) kbc_at_dev_reset(dev, 0); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index fe642fec1..669d9c6f7 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -33,7 +33,9 @@ enum { DEV_STATE_MAIN_2, DEV_STATE_MAIN_CMD, DEV_STATE_MAIN_WANT_IN, - DEV_STATE_MAIN_IN + DEV_STATE_MAIN_IN, + DEV_STATE_EXECUTE_BAT, + DEV_STATE_MAIN_WANT_EXECUTE_BAT }; /* Used by the AT / PS/2 keyboard controller, common device, keyboard, and mouse. */ @@ -61,9 +63,9 @@ typedef struct { output multiple bytes. */ uint8_t cmd_queue[16]; - uint8_t queue[16]; + uint8_t queue[64]; - int mode, + int fifo_mask, mode, x, y, z, b; int *scan;