Subversion Repositories pentevo

Rev

Rev 536 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3.  
  4. #include <util/delay.h>
  5.  
  6. #include "mytypes.h"
  7. #include "main.h"
  8. #include "ps2.h"
  9. #include "zx.h"
  10. #include "pins.h"
  11. #include "spi.h"
  12. #include "rs232.h"
  13. #include "rtc.h"
  14.  
  15. //if want Log than comment next string
  16. #undef LOGENABLE
  17.  
  18. UBYTE ps2_decode(UBYTE count, UWORD shifter)
  19. {
  20.         UBYTE t,byte;
  21.  
  22.         if( count!=0 ) return 0x00; // have nothing received
  23.  
  24.         // check packet:
  25.         //shifter.hi - stp.par.7.6.5.4.3.2
  26.         //shifter.lo - 1.0.strt.x.x.x.x.x
  27.  
  28.         if( !( shifter&0x8000 ) ) return 0x00; // stopbit must be 1
  29.         if( shifter&0x0020 ) return 0x00; // startbit must be 0
  30.  
  31.  
  32.         byte = (UBYTE) ( 0x00FF & (shifter>>6) );
  33.  
  34.         t = byte ^ (byte>>4);
  35.         t = t ^ (t>>2);
  36.         t = t ^ (t>>1); // parity
  37.  
  38.         t = t ^ (UBYTE) ( shifter>>14 ); // compare parities
  39.  
  40.         if( !(t&1) ) return 0x00; // must be different
  41.  
  42.         return byte;
  43. }
  44.  
  45. UWORD ps2_encode(UBYTE byte)
  46. {
  47.         UWORD t;
  48.         t = byte ^ (byte>>4);
  49.         t = t ^ (t>>2);
  50.         t = ~(1 & (t ^ (t>>1))); // parity
  51.  
  52.         t = (((t<<8) + byte)<<1) + 0x0400;
  53.  
  54.         // prepare to shifter:
  55.         //shifter.hi - x.x.x.x.x.stp.par.7
  56.         //shifter.lo - 6.5.4.3.2.1.0.strt
  57.         return t;
  58. }
  59.  
  60. volatile UWORD ps2keyboard_shifter;
  61. volatile UBYTE ps2keyboard_count;
  62. volatile UBYTE ps2keyboard_timeout;
  63. volatile UBYTE ps2keyboard_cmd_count;
  64. volatile UBYTE ps2keyboard_cmd;
  65.  
  66. volatile UBYTE  ps2keyboard_log[16];
  67. volatile UBYTE  ps2keyboard_log_start;
  68. volatile UBYTE  ps2keyboard_log_end;
  69.  
  70. void ps2keyboard_to_log(UBYTE data)
  71. {
  72.         if( ps2keyboard_log_end != 0xFF )
  73.         {
  74.                 if( ps2keyboard_log_end == 0xFE )
  75.                 {
  76.                         //first byte after reset
  77.                         ps2keyboard_log_end = ps2keyboard_log_start;
  78.                 }
  79.  
  80. #ifdef LOGENABLE
  81.                 {
  82.                         char log_ps2kb_parse[] = "LG<..:..\r\n";
  83.                         UBYTE b = ps2keyboard_log_end;
  84.                         log_ps2kb_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  85.                         log_ps2kb_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  86.                         b = data;
  87.                         log_ps2kb_parse[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  88.                         log_ps2kb_parse[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  89.                         to_log(log_ps2kb_parse);
  90.                 }
  91. #endif
  92.                 ps2keyboard_log[ps2keyboard_log_end] = data;
  93.                 ps2keyboard_log_end++;
  94.                 if( ps2keyboard_log_end >= sizeof(ps2keyboard_log) )
  95.                 {
  96.                         ps2keyboard_log_end = 0;
  97.                 }
  98.  
  99.                 if( ps2keyboard_log_end == ps2keyboard_log_start )
  100.                 {
  101.                         //overload
  102.                         ps2keyboard_log_end = 0xFF;
  103.                 }
  104.         }
  105. }
  106.  
  107. UBYTE ps2keyboard_from_log(void)
  108. {
  109.         UBYTE ret;
  110.         if( ps2keyboard_log_start == 0xFF )
  111.         {
  112.                 //reset state
  113.                 return 0;
  114.         }
  115.         if( ps2keyboard_log_end<sizeof(ps2keyboard_log) )
  116.         {
  117.                 if( ps2keyboard_log_end != ps2keyboard_log_start )
  118.                 {
  119.                         ret = ps2keyboard_log[ps2keyboard_log_start];
  120. #ifdef LOGENABLE
  121.                 {
  122.                         char log_ps2kb_parse[] = "LG>..:..\r\n";
  123.                         UBYTE b = ret;
  124.                         log_ps2kb_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  125.                         log_ps2kb_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  126.                         b = ps2keyboard_log_start;
  127.                         log_ps2kb_parse[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  128.                         log_ps2kb_parse[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  129.                         to_log(log_ps2kb_parse);
  130.                 }
  131. #endif
  132.                         ps2keyboard_log_start++;
  133.                         if( ps2keyboard_log_start >= sizeof(ps2keyboard_log) )
  134.                         {
  135.                                 ps2keyboard_log_start = 0;
  136.                         }
  137.                 }
  138.                 else
  139.                 {
  140.                         ret=0;
  141.                 }
  142.         }
  143.         else
  144.         {
  145.                 ret = ps2keyboard_log_end;
  146.                 if ( ret==0xFE )
  147.                 {
  148.                         ret=0;
  149.                 }
  150.                 else
  151.                 {
  152.                         //after reading overload 'FF' - reset log
  153.                         ps2keyboard_reset_log();
  154.                 }
  155.         }
  156.         //0 - no data, 0xFF - overload
  157.         return ret;
  158. }
  159.  
  160. void ps2keyboard_reset_log(void)
  161. {
  162. #ifdef LOGENABLE
  163.         if( ps2keyboard_log_start!=0xFF )
  164.         to_log("LGRESET\r\n");
  165. #endif
  166.         ps2keyboard_log_start = 0xFF;
  167. }
  168.  
  169. static void ps2keyboard_release_clk(void)
  170. {
  171.         ps2keyboard_count = 12; //counter reinit
  172.         if( flags_register & FLAG_PS2KEYBOARD_DIRECTION )
  173.         {
  174.                 PS2KBDAT_DDR &= ~(1<<PS2KBDAT); //ps2 keyboard data pin to input mode
  175.                 flags_register &= ~(FLAG_PS2KEYBOARD_DIRECTION); //set to receive mode
  176.         }
  177.  
  178.         //release ps2 receiver (disabled by now)
  179.         EIFR = (1<<INTF4); // clr any spurious int which can happen when we pulldown clock pin
  180.         PS2KBCLK_DDR  &= ~(1<<PS2KBCLK); //ps2 keyboard clk pin to input mode
  181.         PS2KBCLK_PORT |= (1<<PS2KBCLK);  //release clk pin
  182. }
  183.  
  184. void ps2keyboard_send(UBYTE data)
  185. {
  186. #ifdef LOGENABLE
  187. {
  188.         char log_ps2kb_parse[] = "KB>..\r\n";
  189.         UBYTE b = data;
  190.         log_ps2kb_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  191.         log_ps2kb_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  192.         to_log(log_ps2kb_parse);
  193. }
  194. #endif
  195.         ps2keyboard_shifter = ps2_encode(data); //prepare data
  196.         flags_register |= FLAG_PS2KEYBOARD_DIRECTION; //set send mode
  197.         PS2KBCLK_PORT &= ~(1<<PS2KBCLK); //bring ps2 keyboard clk pin -
  198.     PS2KBCLK_DDR  |= (1<<PS2KBCLK);  //generate interruption
  199. }
  200.  
  201. void ps2keyboard_task(void)
  202. {
  203.         UBYTE b;
  204.  
  205.         if ( ( ps2keyboard_count == 12 ) &&
  206.                  ( ps2keyboard_cmd != 0) &&
  207.                  ( ps2keyboard_cmd_count != 0 ) )
  208.         {
  209.                 //delay need for pause between release and hold clk pin
  210.                 _delay_us(100);
  211.  
  212.                 //if need send command on current stage
  213.                 if ( ((ps2keyboard_cmd_count == 4)&&(ps2keyboard_cmd == PS2KEYBOARD_CMD_SETLED)) ||
  214.                      ((ps2keyboard_cmd_count == 3)&&(ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)) )
  215.                 {
  216.                         ps2keyboard_send(ps2keyboard_cmd);
  217.                         ps2keyboard_cmd_count--;
  218.                 }
  219.                 else
  220.                 //if need send led data on current stage
  221.                 if ( ((ps2keyboard_cmd_count == 2)&&(ps2keyboard_cmd == PS2KEYBOARD_CMD_SETLED)) )
  222.                 {
  223.                         b = (PS2KEYBOARD_LED_SCROLLOCK|PS2KEYBOARD_LED_NUMLOCK|PS2KEYBOARD_LED_CAPSLOCK)&modes_register;
  224.                         ps2keyboard_send(b);
  225.                         ps2keyboard_cmd_count--;
  226.                 }
  227.         }
  228.  
  229.         if ( ( ps2keyboard_count<12 ) &&
  230.                  ( ps2keyboard_timeout==0 ) )
  231.         {
  232.                 //error due send/receive
  233.                 ps2keyboard_release_clk();
  234. #ifdef LOGENABLE
  235.                 to_log("KBerr\r\n");
  236. #endif
  237.                 //TODO: ўхЄр фхырЄ№
  238.                 if ( ps2keyboard_cmd != PS2KEYBOARD_CMD_RESET )
  239.                 {
  240.                         //set cmd  RESET
  241.                         ps2keyboard_cmd = PS2KEYBOARD_CMD_RESET;
  242.                         ps2keyboard_cmd_count = 3;
  243.                 }
  244.                 else
  245.                 {
  246.                         //reset command
  247.                         ps2keyboard_cmd = 0;
  248.                         ps2keyboard_cmd_count = 0;
  249.                 }
  250.  
  251.                 //reset buffer
  252.                 zx_clr_kb();
  253.  
  254.                 return;
  255.         }
  256.  
  257.         if ( ps2keyboard_count!=0 ) return; // not received anything
  258.  
  259.         if ( !(flags_register&FLAG_PS2KEYBOARD_DIRECTION) )
  260.         {
  261.                 //receive complete
  262.                 b = ps2_decode(ps2keyboard_count, ps2keyboard_shifter);
  263. #ifdef LOGENABLE
  264. {
  265.         char log_ps2kb_parse[] = "KB<..\r\n";
  266.         log_ps2kb_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  267.         log_ps2kb_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  268.         to_log(log_ps2kb_parse);
  269. }
  270. #endif
  271.                 if ( ps2keyboard_cmd )
  272.                 {
  273.                         //wait for 0xFA on current stage
  274.                         if ( ((ps2keyboard_cmd == PS2KEYBOARD_CMD_SETLED)&&(ps2keyboard_cmd_count == 3 || ps2keyboard_cmd_count == 1)) ||
  275.                              ((ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)&&(ps2keyboard_cmd_count == 2)) )
  276.                         {
  277.                                 if( b != 0xFA )
  278.                                 {
  279.                                         ps2keyboard_cmd_count = 0;
  280.                                         //if non FA - may be scan code received
  281.                                         if ( b ) ps2keyboard_parse(b);
  282.                                 }
  283.                                 else ps2keyboard_cmd_count--;
  284.  
  285.                                 if ( ps2keyboard_cmd_count == 0 ) ps2keyboard_cmd = 0;
  286.                         }
  287.                         else
  288.                         //wait for 0xAA on current stage
  289.                         if ( ((ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)&&(ps2keyboard_cmd_count == 1)) )
  290.                         {
  291.                                 if ( b != 0xAA )
  292.                                 {
  293.                                         //if non AA - may be scan code received
  294.                                         if ( b ) ps2keyboard_parse(b);
  295.                                 }
  296.                                 ps2keyboard_cmd_count = 0;
  297.                                 ps2keyboard_cmd = 0;
  298.                         }
  299.                 }
  300.                 else
  301.                 if ( b ) // there is no zero byte in scancode tables so we can ignore and use it as 'nothing received'
  302.                 {
  303.                         ps2keyboard_parse(b);
  304.                 }
  305.         }
  306.  
  307.         ps2keyboard_release_clk();
  308. }
  309.  
  310. void ps2keyboard_send_cmd(UBYTE cmd)
  311. {
  312.         if ( ps2keyboard_cmd == 0 )
  313.         {
  314.                 ps2keyboard_cmd = cmd;
  315.                 switch ( cmd )
  316.                 {
  317.                 case PS2KEYBOARD_CMD_RESET:
  318.                         ps2keyboard_cmd_count = 3;
  319.                         break;
  320.                 case PS2KEYBOARD_CMD_SETLED:
  321.                         ps2keyboard_cmd_count = 4;
  322.                         break;
  323.                 default:
  324.                         ps2keyboard_cmd = 0;
  325.                 }
  326.         }
  327. }
  328.  
  329. void ps2keyboard_parse(UBYTE recbyte)
  330. {
  331.         static UBYTE was_release = 0;
  332.         static UBYTE was_E0 = 0;
  333.  
  334.         static UBYTE last_scancode = 0;
  335.         static UBYTE last_scancode_E0 = 1;
  336.  
  337.         static UBYTE skipshit = 0;
  338.  
  339. #ifdef LOGENABLE
  340.         char log_ps2keyboard_parse[] = "KB..\r\n";
  341.         if ( skipshit ) log_ps2keyboard_parse[1] = skipshit + '0';
  342.         log_ps2keyboard_parse[2] = ((recbyte >> 4) <= 9 )?'0'+(recbyte >> 4):'A'+(recbyte >> 4)-10;
  343.         log_ps2keyboard_parse[3] = ((recbyte & 0x0F) <= 9 )?'0'+(recbyte & 0x0F):'A'+(recbyte & 0x0F)-10;
  344.         to_log(log_ps2keyboard_parse);
  345. #endif
  346.  
  347.         if( recbyte==0xFA ) return;
  348.         if( recbyte==0xFE ) return;
  349.         if( recbyte==0xEE ) return;
  350.         if( recbyte==0xAA ) return;
  351.  
  352.         //start write to log only for full key data
  353.         if( (recbyte!=0xE1) && (skipshit==0) ) //PAUSE not logged
  354.         {
  355.                 if( ps2keyboard_log_start == 0xFF )
  356.                 {
  357.                         //reseting log
  358.                         ps2keyboard_log_end = 0xFE;
  359.                         ps2keyboard_log_start = 0;
  360.                 }
  361.                 if( (ps2keyboard_log_end!=0xFE) || ((was_release==0) && (was_E0==0)/* && (skipshit==0)*/) )
  362.                 {
  363.                         ps2keyboard_to_log(recbyte);
  364.                 }
  365.         }
  366.  
  367.         if( skipshit )
  368.         {
  369.                 skipshit--;
  370.                 return;
  371.         }
  372.  
  373.         if( recbyte==0xE0 )
  374.         {
  375.                 was_E0 = 1;
  376.                 return;
  377.         }
  378.  
  379.  
  380.         if( recbyte==0xF0 )
  381.         {
  382.                 was_release = 1;
  383.                 return;
  384.         }
  385.  
  386.         if( recbyte==0xE1 ) // pause pressed
  387.         {
  388.                 skipshit=7;
  389.                 return; // skip next 7 bytes
  390.         }
  391.  
  392.         if( (recbyte==last_scancode) && (was_E0==last_scancode_E0) )
  393.         {
  394.                 if( was_release )
  395.                 {
  396.                         last_scancode = 0x00;
  397.                         last_scancode_E0 = 1; // impossible scancode: E0 00
  398.                 }
  399.                 else // was depress
  400.                 {
  401.                         was_E0 = 0;
  402.                         return;
  403.                 }
  404.         }
  405.  
  406.         if( !was_release )
  407.         {
  408.                 last_scancode = recbyte;
  409.                 last_scancode_E0 = was_E0;
  410.         }
  411.  
  412.         if( (recbyte==0x12) && was_E0 ) // skip E0 12
  413.         {
  414.                 was_E0 = 0;
  415.                 was_release = 0;
  416.                 return;
  417.         }
  418.  
  419.         to_zx( recbyte, was_E0, was_release ); // send valid scancode to zx decoding stage
  420. #ifdef LOGENABLE
  421.         char log_ps2keyboard_parse2[] = "KB(..,.,.)\r\n";
  422.         log_ps2keyboard_parse2[3] = ((recbyte >> 4) <= 9 )?'0'+(recbyte >> 4):'A'+(recbyte >> 4)-10;
  423.         log_ps2keyboard_parse2[4] = ((recbyte & 0x0F) <= 9 )?'0'+(recbyte & 0x0F):'A'+(recbyte & 0x0F)-10;
  424.         log_ps2keyboard_parse2[6] = (was_E0)?'1':'0';
  425.         log_ps2keyboard_parse2[8] = (was_release)?'1':'0';
  426.         to_log(log_ps2keyboard_parse2);
  427. #endif
  428.  
  429.         was_E0 = 0;
  430.         was_release = 0;
  431.  
  432.         return;
  433. }
  434.  
  435. volatile UWORD ps2mouse_shifter;
  436. volatile UBYTE ps2mouse_count;
  437. volatile UBYTE ps2mouse_timeout;
  438. volatile UBYTE ps2mouse_initstep;
  439. volatile UBYTE ps2mouse_resp_count;
  440. volatile UBYTE ps2mouse_cmd;
  441.  
  442. const UBYTE ps2mouse_init_sequence[] =
  443.         "\xFF"      //
  444.         "\xFF"      // reset
  445.         "\xFF"      //
  446.         "\xF3\xC8"  // set sample rate 200  | switch to
  447.         "\xF3\x64"  // set sample rate 100  |     scroll
  448.         "\xF3\x50"  // set sample rate 80   |         mode
  449.         "\xF2"      // get device type
  450. //      "\xE8\x02"  // set resolution to 4 count/mm
  451.         "\xE6"      // set scaling 1:1
  452.         "\xF3\x64"  // set sample rate 100
  453.         "\xF4"      // enable
  454.         ;
  455.  
  456. static void ps2mouse_release_clk(void)
  457. {
  458.         ps2mouse_count = 12; //counter reinit
  459.         if( flags_register & FLAG_PS2MOUSE_DIRECTION )
  460.         {
  461.                 PS2MSDAT_DDR &= ~(1<<PS2MSDAT); //ps2 mouse data pin to input mode
  462.                 flags_register &= ~(FLAG_PS2MOUSE_DIRECTION); //set to receive mode
  463.         }
  464.  
  465.         //release ps2 receiver (disabled by now)
  466.         EIFR = (1<<INTF5); // clr any spurious int which can happen when we pulldown clock pin
  467.         PS2MSCLK_DDR  &= ~(1<<PS2MSCLK); //ps2 mouse clk pin to input mode
  468.         PS2MSCLK_PORT |= (1<<PS2MSCLK);  //release clk pin
  469. }
  470.  
  471. void ps2mouse_send(UBYTE data)
  472. {
  473. #ifdef LOGENABLE
  474. {
  475.         UBYTE b=data;
  476.         char log_ps2mouse_parse[] = "MS>..\r\n";
  477.         log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  478.         log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  479.         to_log(log_ps2mouse_parse);
  480. }
  481. #endif
  482.         ps2mouse_shifter = ps2_encode(data); //prepare data
  483.         flags_register |= FLAG_PS2MOUSE_DIRECTION; //set send mode
  484.         PS2MSCLK_PORT &= ~(1<<PS2MSCLK); //bring ps2 mouse clk pin -
  485.     PS2MSCLK_DDR  |= (1<<PS2MSCLK);  //generate interruption
  486. }
  487.  
  488. void ps2mouse_task(void)
  489. {
  490.         UBYTE b;
  491.  
  492.         if (  ps2mouse_count == 12  )
  493.         {
  494.                 if (  ps2mouse_init_sequence[ps2mouse_initstep] != 0  )
  495.                 {
  496.                         if ( ps2mouse_resp_count == 0 )
  497.                         {
  498.                                 //delay need for pause between release and hold clk pin
  499.                                 _delay_us(200);
  500.  
  501.                                 //initialization not complete
  502.                                 //send next command to mouse
  503.                                 ps2mouse_send(ps2mouse_init_sequence[ps2mouse_initstep]);
  504.                                 ps2mouse_resp_count++;
  505.                         }
  506.                 }
  507.                 else if ( ps2mouse_cmd != 0 )
  508.                 {
  509.                         if ( ps2mouse_resp_count == 0 )
  510.                         {
  511.                                 //delay need for pause between release and hold clk pin
  512.                                 _delay_us(200);
  513.  
  514.                                 //start command
  515.                                 flags_ex_register |= FLAG_EX_PS2MOUSE_CMD;
  516.                                 ps2mouse_send(ps2mouse_cmd);
  517.                                 ps2mouse_resp_count++;
  518.                         }
  519.                         else if( flags_ex_register & FLAG_EX_PS2MOUSE_CMD )
  520.                         {
  521.                                 switch( ps2mouse_cmd )
  522.                                 {
  523.                                         case PS2MOUSE_CMD_SET_RESOLUTION:
  524.                                                 if ( ps2mouse_resp_count == 2 )
  525.                                                 {
  526.                                                         //delay need for pause between release and hold clk pin
  527.                                                         _delay_us(200);
  528.  
  529.                                                         //send resolution
  530.                                                         ps2mouse_send(rtc_read(RTC_PS2MOUSE_RES_REG)&0x03);
  531.                                                         ps2mouse_resp_count++;
  532.                                                 }
  533.                                                 break;
  534.                                 }
  535.                         }
  536.                 }
  537.         }
  538.  
  539.         if ( ( ps2mouse_count<12 ) &&
  540.                  ( ps2mouse_timeout==0 ) )
  541.         {
  542. #ifdef LOGENABLE
  543.                 char log_ps2mouse_err[] = "MS.err.\r\n";
  544.                 if( flags_register&FLAG_PS2MOUSE_DIRECTION ) log_ps2mouse_err[2]='S';   else log_ps2mouse_err[2]='R';
  545.                 if( ps2mouse_count<10 ) log_ps2mouse_err[6]='0'+ps2mouse_count;  else log_ps2mouse_err[6]='A'+ps2mouse_count-10;
  546.                 to_log(log_ps2mouse_err);
  547. #endif
  548.                 //error due exchange data with PS/2 mouse
  549.  
  550.                 //get direction
  551.                 b = flags_register&FLAG_PS2MOUSE_DIRECTION;
  552.  
  553.                 //reset pins and states
  554.                 ps2mouse_release_clk();
  555.  
  556.                 //analizing error
  557.                 if( b && (ps2mouse_initstep==0) )
  558.                 {
  559.                         //error due send first init byte - mouse not connected to PS/2
  560.  
  561.                         //disable mouse
  562.                         zx_mouse_reset(0);
  563.                 }
  564.                 else
  565.                 {
  566.                         //error due receive or send non first byte - mouse connected to PS/2
  567.  
  568.                         //re-init mouse
  569.                         ps2mouse_initstep = 0;
  570.                 }
  571.         }
  572.  
  573.         if ( ps2mouse_count!=0 ) return; // not received anything
  574.  
  575.         if ( !(flags_register&FLAG_PS2MOUSE_DIRECTION) )
  576.         {
  577.                 //receive complete
  578.                 b = ps2_decode(ps2mouse_count, ps2mouse_shifter);
  579.  
  580. #ifdef LOGENABLE
  581. {
  582.         char log_ps2mouse_parse[] = "MS<..\r\n";
  583.         log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  584.         log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  585.         to_log(log_ps2mouse_parse);
  586. }
  587. #endif
  588.  
  589.                 //if command proceed than command code
  590.                 //if initialization proceed than current init code
  591.                 //else 0
  592.                 switch( (flags_ex_register&FLAG_EX_PS2MOUSE_CMD)?ps2mouse_cmd:ps2mouse_init_sequence[ps2mouse_initstep] )
  593.                 {
  594.                         //initialization complete - working mode
  595.                         case 0:
  596.                                 ps2mouse_resp_count++;
  597.                                 switch( ps2mouse_resp_count )
  598.                                 {
  599.                                 case 1:
  600.                                         //byte 1: Y overflow | X overflow | Y sign bit | X sign bit | 1 | Middle Btn | Right Btn | Left Btn
  601.                                         zx_mouse_button = (zx_mouse_button&0xF0) + ((b^0x07)&0x0F);
  602.                                         break;
  603.                                 case 2:
  604.                                         //byte 2: X movement
  605.                                         zx_mouse_x += b;
  606.                                         break;
  607.                                 case 3:
  608.                                         //byte 3: Y movement
  609.                                         zx_mouse_y += b;
  610.                                         if ( !(flags_register&FLAG_PS2MOUSE_TYPE) )
  611.                                         {
  612.                                                 //classical mouse
  613.                                                 ps2mouse_resp_count = 0;
  614.                                                 flags_register |= FLAG_PS2MOUSE_ZX_READY;
  615.                                         }
  616.                                         break;
  617.                                 case 4:
  618.                                         //byte 4: wheel movement
  619.                                         zx_mouse_button += ((b<<4)&0xF0);
  620.                                         flags_register |= FLAG_PS2MOUSE_ZX_READY;
  621.                                         ps2mouse_resp_count = 0;
  622.                                 }
  623.                                 break;
  624.  
  625.                         //reset command
  626.                         case PS2MOUSE_CMD_RESET:
  627.                                 if ( ps2mouse_resp_count==1 )
  628.                                 {
  629.                                         //must be acknowledge
  630.                                         if ( b != 0xFA )
  631.                                         {
  632.                                                 if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  633.                                                 {
  634.                                                         //reset command
  635.                                                         ps2mouse_cmd = 0;
  636.                                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  637.                                                 }
  638.                                                 else
  639.                                                 {
  640.                                                         //reset initialization
  641.                                                         ps2mouse_initstep = 0;
  642.                                                 }
  643.                                                 ps2mouse_resp_count = 0;
  644.                                                 break;
  645.                                         }
  646.                                 }
  647.                                 ps2mouse_resp_count++;
  648.                                 if ( ps2mouse_resp_count >= 4 )
  649.                                 {
  650.                                         ps2mouse_resp_count = 0;
  651.                                         if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  652.                                         {
  653.                                                 //reset command
  654.                                                 ps2mouse_cmd = 0;
  655.                                                 flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  656.                                         }
  657.                                         else
  658.                                         {
  659.                                                 //next initialization stage
  660.                                                 ps2mouse_initstep++;
  661.                                         }
  662.                                 }
  663.                                 break;
  664.  
  665.                         //get device type
  666.                         case PS2MOUSE_CMD_GET_TYPE:
  667.                                 if ( ps2mouse_resp_count==1 )
  668.                                 {
  669.                                         ps2mouse_resp_count++;
  670.                                         //must be acknowledge
  671.                                         if ( b != 0xFA )
  672.                                         {
  673.                                                 if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  674.                                                 {
  675.                                                         //reset command
  676.                                                         ps2mouse_cmd = 0;
  677.                                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  678.                                                 }
  679.                                                 else
  680.                                                 {
  681.                                                         //reset initialization
  682.                                                         ps2mouse_initstep = 0;
  683.                                                 }
  684.                                                 ps2mouse_resp_count = 0;
  685.                                         }
  686.                                         break;
  687.                                 }
  688.                                 else
  689.                                 {
  690.                                         ps2mouse_resp_count = 0;
  691.                                         if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  692.                                         {
  693.                                                 //reset command
  694.                                                 ps2mouse_cmd = 0;
  695.                                                 flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  696.                                         }
  697.                                         else
  698.                                         {
  699.                                                 //next initialization stage
  700.                                                 ps2mouse_initstep++;
  701.                                         }
  702.  
  703.                                         if ( b > 0 )
  704.                                         {
  705.                                                 flags_register |= FLAG_PS2MOUSE_TYPE;
  706.                                         }
  707.                                         else
  708.                                         {
  709.                                                 flags_register &= ~(FLAG_PS2MOUSE_TYPE);
  710.                                         }
  711.                                 }
  712.                                 break;
  713.  
  714.                         //set resolution
  715.                         case PS2MOUSE_CMD_SET_RESOLUTION:
  716.                                 //must be acknowledge
  717.                                 if ( b != 0xFA )
  718.                                 {
  719.                                         if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  720.                                         {
  721.                                                 //reset command
  722.                                                 ps2mouse_cmd = 0;
  723.                                                 flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  724.                                         }
  725.                                         else
  726.                                         {
  727.                                                 //reset initialization
  728.                                                 ps2mouse_initstep = 0;
  729.                                         }
  730.                                         ps2mouse_resp_count = 0;
  731.                                 }
  732.                                 else
  733.                                 {
  734.                                         if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  735.                                         {
  736.                                                 if( ps2mouse_resp_count >= 3 )
  737.                                                 {
  738.                                                         ps2mouse_resp_count = 0;
  739.                                                         //reset command
  740.                                                         //ps2mouse_cmd = 0;
  741.                                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  742.  
  743.                                                         //WARNING! some mouses need enable command after changing resolution
  744.                                                         ps2mouse_cmd = PS2MOUSE_CMD_ENABLE;
  745.                                                 }
  746.                                                 else
  747.                                                 {
  748.                                                         ps2mouse_resp_count ++;
  749.                                                 }
  750.                                         }
  751.                                         else
  752.                                         {
  753.                                                 //next initialization stage
  754.                                                 ps2mouse_resp_count = 0;
  755.                                                 ps2mouse_initstep++;
  756.                                         }
  757.                                 }
  758.                                 break;
  759.  
  760.                         //other commands
  761.                         default:
  762.                                 if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  763.                                 {
  764.                                         //reset command
  765.                                         ps2mouse_cmd = 0;
  766.                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  767.                                 }
  768.                                 else
  769.                                 {
  770.                                         //next initialization stage
  771.                                         ps2mouse_initstep++;
  772.                                         if ( ps2mouse_resp_count==1 )
  773.                                         {
  774.                                                 //must be acknowledge
  775.                                                 if ( b != 0xFA )
  776.                                                 {
  777.                                                         //reset initialization
  778.                                                         ps2mouse_initstep = 0;
  779.                                                 }
  780.                                         }
  781.                                 }
  782.                                 ps2mouse_resp_count = 0;
  783.                                 break;
  784.                 }
  785.         }
  786. //#ifdef LOGENABLE
  787. //      else
  788. //      {
  789. //              //send complete
  790. //              char log_ps2mouse_parse[] = "MS>..\r\n";
  791. //              b = ps2mouse_init_sequence[ps2mouse_initstep];
  792. //              log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  793. //              log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  794. //              to_log(log_ps2mouse_parse);
  795. //      }
  796. //#endif
  797.  
  798.         ps2mouse_release_clk();
  799. }
  800.  
  801. void ps2mouse_set_resolution(UBYTE code)
  802. {
  803. #ifdef LOGENABLE
  804. {
  805.         UBYTE b = zx_mouse_button;
  806.         char log_ps2mouse_parse[] = "SS:..-..\r\n";
  807.         log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  808.         log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  809.         b = code;
  810.         log_ps2mouse_parse[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  811.         log_ps2mouse_parse[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  812.         to_log(log_ps2mouse_parse);
  813. }
  814. #endif
  815.  
  816.         //if pressed left and right buttons on mouse
  817.         if ( (zx_mouse_button & 0x03) == 0 )
  818.         {
  819.                 switch( code )
  820.                 {
  821.                         //keypad '*' - set default resolution
  822.                         case 0x7C:
  823.                                 rtc_write(RTC_PS2MOUSE_RES_REG,0x00);
  824.                                 ps2mouse_cmd = PS2MOUSE_CMD_SET_RESOLUTION;
  825.                                 break;
  826.  
  827.                         //keypad '+' - inc resolution
  828.                         case 0x79:
  829.                         {
  830.                                 UBYTE data = rtc_read(RTC_PS2MOUSE_RES_REG)&0x03;
  831.                                 if( data < 0x03 )
  832.                                 {
  833.                                         data++;
  834.                                 }
  835.                                 rtc_write(RTC_PS2MOUSE_RES_REG,data);
  836.                                 ps2mouse_cmd = PS2MOUSE_CMD_SET_RESOLUTION;
  837.                             break;
  838.                         }
  839.  
  840.                         //keypad '-' - dec resolution
  841.                         case 0x7B:
  842.                         {
  843.                                 UBYTE data = rtc_read(RTC_PS2MOUSE_RES_REG)&0x03;
  844.                                 if (data)
  845.                                 {
  846.                                         data--;
  847.                                 }
  848.                                 rtc_write(RTC_PS2MOUSE_RES_REG,data);
  849.                                 ps2mouse_cmd = PS2MOUSE_CMD_SET_RESOLUTION;
  850.                             break;
  851.                         }
  852.                 }
  853.         }
  854. }
  855.