Page 1 of 1

Mouse Driver not working?

Posted: Sat May 12, 2007 10:35 pm
by pcmattman
I've got some serious issues with my mouse driver:

Code: Select all

// PS2 mouse driver

#include <system.h>
#include <iostream>
#include <mouse.h>

// commands for PS2
#define ENABLE_PS2			0xA8
#define KBD_STAT			0x64
#define MOUSE				0xD4
#define MOUSE_STREAM		0xF4
#define MOUSE_DISABLE		0xF5
#define KBD_CMD				0x60
#define DISABLE_KBD			0xAD
#define ENABLE_KBD			0xAE
#define SET_DEFAULTSETTINGS	0xF6
#define MOUSE_ACK			0xFA

// wait for the mouse - this is in the OSFAQ (http://www.osdev.org/osfaq2)
void MouseWait( char thetype )
{
	long timeout = 500000;
	if( thetype == 0 )
	{
		while( timeout-- )
		{
			if( ( inportb( 0x64 ) & 1 ) == 1 )
			{
				return;
			}
		}
		return;
	}
	if( thetype == 1 )
	{
		while( timeout-- )
		{
			if( ( inportb( 0x64 ) & 2 ) == 0 )
			{
				return;
			}
		}
		return;
	}
}

// writes a byte to the mouse
void mouseWrite( uchar_t b )
{
	// wait
	MouseWait( 1 );
	
	// send the command (ask for the mouse)
	outportb( 0x64, 0xD4 );
	
	// wait
	MouseWait( 1 );
	
	// send the data
	outportb( 0x60, b );
}

// gets a byte from the mouse
uchar_t mouseRead()
{
	// wait
	MouseWait( 0 );
	
	// read
	return inportb( 0x60 );
}

// first stage of initialization - enable the aux device
void EnableAuxDevice()
{
	// wait first
	MouseWait( 1 );
	
	// enable the auxillary device
	cout << "[MOUS] Enabling auxillary device on PS2... ";
	outportb( 0x64, 0xA8 );
	cout << "Done!" << endl;
}

// enables the mouse interrupt - does not install a handler!
void EnableMouseIRQ()
{
	// always wait
	MouseWait( 1 );
	
	// enable, by reading in the current data then writing it again
	cout << "[MOUS] Enabling IRQ... ";
	outportb( 0x64, 0x20 );
	MouseWait( 0 );
	uchar_t status = inportb( 0x60 ) | 2;
	MouseWait( 1 );
	outportb( 0x64, 0x60 );
	MouseWait( 1 );
	outportb( 0x60, status );
	cout << "Done!" << endl;
}

// set the default settings
void SetDefaultSettings()
{
	// send the command
	mouseWrite( SET_DEFAULTSETTINGS );
	
	// get the acknowledgement
	uchar_t ack = mouseRead();
	
	// did it ack?
	if( ack != MOUSE_ACK )
	{
		// something bad happened!
		cout << "[MOUS] Mouse didn't ack SET_DEFAULTSETTINGS" << endl;
	}
}

// enable the mouse
void MouseEnable()
{
	// write the enable command
	mouseWrite( 0xF4 );
	
	// get the acknowledgement
	uchar_t ack = mouseRead();
	
	// did it ack?
	if( ack != MOUSE_ACK )
	{
		// something bad happened!
		cout << "[MOUS] Mouse didn't ack ENABLE" << endl;
	}
}

// mouse IRQ handler
void MouseIRQ( struct regs* r )
{
	cout << "IRQ" << endl;
}

// installs the mouse IRQ handler
void InstallMouseIRQ()
{
	// IRQ12 is the mouse
	irq_install_handler( 12, MouseIRQ );
}

// initializes the mouse
void mouseInit()
{
	// enable the device
	EnableAuxDevice();
	
	// install the IRQ
	InstallMouseIRQ();
	
	// enable the IRQ
	EnableMouseIRQ();
	
	// set the defaults
	SetDefaultSettings();
	
	// enable the mouse, finally
	MouseEnable();
}
Now the MouseWait function's timeout runs out before any data is read in... If I replace 'timeout--' with 'true' MouseWait never returns!

The IRQ only fires once when the mouse moves (any other time it doesn't), when keys are pressed the irq fires!

Any ideas?

Posted: Mon May 14, 2007 1:17 am
by pcmattman
OK, I can get the proper mouse functionality in Bochs.

In QEMU, it gets up to "Enabling IRQ..." then freezes at this code:

Code: Select all

tmp = inportb( 0x64 );
if( ( tmp & 1 ) == 1 )
	return;
This works perfectly in Bochs, not at all in QEMU. Any ideas?

Edit: still, pressing keys makes it do weird things in both emulators...