Re-worked mouse code to be devices (to allow for configuration.)
Re-worked the system pathnames (pc.c), renamed cfg_path to usr_path. Other small things here and there. Logitech bus mouse re-worked, should be OK now.
This commit is contained in:
732
src/mouse_bus.c
732
src/mouse_bus.c
@@ -30,20 +30,26 @@
|
||||
* reading of the DIP switches? Oh-well.
|
||||
*
|
||||
* NOTES: Verified with:
|
||||
* AMI WinBIOS 486 (OK, IRQ5 only)
|
||||
* Microsoft Mouse V2.00 (DOS V6.22)
|
||||
* Microsoft Mouse V9.1 (DOS V6.22)
|
||||
* AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only)
|
||||
* Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK)
|
||||
* Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK)
|
||||
* Logitech LMouse.com V6.02 (DOS V6.22)
|
||||
* Logitech LMouse.com V6.43 (DOS V6.22)
|
||||
* Microsoft WfW V3.11 on DOS V6.22
|
||||
* GEOS V1.0: does not seem to work
|
||||
* GEOS V2.0: does not seem to work
|
||||
* GEOS V1.0 (OK, IRQ5 only)
|
||||
* GEOS V2.0 (OK, IRQ5 only)
|
||||
* Microsoft Windows 95 OSR2
|
||||
* Microsoft Windows 98 SE
|
||||
* Microsoft Windows NT 3.1
|
||||
* Microsoft Windows NT 3.51
|
||||
*
|
||||
* Based on an early driver for MINIX 1.5.
|
||||
* Based on the 86Box PS/2 mouse driver as a framework.
|
||||
*
|
||||
* Version: @(#)mouse_bus.c 1.0.23 2017/11/22
|
||||
* TODO: Re-integrate the InPort part. Currently,
|
||||
* only the Logitech part is considered to
|
||||
* be OK.
|
||||
*
|
||||
* Version: @(#)mouse_bus.c 1.0.24 2017/12/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -59,111 +65,320 @@
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
#include "timer.h"
|
||||
#include "device.h"
|
||||
#include "mouse.h"
|
||||
|
||||
|
||||
#define BUSMOUSE_PORT 0x023c /* default */
|
||||
#define BUSMOUSE_IRQ 5 /* default (DOS,NT31) */
|
||||
#define BUSMOUSE_DEBUG 0
|
||||
|
||||
|
||||
#define ENABLE_3BTN 1 /* enable 3-button mode */
|
||||
#define MOUSE_PORT 0x023c /* default */
|
||||
#define MOUSE_IRQ 5 /* default (DOS,NT31) */
|
||||
#define MOUSE_DEBUG 2
|
||||
|
||||
|
||||
/* Our mouse device. */
|
||||
typedef struct mouse_bus {
|
||||
typedef struct mouse {
|
||||
const char *name; /* name of this device */
|
||||
int8_t type; /* type of this device */
|
||||
uint8_t flags; /* device flags */
|
||||
int8_t irq; /* IRQ channel to use */
|
||||
uint8_t flags; /* device flags */
|
||||
|
||||
uint8_t r_magic; /* MAGIC register */
|
||||
uint8_t r_ctrl; /* CONTROL register (WR) */
|
||||
uint8_t r_intr; /* INTSTAT register (RO) */
|
||||
uint8_t r_conf; /* CONFIG register */
|
||||
uint8_t r_magic, /* MAGIC register */
|
||||
r_ctrl, /* CONTROL register (WR) */
|
||||
r_conf, /* CONFIG register */
|
||||
r_cmd; /* (MS) current command */
|
||||
|
||||
uint8_t but;
|
||||
int16_t x, y; /* current mouse status */
|
||||
uint8_t seq; /* general counter */
|
||||
|
||||
uint8_t but, /* current mouse status */
|
||||
but_last;
|
||||
int8_t x, y;
|
||||
int8_t x_delay,
|
||||
y_delay;
|
||||
|
||||
int64_t timer; /* mouse event timer */
|
||||
|
||||
uint8_t (*read)(struct mouse_bus *, uint16_t);
|
||||
void (*write)(struct mouse_bus *, uint16_t, uint8_t);
|
||||
} mouse_bus_t;
|
||||
#define MOUSE_ENABLED 0x80 /* device is enabled for use */
|
||||
#define MOUSE_SCALED 0x40 /* enable delta scaling */
|
||||
#define MOUSE_FROZEN 0x01 /* do not update counters */
|
||||
uint8_t (*read)(struct mouse *, uint16_t);
|
||||
void (*write)(struct mouse *, uint16_t, uint8_t);
|
||||
} mouse_t;
|
||||
#define FLAG_INPORT 0x80 /* device is MS InPort */
|
||||
#define FLAG_3BTN 0x20 /* enable 3-button mode */
|
||||
#define FLAG_SCALED 0x10 /* enable delta scaling */
|
||||
#define FLAG_INTR 0x04 /* dev can send interrupts */
|
||||
#define FLAG_FROZEN 0x02 /* do not update counters */
|
||||
#define FLAG_ENABLED 0x01 /* dev is enabled for use */
|
||||
|
||||
|
||||
/* Definitions for Logitech. */
|
||||
#define MOUSE_DATA 0 /* DATA register */
|
||||
#define MOUSE_MAGIC 1 /* signature magic register */
|
||||
# define MAGIC_BYTE1 0xa5 /* most drivers use this */
|
||||
# define MAGIC_BYTE2 0x5a /* some drivers use this */
|
||||
#define MOUSE_CTRL 2 /* CTRL register */
|
||||
# define CTRL_FREEZE 0x80 /* do not sample when set */
|
||||
# define CTRL_RD_Y_HI 0x60 /* plus FREEZE */
|
||||
# define CTRL_RD_Y_LO 0x40 /* plus FREEZE */
|
||||
# define CTRL_RD_X_HI 0x20 /* plus FREEZE */
|
||||
# define CTRL_RD_X_LO 0x00 /* plus FREEZE */
|
||||
# define CTRL_RD_MASK 0x60
|
||||
# define CTRL_IDIS 0x10
|
||||
# define CTRL_IENB 0x00
|
||||
#define MOUSE_CONFIG 3 /* CONFIG register */
|
||||
#define LTMOUSE_DATA 0 /* DATA register */
|
||||
#define LTMOUSE_MAGIC 1 /* signature magic register */
|
||||
# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */
|
||||
# define LTMAGIC_BYTE2 0x5a /* some drivers use this */
|
||||
#define LTMOUSE_CTRL 2 /* CTRL register */
|
||||
# define LTCTRL_FREEZE 0x80 /* do not sample when set */
|
||||
# define LTCTRL_RD_Y_HI 0x60
|
||||
# define LTCTRL_RD_Y_LO 0x40
|
||||
# define LTCTRL_RD_X_HI 0x20
|
||||
# define LTCTRL_RD_X_LO 0x00
|
||||
# define LTCTRL_RD_MASK 0x60
|
||||
# define LTCTRL_IDIS 0x10
|
||||
# define LTCTRL_IENB 0x00
|
||||
#define LTMOUSE_CONFIG 3 /* CONFIG register */
|
||||
|
||||
/* Definitions for Microsoft. */
|
||||
#define MSMOUSE_CTRL 0 /* CTRL register */
|
||||
# define MSCTRL_RESET 0x80 /* reset controller */
|
||||
# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */
|
||||
# define MSCTRL_IENB 0x01
|
||||
# define MSCTRL_COMMAND 0x07
|
||||
# define MSCTRL_RD_Y 0x02
|
||||
# define MSCTRL_RD_X 0x01
|
||||
# define MSCTRL_RD_BUT 0x00
|
||||
#define MSMOUSE_DATA 1 /* DATA register */
|
||||
# define MSDATA_BASE 0x10
|
||||
# define MSDATA_IRQ 0x01
|
||||
#define MSMOUSE_MAGIC 2 /* MAGIC register */
|
||||
# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */
|
||||
# define MAGIC_MSBYTE2 0x12
|
||||
#define MSMOUSE_CONFIG 3 /* CONFIG register */
|
||||
|
||||
|
||||
/* Handle a WRITE to a LOGITECH register. */
|
||||
/* Reset the controller state. */
|
||||
static void
|
||||
lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val)
|
||||
ms_reset(mouse_t *dev)
|
||||
{
|
||||
dev->flags &= 0xf0;
|
||||
|
||||
dev->seq = 0;
|
||||
|
||||
dev->x = dev->y = 0;
|
||||
dev->but = 0x00;
|
||||
|
||||
dev->flags |= FLAG_INTR;
|
||||
}
|
||||
|
||||
|
||||
/* Handle a WRITE to an InPort register. */
|
||||
static void
|
||||
ms_write(mouse_t *dev, uint16_t port, uint8_t val)
|
||||
{
|
||||
switch (port) {
|
||||
case MSMOUSE_CTRL:
|
||||
switch (val) {
|
||||
case MSCTRL_RESET:
|
||||
dev->r_ctrl = 0x00;
|
||||
dev->r_cmd = 0x00;
|
||||
break;
|
||||
|
||||
case MSCTRL_COMMAND:
|
||||
case MSCTRL_RD_BUT:
|
||||
case MSCTRL_RD_X:
|
||||
case MSCTRL_RD_Y:
|
||||
dev->r_cmd = val;
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
dev->r_ctrl = 0x00;
|
||||
dev->r_cmd = MSCTRL_COMMAND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSMOUSE_DATA:
|
||||
picintc(1 << dev->irq);
|
||||
if (val == MSDATA_IRQ) {
|
||||
picint(1<<dev->irq);
|
||||
} else switch (dev->r_cmd) {
|
||||
case MSCTRL_COMMAND:
|
||||
dev->r_ctrl = val;
|
||||
if (val & MSCTRL_IENB)
|
||||
dev->flags |= FLAG_INTR;
|
||||
else
|
||||
dev->flags &= ~FLAG_INTR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSMOUSE_MAGIC:
|
||||
break;
|
||||
|
||||
case MSMOUSE_CONFIG:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handle a READ from an InPort register. */
|
||||
static uint8_t
|
||||
ms_read(mouse_t *dev, uint16_t port)
|
||||
{
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
switch (port) {
|
||||
case MSMOUSE_CTRL:
|
||||
ret = dev->r_ctrl;
|
||||
break;
|
||||
|
||||
case MSMOUSE_DATA:
|
||||
switch (dev->r_cmd) {
|
||||
case MSCTRL_RD_BUT:
|
||||
ret = dev->but;
|
||||
ret |= 0x40;
|
||||
break;
|
||||
|
||||
case MSCTRL_RD_X:
|
||||
ret = dev->x;
|
||||
break;
|
||||
|
||||
case MSCTRL_RD_Y:
|
||||
ret = dev->y;
|
||||
break;
|
||||
|
||||
case MSCTRL_COMMAND:
|
||||
ret = dev->r_ctrl;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSMOUSE_MAGIC:
|
||||
if (dev->seq & 0x01)
|
||||
ret = MAGIC_MSBYTE2;
|
||||
else
|
||||
ret = MAGIC_MSBYTE1;
|
||||
dev->seq++;
|
||||
break;
|
||||
|
||||
case MSMOUSE_CONFIG:
|
||||
/* Not really present in real hardware. */
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* Called at 30hz */
|
||||
static void
|
||||
bm_timer(void *priv)
|
||||
{
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
dev->timer += ((1000000.0 / 30.0) * TIMER_USEC);
|
||||
|
||||
#if 0
|
||||
/* The controller updates the data on every interrupt
|
||||
We just don't copy it to the current_X if the 'hold' bit is set */
|
||||
if (dev->is_inport) {
|
||||
if ((dev->but & (1<<2)) ||
|
||||
((dev->but_last & (1<<2)) && !(dev->but & (1<<2))))
|
||||
dev->but |= (1<<5);
|
||||
if ((dev->but & (1<<1)) ||
|
||||
((dev->but_last & (1<<1)) && !(dev->but & (1<<1))))
|
||||
dev->but |= (1<<4);
|
||||
if ((dev->but & (1<<0)) ||
|
||||
((dev->but_last & (1<<0)) && !(dev->buttons & (1<<0))))
|
||||
dev->but |= (1<<3);
|
||||
dev->but_last = dev>but;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dev->flags & FLAG_INTR)
|
||||
picint(1 << dev->irq);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the Microsoft Bus Mouse interface. */
|
||||
static void
|
||||
ms_init(mouse_t *dev)
|
||||
{
|
||||
/* Initialize registers. */
|
||||
dev->r_ctrl = 0x00;
|
||||
dev->r_conf = 0x00;
|
||||
|
||||
dev->flags |= FLAG_INPORT;
|
||||
|
||||
/* Initialize I/O handlers. */
|
||||
dev->read = ms_read;
|
||||
dev->write = ms_write;
|
||||
|
||||
timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev);
|
||||
}
|
||||
|
||||
|
||||
/* Reset the controller state. */
|
||||
static void
|
||||
lt_reset(mouse_t *dev)
|
||||
{
|
||||
dev->flags &= 0xf0;
|
||||
|
||||
dev->r_magic = 0x00;
|
||||
dev->r_ctrl = (LTCTRL_IENB);
|
||||
dev->r_conf = 0x00;
|
||||
|
||||
dev->seq = 0;
|
||||
|
||||
dev->x = dev->y = 0;
|
||||
dev->but = 0x00;
|
||||
|
||||
dev->flags |= FLAG_INTR;
|
||||
}
|
||||
|
||||
|
||||
/* Handle a WRITE to a Logitech register. */
|
||||
static void
|
||||
lt_write(mouse_t *dev, uint16_t port, uint8_t val)
|
||||
{
|
||||
uint8_t b;
|
||||
|
||||
#if BUSMOUSE_DEBUG
|
||||
pclog("BUSMOUSE: lt_write(%d,%02x)\n", port, val);
|
||||
#endif
|
||||
|
||||
switch (port) {
|
||||
case MOUSE_DATA: /* [00] data register */
|
||||
case LTMOUSE_DATA: /* [00] data register */
|
||||
break;
|
||||
|
||||
case MOUSE_MAGIC: /* [01] magic data register */
|
||||
case LTMOUSE_MAGIC: /* [01] magic data register */
|
||||
switch(val) {
|
||||
case MAGIC_BYTE1:
|
||||
case MAGIC_BYTE2:
|
||||
ms->r_ctrl = (CTRL_IENB);
|
||||
ms->r_magic = val;
|
||||
ms->r_intr = 0x00;
|
||||
case LTMAGIC_BYTE1:
|
||||
case LTMAGIC_BYTE2:
|
||||
lt_reset(dev);
|
||||
dev->r_magic = val;
|
||||
dev->flags |= FLAG_ENABLED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_CTRL: /* [02] control register */
|
||||
b = (ms->r_ctrl ^ val);
|
||||
if (b & CTRL_FREEZE) {
|
||||
if (val & CTRL_FREEZE) {
|
||||
case LTMOUSE_CTRL: /* [02] control register */
|
||||
b = (dev->r_ctrl ^ val);
|
||||
if (b & LTCTRL_FREEZE) {
|
||||
if (val & LTCTRL_FREEZE) {
|
||||
/* Hold the sampling while we do something. */
|
||||
ms->flags |= MOUSE_FROZEN;
|
||||
dev->flags |= FLAG_FROZEN;
|
||||
} else {
|
||||
/* Reset current state. */
|
||||
ms->x = ms->y = 0;
|
||||
if (ms->but)
|
||||
/* One more POLL for button-release. */
|
||||
ms->but = 0x80;
|
||||
ms->flags &= ~MOUSE_FROZEN;
|
||||
dev->flags &= ~FLAG_FROZEN;
|
||||
dev->x = dev->y = 0;
|
||||
if (dev->but)
|
||||
dev->but |= 0x80;
|
||||
dev->seq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (b & CTRL_IDIS) {
|
||||
if (b & LTCTRL_IDIS) {
|
||||
/* Disable or enable interrupts. */
|
||||
/* (we don't do anything for that here..) */
|
||||
if (val & LTCTRL_IDIS)
|
||||
dev->flags &= ~FLAG_INTR;
|
||||
else
|
||||
dev->flags |= FLAG_INTR;
|
||||
}
|
||||
|
||||
/* Save new register value. */
|
||||
ms->r_ctrl = val;
|
||||
dev->r_ctrl = val;
|
||||
|
||||
/* Clear any pending interrupts. */
|
||||
picintc(1 << dev->irq);
|
||||
break;
|
||||
|
||||
case MOUSE_CONFIG: /* [03] config register */
|
||||
ms->r_conf = val;
|
||||
case LTMOUSE_CONFIG: /* [03] config register */
|
||||
dev->r_conf = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -172,140 +387,104 @@ lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val)
|
||||
}
|
||||
|
||||
|
||||
/* Handle a READ from a LOGITECH register. */
|
||||
/* Handle a READ from a Logitech register. */
|
||||
static uint8_t
|
||||
lt_read(mouse_bus_t *ms, uint16_t port)
|
||||
lt_read(mouse_t *dev, uint16_t port)
|
||||
{
|
||||
uint8_t r = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
/* The GEOS drivers actually check this. */
|
||||
if (! (dev->flags & FLAG_ENABLED)) return(ret);
|
||||
|
||||
switch (port) {
|
||||
case MOUSE_DATA: /* [00] data register */
|
||||
if (! (ms->r_ctrl & CTRL_FREEZE)) {
|
||||
r = 0x00;
|
||||
} else switch(ms->r_ctrl & CTRL_RD_MASK) {
|
||||
case CTRL_RD_X_LO: /* X, low bits */
|
||||
/*
|
||||
* Some drivers expect the buttons to
|
||||
* be in this byte. Others want it in
|
||||
* the Y-LO byte. --FvK
|
||||
*/
|
||||
r = 0x07;
|
||||
if (ms->but & 0x01) /*LEFT*/
|
||||
r &= ~0x04;
|
||||
if (ms->but & 0x02) /*RIGHT*/
|
||||
r &= ~0x01;
|
||||
#if ENABLE_3BTN
|
||||
if (ms->but & 0x04) /*MIDDLE*/
|
||||
r &= ~0x02;
|
||||
#endif
|
||||
r <<= 5;
|
||||
r |= (ms->x & 0x0f);
|
||||
case LTMOUSE_DATA: /* [00] data register */
|
||||
/*
|
||||
* Regardless of which subcommand used, the first
|
||||
* one has to return the state of the buttons.
|
||||
*/
|
||||
if (! dev->seq) {
|
||||
ret = 0x07;
|
||||
if (dev->but & 0x01) /*LEFT*/
|
||||
ret &= ~0x04;
|
||||
if (dev->but & 0x02) /*RIGHT*/
|
||||
ret &= ~0x01;
|
||||
if (dev->flags & FLAG_3BTN)
|
||||
if (dev->but & 0x04) /*MIDDLE*/
|
||||
ret &= ~0x02;
|
||||
ret <<= 5;
|
||||
} else {
|
||||
dev->seq++;
|
||||
|
||||
ret = 0x00;
|
||||
}
|
||||
|
||||
switch(dev->r_ctrl & LTCTRL_RD_MASK) {
|
||||
case LTCTRL_RD_X_LO: /* X, low bits */
|
||||
ret |= (dev->x & 0x0f);
|
||||
break;
|
||||
|
||||
case CTRL_RD_X_HI: /* X, high bits */
|
||||
r = (ms->x >> 4) & 0x0f;
|
||||
case LTCTRL_RD_X_HI: /* X, high bits */
|
||||
ret |= (dev->x >> 4) & 0x0f;
|
||||
break;
|
||||
|
||||
case CTRL_RD_Y_LO: /* Y, low bits */
|
||||
r = (ms->y & 0x0f);
|
||||
case LTCTRL_RD_Y_LO: /* Y, low bits */
|
||||
ret |= (dev->y & 0x0f);
|
||||
break;
|
||||
|
||||
case CTRL_RD_Y_HI: /* Y, high bits */
|
||||
/*
|
||||
* Some drivers expect the buttons to
|
||||
* be in this byte. Others want it in
|
||||
* the X-LO byte. --FvK
|
||||
*/
|
||||
r = 0x07;
|
||||
if (ms->but & 0x01) /*LEFT*/
|
||||
r &= ~0x04;
|
||||
if (ms->but & 0x02) /*RIGHT*/
|
||||
r &= ~0x01;
|
||||
#if ENABLE_3BTN
|
||||
if (ms->but & 0x04) /*MIDDLE*/
|
||||
r &= ~0x02;
|
||||
#endif
|
||||
r <<= 5;
|
||||
r |= (ms->y >> 4) & 0x0f;
|
||||
case LTCTRL_RD_Y_HI: /* Y, high bits */
|
||||
ret |= (dev->y >> 4) & 0x0f;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_MAGIC: /* [01] magic data register */
|
||||
case LTMOUSE_MAGIC: /* [01] magic data register */
|
||||
/*
|
||||
* Drivers write a magic byte to this register, usually
|
||||
* this is either 5A (AMI WinBIOS, MS Mouse 2.0-9.1) or
|
||||
* A5 (Windows drivers, UNIX/Linux/Minix.)
|
||||
*
|
||||
* It is unclear why there are two values, but the most
|
||||
* likely explanation is to distinguish two variants of
|
||||
* the hardware - one locked to a certain IRQ, and one
|
||||
* that has the DIP switch to set the IRQ value.
|
||||
* this is either 5A (AMI WinBIOS, MS Mouse 2.0) or
|
||||
* A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.)
|
||||
*/
|
||||
r = ms->r_magic;
|
||||
ret = dev->r_magic;
|
||||
break;
|
||||
|
||||
case MOUSE_CTRL: /* [02] control register */
|
||||
r = 0x0f;
|
||||
switch(ms->irq) {
|
||||
case 2:
|
||||
r &= ~0x08;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
r &= ~0x04;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
r &= ~0x02;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
r &= ~0x01;
|
||||
break;
|
||||
}
|
||||
if (ms->r_intr++ < 250) {
|
||||
/* Still settling, return invalid data. */
|
||||
r = (ms->r_ctrl & 0x10) ? r : 0x0f;
|
||||
case LTMOUSE_CTRL: /* [02] control register */
|
||||
if (dev->r_ctrl & LTCTRL_IDIS) {
|
||||
/* IDIS, no interrupts, return all-off. */
|
||||
ret = 0x0f;
|
||||
} else if (dev->seq++ == 0) {
|
||||
/* !IDIS, return DIP switch setting. */
|
||||
ret = 0x0f;
|
||||
switch(dev->irq) {
|
||||
case 2:
|
||||
ret &= ~0x08;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ret &= ~0x04;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ret &= ~0x02;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
ret &= ~0x01;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ms->r_intr = 0;
|
||||
/* Return all-off (invalid data.) */
|
||||
ret = 0x0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_CONFIG: /* [03] config register */
|
||||
r = ms->r_conf;
|
||||
case LTMOUSE_CONFIG: /* [03] config register */
|
||||
ret = dev->r_conf;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if BUSMOUSE_DEBUG > 1
|
||||
pclog("BUSMOUSE: lt_read(%d): %02x\n", port, r);
|
||||
#endif
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the Logitech Bus Mouse interface. */
|
||||
static void
|
||||
lt_init(mouse_bus_t *ms)
|
||||
{
|
||||
pclog("BUSMOUSE: %s, I/O=%04x, IRQ=%d\n",
|
||||
ms->name, BUSMOUSE_PORT, ms->irq);
|
||||
|
||||
/* Initialize registers. */
|
||||
ms->r_magic = 0x00;
|
||||
ms->r_conf = 0x00;
|
||||
ms->r_ctrl= 0x00;
|
||||
|
||||
/* Initialize I/O handlers. */
|
||||
ms->read = lt_read;
|
||||
ms->write = lt_write;
|
||||
|
||||
/* All done. */
|
||||
ms->flags = 0x00;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -313,9 +492,13 @@ lt_init(mouse_bus_t *ms)
|
||||
static void
|
||||
bm_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
ms->write(ms, port-BUSMOUSE_PORT, val);
|
||||
#if MOUSE_DEBUG
|
||||
pclog("%s: write(%d,%02x)\n", dev->name, port-MOUSE_PORT, val);
|
||||
#endif
|
||||
|
||||
dev->write(dev, port-MOUSE_PORT, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -323,57 +506,68 @@ bm_write(uint16_t port, uint8_t val, void *priv)
|
||||
static uint8_t
|
||||
bm_read(uint16_t port, void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
uint8_t r;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
uint8_t ret;
|
||||
|
||||
r = ms->read(ms, port-BUSMOUSE_PORT);
|
||||
ret = dev->read(dev, port-MOUSE_PORT);
|
||||
|
||||
return(r);
|
||||
#if MOUSE_DEBUG > 1
|
||||
pclog("%s: read(%d): %02x\n", dev->name, port-MOUSE_PORT, ret);
|
||||
#endif
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* The emulator calls us with an update on the host mouse device. */
|
||||
static uint8_t
|
||||
static int
|
||||
bm_poll(int x, int y, int z, int b, void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
/* Return early if nothing to do. */
|
||||
if (!x && !y && !z && (ms->but == b)) return(1);
|
||||
if (!x && !y && !z && (dev->but == b)) return(1);
|
||||
|
||||
/* If we are not interested, return. */
|
||||
if (!(ms->flags & MOUSE_ENABLED) || (ms->flags & MOUSE_FROZEN)) return(0);
|
||||
/* If we are not enabled, return. */
|
||||
if (! (dev->flags & FLAG_ENABLED)) return(0);
|
||||
|
||||
#if 0
|
||||
pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b);
|
||||
pclog("%s: poll(%d,%d,%d,%02x) %d\n",
|
||||
dev->name, x, y, z, b, !!(dev->flags & FLAG_FROZEN));
|
||||
#endif
|
||||
|
||||
if (ms->flags & MOUSE_SCALED) {
|
||||
/* Scale down the motion. */
|
||||
if ((x < -1) || (x > 1)) x >>= 1;
|
||||
if ((y < -1) || (y > 1)) y >>= 1;
|
||||
/* If we are frozen, do not update the state. */
|
||||
if (! (dev->flags & FLAG_FROZEN)) {
|
||||
if (dev->flags & FLAG_SCALED) {
|
||||
/* Scale down the motion. */
|
||||
if ((x < -1) || (x > 1)) x >>= 1;
|
||||
if ((y < -1) || (y > 1)) y >>= 1;
|
||||
}
|
||||
|
||||
/* Add the delta to our state. */
|
||||
x += dev->x;
|
||||
if (x > 127)
|
||||
x = 127;
|
||||
if (x < -128)
|
||||
x = -128;
|
||||
dev->x = (int8_t)x;
|
||||
|
||||
y += dev->y;
|
||||
if (y > 127)
|
||||
y = 127;
|
||||
if (y < -1287)
|
||||
y = -1287;
|
||||
dev->y = (int8_t)y;
|
||||
|
||||
dev->x_delay += x;
|
||||
dev->y_delay += y;
|
||||
|
||||
dev->but = b;
|
||||
}
|
||||
|
||||
/* Add the delta to our state. */
|
||||
x += ms->x;
|
||||
if (x > 1023)
|
||||
x = 1023;
|
||||
if (x < -1024)
|
||||
x = -1024;
|
||||
ms->x = (int16_t)x;
|
||||
|
||||
y += ms->y;
|
||||
if (y > 1023)
|
||||
y = 1023;
|
||||
if (y < -1024)
|
||||
y = -1024;
|
||||
ms->y = (int16_t)y;
|
||||
|
||||
ms->but = b;
|
||||
|
||||
/* All set, generate an interrupt. */
|
||||
if (! (ms->r_ctrl & CTRL_IDIS))
|
||||
picint(1 << ms->irq);
|
||||
/* Either way, generate an interrupt. */
|
||||
if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT))
|
||||
picint(1 << dev->irq);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -383,56 +577,60 @@ bm_poll(int x, int y, int z, int b, void *priv)
|
||||
static void
|
||||
bm_close(void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
/* Release our I/O range. */
|
||||
io_removehandler(BUSMOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, ms);
|
||||
io_removehandler(MOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, dev);
|
||||
|
||||
free(ms);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the device for use by the user. */
|
||||
static void *
|
||||
bm_init(mouse_t *info)
|
||||
bm_init(device_t *info)
|
||||
{
|
||||
mouse_bus_t *ms;
|
||||
|
||||
ms = (mouse_bus_t *)malloc(sizeof(mouse_bus_t));
|
||||
memset(ms, 0x00, sizeof(mouse_bus_t));
|
||||
ms->name = info->name;
|
||||
ms->type = info->type;
|
||||
mouse_t *dev;
|
||||
|
||||
dev = (mouse_t *)malloc(sizeof(mouse_t));
|
||||
memset(dev, 0x00, sizeof(mouse_t));
|
||||
dev->name = info->name;
|
||||
dev->type = info->local;
|
||||
#if NOTYET
|
||||
ms->irq = device_get_config_int("irq");
|
||||
dev->irq = device_get_config_int("irq");
|
||||
#else
|
||||
ms->irq = config_get_int((char *)info->name, "irq", 0);
|
||||
dev->irq = config_get_int((char *)info->name, "irq", 0);
|
||||
#endif
|
||||
if (ms->irq == 0)
|
||||
ms->irq = BUSMOUSE_IRQ;
|
||||
if (dev->irq == 0)
|
||||
dev->irq = MOUSE_IRQ;
|
||||
|
||||
switch(ms->type) {
|
||||
pclog("%s: I/O=%04x, IRQ=%d\n", dev->name, MOUSE_PORT, dev->irq);
|
||||
|
||||
switch(dev->type) {
|
||||
case MOUSE_TYPE_LOGIBUS:
|
||||
lt_init(ms);
|
||||
/* Initialize registers. */
|
||||
lt_reset(dev);
|
||||
|
||||
/* Initialize I/O handlers. */
|
||||
dev->read = lt_read;
|
||||
dev->write = lt_write;
|
||||
break;
|
||||
|
||||
case MOUSE_TYPE_INPORT:
|
||||
// ms_init(ms);
|
||||
ms_init(dev);
|
||||
break;
|
||||
}
|
||||
ms->flags |= MOUSE_ENABLED;
|
||||
|
||||
/* Request an I/O range. */
|
||||
io_sethandler(BUSMOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, ms);
|
||||
io_sethandler(MOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, dev);
|
||||
|
||||
/* Return our private data to the I/O layer. */
|
||||
return(ms);
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
#if NOTYET
|
||||
static device_config_t bm_config[] = {
|
||||
{
|
||||
"irq", "IRQ", CONFIG_SELECTION, "", 2, {
|
||||
@@ -451,32 +649,72 @@ static device_config_t bm_config[] = {
|
||||
{
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
mouse_t mouse_bus_logitech = {
|
||||
device_t mouse_logibus_device = {
|
||||
"Logitech Bus Mouse",
|
||||
"logibus",
|
||||
DEVICE_ISA,
|
||||
MOUSE_TYPE_LOGIBUS,
|
||||
bm_init,
|
||||
bm_close,
|
||||
bm_poll
|
||||
bm_init, bm_close, NULL,
|
||||
bm_poll, NULL, NULL, NULL,
|
||||
bm_config
|
||||
};
|
||||
|
||||
mouse_t mouse_bus_msinport = {
|
||||
device_t mouse_msinport_device = {
|
||||
"Microsoft Bus Mouse (InPort)",
|
||||
"msbus",
|
||||
DEVICE_ISA,
|
||||
MOUSE_TYPE_INPORT,
|
||||
bm_init,
|
||||
bm_close,
|
||||
bm_poll
|
||||
bm_init, bm_close, NULL,
|
||||
bm_poll, NULL, NULL, NULL,
|
||||
bm_config
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
@@@@@@
|
||||
void busmouse_update_mouse_data(void *priv)
|
||||
{
|
||||
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
||||
|
||||
int delta_x, delta_y;
|
||||
int hold;
|
||||
|
||||
if (busmouse->x_delay > 127) {
|
||||
delta_x = 127;
|
||||
busmouse->x_delay -= 127;
|
||||
} else if (busmouse->x_delay < -128) {
|
||||
delta_x = -128;
|
||||
busmouse->x_delay += 128;
|
||||
} else {
|
||||
delta_x = busmouse->x_delay;
|
||||
busmouse->x_delay = 0;
|
||||
}
|
||||
if (busmouse->y_delay > 127) {
|
||||
delta_y = 127;
|
||||
busmouse->y_delay -= 127;
|
||||
} else if (busmouse->y_delay < -128) {
|
||||
delta_y = -128;
|
||||
busmouse->y_delay += 128;
|
||||
} else {
|
||||
delta_y = busmouse->y_delay;
|
||||
busmouse->y_delay = 0;
|
||||
}
|
||||
|
||||
if (busmouse->is_inport) {
|
||||
hold = (busmouse->control_val & INP_HOLD_COUNTER) > 0;
|
||||
} else {
|
||||
hold = (busmouse->control_val & HOLD_COUNTER) > 0;
|
||||
}
|
||||
if (!hold) {
|
||||
busmouse->x = (uint8_t) delta_x;
|
||||
busmouse->y = (uint8_t) delta_y;
|
||||
busmouse->but = busmouse->mouse_buttons;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user