Page 2 of 2

Re: PS2 mouse IRQ

Posted: Sun Oct 12, 2008 3:02 pm
by Masterkiller
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? :?:

Re: PS2 mouse IRQ

Posted: Mon Oct 13, 2008 1:19 am
by bewing
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

Posted: Mon Oct 13, 2008 3:00 am
by Brendan
Hi,
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? :?:
Mostly, the entire thing is dodgy...

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
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:

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
It could be replaced by something like this:

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
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:

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

Re: PS2 mouse IRQ

Posted: Mon Oct 13, 2008 3:43 pm
by bewing
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.
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.

Re: PS2 mouse IRQ

Posted: Mon Oct 13, 2008 3:46 pm
by Masterkiller
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.

Re: PS2 mouse IRQ

Posted: Mon Oct 13, 2008 4:32 pm
by Troy Martin
What's with the meganecro? The OP probably doesn't even hang around here anymore :|

Re: PS2 mouse IRQ

Posted: Tue Oct 14, 2008 6:47 am
by bewing
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).

Re: PS2 mouse IRQ

Posted: Tue Oct 14, 2008 6:54 pm
by Troy Martin
Ah well, I'm relatively new here, don't know the preferred styles of posting etc. :?