Improvements for ps2 support

This commit is contained in:
Jeremy Soller 2019-11-10 20:19:23 -07:00
parent d7c15e02ab
commit a1de5983df
No known key found for this signature in database
GPG Key ID: E988B49EE78A7FB1
2 changed files with 65 additions and 10 deletions

View File

@ -14,14 +14,20 @@ void kbc_init(void) {
// System flag
static bool kbc_system = false;
// Enable first port - TODO
static bool kbc_first = false;
// Enable second port - TODO
static bool kbc_second = false;
// Translate from scancode set 2 to scancode set 1
// for basically no good reason
static bool kbc_translate = true;
bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
if (!kbc_first) return true;
if (kbc_translate) {
key = keymap_translate(key);
}
if (!key) return true;
switch (key & 0xFF00) {
case K_E0:
printf(" E0\n");
@ -50,6 +56,9 @@ enum KbcState {
KBC_STATE_SET_LEDS,
KBC_STATE_SCANCODE,
KBC_STATE_WRITE_PORT,
KBC_STATE_FIRST_PORT_OUTPUT,
KBC_STATE_SECOND_PORT_OUTPUT,
KBC_STATE_SECOND_PORT_INPUT,
};
void kbc_event(struct Kbc * kbc) {
@ -70,6 +79,12 @@ void kbc_event(struct Kbc * kbc) {
if (kbc_system) {
config |= (1 << 2);
}
if (!kbc_first) {
config |= (1 << 4);
}
if (!kbc_second) {
config |= (1 << 5);
}
if (kbc_translate) {
config |= (1 << 6);
}
@ -81,9 +96,16 @@ void kbc_event(struct Kbc * kbc) {
break;
case 0xA7:
printf(" disable second port\n");
kbc_second = false;
break;
case 0xA8:
printf(" enable second port\n");
kbc_second = true;
break;
case 0xA9:
printf(" test second port\n");
// TODO: communicate with touchpad?
kbc_keyboard(kbc, 0x00, KBC_TIMEOUT);
break;
case 0xAA:
printf(" test controller\n");
@ -97,14 +119,28 @@ void kbc_event(struct Kbc * kbc) {
break;
case 0xAD:
printf(" disable first port\n");
kbc_first = false;
break;
case 0xAE:
printf(" enable first port\n");
kbc_first = true;
break;
case 0xD1:
printf(" write port byte\n");
state = KBC_STATE_WRITE_PORT;
break;
case 0xD2:
printf(" write first port output\n");
state = KBC_STATE_FIRST_PORT_OUTPUT;
break;
case 0xD3:
printf(" write second port output\n");
state = KBC_STATE_SECOND_PORT_OUTPUT;
break;
case 0xD4:
printf(" write second port input\n");
state = KBC_STATE_SECOND_PORT_INPUT;
break;
}
} else {
printf("kbc data: %02X\n", data);
@ -128,6 +164,14 @@ void kbc_event(struct Kbc * kbc) {
state = KBC_STATE_SCANCODE;
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break;
case 0xF2:
printf(" identify keyboard\n");
if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) {
if (kbc_keyboard(kbc, 0xAB, KBC_TIMEOUT)) {
kbc_keyboard(kbc, 0x83, KBC_TIMEOUT);
}
}
break;
case 0xF4:
printf(" enable scanning\n");
kbscan_enabled = true;
@ -161,16 +205,10 @@ void kbc_event(struct Kbc * kbc) {
} else {
control &= ~(1 << 1);
}
if (data & (1 << 2)) {
kbc_system = true;
} else {
kbc_system = false;
}
if (data & (1 << 6)) {
kbc_translate = true;
} else {
kbc_translate = false;
}
kbc_system = (bool)(data & (1 << 2));
kbc_first = (bool)(!(data & (1 << 4)));
kbc_second = (bool)(!(data & (1 << 5)));
kbc_translate = (bool)(data & (1 << 6));
*kbc->control = control;
break;
case KBC_STATE_SET_LEDS:
@ -192,6 +230,21 @@ void kbc_event(struct Kbc * kbc) {
printf(" write port byte\n");
state = KBC_STATE_NORMAL;
break;
case KBC_STATE_FIRST_PORT_OUTPUT:
printf(" write first port output\n");
state = KBC_STATE_NORMAL;
kbc_keyboard(kbc, data, KBC_TIMEOUT);
break;
case KBC_STATE_SECOND_PORT_OUTPUT:
printf(" write second port output\n");
state = KBC_STATE_NORMAL;
kbc_mouse(kbc, data, KBC_TIMEOUT);
break;
case KBC_STATE_SECOND_PORT_INPUT:
printf(" write second port input\n");
state = KBC_STATE_NORMAL;
// TODO: mouse commands (write to touchpad?)
break;
}
}
}

View File

@ -174,6 +174,8 @@ uint16_t keymap(int output, int input, int layer) {
}
// This is terrible, from http://www.vetra.com/scancodes.html
// TODO: redo by applying transform at lower level as recommended by:
// https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#ss10.3
uint16_t keymap_translate(uint16_t key) {
switch (key) {
// Function keys