Orion
Barry Keyboard/Mouse drivers + POSIX names for structs 1628fcf (3 years, 1 month ago)
/*
* This file contains the mouse driver. It generates the /dev/mouse device
* file, which can be read and returns a structure of the mouse data.
*/
#include <sys/mouse.h>
#include "../drivers.h"
#include "../../proc/proc.h"
#include "../../io.h"
size_t mouse_read(File *file, char *buf, size_t size, off_t offset);
FileOps mouseFileOps = {
.read = mouse_read,
};
Driver mouseDriver = {
.major = 11,
.ops = &mouseFileOps,
.next = NULL,
};
unsigned char mouseCycle = 0;
char mouseByte[3], mouseX = 0, mouseY = 0;
/* Handle the mouse interrupt */
static void
mouse_handler(InterruptFrame *frame)
{
mouseByte[mouseCycle++] = inb(0x60);
if (mouseCycle < 3)
return;
mouseCycle = 0;
mouseX = mouseByte[1];
mouseY = mouseByte[2];
// kprintf("Mouse at [%d,%d]", mouseX, mouseY);
}
/* Wait on the mouse */
static inline void
mouse_io_wait(int type)
{
int time = 100000;
if (!type) {
while (time--)
if ((inb(0x64) & 1) == 1)
return;
} else {
while (time--)
if ((inb(0x64) & 2) == 0)
return;
}
}
/* Write to the mouse */
static inline void
mouse_io_write(char byte)
{
mouse_io_wait(1);
outb(0x64, 0xD4);
mouse_io_wait(1);
outb(0x60, byte);
}
/* Read from the mouse */
static inline char
mouse_io_read(void)
{
mouse_io_wait(0);
return inb(0x60);
}
/* Initialise the mouse */
void
init_mouse(void)
{
register_driver(&mouseDriver);
mknod("/dev/mouse", S_IFCHR | 0666, MKDEV(mouseDriver.major, 0));
register_interrupt(12, mouse_handler);
char status;
mouse_io_wait(1);
outb(0x64, 0xA8);
/* Enable interrupts */
mouse_io_wait(1);
outb(0x64, 0x20);
mouse_io_wait(0);
status = inb(0x60) | 2;
mouse_io_wait(1);
outb(0x64, 0x60);
mouse_io_wait(1);
outb(0x60, status);
/* Use default settings */
mouse_io_write(0xF6);
mouse_io_read();
/* Enable the mouse */
mouse_io_write(0xF4);
mouse_io_read();
}
/* Read the mouse device */
size_t
mouse_read(File *file, char *buf, size_t size, off_t offset)
{
size_t count = 0;
while (count < size) {
*(buf + count++) = mouseByte[0];
*(buf + count++) = mouseX;
*(buf + count++) = mouseY;
}
return count;
}