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 // System flag
static bool kbc_system = false; 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 // Translate from scancode set 2 to scancode set 1
// for basically no good reason // for basically no good reason
static bool kbc_translate = true; static bool kbc_translate = true;
bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) { bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
if (!kbc_first) return true;
if (kbc_translate) { if (kbc_translate) {
key = keymap_translate(key); key = keymap_translate(key);
} }
if (!key) return true;
switch (key & 0xFF00) { switch (key & 0xFF00) {
case K_E0: case K_E0:
printf(" E0\n"); printf(" E0\n");
@ -50,6 +56,9 @@ enum KbcState {
KBC_STATE_SET_LEDS, KBC_STATE_SET_LEDS,
KBC_STATE_SCANCODE, KBC_STATE_SCANCODE,
KBC_STATE_WRITE_PORT, 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) { void kbc_event(struct Kbc * kbc) {
@ -70,6 +79,12 @@ void kbc_event(struct Kbc * kbc) {
if (kbc_system) { if (kbc_system) {
config |= (1 << 2); config |= (1 << 2);
} }
if (!kbc_first) {
config |= (1 << 4);
}
if (!kbc_second) {
config |= (1 << 5);
}
if (kbc_translate) { if (kbc_translate) {
config |= (1 << 6); config |= (1 << 6);
} }
@ -81,9 +96,16 @@ void kbc_event(struct Kbc * kbc) {
break; break;
case 0xA7: case 0xA7:
printf(" disable second port\n"); printf(" disable second port\n");
kbc_second = false;
break; break;
case 0xA8: case 0xA8:
printf(" enable second port\n"); 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; break;
case 0xAA: case 0xAA:
printf(" test controller\n"); printf(" test controller\n");
@ -97,14 +119,28 @@ void kbc_event(struct Kbc * kbc) {
break; break;
case 0xAD: case 0xAD:
printf(" disable first port\n"); printf(" disable first port\n");
kbc_first = false;
break; break;
case 0xAE: case 0xAE:
printf(" enable first port\n"); printf(" enable first port\n");
kbc_first = true;
break; break;
case 0xD1: case 0xD1:
printf(" write port byte\n"); printf(" write port byte\n");
state = KBC_STATE_WRITE_PORT; state = KBC_STATE_WRITE_PORT;
break; 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 { } else {
printf("kbc data: %02X\n", data); printf("kbc data: %02X\n", data);
@ -128,6 +164,14 @@ void kbc_event(struct Kbc * kbc) {
state = KBC_STATE_SCANCODE; state = KBC_STATE_SCANCODE;
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break; 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: case 0xF4:
printf(" enable scanning\n"); printf(" enable scanning\n");
kbscan_enabled = true; kbscan_enabled = true;
@ -161,16 +205,10 @@ void kbc_event(struct Kbc * kbc) {
} else { } else {
control &= ~(1 << 1); control &= ~(1 << 1);
} }
if (data & (1 << 2)) { kbc_system = (bool)(data & (1 << 2));
kbc_system = true; kbc_first = (bool)(!(data & (1 << 4)));
} else { kbc_second = (bool)(!(data & (1 << 5)));
kbc_system = false; kbc_translate = (bool)(data & (1 << 6));
}
if (data & (1 << 6)) {
kbc_translate = true;
} else {
kbc_translate = false;
}
*kbc->control = control; *kbc->control = control;
break; break;
case KBC_STATE_SET_LEDS: case KBC_STATE_SET_LEDS:
@ -192,6 +230,21 @@ void kbc_event(struct Kbc * kbc) {
printf(" write port byte\n"); printf(" write port byte\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
break; 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 // 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) { uint16_t keymap_translate(uint16_t key) {
switch (key) { switch (key) {
// Function keys // Function keys