Subversion Repositories pentevo

Rev

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

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