Problem with mouse code

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
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Problem with mouse code

Post by Prochamber »

Hey, I'm working on a hobby operating system known as TachyonOS (actually someone already took that name, so I might have to rename it...), which is a hobby operating system based on MikeOS. I have been doing some experiments with collecting mouse data so that I can create a Mouse API. This will be a simple non-interrupt driven system, i.e. the user does a call and the mouse delta values and buttons pressed are returned.

Anyway, I found this code on the MikeOS mailing lists, created by a guy known as Dan Barry at http://lists.berlios.de/pipermail/mikeo ... 03137.html. If I run this code I can detect mouse data through port 0x64 and collect it though port 0x60. I successfully created program to detect mouse delta values. However after activating the mouse I ran into the same problem as the creater, I can no longer collect keyboard data through interrupt 16h. I have debugged the code and tried several things such as disable mouse streaming and re-enabling keyboard streaming to no effect. I have read the PS/2 mouse article in the OSDev Wiki but I cannot see what the problem with the driver is.

Can anyone tell me what I am doing wrong?
If necessary I could temporarily switch to the mouse when needed and keep the keyboard running when it is not.

Here is the mouse setup code I am using:

Code: Select all

os_mouse_setup:
 call mouse_port_enable 
 call mouse_activate 
 call mouse_get_byte  ; Get the responce byte of the mouse
 ret

mouse_port_enable:
 mov  al, 0xa8   ; Enable mouse port
 out  0x64, al   ; Write to keyboardcontroller
 call keyboard_check_port ; Check if command is progressed (demand!)
 ret
 
keyboard_check_port:
 xor  cx, cx
.again:
 in   al, 0x64   ; Read from keyboardcontroller
 test al, 2   ; Check if input buffer is empty
 jz  .done
 jmp .again   ; (Demand!) This may cause hanging, use only when sure.
.done:
 ret
 
mouse_write:
 mov  al, 0xd4   ; Write to mouse device instead of to keyboard
 out  0x64, al   ; Write to keyboardcontroller
 call keyboard_check_port ; Check if command is progressed (demand!)
 ret
 
keyboard_buffer_check:
 xor  cx, cx
.mn:
 in   al, 0x64   ; Read from keyboardcontroller
 test al, 0x20   ; Check if mouse output buffer is full
 jz  .mnn
 loop .mn
.mnn:
 ret
 
mouse_activate:
 call mouse_write
 mov  al, 0xf4   ; Command to activate mouse itselve (Stream mode)
 out  0x60, al   ; Write ps/2 controller output port (activate mouse)
 call keyboard_check_port ; Check if command is progressed (demand!)
 call mouse_check  ; Check if a byte is available
 ret
 
mouse_check:
 mov  bl, 0
 xor  cx, cx
.vrd:
 in   al, 0x64   ; Read from keyboardcontroller
 test al, 1   ; Check if controller buffer (60h) has data
 jnz .yy
 loop .vrd
 mov  bl, 1
.yy:
 ret
 
keyboard_disable:
 mov  al, 0xad   ; Disable Keyboard
 out  0x64, al   ; Write to keyboardcontroller
 call keyboard_check_port ; Check if command is progressed (demand!)
 ret
 
keyboard_enable:
 mov  al, 0xae   ; Enable Keyboard
 out  0x64, al   ; Write to keyboardcontroller
 call keyboard_check_port ; Check if command is progressed (demand!)
 ret
 
mouse_get_byte:
.cagain:
 call mouse_check  ; Check if a byte is available
 or   bl, bl
 jnz .cagain
 call keyboard_disable  ; Disable keyboard to read mouse byte
 xor  ax, ax
 in   al, 0x60   ; Read ps/2 controller output port (mousebyte)
 mov  dl, al
 call keyboard_enable  ; Enable keyboard
 mov  al, dl
 ret
 
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: Problem with mouse code

Post by rdos »

I don't think it is a good idea to "busy-poll" or collect mouse/keyboard data this way. You should use two IRQs, one for mouse and one for keyboard, and let these handle the keyboard & mouse exclusively. At least I never got this to work before I did this change. On multicore, the IRQs must have spinlocks for protecting the IO-ports.

The mouse needs some default-configuration which should be done at boot-time. It is a set of command/responses that needs to be sent, and if this code fails in some way, the keyboard system should be RESET, and mouse considered as non-existing, otherwise there is a huge risk that the keyboard will no longer work afterwards.
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Problem with mouse code

Post by Prochamber »

Yea, this code doesn't really check what the response actually is.
Are you suggesting I write a driver that detects input and calls interrupts for IRQ 1 / INT 09H ? I really wanted to avoid doing this but if it is the only way I'll do it. I understand the general idea of what I need to do, i.e. checking I/O port but can you be some specific about what you want me to do?
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Problem with mouse code

Post by Prochamber »

Anyone?
How should I implement mouse support?
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Problem with mouse code

Post by gerryg400 »

You should implement mouse and keyboard support by writing proper device drivers with interrupt routines that read from the devices when an interrupt occurs.
If a trainstation is where trains stop, what is a workstation ?
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Problem with mouse code

Post by Prochamber »

Uh, yea that's what I was saying. I'm just a little unsure how to combine keyboard and mouse.

I will NOT be writing lots of unnecessary drivers through.

Would this work:
1) Save the address of the BIOS keyboard handler
2) Run the mouse activation code I used
3) Install my interrupt handler

4) When an interrupt occurs, check port 0x64
5) If bit 0 = 1 then collect and store 3 mouse bytes for port 0x60
6) If not call the original BIOS interrupt 09h handler to collect the key

This would be a very simple routine that would enable API routines to collect and check the last values, i.e. os_mouse_buttons and os_mouse_movement. I could expand upon that if necessary.

Is this feasible?
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Problem with mouse code

Post by Brendan »

Hi,
Prochamber wrote:1) Save the address of the BIOS keyboard handler
Why? BIOS keyboard handler is lame - better to just replace it too.
Prochamber wrote:4) When an interrupt occurs, check port 0x64
5) If bit 0 = 1 then collect and store 3 mouse bytes for port 0x60
6) If not call the original BIOS interrupt 09h handler to collect the key
You'd get one IRQ per byte, and there's no guarantee that you won't get one or more bytes from the keyboard in between (e.g. "mouse_byte_1, keyboard_byte, mouse_byte_2, keyboard_byte, keyboard_byte, mouse_byte_3").

When IRQ1 occurs get one byte from port 0x60 (without bothering to check anything) and send it to the driver that's using "PS/2 port 0" (if any); and when IRQ12 occurs get one byte from port 0x60 (without bothering to check anything) and send it to the driver that's using "PS/2 port 1" (if any).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Problem with mouse code

Post by Prochamber »

Brendan wrote:Hi,
Prochamber wrote:1) Save the address of the BIOS keyboard handler
Why? BIOS keyboard handler is lame - better to just replace it too.
When I have keyboard interrupts working I can worry rewriting BIOS routines.
Even then I have to create something that mirrors their functionality or it will
mess up many API calls and programs I have.
Brendan wrote:
Prochamber wrote:4) When an interrupt occurs, check port 0x64
5) If bit 0 = 1 then collect and store 3 mouse bytes for port 0x60
6) If not call the original BIOS interrupt 09h handler to collect the key
You'd get one IRQ per byte, and there's no guarantee that you won't get one or more bytes from the keyboard in between (e.g. "mouse_byte_1, keyboard_byte, mouse_byte_2, keyboard_byte, keyboard_byte, mouse_byte_3").
Well, that sucks.
Brendan wrote: When IRQ1 occurs get one byte from port 0x60 (without bothering to check anything) and send it to the driver that's using "PS/2 port 0" (if any); and when IRQ12 occurs get one byte from port 0x60 (without bothering to check anything) and send it to the driver that's using "PS/2 port 1" (if any).
Really? So I can just make the mouse driver handle interrupt 74h and not worry about the keyboard at all? Awesome, thanks!
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
Prochamber
Member
Member
Posts: 100
Joined: Wed Mar 13, 2013 2:27 am

Re: Problem with mouse code

Post by Prochamber »

I've got the mouse handler working now, thanks for your help guys!

I found out the original keyboard lockup was cause by not sending an end of interrupt to the PIC.
I tested it with an application and everything is working great!

By the way I hand translated SANiK's mouse driver (http://forum.osdev.org/viewtopic.php?t=10247) from C to NASM. Should I upload code?
TachyonOS - Violates causality on 95% of attempts. Runs at approximately 1.5c.
Post Reply