Change license from GPLv3 to LGPLv3.
[seabios.git] / src / mouse.c
index 7a74ebad262e360690e60feaf0c0abb8db308b88..19fc6ecacb6965c607a5816822b45364e4cba895 100644 (file)
@@ -3,11 +3,11 @@
 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
 // Copyright (C) 2002  MandrakeSoft S.A.
 //
-// This file may be distributed under the terms of the GNU GPLv3 license.
+// This file may be distributed under the terms of the GNU LGPLv3 license.
 
 #include "biosvar.h" // GET_EBDA
 #include "util.h" // debug_isr
-#include "pic.h" // unmask_pic2
+#include "pic.h" // eoi_pic2
 #include "bregs.h" // struct bregs
 #include "ps2port.h" // aux_command
 
@@ -19,8 +19,7 @@ mouse_setup()
     dprintf(3, "init mouse\n");
     // pointing device installed
     SETBITS_BDA(equipment_list_flags, 0x04);
-    // Enable IRQ12 (handle_74)
-    unmask_pic2(PIC2_IRQ12);
+    enable_hwirq(12, entry_74);
 }
 
 #define RET_SUCCESS      0x00
@@ -31,12 +30,12 @@ mouse_setup()
 #define RET_ENOHANDLER   0x05
 
 static int
-disable_mouse()
+disable_mouse(u16 ebda_seg)
 {
-    u8 ps2ctr = GET_EBDA(ps2ctr);
+    u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr);
     ps2ctr |= I8042_CTR_AUXDIS;
     ps2ctr &= ~I8042_CTR_AUXINT;
-    SET_EBDA(ps2ctr, ps2ctr);
+    SET_EBDA2(ebda_seg, ps2ctr, ps2ctr);
 
     return aux_command(PSMOUSE_CMD_DISABLE, NULL);
 }
@@ -45,7 +44,8 @@ disable_mouse()
 static void
 mouse_15c20000(struct bregs *regs)
 {
-    int ret = disable_mouse();
+    u16 ebda_seg = get_ebda_seg();
+    int ret = disable_mouse(ebda_seg);
     if (ret)
         set_code_fail(regs, RET_ENEEDRESEND);
     else
@@ -56,16 +56,17 @@ mouse_15c20000(struct bregs *regs)
 static void
 mouse_15c20001(struct bregs *regs)
 {
-    u8 mouse_flags_2 = GET_EBDA(mouse_flag2);
+    u16 ebda_seg = get_ebda_seg();
+    u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
     if ((mouse_flags_2 & 0x80) == 0) {
         set_code_fail(regs, RET_ENOHANDLER);
         return;
     }
 
-    u8 ps2ctr = GET_EBDA(ps2ctr);
+    u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr);
     ps2ctr &= ~I8042_CTR_AUXDIS;
     ps2ctr |= I8042_CTR_AUXINT;
-    SET_EBDA(ps2ctr, ps2ctr);
+    SET_EBDA2(ebda_seg, ps2ctr, ps2ctr);
 
     int ret = aux_command(PSMOUSE_CMD_ENABLE, NULL);
     if (ret)
@@ -97,7 +98,7 @@ mouse_15c201(struct bregs *regs)
 {
     u8 param[2];
     int ret = aux_command(PSMOUSE_CMD_RESET_BAT, param);
-    if (ret < 0) {
+    if (ret != 0 && ret != 2) {
         set_code_fail(regs, RET_ENEEDRESEND);
         return;
     }
@@ -110,12 +111,12 @@ mouse_15c201(struct bregs *regs)
 static void
 mouse_15c202(struct bregs *regs)
 {
-    static u8 sample_rates[7] = {10, 20, 40, 60, 80, 100, 200};
+    static u8 VAR16 sample_rates[7] = {10, 20, 40, 60, 80, 100, 200};
     if (regs->bh >= ARRAY_SIZE(sample_rates)) {
         set_code_fail(regs, RET_EINVINPUT);
         return;
     }
-    u8 mouse_data1 = GET_VAR(CS, sample_rates[regs->bh]);
+    u8 mouse_data1 = GET_GLOBAL(sample_rates[regs->bh]);
     int ret = aux_command(PSMOUSE_CMD_SETRATE, &mouse_data1);
     if (ret)
         set_code_fail(regs, RET_ENEEDRESEND);
@@ -166,8 +167,9 @@ mouse_15c205(struct bregs *regs)
         set_code_fail(regs, RET_EINTERFACE);
         return;
     }
-    SET_EBDA(mouse_flag1, 0x00);
-    SET_EBDA(mouse_flag2, regs->bh);
+    u16 ebda_seg = get_ebda_seg();
+    SET_EBDA2(ebda_seg, mouse_flag1, 0x00);
+    SET_EBDA2(ebda_seg, mouse_flag2, regs->bh);
 
     // Reset Mouse
     mouse_15c201(regs);
@@ -234,19 +236,20 @@ static void
 mouse_15c207(struct bregs *regs)
 {
     u32 farptr = (regs->es << 16) | regs->bx;
-    u8 mouse_flags_2 = GET_EBDA(mouse_flag2);
+    u16 ebda_seg = get_ebda_seg();
+    u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
     if (! farptr) {
         /* remove handler */
         if ((mouse_flags_2 & 0x80) != 0) {
             mouse_flags_2 &= ~0x80;
-            disable_mouse();
+            disable_mouse(ebda_seg);
         }
     } else {
         /* install handler */
         mouse_flags_2 |= 0x80;
     }
-    SET_EBDA(mouse_flag2, mouse_flags_2);
-    SET_EBDA(far_call_pointer, farptr);
+    SET_EBDA2(ebda_seg, mouse_flag2, mouse_flags_2);
+    SET_EBDA2(ebda_seg, far_call_pointer, farptr);
     set_code_success(regs);
 }
 
@@ -282,17 +285,11 @@ handle_15c2(struct bregs *regs)
 }
 
 static void
-int74_function()
+process_mouse(u8 data)
 {
-    u8 v = inb(PORT_PS2_STATUS);
-    if ((v & 0x21) != 0x21) {
-        dprintf(1, "int74 but no mouse data.\n");
-        return;
-    }
-    v = inb(PORT_PS2_DATA);
-
-    u8 mouse_flags_1 = GET_EBDA(mouse_flag1);
-    u8 mouse_flags_2 = GET_EBDA(mouse_flag2);
+    u16 ebda_seg = get_ebda_seg();
+    u8 mouse_flags_1 = GET_EBDA2(ebda_seg, mouse_flag1);
+    u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
 
     if (! (mouse_flags_2 & 0x80))
         // far call handler not installed
@@ -300,21 +297,23 @@ int74_function()
 
     u8 package_count = mouse_flags_2 & 0x07;
     u8 index = mouse_flags_1 & 0x07;
-    SET_EBDA(mouse_data[index], v);
+    SET_EBDA2(ebda_seg, mouse_data[index], data);
 
     if ((index+1) < package_count) {
         mouse_flags_1++;
-        SET_EBDA(mouse_flag1, mouse_flags_1);
+        SET_EBDA2(ebda_seg, mouse_flag1, mouse_flags_1);
         return;
     }
 
     //BX_DEBUG_INT74("int74_function: make_farcall=1\n");
-    u16 status = GET_EBDA(mouse_data[0]);
-    u16 X      = GET_EBDA(mouse_data[1]);
-    u16 Y      = GET_EBDA(mouse_data[2]);
-    SET_EBDA(mouse_flag1, 0);
+    u16 status = GET_EBDA2(ebda_seg, mouse_data[0]);
+    u16 X      = GET_EBDA2(ebda_seg, mouse_data[1]);
+    u16 Y      = GET_EBDA2(ebda_seg, mouse_data[2]);
+    SET_EBDA2(ebda_seg, mouse_flag1, 0);
+
+    u32 func = GET_EBDA2(ebda_seg, far_call_pointer);
 
-    u32 func = GET_EBDA(far_call_pointer);
+    irq_enable();
     asm volatile(
         "pushl %0\n"
         "pushw %w1\n"  // status
@@ -324,10 +323,11 @@ int74_function()
         "lcallw *8(%%esp)\n"
         "addl $12, %%esp\n"
         "cld\n"
-        : "+a" (func), "+b" (status), "+c" (X), "+d" (Y)
         :
-        : "esi", "edi", "ebp", "cc"
+        : "r"(func), "r"(status), "r"(X), "r"(Y)
+        : "cc"
         );
+    irq_disable();
 }
 
 // INT74h : PS/2 mouse hardware interrupt
@@ -338,9 +338,15 @@ handle_74()
     if (! CONFIG_PS2_MOUSE)
         goto done;
 
-    irq_enable();
-    int74_function();
-    irq_disable();
+    u8 v = inb(PORT_PS2_STATUS);
+    if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA))
+        != (I8042_STR_OBF|I8042_STR_AUXDATA)) {
+        dprintf(1, "mouse irq but no mouse data.\n");
+        goto done;
+    }
+    v = inb(PORT_PS2_DATA);
+
+    process_mouse(v);
 
 done:
     eoi_pic2();