mirror of
https://github.com/86Box/86Box.git
synced 2026-02-25 04:45:31 -07:00
Merge remote-tracking branch 'upstream/master' into feature/ich2
This commit is contained in:
@@ -19,7 +19,9 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h
|
||||
hwm_vt82c686.c ibm_5161.c intel_ich2_gpio.c intel_ich2_trap.c
|
||||
isamem.c isartc.c ../lpt.c pci_bridge.c
|
||||
postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
|
||||
smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c
|
||||
smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c
|
||||
kbc_at.c kbc_at_dev.c
|
||||
keyboard_at.c
|
||||
mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c
|
||||
mouse_wacom_tablet.c serial_passthrough.c tco.c)
|
||||
|
||||
|
||||
2159
src/device/kbc_at.c
Normal file
2159
src/device/kbc_at.c
Normal file
File diff suppressed because it is too large
Load Diff
198
src/device/kbc_at_dev.c
Normal file
198
src/device/kbc_at_dev.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* AT / PS/2 attached device emulation.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/ppi.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/m_at_t3100e.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/snd_speaker.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/keyboard.h>
|
||||
|
||||
#ifdef ENABLE_KBC_AT_DEV_LOG
|
||||
int kbc_at_dev_do_log = ENABLE_KBC_AT_DEV_LOG;
|
||||
|
||||
static void
|
||||
kbc_at_dev_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (kbc_at_dev_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define kbc_at_dev_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
kbc_at_dev_queue_reset(atkbc_dev_t *dev, uint8_t reset_main)
|
||||
{
|
||||
if (reset_main) {
|
||||
dev->queue_start = dev->queue_end = 0;
|
||||
memset(dev->queue, 0x00, sizeof(dev->queue));
|
||||
}
|
||||
|
||||
dev->cmd_queue_start = dev->cmd_queue_end = 0;
|
||||
memset(dev->cmd_queue, 0x00, sizeof(dev->cmd_queue));
|
||||
}
|
||||
|
||||
uint8_t
|
||||
kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
if (main)
|
||||
ret = ((dev->queue_end - dev->queue_start) & 0xf);
|
||||
else
|
||||
ret = ((dev->cmd_queue_end - dev->cmd_queue_start) & 0xf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main)
|
||||
{
|
||||
if (main) {
|
||||
kbc_at_dev_log("%s: dev->queue[%02X] = %02X;\n", dev->name, dev->queue_end, val);
|
||||
dev->queue[dev->queue_end] = val;
|
||||
dev->queue_end = (dev->queue_end + 1) & 0xf;
|
||||
} else {
|
||||
kbc_at_dev_log("%s: dev->cmd_queue[%02X] = %02X;\n", dev->name, dev->cmd_queue_end, val);
|
||||
dev->cmd_queue[dev->cmd_queue_end] = val;
|
||||
dev->cmd_queue_end = (dev->cmd_queue_end + 1) & 0xf;
|
||||
}
|
||||
|
||||
/* TODO: This should be done on actual send to host. */
|
||||
if (val != 0xfe)
|
||||
dev->last_scan_code = val;
|
||||
}
|
||||
|
||||
static void
|
||||
kbc_at_dev_poll(void *priv)
|
||||
{
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
|
||||
switch (dev->state) {
|
||||
case DEV_STATE_MAIN_1:
|
||||
/* Process the command if needed and then return to main loop #2. */
|
||||
if (dev->port->wantcmd) {
|
||||
kbc_at_dev_log("%s: Processing keyboard command %02X...\n", dev->name, dev->port->dat);
|
||||
kbc_at_dev_queue_reset(dev, 0);
|
||||
dev->process_cmd(dev);
|
||||
dev->port->wantcmd = 0;
|
||||
} else
|
||||
dev->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 (*dev->scan && (dev->port->out_new == -1) && (dev->queue_start != dev->queue_end)) {
|
||||
kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]);
|
||||
dev->port->out_new = dev->queue[dev->queue_start];
|
||||
dev->queue_start = (dev->queue_start + 1) & 0xf;
|
||||
}
|
||||
if (!(*dev->scan) || dev->port->wantcmd)
|
||||
dev->state = DEV_STATE_MAIN_1;
|
||||
break;
|
||||
case DEV_STATE_MAIN_OUT:
|
||||
/* If host wants to send command while we're sending a byte to host, process the command. */
|
||||
if (dev->port->wantcmd) {
|
||||
kbc_at_dev_log("%s: Processing keyboard command %02X...\n", dev->name, dev->port->dat);
|
||||
kbc_at_dev_queue_reset(dev, 0);
|
||||
dev->process_cmd(dev);
|
||||
dev->port->wantcmd = 0;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case DEV_STATE_MAIN_WANT_IN:
|
||||
/* Output command response and then return to main loop #2. */
|
||||
if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) {
|
||||
kbc_at_dev_log("%s: %02X (CMD ) on channel 1\n", dev->name, dev->cmd_queue[dev->cmd_queue_start]);
|
||||
dev->port->out_new = dev->cmd_queue[dev->cmd_queue_start];
|
||||
dev->cmd_queue_start = (dev->cmd_queue_start + 1) & 0xf;
|
||||
}
|
||||
if (dev->cmd_queue_start == dev->cmd_queue_end)
|
||||
dev->state++;
|
||||
break;
|
||||
case DEV_STATE_MAIN_IN:
|
||||
/* Wait for host data. */
|
||||
if (dev->port->wantcmd) {
|
||||
kbc_at_dev_log("%s: Processing keyboard command %02X parameter %02X...\n", dev->name, dev->command, dev->port->dat);
|
||||
kbc_at_dev_queue_reset(dev, 0);
|
||||
dev->process_cmd(dev);
|
||||
dev->port->wantcmd = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa)
|
||||
{
|
||||
dev->port->out_new = -1;
|
||||
dev->port->wantcmd = 0;
|
||||
|
||||
kbc_at_dev_queue_reset(dev, 1);
|
||||
|
||||
dev->last_scan_code = 0x00;
|
||||
|
||||
*dev->scan = 1;
|
||||
|
||||
if (do_fa)
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
|
||||
dev->state = DEV_STATE_MAIN_OUT;
|
||||
|
||||
dev->execute_bat(dev);
|
||||
}
|
||||
|
||||
atkbc_dev_t *
|
||||
kbc_at_dev_init(uint8_t inst)
|
||||
{
|
||||
atkbc_dev_t *dev;
|
||||
|
||||
dev = (atkbc_dev_t *) malloc(sizeof(atkbc_dev_t));
|
||||
memset(dev, 0x00, sizeof(atkbc_dev_t));
|
||||
|
||||
dev->port = kbc_at_ports[inst];
|
||||
|
||||
if (dev->port != NULL) {
|
||||
dev->port->priv = dev;
|
||||
dev->port->poll = kbc_at_dev_poll;
|
||||
}
|
||||
|
||||
/* Return our private data to the I/O layer. */
|
||||
return (dev);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -102,6 +102,8 @@ static int mouse_nbut;
|
||||
static int (*mouse_dev_poll)(int x, int y, int z, int b, void *priv);
|
||||
static void (*mouse_poll_ex)(void) = NULL;
|
||||
|
||||
static double sample_rate = 200.0;
|
||||
|
||||
#ifdef ENABLE_MOUSE_LOG
|
||||
int mouse_do_log = ENABLE_MOUSE_LOG;
|
||||
|
||||
@@ -153,7 +155,7 @@ static void
|
||||
mouse_timer_poll(void *priv)
|
||||
{
|
||||
/* Poll at 255 Hz, maximum supported by PS/2 mic. */
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / 255.0);
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
|
||||
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
|
||||
if (gdbstub_step == GDBSTUB_EXEC)
|
||||
@@ -161,6 +163,15 @@ mouse_timer_poll(void *priv)
|
||||
mouse_process();
|
||||
}
|
||||
|
||||
void
|
||||
mouse_set_sample_rate(double new_rate)
|
||||
{
|
||||
timer_stop(&mouse_timer);
|
||||
|
||||
sample_rate = new_rate;
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
}
|
||||
|
||||
void
|
||||
mouse_reset(void)
|
||||
{
|
||||
@@ -179,15 +190,16 @@ mouse_reset(void)
|
||||
if (mouse_type == 0)
|
||||
return;
|
||||
|
||||
timer_add(&mouse_timer, mouse_timer_poll, NULL, 0);
|
||||
|
||||
/* Poll at 100 Hz, the default of a PS/2 mouse. */
|
||||
sample_rate = 100.0;
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
|
||||
mouse_curr = mouse_devices[mouse_type].device;
|
||||
|
||||
if (mouse_curr != NULL)
|
||||
mouse_priv = device_add(mouse_curr);
|
||||
|
||||
timer_add(&mouse_timer, mouse_timer_poll, NULL, 0);
|
||||
|
||||
/* Poll at 255 Hz, maximum supported by PS/2 mic. */
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / 255.0);
|
||||
}
|
||||
|
||||
/* Callback from the hardware driver. */
|
||||
|
||||
@@ -30,22 +30,7 @@ enum {
|
||||
MODE_ECHO
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *name; /* name of this device */
|
||||
int8_t type; /* type of this device */
|
||||
|
||||
int mode;
|
||||
|
||||
uint16_t flags;
|
||||
uint8_t resolution;
|
||||
uint8_t sample_rate;
|
||||
|
||||
uint8_t command;
|
||||
|
||||
int x, y, z, b;
|
||||
|
||||
uint8_t last_data[6];
|
||||
} mouse_t;
|
||||
#define FLAG_EXPLORER 0x200 /* Has 5 buttons */
|
||||
#define FLAG_5BTN 0x100 /* using Intellimouse Optical mode */
|
||||
#define FLAG_INTELLI 0x80 /* device is IntelliMouse */
|
||||
#define FLAG_INTMODE 0x40 /* using Intellimouse mode */
|
||||
@@ -76,13 +61,13 @@ mouse_ps2_log(const char *fmt, ...)
|
||||
void
|
||||
mouse_clear_data(void *priv)
|
||||
{
|
||||
mouse_t *dev = (mouse_t *) priv;
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
}
|
||||
|
||||
static void
|
||||
ps2_report_coordinates(mouse_t *dev, int cmd)
|
||||
ps2_report_coordinates(atkbc_dev_t *dev, int main)
|
||||
{
|
||||
uint8_t buff[3] = { 0x08, 0x00, 0x00 };
|
||||
int temp_z;
|
||||
@@ -123,15 +108,9 @@ ps2_report_coordinates(mouse_t *dev, int cmd)
|
||||
buff[1] = (dev->x & 0xff);
|
||||
buff[2] = (dev->y & 0xff);
|
||||
|
||||
if (cmd) {
|
||||
keyboard_at_adddata_mouse_cmd(buff[0]);
|
||||
keyboard_at_adddata_mouse_cmd(buff[1]);
|
||||
keyboard_at_adddata_mouse_cmd(buff[2]);
|
||||
} else {
|
||||
keyboard_at_adddata_mouse(buff[0]);
|
||||
keyboard_at_adddata_mouse(buff[1]);
|
||||
keyboard_at_adddata_mouse(buff[2]);
|
||||
}
|
||||
kbc_at_dev_queue_add(dev, buff[0], main);
|
||||
kbc_at_dev_queue_add(dev, buff[1], main);
|
||||
kbc_at_dev_queue_add(dev, buff[2], main);
|
||||
if (dev->flags & FLAG_INTMODE) {
|
||||
temp_z = dev->z & 0x0f;
|
||||
if ((dev->flags & FLAG_5BTN)) {
|
||||
@@ -144,144 +123,192 @@ ps2_report_coordinates(mouse_t *dev, int cmd)
|
||||
if (temp_z & 0x08)
|
||||
temp_z |= 0xf0;
|
||||
}
|
||||
if (cmd)
|
||||
keyboard_at_adddata_mouse_cmd(temp_z);
|
||||
else
|
||||
keyboard_at_adddata_mouse(temp_z);
|
||||
kbc_at_dev_queue_add(dev, temp_z, main);
|
||||
}
|
||||
|
||||
dev->x = dev->y = dev->z = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ps2_write(uint8_t val, void *priv)
|
||||
ps2_set_defaults(atkbc_dev_t *dev)
|
||||
{
|
||||
mouse_t *dev = (mouse_t *) priv;
|
||||
uint8_t temp;
|
||||
dev->mode = MODE_STREAM;
|
||||
dev->rate = 100;
|
||||
mouse_set_sample_rate(100.0);
|
||||
dev->resolution = 2;
|
||||
dev->flags &= 0x88;
|
||||
mouse_scan = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ps2_bat(void *priv)
|
||||
{
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
|
||||
ps2_set_defaults(dev);
|
||||
|
||||
kbc_at_dev_queue_add(dev, 0xaa, 0);
|
||||
kbc_at_dev_queue_add(dev, 0x00, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ps2_write(void *priv)
|
||||
{
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
uint8_t temp, val;
|
||||
static uint8_t last_data[6] = { 0x00 };
|
||||
|
||||
if (dev->port == NULL)
|
||||
return;
|
||||
|
||||
val = dev->port->dat;
|
||||
|
||||
dev->state = DEV_STATE_MAIN_OUT;
|
||||
|
||||
if (dev->flags & FLAG_CTRLDAT) {
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
|
||||
if (val == 0xff)
|
||||
goto mouse_reset;
|
||||
|
||||
switch (dev->command) {
|
||||
kbc_at_dev_reset(dev, 1);
|
||||
else switch (dev->command) {
|
||||
case 0xe8: /* set mouse resolution */
|
||||
dev->resolution = val;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
mouse_ps2_log("%s: Set mouse resolution [%02X]\n", dev->name, val);
|
||||
break;
|
||||
|
||||
case 0xf3: /* set sample rate */
|
||||
dev->sample_rate = val;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa); /* Command response */
|
||||
dev->rate = val;
|
||||
mouse_set_sample_rate((double) val);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0); /* Command response */
|
||||
mouse_ps2_log("%s: Set sample rate [%02X]\n", dev->name, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
keyboard_at_adddata_mouse_cmd(0xfc);
|
||||
kbc_at_dev_queue_add(dev, 0xfc, 0);
|
||||
}
|
||||
} else {
|
||||
dev->command = val;
|
||||
|
||||
switch (dev->command) {
|
||||
case 0xe6: /* set scaling to 1:1 */
|
||||
mouse_ps2_log("%s: Set scaling to 1:1\n", dev->name);
|
||||
dev->flags &= ~FLAG_SCALED;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
break;
|
||||
|
||||
case 0xe7: /* set scaling to 2:1 */
|
||||
mouse_ps2_log("%s: Set scaling to 2:1\n", dev->name);
|
||||
dev->flags |= FLAG_SCALED;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
break;
|
||||
|
||||
case 0xe8: /* set mouse resolution */
|
||||
mouse_ps2_log("%s: Set mouse resolution\n", dev->name);
|
||||
dev->flags |= FLAG_CTRLDAT;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
dev->state = DEV_STATE_MAIN_WANT_IN;
|
||||
break;
|
||||
|
||||
case 0xe9: /* status request */
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
temp = (dev->flags & 0x30);
|
||||
mouse_ps2_log("%s: Status request\n", dev->name);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
temp = (dev->flags & 0x20);
|
||||
if (mouse_scan)
|
||||
temp |= FLAG_ENABLED;
|
||||
if (mouse_buttons & 1)
|
||||
temp |= 4;
|
||||
if (mouse_buttons & 2)
|
||||
temp |= 1;
|
||||
if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI))
|
||||
temp |= 2;
|
||||
keyboard_at_adddata_mouse_cmd(temp);
|
||||
keyboard_at_adddata_mouse_cmd(dev->resolution);
|
||||
keyboard_at_adddata_mouse_cmd(dev->sample_rate);
|
||||
kbc_at_dev_queue_add(dev, temp, 0);
|
||||
kbc_at_dev_queue_add(dev, dev->resolution, 0);
|
||||
kbc_at_dev_queue_add(dev, dev->rate, 0);
|
||||
break;
|
||||
|
||||
case 0xea: /* set stream */
|
||||
mouse_ps2_log("%s: Set stream\n", dev->name);
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
dev->mode = MODE_STREAM;
|
||||
mouse_scan = 1;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */
|
||||
break;
|
||||
|
||||
case 0xeb: /* Get mouse data */
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
mouse_ps2_log("%s: Get mouse data\n", dev->name);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
|
||||
ps2_report_coordinates(dev, 1);
|
||||
ps2_report_coordinates(dev, 0);
|
||||
break;
|
||||
|
||||
case 0xf0: /* set remote */
|
||||
mouse_ps2_log("%s: Set remote\n", dev->name);
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
dev->mode = MODE_REMOTE;
|
||||
mouse_scan = 1;
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */
|
||||
break;
|
||||
|
||||
case 0xf2: /* read ID */
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
mouse_ps2_log("%s: Read ID\n", dev->name);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
if (dev->flags & FLAG_INTMODE)
|
||||
keyboard_at_adddata_mouse_cmd((dev->flags & FLAG_5BTN) ? 0x04 : 0x03);
|
||||
kbc_at_dev_queue_add(dev, (dev->flags & FLAG_5BTN) ? 0x04 : 0x03, 0);
|
||||
else
|
||||
keyboard_at_adddata_mouse_cmd(0x00);
|
||||
kbc_at_dev_queue_add(dev, 0x00, 0);
|
||||
break;
|
||||
|
||||
case 0xf3: /* set command mode */
|
||||
case 0xf3: /* set sample rate */
|
||||
mouse_ps2_log("%s: Set sample rate\n", dev->name);
|
||||
dev->flags |= FLAG_CTRLDAT;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa); /* ACK for command byte */
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */
|
||||
dev->state = DEV_STATE_MAIN_WANT_IN;
|
||||
break;
|
||||
|
||||
case 0xf4: /* enable */
|
||||
dev->flags |= FLAG_ENABLED;
|
||||
mouse_ps2_log("%s: Enable\n", dev->name);
|
||||
mouse_scan = 1;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
break;
|
||||
|
||||
case 0xf5: /* disable */
|
||||
dev->flags &= ~FLAG_ENABLED;
|
||||
mouse_ps2_log("%s: Disable\n", dev->name);
|
||||
mouse_scan = 0;
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
break;
|
||||
|
||||
case 0xf6: /* set defaults */
|
||||
mouse_ps2_log("%s: Set defaults\n", dev->name);
|
||||
ps2_set_defaults(dev);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
break;
|
||||
|
||||
case 0xff: /* reset */
|
||||
mouse_reset:
|
||||
dev->mode = MODE_STREAM;
|
||||
dev->flags &= 0x88;
|
||||
mouse_scan = 1;
|
||||
keyboard_at_mouse_reset();
|
||||
keyboard_at_adddata_mouse_cmd(0xfa);
|
||||
if (dev->command == 0xff) {
|
||||
keyboard_at_adddata_mouse_cmd(0xaa);
|
||||
keyboard_at_adddata_mouse_cmd(0x00);
|
||||
}
|
||||
mouse_ps2_log("%s: Reset\n", dev->name);
|
||||
kbc_at_dev_reset(dev, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
keyboard_at_adddata_mouse_cmd(0xfe);
|
||||
kbc_at_dev_queue_add(dev, 0xfe, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->flags & FLAG_INTELLI) {
|
||||
for (temp = 0; temp < 5; temp++)
|
||||
dev->last_data[temp] = dev->last_data[temp + 1];
|
||||
last_data[temp] = last_data[temp + 1];
|
||||
|
||||
dev->last_data[5] = val;
|
||||
last_data[5] = val;
|
||||
|
||||
if ((dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) &&
|
||||
(dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0x64) &&
|
||||
(dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50))
|
||||
if ((last_data[0] == 0xf3) && (last_data[1] == 0xc8) &&
|
||||
(last_data[2] == 0xf3) && (last_data[3] == 0x64) &&
|
||||
(last_data[4] == 0xf3) && (last_data[5] == 0x50))
|
||||
dev->flags |= FLAG_INTMODE;
|
||||
|
||||
if ((dev->flags & FLAG_INTMODE) && (dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) &&
|
||||
(dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0xc8) &&
|
||||
(dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50))
|
||||
if ((dev->flags & FLAG_EXPLORER) && (dev->flags & FLAG_INTMODE) &&
|
||||
(last_data[0] == 0xf3) && (last_data[1] == 0xc8) &&
|
||||
(last_data[2] == 0xf3) && (last_data[3] == 0xc8) &&
|
||||
(last_data[4] == 0xf3) && (last_data[5] == 0x50))
|
||||
dev->flags |= FLAG_5BTN;
|
||||
}
|
||||
}
|
||||
@@ -289,30 +316,18 @@ mouse_reset:
|
||||
static int
|
||||
ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
|
||||
{
|
||||
mouse_t *dev = (mouse_t *) priv;
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
|
||||
if (!x && !y && !z && (b == dev->b))
|
||||
return (0xff);
|
||||
|
||||
#if 0
|
||||
if (!(dev->flags & FLAG_ENABLED))
|
||||
return(0xff);
|
||||
#endif
|
||||
|
||||
if (!mouse_scan)
|
||||
if (!mouse_scan || (!x && !y && !z && (b == dev->b)))
|
||||
return (0xff);
|
||||
|
||||
dev->x += x;
|
||||
dev->y -= y;
|
||||
dev->z -= z;
|
||||
#if 0
|
||||
if ((dev->mode == MODE_STREAM) && (dev->flags & FLAG_ENABLED) && (keyboard_at_mouse_pos() < 13)) {
|
||||
#else
|
||||
if ((dev->mode == MODE_STREAM) && (keyboard_at_mouse_pos() < 13)) {
|
||||
#endif
|
||||
if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < 13)) {
|
||||
dev->b = b;
|
||||
|
||||
ps2_report_coordinates(dev, 0);
|
||||
ps2_report_coordinates(dev, 1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
@@ -326,11 +341,9 @@ ps2_poll(int x, int y, int z, int b, double abs_x, double abs_y, void *priv)
|
||||
void *
|
||||
mouse_ps2_init(const device_t *info)
|
||||
{
|
||||
mouse_t *dev;
|
||||
atkbc_dev_t *dev = kbc_at_dev_init(DEV_AUX);
|
||||
int i;
|
||||
|
||||
dev = (mouse_t *) malloc(sizeof(mouse_t));
|
||||
memset(dev, 0x00, sizeof(mouse_t));
|
||||
dev->name = info->name;
|
||||
dev->type = info->local;
|
||||
|
||||
@@ -338,18 +351,25 @@ mouse_ps2_init(const device_t *info)
|
||||
i = device_get_config_int("buttons");
|
||||
if (i > 2)
|
||||
dev->flags |= FLAG_INTELLI;
|
||||
if (i > 4)
|
||||
dev->flags |= FLAG_EXPLORER;
|
||||
|
||||
if (i == 4)
|
||||
if (i >= 4)
|
||||
i = 3;
|
||||
|
||||
/* Hook into the general AT Keyboard driver. */
|
||||
keyboard_at_set_mouse(ps2_write, dev);
|
||||
|
||||
mouse_ps2_log("%s: buttons=%d\n", dev->name, i);
|
||||
|
||||
/* Tell them how many buttons we have. */
|
||||
mouse_set_buttons(i);
|
||||
|
||||
dev->process_cmd = ps2_write;
|
||||
dev->execute_bat = ps2_bat;
|
||||
|
||||
dev->scan = &mouse_scan;
|
||||
|
||||
if (dev->port != NULL)
|
||||
kbc_at_dev_reset(dev, 0);
|
||||
|
||||
/* Return our private data to the I/O layer. */
|
||||
return (dev);
|
||||
}
|
||||
@@ -357,10 +377,7 @@ mouse_ps2_init(const device_t *info)
|
||||
static void
|
||||
ps2_close(void *priv)
|
||||
{
|
||||
mouse_t *dev = (mouse_t *) priv;
|
||||
|
||||
/* Unhook from the general AT Keyboard driver. */
|
||||
keyboard_at_set_mouse(NULL, NULL);
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user