Subversion Repositories pentevo

Rev

Rev 536 | 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.  
  239.                 //reset command
  240.                 ps2keyboard_cmd_count = 0;
  241.                 ps2keyboard_cmd = 0;
  242.  
  243.                 //reset buffer
  244.                 zx_clr_kb();
  245.         }
  246.  
  247.         if ( ps2keyboard_count!=0 ) return; // not received anything
  248.  
  249.         if ( !(flags_register&FLAG_PS2KEYBOARD_DIRECTION) )
  250.         {
  251.                 //receive complete
  252.                 b = ps2_decode(ps2keyboard_count, ps2keyboard_shifter);
  253. #ifdef LOGENABLE
  254. {
  255.         char log_ps2kb_parse[] = "KB<..\r\n";
  256.         log_ps2kb_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  257.         log_ps2kb_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  258.         to_log(log_ps2kb_parse);
  259. }
  260. #endif
  261.                 if ( ps2keyboard_cmd )
  262.                 {
  263.                         //wait for 0xFA on current stage
  264.                         if ( ((ps2keyboard_cmd == PS2KEYBOARD_CMD_SETLED)&&(ps2keyboard_cmd_count == 3 || ps2keyboard_cmd_count == 1)) ||
  265.                              ((ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)&&(ps2keyboard_cmd_count == 2)) )
  266.                         {
  267.                                 if( b != 0xFA )
  268.                                 {
  269.                                         ps2keyboard_cmd_count = 0;
  270.                                         //if non FA - may be scan code received
  271.                                         if ( b ) ps2keyboard_parse(b);
  272.                                 }
  273.                                 else ps2keyboard_cmd_count--;
  274.  
  275.                                 if ( ps2keyboard_cmd_count == 0 ) ps2keyboard_cmd = 0;
  276.                         }
  277.                         else
  278.                         //wait for 0xAA on current stage
  279.                         if ( ((ps2keyboard_cmd == PS2KEYBOARD_CMD_RESET)&&(ps2keyboard_cmd_count == 1)) )
  280.                         {
  281.                                 if ( b != 0xAA )
  282.                                 {
  283.                                         //if non AA - may be scan code received
  284.                                         if ( b ) ps2keyboard_parse(b);
  285.                                 }
  286.                                 ps2keyboard_cmd_count = 0;
  287.                                 ps2keyboard_cmd = 0;
  288.                         }
  289.                 }
  290.                 else
  291.                 if ( b ) // there is no zero byte in scancode tables so we can ignore and use it as 'nothing received'
  292.                 {
  293.                         ps2keyboard_parse(b);
  294.                 }
  295.         }
  296.  
  297.         ps2keyboard_release_clk();
  298. }
  299.  
  300. void ps2keyboard_send_cmd(UBYTE cmd)
  301. {
  302.         if ( ps2keyboard_cmd == 0 )
  303.         {
  304.                 ps2keyboard_cmd = cmd;
  305.                 switch ( cmd )
  306.                 {
  307.                 case PS2KEYBOARD_CMD_RESET:
  308.                         ps2keyboard_cmd_count = 3;
  309.                         break;
  310.                 case PS2KEYBOARD_CMD_SETLED:
  311.                         ps2keyboard_cmd_count = 4;
  312.                         break;
  313.                 default:
  314.                         ps2keyboard_cmd = 0;
  315.                 }
  316.         }
  317. }
  318.  
  319. void ps2keyboard_parse(UBYTE recbyte)
  320. {
  321.         static UBYTE was_release = 0;
  322.         static UBYTE was_E0 = 0;
  323.  
  324.         static UBYTE last_scancode = 0;
  325.         static UBYTE last_scancode_E0 = 1;
  326.  
  327.         static UBYTE skipshit = 0;
  328.  
  329. #ifdef LOGENABLE
  330.         char log_ps2keyboard_parse[] = "KB..\r\n";
  331.         if ( skipshit ) log_ps2keyboard_parse[1] = skipshit + '0';
  332.         log_ps2keyboard_parse[2] = ((recbyte >> 4) <= 9 )?'0'+(recbyte >> 4):'A'+(recbyte >> 4)-10;
  333.         log_ps2keyboard_parse[3] = ((recbyte & 0x0F) <= 9 )?'0'+(recbyte & 0x0F):'A'+(recbyte & 0x0F)-10;
  334.         to_log(log_ps2keyboard_parse);
  335. #endif
  336.  
  337.         if( recbyte==0xFA ) return;
  338.         if( recbyte==0xFE ) return;
  339.         if( recbyte==0xEE ) return;
  340.         if( recbyte==0xAA ) return;
  341.  
  342.         //start write to log only for full key data
  343.         if( (recbyte!=0xE1) && (skipshit==0) ) //PAUSE not logged
  344.         {
  345.                 if( ps2keyboard_log_start == 0xFF )
  346.                 {
  347.                         //reseting log
  348.                         ps2keyboard_log_end = 0xFE;
  349.                         ps2keyboard_log_start = 0;
  350.                 }
  351.                 if( (ps2keyboard_log_end!=0xFE) || ((was_release==0) && (was_E0==0)/* && (skipshit==0)*/) )
  352.                 {
  353.                         ps2keyboard_to_log(recbyte);
  354.                 }
  355.         }
  356.  
  357.         if( skipshit )
  358.         {
  359.                 skipshit--;
  360.                 return;
  361.         }
  362.  
  363.         if( recbyte==0xE0 )
  364.         {
  365.                 was_E0 = 1;
  366.                 return;
  367.         }
  368.  
  369.  
  370.         if( recbyte==0xF0 )
  371.         {
  372.                 was_release = 1;
  373.                 return;
  374.         }
  375.  
  376.         if( recbyte==0xE1 ) // pause pressed
  377.         {
  378.                 skipshit=7;
  379.                 return; // skip next 7 bytes
  380.         }
  381.  
  382.         if( (recbyte==last_scancode) && (was_E0==last_scancode_E0) )
  383.         {
  384.                 if( was_release )
  385.                 {
  386.                         last_scancode = 0x00;
  387.                         last_scancode_E0 = 1; // impossible scancode: E0 00
  388.                 }
  389.                 else // was depress
  390.                 {
  391.                         was_E0 = 0;
  392.                         return;
  393.                 }
  394.         }
  395.  
  396.         if( !was_release )
  397.         {
  398.                 last_scancode = recbyte;
  399.                 last_scancode_E0 = was_E0;
  400.         }
  401.  
  402.         if( (recbyte==0x12) && was_E0 ) // skip E0 12
  403.         {
  404.                 was_E0 = 0;
  405.                 was_release = 0;
  406.                 return;
  407.         }
  408.  
  409.         to_zx( recbyte, was_E0, was_release ); // send valid scancode to zx decoding stage
  410. #ifdef LOGENABLE
  411.         char log_ps2keyboard_parse2[] = "KB(..,.,.)\r\n";
  412.         log_ps2keyboard_parse2[3] = ((recbyte >> 4) <= 9 )?'0'+(recbyte >> 4):'A'+(recbyte >> 4)-10;
  413.         log_ps2keyboard_parse2[4] = ((recbyte & 0x0F) <= 9 )?'0'+(recbyte & 0x0F):'A'+(recbyte & 0x0F)-10;
  414.         log_ps2keyboard_parse2[6] = (was_E0)?'1':'0';
  415.         log_ps2keyboard_parse2[8] = (was_release)?'1':'0';
  416.         to_log(log_ps2keyboard_parse2);
  417. #endif
  418.  
  419.         was_E0 = 0;
  420.         was_release = 0;
  421.  
  422.         return;
  423. }
  424.  
  425. volatile UWORD ps2mouse_shifter;
  426. volatile UBYTE ps2mouse_count;
  427. volatile UBYTE ps2mouse_timeout;
  428. volatile UBYTE ps2mouse_initstep;
  429. volatile UBYTE ps2mouse_resp_count;
  430. volatile UBYTE ps2mouse_cmd;
  431.  
  432. const UBYTE ps2mouse_init_sequence[] =
  433.         "\xFF"      //
  434.         "\xFF"      // reset
  435.         "\xFF"      //
  436.         "\xF3\xC8"  // set sample rate 200  | switch to
  437.         "\xF3\x64"  // set sample rate 100  |     scroll
  438.         "\xF3\x50"  // set sample rate 80   |         mode
  439.         "\xF2"      // get device type
  440.         "\xE6"      // set scaling 1:1
  441.         "\xF3\x64"  // set sample rate 100
  442.         "\xF4"      // enable
  443.         ;
  444.  
  445. static void ps2mouse_release_clk(void)
  446. {
  447.         ps2mouse_count = 12; //counter reinit
  448.         if( flags_register & FLAG_PS2MOUSE_DIRECTION )
  449.         {
  450.                 PS2MSDAT_DDR &= ~(1<<PS2MSDAT); //ps2 mouse data pin to input mode
  451.                 flags_register &= ~(FLAG_PS2MOUSE_DIRECTION); //set to receive mode
  452.         }
  453.  
  454.         //release ps2 receiver (disabled by now)
  455.         EIFR = (1<<INTF5); // clr any spurious int which can happen when we pulldown clock pin
  456.         PS2MSCLK_DDR  &= ~(1<<PS2MSCLK); //ps2 mouse clk pin to input mode
  457.         PS2MSCLK_PORT |= (1<<PS2MSCLK);  //release clk pin
  458. }
  459.  
  460. void ps2mouse_send(UBYTE data)
  461. {
  462. #ifdef LOGENABLE
  463. {
  464.         UBYTE b=data;
  465.         char log_ps2mouse_parse[] = "MS>..\r\n";
  466.         log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  467.         log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  468.         to_log(log_ps2mouse_parse);
  469. }
  470. #endif
  471.         ps2mouse_shifter = ps2_encode(data); //prepare data
  472.         flags_register |= FLAG_PS2MOUSE_DIRECTION; //set send mode
  473.         PS2MSCLK_PORT &= ~(1<<PS2MSCLK); //bring ps2 mouse clk pin -
  474.     PS2MSCLK_DDR  |= (1<<PS2MSCLK);  //generate interruption
  475. }
  476.  
  477. void ps2mouse_task(void)
  478. {
  479.         UBYTE b;
  480.  
  481.         if (  ps2mouse_count == 12  )
  482.         {
  483.                 if (  ps2mouse_init_sequence[ps2mouse_initstep] != 0  )
  484.                 {
  485.                         if ( ps2mouse_resp_count == 0 )
  486.                         {
  487.                                 //delay need for pause between release and hold clk pin
  488.                                 _delay_us(200);
  489.  
  490.                                 //initialization not complete
  491.                                 //send next command to mouse
  492.                                 ps2mouse_send(ps2mouse_init_sequence[ps2mouse_initstep]);
  493.                                 ps2mouse_resp_count++;
  494.                         }
  495.                 }
  496.                 else if ( ps2mouse_cmd != 0 )
  497.                 {
  498.                         if ( ps2mouse_resp_count == 0 )
  499.                         {
  500.                                 //delay need for pause between release and hold clk pin
  501.                                 _delay_us(200);
  502.  
  503.                                 //start command
  504.                                 flags_ex_register |= FLAG_EX_PS2MOUSE_CMD;
  505.                                 ps2mouse_send(ps2mouse_cmd);
  506.                                 ps2mouse_resp_count++;
  507.                         }
  508.                         else if( flags_ex_register & FLAG_EX_PS2MOUSE_CMD )
  509.                         {
  510.                                 switch( ps2mouse_cmd )
  511.                                 {
  512.                                         case PS2MOUSE_CMD_SET_RESOLUTION:
  513.                                                 if ( ps2mouse_resp_count == 2 )
  514.                                                 {
  515.                                                         //delay need for pause between release and hold clk pin
  516.                                                         _delay_us(200);
  517.  
  518.                                                         //send resolution
  519.                                                         ps2mouse_send(rtc_read(RTC_PS2MOUSE_RES_REG)&0x03);
  520.                                                         ps2mouse_resp_count++;
  521.                                                 }
  522.                                                 break;
  523.                                 }
  524.                         }
  525.                 }
  526.         }
  527.  
  528.         if ( ( ps2mouse_count<12 ) &&
  529.                  ( ps2mouse_timeout==0 ) )
  530.         {
  531. #ifdef LOGENABLE
  532.                 char log_ps2mouse_err[] = "MS.err.\r\n";
  533.                 if( flags_register&FLAG_PS2MOUSE_DIRECTION ) log_ps2mouse_err[2]='S';   else log_ps2mouse_err[2]='R';
  534.                 if( ps2mouse_count<10 ) log_ps2mouse_err[6]='0'+ps2mouse_count;  else log_ps2mouse_err[6]='A'+ps2mouse_count-10;
  535.                 to_log(log_ps2mouse_err);
  536. #endif
  537.                 //error due exchange data with PS/2 mouse
  538.  
  539.                 //get direction
  540.                 b = flags_register&FLAG_PS2MOUSE_DIRECTION;
  541.  
  542.                 //reset pins and states
  543.                 ps2mouse_release_clk();
  544.  
  545.                 //analizing error
  546.                 if( b && (ps2mouse_initstep==0) )
  547.                 {
  548.                         //error due send first init byte - mouse not connected to PS/2
  549.  
  550.                         //disable mouse
  551.                         zx_mouse_reset(0);
  552.                 }
  553.                 else
  554.                 {
  555.                         //error due receive or send non first byte - mouse connected to PS/2
  556.  
  557.                         //re-init mouse
  558.                         ps2mouse_initstep = 0;
  559.                 }
  560.         }
  561.  
  562.         if ( ps2mouse_count!=0 ) return; // not received anything
  563.  
  564.         if ( !(flags_register&FLAG_PS2MOUSE_DIRECTION) )
  565.         {
  566.                 //receive complete
  567.                 b = ps2_decode(ps2mouse_count, ps2mouse_shifter);
  568.  
  569. #ifdef LOGENABLE
  570. {
  571.         char log_ps2mouse_parse[] = "MS<..\r\n";
  572.         log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  573.         log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  574.         to_log(log_ps2mouse_parse);
  575. }
  576. #endif
  577.  
  578.                 //if command proceed than command code
  579.                 //if initialization proceed than current init code
  580.                 //else 0
  581.                 switch( (flags_ex_register&FLAG_EX_PS2MOUSE_CMD)?ps2mouse_cmd:ps2mouse_init_sequence[ps2mouse_initstep] )
  582.                 {
  583.                         //initialization complete - working mode
  584.                         case 0:
  585.                                 ps2mouse_resp_count++;
  586.                                 switch( ps2mouse_resp_count )
  587.                                 {
  588.                                 case 1:
  589.                                         //byte 1: Y overflow | X overflow | Y sign bit | X sign bit | 1 | Middle Btn | Right Btn | Left Btn
  590.                                         zx_mouse_button = (zx_mouse_button&0xF0) + ((b^0x07)&0x0F);
  591.                                         break;
  592.                                 case 2:
  593.                                         //byte 2: X movement
  594.                                         zx_mouse_x += b;
  595.                                         break;
  596.                                 case 3:
  597.                                         //byte 3: Y movement
  598.                                         zx_mouse_y += b;
  599.                                         if ( !(flags_register&FLAG_PS2MOUSE_TYPE) )
  600.                                         {
  601.                                                 //classical mouse
  602.                                                 ps2mouse_resp_count = 0;
  603.                                                 flags_register |= FLAG_PS2MOUSE_ZX_READY;
  604.                                         }
  605.                                         break;
  606.                                 case 4:
  607.                                         //byte 4: wheel movement
  608.                                         zx_mouse_button += ((b<<4)&0xF0);
  609.                                         flags_register |= FLAG_PS2MOUSE_ZX_READY;
  610.                                         ps2mouse_resp_count = 0;
  611.                                 }
  612.                                 break;
  613.  
  614.                         //reset command
  615.                         case PS2MOUSE_CMD_RESET:
  616.                                 if ( ps2mouse_resp_count==1 )
  617.                                 {
  618.                                         //must be acknowledge
  619.                                         if ( b != 0xFA )
  620.                                         {
  621.                                                 if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  622.                                                 {
  623.                                                         //reset command
  624.                                                         ps2mouse_cmd = 0;
  625.                                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  626.                                                 }
  627.                                                 else
  628.                                                 {
  629.                                                         //reset initialization
  630.                                                         ps2mouse_initstep = 0;
  631.                                                 }
  632.                                                 ps2mouse_resp_count = 0;
  633.                                                 break;
  634.                                         }
  635.                                 }
  636.                                 ps2mouse_resp_count++;
  637.                                 if ( ps2mouse_resp_count >= 4 )
  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.                                 break;
  653.  
  654.                         //get device type
  655.                         case PS2MOUSE_CMD_GET_TYPE:
  656.                                 if ( ps2mouse_resp_count==1 )
  657.                                 {
  658.                                         ps2mouse_resp_count++;
  659.                                         //must be acknowledge
  660.                                         if ( b != 0xFA )
  661.                                         {
  662.                                                 if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  663.                                                 {
  664.                                                         //reset command
  665.                                                         ps2mouse_cmd = 0;
  666.                                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  667.                                                 }
  668.                                                 else
  669.                                                 {
  670.                                                         //reset initialization
  671.                                                         ps2mouse_initstep = 0;
  672.                                                 }
  673.                                                 ps2mouse_resp_count = 0;
  674.                                         }
  675.                                         break;
  676.                                 }
  677.                                 else
  678.                                 {
  679.                                         ps2mouse_resp_count = 0;
  680.                                         if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  681.                                         {
  682.                                                 //reset command
  683.                                                 ps2mouse_cmd = 0;
  684.                                                 flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  685.                                         }
  686.                                         else
  687.                                         {
  688.                                                 //next initialization stage
  689.                                                 ps2mouse_initstep++;
  690.                                         }
  691.  
  692.                                         if ( b > 0 )
  693.                                         {
  694.                                                 flags_register |= FLAG_PS2MOUSE_TYPE;
  695.                                         }
  696.                                         else
  697.                                         {
  698.                                                 flags_register &= ~(FLAG_PS2MOUSE_TYPE);
  699.                                         }
  700.                                 }
  701.                                 break;
  702.  
  703.                         //set resolution
  704.                         case PS2MOUSE_CMD_SET_RESOLUTION:
  705.                                 //must be acknowledge
  706.                                 if ( b != 0xFA )
  707.                                 {
  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.                                                 //reset initialization
  717.                                                 ps2mouse_initstep = 0;
  718.                                         }
  719.                                         ps2mouse_resp_count = 0;
  720.                                 }
  721.                                 else
  722.                                 {
  723.                                         if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  724.                                         {
  725.                                                 if( ps2mouse_resp_count >= 3 )
  726.                                                 {
  727.                                                         ps2mouse_resp_count = 0;
  728.                                                         //reset command
  729.                                                         ps2mouse_cmd = 0;
  730.                                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  731.                                                 }
  732.                                                 else
  733.                                                 {
  734.                                                         ps2mouse_resp_count ++;
  735.                                                 }
  736.                                         }
  737.                                         else
  738.                                         {
  739.                                                 //next initialization stage
  740.                                                 ps2mouse_resp_count = 0;
  741.                                                 ps2mouse_initstep++;
  742.                                         }
  743.                                 }
  744.                                 break;
  745.  
  746.                         //other commands
  747.                         default:
  748.                                 if( flags_ex_register&FLAG_EX_PS2MOUSE_CMD )
  749.                                 {
  750.                                         //reset command
  751.                                         ps2mouse_cmd = 0;
  752.                                         flags_ex_register &= ~FLAG_EX_PS2MOUSE_CMD;
  753.                                 }
  754.                                 else
  755.                                 {
  756.                                         //next initialization stage
  757.                                         ps2mouse_initstep++;
  758.                                         if ( ps2mouse_resp_count==1 )
  759.                                         {
  760.                                                 //must be acknowledge
  761.                                                 if ( b != 0xFA )
  762.                                                 {
  763.                                                         //reset initialization
  764.                                                         ps2mouse_initstep = 0;
  765.                                                 }
  766.                                         }
  767.                                 }
  768.                                 ps2mouse_resp_count = 0;
  769.                                 break;
  770.                 }
  771.         }
  772. //#ifdef LOGENABLE
  773. //      else
  774. //      {
  775. //              //send complete
  776. //              char log_ps2mouse_parse[] = "MS>..\r\n";
  777. //              b = ps2mouse_init_sequence[ps2mouse_initstep];
  778. //              log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  779. //              log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  780. //              to_log(log_ps2mouse_parse);
  781. //      }
  782. //#endif
  783.  
  784.         ps2mouse_release_clk();
  785. }
  786.  
  787. void ps2mouse_set_resolution(UBYTE code)
  788. {
  789. #ifdef LOGENABLE
  790. {
  791.         UBYTE b = zx_mouse_button;
  792.         char log_ps2mouse_parse[] = "SS:..-..\r\n";
  793.         log_ps2mouse_parse[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  794.         log_ps2mouse_parse[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  795.         b = code;
  796.         log_ps2mouse_parse[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  797.         log_ps2mouse_parse[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  798.         to_log(log_ps2mouse_parse);
  799. }
  800. #endif
  801.  
  802.         //if pressed left and right buttons on mouse
  803.         if ( (zx_mouse_button & 0x03) == 0 )
  804.         {
  805.                 switch( code )
  806.                 {
  807.                         //keypad '*' - set default resolution
  808.                         case 0x7C:
  809.                                 rtc_write(RTC_PS2MOUSE_RES_REG,0x00);
  810.                                 ps2mouse_cmd = PS2MOUSE_CMD_SET_RESOLUTION;
  811.                                 break;
  812.  
  813.                         //keypad '+' - inc resolution
  814.                         case 0x79:
  815.                         {
  816.                                 UBYTE data = rtc_read(RTC_PS2MOUSE_RES_REG)&0x03;
  817.                                 if( data < 0x03 )
  818.                                 {
  819.                                         data++;
  820.                                 }
  821.                                 rtc_write(RTC_PS2MOUSE_RES_REG,data);
  822.                                 ps2mouse_cmd = PS2MOUSE_CMD_SET_RESOLUTION;
  823.                             break;
  824.                         }
  825.  
  826.                         //keypad '-' - dec resolution
  827.                         case 0x7B:
  828.                         {
  829.                                 UBYTE data = rtc_read(RTC_PS2MOUSE_RES_REG)&0x03;
  830.                                 if (data)
  831.                                 {
  832.                                         data--;
  833.                                 }
  834.                                 rtc_write(RTC_PS2MOUSE_RES_REG,data);
  835.                                 ps2mouse_cmd = PS2MOUSE_CMD_SET_RESOLUTION;
  836.                             break;
  837.                         }
  838.                 }
  839.         }
  840. }
  841.