Subversion Repositories pentevo

Rev

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