Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -316,6 +316,9 @@ then
|
|||||||
pacman -S --needed --noconfirm "$pkg"
|
pacman -S --needed --noconfirm "$pkg"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Clean pacman cache when running under Jenkins to save disk space.
|
||||||
|
[ "$CI" = "true" ] && rm -rf /var/cache/pacman/pkg
|
||||||
|
|
||||||
# Generate a new freetype DLL for this architecture.
|
# Generate a new freetype DLL for this architecture.
|
||||||
rm -f "$freetype_dll"
|
rm -f "$freetype_dll"
|
||||||
|
@@ -93,7 +93,10 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
KBC_STATE_RESET = 0,
|
KBC_STATE_RESET = 0,
|
||||||
KBC_STATE_NORMAL,
|
KBC_STATE_MAIN_IBF,
|
||||||
|
KBC_STATE_MAIN_KBD,
|
||||||
|
KBC_STATE_MAIN_MOUSE,
|
||||||
|
KBC_STATE_MAIN_BOTH,
|
||||||
KBC_STATE_KBC_OUT,
|
KBC_STATE_KBC_OUT,
|
||||||
KBC_STATE_KBC_PARAM,
|
KBC_STATE_KBC_PARAM,
|
||||||
KBC_STATE_KBD,
|
KBC_STATE_KBD,
|
||||||
@@ -102,6 +105,18 @@ enum {
|
|||||||
#define KBC_STATE_SCAN_KBD KBC_STATE_KBD
|
#define KBC_STATE_SCAN_KBD KBC_STATE_KBD
|
||||||
#define KBC_STATE_SCAN_MOUSE KBC_STATE_MOUSE
|
#define KBC_STATE_SCAN_MOUSE KBC_STATE_MOUSE
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DEV_STATE_RESET = 0,
|
||||||
|
DEV_STATE_MAIN_1,
|
||||||
|
DEV_STATE_MAIN_2,
|
||||||
|
DEV_STATE_MAIN_CMD,
|
||||||
|
DEV_STATE_MAIN_OUT,
|
||||||
|
DEV_STATE_MAIN_WANT_IN,
|
||||||
|
DEV_STATE_MAIN_IN,
|
||||||
|
DEV_STATE_MAIN_WANT_RESET,
|
||||||
|
DEV_STATE_RESET_OUT
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t command, status, ib, out,
|
uint8_t command, status, ib, out,
|
||||||
old_out, secr_phase, mem_addr, input_port,
|
old_out, secr_phase, mem_addr, input_port,
|
||||||
@@ -702,7 +717,7 @@ kbc_irq(atkbd_t *dev, uint16_t irq, int raise)
|
|||||||
{
|
{
|
||||||
picint_common(irq, (dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF, raise);
|
picint_common(irq, (dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF, raise);
|
||||||
if (raise)
|
if (raise)
|
||||||
dev->irq_levels |= irq;
|
dev->irq_levels = irq;
|
||||||
else
|
else
|
||||||
dev->irq_levels &= ~irq;
|
dev->irq_levels &= ~irq;
|
||||||
}
|
}
|
||||||
@@ -814,7 +829,7 @@ kbc_ibf_process(atkbd_t *dev)
|
|||||||
{
|
{
|
||||||
/* IBF set, process both commands and data. */
|
/* IBF set, process both commands and data. */
|
||||||
dev->status &= ~STAT_IFULL;
|
dev->status &= ~STAT_IFULL;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
if (dev->status & STAT_CD)
|
if (dev->status & STAT_CD)
|
||||||
kbc_process_cmd(dev);
|
kbc_process_cmd(dev);
|
||||||
else {
|
else {
|
||||||
@@ -836,7 +851,7 @@ kbc_scan_kbd_at(atkbd_t *dev)
|
|||||||
if (dev->out_new != -1) {
|
if (dev->out_new != -1) {
|
||||||
add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00);
|
add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00);
|
||||||
dev->out_new = -1;
|
dev->out_new = -1;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
} else if (dev->status & STAT_IFULL)
|
} else if (dev->status & STAT_IFULL)
|
||||||
kbc_ibf_process(dev);
|
kbc_ibf_process(dev);
|
||||||
/* AT mode. */
|
/* AT mode. */
|
||||||
@@ -858,9 +873,8 @@ kbc_scan_kbd_at(atkbd_t *dev)
|
|||||||
} else
|
} else
|
||||||
add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00);
|
add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00);
|
||||||
dev->out_new = -1;
|
dev->out_new = -1;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
} else if (dev->status & STAT_IFULL)
|
}
|
||||||
kbc_ibf_process(dev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -876,7 +890,9 @@ kbc_poll_at(atkbd_t *dev)
|
|||||||
kbc_process_cmd(dev);
|
kbc_process_cmd(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KBC_STATE_NORMAL:
|
case KBC_STATE_MAIN_IBF:
|
||||||
|
case KBC_STATE_MAIN_MOUSE:
|
||||||
|
case KBC_STATE_SCAN_MOUSE:
|
||||||
if (dev->status & STAT_OFULL) {
|
if (dev->status & STAT_OFULL) {
|
||||||
/* OBF set, wait until it is cleared but still process commands. */
|
/* OBF set, wait until it is cleared but still process commands. */
|
||||||
if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD)) {
|
if ((dev->status & STAT_IFULL) && (dev->status & STAT_CD)) {
|
||||||
@@ -885,23 +901,28 @@ kbc_poll_at(atkbd_t *dev)
|
|||||||
}
|
}
|
||||||
} else if (dev->status & STAT_IFULL)
|
} else if (dev->status & STAT_IFULL)
|
||||||
kbc_ibf_process(dev);
|
kbc_ibf_process(dev);
|
||||||
else
|
else if (!(dev->mem[0x20] & 0x10))
|
||||||
kbc_scan_kbd_at(dev);
|
dev->kbc_state = KBC_STATE_MAIN_KBD;
|
||||||
|
break;
|
||||||
|
case KBC_STATE_MAIN_KBD:
|
||||||
|
case KBC_STATE_MAIN_BOTH:
|
||||||
|
(void) kbc_scan_kbd_at(dev);
|
||||||
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
break;
|
break;
|
||||||
case KBC_STATE_KBC_OUT:
|
case KBC_STATE_KBC_OUT:
|
||||||
/* Keyboard controller command want to output multiple bytes. */
|
/* Keyboard controller command want to output multiple bytes. */
|
||||||
if (dev->status & STAT_IFULL) {
|
if (dev->status & STAT_IFULL) {
|
||||||
/* Data from host aborts dumping. */
|
/* Data from host aborts dumping. */
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
kbc_ibf_process(dev);
|
kbc_ibf_process(dev);
|
||||||
}
|
}
|
||||||
/* Do not continue dumping until OBF is clear. */
|
/* Do not continue dumping until OBF is clear. */
|
||||||
if (!(dev->status & STAT_OFULL)) {
|
if (!(dev->status & STAT_OFULL)) {
|
||||||
kbd_log("ATkbc: %02X coming from channel 0\n", dev->out_new & 0xff);
|
kbd_log("ATkbc: %02X coming from channel 0\n", key_ctrl_queue[key_ctrl_queue_start]);
|
||||||
add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00);
|
add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00);
|
||||||
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f;
|
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f;
|
||||||
if (key_ctrl_queue_start == key_ctrl_queue_end)
|
if (key_ctrl_queue_start == key_ctrl_queue_end)
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KBC_STATE_KBC_PARAM:
|
case KBC_STATE_KBC_PARAM:
|
||||||
@@ -909,7 +930,7 @@ kbc_poll_at(atkbd_t *dev)
|
|||||||
if (dev->status & STAT_IFULL) {
|
if (dev->status & STAT_IFULL) {
|
||||||
/* Command written, abort current command. */
|
/* Command written, abort current command. */
|
||||||
if (dev->status & STAT_CD)
|
if (dev->status & STAT_CD)
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
|
||||||
dev->status &= ~STAT_IFULL;
|
dev->status &= ~STAT_IFULL;
|
||||||
kbc_process_cmd(dev);
|
kbc_process_cmd(dev);
|
||||||
@@ -921,13 +942,23 @@ kbc_poll_at(atkbd_t *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Correct Procedure:
|
||||||
|
1. Controller asks the device (keyboard or mouse) for a byte.
|
||||||
|
2. The device, unless it's in the reset or command states, sees if there's anything to give it,
|
||||||
|
and if yes, begins the transfer.
|
||||||
|
3. The controller checks if there is a transfer, if yes, transfers the byte and sends it to the host,
|
||||||
|
otherwise, checks the next device, or if there is no device left to check, checks if IBF is full
|
||||||
|
and if yes, processes it.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
kbc_scan_kbd_ps2(atkbd_t *dev)
|
kbc_scan_kbd_ps2(atkbd_t *dev)
|
||||||
{
|
{
|
||||||
if (dev->out_new != -1) {
|
if (dev->out_new != -1) {
|
||||||
|
kbd_log("ATkbc: %02X coming from channel 1\n", dev->out_new & 0xff);
|
||||||
add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00);
|
add_to_kbc_queue_front(dev, dev->out_new, 1, 0x00);
|
||||||
dev->out_new = -1;
|
dev->out_new = -1;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,9 +969,10 @@ static int
|
|||||||
kbc_scan_aux_ps2(atkbd_t *dev)
|
kbc_scan_aux_ps2(atkbd_t *dev)
|
||||||
{
|
{
|
||||||
if (dev->out_new_mouse != -1) {
|
if (dev->out_new_mouse != -1) {
|
||||||
|
kbd_log("ATkbc: %02X coming from channel 2\n", dev->out_new_mouse & 0xff);
|
||||||
add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00);
|
add_to_kbc_queue_front(dev, dev->out_new_mouse, 2, 0x00);
|
||||||
dev->out_new_mouse = -1;
|
dev->out_new_mouse = -1;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -952,50 +984,57 @@ kbc_poll_ps2(atkbd_t *dev)
|
|||||||
{
|
{
|
||||||
switch (dev->kbc_state) {
|
switch (dev->kbc_state) {
|
||||||
case KBC_STATE_RESET:
|
case KBC_STATE_RESET:
|
||||||
|
// pclog("KBC_STATE_RESET\n");
|
||||||
if (dev->status & STAT_IFULL) {
|
if (dev->status & STAT_IFULL) {
|
||||||
dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL;
|
dev->status = ((dev->status & 0x0f) | 0x10) & ~STAT_IFULL;
|
||||||
if ((dev->status & STAT_CD) && (dev->ib == 0xaa))
|
if ((dev->status & STAT_CD) && (dev->ib == 0xaa))
|
||||||
kbc_process_cmd(dev);
|
kbc_process_cmd(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KBC_STATE_NORMAL:
|
case KBC_STATE_MAIN_IBF:
|
||||||
|
// pclog("KBC_STATE_MAIN_IBF\n");
|
||||||
if (dev->status & STAT_IFULL)
|
if (dev->status & STAT_IFULL)
|
||||||
kbc_ibf_process(dev);
|
kbc_ibf_process(dev);
|
||||||
else if (!(dev->status & STAT_OFULL)) {
|
else if (!(dev->status & STAT_OFULL)) {
|
||||||
if (dev->mem[0x20] & 0x20) {
|
if (dev->mem[0x20] & 0x20) {
|
||||||
if (!(dev->mem[0x20] & 0x10)) {
|
if (!(dev->mem[0x20] & 0x10)) {
|
||||||
dev->output_port &= 0xbf;
|
dev->output_port &= 0xbf;
|
||||||
|
dev->kbc_state = KBC_STATE_MAIN_KBD;
|
||||||
if (kbc_scan_kbd_ps2(dev) == 0) {
|
|
||||||
if (dev->status & STAT_IFULL)
|
|
||||||
kbc_ibf_process(dev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dev->output_port &= 0xf7;
|
dev->output_port &= 0xf7;
|
||||||
if (dev->mem[0x20] & 0x10) {
|
if (dev->mem[0x20] & 0x10)
|
||||||
if (kbc_scan_aux_ps2(dev) == 0) {
|
dev->kbc_state = KBC_STATE_MAIN_MOUSE;
|
||||||
if (dev->status & STAT_IFULL)
|
else {
|
||||||
kbc_ibf_process(dev);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dev->output_port &= 0xbf;
|
dev->output_port &= 0xbf;
|
||||||
|
dev->kbc_state = KBC_STATE_MAIN_BOTH;
|
||||||
if (kbc_scan_kbd_ps2(dev) == 0) {
|
|
||||||
if (kbc_scan_aux_ps2(dev) == 0) {
|
|
||||||
if (dev->status & STAT_IFULL)
|
|
||||||
kbc_ibf_process(dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KBC_STATE_MAIN_KBD:
|
||||||
|
// pclog("KBC_STATE_MAIN_KBD\n");
|
||||||
|
(void) kbc_scan_kbd_ps2(dev);
|
||||||
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
break;
|
||||||
|
case KBC_STATE_MAIN_MOUSE:
|
||||||
|
// pclog("KBC_STATE_MAIN_MOUSE\n");
|
||||||
|
(void) kbc_scan_aux_ps2(dev);
|
||||||
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
break;
|
||||||
|
case KBC_STATE_MAIN_BOTH:
|
||||||
|
// pclog("KBC_STATE_MAIN_BOTH\n");
|
||||||
|
if (kbc_scan_kbd_ps2(dev))
|
||||||
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
else
|
||||||
|
dev->kbc_state = KBC_STATE_MAIN_MOUSE;
|
||||||
|
break;
|
||||||
case KBC_STATE_KBC_OUT:
|
case KBC_STATE_KBC_OUT:
|
||||||
|
// pclog("KBC_STATE_KBC_OUT\n");
|
||||||
/* Keyboard controller command want to output multiple bytes. */
|
/* Keyboard controller command want to output multiple bytes. */
|
||||||
if (dev->status & STAT_IFULL) {
|
if (dev->status & STAT_IFULL) {
|
||||||
/* Data from host aborts dumping. */
|
/* Data from host aborts dumping. */
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
kbc_ibf_process(dev);
|
kbc_ibf_process(dev);
|
||||||
}
|
}
|
||||||
/* Do not continue dumping until OBF is clear. */
|
/* Do not continue dumping until OBF is clear. */
|
||||||
@@ -1004,29 +1043,104 @@ kbc_poll_ps2(atkbd_t *dev)
|
|||||||
add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00);
|
add_to_kbc_queue_front(dev, key_ctrl_queue[key_ctrl_queue_start], 0, 0x00);
|
||||||
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f;
|
key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0x3f;
|
||||||
if (key_ctrl_queue_start == key_ctrl_queue_end)
|
if (key_ctrl_queue_start == key_ctrl_queue_end)
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KBC_STATE_KBC_PARAM:
|
case KBC_STATE_KBC_PARAM:
|
||||||
|
// pclog("KBC_STATE_KBC_PARAM\n");
|
||||||
/* Keyboard controller command wants data, wait for said data. */
|
/* Keyboard controller command wants data, wait for said data. */
|
||||||
if (dev->status & STAT_IFULL) {
|
if (dev->status & STAT_IFULL) {
|
||||||
/* Command written, abort current command. */
|
/* Command written, abort current command. */
|
||||||
if (dev->status & STAT_CD)
|
if (dev->status & STAT_CD)
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
|
||||||
dev->status &= ~STAT_IFULL;
|
dev->status &= ~STAT_IFULL;
|
||||||
kbc_process_cmd(dev);
|
kbc_process_cmd(dev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KBC_STATE_SCAN_KBD:
|
case KBC_STATE_SCAN_KBD:
|
||||||
|
// pclog("KBC_STATE_SCAN_KBD\n");
|
||||||
(void) kbc_scan_kbd_ps2(dev);
|
(void) kbc_scan_kbd_ps2(dev);
|
||||||
break;
|
break;
|
||||||
case KBC_STATE_SCAN_MOUSE:
|
case KBC_STATE_SCAN_MOUSE:
|
||||||
|
// pclog("KBC_STATE_SCAN_MOUSE\n");
|
||||||
(void) kbc_scan_aux_ps2(dev);
|
(void) kbc_scan_aux_ps2(dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kbc_poll_kbd(atkbd_t *dev)
|
||||||
|
{
|
||||||
|
switch (dev->kbd_state) {
|
||||||
|
case DEV_STATE_RESET:
|
||||||
|
/* Reset state. */
|
||||||
|
if (dev->reset_delay) {
|
||||||
|
dev->reset_delay--;
|
||||||
|
if (!dev->reset_delay) {
|
||||||
|
kbd_log("ATkbc: Sending AA on keyboard reset...\n");
|
||||||
|
add_data_kbd_front(dev, 0xaa);
|
||||||
|
dev->kbd_state = DEV_STATE_RESET_OUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEV_STATE_MAIN_1:
|
||||||
|
/* Process the command if needed and then return to main loop #2. */
|
||||||
|
if (dev->key_wantcmd) {
|
||||||
|
kbd_log("ATkbc: Processing keyboard command...\n");
|
||||||
|
kbd_process_cmd(dev);
|
||||||
|
dev->key_wantcmd = 0;
|
||||||
|
} else
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_2;
|
||||||
|
break;
|
||||||
|
case DEV_STATE_MAIN_2:
|
||||||
|
/* Output from scan queue if needed and then return to main loop #1. */
|
||||||
|
if (keyboard_scan && (key_queue_start != key_queue_end)) {
|
||||||
|
kbd_log("ATkbc: %02X (DATA) 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;
|
||||||
|
}
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_1;
|
||||||
|
break;
|
||||||
|
case DEV_STATE_MAIN_OUT:
|
||||||
|
case DEV_STATE_RESET_OUT:
|
||||||
|
/* Output command resposne and then return to main loop #2. */
|
||||||
|
if (key_cmd_queue_start != key_cmd_queue_end) {
|
||||||
|
kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]);
|
||||||
|
dev->out_new = key_cmd_queue[key_cmd_queue_start];
|
||||||
|
key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf;
|
||||||
|
}
|
||||||
|
dev->kbd_state = (dev->kbd_state == DEV_STATE_RESET_OUT) ? DEV_STATE_MAIN_1 : DEV_STATE_MAIN_2;
|
||||||
|
break;
|
||||||
|
case DEV_STATE_MAIN_WANT_IN:
|
||||||
|
/* Output command response and then wait for host data. */
|
||||||
|
if (key_cmd_queue_start != key_cmd_queue_end) {
|
||||||
|
kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]);
|
||||||
|
dev->out_new = key_cmd_queue[key_cmd_queue_start];
|
||||||
|
key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf;
|
||||||
|
}
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_IN;
|
||||||
|
break;
|
||||||
|
case DEV_STATE_MAIN_IN:
|
||||||
|
/* Wait for host data. */
|
||||||
|
if (dev->key_wantcmd) {
|
||||||
|
kbd_log("ATkbc: Processing keyboard command...\n");
|
||||||
|
kbd_process_cmd(dev);
|
||||||
|
dev->key_wantcmd = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEV_STATE_MAIN_WANT_RESET:
|
||||||
|
/* Output command response and then go to the reset state. */
|
||||||
|
if (key_cmd_queue_start != key_cmd_queue_end) {
|
||||||
|
kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]);
|
||||||
|
dev->out_new = key_cmd_queue[key_cmd_queue_start];
|
||||||
|
key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf;
|
||||||
|
}
|
||||||
|
dev->kbd_state = DEV_STATE_RESET;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: State machines for controller, keyboard, and mouse. */
|
/* TODO: State machines for controller, keyboard, and mouse. */
|
||||||
static void
|
static void
|
||||||
kbd_poll(void *priv)
|
kbd_poll(void *priv)
|
||||||
@@ -1042,31 +1156,7 @@ kbd_poll(void *priv)
|
|||||||
else
|
else
|
||||||
kbc_poll_ps2(dev);
|
kbc_poll_ps2(dev);
|
||||||
|
|
||||||
if (dev->reset_delay) {
|
kbc_poll_kbd(dev);
|
||||||
dev->reset_delay--;
|
|
||||||
if (!dev->reset_delay) {
|
|
||||||
kbd_log("ATkbc: Sending AA on keyboard reset...\n");
|
|
||||||
add_data_kbd_front(dev, 0xaa);
|
|
||||||
}
|
|
||||||
} else if (dev->key_wantcmd) {
|
|
||||||
if ((key_cmd_queue_start == key_cmd_queue_end) && (dev->out_new == -1) && (dev->reset_delay == 0)) {
|
|
||||||
kbd_log("ATkbc: Processing keyboard command...\n");
|
|
||||||
kbd_process_cmd(dev);
|
|
||||||
dev->key_wantcmd = 0;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (dev->out_new == -1) {
|
|
||||||
if (key_cmd_queue_start != key_cmd_queue_end) {
|
|
||||||
kbd_log("ATkbc: %02X (CMD ) on channel 1\n", key_cmd_queue[key_cmd_queue_start]);
|
|
||||||
dev->out_new = key_cmd_queue[key_cmd_queue_start];
|
|
||||||
key_cmd_queue_start = (key_cmd_queue_start + 1) & 0xf;
|
|
||||||
} else if (key_queue_start != key_queue_end) {
|
|
||||||
kbd_log("ATkbc: %02X (DATA) 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->mouse_reset_delay) {
|
if (dev->mouse_reset_delay) {
|
||||||
dev->mouse_reset_delay--;
|
dev->mouse_reset_delay--;
|
||||||
@@ -1082,8 +1172,7 @@ kbd_poll(void *priv)
|
|||||||
// dev->mouse_reset_delay = RESET_DELAY_TIME;
|
// dev->mouse_reset_delay = RESET_DELAY_TIME;
|
||||||
dev->mouse_wantcmd = 0;
|
dev->mouse_wantcmd = 0;
|
||||||
}
|
}
|
||||||
}
|
} else if (dev->out_new_mouse == -1) {
|
||||||
if (dev->out_new_mouse == -1) {
|
|
||||||
if (mouse_cmd_queue_start != mouse_cmd_queue_end) {
|
if (mouse_cmd_queue_start != mouse_cmd_queue_end) {
|
||||||
kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]);
|
kbd_log("ATkbc: %02X (CMD ) on channel 2\n", mouse_cmd_queue[mouse_cmd_queue_start]);
|
||||||
dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start];
|
dev->out_new_mouse = mouse_cmd_queue[mouse_cmd_queue_start];
|
||||||
@@ -2085,6 +2174,11 @@ kbd_key_reset(atkbd_t *dev, int do_fa)
|
|||||||
|
|
||||||
keyboard_scan = 1;
|
keyboard_scan = 1;
|
||||||
dev->reset_delay = RESET_DELAY_TIME;
|
dev->reset_delay = RESET_DELAY_TIME;
|
||||||
|
|
||||||
|
if (do_fa)
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_WANT_RESET;
|
||||||
|
else
|
||||||
|
dev->kbd_state = DEV_STATE_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2095,6 +2189,8 @@ kbd_process_cmd(void *priv)
|
|||||||
/* Write data to keyboard. */
|
/* Write data to keyboard. */
|
||||||
dev->mem[0x20] &= ~0x10;
|
dev->mem[0x20] &= ~0x10;
|
||||||
|
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_OUT;
|
||||||
|
|
||||||
if (dev->key_wantdata) {
|
if (dev->key_wantdata) {
|
||||||
dev->key_wantdata = 0;
|
dev->key_wantdata = 0;
|
||||||
|
|
||||||
@@ -2159,6 +2255,7 @@ kbd_process_cmd(void *priv)
|
|||||||
add_data_kbd_raw(dev, 0xfa);
|
add_data_kbd_raw(dev, 0xfa);
|
||||||
|
|
||||||
dev->key_wantdata = 1;
|
dev->key_wantdata = 1;
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_WANT_IN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xee: /* diagnostic echo */
|
case 0xee: /* diagnostic echo */
|
||||||
@@ -2174,6 +2271,7 @@ kbd_process_cmd(void *priv)
|
|||||||
kbd_log("ATkbd: scan code set\n");
|
kbd_log("ATkbd: scan code set\n");
|
||||||
add_data_kbd_raw(dev, 0xfa);
|
add_data_kbd_raw(dev, 0xfa);
|
||||||
dev->key_wantdata = 1;
|
dev->key_wantdata = 1;
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_WANT_IN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf2: /* read ID */
|
case 0xf2: /* read ID */
|
||||||
@@ -2190,6 +2288,7 @@ kbd_process_cmd(void *priv)
|
|||||||
kbd_log("ATkbd: set typematic rate/delay\n");
|
kbd_log("ATkbd: set typematic rate/delay\n");
|
||||||
add_data_kbd_raw(dev, 0xfa);
|
add_data_kbd_raw(dev, 0xfa);
|
||||||
dev->key_wantdata = 1;
|
dev->key_wantdata = 1;
|
||||||
|
dev->kbd_state = DEV_STATE_MAIN_WANT_IN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf4: /* enable keyboard */
|
case 0xf4: /* enable keyboard */
|
||||||
@@ -2270,7 +2369,7 @@ kbc_process_cmd(void *priv)
|
|||||||
if (dev->status & STAT_CD) {
|
if (dev->status & STAT_CD) {
|
||||||
/* Controller command. */
|
/* Controller command. */
|
||||||
dev->want60 = 0;
|
dev->want60 = 0;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
|
||||||
/* Clear the keyboard controller queue. */
|
/* Clear the keyboard controller queue. */
|
||||||
kbc_queue_reset(0);
|
kbc_queue_reset(0);
|
||||||
@@ -2328,7 +2427,7 @@ kbc_process_cmd(void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
kbc_queue_reset(0);
|
kbc_queue_reset(0);
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
|
||||||
add_to_kbc_queue_front(dev, 0x55, 0, 0x00);
|
add_to_kbc_queue_front(dev, 0x55, 0, 0x00);
|
||||||
break;
|
break;
|
||||||
@@ -2433,7 +2532,7 @@ kbc_process_cmd(void *priv)
|
|||||||
} else if (dev->want60) {
|
} else if (dev->want60) {
|
||||||
/* Write data to controller. */
|
/* Write data to controller. */
|
||||||
dev->want60 = 0;
|
dev->want60 = 0;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
|
|
||||||
switch (dev->command) {
|
switch (dev->command) {
|
||||||
case 0x60 ... 0x7f:
|
case 0x60 ... 0x7f:
|
||||||
@@ -2529,7 +2628,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
write_output(dev, val | 0x01);
|
write_output(dev, val | 0x01);
|
||||||
dev->want60 = 0;
|
dev->want60 = 0;
|
||||||
dev->kbc_state = KBC_STATE_NORMAL;
|
dev->kbc_state = KBC_STATE_MAIN_IBF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2644,7 +2743,7 @@ kbd_reset(void *priv)
|
|||||||
dev->kbc_state = KBC_STATE_RESET;
|
dev->kbc_state = KBC_STATE_RESET;
|
||||||
|
|
||||||
/* Reset the keyboard. */
|
/* Reset the keyboard. */
|
||||||
// kbd_key_reset(dev, 0);
|
kbd_key_reset(dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the AT keyboard - this is needed for the PCI TRC and is done
|
/* Reset the AT keyboard - this is needed for the PCI TRC and is done
|
||||||
|
Reference in New Issue
Block a user