Reverted the AT keyboard code queues to before I created that mess, and fixed the DEL scan code sent on CTRL+ALT+DEL.
This commit is contained in:
@@ -675,7 +675,7 @@ pc_send_ca(uint16_t sc)
|
||||
void
|
||||
pc_send_cad(void)
|
||||
{
|
||||
pc_send_ca(0xE053);
|
||||
pc_send_ca(0x153);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -103,7 +103,8 @@ typedef struct {
|
||||
uint8_t mem[0x100];
|
||||
|
||||
int last_irq, old_last_irq,
|
||||
reset_delay;
|
||||
reset_delay,
|
||||
out_new, out_delayed;
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
@@ -125,10 +126,13 @@ uint8_t keyboard_set3_all_break;
|
||||
uint8_t keyboard_mode = 0x42;
|
||||
|
||||
|
||||
static uint8_t kbc_queue_pos, channel_queue_pos[3];
|
||||
static uint16_t kbc_queue[48];
|
||||
static uint8_t key_ctrl_queue[16];
|
||||
static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0;
|
||||
static uint8_t key_queue[16];
|
||||
static int key_queue_start = 0, key_queue_end = 0;
|
||||
uint8_t mouse_queue[16];
|
||||
int mouse_queue_start = 0, mouse_queue_end = 0;
|
||||
static uint8_t kbd_last_scan_code;
|
||||
static uint8_t channel_queue[3][16];
|
||||
static void (*mouse_write)(uint8_t val, void *priv) = NULL;
|
||||
static void *mouse_p = NULL;
|
||||
static uint8_t sc_or = 0;
|
||||
@@ -617,88 +621,65 @@ set_scancode_map(atkbd_t *dev)
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
kbc_queue_reset(uint8_t channel)
|
||||
{
|
||||
channel_queue_pos[channel] = 0;
|
||||
memset(channel_queue[channel], 0x00, 16);
|
||||
if (channel == 2) {
|
||||
mouse_queue_start = mouse_queue_end = 0;
|
||||
memset(mouse_queue, 0x00, sizeof(mouse_queue));
|
||||
} else if (channel == 1) {
|
||||
key_queue_start = key_queue_end = 0;
|
||||
memset(key_queue, 0x00, sizeof(key_queue));
|
||||
} else {
|
||||
key_ctrl_queue_start = key_ctrl_queue_end = 0;
|
||||
memset(key_ctrl_queue, 0x00, sizeof(key_ctrl_queue));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
kbc_queue_add(uint8_t val, uint8_t channel)
|
||||
{
|
||||
if ((channel > 0x03) || (kbc_queue_pos >= 48))
|
||||
return;
|
||||
kbd_log("ATkbc: kbc_queue[%02X] = %04X;\n", kbc_queue_pos, val | (channel << 8));
|
||||
kbc_queue[kbc_queue_pos] = val | (channel << 8);
|
||||
kbc_queue_pos++;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
channel_queue_get(uint8_t channel)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (channel_queue_pos[channel] != 0) {
|
||||
ret = channel_queue[channel][0];
|
||||
kbd_log("ATkbc: channel_queue_get(%i): ret = %02X;\n", (uint32_t) channel, (uint32_t) channel_queue[channel][0]);
|
||||
for (i = 0; i < 15; i++)
|
||||
channel_queue[channel][i] = channel_queue[channel][i + 1];
|
||||
channel_queue_pos[channel]--;
|
||||
} else
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
if (channel == 2) {
|
||||
kbd_log("ATkbc: mouse_queue[%02X] = %02X;\n", mouse_queue_end, val);
|
||||
mouse_queue[mouse_queue_end] = val;
|
||||
mouse_queue_end = (mouse_queue_end + 1) & 0xf;
|
||||
} else if (channel == 1) {
|
||||
kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val);
|
||||
key_queue[key_queue_end] = val;
|
||||
key_queue_end = (key_queue_end + 1) & 0xf;
|
||||
} else {
|
||||
kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val);
|
||||
key_ctrl_queue[key_ctrl_queue_end] = val;
|
||||
key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_to_kbc_queue_front(atkbd_t *dev, uint8_t val)
|
||||
{
|
||||
kbd_log("ATkbc: Adding %02X to front...\n", val);
|
||||
dev->wantirq = 0;
|
||||
picint(0x0000);
|
||||
if (dev->mem[0] & 0x01)
|
||||
picint(2);
|
||||
dev->out = val;
|
||||
dev->status |= STAT_OFULL;
|
||||
dev->status &= ~STAT_IFULL;
|
||||
dev->status &= ~STAT_MFULL;
|
||||
dev->status = (dev->status & ~(STAT_IFULL | STAT_MFULL)) | STAT_OFULL;
|
||||
dev->last_irq = 0x0000;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
channel_queue_check(atkbd_t *dev, uint8_t channel)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (channel >= 0x03)
|
||||
return 0;
|
||||
|
||||
if ((channel == 0x01) && (dev->mem[0] & 0x10))
|
||||
return 0;
|
||||
if ((channel == 0x02) && (((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_NOREF) || (dev->mem[0] & 0x20)))
|
||||
return 0;
|
||||
|
||||
val = channel_queue_get(channel);
|
||||
if (val == -1)
|
||||
return 0;
|
||||
kbc_queue_add(val & 0xff, channel);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_data_kbd_queue(atkbd_t *dev, int direct, uint8_t val)
|
||||
{
|
||||
if ((!keyboard_scan && !direct) || (dev->reset_delay > 0) || (channel_queue_pos[1] >= 16)) {
|
||||
kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !keyboard_scan, (dev->reset_delay > 0), (channel_queue_pos[1] >= 16));
|
||||
if ((!keyboard_scan && !direct) || (dev->reset_delay > 0) || (key_queue_end >= 16)) {
|
||||
kbd_log("ATkbc: Unable to add to queue, conditions: %i, %i, %i\n", !keyboard_scan, (dev->reset_delay > 0), (key_queue_end >= 16));
|
||||
return;
|
||||
}
|
||||
kbd_log("ATkbc: channel_queue[1][channel_queue_pos[1]] = %02X;\n", (uint32_t) val);
|
||||
channel_queue[1][channel_queue_pos[1]] = val;
|
||||
channel_queue_pos[1]++;
|
||||
kbd_log("ATkbc: key_queue[%02X] = %02X;\n", key_queue_end, val);
|
||||
key_queue[key_queue_end] = val;
|
||||
key_queue_end = (key_queue_end + 1) & 0xf;
|
||||
kbd_last_scan_code = val;
|
||||
}
|
||||
|
||||
@@ -723,7 +704,6 @@ add_data_kbd_direct(atkbd_t *dev, uint8_t val)
|
||||
send = val;
|
||||
|
||||
add_data_kbd_queue(dev, 1, send);
|
||||
channel_queue_check(dev, 0x01);
|
||||
}
|
||||
|
||||
|
||||
@@ -731,7 +711,6 @@ static void
|
||||
add_data_kbd_raw(atkbd_t *dev, uint8_t val)
|
||||
{
|
||||
add_data_kbd_queue(dev, 1, val);
|
||||
channel_queue_check(dev, 0x01);
|
||||
}
|
||||
|
||||
|
||||
@@ -739,45 +718,57 @@ static void
|
||||
kbd_poll(void *priv)
|
||||
{
|
||||
atkbd_t *dev = (atkbd_t *)priv;
|
||||
uint16_t irq_table[4] = { 0x0002, 0x0002, 0x1000, 0xffff };
|
||||
int i, channel;
|
||||
uint16_t val, irq;
|
||||
#ifdef ENABLE_KEYBOARD_AT_LOG
|
||||
const uint8_t channels[4] = { 1, 2, 0, 0 };
|
||||
#endif
|
||||
|
||||
timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC));
|
||||
|
||||
kbd_log("ATkbc: dev->last_irq = %04X, kbc_queue_pos = %i\n", (uint32_t) dev->last_irq, (uint32_t) kbc_queue_pos);
|
||||
if ((dev->last_irq == 0xffff) && (kbc_queue_pos > 0)) {
|
||||
val = kbc_queue[0];
|
||||
kbd_log("ATkbc: Word from queue: %04X\n", (uint32_t) val);
|
||||
channel = (val >> 8) & 0x03;
|
||||
for (i = 0; i < 47; i++)
|
||||
kbc_queue[i] = kbc_queue[i + 1];
|
||||
kbc_queue_pos = (kbc_queue_pos - 1) & 0xff;
|
||||
irq = irq_table[channel];
|
||||
if (channel < 0x03) {
|
||||
dev->wantirq = 0;
|
||||
if ((channel == 0) || (dev->mem[0] & channel))
|
||||
picint(irq);
|
||||
dev->out = val & 0xff;
|
||||
dev->status |= STAT_OFULL;
|
||||
dev->status &= ~STAT_IFULL;
|
||||
if (channel == 0x02)
|
||||
dev->status |= STAT_MFULL;
|
||||
else
|
||||
dev->status &= ~STAT_MFULL;
|
||||
dev->last_irq = irq;
|
||||
if (dev->out_new != -1 && !dev->last_irq) {
|
||||
dev->wantirq = 0;
|
||||
if (dev->out_new & 0x100) {
|
||||
if (dev->mem[0] & 0x02)
|
||||
picint(0x1000);
|
||||
kbd_log("ATkbc: %02X coming from channel 2\n");
|
||||
dev->out = dev->out_new & 0xff;
|
||||
dev->out_new = -1;
|
||||
dev->status = (dev->status & ~STAT_IFULL) | (STAT_OFULL | STAT_MFULL);
|
||||
dev->last_irq = 0x1000;
|
||||
} else {
|
||||
if (dev->mem[0] & 0x01)
|
||||
picint(2);
|
||||
kbd_log("ATkbc: %02X coming from channel %i\n", dev->out_new & 0xff, channels[(dev->out_new >> 8) & 0x03]);
|
||||
dev->out = dev->out_new & 0xff;
|
||||
dev->out_new = -1;
|
||||
dev->status = (dev->status & ~(STAT_IFULL | STAT_MFULL)) | STAT_OFULL;
|
||||
dev->last_irq = 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0x00; i < 0x03; i++) {
|
||||
if (channel_queue_check(dev, i))
|
||||
break;
|
||||
if (dev->out_new == -1 && !(dev->status & STAT_OFULL) && key_ctrl_queue_start != key_ctrl_queue_end) {
|
||||
kbd_log("ATkbc: %02X on channel 0\n", key_ctrl_queue[key_ctrl_queue_start]);
|
||||
dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200;
|
||||
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf;
|
||||
} else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && dev->out_delayed != -1) {
|
||||
kbd_log("ATkbc: %02X delayed on channel %i\n", dev->out_delayed & 0xff, channels[(dev->out_delayed >> 8) & 0x03]);
|
||||
dev->out_new = dev->out_delayed;
|
||||
dev->out_delayed = -1;
|
||||
} else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && mouse_queue_start != mouse_queue_end) {
|
||||
kbd_log("ATkbc: %02X on channel 2\n", mouse_queue[mouse_queue_start]);
|
||||
dev->out_new = mouse_queue[mouse_queue_start] | 0x100;
|
||||
mouse_queue_start = (mouse_queue_start + 1) & 0xf;
|
||||
} else if (!(dev->status & STAT_OFULL) && dev->out_new == -1 && !(dev->mem[0] & 0x10) && key_queue_start != key_queue_end) {
|
||||
kbd_log("ATkbc: %02X on channel 1\n", key_queue[key_queue_start]);
|
||||
dev->out_new = key_queue[key_queue_start];
|
||||
key_queue_start = (key_queue_start + 1) & 0xf;
|
||||
}
|
||||
|
||||
if (dev->reset_delay > 0) {
|
||||
if (dev->reset_delay) {
|
||||
dev->reset_delay--;
|
||||
if (dev->reset_delay == 0)
|
||||
if (!dev->reset_delay) {
|
||||
kbd_log("ATkbc: Sending AA on keyboard reset...\n");
|
||||
add_data_kbd_direct(dev, 0xaa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,10 +778,13 @@ add_data(atkbd_t *dev, uint8_t val)
|
||||
{
|
||||
kbd_log("ATkbc: add to queue\n");
|
||||
|
||||
if (channel_queue_pos[0] < 16) {
|
||||
kbd_log("ATkbc: channel_queue[0][channel_queue_pos[0]] = %02X;\n", (uint32_t) val);
|
||||
channel_queue[0][channel_queue_pos[0]] = val;
|
||||
channel_queue_pos[0]++;
|
||||
kbd_log("ATkbc: key_ctrl_queue[%02X] = %02X;\n", key_ctrl_queue_end, val);
|
||||
key_ctrl_queue[key_ctrl_queue_end] = val;
|
||||
key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf;
|
||||
|
||||
if (!(dev->out_new & 0x300)) {
|
||||
dev->out_delayed = dev->out_new;
|
||||
dev->out_new = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1112,6 +1106,7 @@ pulse_output(atkbd_t *dev, uint8_t mask)
|
||||
{
|
||||
if (mask != 0x0f) {
|
||||
dev->old_output_port = dev->output_port & ~(0xf0 | mask);
|
||||
kbd_log("pulse_output(): Output port now: %02X\n", dev->output_port & (0xf0 | mask));
|
||||
write_output(dev, dev->output_port & (0xf0 | mask));
|
||||
timer_set_delay_u64(&dev->pulse_cb, 6ULL * TIMER_USEC);
|
||||
}
|
||||
@@ -1123,6 +1118,7 @@ pulse_poll(void *priv)
|
||||
{
|
||||
atkbd_t *dev = (atkbd_t *)priv;
|
||||
|
||||
kbd_log("pulse_poll(): Output port now: %02X\n", dev->output_port | dev->old_output_port);
|
||||
write_output(dev, dev->output_port | dev->old_output_port);
|
||||
}
|
||||
|
||||
@@ -1876,7 +1872,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
case 0xf6: /* set defaults */
|
||||
kbd_log("ATkbd: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard");
|
||||
keyboard_scan = (val == 0xf6);
|
||||
kbc_queue_reset(1);
|
||||
kbd_log("val = %02X, keyboard_scan = %i, dev->mem[0] = %02X\n",
|
||||
val, keyboard_scan, dev->mem[0]);
|
||||
add_data_kbd_direct(dev, 0xfa);
|
||||
@@ -1994,13 +1989,12 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
if (! dev->initialized) {
|
||||
kbd_log("ATkbc: self-test reinitialization\n");
|
||||
dev->initialized = 1;
|
||||
memset(kbc_queue, 0x00, 48 * sizeof(uint16_t));
|
||||
kbc_queue_pos = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
dev->out_new = dev->out_delayed = -1;
|
||||
for (i = 0; i < 3; i++)
|
||||
kbc_queue_reset(i);
|
||||
kbd_last_scan_code = 0x00;
|
||||
dev->status &= ~STAT_OFULL;
|
||||
dev->last_irq = 0xffff;
|
||||
dev->last_irq = dev->old_last_irq = 0;
|
||||
}
|
||||
dev->status |= STAT_SYSFLAG;
|
||||
dev->mem[0] |= 0x04;
|
||||
@@ -2115,18 +2109,10 @@ kbd_read(uint16_t port, void *priv)
|
||||
|
||||
switch (port) {
|
||||
case 0x60:
|
||||
ret = dev->out;
|
||||
dev->status &= ~(STAT_OFULL);
|
||||
if ((dev->last_irq == 0x0002) || (dev->last_irq == 0x1000))
|
||||
picintc(dev->last_irq);
|
||||
dev->last_irq = 0xffff;
|
||||
if (dev->old_last_irq != 0xffff) {
|
||||
dev->out = dev->old_out;
|
||||
dev->last_irq = dev->old_last_irq;
|
||||
dev->status = dev->old_status;
|
||||
dev->old_last_irq = 0xffff;
|
||||
picint(dev->last_irq);
|
||||
}
|
||||
ret = dev->out;
|
||||
dev->status &= ~STAT_OFULL;
|
||||
picintc(dev->last_irq);
|
||||
dev->last_irq = 0;
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
@@ -2228,8 +2214,7 @@ kbd_reset(void *priv)
|
||||
dev->mem[0] |= CCB_TRANSLATE;
|
||||
dev->wantirq = 0;
|
||||
write_output(dev, 0xcf);
|
||||
dev->last_irq = 0xffff;
|
||||
dev->old_last_irq = 0xffff;
|
||||
dev->last_irq = dev->old_last_irq = 0;
|
||||
dev->secr_phase = 0;
|
||||
dev->key_wantdata = 0;
|
||||
|
||||
@@ -2248,9 +2233,8 @@ kbd_reset(void *priv)
|
||||
set_enable_mouse(dev, 0);
|
||||
mouse_scan = 0;
|
||||
|
||||
memset(kbc_queue, 0x00, 48 * sizeof(uint16_t));
|
||||
kbc_queue_pos = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
dev->out_new = dev->out_delayed = -1;
|
||||
for (i = 0; i < 3; i++)
|
||||
kbc_queue_reset(i);
|
||||
kbd_last_scan_code = 0;
|
||||
|
||||
@@ -2583,25 +2567,21 @@ keyboard_at_adddata_keyboard_raw(uint8_t val)
|
||||
void
|
||||
keyboard_at_adddata_mouse(uint8_t val)
|
||||
{
|
||||
if (channel_queue_pos[2] >= 16)
|
||||
return;
|
||||
channel_queue[2][channel_queue_pos[2]] = val;
|
||||
channel_queue_pos[2]++;
|
||||
kbc_queue_add(val, 2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
keyboard_at_mouse_reset(void)
|
||||
{
|
||||
channel_queue_pos[2] = 0;
|
||||
memset(channel_queue[2], 0x00, 16);
|
||||
kbc_queue_reset(2);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
keyboard_at_mouse_pos(void)
|
||||
{
|
||||
return channel_queue_pos[2];
|
||||
return ((mouse_queue_end - mouse_queue_start) & 0xf);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user