Mouse driver confusion
Posted: Thu Apr 29, 2010 6:34 am
I wrote this mouse driver probably 8 months ago, and it worked very well in a tty. Now I've taken the exact same code and tried to use it in video mode, and it's failing horribly.
From the output, packet1 seems to always be 0 and packet2 looks like packet one. What's wrong here? I'm mostly perplexed because it was working before.
Code: Select all
enum mouse_action
{
to_read,
to_write
};
s32 x, y, z;
bool scroll_wheel_enabled;
int mouse_cycle;
u8 packet1, packet2, packet3, packet4;
void mouse_write(u32 data)
{
mouse_wait(to_write);
outportb(0x64, 0xD4);
mouse_wait(to_write);
outportb(0x60, data);
}
u8 mouse_read()
{
mouse_wait(to_read);
return inportb(0x60);
}
void mouse_handler(regs_t *r)
{
switch(mouse_cycle)
{
case 0:
packet1 = mouse_read();
mouse_cycle++;
break;
case 1:
packet2 = mouse_read();
mouse_cycle++;
break;
case 2:
packet3 = mouse_read();
if (packet1 & 1) // left button
{
print_serial("left!\n");
}
if (packet1 & (1 << 1)) // right button
{
print_serial("right!\n");
}
if (packet1 & (1 << 2)) // middle button
{
print_serial("middle!\n");
}
print_serial("packet 1: %b\n", packet1);
print_serial("x change: %i\n", packet2);
print_serial("y change: %i\n", packet3);
if (packet1 & (1 << 4)) // sign x
x = max(0, x - (255 - (s32)packet2));
else
x = min(x+packet2, framebuffer_info.height);
if (packet1 & (1 << 5)) // sign y
y = max(0, y - (255 - (s32)packet3));
else
y = min(y+packet3, framebuffer_info.width);
if (scroll_wheel_enabled)
mouse_cycle++;
else
mouse_cycle = 0;
put_pixel(x, framebuffer_info.width - y, 0xFF0000);
packet1 = 0;
packet2 = 0;
packet3 = 0;
break;
case 3:
packet4 = mouse_read();
if ((packet4 & 0xF) == 0xF)
{
z++;
}
else if (packet4 & 1)
{
z--;
}
mouse_cycle = 0;
break;
}
}
u8 get_mouse_id()
{
mouse_write(0xF2);
u8 byte;
while((byte = mouse_read()) == 0xFA);
return byte;
}
bool enable_scroll_wheel()
{
u8 mouse_id = get_mouse_id();
mouse_write(0xF3); // set sample rate
mouse_read(/*ACK*/);
mouse_write(200); // sample rate
mouse_write(0xF3); // set sample rate
mouse_read(/*ACK*/);
mouse_write(100); // sample rate
mouse_write(0xF3); // set sample rate
mouse_read(/*ACK*/);
mouse_write(80); // sample rate
/* if our mouseID has changed, we have enabled the scroll wheel */
scroll_wheel_enabled = (mouse_id == get_mouse_id())?false:true;
return scroll_wheel_enabled;
}
void mouse_wait(int type)
{
u32 time_out = 1000;
if (type)
while (time_out--)
if (inportb(0x64) & 1) return;
else
while (time_out--)
if (!(inportb(0x64) & 2)) return;
}
void mouse_install()
{
u8 status;
// Enable the auxiliary mouse device
mouse_wait(to_write);
outportb(0x64, 0xA8);
// Enable the interrupts
mouse_wait(to_write);
outportb(0x64, 0x20);
mouse_wait(to_read);
status=(inportb(0x60) | 2);
mouse_wait(to_write);
outportb(0x64, 0x60);
mouse_wait(to_write);
outportb(0x60, status);
// Set Defaults
mouse_write(0xF6);
mouse_read(/*ACK*/);
// Disable data reporting
mouse_write(0xF5);
mouse_read(/*ACK*/);
// Enable scaling
mouse_write(0xE7);
mouse_read(/*ACK*/);
// Enable the mouse
mouse_write(0xF4);
mouse_read(/*ACK*/);
x = 0;
y = 0;
if ((scroll_wheel_enabled = enable_scroll_wheel())) z = 0;
mouse_cycle = 0;
// Setup the mouse handler
irq_install_handler(12, mouse_handler);
}