Advertisement
Geometrian

mouse_ps2.cpp

Jul 10th, 2013
349
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.64 KB | None | 0 0
  1. #include "mouse_ps2.h"
  2.  
  3.  
  4. namespace MOSS { namespace Input { namespace Devices {
  5.  
  6.  
  7. DevicePS2Mouse::DevicePS2Mouse(ControllerPS2* controller) : DevicePS2Base(controller) {
  8.     //Note: DevicePS2Base maintains a pointer to the PS/2
  9.     //controller in the protected variable "controller".
  10.  
  11.     ASSERT(sizeof(received_data)==4,"Mouse data packet is the wrong size!");
  12.  
  13.     mouse_cycle = 0;
  14.     x = last_x = 0;
  15.     y = last_y = 0;
  16. }
  17. DevicePS2Mouse::~DevicePS2Mouse(void) {}
  18.  
  19. void DevicePS2Mouse::reset(void) {
  20.     //The mouse probably sends ACK (0xFA) plus several more bytes, then resets itself, and always sends 0xAA.
  21.     send_command_device(0xFF);
  22.  
  23.     uint8_t response;
  24.     do {
  25.         bool result = controller->recv_data(&response,10000);
  26.         ASSERT(result,"PS/2 mouse does not exist or reset failed!");
  27.     } while (response!=0xAA);
  28.  
  29.     //Tell the mouse to use default settings
  30.     //    Disables streaming, sets the packet rate to 100 per second, and resolution to 4 pixels per mm.
  31.     send_command_device(0xF6);
  32.     wait_response();
  33. }
  34.  
  35. void DevicePS2Mouse:: enable(void) {
  36.     //Enable packet streaming
  37.     send_command_device(0xF4);
  38.     wait_response();
  39. }
  40. void DevicePS2Mouse::disable(void) {
  41.     //Disable packet streaming
  42.     send_command_device(0xF5);
  43.     wait_response();
  44. }
  45.  
  46. //List of commands: http://wiki.osdev.org/Mouse_Input#Useful_Mouse_Command_Set
  47. void DevicePS2Mouse::send_command_device(uint8_t command) {
  48.     Kernel::terminal->write("Sending mouse command %d\n",command);
  49.  
  50.     //Tell the PS/2 controller that the next byte should be redirected to the second port (mouse)
  51.     controller->send_command(0xD4); //No response expected
  52.  
  53.     //Write command to PS/2 controller, which will now redirect it to the mouse
  54.     controller->send_data(command); //Caller should check for a response, iff applicable!
  55. }
  56. void DevicePS2Mouse::wait_response(uint8_t wait_byte/*=0xFA*/) {
  57.     //Called after most commands, which return 0xFA (ACK).  The only one that (might) not is the reset command.
  58.     uint8_t response;
  59.     controller->recv_data(&response);
  60.     ASSERT(response==wait_byte,"Command to mouse failed (expected %d, got %d)!",wait_byte,response);
  61. }
  62.  
  63. void DevicePS2Mouse::_handle_current_packet(void) {
  64.     //http://wiki.osdev.org/PS/2_Mouse
  65.  
  66.     if (received_data.dx_overflowed || received_data.dy_overflowed) return; //Just give up.
  67.  
  68.     int dx = (int)(received_data.dx) - (int)((received_data.byte1<<4)&0x100);
  69.     int dy = (int)(received_data.dy) - (int)((received_data.byte1<<3)&0x100);
  70.  
  71.     set_position(x+dx,y+dy);
  72. }
  73. void DevicePS2Mouse::handle_irq(void) /*override*/ {
  74.     //http://forum.osdev.org/viewtopic.php?t=10247
  75.     //http://www.computer-engineering.org/ps2mouse/
  76.  
  77.     uint8_t byte;
  78.     controller->recv_data(&byte);
  79.  
  80.     switch (mouse_cycle) {
  81.         case 0:
  82.             received_data.byte1 = byte;
  83.             ++mouse_cycle;
  84.             //if ((received_data.byte1&0x08)!=0) {
  85.             //    ++mouse_cycle; //Only accept this as the first byte if the "must be 1" bit is set
  86.             //}
  87.             break;
  88.         case 1:
  89.             received_data.byte2 = byte;
  90.             ++mouse_cycle;
  91.             break;
  92.         case 2:
  93.             received_data.byte3 = byte;
  94.             _handle_current_packet();
  95.             mouse_cycle = 0;
  96.             break;
  97.     }
  98. }
  99.  
  100. void DevicePS2Mouse::set_position(int x, int y) {
  101.     int dx = x - this->x;
  102.     int dy = y - this->y;
  103.     if (dx!=0 || dy!=0) {
  104.         last_x = this->x;
  105.         last_y = this->y;
  106.         this->x += dx;
  107.         this->y += dy;
  108.         Kernel::handle_mouse_move(Mouse::EventMove(this->x,this->y,dx,dy));
  109.     }
  110. }
  111.  
  112.  
  113. }}}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement