More keyboard controller improvements - fixes IBM AT boot, CTRL and ALT getting stuck on pressing CTRL+ALT+ESC on Acer BIOS'es, Norton Commander behaving strangely after pressing ALT+Print Screen, and also moved PS/2 mouse command responses to their own queue to simulate the fact that on real hardware, PS/2 mouse commands, like keyboard commands, bypass the FIFO.

This commit is contained in:
OBattler
2023-04-02 04:17:33 +02:00
parent 21d31bb839
commit aab8eb809d
3 changed files with 504 additions and 522 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -82,7 +82,7 @@ mouse_clear_data(void *priv)
} }
static void static void
ps2_report_coordinates(mouse_t *dev) ps2_report_coordinates(mouse_t *dev, int cmd)
{ {
uint8_t buff[3] = { 0x08, 0x00, 0x00 }; uint8_t buff[3] = { 0x08, 0x00, 0x00 };
@@ -114,9 +114,15 @@ ps2_report_coordinates(mouse_t *dev)
buff[1] = (dev->x & 0xff); buff[1] = (dev->x & 0xff);
buff[2] = (dev->y & 0xff); buff[2] = (dev->y & 0xff);
keyboard_at_adddata_mouse(buff[0]); if (cmd) {
keyboard_at_adddata_mouse(buff[1]); keyboard_at_adddata_mouse_cmd(buff[0]);
keyboard_at_adddata_mouse(buff[2]); keyboard_at_adddata_mouse_cmd(buff[1]);
keyboard_at_adddata_mouse_cmd(buff[2]);
} else {
keyboard_at_adddata_mouse(buff[0]);
keyboard_at_adddata_mouse(buff[1]);
keyboard_at_adddata_mouse(buff[2]);
}
if (dev->flags & FLAG_INTMODE) { if (dev->flags & FLAG_INTMODE) {
int temp_z = dev->z; int temp_z = dev->z;
if ((dev->flags & FLAG_5BTN)) { if ((dev->flags & FLAG_5BTN)) {
@@ -126,7 +132,10 @@ ps2_report_coordinates(mouse_t *dev)
if (mouse_buttons & 16) if (mouse_buttons & 16)
temp_z |= 0x20; temp_z |= 0x20;
} }
keyboard_at_adddata_mouse(temp_z); if (cmd)
keyboard_at_adddata_mouse_cmd(temp_z);
else
keyboard_at_adddata_mouse(temp_z);
} }
dev->x = dev->y = dev->z = 0; dev->x = dev->y = dev->z = 0;
@@ -147,16 +156,16 @@ ps2_write(uint8_t val, void *priv)
switch (dev->command) { switch (dev->command) {
case 0xe8: /* set mouse resolution */ case 0xe8: /* set mouse resolution */
dev->resolution = val; dev->resolution = val;
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
break; break;
case 0xf3: /* set sample rate */ case 0xf3: /* set sample rate */
dev->sample_rate = val; dev->sample_rate = val;
keyboard_at_adddata_mouse(0xfa); /* Command response */ keyboard_at_adddata_mouse_cmd(0xfa); /* Command response */
break; break;
default: default:
keyboard_at_adddata_mouse(0xfc); keyboard_at_adddata_mouse_cmd(0xfc);
} }
} else { } else {
dev->command = val; dev->command = val;
@@ -164,21 +173,21 @@ ps2_write(uint8_t val, void *priv)
switch (dev->command) { switch (dev->command) {
case 0xe6: /* set scaling to 1:1 */ case 0xe6: /* set scaling to 1:1 */
dev->flags &= ~FLAG_SCALED; dev->flags &= ~FLAG_SCALED;
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
break; break;
case 0xe7: /* set scaling to 2:1 */ case 0xe7: /* set scaling to 2:1 */
dev->flags |= FLAG_SCALED; dev->flags |= FLAG_SCALED;
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
break; break;
case 0xe8: /* set mouse resolution */ case 0xe8: /* set mouse resolution */
dev->flags |= FLAG_CTRLDAT; dev->flags |= FLAG_CTRLDAT;
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
break; break;
case 0xe9: /* status request */ case 0xe9: /* status request */
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
temp = (dev->flags & 0x30); temp = (dev->flags & 0x30);
if (mouse_buttons & 1) if (mouse_buttons & 1)
temp |= 4; temp |= 4;
@@ -186,46 +195,46 @@ ps2_write(uint8_t val, void *priv)
temp |= 1; temp |= 1;
if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI)) if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI))
temp |= 2; temp |= 2;
keyboard_at_adddata_mouse(temp); keyboard_at_adddata_mouse_cmd(temp);
keyboard_at_adddata_mouse(dev->resolution); keyboard_at_adddata_mouse_cmd(dev->resolution);
keyboard_at_adddata_mouse(dev->sample_rate); keyboard_at_adddata_mouse_cmd(dev->sample_rate);
break; break;
case 0xea: /* set stream */ case 0xea: /* set stream */
dev->flags &= ~FLAG_CTRLDAT; dev->flags &= ~FLAG_CTRLDAT;
mouse_scan = 1; mouse_scan = 1;
keyboard_at_adddata_mouse(0xfa); /* ACK for command byte */ keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */
break; break;
case 0xeb: /* Get mouse data */ case 0xeb: /* Get mouse data */
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
ps2_report_coordinates(dev); ps2_report_coordinates(dev, 1);
break; break;
case 0xf2: /* read ID */ case 0xf2: /* read ID */
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
if (dev->flags & FLAG_INTMODE) if (dev->flags & FLAG_INTMODE)
keyboard_at_adddata_mouse((dev->flags & FLAG_5BTN) ? 0x04 : 0x03); keyboard_at_adddata_mouse_cmd((dev->flags & FLAG_5BTN) ? 0x04 : 0x03);
else else
keyboard_at_adddata_mouse(0x00); keyboard_at_adddata_mouse_cmd(0x00);
break; break;
case 0xf3: /* set command mode */ case 0xf3: /* set command mode */
dev->flags |= FLAG_CTRLDAT; dev->flags |= FLAG_CTRLDAT;
keyboard_at_adddata_mouse(0xfa); /* ACK for command byte */ keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */
break; break;
case 0xf4: /* enable */ case 0xf4: /* enable */
dev->flags |= FLAG_ENABLED; dev->flags |= FLAG_ENABLED;
mouse_scan = 1; mouse_scan = 1;
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
break; break;
case 0xf5: /* disable */ case 0xf5: /* disable */
dev->flags &= ~FLAG_ENABLED; dev->flags &= ~FLAG_ENABLED;
mouse_scan = 0; mouse_scan = 0;
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
break; break;
case 0xf6: /* set defaults */ case 0xf6: /* set defaults */
@@ -235,15 +244,15 @@ mouse_reset:
dev->flags &= 0x88; dev->flags &= 0x88;
mouse_scan = 1; mouse_scan = 1;
keyboard_at_mouse_reset(); keyboard_at_mouse_reset();
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse_cmd(0xfa);
if (dev->command == 0xff) { if (dev->command == 0xff) {
keyboard_at_adddata_mouse(0xaa); keyboard_at_adddata_mouse_cmd(0xaa);
keyboard_at_adddata_mouse(0x00); keyboard_at_adddata_mouse_cmd(0x00);
} }
break; break;
default: default:
keyboard_at_adddata_mouse(0xfe); keyboard_at_adddata_mouse_cmd(0xfe);
} }
} }
@@ -288,7 +297,7 @@ ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
if ((dev->mode == MODE_STREAM) && (dev->flags & FLAG_ENABLED) && (keyboard_at_mouse_pos() < 13)) { if ((dev->mode == MODE_STREAM) && (dev->flags & FLAG_ENABLED) && (keyboard_at_mouse_pos() < 13)) {
dev->b = b; dev->b = b;
ps2_report_coordinates(dev); ps2_report_coordinates(dev, 0);
} }
return (0); return (0);

View File

@@ -139,6 +139,7 @@ extern uint8_t keyboard_set3_flags[512];
extern uint8_t keyboard_set3_all_repeat; extern uint8_t keyboard_set3_all_repeat;
extern uint8_t keyboard_set3_all_break; extern uint8_t keyboard_set3_all_break;
extern int mouse_queue_start, mouse_queue_end; extern int mouse_queue_start, mouse_queue_end;
extern int mouse_cmd_queue_start, mouse_cmd_queue_end;
extern int mouse_scan; extern int mouse_scan;
#ifdef EMU_DEVICE_H #ifdef EMU_DEVICE_H