Page 1 of 1

Mouse driver confusion

Posted: Thu Apr 29, 2010 6:34 am
by xvedejas
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.

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);
}
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.

Re: Mouse driver confusion

Posted: Thu Apr 29, 2010 7:26 am
by bewing
It is easy for mouse packets to get "misaligned" -- because there is nothing standardized to align them on. I'd bet your packet scanner just got off by one byte, and it's staying that way forever after. Truly, it's a hard problem to fix.

Re: Mouse driver confusion

Posted: Thu Apr 29, 2010 11:09 am
by xvedejas
That does seem to be a problem. The wiki page on mouse drivers mentions a bit that is always on for packet alignment. Does this hold true for enough models to use it?

Re: Mouse driver confusion

Posted: Thu Apr 29, 2010 3:31 pm
by bewing
I'm afraid I don't have enough different manufacturer's/models to actually test that. I wrote the wiki article, so I can't really add much to it. I suspect that all logitech mice fail to set the bit.