Subversion Repositories pentevo

Rev

Rev 11 | Rev 70 | 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 "spi.h"
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18. #define ZX_FIFO_SIZE 256 /* do not change this since it must be exactly byte-wise */
  19.  
  20. UBYTE zx_fifo[ZX_FIFO_SIZE];
  21.  
  22. UBYTE zx_fifo_in_ptr;
  23. UBYTE zx_fifo_out_ptr;
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  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.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43. /*
  44.  
  45. 69 - keypad 1
  46. 6B - keypad 4
  47. 6C - keypad 7
  48. 70 - keypad 0
  49. 71 - keypad .
  50. 72 - keypad 2
  51. 73 - keypad 5
  52. 74 - keypad 6
  53. 75 - keypad 8
  54. 79 - keypad +
  55. 7A - keypad 3
  56. 7B - keypad -
  57. 7C - keypad *
  58. 7D - keypad 9
  59. E0 5A - keypad enter
  60. E0 4A - keypad /
  61.  
  62. */
  63.  
  64. const UBYTE kmap[] PROGMEM =
  65. {
  66. NO_KEY,NO_KEY, // 00
  67. RST_48,NO_KEY, // 01  F9
  68. NO_KEY,NO_KEY, // 02
  69. NO_KEY,NO_KEY, // 03
  70. NO_KEY,NO_KEY, // 04
  71. NO_KEY,NO_KEY, // 05
  72. NO_KEY,NO_KEY, // 06
  73. RSTSYS,NO_KEY, // 07 F12
  74. NO_KEY,NO_KEY, // 08
  75. RST128,NO_KEY, // 09 F10
  76. NO_KEY,NO_KEY, // 0A
  77. NO_KEY,NO_KEY, // 0B
  78. NO_KEY,NO_KEY, // 0C
  79. KEY_CS,KEY_SP, // 0D TAB
  80. KEY_CS,KEY_1 , // 0E ~
  81. NO_KEY,NO_KEY, // 0F
  82.  
  83. NO_KEY,NO_KEY, // 10
  84. NO_KEY,NO_KEY, // 11
  85. KEY_CS,NO_KEY, // 12 LSHIFT
  86. NO_KEY,NO_KEY, // 13
  87. NO_KEY,NO_KEY, // 14
  88. KEY_Q ,NO_KEY, // 15 Q
  89. KEY_1 ,NO_KEY, // 16 1
  90. NO_KEY,NO_KEY, // 17
  91. NO_KEY,NO_KEY, // 18
  92. NO_KEY,NO_KEY, // 19
  93. KEY_Z ,NO_KEY, // 1A Z
  94. KEY_S ,NO_KEY, // 1B S
  95. KEY_A ,NO_KEY, // 1C A
  96. KEY_W ,NO_KEY, // 1D W
  97. KEY_2 ,NO_KEY, // 1E 2
  98. NO_KEY,NO_KEY, // 1F
  99.  
  100. NO_KEY,NO_KEY, // 20
  101. KEY_C ,NO_KEY, // 21 C
  102. KEY_X ,NO_KEY, // 22 X
  103. KEY_D ,NO_KEY, // 23 D
  104. KEY_E ,NO_KEY, // 24 E
  105. KEY_4 ,NO_KEY, // 25 4
  106. KEY_3 ,NO_KEY, // 26 3
  107. NO_KEY,NO_KEY, // 27
  108. NO_KEY,NO_KEY, // 28
  109. KEY_SP,NO_KEY, // 29 SPACE
  110. KEY_V ,NO_KEY, // 2A V
  111. KEY_F ,NO_KEY, // 2B F
  112. KEY_T ,NO_KEY, // 2C T
  113. KEY_R ,NO_KEY, // 2D R
  114. KEY_5 ,NO_KEY, // 2E 5
  115. NO_KEY,NO_KEY, // 2F
  116.  
  117. NO_KEY,NO_KEY, // 30
  118. KEY_N ,NO_KEY, // 31 N
  119. KEY_B ,NO_KEY, // 32 B
  120. KEY_H ,NO_KEY, // 33 H
  121. KEY_G ,NO_KEY, // 34 G
  122. KEY_Y ,NO_KEY, // 35 Y
  123. KEY_6 ,NO_KEY, // 36 6
  124. NO_KEY,NO_KEY, // 37
  125. NO_KEY,NO_KEY, // 38
  126. NO_KEY,NO_KEY, // 39
  127. KEY_M ,NO_KEY, // 3A M
  128. KEY_J ,NO_KEY, // 3B J
  129. KEY_U ,NO_KEY, // 3C U
  130. KEY_7 ,NO_KEY, // 3D 7
  131. KEY_8 ,NO_KEY, // 3E 8
  132. NO_KEY,NO_KEY, // 3F
  133.  
  134. NO_KEY,NO_KEY, // 40
  135. KEY_SS,KEY_N , // 41 ,
  136. KEY_K ,NO_KEY, // 42 K
  137. KEY_I ,NO_KEY, // 43 I
  138. KEY_O ,NO_KEY, // 44 O
  139. KEY_0 ,NO_KEY, // 45 0
  140. KEY_9 ,NO_KEY, // 46 9
  141. NO_KEY,NO_KEY, // 47
  142. NO_KEY,NO_KEY, // 48
  143. KEY_SS,KEY_M , // 49 .
  144. KEY_SS,KEY_C , // 4A /
  145. KEY_L ,NO_KEY, // 4B L
  146. KEY_SS,KEY_Z , // 4C :
  147. KEY_P ,NO_KEY, // 4D P
  148. KEY_SS,KEY_J , // 4E -
  149. NO_KEY,NO_KEY, // 4F
  150.  
  151. NO_KEY,NO_KEY, // 50
  152. NO_KEY,NO_KEY, // 51
  153. KEY_SS,KEY_P , // 52 "
  154. NO_KEY,NO_KEY, // 53
  155. KEY_SS,KEY_8 , // 54 [
  156. KEY_SS,KEY_K , // 55 +
  157. NO_KEY,NO_KEY, // 56
  158. NO_KEY,NO_KEY, // 57
  159. KEY_CS,KEY_2 , // 58 CAPSLOCK
  160. KEY_SS,NO_KEY, // 59 RSHIFT
  161. KEY_EN,NO_KEY, // 5A ENTER
  162. KEY_SS,KEY_9 , // 5B ]
  163. NO_KEY,NO_KEY, // 5C
  164. KEY_SS,KEY_CS, // 5D backslash
  165. NO_KEY,NO_KEY, // 5E
  166. NO_KEY,NO_KEY, // 5F
  167.  
  168. NO_KEY,NO_KEY, // 60
  169. KEY_SS,KEY_CS, // 61 backslash
  170. NO_KEY,NO_KEY, // 62
  171. NO_KEY,NO_KEY, // 63
  172. NO_KEY,NO_KEY, // 64
  173. NO_KEY,NO_KEY, // 65
  174. KEY_CS,KEY_0 , // 66 BACKSPACE
  175. NO_KEY,NO_KEY, // 67
  176. NO_KEY,NO_KEY, // 68
  177. KEY_1 ,NO_KEY, // 69 keypad 1
  178. NO_KEY,NO_KEY, // 6A
  179. KEY_4 ,NO_KEY, // 6B keypad 4
  180. KEY_7 ,NO_KEY, // 6C keypad 7
  181. NO_KEY,NO_KEY, // 6D
  182. NO_KEY,NO_KEY, // 6E
  183. NO_KEY,NO_KEY, // 6F
  184.  
  185. KEY_0 ,NO_KEY, // 70 keypad 0
  186. KEY_SS,KEY_M , // 71 keypad .
  187. KEY_2 ,NO_KEY, // 72 keypad 2
  188. KEY_5 ,NO_KEY, // 73 keypad 5
  189. KEY_6 ,NO_KEY, // 74 keypad 6
  190. KEY_8 ,NO_KEY, // 75 keypad 8
  191. CLRKYS,NO_KEY, // 76 ESC
  192. NO_KEY,NO_KEY, // 77
  193. RSTRDS,NO_KEY, // 78 F11
  194. KEY_SS,KEY_K , // 79 keypad +
  195. KEY_3 ,NO_KEY, // 7A keypad 3
  196. KEY_SS,KEY_J , // 7B keypad -
  197. KEY_SS,KEY_B , // 7C keypad *
  198. KEY_9 ,NO_KEY, // 7D keypad 9
  199. NO_KEY,NO_KEY, // 7E
  200. NO_KEY,NO_KEY  // 7F
  201. };
  202.  
  203.  
  204.  
  205. const UBYTE kmap_E0[] PROGMEM =
  206. {
  207. NO_KEY,NO_KEY, // 60
  208. NO_KEY,NO_KEY, // 61
  209. NO_KEY,NO_KEY, // 62
  210. NO_KEY,NO_KEY, // 63
  211. NO_KEY,NO_KEY, // 64
  212. NO_KEY,NO_KEY, // 65
  213. NO_KEY,NO_KEY, // 66
  214. NO_KEY,NO_KEY, // 67
  215. NO_KEY,NO_KEY, // 68
  216. KEY_SS,KEY_E , // 69 END
  217. NO_KEY,NO_KEY, // 6A
  218. KEY_CS,KEY_5 , // 6B LEFT
  219. KEY_SS,KEY_Q , // 6C HOME
  220. NO_KEY,NO_KEY, // 6D
  221. NO_KEY,NO_KEY, // 6E
  222. NO_KEY,NO_KEY, // 6F
  223.  
  224. KEY_SS,KEY_W , // 70 INS
  225. KEY_CS,KEY_9 , // 71 DEL
  226. KEY_CS,KEY_6 , // 72 DOWN
  227. NO_KEY,NO_KEY, // 73
  228. KEY_CS,KEY_8 , // 74 RIGHT
  229. KEY_CS,KEY_7 , // 75 UP
  230. CLRKYS,NO_KEY, // 76 ESC
  231. NO_KEY,NO_KEY, // 77
  232. NO_KEY,NO_KEY, // 78
  233. NO_KEY,NO_KEY, // 79
  234. KEY_CS,KEY_4 , // 7A PGDN
  235. NO_KEY,NO_KEY, // 7B
  236. NO_KEY,NO_KEY, // 7C
  237. KEY_CS,KEY_3 , // 7D PGUP
  238. NO_KEY,NO_KEY, // 7E
  239. NO_KEY,NO_KEY  // 7F
  240. };
  241.  
  242.  
  243. //struct zx current;
  244. //struct zx towrite;
  245. //volatile UBYTE keys_changed;
  246. //volatile UBYTE send_state;
  247.  
  248.  
  249. void zx_init(void)
  250. {
  251.         BYTE i;
  252.  
  253.         i=39;
  254.         do zx_counters[i] = zx_counters[i] = 0x00; while( (--i)>=0 );
  255.  
  256.         zx_fifo_in_ptr=zx_fifo_out_ptr=0;
  257.  
  258.         zx_task(ZX_TASK_INIT);
  259.  
  260.  
  261.         nSPICS_DDR  |= (1<<nSPICS);
  262.         nSPICS_PORT &= ~(1<<nSPICS);
  263.         _delay_us(10);
  264.         nSPICS_PORT |= (1<<nSPICS);
  265.         _delay_us(10);
  266.         spi_send(0xE2); // send specific reset
  267.         _delay_us(10);
  268.         nSPICS_PORT &= ~(1<<nSPICS);
  269.         _delay_us(10);
  270.         nSPICS_PORT |= (1<<nSPICS);
  271.  
  272. }
  273.  
  274.  
  275.  
  276. void zx_task(UBYTE operation) // zx task, tracks when there is need to send new keymap to the fpga
  277. {
  278.         static UBYTE prev_code;
  279.         static UBYTE task_state;
  280.         static UBYTE reset_type;
  281.  
  282.         UBYTE was_data;
  283.         UBYTE code,keynum,keybit;
  284.  
  285.         if(operation==ZX_TASK_INIT)
  286.         {
  287.                 reset_type = 0;
  288.                 prev_code = KEY_V+1; // impossible scancode
  289.                 task_state = 0;
  290.                 shift_pause = 0;
  291.  
  292.                 zx_clr_kb();
  293.         }
  294.         else /*if(operation==ZX_TASK_WORK)*/
  295.  
  296.         // шч ЇшЇ√ яЁшїюфшЄ: эрцрЄш  ш юЄцрЄш  ЁхёхЄют, эрцрЄш  ш юЄцрЄш  ъэюяъют, CLRKYS (Єюы№ъю эрцрэшх).
  297.         // чрфрўр: єяфхщЄшЄ№ т ёююЄтхЄёЄтшш ё ¤Єшь сшЄьря ъэюяюъ, яюё√ырЄ№ хую т Їяує, яюё√ырЄ№ ЁхёхЄ√.
  298.         // ъЁюьх Єюую, фхырЄ№ ярєчє т єяфхщЄх сшЄьряр ш яюё√ыъх хую т Їяур ьхцфє эрцрЄшхь CS|SS ш яюёыхфє■∙хщ эх-CS|SS ъэюяъш,
  299.         // Ёртэю ъръ ш ьхцфє юЄцрЄшхь эх-CS|SS ъэюяъш ш яюёыхфє■∙шь юЄцрЄшхь CS|SS.
  300.  
  301.         // ёэрўрыр фхырхь Єєяю схч эшъръшї ярєч - ўЄюс√ ЁрсюЄрыю тююс∙х ё ЇшЇющ
  302.  
  303.         {
  304.                 if( !task_state )
  305.                 {
  306.                         nSPICS_PORT |= (1<<nSPICS);
  307.  
  308.                         was_data = 0;
  309.  
  310.                         while( !zx_fifo_isempty() )
  311.                         {
  312.                                 code=zx_fifo_copy(); // don't remove byte from fifo!
  313.  
  314.                                 if( code==CLRKYS )
  315.                                 {
  316.                                         was_data = 1; // we've got something!
  317.  
  318.                                         zx_fifo_get(); // remove byte from fifo
  319.  
  320.                                         reset_type = 0;
  321.                                         prev_code  = KEY_V+1;
  322.  
  323.                                         zx_clr_kb();
  324.  
  325.                                         break; // flush changes immediately to the fpga
  326.                                 }
  327.                                 else if( (code&KEY_MASK) >= RSTSYS )
  328.                                 {
  329.                                         was_data = 1; // we've got something!
  330.  
  331.                                         zx_fifo_get(); // remove byte from fifo
  332.  
  333.                                         if( code&PRESS_MASK ) // reset key pressed
  334.                                         {
  335.                                                 reset_type  = 0x30 & ((code+1)<<4);
  336.                                                 reset_type += 2;
  337.  
  338.                                                 break; // flush immediately
  339.                                         }
  340.                                         else // reset key released
  341.                                         {
  342.                                                 reset_type = 0;
  343.                                         }
  344.                                 }
  345.                                 else /*if( (code&KEY_MASK) < 40 )*/
  346.                                 {
  347.                                         if( shift_pause ) // if we inside pause interval and need checking
  348.                                         {
  349.                                                 if( (PRESS_MASK&prev_code) && (PRESS_MASK&code) )
  350.                                                 {
  351.                                                         if(     /* prev key was CS|SS down */
  352.                                                                 ( (PRESS_MASK|KEY_CS)<=prev_code && prev_code<=(PRESS_MASK|KEY_SS) ) &&
  353.                                                                 /* curr key is not-CS|SS down */
  354.                                                                 ( code<(PRESS_MASK|KEY_CS) || (PRESS_MASK|KEY_SS)<code )
  355.                                                         )
  356.                                                                 break; // while loop
  357.                                                 }
  358.  
  359.                                                 if( (!(PRESS_MASK&prev_code)) && (!(PRESS_MASK&code)) )
  360.                                                 {
  361.                                                         if(     /* prev key was not-CS|SS up */
  362.                                                                 ( prev_code<KEY_CS || KEY_SS<prev_code ) &&
  363.                                                                 /* curr key is CS|SS up */
  364.                                                                 ( KEY_CS<=prev_code && prev_code<=KEY_SS )
  365.                                                         )
  366.                                                                 break;
  367.                                                 }
  368.                                         }
  369.  
  370.                                         // just normal processing out of pause interval
  371.                                         keynum = (code&KEY_MASK)>>3;
  372.  
  373.                                         keybit = 0x0080 >> (code&7); // KEY_MASK - эрфьэюцхёЄтю сшЄют 7
  374.  
  375.                                         if( code&PRESS_MASK )
  376.                                                 zx_map[keynum] |=   keybit;
  377.                                         else
  378.                                                 zx_map[keynum] &= (~keybit);
  379.  
  380.                                         prev_code = code;
  381.                                         zx_fifo_get();
  382.                                         shift_pause = SHIFT_PAUSE; // init wait timer
  383.  
  384.                                         was_data = 1;
  385.                                 }
  386.                         }
  387.  
  388.                         if( was_data ) // initialize transfer
  389.                         {
  390.                                 task_state = 6;
  391.                         }
  392.                 }
  393.                 else // sending bytes one by one in each state
  394.                 {
  395.                         task_state--;
  396.  
  397.                         if( task_state==5 )
  398.                         {
  399.                                 nSPICS_PORT |= (1<<nSPICS);
  400.                                 spi_send(reset_type);
  401.                         }
  402.                         else // task_state==4..0
  403.                         {
  404.                                 nSPICS_PORT &= ~(1<<nSPICS);
  405.                                 spi_send( zx_map[task_state] );
  406.                         }
  407.                 }
  408.         }
  409.  
  410. }
  411.  
  412. void zx_clr_kb(void)
  413. {
  414.         BYTE i;
  415.  
  416.         i=4;
  417.         do
  418.                 zx_map[i] = 0;
  419.         while( (--i)>=0 );
  420.  
  421.  
  422.         i=39;
  423.         do
  424.                 zx_counters[i] = 0;
  425.         while( (--i)>=0 );
  426. }
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442. void to_zx(UBYTE scancode, UBYTE was_E0, UBYTE was_release)
  443. {
  444.         ULONG tbldisp,tblptr;
  445.         UBYTE tbl1,tbl2;
  446.  
  447.  
  448.         tbl1=tbl2=NO_KEY;
  449.  
  450.         if( was_E0 )
  451.         {
  452.                 if( scancode==0x4A ) // keypad /
  453.                 {
  454.                         tbl1 = KEY_SS;
  455.                         tbl2 = KEY_V;
  456.                 }
  457.                 else if( scancode==0x5A ) // keypad enter
  458.                 {
  459.                         tbl1 = KEY_EN;
  460.                 }
  461.                 else if( (scancode>=0x60) && (scancode<=0x7F) )
  462.                 {
  463.                         tbldisp = (scancode-0x60)*2;
  464.                         tblptr = tbldisp + GET_FAR_ADDRESS(kmap_E0);
  465.  
  466.                         tbl1 = pgm_read_byte_far( tblptr++ );
  467.                         tbl2 = pgm_read_byte_far( tblptr );
  468.                 }
  469.         }
  470.         else
  471.         {
  472.                 if( scancode<=0x7F )
  473.                 {
  474.                         tbldisp = scancode*2;
  475.                         tblptr = tbldisp + GET_FAR_ADDRESS(kmap);
  476.  
  477.                         tbl1 = pgm_read_byte_far( tblptr++ );
  478.                         tbl2 = pgm_read_byte_far( tblptr );
  479.                 }
  480.         }
  481.  
  482.         if( tbl1!=NO_KEY )
  483.         {
  484.                 update_keys(tbl1,was_release);
  485.  
  486.                 if( tbl2!=NO_KEY ) update_keys(tbl2,was_release);
  487.         }
  488. }
  489.  
  490.  
  491.  
  492. void update_keys(UBYTE zxcode, UBYTE was_release)
  493. {
  494.         BYTE i;
  495.  
  496.         if( zxcode==NO_KEY )
  497.         {
  498.                 /* NOTHING */
  499.         }
  500.         else if( (zxcode==CLRKYS) && (!was_release) ) // does not have release option
  501.         {
  502.                 i=39;
  503.                 do zx_counters[i]=0; while( (--i)>=0 );
  504.  
  505.                 if( !zx_fifo_isfull() )
  506.                         zx_fifo_put(CLRKYS);
  507.         }
  508.         else if( zxcode>=RSTSYS ) // resets - press and release
  509.         {
  510.                 if( !zx_fifo_isfull() )
  511.                         zx_fifo_put( (was_release ? 0 : PRESS_MASK) | zxcode );
  512.         }
  513.         else if( zxcode < 40 ); // ordinary keys too
  514.         {
  515.                 if( was_release )
  516.                 {
  517.                         if( zx_counters[zxcode] && !(--zx_counters[zxcode]) ) // left-to-right evaluation and shortcutting
  518.                         {
  519.                                 if( !zx_fifo_isfull() )
  520.                                         zx_fifo_put(zxcode);
  521.                         }
  522.                 }
  523.                 else // key pressed
  524.                 {
  525.                         if( !(zx_counters[zxcode]++) )
  526.                         {
  527.                                 if( !zx_fifo_isfull() )
  528.                                         zx_fifo_put( PRESS_MASK | zxcode );
  529.                         }
  530.                 }
  531.         }
  532. }
  533.  
  534.  
  535. void zx_fifo_put(UBYTE input)
  536. {
  537.         zx_fifo[zx_fifo_in_ptr++] = input;
  538. }
  539.  
  540. UBYTE zx_fifo_isfull(void)
  541. {
  542.         //always one byte unused, to distinguish between totally full fifo and empty fifo
  543.         return( (zx_fifo_in_ptr+1)==zx_fifo_out_ptr );
  544. }
  545.  
  546.  
  547. UBYTE zx_fifo_isempty(void)
  548. {
  549.         return (zx_fifo_in_ptr==zx_fifo_out_ptr);
  550. }
  551.  
  552. UBYTE zx_fifo_get(void)
  553. {
  554.         return zx_fifo[zx_fifo_out_ptr++]; // get byte permanently
  555. }
  556.  
  557. UBYTE zx_fifo_copy(void)
  558. {
  559.         return zx_fifo[zx_fifo_out_ptr]; // get byte but leave it in fifo
  560. }
  561.  
  562.