summaryrefslogtreecommitdiff
path: root/driver/mouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/mouse.c')
-rw-r--r--driver/mouse.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/driver/mouse.c b/driver/mouse.c
new file mode 100644
index 0000000..d676f45
--- /dev/null
+++ b/driver/mouse.c
@@ -0,0 +1,166 @@
+#define FOOLOS_MODULE_NAME "mouse"
+
+//http://forum.osdev.org/viewtopic.php?t=10247
+//based on Mouse.inc by SANiK
+//License: Use as you wish, except to cause damage
+
+#include "lib/logger/log.h"
+#include <stdint.h>
+
+#include "kernel/x86.h"
+
+static volatile uint8_t mouse_cycle;
+static volatile uint8_t mouse_byte[3];
+volatile int16_t mouse_x;
+volatile int16_t mouse_y;
+static volatile uint8_t mouse_a;
+
+uint8_t mouse_read();
+
+void mouse_wait(uint8_t a_type) //unsigned char
+{
+ uint32_t _time_out=100000; //unsigned int
+ if(a_type==0)
+ {
+ while(_time_out--) //Data
+ {
+ if((x86_inb(0x64) & 1)==1)
+ {
+ return;
+ }
+ }
+ return;
+ }
+ else
+ {
+ while(_time_out--) //Signal
+ {
+ if((x86_inb(0x64) & 2)==0)
+ {
+ return;
+ }
+ }
+ return;
+ }
+}
+
+void mouse_write(uint8_t a_write)
+{
+ //Wait to be able to send a command
+ mouse_wait(1);
+ //Tell the mouse we are sending a command
+ x86_outb(0x64, 0xD4);
+ //Wait for the final part
+ mouse_wait(1);
+ //Finally write
+ x86_outb(0x60, a_write);
+}
+
+int8_t mouse_get_x()
+{
+ return mouse_x;
+}
+int8_t mouse_get_y()
+{
+ return mouse_y;
+}
+
+void mouse_init()
+{
+ mouse_x=mouse_y=0;
+ mouse_cycle=0;
+
+ uint8_t _status; //unsigned char
+
+ //Enable the auxiliary mouse device
+ mouse_wait(1);
+ x86_outb(0x64, 0xA8);
+
+ //Enable the interrupts
+ mouse_wait(1);
+ x86_outb(0x64, 0x20);
+ mouse_wait(0);
+ _status=(x86_inb(0x60) | 2);
+ mouse_wait(1);
+ x86_outb(0x64, 0x60);
+ mouse_wait(1);
+ x86_outb(0x60, _status);
+
+ //Tell the mouse to use default settings
+ mouse_write(0xF6);
+ mouse_read(); //Acknowledge
+
+ //Enable the mouse
+ mouse_write(0xF4);
+ mouse_read(); //Acknowledge
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Mouse Initialized");
+}
+
+void mouse_log()
+{
+ //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%02x / %02x / %02x ",mouse_byte[0], mouse_byte[1],mouse_byte[2]);
+
+ if(mouse_byte[0]&0x80||mouse_byte[0]&0x40)return; //skip packet on overflow
+ if(!(mouse_byte[0]&0x8))panic(FOOLOS_MODULE_NAME,"mouse packets out of sync!?"); // this bit is always 1, otherwise panic!
+
+ //
+ if(mouse_byte[1]>127){
+ mouse_x-=256;
+ mouse_x+=mouse_byte[1];
+ }
+ else
+ {
+ mouse_x+=mouse_byte[1];
+ }
+ if(mouse_byte[2]>127){
+ mouse_y-=256;
+ mouse_y+=mouse_byte[2];
+ }
+ else
+ {
+ mouse_y+=mouse_byte[2];
+ }
+
+ if(mouse_x<0)mouse_x=0;
+ if(mouse_y<0)mouse_y=0;
+ if(mouse_x>800)mouse_x=800;
+ if(mouse_y>600)mouse_y=600;
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%d / %d / %02x ",mouse_x, mouse_y,mouse_byte[2]);
+ //PutFont('X', mouse_x,600-mouse_y, 0xffffff);
+
+}
+
+//Mouse functions
+void mouse_handler()//struct regs *a_r) //struct regs *a_r (not used but just there)
+{
+// X86_IRQ_BEGIN
+
+ switch(mouse_cycle)
+ {
+ case 0:
+ mouse_byte[0]=x86_inb(0x60);
+ mouse_cycle++;
+ break;
+ case 1:
+ mouse_byte[1]=x86_inb(0x60);
+ mouse_cycle++;
+ break;
+ case 2:
+ mouse_byte[2]=x86_inb(0x60);
+ mouse_cycle=0;
+ mouse_log();
+ break;
+ }
+
+// X86_IRQ_END
+}
+
+uint8_t mouse_read()
+{
+ //Get's response from mouse
+ mouse_wait(0);
+ return x86_inb(0x60);
+}
+