Subversion Repositories pentevo

Rev

Rev 119 | Rev 151 | 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. #include <avr/pgmspace.h>
  4. #include <util/delay.h>
  5.  
  6.  
  7. #include "mytypes.h"
  8. #include "zx.h"
  9. #include "pins.h"
  10. #include "getfaraddress.h"
  11. #include "main.h"
  12. #include "spi.h"
  13. #include "rs232.h"
  14. #include "ps2.h"
  15. #include "rtc.h"
  16.  
  17.  
  18.  
  19. //zx mouse registers
  20. volatile UBYTE zx_mouse_button;
  21. volatile UBYTE zx_mouse_x;
  22. volatile UBYTE zx_mouse_y;
  23.  
  24.  
  25.  
  26. #define ZX_FIFO_SIZE 256 /* do not change this since it must be exactly byte-wise */
  27.  
  28. UBYTE zx_fifo[ZX_FIFO_SIZE];
  29.  
  30. UBYTE zx_fifo_in_ptr;
  31. UBYTE zx_fifo_out_ptr;
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39. UBYTE zx_counters[40]; // filter ZX keystrokes here to assure every is pressed and released only once
  40. UBYTE zx_map[5]; // keys bitmap. send order: LSbit first, from [4] to [0]
  41.  
  42.  
  43. volatile UBYTE shift_pause;
  44.  
  45. UBYTE zx_realkbd[11];
  46.  
  47.  
  48.  
  49. /*
  50.  
  51. 69 - keypad 1
  52. 6B - keypad 4
  53. 6C - keypad 7
  54. 70 - keypad 0
  55. 71 - keypad .
  56. 72 - keypad 2
  57. 73 - keypad 5
  58. 74 - keypad 6
  59. 75 - keypad 8
  60. 79 - keypad +
  61. 7A - keypad 3
  62. 7B - keypad -
  63. 7C - keypad *
  64. 7D - keypad 9
  65. E0 5A - keypad enter
  66. E0 4A - keypad /
  67.  
  68. */
  69.  
  70. const UBYTE kmap[] PROGMEM =
  71. {
  72. NO_KEY,NO_KEY, // 00
  73. RST_48,NO_KEY, // 01  F9
  74. NO_KEY,NO_KEY, // 02
  75. NO_KEY,NO_KEY, // 03
  76. NO_KEY,NO_KEY, // 04
  77. NO_KEY,NO_KEY, // 05
  78. NO_KEY,NO_KEY, // 06
  79. RSTSYS,NO_KEY, // 07 F12
  80. NO_KEY,NO_KEY, // 08
  81. RST128,NO_KEY, // 09 F10
  82. NO_KEY,NO_KEY, // 0A
  83. NO_KEY,NO_KEY, // 0B
  84. NO_KEY,NO_KEY, // 0C
  85. KEY_CS,KEY_SP, // 0D TAB
  86. KEY_CS,KEY_1 , // 0E ~
  87. NO_KEY,NO_KEY, // 0F
  88.  
  89. NO_KEY,NO_KEY, // 10
  90. NO_KEY,NO_KEY, // 11
  91. KEY_CS,NO_KEY, // 12 LSHIFT
  92. NO_KEY,NO_KEY, // 13
  93. NO_KEY,NO_KEY, // 14
  94. KEY_Q ,NO_KEY, // 15 Q
  95. KEY_1 ,NO_KEY, // 16 1
  96. NO_KEY,NO_KEY, // 17
  97. NO_KEY,NO_KEY, // 18
  98. NO_KEY,NO_KEY, // 19
  99. KEY_Z ,NO_KEY, // 1A Z
  100. KEY_S ,NO_KEY, // 1B S
  101. KEY_A ,NO_KEY, // 1C A
  102. KEY_W ,NO_KEY, // 1D W
  103. KEY_2 ,NO_KEY, // 1E 2
  104. NO_KEY,NO_KEY, // 1F
  105.  
  106. NO_KEY,NO_KEY, // 20
  107. KEY_C ,NO_KEY, // 21 C
  108. KEY_X ,NO_KEY, // 22 X
  109. KEY_D ,NO_KEY, // 23 D
  110. KEY_E ,NO_KEY, // 24 E
  111. KEY_4 ,NO_KEY, // 25 4
  112. KEY_3 ,NO_KEY, // 26 3
  113. NO_KEY,NO_KEY, // 27
  114. NO_KEY,NO_KEY, // 28
  115. KEY_SP,NO_KEY, // 29 SPACE
  116. KEY_V ,NO_KEY, // 2A V
  117. KEY_F ,NO_KEY, // 2B F
  118. KEY_T ,NO_KEY, // 2C T
  119. KEY_R ,NO_KEY, // 2D R
  120. KEY_5 ,NO_KEY, // 2E 5
  121. NO_KEY,NO_KEY, // 2F
  122.  
  123. NO_KEY,NO_KEY, // 30
  124. KEY_N ,NO_KEY, // 31 N
  125. KEY_B ,NO_KEY, // 32 B
  126. KEY_H ,NO_KEY, // 33 H
  127. KEY_G ,NO_KEY, // 34 G
  128. KEY_Y ,NO_KEY, // 35 Y
  129. KEY_6 ,NO_KEY, // 36 6
  130. NO_KEY,NO_KEY, // 37
  131. NO_KEY,NO_KEY, // 38
  132. NO_KEY,NO_KEY, // 39
  133. KEY_M ,NO_KEY, // 3A M
  134. KEY_J ,NO_KEY, // 3B J
  135. KEY_U ,NO_KEY, // 3C U
  136. KEY_7 ,NO_KEY, // 3D 7
  137. KEY_8 ,NO_KEY, // 3E 8
  138. NO_KEY,NO_KEY, // 3F
  139.  
  140. NO_KEY,NO_KEY, // 40
  141. KEY_SS,KEY_N , // 41 ,
  142. KEY_K ,NO_KEY, // 42 K
  143. KEY_I ,NO_KEY, // 43 I
  144. KEY_O ,NO_KEY, // 44 O
  145. KEY_0 ,NO_KEY, // 45 0
  146. KEY_9 ,NO_KEY, // 46 9
  147. NO_KEY,NO_KEY, // 47
  148. NO_KEY,NO_KEY, // 48
  149. KEY_SS,KEY_M , // 49 .
  150. KEY_SS,KEY_C , // 4A /
  151. KEY_L ,NO_KEY, // 4B L
  152. KEY_SS,KEY_Z , // 4C :
  153. KEY_P ,NO_KEY, // 4D P
  154. KEY_SS,KEY_J , // 4E -
  155. NO_KEY,NO_KEY, // 4F
  156.  
  157. NO_KEY,NO_KEY, // 50
  158. NO_KEY,NO_KEY, // 51
  159. KEY_SS,KEY_P , // 52 "
  160. NO_KEY,NO_KEY, // 53
  161. KEY_SS,KEY_8 , // 54 [
  162. KEY_SS,KEY_K , // 55 +
  163. NO_KEY,NO_KEY, // 56
  164. NO_KEY,NO_KEY, // 57
  165. KEY_CS,KEY_2 , // 58 CAPSLOCK
  166. KEY_SS,NO_KEY, // 59 RSHIFT
  167. KEY_EN,NO_KEY, // 5A ENTER
  168. KEY_SS,KEY_9 , // 5B ]
  169. NO_KEY,NO_KEY, // 5C
  170. KEY_SS,KEY_CS, // 5D backslash
  171. NO_KEY,NO_KEY, // 5E
  172. NO_KEY,NO_KEY, // 5F
  173.  
  174. NO_KEY,NO_KEY, // 60
  175. KEY_SS,KEY_CS, // 61 backslash
  176. NO_KEY,NO_KEY, // 62
  177. NO_KEY,NO_KEY, // 63
  178. NO_KEY,NO_KEY, // 64
  179. NO_KEY,NO_KEY, // 65
  180. KEY_CS,KEY_0 , // 66 BACKSPACE
  181. NO_KEY,NO_KEY, // 67
  182. NO_KEY,NO_KEY, // 68
  183. KEY_1 ,NO_KEY, // 69 keypad 1
  184. NO_KEY,NO_KEY, // 6A
  185. KEY_4 ,NO_KEY, // 6B keypad 4
  186. KEY_7 ,NO_KEY, // 6C keypad 7
  187. NO_KEY,NO_KEY, // 6D
  188. NO_KEY,NO_KEY, // 6E
  189. NO_KEY,NO_KEY, // 6F
  190.  
  191. KEY_0 ,NO_KEY, // 70 keypad 0
  192. KEY_SS,KEY_M , // 71 keypad .
  193. KEY_2 ,NO_KEY, // 72 keypad 2
  194. KEY_5 ,NO_KEY, // 73 keypad 5
  195. KEY_6 ,NO_KEY, // 74 keypad 6
  196. KEY_8 ,NO_KEY, // 75 keypad 8
  197. CLRKYS,NO_KEY, // 76 ESC
  198. NO_KEY,NO_KEY, // 77
  199. RSTRDS,NO_KEY, // 78 F11
  200. KEY_SS,KEY_K , // 79 keypad +
  201. KEY_3 ,NO_KEY, // 7A keypad 3
  202. KEY_SS,KEY_J , // 7B keypad -
  203. KEY_SS,KEY_B , // 7C keypad *
  204. KEY_9 ,NO_KEY, // 7D keypad 9
  205. NO_KEY,NO_KEY, // 7E Scroll Lock
  206. NO_KEY,NO_KEY  // 7F
  207. };
  208.  
  209.  
  210.  
  211. const UBYTE kmap_E0[] PROGMEM =
  212. {
  213. NO_KEY,NO_KEY, // 60
  214. NO_KEY,NO_KEY, // 61
  215. NO_KEY,NO_KEY, // 62
  216. NO_KEY,NO_KEY, // 63
  217. NO_KEY,NO_KEY, // 64
  218. NO_KEY,NO_KEY, // 65
  219. NO_KEY,NO_KEY, // 66
  220. NO_KEY,NO_KEY, // 67
  221. NO_KEY,NO_KEY, // 68
  222. KEY_SS,KEY_E , // 69 END
  223. NO_KEY,NO_KEY, // 6A
  224. KEY_CS,KEY_5 , // 6B LEFT
  225. KEY_SS,KEY_Q , // 6C HOME
  226. NO_KEY,NO_KEY, // 6D
  227. NO_KEY,NO_KEY, // 6E
  228. NO_KEY,NO_KEY, // 6F
  229.  
  230. KEY_SS,KEY_W , // 70 INS
  231. KEY_CS,KEY_9 , // 71 DEL
  232. KEY_CS,KEY_6 , // 72 DOWN
  233. NO_KEY,NO_KEY, // 73
  234. KEY_CS,KEY_8 , // 74 RIGHT
  235. KEY_CS,KEY_7 , // 75 UP
  236. CLRKYS,NO_KEY, // 76 ESC
  237. NO_KEY,NO_KEY, // 77
  238. NO_KEY,NO_KEY, // 78
  239. NO_KEY,NO_KEY, // 79
  240. KEY_CS,KEY_4 , // 7A PGDN
  241. NO_KEY,NO_KEY, // 7B
  242. NO_KEY,NO_KEY, // 7C
  243. KEY_CS,KEY_3 , // 7D PGUP
  244. NO_KEY,NO_KEY, // 7E
  245. NO_KEY,NO_KEY  // 7F
  246. };
  247.  
  248.  
  249. //struct zx current;
  250. //struct zx towrite;
  251. //volatile UBYTE keys_changed;
  252. //volatile UBYTE send_state;
  253.  
  254.  
  255. void zx_init(void)
  256. {
  257.         BYTE i;
  258.  
  259.         i=39;
  260.         do /*zx_counters[i] =*/ zx_counters[i] = 0x00; while( (--i)>=0 );
  261.  
  262.         zx_fifo_in_ptr=zx_fifo_out_ptr=0;
  263.  
  264.         zx_task(ZX_TASK_INIT);
  265.  
  266.  
  267.         nSPICS_DDR      |= (1<<nSPICS);
  268.         nSPICS_PORT &= ~(1<<nSPICS);
  269.         _delay_us(10);
  270.         nSPICS_PORT |= (1<<nSPICS);
  271.         _delay_us(10);
  272.         spi_send(0xE2); // send specific reset
  273.         _delay_us(10);
  274.         nSPICS_PORT &= ~(1<<nSPICS);
  275.         _delay_us(10);
  276.         nSPICS_PORT |= (1<<nSPICS);
  277.  
  278. }
  279.  
  280. UBYTE zx_spi_send(UBYTE addr, UBYTE data, UBYTE mask)
  281. {
  282.         UBYTE status;
  283.         UBYTE ret;
  284.         nSPICS_PORT &= ~(1<<nSPICS); // fix for status locking
  285.         nSPICS_PORT |= (1<<nSPICS);  // set address of SPI register
  286.         status = spi_send(addr);
  287.         nSPICS_PORT &= ~(1<<nSPICS); // send data for that register
  288.         ret = spi_send(data);
  289.         nSPICS_PORT |= (1<<nSPICS);
  290.  
  291.         //if CPU waited
  292.         if ( status&mask ) zx_wait_task(status);
  293.  
  294.         return ret;
  295. }
  296.  
  297.  
  298. void zx_task(UBYTE operation) // zx task, tracks when there is need to send new keymap to the fpga
  299. {
  300.         static UBYTE prev_code;
  301.         static UBYTE task_state;
  302.         static UBYTE reset_type;
  303.  
  304.         UBYTE was_data;
  305.         UBYTE code,keynum,keybit;
  306.  
  307.         if(operation==ZX_TASK_INIT)
  308.         {
  309.                 reset_type = 0;
  310.                 prev_code = KEY_V+1; // impossible scancode
  311.                 task_state = 0;
  312.                 shift_pause = 0;
  313.  
  314.                 zx_clr_kb();
  315.         }
  316.         else /*if(operation==ZX_TASK_WORK)*/
  317.  
  318.         // шч ЇшЇ√ яЁшїюфшЄ: эрцрЄш  ш юЄцрЄш  ЁхёхЄют, эрцрЄш  ш юЄцрЄш  ъэюяъют, CLRKYS (Єюы№ъю эрцрэшх).
  319.         // чрфрўр: єяфхщЄшЄ№ т ёююЄтхЄёЄтшш ё ¤Єшь сшЄьря ъэюяюъ, яюё√ырЄ№ хую т Їяує, яюё√ырЄ№ ЁхёхЄ√.
  320.         // ъЁюьх Єюую, фхырЄ№ ярєчє т єяфхщЄх сшЄьряр ш яюё√ыъх хую т Їяур ьхцфє эрцрЄшхь CS|SS ш яюёыхфє■∙хщ эх-CS|SS ъэюяъш,
  321.         // Ёртэю ъръ ш ьхцфє юЄцрЄшхь эх-CS|SS ъэюяъш ш яюёыхфє■∙шь юЄцрЄшхь CS|SS.
  322.  
  323.         // ёэрўрыр фхырхь Єєяю схч эшъръшї ярєч - ўЄюс√ ЁрсюЄрыю тююс∙х ё ЇшЇющ
  324.  
  325.         {
  326.                 if( !task_state )
  327.                 {
  328.                         nSPICS_PORT |= (1<<nSPICS);
  329.  
  330.                         was_data = 0;
  331.  
  332.                         while( !zx_fifo_isempty() )
  333.                         {
  334.                                 code=zx_fifo_copy(); // don't remove byte from fifo!
  335.  
  336.                                 if( code==CLRKYS )
  337.                                 {
  338.                                         was_data = 1; // we've got something!
  339.  
  340.                                         zx_fifo_get(); // remove byte from fifo
  341.  
  342.                                         reset_type = 0;
  343.                                         prev_code  = KEY_V+1;
  344.  
  345.                                         zx_clr_kb();
  346.  
  347.                                         break; // flush changes immediately to the fpga
  348.                                 }
  349.                                 else if( (code&KEY_MASK) >= RSTSYS )
  350.                                 {
  351.                                         was_data = 1; // we've got something!
  352.  
  353.                                         zx_fifo_get(); // remove byte from fifo
  354.  
  355.                                         if( code&PRESS_MASK ) // reset key pressed
  356.                                         {
  357.                                                 reset_type      = 0x30 & ((code+1)<<4);
  358.                                                 reset_type += 2;
  359.  
  360.                                                 break; // flush immediately
  361.                                         }
  362.                                         else // reset key released
  363.                                         {
  364.                                                 reset_type = 0;
  365.                                         }
  366.                                 }
  367.                                 else /*if( (code&KEY_MASK) < 40 )*/
  368.                                 {
  369.                                         if( shift_pause ) // if we inside pause interval and need checking
  370.                                         {
  371.                                                 if( (PRESS_MASK&prev_code) && (PRESS_MASK&code) )
  372.                                                 {
  373.                                                         if( /* prev key was CS|SS down */
  374.                                                                 ( (PRESS_MASK|KEY_CS)<=prev_code && prev_code<=(PRESS_MASK|KEY_SS) ) &&
  375.                                                                 /* curr key is not-CS|SS down */
  376.                                                                 ( code<(PRESS_MASK|KEY_CS) || (PRESS_MASK|KEY_SS)<code )
  377.                                                         )
  378.                                                                 break; // while loop
  379.                                                 }
  380.  
  381.                                                 if( (!(PRESS_MASK&prev_code)) && (!(PRESS_MASK&code)) )
  382.                                                 {
  383.                                                         if( /* prev key was not-CS|SS up */
  384.                                                                 ( prev_code<KEY_CS || KEY_SS<prev_code ) &&
  385.                                                                 /* curr key is CS|SS up */
  386.                                                                 ( KEY_CS<=prev_code && prev_code<=KEY_SS )
  387.                                                         )
  388.                                                                 break;
  389.                                                 }
  390.                                         }
  391.  
  392.                                         // just normal processing out of pause interval
  393.                                         keynum = (code&KEY_MASK)>>3;
  394.  
  395.                                         keybit = 0x0080 >> (code&7); // KEY_MASK - эрфьэюцхёЄтю сшЄют 7
  396.  
  397.                                         if( code&PRESS_MASK )
  398.                                                 zx_map[keynum] |=       keybit;
  399.                                         else
  400.                                                 zx_map[keynum] &= (~keybit);
  401.  
  402.                                         prev_code = code;
  403.                                         zx_fifo_get();
  404.                                         shift_pause = SHIFT_PAUSE; // init wait timer
  405.  
  406.                                         was_data = 1;
  407.                                 }
  408.                         }
  409.  
  410.                         if ( zx_realkbd[10] )
  411.                         {
  412.                                 for (UBYTE i=0; i<5; i++)
  413.                                 {
  414.                                          UBYTE tmp;
  415.                                          tmp = zx_realkbd[i+5];
  416.                                          was_data |= zx_realkbd[i] ^ tmp;
  417.                                          zx_realkbd[i] = tmp;
  418.                                 }
  419.                                 zx_realkbd[10] = 0;
  420.                         }
  421.  
  422.                         if( was_data ) // initialize transfer
  423.                         {
  424.                                 task_state = 7;
  425.                         }
  426.                 }
  427.                 else // sending bytes one by one in each state
  428.                 {
  429.                         task_state--;
  430. #ifdef LOGENABLE
  431.         char log_task_state[] = "TS..\r\n";
  432.         log_task_state[2] = ((task_state >> 4) <= 9 )?'0'+(task_state >> 4):'A'+(task_state >> 4)-10;
  433.         log_task_state[3] = ((task_state & 0x0F) <= 9 )?'0'+(task_state & 0x0F):'A'+(task_state & 0x0F)-10;
  434.         to_log(log_task_state);
  435. #endif
  436.  
  437.                         if( task_state==6 ) // send (or not) reset
  438.                         {
  439.                                 if( reset_type )
  440.                                 {
  441. //                                      nSPICS_PORT |= (1<<nSPICS);  // set address of SPI register
  442. //                                      spi_send(SPI_RST_REG);
  443. //                                      nSPICS_PORT &= ~(1<<nSPICS); // send data for that register
  444. //                                      spi_send( reset_type );
  445. //                                      nSPICS_PORT |= (1<<nSPICS);
  446.                                         zx_spi_send(SPI_RST_REG, reset_type, 0x7F);
  447. #ifdef LOGENABLE
  448.         char log_reset_type[] = "TR..\r\n";
  449.         log_reset_type[2] = ((reset_type >> 4) <= 9 )?'0'+(reset_type >> 4):'A'+(reset_type >> 4)-10;
  450.         log_reset_type[3] = ((reset_type & 0x0F) <= 9 )?'0'+(reset_type & 0x0F):'A'+(reset_type & 0x0F)-10;
  451.         to_log(log_reset_type);
  452. #endif
  453.                                 }
  454.                         }
  455.                         else if( task_state>0 )// task_state==5..1
  456.                         {
  457. //                              nSPICS_PORT |= (1<<nSPICS);  // set address of SPI register
  458. //                              spi_send(SPI_KBD_DAT);
  459. //                              nSPICS_PORT &= ~(1<<nSPICS);
  460. //                              spi_send( zx_map[task_state-1] );
  461. //                              nSPICS_PORT |= (1<<nSPICS);
  462.                                 UBYTE key_data;
  463.                                 key_data = zx_map[task_state-1] | ~zx_realkbd[task_state-1];
  464.                                 zx_spi_send(SPI_KBD_DAT, key_data, 0x7F);
  465. #ifdef LOGENABLE
  466.         char log_zxmap_task_state[] = "TK..\r\n";
  467.         log_zxmap_task_state[2] = ((key_data >> 4) <= 9 )?'0'+(key_data >> 4):'A'+(key_data >> 4)-10;
  468.         log_zxmap_task_state[3] = ((key_data & 0x0F) <= 9 )?'0'+(key_data & 0x0F):'A'+(key_data & 0x0F)-10;
  469.         to_log(log_zxmap_task_state);
  470. #endif
  471.                         }
  472.                         else // task_state==0
  473.                         {
  474.                                 UBYTE status;
  475.                                 nSPICS_PORT |= (1<<nSPICS);
  476.                                 status = spi_send(SPI_KBD_STB);    // strobe input kbd data to the Z80 port engine
  477. //                              nSPICS_PORT &= ~(1<<nSPICS);
  478. //                              nSPICS_PORT &= ~(1<<nSPICS);
  479.                                 nSPICS_PORT &= ~(1<<nSPICS);
  480. //                              nSPICS_PORT |= (1<<nSPICS);
  481. //                              nSPICS_PORT |= (1<<nSPICS);
  482.                                 nSPICS_PORT |= (1<<nSPICS);
  483.                                 if ( status&0x7F ) zx_wait_task(status);
  484. #ifdef LOGENABLE
  485.         to_log("STB\r\n");
  486. #endif
  487.                         }
  488.                 }
  489.         }
  490.  
  491. }
  492.  
  493. void zx_clr_kb(void)
  494. {
  495.         BYTE i;
  496.  
  497.         i=4;
  498.         do
  499.                 zx_map[i] = 0;
  500.         while( (--i)>=0 );
  501.  
  502.         i=0;
  503.         do
  504.                 zx_realkbd[i] = 0xff;
  505.         while( (++i)<=9 );
  506.         zx_realkbd[10] = 0;
  507.  
  508.  
  509.         i=39;
  510.         do
  511.                 zx_counters[i] = 0;
  512.         while( (--i)>=0 );
  513. }
  514.  
  515.  
  516. void to_zx(UBYTE scancode, UBYTE was_E0, UBYTE was_release)
  517. {
  518.         ULONG tbldisp,tblptr;
  519.         UBYTE tbl1,tbl2;
  520.  
  521.  
  522.         tbl1=tbl2=NO_KEY;
  523.  
  524.         if( was_E0 )
  525.         {
  526.                 if( scancode==0x4A ) // keypad /
  527.                 {
  528.                         tbl1 = KEY_SS;
  529.                         tbl2 = KEY_V;
  530.                 }
  531.                 else if( scancode==0x5A ) // keypad enter
  532.                 {
  533.                         tbl1 = KEY_EN;
  534.                 }
  535.                 else if( (scancode>=0x60) && (scancode<=0x7F) )
  536.                 {
  537.                         tbldisp = (scancode-0x60)*2;
  538.                         tblptr = tbldisp + GET_FAR_ADDRESS(kmap_E0);
  539.  
  540.                         tbl1 = pgm_read_byte_far( tblptr++ );
  541.                         tbl2 = pgm_read_byte_far( tblptr );
  542.                 }
  543.         }
  544.         else
  545.         {
  546.                 if( scancode<=0x7F )
  547.                 {
  548.                         tbldisp = scancode*2;
  549.                         tblptr = tbldisp + GET_FAR_ADDRESS(kmap);
  550.  
  551.                         tbl1 = pgm_read_byte_far( tblptr++ );
  552.                         tbl2 = pgm_read_byte_far( tblptr );
  553.                 }
  554.  
  555.                 //check key of vga mode switcher
  556.                 if ( ( scancode == 0x7E ) && !was_release) zx_vga_switcher();
  557.         }
  558.  
  559.         if( tbl1!=NO_KEY )
  560.         {
  561.                 update_keys(tbl1,was_release);
  562.  
  563.                 if( tbl2!=NO_KEY ) update_keys(tbl2,was_release);
  564.         }
  565. }
  566.  
  567.  
  568.  
  569. void update_keys(UBYTE zxcode, UBYTE was_release)
  570. {
  571.         BYTE i;
  572.  
  573.         if( zxcode==NO_KEY )
  574.         {
  575.                 /* NOTHING */
  576.         }
  577.         else if( (zxcode==CLRKYS) && (!was_release) ) // does not have release option
  578.         {
  579.                 i=39;
  580.                 do zx_counters[i]=0; while( (--i)>=0 );
  581.  
  582.                 if( !zx_fifo_isfull() )
  583.                         zx_fifo_put(CLRKYS);
  584.         }
  585.         else if( zxcode>=RSTSYS ) // resets - press and release
  586.         {
  587.                 if( !zx_fifo_isfull() )
  588.                         zx_fifo_put( (was_release ? 0 : PRESS_MASK) | zxcode );
  589.         }
  590.         else if( zxcode < 40 ); // ordinary keys too
  591.         {
  592.                 if( was_release )
  593.                 {
  594.                         if( zx_counters[zxcode] && !(--zx_counters[zxcode]) ) // left-to-right evaluation and shortcutting
  595.                         {
  596.                                 if( !zx_fifo_isfull() )
  597.                                         zx_fifo_put(zxcode);
  598.                         }
  599.                 }
  600.                 else // key pressed
  601.                 {
  602.                         if( !(zx_counters[zxcode]++) )
  603.                         {
  604.                                 if( !zx_fifo_isfull() )
  605.                                         zx_fifo_put( PRESS_MASK | zxcode );
  606.                         }
  607.                 }
  608.         }
  609. }
  610.  
  611.  
  612. void zx_fifo_put(UBYTE input)
  613. {
  614.         zx_fifo[zx_fifo_in_ptr++] = input;
  615. }
  616.  
  617. UBYTE zx_fifo_isfull(void)
  618. {
  619.         //always one byte unused, to distinguish between totally full fifo and empty fifo
  620.         return( (zx_fifo_in_ptr+1)==zx_fifo_out_ptr );
  621. }
  622.  
  623.  
  624. UBYTE zx_fifo_isempty(void)
  625. {
  626.         return (zx_fifo_in_ptr==zx_fifo_out_ptr);
  627. }
  628.  
  629. UBYTE zx_fifo_get(void)
  630. {
  631.         return zx_fifo[zx_fifo_out_ptr++]; // get byte permanently
  632. }
  633.  
  634. UBYTE zx_fifo_copy(void)
  635. {
  636.         return zx_fifo[zx_fifo_out_ptr]; // get byte but leave it in fifo
  637. }
  638.  
  639.  
  640.  
  641. void zx_mouse_reset(UBYTE enable)
  642. {
  643.         if ( enable )
  644.         {
  645.                 //ZX autodetecting found mouse on this values
  646.                 zx_mouse_x = 0;
  647.                 zx_mouse_y = 1;
  648.         }
  649.         else
  650.         {
  651.                 //ZX autodetecting not found mouse on this values
  652.                 zx_mouse_y = zx_mouse_x = 0xFF;
  653.         }
  654.         zx_mouse_button = 0xFF;
  655.         flags_register|=(FLAG_PS2MOUSE_ZX_READY);
  656. }
  657.  
  658. void zx_mouse_task(void)
  659. {
  660.         if ( flags_register&FLAG_PS2MOUSE_ZX_READY )
  661.         {
  662. #ifdef LOGENABLE
  663.         char log_zxmouse[] = "ZXM.. .. ..\r\n";
  664.         log_zxmouse[3] = ((zx_mouse_button >> 4) <= 9 )?'0'+(zx_mouse_button >> 4):'A'+(zx_mouse_button >> 4)-10;
  665.         log_zxmouse[4] = ((zx_mouse_button & 0x0F) <= 9 )?'0'+(zx_mouse_button & 0x0F):'A'+(zx_mouse_button & 0x0F)-10;
  666.         log_zxmouse[6] = ((zx_mouse_x >> 4) <= 9 )?'0'+(zx_mouse_x >> 4):'A'+(zx_mouse_x >> 4)-10;
  667.         log_zxmouse[7] = ((zx_mouse_x & 0x0F) <= 9 )?'0'+(zx_mouse_x & 0x0F):'A'+(zx_mouse_x & 0x0F)-10;
  668.         log_zxmouse[9] = ((zx_mouse_y >> 4) <= 9 )?'0'+(zx_mouse_y >> 4):'A'+(zx_mouse_y >> 4)-10;
  669.         log_zxmouse[10] = ((zx_mouse_y & 0x0F) <= 9 )?'0'+(zx_mouse_y & 0x0F):'A'+(zx_mouse_y & 0x0F)-10;
  670.         to_log(log_zxmouse);
  671. #endif
  672.                 //TODO: яюър ёфхыры ёъюяюь, яюЄюь ёфхырЄ№ яю юфэюьє срщЄє чр чрїюф
  673.  
  674. //              nSPICS_PORT |= (1<<nSPICS);  // set address of SPI register
  675. //              spi_send(SPI_MOUSE_BTN);
  676. //              nSPICS_PORT &= ~(1<<nSPICS);
  677. //              spi_send(zx_mouse_button);
  678. //              nSPICS_PORT |= (1<<nSPICS);
  679.                 zx_spi_send(SPI_MOUSE_BTN, zx_mouse_button, 0x7F);
  680.  
  681. //              nSPICS_PORT |= (1<<nSPICS);  // set address of SPI register
  682. //              spi_send(SPI_MOUSE_X);
  683. //              nSPICS_PORT &= ~(1<<nSPICS);
  684. //              spi_send(zx_mouse_x);
  685. //              nSPICS_PORT |= (1<<nSPICS);
  686.                 zx_spi_send(SPI_MOUSE_X, zx_mouse_x, 0x7F);
  687.  
  688. //              nSPICS_PORT |= (1<<nSPICS);  // set address of SPI register
  689. //              spi_send(SPI_MOUSE_Y);
  690. //              nSPICS_PORT &= ~(1<<nSPICS);
  691. //              spi_send(zx_mouse_y);
  692. //              nSPICS_PORT |= (1<<nSPICS);
  693.                 zx_spi_send(SPI_MOUSE_Y, zx_mouse_y, 0x7F);
  694.  
  695.                 //data sended - reset flag
  696.                 flags_register&=~(FLAG_PS2MOUSE_ZX_READY);
  697.         }
  698. }
  699.  
  700.  
  701. void zx_wait_task(UBYTE status)
  702. {
  703.         UBYTE addr = 0;
  704.         UBYTE data = 0xFF;
  705.  
  706.         //reset flag
  707.         flags_register &= ~FLAG_SPI_INT;
  708.  
  709.         //prepare data
  710.         switch( status&0x7F )
  711.         {
  712.         case ZXW_GLUK_CLOCK:
  713.                 {
  714.                         addr = zx_spi_send(SPI_GLUK_ADDR, data, 0);
  715.                         if ( status&0x80 ) data = gluk_get_reg(addr);
  716.                         break;
  717.                 }
  718.         }
  719.  
  720.         if ( status&0x80 ) zx_spi_send(SPI_WAIT_DATA, data, 0);
  721.         else data = zx_spi_send(SPI_WAIT_DATA, data, 0);
  722.  
  723.         if ( !(status&0x80) )
  724.         {
  725.                 //save data
  726.                 switch( status&0x7F )
  727.                 {
  728.                 case ZXW_GLUK_CLOCK:
  729.                         {
  730.                                 gluk_set_reg(addr, data);
  731.                                 break;
  732.                         }
  733.                 }
  734.         }
  735. /*#ifdef LOGENABLE
  736.         char log_wait[] = "W..A..D..\r\n";
  737.         log_wait[1] = ((status >> 4) <= 9 )?'0'+(status >> 4):'A'+(status >> 4)-10;
  738.         log_wait[2] = ((status & 0x0F) <= 9 )?'0'+(status & 0x0F):'A'+(status & 0x0F)-10;
  739.         log_wait[4] = ((addr >> 4) <= 9 )?'0'+(addr >> 4):'A'+(addr >> 4)-10;
  740.         log_wait[5] = ((addr & 0x0F) <= 9 )?'0'+(addr & 0x0F):'A'+(addr & 0x0F)-10;
  741.         log_wait[7] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+(data >> 4)-10;
  742.         log_wait[8] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+(data & 0x0F)-10;
  743.         to_log(log_wait);
  744. #endif   */
  745. }
  746.  
  747. void zx_vga_switcher(void)
  748. {
  749.         //invert VGA mode
  750.         modes_register ^= MODE_VGA;
  751.  
  752.         //send mode to FPGA
  753.         zx_spi_send(SPI_VGA_REG, modes_register&MODE_VGA, 0x7F);
  754.  
  755.         //save mode register to RTC NVRAM
  756.         rtc_write(RTC_COMMON_MODE_REG, modes_register);
  757. }
  758.