Add delay to keyboard AT reset response.

A few other keyboard / PS2 mouse fixes.
Based on patch from EluanCM.
This commit is contained in:
SarahW 2020-02-10 20:51:26 +00:00
commit 00f65675af
2 changed files with 23 additions and 3 deletions

View file

@ -26,6 +26,8 @@
#define PS2_REFRESH_TIME (16 * TIMER_USEC) #define PS2_REFRESH_TIME (16 * TIMER_USEC)
#define RESET_DELAY_TIME (100 * 10) /*600ms*/
struct struct
{ {
int initialised; int initialised;
@ -58,6 +60,8 @@ struct
int is_ps2; int is_ps2;
pc_timer_t send_delay_timer; pc_timer_t send_delay_timer;
int reset_delay;
} keyboard_at; } keyboard_at;
/*Translation table taken from https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#ss10.3*/ /*Translation table taken from https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#ss10.3*/
@ -89,6 +93,8 @@ static int key_queue_start = 0, key_queue_end = 0;
static uint8_t mouse_queue[16]; static uint8_t mouse_queue[16];
int mouse_queue_start = 0, mouse_queue_end = 0; int mouse_queue_start = 0, mouse_queue_end = 0;
void keyboard_at_adddata_keyboard(uint8_t val);
void keyboard_at_poll() void keyboard_at_poll()
{ {
timer_advance_u64(&keyboard_at.send_delay_timer, (100 * TIMER_USEC)); timer_advance_u64(&keyboard_at.send_delay_timer, (100 * TIMER_USEC));
@ -152,6 +158,13 @@ void keyboard_at_poll()
keyboard_at.out_new = key_queue[key_queue_start]; keyboard_at.out_new = key_queue[key_queue_start];
key_queue_start = (key_queue_start + 1) & 0xf; key_queue_start = (key_queue_start + 1) & 0xf;
} }
if (keyboard_at.reset_delay)
{
keyboard_at.reset_delay--;
if (!keyboard_at.reset_delay)
keyboard_at_adddata_keyboard(0xaa);
}
} }
void keyboard_at_adddata(uint8_t val) void keyboard_at_adddata(uint8_t val)
@ -168,6 +181,8 @@ void keyboard_at_adddata(uint8_t val)
void keyboard_at_adddata_keyboard(uint8_t val) void keyboard_at_adddata_keyboard(uint8_t val)
{ {
if (keyboard_at.reset_delay)
return;
/* if (val == 0x1c) /* if (val == 0x1c)
{ {
key_1c++; key_1c++;
@ -406,7 +421,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
case 0xff: /*Reset*/ case 0xff: /*Reset*/
key_queue_start = key_queue_end = 0; /*Clear key queue*/ key_queue_start = key_queue_end = 0; /*Clear key queue*/
keyboard_at_adddata_keyboard(0xfa); keyboard_at_adddata_keyboard(0xfa);
keyboard_at_adddata_keyboard(0xaa); keyboard_at.reset_delay = RESET_DELAY_TIME;
break; break;
default: default:
@ -651,7 +666,10 @@ uint8_t keyboard_at_read(uint16_t port, void *priv)
{ {
case 0x60: case 0x60:
temp = keyboard_at.out; temp = keyboard_at.out;
keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/); if (keyboard_at.last_irq == 0x1000)
keyboard_at.status &= ~(STAT_OFULL | STAT_MFULL);
else
keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/);
picintc(keyboard_at.last_irq); picintc(keyboard_at.last_irq);
keyboard_at.last_irq = 0; keyboard_at.last_irq = 0;
break; break;
@ -699,6 +717,7 @@ void keyboard_at_reset()
else else
keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0; keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0;
keyboard_at.out_new = -1; keyboard_at.out_new = -1;
keyboard_at.out_delayed = -1;
keyboard_at.last_irq = 0; keyboard_at.last_irq = 0;
keyboard_at.key_wantdata = 0; keyboard_at.key_wantdata = 0;

View file

@ -123,6 +123,7 @@ void mouse_ps2_write(uint8_t val, void *p)
mouse->mode = MOUSE_STREAM; mouse->mode = MOUSE_STREAM;
mouse->flags = 0; mouse->flags = 0;
mouse->intellimouse_mode = 0; mouse->intellimouse_mode = 0;
mouse_queue_start = mouse_queue_end = 0;
keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse(0xfa);
keyboard_at_adddata_mouse(0xaa); keyboard_at_adddata_mouse(0xaa);
keyboard_at_adddata_mouse(0x00); keyboard_at_adddata_mouse(0x00);