Subversion Repositories pentevo

Rev

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