Subversion Repositories pentevo

Rev

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