#include #include // sprintf #include /*D - Input/Output to Computer * D.1 - Output Clock * D.3 - Input Clock * D.6 - Output Data * D.4 - Input Data */ //define some useful maps to bits #define CLK_OUT PORTC.1 // #define DATA_OUT PORTC.6 #define CLK_IN PINC.3 #define DATA_IN PINC.4 //#define VCC_IN PINA.4 //define PS/2 data line states #define IDLE 0 #define INHIBIT 1 #define BUSY 2 #define WAIT_FOR_REQUEST 3 #define REQUEST 4 #define POWEROFF 5 // boolean defines #define TRUE 1 #define FALSE 0 unsigned char Ytilt, Xtilt, Button0, Button1, ScrollState; //ScrollState 1 => scrolling. //ScrollState 0 => button pushing. signed char Xmove, Ymove, timetemp, OldXmove, OldYmove; unsigned int time, Button0pushed, Button1pushed, ButtonTimeDiff; // byte declarations unsigned char byte_index; unsigned char transmit_byte; unsigned char transmit_parity; unsigned char receive_byte; unsigned char receive_bit; unsigned char previous_byte; unsigned char resend_byte; // clock state machine declarations unsigned char clock_state; unsigned char next_clock_state; unsigned char mouse_state; unsigned char transmit; unsigned char receive; unsigned char outInhibit, Xneg, Yneg; // mouse packet declarations unsigned char gen_mouse_packet; unsigned int count; #define RISE 0 #define HIGH 1 #define FALL 2 #define LOW 3 // queue declarations #define QUEUELEN 200 unsigned char queue[QUEUELEN]; //queue of data sent by keyboard. (first in, first out) unsigned char queueFull; //indicates if queue is full unsigned char queueEmpty;//indicates if queue is empty unsigned char queueIn; //indicates where to put data into queue unsigned char queueOut; //indicates where to take data out of queue // PS/2 Host Command set. #define ERROR 0xFC #define RESET 0xFF #define RESEND 0xFE #define SET_DEFAULT 0xF6 #define DIS_DATA_REPORT 0xF5 #define EN_DATA_REPORT 0xF4 #define SET_SAMPLE_RATE 0xF3 #define GET_DEVICE_ID 0xF2 #define SET_REMOTE_MODE 0xF0 #define SET_WRAP_MODE 0xEE #define RESET_WRAP_MODE 0xEC #define READ_DATA OxEB #define SET_STREAM_MODE 0xEA #define STATUS_REQ 0xE9 #define SET_RES 0xE8 #define SET_SCALING21 0xE7 #define SET_SCALING11 0xE6 #define ACK 0xFA #define SELF_TEST_PASS 0xAA #define INIT 0x00 #define SCALING21 0x02 // mouse declarations unsigned char deviceID; unsigned char data_reporting; unsigned char sample_rate; unsigned char scaling; // 0 = 1:1, 1 = 2:1 unsigned char resolution; unsigned char waiting_for_sample_rate; unsigned char waiting_for_resolution; // data reporting declarations unsigned char mouse_posX; unsigned char mouse_posY; signed char prev_byte1, prev_byte2, prev_byte3; unsigned char left_button_click; unsigned char middle_button_click; unsigned char right_button_click; unsigned char mouse_byte1; char scroll_byte; //RXC ISR variables unsigned char r_index; //current string index unsigned char r_buffer[32]; //input string unsigned char r_ready; //flag for receive done unsigned char r_char; //current character //TX empty ISR variables unsigned char t_index; //current string index unsigned char t_ready; //flag for transmit done unsigned char t_char; //current character unsigned char t_buffer[32]; // output string int temp; unsigned char portb_cycle; // Function prototypes void gets_string(void); //starts getting a string from serial line void puts_string(void); //starts a send to serial line void initialize(void); //all the usual mcu stuff // function prototypes unsigned char queuePut(unsigned char); unsigned char queueGet(void); unsigned char getParity(unsigned char); void process_command(unsigned char); //UART character-ready ISR interrupt [USART_RXC] void uart_rec(void) { r_char=UDR; //get a char UDR=r_char; //then print it //build the input string if (r_char != '\r') r_buffer[r_index++]=r_char; else { putchar('\n'); //use putchar to avoid overwrite r_buffer[r_index]=0x00; //zero terminate r_ready=1; //signal cmd processor UCSRB.7=0; //stop rec ISR } } //UART xmit-empty ISR interrupt [USART_DRE] void uart_send(void) { t_char = t_buffer[++t_index]; if (t_char == 0){ UCSRB.5=0; //kill isr t_ready=1; //transmit done } else UDR = t_char ; //send the char } // -- non-blocking keyboard check initializes ISR-driven // receive. This routine merely sets up the ISR, which then //does all the work of getting a command. void gets_string(void) { r_ready=0; r_index=0; UCSRB.7=1; } // -- nonblocking print: initializes ISR-driven // transmit. This routine merely sets up the ISR, then //send one character, The ISR does all the work. void puts_string(void) { t_ready=0; t_index=0; if (t_buffer[0]>0) { putchar(t_buffer[0]); UCSRB.5=1; } } // this interrupt should run every 20us or 1/4 period of the clock interrupt [TIM0_COMP] void timer0_overflow(void) { if (timetemp >= 50){ timetemp = 0; time++; } else timetemp++; if (time >= 1000) time = 0; if (queueEmpty == TRUE) count++; if (count >= 500) // 100 samples a second { gen_mouse_packet = TRUE; count = 0; } // state machine for transmitting a byte to Host if(transmit){ // update the next clock state clock_state = next_clock_state; // do the appropriate command based on the state of the clock switch (clock_state) { case RISE: // start or end a byte transmission switch (byte_index) { case 0: // get a new byte to be xmitted if (queueEmpty == FALSE) { // get data off the queue to be xmitted transmit_byte = queueGet(); transmit_parity = getParity(transmit_byte); // print out transmit byte to hyperterminal //if (gen_mouse_packet == TRUE) { // printf("TRANSMIT\n\r"); //} //printf("%x\n\r", transmit_byte); delay_us(150); // used to wait until host is ready } break; case 11: // finished transmission transmit = 0; // transmit finished byte_index = 0; // reset byte index break; default: break; } // set the new clock state CLK_OUT = 1; next_clock_state = HIGH; break; // end of RISE case HIGH: // can begin writing data to host // state machine ensure we transmit the correct bit from the PS/2 byte switch (byte_index) { case 0: DATA_OUT = 0; break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: DATA_OUT = transmit_byte & 0x01; transmit_byte = transmit_byte >> 1; break; case 9: DATA_OUT = transmit_parity; break; case 10: DATA_OUT = 1; break; default: break; } // update the byte index byte_index++; // update the clock state next_clock_state = FALL; break; // end of HIGH case FALL: // clock transitions to low CLK_OUT=0; // pull the clock to 0 next_clock_state = LOW; // set the next clock state to low break; // end of FALL case LOW: // clock is low - nothing happens here next_clock_state = RISE; // next clock state is rising break; // end of RISE } } if(receive) { // get the next clock state clock_state = next_clock_state; switch (clock_state) { case RISE: // all receiving done on the rising edge of the clock CLK_OUT = 1; // get the bit off the data line // and place into the receive_byte if (byte_index >=0 && byte_index < 8) { receive_bit = DATA_IN; receive_byte = ((receive_bit & 0x01) << byte_index) | receive_byte; } // update variables for the next state if (byte_index < 11) { next_clock_state = HIGH; byte_index++; } break; case HIGH: switch (byte_index) { case 10: DATA_OUT = 0; break; case 11: DATA_OUT = 1; // send ACK // terminate receive operation and reset receive = 0; byte_index = 0; // process the received command //PORTB.4 = 0x00; process_command(receive_byte); receive_byte = 0; receive_bit = 0; break; default: //if (byte_index == 1) // PORTB.4 = 0x0; break; } next_clock_state = FALL; break; case FALL: // hosts transmits on the falling edge CLK_OUT = 0; next_clock_state = LOW; break; case LOW: next_clock_state = RISE; //printf("BYTE: %c\n\r", byte_index); break; } } switch (mouse_state) { case IDLE: // enter inhibt state if clock is trying to be pulled // low by host when device is trying to make high if ((clock_state == HIGH || clock_state == RISE) && CLK_IN == 0) // host trying to pull CLK low! { mouse_state = INHIBIT; // go to the INHIBIT state next_clock_state = LOW; // turn off the clock transmit = 0; // mouse can no longer transmit receive = 0; // mouse can no longer receive } else { // check if mouse needs to be in BUSY state -- anything on queue? if(queueEmpty == FALSE) { mouse_state = BUSY; // transition to busy state transmit = 1; // allow mouse to transmit receive = 0; // make sure we don't receive! next_clock_state = RISE; // turn on the clock byte_index = 0; // reset the byte index for transmit } else // otherwise we should just stay in IDLE { mouse_state = IDLE; } } break; case BUSY: //PORTB.0 = 0x0; // again check if host is trying to inhibt // by pulling the clock low when it should be high if ((clock_state == HIGH || clock_state == RISE) && CLK_IN == 0) { mouse_state = INHIBIT; // go to the INHIBIT state next_clock_state = LOW; // turn off the clock transmit = 0; // mouse can no longer transmit receive = 0; // mouse can no longer receive } else { // go back to IDLE if mouse has nothing to send or receive if ( !(transmit|| receive) ) mouse_state = IDLE; else mouse_state = BUSY; // otherwise stay BUSY } break; case INHIBIT: // if we enter the INHIBIT state before we finish sending // a byte, we should save the byte & resend! if(byte_index > 0 && byte_index < 10) { resend_byte = TRUE; } // reset the byte index byte_index = 0; // check for REQUEST state // first, the host must release the CLK if (CLK_IN == 1) { mouse_state = WAIT_FOR_REQUEST; // next, we check for DATA line to go low } else { // stay in INHIBIT state mouse_state = INHIBIT; transmit = 0; receive = 0; next_clock_state = LOW; } break; case WAIT_FOR_REQUEST: // check if the data line has gone low if(DATA_IN == 0) { mouse_state = REQUEST; // go to REQUEST state next_clock_state = RISE; // turn on the clock } else { // we must be in the IDLE state because both // CLK & DATA are high mouse_state = IDLE; next_clock_state = RISE; } break; case REQUEST: // get ready to receive data from the host transmit = 0; receive = 1; byte_index = 0; next_clock_state = FALL; // host sends data on falling edge // In case we get another INHIBIT state if ((clock_state == HIGH || clock_state == RISE) && CLK_IN == 0) { mouse_state = INHIBIT; next_clock_state = LOW; transmit = 0; receive = 0; } else if (transmit || receive) // go to BUSY state to process data mouse_state = BUSY; else mouse_state = REQUEST; // otherwise stay in REQUEST until data comes break; }//end switch } //insert data into queue. Return 1 if queue full, or 0 if inserted data sucessfully unsigned char queuePut(unsigned char d) { if (queueFull==TRUE) { //check if queue is full return(TRUE); } queue[queueIn]=d; //insert d into queue queueIn++; //increment where to stick in the next d value queueEmpty=FALSE; //indicate queue isnt' empty anymore if (queueIn==QUEUELEN) //if reached the end of the queue queueIn=0; //wrap around to the beginning if (queueIn==queueOut) //if queueIn caught up to queueOut queueFull=TRUE; //indicate queue is full return(0); } //get data out of queue. Return 0 if queue empty or the actual data if not empty unsigned char queueGet(void) { char d; if(resend_byte == TRUE) // in case we need to resend data due to an INHIBIT { resend_byte = FALSE; return previous_byte; } if (queueEmpty==TRUE) //check if queue is empty return(0); d=queue[queueOut]; //get data out of queue queueOut++; //increment location where to get next d value queueFull=FALSE; //indicate queue isn't full anymore if (queueOut==QUEUELEN) //if reached the end of the queue queueOut=0; //wrap around to the beginning if (queueOut==queueIn) //if queueOut caught up to queueIn queueEmpty=TRUE; //indicate queue is empty //if(d==0xAA) // delay_ms(375); previous_byte = d; // save the byte we just popped // in case we need to resend it. return(d); //return the data from queue } //calculate the parity of a character unsigned char getParity(unsigned char x) { unsigned char temp, i; temp=1; for(i=0;i<8;i++) { temp=temp^(x&1); x>>=1; } return temp; } void process_command(unsigned char host_command) { //PORTB.3 = 0x0; delay_us(50); // do this stuff at rising edge of CLK //PORTB = 0xFF; //delay_ms(1000); //PORTB = host_command; //delay_ms(1000); if (host_command == RESET) { queueIn = 0; queueOut=0; queueEmpty = TRUE; queueFull = FALSE; delay_us(500); } // Acknowledge the incoming request queuePut(ACK); // we received a byte w/ the new resolution if(waiting_for_resolution) { // check for valid resolution if(host_command >= 0 && host_command <= 3) resolution = host_command; else { queuePut(ERROR); } waiting_for_resolution = 0; return; } // we received a byte w/ the new sample rate if(waiting_for_sample_rate) { // check for valid sample rate if(host_command >= 10 && host_command <= 200) { sample_rate = host_command; } else { // bad sample rate queuePut(ERROR); } waiting_for_sample_rate = 0; return; } switch (host_command) { case RESET: // RESET PORTB.2 = 0x0; deviceID = 0x03; // create a device ID queuePut(SELF_TEST_PASS); // respond w/ self-test passed (0xAA) queuePut(deviceID); // send host device ID // queuePut(INIT_SUCC_1); data_reporting = 0; // disable data reporting sample_rate = 100; // set the sampling rate to 100 scaling = 0; // set scaling to 1:1 resolution = 0x02; // set resolution to 4 break; case RESEND: // Host requests for resending of data resend_byte = TRUE; //PORTB.7 = 0x0; break; case EN_DATA_REPORT: // Enabling of data reporting PORTB.7 = 0x0; // indicates mouse was detected data_reporting = TRUE; break; case SET_SCALING11: // set scaling 1:1 scaling = 0; break; case SET_SCALING21: // set scaling 2:1 scaling = 1; break; case GET_DEVICE_ID: // host requests device ID PORTB.5 = 0x00; queuePut(deviceID); break; case SET_RES: // host requests to set resolution // host sends next byte with valid resolution // set a flag to get this byte waiting_for_resolution = 1; break; case STATUS_REQ: //status request respond 0xFA, 0x00, 0x02, 0x64 queuePut(0x00); // have to create the right byte here ... queuePut(resolution); queuePut(sample_rate); break; case SET_SAMPLE_RATE: // host requests setting of sample rate // host sends next byte with valid sample rate // set a flag to get this byte waiting_for_sample_rate = 1; break; case DIS_DATA_REPORT: // disable data reporting data_reporting = 0; break; case SET_DEFAULT: // set default values data_reporting = 0; sample_rate = 100; resolution = 4; break; default: break; } } void init_serial(void) { //serial setup for debugging using printf, etc. UCSRB = 0x18; UBRRL = 103; putsf("\r\nStarting...\r\n"); //set up timer 0 //OCR2=249; //1 mSec //TIMSK=0b10000010; //turn on timer 0 cmp-match ISR //TCCR2=0b00001011; //prescalar to 64 and Clr-on-match r_ready=0; t_ready=1; puts_string(); } void initialize(void) { Button0pushed = 1050; Button1pushed = 1050; ADMUX = 0b01000000; //ADLAR is not set ADCSRA = 0b11000111; //Enable & Start ADC w/ division factor of 128 OCR0=5; //20 uSec TIMSK=2; //turn on timer 0 cmp-match ISR TCCR0=0b00001011; //prescalar to 64 and Clr-on-match // Set up the A/D //ADMUX = 0b00100001; //ADLAR is set //ADCSR = 0b11000111; //Enable & Start ADC w/ division factor of 128 // setup Port D for PS/2 communication DDRC = 0b01000010; PORTC = 0b01000010; // setup LEDs for debugging DDRB = 0xFF; PORTB = 0xFF; //DDRD = 0xFF; //PORTD = 0xFF; // use Port C for buttons //DDRC=0x00; // set as input // counter to be used in ISR count = 0; // initialize our outputs CLK_OUT = 1; DATA_OUT = 1; // initialize the queue queueEmpty = TRUE; queueFull = FALSE; queueIn = 0; queueOut =0; // initialize the states byte_index = 0; // where we are in byte mouse_state = IDLE; // state of the mouse clock_state = HIGH; // state of the clock next_clock_state = HIGH; // what clock will be changing to transmit = receive = 0; outInhibit = FALSE; // init byte vars transmit_byte = 0xFA; receive_byte = 0x00; previous_byte = 0x00; resend_byte = FALSE; gen_mouse_packet = FALSE; // init mouse vars deviceID = 0x03; data_reporting = FALSE; sample_rate = 0; scaling = 0; resolution = 0; waiting_for_sample_rate = FALSE; waiting_for_resolution = FALSE; // init data reporting vars mouse_posX = 0x00; mouse_posY = 0x00; left_button_click = middle_button_click = right_button_click = 0; mouse_byte1 = 0x0; scroll_byte = 0x0; // Set up the A/D //ADMUX = 0b00000000; //ADLAR is not set //ADCSRA = 0b11000111; //Enable & Start ADC w/ division factor of 128 portb_cycle = 0; //crank up the ISRs #asm sei #endasm } void main(void) { // tell the computer that the mouse is ready and alive. initialize(); //init_serial(); // printf("Hello\r\n"); // let the host know the mouse is connected queuePut(SELF_TEST_PASS); queuePut(INIT); //printf(" \r\n", Button0, Xmove, Button1, Ymove); // begin real work while (1) { // can we generate a new packet? if(gen_mouse_packet == TRUE && data_reporting == TRUE) { //if(1){ gen_mouse_packet = FALSE; // if (1){ // check buttons mouse_byte1 = 0x08; mouse_posX = 0x00; mouse_posY = 0x00; Xmove = 0; Ymove = 0; scroll_byte = 0; /*if (PINC.2 == 0x0){ //PORTB.0 == 0x0; left_button_click = 1; } else { left_button_click = 0; //PORTB.0 == 0x1; } if (PINC.1 == 0x0){ //PORTB.1 = 0x0; middle_button_click = 1; } else { middle_button_click = 0; //PORTB.0 == 0x1; } if (PINC.0 == 0x0){ //PORTB.2 = 0x0; right_button_click = 1; } else { right_button_click = 0; //PORTB.0 == 0x1; } if (PINC.3 == 0x0) { mouse_posX = 10; } if (PINC.4 == 0x0) { mouse_posX = -10; } if (PINC.5 == 0x0) { mouse_posY = 10; } if (PINC.6 == 0x0) { mouse_posY = -10; }*/ Button0 = 0; Button1 = 0; OldXmove = Xmove; OldYmove = Ymove; ADMUX = 0b01100000; //tilt around Y axis (accel on the side is being read) => X axis motion on computer ADCSRA.6 = 1; while(ADCSRA.6 == 1){ //wait for an ADC conversion to finish } Ytilt = (ADCH); Xmove = (signed char)(Ytilt); ADMUX = 0b01100001; //tilt around X axis (accel on top is being read) => Y axis motion on computer ADCSRA.6 = 1; while(ADCSRA.6 == 1){ //wait for an ADC conversion to finish } Xtilt = (ADCH); Ymove = (signed char)(Xtilt); if (Xmove < -121 || Xmove > 121) {//tolerance condition Xmove = 0; } if (Xmove > 0){ //Need to correct descending system to ascending system //Xmove = (-127)-Xmove; Xmove = (-132)-Xmove; //Smoother with 133 rather than 127 } else if (Xmove < 0){ //Xmove = 127-Xmove; Xmove = 132-Xmove; } if (Ymove < -123 || Ymove > 123) {//tolerance condition Ymove = 0; } if (Ymove < 0){ //Need to correct descending system to ascending system Ymove = (-127)-Ymove; //Smoothness does not matter as much for Y axis //since theres less Y to traverse than there is X space. } else if (Ymove > 0){ Ymove = 127-Ymove; } Xmove = (Xmove*(-1)); if (Button0pushed == 1050 || Button0pushed <= time){ ADMUX = 0b01100010; //tilt around Y axis (accel on the side is being read) => X axis motion on computer ADCSRA.6 = 1; while(ADCSRA.6 == 1){ //wait for an ADC conversion to finish } Button0 = (ADCH); //if (Button0 >= 140 && (Xmove>-25)){ //Can't press button while tilted if (((Xmove>-10)&&(Button0 >140))||((Xmove<-10)&&(Button0 >= (140-Xmove)))) {//This will allow buttons to be pushed even while mouse is tilted. Button0pushed = time+150; if (Button0pushed >= 1000) Button0pushed = (Button0pushed-999); //Overflow check Button0 = 1; } else { Button0 = 0; Button0pushed = 1050; } } if (Button1pushed = 1050 || Button1pushed <= time){ ADMUX = 0b01100011; //tilt around X axis (accel on top is being read) => Y axis motion on computer ADCSRA.6 = 1; while(ADCSRA.6 == 1){ //wait for an ADC conversion to finish } Button1 = (ADCH); //if (Button1 >= 140 && (Xmove>-25)){ if (((Xmove>-10)&&(Button1 >140))||((Xmove<-10)&&(Button1 >= (140-Xmove)))) {//This will allow buttons to be pushed even while mouse is tilted. Button1 = 1; Button1pushed = time+150; if (Button1pushed >= 1000) Button1pushed = (Button1pushed-999); //Overflow check } else{ Button1 = 0; Button1pushed = 1050; } } //Check for both buttons pushed together (within 20ms) to toggle scroll mode off & on //first check the time difference between the button pushes. if (Button1pushed > Button0pushed) ButtonTimeDiff = Button1pushed - Button0pushed; //else ButtonTimeDiff = Button0pushed - Button1pushed; if (ButtonTimeDiff <= 80 && (Button0pushed!= 1050) && Button1pushed!=1050){//Less than 20ms ScrollState = ~ScrollState; //Toggle the scroll state //Note that a 255 => scrolling and a 0 => normal button functionality } //Safety conditions: if ((Button0pushed > time + 151) || (Button0pushed > 1050)) Button0pushed = 1050; if ((Button1pushed > time + 151) || (Button1pushed > 1050)) Button1pushed = 1050; //Button1 = 0; //Button0 = 0; //Xmove = 0; mouse_posX = (unsigned char) Xmove; mouse_posY = (unsigned char) Ymove; /*if (Xmove < 0){ mouse_posX = 255-mouse_posX; } */ //printf(" \r\n", Ymove, mouse_posY, Xmove, mouse_posX); //printf(" \r\n", Button0, Button1, ScrollState,Xmove); //delay_ms(8); //mouse_byte1 = mouse_byte1 | (((Yneg)&0x1)<<5) | (((Xneg)&0x1)<<4) | ((middle_button_click&0x1) <<2) | ((Button1&0x1)<<1) | (Button0 & 0x1); if (ScrollState ==0) {//Not in scrolling mode mouse_byte1 = mouse_byte1 | (((Ymove >> 7)&0x1)<<5) | (((Xmove >> 7)&0x1)<<4) | ((middle_button_click&0x1) <<2) | ((Button1&0x1)<<1) | (Button0 & 0x1); } else {//In scrolling mode mouse_byte1 = mouse_byte1 | (((Ymove >> 7)&0x1)<<5) | (((Xmove >> 7)&0x1)<<4) | ((middle_button_click&0x1) <<2) | ((Button1&0x1)<<1) | (Button0 & 0x1); mouse_byte1 = ((mouse_byte1 >> 2)<<2); //shift out the last 2 bits corresponding to button pushes. //You can't push buttons while you are scrolling => the button pushes mean you are scrolling up and down } //if (!(prev_byte1 == mouse_byte1 && prev_byte2 == Xmove && prev_byte3 == Ymove)) { //if ((mouse_posX-prev_byte2)>50 || (mouse_posX-prev_byte2)<-50 || (mouse_posY-prev_byte3) > 50 || (mouse_posY-prev_byte3) < -50 || mouse_byte1 != prev_byte1) { //if ((Xmove-prev_byte2)>3 || (Xmove-prev_byte2)<-3 || (Ymove-prev_byte3) > 3 || (Ymove-prev_byte3) < -3 || mouse_byte1 != prev_byte1) { //if (((Xmove-OldXmove)>100) ||((Xmove-OldXmove) <-100)|| ((OldYmove-Ymove)>100) || ((OldYmove-Ymove)<-100) || mouse_byte1 != prev_byte1) { if(1){ //if (prev_byte1 != mouse_byte1) { if (portb_cycle == 0) { PORTB.0 = 1; portb_cycle = 1; } else { PORTB.0 = 0; portb_cycle = 0; } queuePut(mouse_byte1); queuePut(Xmove); queuePut(Ymove); /* new code */ if (ScrollState != 0 && Button0 == 1) { scroll_byte = 4; } if (ScrollState != 0 && Button1 == 1) { scroll_byte = -4; } queuePut(scroll_byte); /*prev_byte1 = mouse_byte1; prev_byte2 = Xmove; prev_byte3 = Ymove;*/ } prev_byte1 = mouse_byte1; prev_byte2 = Xmove; prev_byte3 = Ymove; // reset state variables for this loop } } }