#include "ibm.h" #include "keyboard_at.h" #include "mouse.h" #include "mouse_ps2.h" #include "plat-mouse.h" int mouse_scan = 0; enum { MOUSE_STREAM, MOUSE_REMOTE, MOUSE_ECHO }; #define MOUSE_ENABLE 0x20 #define MOUSE_SCALE 0x10 static struct { int mode; uint8_t flags; uint8_t resolution; uint8_t sample_rate; uint8_t type; uint8_t command; int cd; } mouse_ps2; void mouse_ps2_write(uint8_t val) { // pclog("PS/2 Mouse: Write %02X\n", val); if (mouse_ps2.cd) { mouse_ps2.cd = 0; switch (mouse_ps2.command) { case 0xe8: /*Set mouse resolution*/ mouse_ps2.resolution = val; keyboard_at_adddata_mouse(0xfa); break; case 0xf3: /*Set sample rate*/ mouse_ps2.sample_rate = val; keyboard_at_adddata_mouse(0xfa); break; // default: // fatal("mouse_ps2 : Bad data write %02X for command %02X\n", val, mouse_ps2.command); } } else { uint8_t temp; mouse_ps2.command = val; switch (mouse_ps2.command) { case 0xe6: /*Set scaling to 1:1*/ mouse_ps2.flags &= ~MOUSE_SCALE; keyboard_at_adddata_mouse(0xfa); break; case 0xe7: /*Set scaling to 2:1*/ mouse_ps2.flags |= MOUSE_SCALE; keyboard_at_adddata_mouse(0xfa); break; case 0xe8: /*Set mouse resolution*/ mouse_ps2.cd = 1; keyboard_at_adddata_mouse(0xfa); break; case 0xe9: /*Status request*/ keyboard_at_adddata_mouse(0xfa); temp = mouse_ps2.flags; if (mouse_buttons & 1) temp |= 1; if (mouse_buttons & 2) temp |= 2; if (mouse_buttons & 4) temp |= 3; keyboard_at_adddata_mouse(temp); keyboard_at_adddata_mouse(mouse_ps2.resolution); keyboard_at_adddata_mouse(mouse_ps2.sample_rate); break; case 0xf2: /*Read ID*/ keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse(0x00); break; case 0xf3: /*Set sample rate*/ mouse_ps2.cd = 1; keyboard_at_adddata_mouse(0xfa); break; case 0xf4: /*Enable*/ mouse_ps2.flags |= MOUSE_ENABLE; keyboard_at_adddata_mouse(0xfa); break; case 0xf5: /*Disable*/ mouse_ps2.flags &= ~MOUSE_ENABLE; keyboard_at_adddata_mouse(0xfa); break; case 0xff: /*Reset*/ mouse_ps2.mode = MOUSE_STREAM; mouse_ps2.flags = 0; keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse(0xaa); keyboard_at_adddata_mouse(0x00); break; // default: // fatal("mouse_ps2 : Bad command %02X\n", val, mouse_ps2.command); } } } static int ps2_x = 0, ps2_y = 0, ps2_b = 0; int first_time = 1; void mouse_ps2_poll(int x, int y, int b) { uint8_t packet[3] = {0x08, 0, 0}; if (!x && !y && b == ps2_b && !first_time){ // pclog("PS/2 Mouse: X is 0, Y is 0, and B is PS2_B\n"); return; } if (first_time) first_time = 0; if (!mouse_scan) { // pclog("PS/2 Mouse: Not scanning\n"); return; } ps2_x += x; ps2_y -= y; if (mouse_ps2.mode == MOUSE_STREAM && (mouse_ps2.flags & MOUSE_ENABLE) && ((mouse_queue_end - mouse_queue_start) & 0xf) < 13) { ps2_b = b; // pclog("Send packet : %i %i\n", ps2_x, ps2_y); if (ps2_x > 255) ps2_x = 255; if (ps2_x < -256) ps2_x = -256; if (ps2_y > 255) ps2_y = 255; if (ps2_y < -256) ps2_y = -256; if (ps2_x < 0) packet[0] |= 0x10; if (ps2_y < 0) packet[0] |= 0x20; if (mouse_buttons & 1) packet[0] |= 1; if (mouse_buttons & 2) packet[0] |= 2; if (mouse_buttons & 4) packet[0] |= 4; packet[1] = ps2_x & 0xff; packet[2] = ps2_y & 0xff; ps2_x = ps2_y = 0; keyboard_at_adddata_mouse(packet[0]); keyboard_at_adddata_mouse(packet[1]); keyboard_at_adddata_mouse(packet[2]); } // pclog("PS/2 Mouse: Poll\n"); } void mouse_ps2_init() { mouse_poll = mouse_ps2_poll; mouse_write = mouse_ps2_write; mouse_ps2.cd = 0; mouse_ps2.flags = 0; mouse_ps2.mode = MOUSE_STREAM; }