2017-05-05 01:49:42 +02:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* Implementation of Bus Mouse devices.
|
|
|
|
|
*
|
2017-05-06 17:48:33 +02:00
|
|
|
* These devices were made by both Microsoft and Logitech. At
|
|
|
|
|
* first, Microsoft used the same protocol as Logitech, but did
|
|
|
|
|
* switch to their new protocol for their InPort interface. So,
|
|
|
|
|
* although alike enough to be handled in the same driver, they
|
|
|
|
|
* are not the same.
|
2017-05-05 01:49:42 +02:00
|
|
|
*
|
2017-05-06 17:48:33 +02:00
|
|
|
* This code is based on my Minix driver for the Logitech(-mode)
|
|
|
|
|
* interface. Although that driver blindly took IRQ5, the board
|
|
|
|
|
* seems to be able to tell the driver what IRQ it is set for.
|
|
|
|
|
* When testing on MS-DOS (6.22), the 'mouse.exe' driver did not
|
|
|
|
|
* want to start, and only after disassembling it and inspecting
|
|
|
|
|
* the code it was discovered that driver actually does use the
|
|
|
|
|
* IRQ reporting feature. In a really, really weird way, too: it
|
2017-05-05 01:49:42 +02:00
|
|
|
* sets up the board, and then reads the CTRL register which is
|
|
|
|
|
* supposed to return that IRQ value. Depending on whether or
|
|
|
|
|
* not the FREEZE bit is set, it has to return either the two's
|
|
|
|
|
* complemented (negated) value, or (if clear) just the value.
|
|
|
|
|
* The mouse.com driver reads both values 10,000 times, and
|
|
|
|
|
* then makes up its mind. Maybe an effort to 'debounce' the
|
|
|
|
|
* reading of the DIP switches? Oh-well.
|
|
|
|
|
*
|
|
|
|
|
* Based on an early driver for MINIX 1.5.
|
|
|
|
|
* Based on the 86Box PS/2 mouse driver as a framework.
|
|
|
|
|
*
|
2017-07-24 18:42:29 +02:00
|
|
|
* Version: @(#)mouse_bus.c 1.0.6 2017/07/24
|
2017-05-05 01:49:42 +02:00
|
|
|
*
|
|
|
|
|
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
2017-07-24 18:42:29 +02:00
|
|
|
* TheCollector1995,
|
|
|
|
|
* Copyright 1989-2017 Fred N. van Kempen, TheCollector1995.
|
2017-05-05 01:49:42 +02:00
|
|
|
*/
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include "ibm.h"
|
|
|
|
|
#include "io.h"
|
|
|
|
|
#include "pic.h"
|
2017-07-24 16:34:56 +02:00
|
|
|
#include "timer.h"
|
2017-05-05 01:49:42 +02:00
|
|
|
#include "mouse.h"
|
|
|
|
|
#include "mouse_bus.h"
|
2017-05-18 01:57:16 -04:00
|
|
|
#include "plat_mouse.h"
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
#define BUS_MOUSE_IRQ 5
|
|
|
|
|
#define IRQ_MASK ((1<<5) >> BUS_MOUSE_IRQ)
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
// 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
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
#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
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
#define INP_HOLD_COUNTER (1 << 5)
|
|
|
|
|
#define INP_ENABLE_IRQ (1 << 0)
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
// MS/Logictech Standard Bus Mouse Adapter
|
|
|
|
|
#define BUSM_PORT_DATA 0x023C
|
|
|
|
|
#define BUSM_PORT_SIGNATURE 0x023D
|
|
|
|
|
#define BUSM_PORT_CONTROL 0x023E
|
|
|
|
|
#define BUSM_PORT_CONFIG 0x023F
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
#define HOLD_COUNTER (1 << 7)
|
|
|
|
|
#define READ_X (0 << 6)
|
|
|
|
|
#define READ_Y (1 << 6)
|
|
|
|
|
#define READ_LOW (0 << 5)
|
|
|
|
|
#define READ_HIGH (1 << 5)
|
|
|
|
|
#define DISABLE_IRQ (1 << 4)
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
#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)
|
2017-05-05 01:49:42 +02:00
|
|
|
|
|
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
/* Our mouse device. */
|
|
|
|
|
typedef struct mouse_bus_t
|
|
|
|
|
{
|
|
|
|
|
int irq;
|
|
|
|
|
int timer_index;
|
|
|
|
|
int x_delay;
|
|
|
|
|
int y_delay;
|
|
|
|
|
uint8_t mouse_buttons;
|
|
|
|
|
uint8_t mouse_buttons_last;
|
|
|
|
|
uint8_t x, y, but;
|
|
|
|
|
uint8_t command_val;
|
|
|
|
|
uint8_t control_val;
|
|
|
|
|
uint8_t config_val;
|
|
|
|
|
uint8_t sig_val;
|
|
|
|
|
uint16_t toggle_counter;
|
|
|
|
|
int interrupts;
|
|
|
|
|
int is_inport;
|
2017-05-05 01:49:42 +02:00
|
|
|
} mouse_bus_t;
|
|
|
|
|
|
|
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
/* Handle a WRITE operation to one of our registers. */
|
|
|
|
|
static void busmouse_write(uint16_t port, uint8_t val, void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-07-24 16:34:56 +02:00
|
|
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
|
|
|
|
|
|
|
|
|
switch (port)
|
|
|
|
|
{
|
|
|
|
|
case BUSM_PORT_CONTROL:
|
|
|
|
|
busmouse->control_val = val | 0x0f;
|
|
|
|
|
busmouse->interrupts = (val & DISABLE_IRQ) == 0;
|
|
|
|
|
picintc(1 << busmouse->irq);
|
2017-05-06 17:48:33 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case BUSM_PORT_CONFIG:
|
|
|
|
|
busmouse->config_val = val;
|
2017-05-06 17:48:33 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case BUSM_PORT_SIGNATURE:
|
|
|
|
|
busmouse->sig_val = val;
|
2017-05-06 17:48:33 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case BUSM_PORT_DATA:
|
2017-05-06 17:48:33 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
/* Handle a READ operation from one of our registers. */
|
|
|
|
|
static uint8_t busmouse_read(uint16_t port, void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-07-24 16:34:56 +02:00
|
|
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
|
|
|
|
uint8_t r = 0;
|
|
|
|
|
|
|
|
|
|
switch (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;
|
|
|
|
|
|
|
|
|
|
busmouse->control_val &= ~IRQ_MASK;
|
|
|
|
|
busmouse->toggle_counter = (busmouse->toggle_counter + 1) & 0x7ff;
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
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;
|
2017-05-06 17:48:33 +02:00
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case BUSM_PORT_CONFIG:
|
|
|
|
|
r = busmouse->config_val;
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case BUSM_PORT_SIGNATURE:
|
|
|
|
|
r = busmouse->sig_val;
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
return(r);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
static void inport_write(uint16_t port, uint8_t val, void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-07-24 16:34:56 +02:00
|
|
|
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;
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
default:
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case INP_PORT_SIGNATURE:
|
|
|
|
|
case INP_PORT_CONFIG:
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
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;
|
2017-07-24 20:51:06 +02:00
|
|
|
r |= 0x40;
|
2017-07-24 16:34:56 +02:00
|
|
|
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;
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case INP_PORT_SIGNATURE:
|
|
|
|
|
if (!inport->toggle_counter)
|
|
|
|
|
{
|
|
|
|
|
r = 0xde;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
r = 0x12;
|
|
|
|
|
}
|
|
|
|
|
inport->toggle_counter ^= 1;
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
case INP_PORT_CONFIG:
|
2017-05-05 01:49:42 +02:00
|
|
|
break;
|
2017-07-24 16:34:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(r);
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
void busmouse_update_mouse_data(void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-07-24 16:34:56 +02:00
|
|
|
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;
|
|
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
/* 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);
|
|
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
|
|
|
|
|
/* The emulator calls us with an update on the host mouse device. */
|
2017-07-24 16:34:56 +02:00
|
|
|
static uint8_t busmouse_poll(int x, int y, int z, int b, void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-07-24 16:34:56 +02:00
|
|
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
2017-05-05 01:49:42 +02:00
|
|
|
|
|
|
|
|
/* Return early if nothing to do. */
|
2017-07-24 16:34:56 +02:00
|
|
|
if (!x && !y && !z && (busmouse->mouse_buttons == b)) return(1);
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
#if 1
|
2017-05-06 17:48:33 +02:00
|
|
|
pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b);
|
|
|
|
|
#endif
|
2017-07-24 16:34:56 +02:00
|
|
|
|
|
|
|
|
// scale down the motion
|
|
|
|
|
if ((x < -1) || (x > 1))
|
|
|
|
|
x /= 2;
|
|
|
|
|
if ((y < -1) || (y > 1))
|
|
|
|
|
y /= 2;
|
|
|
|
|
|
|
|
|
|
if (x > 127) x =127;
|
|
|
|
|
if (y > 127) y =127;
|
|
|
|
|
if (x < -128) x = -128;
|
|
|
|
|
if (y < -128) y = -128;
|
|
|
|
|
|
|
|
|
|
busmouse->x_delay += x;
|
|
|
|
|
busmouse->y_delay += y;
|
|
|
|
|
|
|
|
|
|
busmouse->mouse_buttons = (uint8_t)(((b & 1) << 2) |
|
|
|
|
|
((b & 4) >> 1) | ((b & 2) >> 1));
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Release all resources held by the device. */
|
2017-07-24 16:34:56 +02:00
|
|
|
static void busmouse_close(void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-07-24 16:34:56 +02:00
|
|
|
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
2017-05-05 01:49:42 +02:00
|
|
|
|
|
|
|
|
/* Release our I/O range. */
|
2017-07-24 16:34:56 +02:00
|
|
|
io_removehandler(0x023C, 0x0004, busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, busmouse);
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
free(busmouse);
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize the device for use by the user. */
|
2017-07-24 16:34:56 +02:00
|
|
|
static void *busmouse_init(void)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2017-07-24 16:34:56 +02:00
|
|
|
mouse_bus_t *busmouse;
|
|
|
|
|
|
|
|
|
|
busmouse = (mouse_bus_t *)malloc(sizeof(mouse_bus_t));
|
|
|
|
|
memset(busmouse, 0x00, sizeof(mouse_bus_t));
|
|
|
|
|
|
|
|
|
|
busmouse->is_inport = 0;
|
|
|
|
|
busmouse->irq = BUS_MOUSE_IRQ;
|
|
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
/* Initialize registers. */
|
2017-07-24 16:34:56 +02:00
|
|
|
busmouse->control_val = 0x1f; /* The control port value */
|
|
|
|
|
busmouse->config_val = 0x0e; /* The config port value */
|
|
|
|
|
|
|
|
|
|
/* Common. */
|
|
|
|
|
busmouse->command_val = 0;
|
|
|
|
|
busmouse->toggle_counter = 0;
|
|
|
|
|
busmouse->interrupts = 0;
|
|
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
/* Request an I/O range. */
|
2017-07-24 16:34:56 +02:00
|
|
|
io_sethandler(0x023C, 0x0004, busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, busmouse);
|
|
|
|
|
timer_add(busmouse_timer_handler, &busmouse->timer_index, TIMER_ALWAYS_ENABLED, busmouse);
|
|
|
|
|
|
2017-05-05 01:49:42 +02:00
|
|
|
/* Return our private data to the I/O layer. */
|
2017-07-24 16:34:56 +02:00
|
|
|
return(busmouse);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize the device for use by the user. */
|
|
|
|
|
static void *inport_init(void)
|
|
|
|
|
{
|
|
|
|
|
mouse_bus_t *inport;
|
|
|
|
|
|
|
|
|
|
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);
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-24 16:34:56 +02:00
|
|
|
mouse_t mouse_bus =
|
|
|
|
|
{
|
2017-05-05 01:49:42 +02:00
|
|
|
"Bus Mouse",
|
|
|
|
|
"msbus",
|
|
|
|
|
MOUSE_TYPE_BUS,
|
2017-07-24 16:34:56 +02:00
|
|
|
busmouse_init,
|
|
|
|
|
busmouse_close,
|
|
|
|
|
busmouse_poll
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
mouse_t mouse_inport =
|
|
|
|
|
{
|
|
|
|
|
"InPort Mouse",
|
|
|
|
|
"inport",
|
|
|
|
|
MOUSE_TYPE_INPORT,
|
|
|
|
|
inport_init,
|
|
|
|
|
busmouse_close,
|
|
|
|
|
busmouse_poll
|
2017-05-05 01:49:42 +02:00
|
|
|
};
|