PS/2 Mice Initialization Order
PS/2 Mice Initialization Order
Can somebody, please, tell me what commands I should send to the Keyboard controller to initialize and enable a PS/2 mouse up to the point I can receive its interrupts? Thanks in advance.
P.S: It'd be great if the ports to which the commands had to be sent and read from, could be mentioned too.
P.S: It'd be great if the ports to which the commands had to be sent and read from, could be mentioned too.
- salil_bhagurkar
- Member
- Posts: 261
- Joined: Mon Feb 19, 2007 10:40 am
- Location: India
There has been alot of people with mouse problem in the forum, so i have code a simple demo, of a working mouse driver, that does not use any OS code and is fully self contained.
Here is the fasm code and a bootable program to test it, (Note: it will run from dos, but not a dosbox under windows).
http://www.dex4u.com/tuts/MouseDemo.zip
I will add comment in the next day or two, but for now, the code is there.
PS: The demo is running in MiniDos, if you want the code let me know.
Here is the fasm code and a bootable program to test it, (Note: it will run from dos, but not a dosbox under windows).
http://www.dex4u.com/tuts/MouseDemo.zip
I will add comment in the next day or two, but for now, the code is there.
PS: The demo is running in MiniDos, if you want the code let me know.
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
Keyboard is on IRQ 1, mouse is on IRQ 12. Also, to setup the mouse you must use the keyboard controller.salil_bhagurkar wrote:Hello pcmattman i wrote the mouse and kbd code separately. Could you please tell me how i can make both of them work separately on different IRQs? (both ps2).
Could i get some code? Thanx...
Code for my mouse driver:
Code: Select all
// 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
// checks the port
void CheckPort()
{
unsigned char temp;
while( true )
{
temp = inportb( KBD_STAT );
if( ( temp & 2 ) == 0 )
break;
}
}
// waits for the ouse buffer to be full
void MouseBufferFull()
{
unsigned char temp;
while( true )
{
temp = inportb( KBD_STAT );
if( ( temp & 0x20 ) == 0 )
break;
}
}
// checks the mouse
char CheckMouse()
{
unsigned char temp;
temp = inportb( KBD_STAT );
if( temp & 1 )
return 0;
else
return 1;
}
// set the ps2 bytes
void PS2Set()
{
// mouse enabled
outportb( KBD_STAT, ENABLE_PS2 );
CheckPort();
}
// waits for the mouse
void WaitMouse()
{
outportb( KBD_STAT, MOUSE );
CheckPort();
}
// sets the streaming mode
void StartStream()
{
WaitMouse();
outportb( KBD_CMD, MOUSE_STREAM );
CheckPort();
CheckMouse();
}
// disables the keyboard
void DisableKeyboard()
{
outportb( KBD_STAT, DISABLE_KBD );
CheckPort();
}
// enables the keyboard
void EnableKeyboard()
{
outportb( KBD_STAT, ENABLE_KBD );
CheckPort();
}
// wait for the mouse - this is in the OSFAQ (http://www.osdev.org/osfaq2)
void MouseWait( char thetype )
{
long timeout = 100000;
if( thetype == 0 )
{
while( timeout-- )
{
if( inportb( 0x64 ) & 1 )
{
return;
}
}
return;
}
if( thetype == 1 )
{
while( timeout-- )
{
if( ( inportb( 0x64 ) & 2 ) == 0 )
{
return;
}
}
return;
}
}
// get a byte from the port
char GetByte()
{
MouseWait( 0 );
char ret = inportb( 0x60 );
return ret;
}
// info
int readable = 0;
// data pointer
MOUSEDATA LocalData;
// irq handler for the mouse
void MouseIRQ( struct regs* r )
{
LocalData.status = GetByte();
LocalData.xcoord = GetByte();
LocalData.ycoord = GetByte();
readable = 1;
}
// installs the IRQ
void InstallMouseIRQ()
{
// enable the irq
outportb( 0x64, 0x20 );
KeyContWaitReady();
unsigned char c = inportb( 0x60 ) | 2;
outportb( 0x64, 0x60 );
KeyContWaitReady();
outportb( 0x60, c );
// install the irq handler
irq_install_handler( 12, MouseIRQ );
}
// get data from the mouse
void GetMouseData( MOUSEDATA* data )
{
// is there data?
if( ! readable )
{
// there's no data yet, so just make no movement
*data.status = 0;
*data.xcoord = 0;
*data.ycoord = 0;
// go back to caller
return;
}
// disable interrupts
__asm__ __volatile__ ( "cli" );
// readable is false now
readable = 0;
// get the important stuff
LocalData.leftbut = LocalData.status & 1;
LocalData.rightbut = ( LocalData.status & 2 ) >> 1;
LocalData.midbut = ( LocalData.status & 4 ) >> 2;
LocalData.xsign = ( LocalData.status & 16 ) >> 4;
LocalData.ysign = ( LocalData.status & 32 ) >> 5;
LocalData.xover = ( LocalData.status & 64 ) >> 6;
LocalData.yover = ( LocalData.status & 128 ) >> 7;
// return the data
*data = LocalData;
// enable interrupts
__asm__ __volatile__ ( "sti" );
}
// init the mouse
void InitMouse()
{
PS2Set();
InstallMouseIRQ();
StartStream();
}
Code: Select all
typedef struct tagMOUSEDATA
{
char xover;
char yover;
char xsign;
char ysign;
char midbut;
char rightbut;
char leftbut;
char status;
char xcoord;
char ycoord;
} MOUSEDATA;
// init the mouse
void InitMouse();
// get data from the mouse
void GetMouseData( MOUSEDATA* data );
Code: Select all
MOUSEDATA m;
GetMouseData( &m );
MouseX += ( m.xcoord * 1 );
MouseY += ( m.xcoord * -1 );
Okey Dokey. Here is the code for initializing the PS/2 Mouse. The code is written in NASM. All procedures use the StdCall calling convention. Below is the INVOKE macro that I have written in NASM that allows you to call these procedures with the StdCall calling convention.
Every single line of the code is commented. All you have to do is to INVOKE the __SetUpMouse procedure.
Code: Select all
; --------------------------------------------------
%MACRO INVOKE 1-*
%REP %0 - 1
%ROTATE -1
PUSH DWORD %1
%ENDREP
%ROTATE -1
CALL %1
%ENDMACRO
; --------------------------------------------------
- Attachments
-
- MouseKeyboard.asm
- How to set up and initialize PS/2 Mice
- (17.12 KiB) Downloaded 177 times
Hi
I need SendMouseClick(), SetCursorPosition() functions but without using interrupts (i'm trying to do this on .NET using inpout32.dll).
As a start i was trying to read from mouse, instead of writing..
But even so i found a few problems...
Any ideas?
I need SendMouseClick(), SetCursorPosition() functions but without using interrupts (i'm trying to do this on .NET using inpout32.dll).
As a start i was trying to read from mouse, instead of writing..
But even so i found a few problems...
Code: Select all
void readMouse()
{
readMouse = !readMouse;
short ack;
short[] data = new short[10];
int i;
while (readMouse)
{
//Set mouse command: read mouse data packet
while ((Inp32(0x64) & 0x02) != 0) ; //Wait Input Buffer empty
Out32(0x64, 0xD4); // 0xD4
//Send read command to mouse
while ((Inp32(0x64) & 0x02) != 0) ; //Wait Input Buffer empty
Out32(0x60, 0xEB);
//Send GET PACK to mouse
//Wait aux data... (This loops forever... i tryed a delay instead)
while ((Inp32(0x64) & 0x21) != 0x21) ;
ack = Inp32(0x60); //should be 0xFA if OK
// I get ack=0xFE (resend) instead of 0xFA...
//Get packet of 4 bytes
if (ack == 0xFA)
{
for (i = 0; i < 4; ++i)
{
//Wait aux data, again it loops forever...
//I tryed a delay instead..
while ((Inp32(0x64) & 0x21) != 0x21) ;
data[i] = Inp32(0x60); //read next packet byte
}
if ((data[0] & 0x01) != 0) {left button pressed...}
if ((data[0] & 0x02) != 0) {right button pressed...}
}
}
}
@Nitro: if everything else was working perfectly, your code looks to me like it should work. Which means that everything else is not working perfectly. I know nothing about the .NET inpout32.dll. However, it scares me that you are reading shorts from Out32 at the bottom -- especially with that 32 in the name of both functions. Are you certain that both Inp32 and Out32 transmit BYTES only? Because if there are extra 0 value bytes being sent to port 0x60 when you do an Out32, then that will totally screw up everything.
Also, are you sure that you initialized the mouse successfully, to send 4 byte packets? You got all the proper ACKs during the process? 3 byte packets is default. Somehow, I expect that you are skipping that part -- which is OK -- but you should limit packets to 3 bytes.
Also, are you sure that there is no keyboard handler that is eating bytes from port 0x60 at the same time that you are trying to grab mouse bytes? (It seems to me that you will have no choice at all, but to integrate both drivers together.)
Also, regarding these 0xFE bytes that are coming in -- is the 0x20 bit set on the byte that you read from port 0x64? Or are the 0xFE bytes coming from the KEYBOARD?
@svdmeer: There is something called SMM that automatically translates USB mice data/commands <-> PS2 mice data/commands invisibly, for you, until you turn it off. So, yes, they start off behaving identically.
Also, are you sure that you initialized the mouse successfully, to send 4 byte packets? You got all the proper ACKs during the process? 3 byte packets is default. Somehow, I expect that you are skipping that part -- which is OK -- but you should limit packets to 3 bytes.
Also, are you sure that there is no keyboard handler that is eating bytes from port 0x60 at the same time that you are trying to grab mouse bytes? (It seems to me that you will have no choice at all, but to integrate both drivers together.)
Also, regarding these 0xFE bytes that are coming in -- is the 0x20 bit set on the byte that you read from port 0x64? Or are the 0xFE bytes coming from the KEYBOARD?
@svdmeer: There is something called SMM that automatically translates USB mice data/commands <-> PS2 mice data/commands invisibly, for you, until you turn it off. So, yes, they start off behaving identically.
I'm aware that these ports should receive bytes only.bewing wrote: I know nothing about the .NET inpout32.dll. However, it scares me that you are reading shorts from Out32 at the bottom -- especially with that 32 in the name of both functions. Are you certain that both Inp32 and Out32 transmit BYTES only? Because if there are extra 0 value bytes being sent to port 0x60 when you do an Out32, then that will totally screw up everything.
The 32 does not mean that i'm sending/receiving 32bit values, it has to do with the supported architecture.
I also managed to perfectly send keys using this DLL.
I didn't any mouse initialization, i tryed to use the mouse_install() posted above, and i got the same results, so i guess the problem isn't there.bewing wrote: Also, are you sure that you initialized the mouse successfully, to send 4 byte packets? You got all the proper ACKs during the process? 3 byte packets is default. Somehow, I expect that you are skipping that part -- which is OK -- but you should limit packets to 3 bytes.
I'm starting to think that this may be the problem... i dont have any keyboard handlers, at least i didnt included any...bewing wrote: Also, are you sure that there is no keyboard handler that is eating bytes from port 0x60 at the same time that you are trying to grab mouse bytes? (It seems to me that you will have no choice at all, but to integrate both drivers together.)
I'm running a .net 2.0 program, maybe something is screweing up the process, it seems that that every command i issue, i always receive a 0xFE reply instead of 0xFA..
I get 0x22 when reading the por 0x64, so yes 0x20 is set.bewing wrote: Also, regarding these 0xFE bytes that are coming in -- is the 0x20 bit set on the byte that you read from port 0x64? Or are the 0xFE bytes coming from the KEYBOARD?
After writting 0xD4 to the port 0x64 i should receive a 0xFA ack right?
Well again i get 0xFE... these resends probably mean that something is not letting me comunicate with the mouse.
But the critical problem seems to be here:
//Send CMD GET PACK to mouse
while ((Inp32(0x64) & 0x21) != 0x21) ; //Wait aux data
ack = Inp32(0x60);
I get 0xFE instead of 0xFA... so i'm not able to read the packets...
My mouse is connected thru USB, but i guess this is not the problem...
Btw the code i posted it's not mine i found it on other site and i don't fully understand it..
How would i write a send click/move for instance? (this is my main goal..)
EDIT: After issuing the enable mouse (0xA8) i managed to receive an ack to read the packets. Later i restarted the pc and the same code no longer worked...
My guess is that it has something to do with the mouse initialization, maybe i should not be using the streaming mode (default)?
I think you may have not read the wiki article I wrote on this:
http://www.osdev.org/wiki/Mouse_Input
No, the 0xD4 byte does not produce an ACK.
As I recall, streaming mode should work OK -- packet transmission is turned off by default. Using the Read Packet (0xEB) command should work equally well in both modes, I think.
http://www.osdev.org/wiki/Mouse_Input
No, the 0xD4 byte does not produce an ACK.
As I recall, streaming mode should work OK -- packet transmission is turned off by default. Using the Read Packet (0xEB) command should work equally well in both modes, I think.
Your goal is impossible. The mouse (and any other input device) cannot be told where to move or where to click. It senses movement and delivers that movement to the operating system (technically the mouse driver) in the form of deltas along two different axes, and click/unclick information.How would i write a send click/move for instance? (this is my main goal..)
It is up to the operating system to interpret these inputs and produce something tangible from them. You cannot tell the mouse when to write something, or what to write, and you cannot 'spoof' commands from the mouse.
Your goal is impossible.
Cheers
James