Detecting PS/2 mouse

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Danyy
Posts: 16
Joined: Mon Sep 21, 2020 11:22 pm
Libera.chat IRC: Danyy

Detecting PS/2 mouse

Post by Danyy »

How can I detect a ps/2 mouse being plugged into my OS. In the wiki it states that " When a mouse is plugged into a running system it may send a 0xAA, then a 0x00 byte, and then go into default state". As far as I understand, when a device is hot-plugged into a system it is reset (?) and/or sends a 0xAA 0x00 and then resets. However I don't think an interrupt is fired because it hasn't been initialised to send packets yet. How can I detect a mouse being plugged into a system? or How can I detect if a mouse is already plugged in? so that I can initialise the mouse.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Detecting PS/2 mouse

Post by Gigasoft »

An interrupt happens for every arriving byte.
Danyy
Posts: 16
Joined: Mon Sep 21, 2020 11:22 pm
Libera.chat IRC: Danyy

Re: Detecting PS/2 mouse

Post by Danyy »

Gigasoft wrote:An interrupt happens for every arriving byte.
I am confused. Is an interrupt fired even though interrupts are disabled?
When the mouse is reset, either by applying power or with a reset command (0xFF), it always goes into the following default state:

packets disabled
emulate 3 button mouse (buttons 4, 5, and scroll wheels disabled)
3 byte packets
4 pixel/mm resolution
100 packets per second sample rate
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Detecting PS/2 mouse

Post by Octocontrabass »

Packets are disabled, not interrupts. The mouse will send the 0xAA 0x00 byte sequence, and if you've configured the PS/2 controller to raise interrupts, those bytes will cause interrupts.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Detecting PS/2 mouse

Post by BenLunt »

Danyy wrote:How can I detect a ps/2 mouse being plugged into my OS. In the wiki it states that " When a mouse is plugged into a running system it may send a 0xAA, then a 0x00 byte, and then go into default state". As far as I understand, when a device is hot-plugged into a system it is reset (?) and/or sends a 0xAA 0x00 and then resets. However I don't think an interrupt is fired because it hasn't been initialised to send packets yet. How can I detect a mouse being plugged into a system? or How can I detect if a mouse is already plugged in? so that I can initialise the mouse.
Hi,

First if I may suggest that you write three drivers; the PS2, the Mouse, and the Keyboard. This way you keep the PS2 part separate. Normally, and due to early designs, the mouse will be on the second channel. However, [ side note, we are still talking about obsolete hardware :-) ] later hardware allowed for the mouse to be plugged in to either port, same for the keyboard. You simply detected the device attached. For that matter, you could actually have two mice or two keyboards attached at the same time. Anyway, I would suggest that you keep the PS2 controller and the mouse and/or keyboard separate.

Second, if you are actually using hardware (and not emulation), if the hardware is old, hot-plugging the PS2 can actually damage the hardware. It is not recommended to plug something in to the PS2 port while power is applied. Unplugging is okay, plugging something in is not.

Anyway, you can detect if a PS2 controller is present be reading the configuration register/data. You also can/need to find out if it is an MCA type controller which will have two different types.

If you send 0xAA to the command port (64h), the controller should return 0x55 in the data port (60h). This can be one of the ways you check to see if a PS2 controller is present. Please note that this is the controller returning the 0x55, not the attached device (mouse or keyboard). This is why I suggest you keep these drivers separate.

Once you detect and configure the PS2 controller, you can then detect if it has one or both ports.

Once you have detected that each port is present, you can then detect what is actually attached by what the initialization bytes return.

For example, after resetting the device (or sending the Get ID command), the ID byte returned will be a value of zero for a standard mouse, and the first byte returned will be 0xAB for a keyboard. Please note that a keyboard may not return the ID byte(s) after a reset, so you must use the Get ID command for keyboards.

For keyboards, if it is a MCA type controller, as stated earlier, you have to get the type so that you know what scan set(s) are available. Look at bit 6 is the configuration byte for more information on figuring out what type it is. (i.e.: Try setting bit 6. If it won't set, you have one type. If it will set, you have the other type)

If you are interested, my book explains in quite detail about the PS2 controller in Chapter 5, the Keyboard in Chapter 6, and the Mouse in Chapter 7. The source code is freely available from that URL whether you purchase the book or not.

A few more notes:
1) While working with/configuring one port, you need to disable the other port. What if you are configuring the keyboard and the mouse happens to be moved? You will get a byte from the mouse packet thinking that it is a configuration byte for the keyboard.

2) A Wheel Mouse will return an ID byte of zero, and a 3-byte packet not including the wheel axis until you tell it to. Send the Set_Sample_Rate command three times in a row with a value of 200, 100, and then 80, to "turn on" the wheel part. Sending this sequence will then allow you to get the ID byte again. If the ID byte is now 3, you have a wheel mouse that will return a 4-byte packet. Sending this sequence to a non-wheel mouse will have no effect (or damage) and will return an ID byte of zero as before. No harm no foul.

3) One of the most common mistakes made by PS2 newbies is that they try to read the whole packet of data while in the interrupt handler. Please remember that you can only get one byte per interrupt. i.e.: You cannot send a command then expect a multi-byte return (or receive a movement packet), and read that multi-byte return after a single interrupt. You must keep track of where you are in the packet at every interrupt. Only one byte per interrupt. If you ever become unaware of where you are within a packet sequence, you must reset the device so that you can get to a known state.

Hope this helps,
Ben
Danyy
Posts: 16
Joined: Mon Sep 21, 2020 11:22 pm
Libera.chat IRC: Danyy

Re: Detecting PS/2 mouse

Post by Danyy »

BenLunt wrote:
Danyy wrote:How can I detect a ps/2 mouse being plugged into my OS. In the wiki it states that " When a mouse is plugged into a running system it may send a 0xAA, then a 0x00 byte, and then go into default state". As far as I understand, when a device is hot-plugged into a system it is reset (?) and/or sends a 0xAA 0x00 and then resets. However I don't think an interrupt is fired because it hasn't been initialised to send packets yet. How can I detect a mouse being plugged into a system? or How can I detect if a mouse is already plugged in? so that I can initialise the mouse.
Hi,

First if I may suggest that you write three drivers; the PS2, the Mouse, and the Keyboard. This way you keep the PS2 part separate. Normally, and due to early designs, the mouse will be on the second channel. However, [ side note, we are still talking about obsolete hardware :-) ] later hardware allowed for the mouse to be plugged in to either port, same for the keyboard. You simply detected the device attached. For that matter, you could actually have two mice or two keyboards attached at the same time. Anyway, I would suggest that you keep the PS2 controller and the mouse and/or keyboard separate.

Second, if you are actually using hardware (and not emulation), if the hardware is old, hot-plugging the PS2 can actually damage the hardware. It is not recommended to plug something in to the PS2 port while power is applied. Unplugging is okay, plugging something in is not.

Anyway, you can detect if a PS2 controller is present be reading the configuration register/data. You also can/need to find out if it is an MCA type controller which will have two different types.

If you send 0xAA to the command port (64h), the controller should return 0x55 in the data port (60h). This can be one of the ways you check to see if a PS2 controller is present. Please note that this is the controller returning the 0x55, not the attached device (mouse or keyboard). This is why I suggest you keep these drivers separate.

Once you detect and configure the PS2 controller, you can then detect if it has one or both ports.

Once you have detected that each port is present, you can then detect what is actually attached by what the initialization bytes return.

For example, after resetting the device (or sending the Get ID command), the ID byte returned will be a value of zero for a standard mouse, and the first byte returned will be 0xAB for a keyboard. Please note that a keyboard may not return the ID byte(s) after a reset, so you must use the Get ID command for keyboards.

For keyboards, if it is a MCA type controller, as stated earlier, you have to get the type so that you know what scan set(s) are available. Look at bit 6 is the configuration byte for more information on figuring out what type it is. (i.e.: Try setting bit 6. If it won't set, you have one type. If it will set, you have the other type)

If you are interested, my book explains in quite detail about the PS2 controller in Chapter 5, the Keyboard in Chapter 6, and the Mouse in Chapter 7. The source code is freely available from that URL whether you purchase the book or not.

A few more notes:
1) While working with/configuring one port, you need to disable the other port. What if you are configuring the keyboard and the mouse happens to be moved? You will get a byte from the mouse packet thinking that it is a configuration byte for the keyboard.

2) A Wheel Mouse will return an ID byte of zero, and a 3-byte packet not including the wheel axis until you tell it to. Send the Set_Sample_Rate command three times in a row with a value of 200, 100, and then 80, to "turn on" the wheel part. Sending this sequence will then allow you to get the ID byte again. If the ID byte is now 3, you have a wheel mouse that will return a 4-byte packet. Sending this sequence to a non-wheel mouse will have no effect (or damage) and will return an ID byte of zero as before. No harm no foul.

3) One of the most common mistakes made by PS2 newbies is that they try to read the whole packet of data while in the interrupt handler. Please remember that you can only get one byte per interrupt. i.e.: You cannot send a command then expect a multi-byte return (or receive a movement packet), and read that multi-byte return after a single interrupt. You must keep track of where you are in the packet at every interrupt. Only one byte per interrupt. If you ever become unaware of where you are within a packet sequence, you must reset the device so that you can get to a known state.

Hope this helps,
Ben
Thank you for your detailed answer.
Post Reply