Subversion Repositories pentevo

Rev

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