292 lines
5.7 KiB
C
292 lines
5.7 KiB
C
// Mouse.inc by SANiK
|
|
// License: Use as you wish, except to cause damage
|
|
#include "console.h"
|
|
#include "interrupts.h"
|
|
#include "io.h"
|
|
|
|
extern volatile unsigned long timer_ticks;
|
|
|
|
unsigned char mouse_cycle = 0; // unsigned char
|
|
unsigned char mouse_byte[4]; // signed char
|
|
short mouse_x = 0; // signed char
|
|
short mouse_y = 0; // signed char
|
|
char middle_btn = 0;
|
|
char left_btn = 0;
|
|
char right_btn = 0;
|
|
|
|
unsigned char mouse_type = 0;
|
|
|
|
unsigned int left_cycles_down = 0;
|
|
unsigned int right_cycles_down = 0;
|
|
unsigned int middle_cycles_down = 0;
|
|
|
|
char middle_click = 0;
|
|
char right_click = 0;
|
|
char left_click = 0;
|
|
|
|
int mouse_pos_x = 0;
|
|
int mouse_pos_y = 0;
|
|
|
|
volatile unsigned long last_ticks = 0;
|
|
|
|
extern unsigned short width;
|
|
extern unsigned short height;
|
|
|
|
int mouse_is_dragging(int btn) {
|
|
switch (btn) {
|
|
case 0:
|
|
if (left_btn == 1 && left_cycles_down > 1) {
|
|
return 1;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (right_btn == 1 && right_cycles_down > 1) {
|
|
return 1;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (middle_btn == 1 && middle_cycles_down > 1) {
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int mouse_get_click(int btn) {
|
|
int ret = 0;
|
|
switch (btn) {
|
|
case 0:
|
|
ret = left_click;
|
|
left_click = 0;
|
|
break;
|
|
case 1:
|
|
ret = right_click;
|
|
right_click = 0;
|
|
break;
|
|
case 2:
|
|
ret = middle_click;
|
|
middle_click = 0;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Mouse functions
|
|
void mouse_handler(struct regs *a_r) // struct regs *a_r (not used but just there)
|
|
{
|
|
short state;
|
|
short d;
|
|
switch (mouse_cycle) {
|
|
case 0:
|
|
mouse_byte[0] = inportb(0x60);
|
|
if (mouse_byte[0] & 0x08) {
|
|
mouse_cycle++;
|
|
}
|
|
break;
|
|
case 1:
|
|
mouse_byte[1] = inportb(0x60);
|
|
mouse_cycle++;
|
|
break;
|
|
case 2:
|
|
mouse_byte[2] = inportb(0x60);
|
|
if (mouse_byte[0] & 4) {
|
|
if (middle_btn == 1) {
|
|
middle_cycles_down += (timer_ticks - last_ticks);
|
|
}
|
|
middle_btn = 1;
|
|
} else if (middle_cycles_down < 100) {
|
|
if (middle_btn == 1) {
|
|
middle_click = 1;
|
|
}
|
|
middle_cycles_down = 0;
|
|
middle_btn = 0;
|
|
} else {
|
|
middle_cycles_down = 0;
|
|
middle_btn = 0;
|
|
}
|
|
|
|
if (mouse_byte[0] & 2) {
|
|
if (right_btn == 1) {
|
|
right_cycles_down += (timer_ticks - last_ticks);
|
|
}
|
|
right_btn = 1;
|
|
} else if (right_cycles_down < 100) {
|
|
if (right_btn == 1) {
|
|
right_click = 1;
|
|
}
|
|
right_cycles_down = 0;
|
|
right_btn = 0;
|
|
} else {
|
|
right_cycles_down = 0;
|
|
right_btn = 0;
|
|
}
|
|
|
|
if (mouse_byte[0] & 1) {
|
|
if (left_btn == 1) {
|
|
left_cycles_down += (timer_ticks - last_ticks);
|
|
}
|
|
left_btn = 1;
|
|
} else if (left_cycles_down < 100) {
|
|
if (left_btn == 1) {
|
|
left_click = 1;
|
|
}
|
|
left_cycles_down = 0;
|
|
left_btn = 0;
|
|
} else {
|
|
left_cycles_down = 0;
|
|
left_btn = 0;
|
|
}
|
|
|
|
state = mouse_byte[0];
|
|
d = mouse_byte[1];
|
|
mouse_x = d - ((state << 4) & 0x100);
|
|
d = mouse_byte[2];
|
|
mouse_y = d - ((state << 3) & 0x100);
|
|
|
|
mouse_pos_x += mouse_x;
|
|
if (mouse_pos_x > width) {
|
|
mouse_pos_x = width;
|
|
}
|
|
if (mouse_pos_x < 0) {
|
|
mouse_pos_x = 0;
|
|
}
|
|
|
|
mouse_pos_y += -mouse_y;
|
|
if (mouse_pos_y > height) {
|
|
mouse_pos_y = height;
|
|
}
|
|
if (mouse_pos_y < 0) {
|
|
mouse_pos_y = 0;
|
|
}
|
|
|
|
if (mouse_type == 0x03 || mouse_type == 0x04) {
|
|
mouse_cycle = 3;
|
|
} else {
|
|
mouse_cycle = 0;
|
|
}
|
|
last_ticks = timer_ticks;
|
|
break;
|
|
case 3:
|
|
mouse_byte[3] = inportb(0x60);
|
|
// kprintf("Byte0 0x%x X 0x%x Y 0x%x Z 0x%x\n", mouse_byte[0], mouse_byte[1], mouse_byte[2], mouse_byte[3]);
|
|
mouse_cycle = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline void mouse_wait(unsigned char a_type) // unsigned char
|
|
{
|
|
unsigned int _time_out = 100000; // unsigned int
|
|
if (a_type == 0) {
|
|
while (_time_out--) // Data
|
|
{
|
|
if ((inportb(0x64) & 1) == 1) {
|
|
return;
|
|
}
|
|
}
|
|
return;
|
|
} else {
|
|
while (_time_out--) // Signal
|
|
{
|
|
if ((inportb(0x64) & 2) == 0) {
|
|
return;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
static inline void mouse_write(unsigned char a_write) // unsigned char
|
|
{
|
|
// Wait to be able to send a command
|
|
mouse_wait(1);
|
|
// Tell the mouse we are sending a command
|
|
outportb(0x64, 0xD4);
|
|
// Wait for the final part
|
|
mouse_wait(1);
|
|
// Finally write
|
|
outportb(0x60, a_write);
|
|
}
|
|
|
|
unsigned char mouse_read() {
|
|
// Get's response from mouse
|
|
mouse_wait(0);
|
|
return inportb(0x60);
|
|
}
|
|
|
|
void mouse_sample_rate(unsigned char sample_rate) {
|
|
mouse_write(0xF3);
|
|
mouse_wait(0);
|
|
mouse_read();
|
|
mouse_write(sample_rate);
|
|
mouse_wait(0);
|
|
mouse_read();
|
|
}
|
|
|
|
void wait_for_ack() {
|
|
int timeout = 100000;
|
|
while (mouse_read() != 0xFA) {
|
|
timeout--;
|
|
if (!timeout) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void init_mouse() {
|
|
unsigned char _status; // unsigned char
|
|
|
|
last_ticks = 0;
|
|
|
|
// Enable the auxiliary mouse device
|
|
mouse_wait(1);
|
|
outportb(0x64, 0xA8);
|
|
|
|
// Enable the interrupts
|
|
mouse_wait(1);
|
|
outportb(0x64, 0x20);
|
|
mouse_wait(0);
|
|
_status = (inportb(0x60) | 2);
|
|
mouse_wait(1);
|
|
outportb(0x64, 0x60);
|
|
mouse_wait(1);
|
|
outportb(0x60, _status);
|
|
|
|
// Tell the mouse to use default settings
|
|
mouse_write(0xF6);
|
|
wait_for_ack();
|
|
|
|
mouse_write(0xF5);
|
|
wait_for_ack();
|
|
|
|
mouse_sample_rate(200);
|
|
mouse_sample_rate(100);
|
|
mouse_sample_rate(80);
|
|
|
|
mouse_write(0xF2);
|
|
wait_for_ack();
|
|
|
|
mouse_type = mouse_read();
|
|
|
|
if (mouse_type == 3) {
|
|
mouse_sample_rate(200);
|
|
mouse_sample_rate(200);
|
|
mouse_sample_rate(80);
|
|
|
|
mouse_write(0xF2);
|
|
wait_for_ack();
|
|
|
|
mouse_type = mouse_read();
|
|
}
|
|
|
|
kprintf("Mouse type 0x%x\n", mouse_type);
|
|
|
|
// Enable the mouse
|
|
mouse_write(0xF4);
|
|
wait_for_ack(); // Acknowledge
|
|
|
|
// Setup the mouse handler
|
|
irq_install_handler(12, mouse_handler, 0);
|
|
}
|