Added proper Bus Mouse emulation and introduced InPort Mouse emulation.
This commit is contained in:
@@ -841,14 +841,15 @@ BEGIN
|
|||||||
|
|
||||||
IDS_3072 "None"
|
IDS_3072 "None"
|
||||||
IDS_3073 "[Bus] Bus mouse"
|
IDS_3073 "[Bus] Bus mouse"
|
||||||
IDS_3074 "[Serial] Mouse Systems mouse"
|
IDS_3074 "[Bus] InPort mouse"
|
||||||
IDS_3075 "[Serial] Microsoft 2-button mouse"
|
IDS_3075 "[Serial] Mouse Systems mouse"
|
||||||
IDS_3076 "[Serial] Logitech 3-button mouse"
|
IDS_3076 "[Serial] Microsoft 2-button mouse"
|
||||||
IDS_3077 "[Serial] Microsoft wheel mouse"
|
IDS_3077 "[Serial] Logitech 3-button mouse"
|
||||||
IDS_3078 "[PS/2] 2-button mouse"
|
IDS_3078 "[Serial] Microsoft wheel mouse"
|
||||||
IDS_3079 "[PS/2] Microsoft Intellimouse"
|
IDS_3079 "[PS/2] 2-button mouse"
|
||||||
IDS_3080 "[Proprietary] Amstrad mouse"
|
IDS_3080 "[PS/2] Microsoft Intellimouse"
|
||||||
IDS_3081 "[Proprietary] Olivetti M24 mouse"
|
IDS_3081 "[Proprietary] Amstrad mouse"
|
||||||
|
IDS_3082 "[Proprietary] Olivetti M24 mouse"
|
||||||
|
|
||||||
IDS_4096 "Hard disk (%s)"
|
IDS_4096 "Hard disk (%s)"
|
||||||
IDS_4097 "%01i:%01i"
|
IDS_4097 "%01i:%01i"
|
||||||
|
|||||||
@@ -330,6 +330,7 @@
|
|||||||
#define IDS_3079 3079
|
#define IDS_3079 3079
|
||||||
#define IDS_3080 3080
|
#define IDS_3080 3080
|
||||||
#define IDS_3081 3081
|
#define IDS_3081 3081
|
||||||
|
#define IDS_3082 3082
|
||||||
|
|
||||||
#define IDS_4096 4096
|
#define IDS_4096 4096
|
||||||
#define IDS_4097 4097
|
#define IDS_4097 4097
|
||||||
@@ -391,7 +392,7 @@
|
|||||||
#define IDS_LANG_ENUS IDS_6144
|
#define IDS_LANG_ENUS IDS_6144
|
||||||
|
|
||||||
#define STRINGS_NUM_2048 122
|
#define STRINGS_NUM_2048 122
|
||||||
#define STRINGS_NUM_3072 10
|
#define STRINGS_NUM_3072 11
|
||||||
#define STRINGS_NUM_4096 20
|
#define STRINGS_NUM_4096 20
|
||||||
#define STRINGS_NUM_4352 7
|
#define STRINGS_NUM_4352 7
|
||||||
#define STRINGS_NUM_4608 7
|
#define STRINGS_NUM_4608 7
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ static mouse_t mouse_none = {
|
|||||||
|
|
||||||
static mouse_t *mouse_list[] = {
|
static mouse_t *mouse_list[] = {
|
||||||
&mouse_none,
|
&mouse_none,
|
||||||
&mouse_bus, /* 1 Logitech Bus Mouse 2-button */
|
&mouse_bus, /* 1 Microsoft/Logitech Bus Mouse 2-button */
|
||||||
&mouse_msystems, /* 2 Mouse Systems */
|
&mouse_msystems, /* 2 Mouse Systems */
|
||||||
&mouse_serial_microsoft, /* 3 Microsoft Serial Mouse */
|
&mouse_serial_microsoft, /* 3 Microsoft Serial Mouse */
|
||||||
&mouse_serial_logitech, /* 4 Logitech 3-button Serial Mouse */
|
&mouse_serial_logitech, /* 4 Logitech 3-button Serial Mouse */
|
||||||
@@ -44,8 +44,9 @@ static mouse_t *mouse_list[] = {
|
|||||||
&mouse_intellimouse, /* 7 PS/2 Intellimouse 3-button */
|
&mouse_intellimouse, /* 7 PS/2 Intellimouse 3-button */
|
||||||
&mouse_amstrad, /* 8 Amstrad PC System Mouse */
|
&mouse_amstrad, /* 8 Amstrad PC System Mouse */
|
||||||
&mouse_olim24, /* 9 Olivetti M24 System Mouse */
|
&mouse_olim24, /* 9 Olivetti M24 System Mouse */
|
||||||
|
&mouse_inport, /* 10 Microsoft InPort Mouse */
|
||||||
#if 0
|
#if 0
|
||||||
&mouse_genius, /* 10 Genius Bus Mouse */
|
&mouse_genius, /* 11 Genius Bus Mouse */
|
||||||
#endif
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#define MOUSE_TYPE_NONE 0
|
#define MOUSE_TYPE_NONE 0
|
||||||
#if 0
|
#if 0
|
||||||
#define MOUSE_TYPE_GENIUS 10 /* Genius Bus Mouse */
|
#define MOUSE_TYPE_GENIUS 11 /* Genius Bus Mouse */
|
||||||
#endif
|
#endif
|
||||||
#define MOUSE_TYPE_BUS 1 /* Logitech/ATI Bus Mouse */
|
#define MOUSE_TYPE_BUS 1 /* Logitech/ATI Bus Mouse */
|
||||||
#define MOUSE_TYPE_MSYSTEMS 2 /* Mouse Systems mouse */
|
#define MOUSE_TYPE_MSYSTEMS 2 /* Mouse Systems mouse */
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
#define MOUSE_TYPE_PS2_MS 7 /* Microsoft Intellimouse PS/2 */
|
#define MOUSE_TYPE_PS2_MS 7 /* Microsoft Intellimouse PS/2 */
|
||||||
#define MOUSE_TYPE_AMSTRAD 8 /* Amstrad PC system mouse */
|
#define MOUSE_TYPE_AMSTRAD 8 /* Amstrad PC system mouse */
|
||||||
#define MOUSE_TYPE_OLIM24 9 /* Olivetti M24 system mouse */
|
#define MOUSE_TYPE_OLIM24 9 /* Olivetti M24 system mouse */
|
||||||
|
#define MOUSE_TYPE_INPORT 10 /* Microsoft InPort Mouse */
|
||||||
|
|
||||||
#define MOUSE_TYPE_MASK 0x0f
|
#define MOUSE_TYPE_MASK 0x0f
|
||||||
#define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */
|
#define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */
|
||||||
|
|||||||
737
src/mouse_bus.c
737
src/mouse_bus.c
@@ -42,452 +42,443 @@
|
|||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "mouse_bus.h"
|
#include "mouse_bus.h"
|
||||||
#include "plat_mouse.h"
|
#include "plat_mouse.h"
|
||||||
|
|
||||||
|
#define BUS_MOUSE_IRQ 5
|
||||||
|
#define IRQ_MASK ((1<<5) >> BUS_MOUSE_IRQ)
|
||||||
|
|
||||||
#define ENABLE_3BTN 1 /* enable 3-button mode */
|
// MS Inport Bus Mouse Adapter
|
||||||
|
#define INP_PORT_CONTROL 0x023C
|
||||||
|
#define INP_PORT_DATA 0x023D
|
||||||
|
#define INP_PORT_SIGNATURE 0x023E
|
||||||
|
#define INP_PORT_CONFIG 0x023F
|
||||||
|
|
||||||
|
#define INP_CTRL_READ_BUTTONS 0x00
|
||||||
|
#define INP_CTRL_READ_X 0x01
|
||||||
|
#define INP_CTRL_READ_Y 0x02
|
||||||
|
#define INP_CTRL_COMMAND 0x07
|
||||||
|
#define INP_CTRL_RAISE_IRQ 0x16
|
||||||
|
#define INP_CTRL_RESET 0x80
|
||||||
|
|
||||||
/* Register definitions for Logitech mode. */
|
#define INP_HOLD_COUNTER (1 << 5)
|
||||||
#define LTMOUSE_DATA 0 /* DATA register */
|
#define INP_ENABLE_IRQ (1 << 0)
|
||||||
#define LTMOUSE_MAGIC 1 /* signature magic register */
|
|
||||||
# define MAGIC_BYTE1 0xa5 /* most drivers use this */
|
|
||||||
# define MAGIC_BYTE2 0x5a /* some drivers use this */
|
|
||||||
#define LTMOUSE_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 CTRL_DFLT (CTRL_IDIS)
|
|
||||||
#define LTMOUSE_CONFIG 3 /* CONFIG register */
|
|
||||||
# define CONFIG_DFLT 0x91 /* 8255 controller config */
|
|
||||||
|
|
||||||
/* Register definitions for Microsoft mode. */
|
// MS/Logictech Standard Bus Mouse Adapter
|
||||||
#define MSMOUSE_CTRL 0 /* CTRL register */
|
#define BUSM_PORT_DATA 0x023C
|
||||||
# define MSCTRL_RESET 0x80
|
#define BUSM_PORT_SIGNATURE 0x023D
|
||||||
# define MSCTRL_MODE 0x07
|
#define BUSM_PORT_CONTROL 0x023E
|
||||||
# define MSCTRL_RD_Y 0x02
|
#define BUSM_PORT_CONFIG 0x023F
|
||||||
# define MSCTRL_RD_X 0x01
|
|
||||||
# define MSCTRL_RD_BUT 0x00
|
#define HOLD_COUNTER (1 << 7)
|
||||||
#define MSMOUSE_DATA 1 /* DATA register */
|
#define READ_X (0 << 6)
|
||||||
# define MSDATA_BASE 0x10
|
#define READ_Y (1 << 6)
|
||||||
# define MSDATA_IRQ 0x01
|
#define READ_LOW (0 << 5)
|
||||||
#define MSMOUSE_MAGIC 2 /* MAGIC register */
|
#define READ_HIGH (1 << 5)
|
||||||
# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */
|
#define DISABLE_IRQ (1 << 4)
|
||||||
# define MAGIC_MSBYTE2 0xad
|
|
||||||
#define MSMOUSE_CONFIG 3 /* CONFIG register */
|
#define READ_X_LOW (READ_X | READ_LOW)
|
||||||
|
#define READ_X_HIGH (READ_X | READ_HIGH)
|
||||||
|
#define READ_Y_LOW (READ_Y | READ_LOW)
|
||||||
|
#define READ_Y_HIGH (READ_Y | READ_HIGH)
|
||||||
|
|
||||||
|
|
||||||
/* Our mouse device. */
|
/* Our mouse device. */
|
||||||
typedef struct {
|
typedef struct mouse_bus_t
|
||||||
uint16_t port; /* I/O port range start */
|
{
|
||||||
uint16_t portlen; /* length of I/O port range */
|
int irq;
|
||||||
int8_t irq; /* IRQ channel to use */
|
int timer_index;
|
||||||
uint8_t flags; /* device flags */
|
int x_delay;
|
||||||
|
int y_delay;
|
||||||
uint8_t r_magic; /* MAGIC register */
|
uint8_t mouse_buttons;
|
||||||
uint8_t r_ctrl; /* CONTROL register (WR) */
|
uint8_t mouse_buttons_last;
|
||||||
uint8_t r_intr; /* INTSTAT register (RO) */
|
uint8_t x, y, but;
|
||||||
uint8_t r_conf; /* CONFIG register */
|
uint8_t command_val;
|
||||||
|
uint8_t control_val;
|
||||||
int8_t x, y; /* current mouse status */
|
uint8_t config_val;
|
||||||
uint8_t but;
|
uint8_t sig_val;
|
||||||
|
uint16_t toggle_counter;
|
||||||
|
int interrupts;
|
||||||
|
int is_inport;
|
||||||
} mouse_bus_t;
|
} mouse_bus_t;
|
||||||
#define MOUSE_ENABLED 0x80 /* device is enabled for use */
|
|
||||||
#define MOUSE_LOGITECH 0x40 /* running in Logitech mode */
|
|
||||||
#define MOUSE_MICROSOFT 0x20 /* running in Microsoft mode */
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle a WRITE to a Microsoft-mode register. */
|
|
||||||
static void
|
|
||||||
ms_write(mouse_bus_t *ms, uint16_t port, uint8_t val)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
pclog("BUSMOUSE: ms_write(%d,%02x)\n", port, val);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (port) {
|
|
||||||
case MSMOUSE_CTRL: /* [00] control register */
|
|
||||||
if (val & MSCTRL_RESET) {
|
|
||||||
/* Reset the interface. */
|
|
||||||
ms->r_magic = MAGIC_MSBYTE1;
|
|
||||||
ms->r_conf = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save new register value. */
|
|
||||||
ms->r_ctrl = val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSMOUSE_DATA: /* [01] data register */
|
|
||||||
if (ms->r_ctrl == MSCTRL_MODE) {
|
|
||||||
ms->r_conf = val;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSMOUSE_MAGIC: /* [02] magic data register */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSMOUSE_CONFIG: /* [03] config register */
|
|
||||||
ms->r_conf = val;
|
|
||||||
ms->flags &= ~MOUSE_MICROSOFT;
|
|
||||||
ms->flags |= MOUSE_LOGITECH;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle a WRITE to a LOGITECH-mode register. */
|
|
||||||
static void
|
|
||||||
lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val)
|
|
||||||
{
|
|
||||||
uint8_t b = (ms->r_ctrl ^ val);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
pclog("BUSMOUSE: lt_write(%d,%02x)\n", port, val);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (port) {
|
|
||||||
case LTMOUSE_DATA: /* [00] data register */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LTMOUSE_MAGIC: /* [01] magic data register */
|
|
||||||
if (val == MAGIC_BYTE1 || val == MAGIC_BYTE2) {
|
|
||||||
ms->flags |= MOUSE_LOGITECH;
|
|
||||||
ms->r_magic = val;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LTMOUSE_CTRL: /* [02] control register */
|
|
||||||
if (b & CTRL_FREEZE) {
|
|
||||||
/* Hold the sampling while we do something. */
|
|
||||||
if (! (val & CTRL_FREEZE)) {
|
|
||||||
/* Reset current state. */
|
|
||||||
ms->x = ms->y = 0;
|
|
||||||
if (ms->but)
|
|
||||||
/* One more POLL for button-release. */
|
|
||||||
ms->but = 0x80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b & CTRL_IDIS) {
|
|
||||||
/* Disable or enable interrupts. */
|
|
||||||
/* (we don't do anything for that here..) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save new register value. */
|
|
||||||
ms->r_ctrl = val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LTMOUSE_CONFIG: /* [03] config register */
|
|
||||||
ms->r_conf = val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle a WRITE operation to one of our registers. */
|
/* Handle a WRITE operation to one of our registers. */
|
||||||
static void
|
static void busmouse_write(uint16_t port, uint8_t val, void *priv)
|
||||||
bm_write(uint16_t port, uint8_t val, void *priv)
|
|
||||||
{
|
{
|
||||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
||||||
|
|
||||||
if (ms->flags & MOUSE_LOGITECH)
|
switch (port)
|
||||||
lt_write(ms, port - ms->port, val);
|
{
|
||||||
|
case BUSM_PORT_CONTROL:
|
||||||
if (ms->flags & MOUSE_MICROSOFT)
|
busmouse->control_val = val | 0x0f;
|
||||||
ms_write(ms, port - ms->port, val);
|
busmouse->interrupts = (val & DISABLE_IRQ) == 0;
|
||||||
}
|
picintc(1 << busmouse->irq);
|
||||||
|
|
||||||
|
|
||||||
/* Handle a READ from a Microsoft-mode register. */
|
|
||||||
static uint8_t
|
|
||||||
ms_read(mouse_bus_t *ms, uint16_t port)
|
|
||||||
{
|
|
||||||
uint8_t r = 0xff;
|
|
||||||
|
|
||||||
switch (port) {
|
|
||||||
case MSMOUSE_CTRL: /* [00] control register */
|
|
||||||
r = ms->r_ctrl;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSMOUSE_DATA: /* [01] data register */
|
case BUSM_PORT_CONFIG:
|
||||||
|
busmouse->config_val = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSMOUSE_MAGIC: /* [02] magic data register */
|
case BUSM_PORT_SIGNATURE:
|
||||||
/*
|
busmouse->sig_val = val;
|
||||||
* Drivers for the InPort controllers usually start
|
|
||||||
* by reading this register. If they find 0xDE here,
|
|
||||||
* they will continue their probe, otherwise no go.
|
|
||||||
*/
|
|
||||||
r = ms->r_magic;
|
|
||||||
|
|
||||||
/* For the InPort, switch magic bytes. */
|
|
||||||
if (ms->r_magic == MAGIC_MSBYTE1)
|
|
||||||
ms->r_magic = MAGIC_MSBYTE2;
|
|
||||||
else
|
|
||||||
ms->r_magic = MAGIC_MSBYTE1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSMOUSE_CONFIG: /* [03] config register */
|
case BUSM_PORT_DATA:
|
||||||
r = ms->r_conf;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
pclog("BUSMOUSE: ms_read(%d): %02x\n", port, r);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle a READ from a LOGITECH-mode register. */
|
|
||||||
static uint8_t
|
|
||||||
lt_read(mouse_bus_t *ms, uint16_t port)
|
|
||||||
{
|
|
||||||
uint8_t r = 0xff;
|
|
||||||
|
|
||||||
switch (port) {
|
|
||||||
case LTMOUSE_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);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTRL_RD_X_HI: /* X, high bits */
|
|
||||||
r = (ms->x >> 4) & 0x0f;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CTRL_RD_Y_LO: /* Y, low bits */
|
|
||||||
r = (ms->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;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LTMOUSE_MAGIC: /* [01] magic data register */
|
|
||||||
/*
|
|
||||||
* Logitech drivers start out by blasting their magic
|
|
||||||
* value (0xA5) into this register, and then read it
|
|
||||||
* back to see if that worked. If it did (and we do
|
|
||||||
* support this) the controller is assumed to be a
|
|
||||||
* Logitech-protocol one, and not InPort.
|
|
||||||
*/
|
|
||||||
r = ms->r_magic;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LTMOUSE_CTRL: /* [02] control register */
|
|
||||||
/*
|
|
||||||
* This is the weird stuff mentioned in the file header
|
|
||||||
* above. Microsoft's "mouse.exe" does some whacky stuff
|
|
||||||
* to extract the configured IRQ channel from the board.
|
|
||||||
*
|
|
||||||
* First, it reads the current value, and then re-reads
|
|
||||||
* it another 10,000 (yes, really) times. It keeps track
|
|
||||||
* of whether or not the data has changed, most likely
|
|
||||||
* to de-bounce reading of a DIP switch for example. This
|
|
||||||
* first value is assumed to be the 2's complement of the
|
|
||||||
* actual IRQ value.
|
|
||||||
* Next, it does this a second time, but now with the
|
|
||||||
* IDIS bit clear (so, interrupts enabled), which is
|
|
||||||
* our cue to return the regular (not complemented) value
|
|
||||||
* to them.
|
|
||||||
*
|
|
||||||
* Since we have to fake the initial value and the settling
|
|
||||||
* of the data a bit later on, we first return a bunch of
|
|
||||||
* invalid ("random") data, and then the real value.
|
|
||||||
*
|
|
||||||
* Yes, this is weird. --FvK
|
|
||||||
*/
|
|
||||||
if (ms->r_intr++ < 250)
|
|
||||||
/* Still settling, return invalid data. */
|
|
||||||
r = (ms->r_ctrl&CTRL_IDIS)?0xff:0x00;
|
|
||||||
else {
|
|
||||||
/* OK, all good, return correct data. */
|
|
||||||
r = (ms->r_ctrl&CTRL_IDIS)?-ms->irq:ms->irq;
|
|
||||||
ms->r_intr = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LTMOUSE_CONFIG: /* [03] config register */
|
|
||||||
r = ms->r_conf;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
pclog("BUSMOUSE: lt_read(%d): %02x\n", port, r);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Handle a READ operation from one of our registers. */
|
/* Handle a READ operation from one of our registers. */
|
||||||
static uint8_t
|
static uint8_t busmouse_read(uint16_t port, void *priv)
|
||||||
bm_read(uint16_t port, void *priv)
|
|
||||||
{
|
{
|
||||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
||||||
uint8_t r = 0xff;
|
uint8_t r = 0;
|
||||||
|
|
||||||
if (ms->flags & MOUSE_LOGITECH)
|
switch (port)
|
||||||
r = lt_read(ms, port - ms->port);
|
{
|
||||||
|
case BUSM_PORT_CONTROL:
|
||||||
|
r = busmouse->control_val;
|
||||||
|
/* This is to allow the driver to see which IRQ the card has "jumpered"
|
||||||
|
only happens if IRQ's are enabled */
|
||||||
|
busmouse->control_val |= 0x0f;
|
||||||
|
|
||||||
if (ms->flags & MOUSE_MICROSOFT)
|
busmouse->control_val &= ~IRQ_MASK;
|
||||||
r = ms_read(ms, port - ms->port);
|
busmouse->toggle_counter = (busmouse->toggle_counter + 1) & 0x7ff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BUSM_PORT_DATA:
|
||||||
|
switch (busmouse->control_val & 0x60)
|
||||||
|
{
|
||||||
|
case READ_X_LOW:
|
||||||
|
r = busmouse->x & 0x0f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ_X_HIGH:
|
||||||
|
r = (busmouse->x >> 4) & 0x0f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ_Y_LOW:
|
||||||
|
r = busmouse->y & 0x0f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ_Y_HIGH:
|
||||||
|
r = ((busmouse->but ^ 7) << 5) | ((busmouse->y >> 4) & 0x0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BUSM_PORT_CONFIG:
|
||||||
|
r = busmouse->config_val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BUSM_PORT_SIGNATURE:
|
||||||
|
r = busmouse->sig_val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void inport_write(uint16_t port, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
mouse_bus_t *inport = (mouse_bus_t *)priv;
|
||||||
|
|
||||||
|
switch (port)
|
||||||
|
{
|
||||||
|
case INP_PORT_CONTROL:
|
||||||
|
switch (val)
|
||||||
|
{
|
||||||
|
case INP_CTRL_RESET:
|
||||||
|
inport->control_val = 0;
|
||||||
|
inport->command_val = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_CTRL_COMMAND:
|
||||||
|
case INP_CTRL_READ_BUTTONS:
|
||||||
|
case INP_CTRL_READ_X:
|
||||||
|
case INP_CTRL_READ_Y:
|
||||||
|
inport->command_val = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x87:
|
||||||
|
inport->control_val = 0;
|
||||||
|
inport->command_val = 0x07;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_PORT_DATA:
|
||||||
|
picintc(1 << inport->irq);
|
||||||
|
if (val == INP_CTRL_RAISE_IRQ)
|
||||||
|
{
|
||||||
|
picint(1 << inport->irq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (inport->command_val)
|
||||||
|
{
|
||||||
|
case INP_CTRL_COMMAND:
|
||||||
|
inport->control_val = val;
|
||||||
|
inport->interrupts = (val & INP_ENABLE_IRQ) > 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_PORT_SIGNATURE:
|
||||||
|
case INP_PORT_CONFIG:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t inport_read(uint16_t port, void *priv)
|
||||||
|
{
|
||||||
|
mouse_bus_t *inport = (mouse_bus_t *)priv;
|
||||||
|
uint8_t r = 0;
|
||||||
|
|
||||||
|
switch (port)
|
||||||
|
{
|
||||||
|
case INP_PORT_CONTROL:
|
||||||
|
r = inport->control_val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_PORT_DATA:
|
||||||
|
switch (inport->command_val)
|
||||||
|
{
|
||||||
|
case INP_CTRL_READ_BUTTONS:
|
||||||
|
r = inport->but;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_CTRL_READ_X:
|
||||||
|
r = inport->x;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_CTRL_READ_Y:
|
||||||
|
r = inport->y;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_CTRL_COMMAND:
|
||||||
|
r = inport->control_val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_PORT_SIGNATURE:
|
||||||
|
if (!inport->toggle_counter)
|
||||||
|
{
|
||||||
|
r = 0xde;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = 0x12;
|
||||||
|
}
|
||||||
|
inport->toggle_counter ^= 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INP_PORT_CONFIG:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called at 30hz */
|
||||||
|
void busmouse_timer_handler(void *priv)
|
||||||
|
{
|
||||||
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
||||||
|
|
||||||
|
busmouse->timer_index += ((1000000.0 / 30.0) * TIMER_USEC);
|
||||||
|
|
||||||
|
/* The controller updates the data on every interrupt
|
||||||
|
We just don't copy it to the current_X if the 'hold' bit is set */
|
||||||
|
busmouse_update_mouse_data(busmouse);
|
||||||
|
}
|
||||||
|
|
||||||
/* The emulator calls us with an update on the host mouse device. */
|
/* The emulator calls us with an update on the host mouse device. */
|
||||||
static uint8_t
|
static uint8_t busmouse_poll(int x, int y, int z, int b, void *priv)
|
||||||
bm_poll(int x, int y, int z, int b, void *priv)
|
|
||||||
{
|
{
|
||||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
||||||
|
|
||||||
/* Return early if nothing to do. */
|
/* Return early if nothing to do. */
|
||||||
if (!x && !y && !z && (ms->but == b)) return(1);
|
if (!x && !y && !z && (busmouse->mouse_buttons == b)) return(1);
|
||||||
|
|
||||||
/* If we are not interested, return. */
|
#if 1
|
||||||
if (!(ms->flags & MOUSE_ENABLED) ||
|
|
||||||
(ms->r_ctrl & CTRL_FREEZE)) return(0);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b);
|
pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Add the delta to our state. */
|
// scale down the motion
|
||||||
x += ms->x;
|
if ((x < -1) || (x > 1))
|
||||||
if (x > 127)
|
x /= 2;
|
||||||
x = 127;
|
if ((y < -1) || (y > 1))
|
||||||
if (x < -128)
|
y /= 2;
|
||||||
x = -128;
|
|
||||||
ms->x = (int8_t)x;
|
|
||||||
|
|
||||||
y += ms->y;
|
if (x > 127) x =127;
|
||||||
if (y > 127)
|
if (y > 127) y =127;
|
||||||
y = 127;
|
if (x < -128) x = -128;
|
||||||
if (y < -128)
|
if (y < -128) y = -128;
|
||||||
y = -128;
|
|
||||||
ms->y = (int8_t)y;
|
|
||||||
|
|
||||||
ms->but = b;
|
busmouse->x_delay += x;
|
||||||
|
busmouse->y_delay += y;
|
||||||
|
|
||||||
/* All set, generate an interrupt. */
|
busmouse->mouse_buttons = (uint8_t)(((b & 1) << 2) |
|
||||||
if (! (ms->r_ctrl & CTRL_IDIS))
|
((b & 4) >> 1) | ((b & 2) >> 1));
|
||||||
picint(1 << ms->irq);
|
|
||||||
|
if (busmouse->is_inport)
|
||||||
|
{
|
||||||
|
if ((busmouse->mouse_buttons & (1<<2)) ||
|
||||||
|
((busmouse->mouse_buttons_last & (1<<2)) && !(busmouse->mouse_buttons & (1<<2))))
|
||||||
|
busmouse->mouse_buttons |= (1<<5);
|
||||||
|
if ((busmouse->mouse_buttons & (1<<1)) ||
|
||||||
|
((busmouse->mouse_buttons_last & (1<<1)) && !(busmouse->mouse_buttons & (1<<1))))
|
||||||
|
busmouse->mouse_buttons |= (1<<4);
|
||||||
|
if ((busmouse->mouse_buttons & (1<<0)) ||
|
||||||
|
((busmouse->mouse_buttons_last & (1<<0)) && !(busmouse->mouse_buttons & (1<<0))))
|
||||||
|
busmouse->mouse_buttons |= (1<<3);
|
||||||
|
busmouse->mouse_buttons_last = busmouse->mouse_buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if interrupts are on, fire the interrupt */
|
||||||
|
if (busmouse->interrupts)
|
||||||
|
{
|
||||||
|
picint(1 << busmouse->irq);
|
||||||
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Release all resources held by the device. */
|
/* Release all resources held by the device. */
|
||||||
static void
|
static void busmouse_close(void *priv)
|
||||||
bm_close(void *priv)
|
|
||||||
{
|
{
|
||||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
||||||
|
|
||||||
/* Release our I/O range. */
|
/* Release our I/O range. */
|
||||||
io_removehandler(ms->port, ms->portlen,
|
io_removehandler(0x023C, 0x0004, busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, busmouse);
|
||||||
bm_read, NULL, NULL, bm_write, NULL, NULL, ms);
|
|
||||||
|
|
||||||
free(ms);
|
free(busmouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the device for use by the user. */
|
/* Initialize the device for use by the user. */
|
||||||
static void *
|
static void *busmouse_init(void)
|
||||||
bm_init(void)
|
|
||||||
{
|
{
|
||||||
mouse_bus_t *ms;
|
mouse_bus_t *busmouse;
|
||||||
|
|
||||||
ms = (mouse_bus_t *)malloc(sizeof(mouse_bus_t));
|
busmouse = (mouse_bus_t *)malloc(sizeof(mouse_bus_t));
|
||||||
memset(ms, 0x00, sizeof(mouse_bus_t));
|
memset(busmouse, 0x00, sizeof(mouse_bus_t));
|
||||||
ms->port = BUSMOUSE_PORT;
|
|
||||||
ms->portlen = BUSMOUSE_PORTLEN;
|
busmouse->is_inport = 0;
|
||||||
#if BUSMOUSE_IRQ
|
busmouse->irq = BUS_MOUSE_IRQ;
|
||||||
ms->irq = BUSMOUSE_IRQ;
|
|
||||||
#else
|
|
||||||
ms->irq = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pclog("Logitech/Microsoft Bus Mouse, I/O=%04x, IRQ=%d\n",
|
|
||||||
ms->port, ms->irq);
|
|
||||||
/* Initialize registers. */
|
/* Initialize registers. */
|
||||||
ms->r_magic = MAGIC_MSBYTE1;
|
busmouse->control_val = 0x1f; /* The control port value */
|
||||||
ms->r_conf = CONFIG_DFLT;
|
busmouse->config_val = 0x0e; /* The config port value */
|
||||||
ms->r_ctrl = CTRL_DFLT;
|
|
||||||
|
|
||||||
/* Initialize with Microsoft-mode being default. */
|
/* Common. */
|
||||||
ms->flags = (MOUSE_ENABLED | MOUSE_MICROSOFT);
|
busmouse->command_val = 0;
|
||||||
|
busmouse->toggle_counter = 0;
|
||||||
|
busmouse->interrupts = 0;
|
||||||
|
|
||||||
/* Request an I/O range. */
|
/* Request an I/O range. */
|
||||||
io_sethandler(ms->port, ms->portlen,
|
io_sethandler(0x023C, 0x0004, busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, busmouse);
|
||||||
bm_read, NULL, NULL, bm_write, NULL, NULL, ms);
|
timer_add(busmouse_timer_handler, &busmouse->timer_index, TIMER_ALWAYS_ENABLED, busmouse);
|
||||||
|
|
||||||
/* Return our private data to the I/O layer. */
|
/* Return our private data to the I/O layer. */
|
||||||
return(ms);
|
return(busmouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the device for use by the user. */
|
||||||
|
static void *inport_init(void)
|
||||||
|
{
|
||||||
|
mouse_bus_t *inport;
|
||||||
|
|
||||||
mouse_t mouse_bus = {
|
inport = (mouse_bus_t *)malloc(sizeof(mouse_bus_t));
|
||||||
|
memset(inport, 0x00, sizeof(mouse_bus_t));
|
||||||
|
|
||||||
|
inport->is_inport = 1;
|
||||||
|
inport->irq = BUS_MOUSE_IRQ;
|
||||||
|
|
||||||
|
/* Initialize registers. */
|
||||||
|
inport->control_val = 0x00; /* The control port value */
|
||||||
|
inport->config_val = 0x00; /* The config port value */
|
||||||
|
|
||||||
|
/* Common. */
|
||||||
|
inport->command_val = 0;
|
||||||
|
inport->toggle_counter = 0;
|
||||||
|
inport->interrupts = 0;
|
||||||
|
|
||||||
|
/* Request an I/O range. */
|
||||||
|
io_sethandler(0x023C, 0x0004, inport_read, NULL, NULL, inport_write, NULL, NULL, inport);
|
||||||
|
timer_add(busmouse_timer_handler, &inport->timer_index, TIMER_ALWAYS_ENABLED, inport);
|
||||||
|
|
||||||
|
/* Return our private data to the I/O layer. */
|
||||||
|
return(inport);
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_t mouse_bus =
|
||||||
|
{
|
||||||
"Bus Mouse",
|
"Bus Mouse",
|
||||||
"msbus",
|
"msbus",
|
||||||
MOUSE_TYPE_BUS,
|
MOUSE_TYPE_BUS,
|
||||||
bm_init,
|
busmouse_init,
|
||||||
bm_close,
|
busmouse_close,
|
||||||
bm_poll
|
busmouse_poll
|
||||||
|
};
|
||||||
|
|
||||||
|
mouse_t mouse_inport =
|
||||||
|
{
|
||||||
|
"InPort Mouse",
|
||||||
|
"inport",
|
||||||
|
MOUSE_TYPE_INPORT,
|
||||||
|
inport_init,
|
||||||
|
busmouse_close,
|
||||||
|
busmouse_poll
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,12 +23,8 @@
|
|||||||
# define MOUSE_BUS_H
|
# define MOUSE_BUS_H
|
||||||
|
|
||||||
|
|
||||||
#define BUSMOUSE_PORT 0x023c
|
|
||||||
#define BUSMOUSE_PORTLEN 4
|
|
||||||
#define BUSMOUSE_IRQ 5
|
|
||||||
|
|
||||||
|
|
||||||
extern mouse_t mouse_bus;
|
extern mouse_t mouse_bus;
|
||||||
|
extern mouse_t mouse_inport;
|
||||||
|
|
||||||
|
|
||||||
#endif /*MOUSE_BUS_H*/
|
#endif /*MOUSE_BUS_H*/
|
||||||
|
|||||||
Reference in New Issue
Block a user