I hate the 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
j_freeman

I hate the PS/2 mouse

Post by j_freeman »

Hello. Before you get scared off because you see a relatively long code post (most likely a newbie wanting you to fix his code, right... ;)), I'd like to say I've been hacking at this for 3 days now. I've read every document and driver ever created on PS/2 mice! (Well, lately it seems I must have. ;)) I've searched through all of the big OS development message boards. After all of this, I still don't get why this driver isn't working as intended...

Please consider the following code:

Code: Select all

#include "ps2mouse.h"
#include "idt.h"
#include "gdt.h"

void PS2Mouse_Handler(void)
{
   // Print out what the auxiliary device (mouse) sent us, in decimal form.
   printf(inportb(0x60));

   // Signal EOI.
   outportb(0x20, 0x20);
}

void PS2_Write(unsigned short int port, unsigned char value)
{
   unsigned long int timeout;

   for(timeout = 0; timeout < 500000L; timeout++)
   {
      // Is the PS/2 input buffer empty?
      if((inportb(0x64) & 0x02) == 0)
      {
         // Yes, write the byte then break out of loop.
         outportb(port, value);
         break;
      }
   }
}

unsigned char PS2_Read()
{
   unsigned long int timeout;
   unsigned char status, data;

   for(timeout = 0; timeout < 50000L; timeout++)
   {
      // Read status from status register.
      status = inportb(0x64);

      // Loop until PS/2 output buffer is full.
      if((status & 0x01) != 0)
      {
         // Read data from output buffer.
         data = inportb(0x60);

         // Return data read from output buffer if
         // there's no parity error; otherwise,
         // continue to loop.
         if((status & 0xC0) == 0)
         {
            // Return data.
            return data;
         }
      }
   }

   return 0;
}

signed char Init_PS2Mouse(void)
{
   // Disable interrupts while we initialize the mouse.
   asm("cli");

   // Reset PS/2 auxiliary device.
   PS2_Write(0x64, 0xD4);
   PS2_Write(0x60, 0xFF);
   printf(PS2_Read());
   printf(PS2_Read());
   printf(PS2_Read());

   // Set the PS/2 auxiliary IBF interrupt bit
   // in the Command Byte so that we get an interrupt
   // when the mouse has information for us.
   PS2_Write(0x64, 0x60);
   PS2_Write(0x60, 0x02);

   // Enable data reporting.
   PS2_Write(0x64, 0xD4);
   PS2_Write(0x60, 0xF4);
   printf(PS2_Read());

   // Program the PS/2 auxiliary ISR.
   Set_Vector(PS2Mouse_ISR, 44, D_PRESENT + D_INT + D_DPL3);

   // Enable the PS/2 auxiliary IRQ.
   Enable_IRQ(12);

   // Re-enable interrupts.
   asm("sti");

   return 0;
}
Most routine functionality should be apparent; if there's a function you dunno what is supposed to do, please ask me.

After racking my brain trying to understand the PS/2 protocol, I managed to write this source code. It's based off of my perfectly-functioning keyboard code, so the problem shouldn't be in the basic interrupt code routines (Set_Vector, Enable_IRQ, etc.).

Now, the problem is very simple but it's driving me mad. When Init_PS2Mouse() is called by the kernel, everything goes absolutely fine. It communicates with the mouse marvelously. In case you'd like to know, the verbatim output from the function is as follows:
2501700250
If you notice the printf()'s, you'll find this is exactly what should be printed (based on the various PS/2 technical docs circulating the Web).

Once this is printed, I test the code out by clicking the left mouse button. Considering the mouse handler I set up, everything works fine when a '9' is printed to the screen. The problem is that's the last I hear from our friend, the mouse.

If you've messed around with the keyboard, you know it will only continue to fire IRQ1's when you read from port 0x60 each time. If you don't read from port 0x60 each time, it blocks future IRQs from happening. This is basically what it seems is happening in this case; what's driving me mad is the fact that I am reading from port 0x60 each time an IRQ12 fires!!

Does ANYONE see ANYTHING that would have ANYTHING to do with this code not working as intended? If so, I should owe you immense gratitude. :D

P.S. Sorry the message is so long!
Slasher

Re:I hate the PS/2 mouse

Post by Slasher »

You forgot to acknowledge the interrupt to the slave pic in your mouse ISR routine. IRQ12 is not on the MASTER PIC,its on the SLAVE PIC. So add
outportb(0xa0,0x20).
That should fix it! ;D
j_freeman

Re:I hate the PS/2 mouse

Post by j_freeman »

OMG, it works!! ;D

If I could kiss you, I would, Code Slasher! ;) Thankyou so much!!!
Post Reply