I initialize mouse with reset command and keep mouseID to 0 (to ensure 3 byte packets).
Code of initialization: http://pastebin.com/f10a74ca0
Since I plan to work in unreal mode for now, I use real-mode mapped IRQ12 to Software interrupt to 0x74. Int 0x74 points to following procedure: http://pastebin.com/f4a58e18a
(Note: UnDisplayCursor() removes mouse cursor from the screen, DisplayCursor(x,y) where x and y are words displays the mouse cursor at specified position)
Everything works perfectly fine, except that mouse interrupt handler is called only once. I test the stack and no stack failure. No registers and system flags are affected by my interrupt handler and stack is OK. Where am I wrong?
PS2 mouse IRQ
- Masterkiller
- Member
- Posts: 153
- Joined: Sat May 05, 2007 6:20 pm
Re: PS2 mouse IRQ
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
Current state: real-mode kernel-FS reader...
Re: PS2 mouse IRQ
I don't see you sending an EOI to either PIC in your interrupt handler. You need to send one to each, before it will interrupt you again.
Re: PS2 mouse IRQ
Hi,
First, you don't need to save and restore registers that aren't used. You don't use most of the general registers and don't use DS or ES (as far as I can tell), so don't bother saving and restoring them. Alternatively you could set DS and use it instead of having heaps of CS segment override prefixes.
Next, the keyboard controller won't generate an IRQ 12 unless there's data ready from the mouse, and it also won't generate and IRQ 1 unless there's data ready from the keyboard. This means that the following lines should be deleted:
Next, the keyboard controller generates an IRQ for each byte, so you should get one byte per IRQ. You're trying to get 3 bytes per IRQ and probably causing a huge amount of IRQ latency while you wait for the second and third bytes to go from the mouse to the keyboard controller over a slow serial connection. Basically this code needs to be ripped out:
It could be replaced by something like this:
Note: This code is simplistic example code for demonstration purposes only. IIRC there's a bit set in the first byte that can be used for synchronization, so that you know that the first byte really is the first byte, and so that if a byte is lost somewhere you don't continually think that the second byte is the first byte and the third byte is the second byte, etc.
Next, why have you got part of a GUI wedged into your IRQ handler? The only thing the mouse IRQ handler should do is send a "mouse packet arrived" event to something. It shouldn't do anything involving mouse cursors or video - that's the GUI's job. An even better idea might be to put the raw bytes onto a FIFO, where something else can get the bytes out the other end of the FIFO and work out how to interpret the received bytes (and where even less work needs to be done in the IRQ handler). That way you could have several different pieces of code (one for each different mouse protocol) that all rely on the same "keyboard controller chip" driver.
Lastly, at the end of an IRQ handler you need to send an EOI to let the interrupt controller know you've finished handling the interrupt. In this case you need to send one EOI to the slave PIC and one EOI to the master PIC. If you don't do this then the PIC chips won't send any more IRQs for that device or for any other devices that use a lower priority IRQ. Don't add code to send the EOI to the end of the IRQ handler - use some abstraction and call a "sendEOI()" kernel function at the end of the IRQ handler instead and let the kernel can deal with the PIC chips (or the I/O APIC, if present).
After all of that, you'd end up with something like:
Cheers,
Brendan
Mostly, the entire thing is dodgy...Masterkiller wrote:Everything works perfectly fine, except that mouse interrupt handler is called only once. I test the stack and no stack failure. No registers and system flags are affected by my interrupt handler and stack is OK. Where am I wrong?
First, you don't need to save and restore registers that aren't used. You don't use most of the general registers and don't use DS or ES (as far as I can tell), so don't bother saving and restoring them. Alternatively you could set DS and use it instead of having heaps of CS segment override prefixes.
Next, the keyboard controller won't generate an IRQ 12 unless there's data ready from the mouse, and it also won't generate and IRQ 1 unless there's data ready from the keyboard. This means that the following lines should be deleted:
Code: Select all
IN al, 0x64
.checkData:
TEST al, 0x1 ;1 <data available?>
JZ .iexit
TEST al, 0x20 ;Test bit 5 <mouse data?>
JNZ .mouseDataAvailable
IN al, 0x60 ;Removing unexpected keyboard data
JMP short .checkData
Code: Select all
.mouseDataAvailable: ;Get the 3 byte packet
IN al, 0x60
MOV byte[CS:mouseDataStatus], al
CALL waitForRead
IN al, 0x60
MOV byte[CS:mouseDataX], al
CALL waitForRead
IN al, 0x60
MOV byte[CS:mouseDataY], al
Code: Select all
section .bss
mouseBuffer:
resb 3
section .data
mouseBufferPointer:
dd mouseBuffer
section .text
in al,0x60
mov edx,[mouseBufferPointer]
mov [edx],al
inc edx
cmp edx,mouseBuffer + 3
jb .done
mov edx,mouseBuffer
; *** More stuff here ***
.done:
mov [mouseBufferPointer],edx
Next, why have you got part of a GUI wedged into your IRQ handler? The only thing the mouse IRQ handler should do is send a "mouse packet arrived" event to something. It shouldn't do anything involving mouse cursors or video - that's the GUI's job. An even better idea might be to put the raw bytes onto a FIFO, where something else can get the bytes out the other end of the FIFO and work out how to interpret the received bytes (and where even less work needs to be done in the IRQ handler). That way you could have several different pieces of code (one for each different mouse protocol) that all rely on the same "keyboard controller chip" driver.
Lastly, at the end of an IRQ handler you need to send an EOI to let the interrupt controller know you've finished handling the interrupt. In this case you need to send one EOI to the slave PIC and one EOI to the master PIC. If you don't do this then the PIC chips won't send any more IRQs for that device or for any other devices that use a lower priority IRQ. Don't add code to send the EOI to the end of the IRQ handler - use some abstraction and call a "sendEOI()" kernel function at the end of the IRQ handler instead and let the kernel can deal with the PIC chips (or the I/O APIC, if present).
After all of that, you'd end up with something like:
Code: Select all
irq12:
push eax
push ebx
in al,0x60
; ** send the byte to whoever is listening here **
mov eax,KAPI_SENDEOI ;Function number for the "send the EOI" function
mov ebx,12 ;ebx = IRQ number
CALL_KERNEL_API ;Call the kernel API
pop ebx
pop eax
iret
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.
Re: PS2 mouse IRQ
Unfortunately, not all mice set the bit. I have a logitech mouse that does not. So synchronizing mouse packets cleverly needs to be part of the "smarts" that you may need to add to Brendan's simple example code.IIRC there's a bit set in the first byte that can be used for synchronization, so that you know that the first byte really is the first byte, and so that if a byte is lost somewhere you don't continually think that the second byte is the first byte and the third byte is the second byte, etc.
- Masterkiller
- Member
- Posts: 153
- Joined: Sat May 05, 2007 6:20 pm
Re: PS2 mouse IRQ
10x a lot, that would help making the mousedriver. I just need boot-time mouse for now in the most simple variant, e.g. mouseID 0. Since no multithreading I do not worry about IRQ latency, getting all three bytes of mouse data seems simpler than one by IRQ and trying to sync. But yes, for the pmode mouse driver I will follow better way. I added EOI function and everything went OK.
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
Current state: real-mode kernel-FS reader...
- Troy Martin
- Member
- Posts: 1686
- Joined: Fri Apr 18, 2008 4:40 pm
- Location: Langley, Vancouver, BC, Canada
- Contact:
Re: PS2 mouse IRQ
What's with the meganecro? The OP probably doesn't even hang around here anymore
Re: PS2 mouse IRQ
It was an on-topic question, and not just an additional pointless post. Chase has said that he prefers necromancy over creating a bazillion threads on the same topic (and I agree with him, because it makes searches work better).
- Troy Martin
- Member
- Posts: 1686
- Joined: Fri Apr 18, 2008 4:40 pm
- Location: Langley, Vancouver, BC, Canada
- Contact:
Re: PS2 mouse IRQ
Ah well, I'm relatively new here, don't know the preferred styles of posting etc.