Subversion Repositories pentevo

Rev

Rev 656 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/eeprom.h>
  4. #include <util/twi.h>
  5.  
  6. #include "pins.h"
  7. #include "mytypes.h"
  8. #include "main.h"
  9. #include "zx.h"
  10. #include "rtc.h"
  11. #include "ps2.h"
  12. #include "version.h"
  13. #include "rs232.h"
  14.  
  15. //if want Log than comment next string
  16. #undef LOGENABLE
  17.  
  18. volatile UBYTE gluk_regs[14];
  19.  
  20. //stop transmit
  21. static void tw_send_stop(void)
  22. {
  23.         TWCR = _BV(TWINT)|_BV(TWEN)|_BV(TWSTO);
  24.         //wait for flag
  25. //      while ( (TWCR&_BV(TWSTO))!=0 );
  26. //      _delay_us(20); //4mks for PCF8583
  27. }
  28.  
  29. static UBYTE tw_send_start(void)
  30. {
  31.         //start transmit
  32.         TWCR =_BV(TWINT)|_BV(TWSTA)|_BV(TWEN);
  33.  
  34.         //wait for flag
  35.         while ( (TWCR&_BV(TWINT))==0 );
  36. //      while ( TWCR & (1<<TWSTA) );
  37.  
  38. //#ifdef LOGENABLE
  39. //      char log_reset_type[] = "TWS..[..]..\r\n";
  40. //      UBYTE b = TWSR;
  41. //      log_reset_type[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  42. //      log_reset_type[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  43. //      b=TWCR;
  44. //      log_reset_type[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  45. //      log_reset_type[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  46. //      b=TWDR;
  47. //      log_reset_type[9] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  48. //      log_reset_type[10] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  49. //      to_log(log_reset_type);
  50. //#endif
  51.         //return status
  52.    return TW_STATUS;
  53. }
  54.  
  55. static UBYTE tw_send_addr(UBYTE addr)
  56. {
  57.         //set address
  58.         TWDR = addr;
  59.  
  60.         //enable transmit
  61.         TWCR = _BV(TWINT)|_BV(TWEN);
  62.  
  63.         //wait for end transmit
  64.         while ( (TWCR &_BV(TWINT))==0 );
  65.  
  66. //#ifdef LOGENABLE
  67. //      char log_tw[] = "TWA..[..]..\r\n";
  68. //      UBYTE b = TWSR;
  69. //      log_tw[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  70. //      log_tw[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  71. //      b=TWCR;
  72. //      log_tw[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  73. //      log_tw[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  74. //      log_tw[9] = ((addr >> 4) <= 9 )?'0'+(addr >> 4):'A'+(addr >> 4)-10;
  75. //      log_tw[10] = ((addr & 0x0F) <= 9 )?'0'+(addr & 0x0F):'A'+(addr & 0x0F)-10;
  76. //      to_log(log_tw);
  77. //#endif
  78.         //return status
  79.    return TW_STATUS;
  80. }
  81.  
  82. static UBYTE tw_send_data(UBYTE data)
  83. {
  84.         //set data
  85.         TWDR = data;
  86.  
  87.         //enable transmit
  88.         TWCR = _BV(TWINT)|_BV(TWEN);
  89.  
  90.         //wait for end transmit
  91.         while ( (TWCR&_BV(TWINT))==0 );
  92.  
  93. //#ifdef LOGENABLE
  94. //      char log_tw[] = "TWW..[..]..\r\n";
  95. //      UBYTE b = TWSR;
  96. //      log_tw[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  97. //      log_tw[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  98. //      b=TWCR;
  99. //      log_tw[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  100. //      log_tw[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  101. //      log_tw[9] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+(data >> 4)-10;
  102. //      log_tw[10] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+(data & 0x0F)-10;
  103. //      to_log(log_tw);
  104. //#endif
  105.         //return status
  106.    return TW_STATUS;
  107. }
  108.  
  109. static UBYTE tw_read_data(UBYTE* data)
  110. {
  111.         //enable
  112.         TWCR = _BV(TWINT)|_BV(TWEN);
  113.  
  114.         //wait for flag set
  115.         while ( (TWCR&_BV(TWINT))==0 );
  116.  
  117. //#ifdef LOGENABLE
  118. //      char log_tw[] = "TWR..[..]..\r\n";
  119. //      UBYTE b = TWSR;
  120. //      log_tw[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  121. //      log_tw[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  122. //      b=TWCR;
  123. //      log_tw[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  124. //      log_tw[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  125. //      log_tw[9] = ((TWDR >> 4) <= 9 )?'0'+(TWDR >> 4):'A'+(TWDR >> 4)-10;
  126. //      log_tw[10] = ((TWDR & 0x0F) <= 9 )?'0'+(TWDR & 0x0F):'A'+(TWDR & 0x0F)-10;
  127. //      to_log(log_tw);
  128. //#endif
  129.         //get data
  130.         *data = TWDR;
  131.  
  132.         //return status
  133.    return TW_STATUS;
  134. }
  135.  
  136. static UBYTE bcd_to_hex(UBYTE data)
  137. {
  138.         //convert BCD to HEX
  139.         return  (UBYTE)(data>>4)*10 + (UBYTE)(data&0x0F);
  140. }
  141.  
  142. static UBYTE hex_to_bcd(UBYTE data)
  143. {
  144.         //convert HEX to BCD
  145.         return  (UBYTE)((data/10)<<4) + (UBYTE)(data%10);
  146. }
  147.  
  148. static UBYTE days_of_months()
  149. {
  150.         //return number of days in month
  151.         static const UBYTE days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
  152.         UBYTE tmp = gluk_regs[GLUK_REG_MONTH]-1;
  153.  
  154.         if ( tmp > sizeof(days)-1 ) tmp = 0; //check range
  155.  
  156.         tmp = days[tmp];
  157.  
  158.         //check leap-year
  159.         if ( (tmp == 28) && ( ( gluk_regs[GLUK_REG_YEAR]&0x03 ) == 0 ) ) tmp++;
  160.  
  161.         return tmp;
  162. }
  163.  
  164. static UBYTE read_eeprom(UBYTE offset)
  165. {
  166.         UWORD ptr = gluk_regs[GLUK_REG_A];
  167.         ptr = (ptr<<4) + (0x0F&offset);
  168.  
  169.         //wait for eeprom
  170.         eeprom_busy_wait();
  171.  
  172.         return eeprom_read_byte((UBYTE*)ptr);
  173. }
  174.  
  175. static void write_eeprom(UBYTE offset, UBYTE data)
  176. {
  177.         UWORD ptr = gluk_regs[GLUK_REG_A];
  178.         ptr = (ptr<<4) + (0x0F&offset);
  179.  
  180.         //wait for eeprom
  181.         eeprom_busy_wait();
  182.  
  183.         eeprom_write_byte ((UBYTE*)ptr, data);
  184. }
  185.  
  186. void rtc_init(void)
  187. {
  188.         //SCL frequency = CPU clk/ ( 16 + 2* (TWBR) * 4^(TWPS) )
  189.         // 11052000 / (16 + 2*48 ) = 98678,5Hz (100000Hz recommended for PCF8583)
  190.         TWSR = 0;
  191.         TWBR = 48;
  192.         TWAR = 0; //disable address match unit
  193.  
  194.         //reset RTC
  195.         //write 0 to control/status register [0] on PCF8583
  196.         rtc_write(0, 0);
  197.  
  198.         //set Gluk clock registers
  199.         gluk_init();
  200.         if ( gluk_regs[GLUK_REG_SEC] == 0 ) gluk_init();
  201.  
  202.         //restore mode register from NVRAM (CAPS LED off on init)
  203.         modes_register = rtc_read(RTC_COMMON_MODE_REG) & ~(MODE_CAPSLED);
  204.  
  205.         //set modes on fpga
  206.         zx_set_config(0);
  207. }
  208.  
  209. void rtc_write(UBYTE addr, UBYTE data)
  210. {
  211.         //set address
  212.         if ( tw_send_start() & (TW_START|TW_REP_START) )
  213.         {
  214.                 if ( tw_send_addr(RTC_ADDRESS|TW_WRITE) == TW_MT_SLA_ACK )
  215.                 {
  216.                         if ( tw_send_data(addr) == TW_MT_DATA_ACK )
  217.                         {
  218.                                 //write data
  219.                                 tw_send_data(data);
  220.                         }
  221.                 }
  222.         }
  223.         tw_send_stop();
  224. }
  225.  
  226. UBYTE rtc_read(UBYTE addr)
  227. {
  228.         UBYTE ret = 0;
  229.  
  230.         //set address
  231.         if ( tw_send_start() & (TW_START|TW_REP_START) )
  232.         {
  233.                 if ( tw_send_addr(RTC_ADDRESS|TW_WRITE) == TW_MT_SLA_ACK )
  234.                 {
  235.                         if ( tw_send_data(addr) == TW_MT_DATA_ACK )
  236.                         {
  237.                                 //read data
  238.                                 if ( tw_send_start() == TW_REP_START )
  239.                                 {
  240.                                         if ( tw_send_addr(RTC_ADDRESS|TW_READ) == TW_MR_SLA_ACK )
  241.                                         {
  242.                                                 tw_read_data(&ret);
  243.                                         }
  244.                                 }
  245.                         }
  246.                 }
  247.         }
  248.         tw_send_stop();
  249.         return ret;
  250. }
  251.  
  252. void gluk_init(void)
  253. {
  254.         UBYTE tmp;
  255.         //default values
  256.         gluk_regs[GLUK_REG_A] = GLUK_A_INIT_VALUE;
  257.         gluk_regs[GLUK_REG_B] = GLUK_B_INIT_VALUE;
  258.         gluk_regs[GLUK_REG_C] = GLUK_C_INIT_VALUE;
  259.         gluk_regs[GLUK_REG_D] = GLUK_D_INIT_VALUE;
  260.  
  261.         //setup
  262.  
  263.         //read month and day of week
  264.         tmp = rtc_read(6);
  265.         gluk_regs[GLUK_REG_MONTH] = bcd_to_hex(0x1F&tmp);
  266.         tmp = (tmp>>5);
  267.         //PC8583 dayweek 0..6 => DS12788 dayweek 1..7
  268.         gluk_regs[GLUK_REG_DAY_WEEK] = (tmp>6)?1:tmp+1;
  269.  
  270.         //read year and day of month
  271.         tmp = rtc_read(5);
  272.         gluk_regs[GLUK_REG_DAY_MONTH] = bcd_to_hex(0x3F&tmp);
  273.         gluk_regs[GLUK_REG_YEAR] = tmp>>6;
  274.         tmp = rtc_read(RTC_YEAR_ADD_REG);
  275.         if ( (tmp&0x03) > gluk_regs[GLUK_REG_YEAR] )
  276.         {
  277.                 //count of year over - correct year
  278.                 tmp += 4;
  279.                 if ( tmp >= 100 ) tmp = 0;
  280.         }
  281.         gluk_regs[GLUK_REG_YEAR] += tmp&0xFC;
  282.         rtc_write(RTC_YEAR_ADD_REG,gluk_regs[GLUK_REG_YEAR]); //save year
  283.  
  284.         //read time
  285.         gluk_regs[GLUK_REG_HOUR] = bcd_to_hex(0x3F&rtc_read(4)); //TODO 12/24 format
  286.         gluk_regs[GLUK_REG_MIN] = bcd_to_hex(rtc_read(3));
  287.         gluk_regs[GLUK_REG_SEC] = bcd_to_hex(rtc_read(2));
  288. }
  289.  
  290. void gluk_inc(void)
  291. {
  292.         if ( ++gluk_regs[GLUK_REG_SEC] >= 60 )
  293.         {
  294.                 gluk_regs[GLUK_REG_SEC] = 0;
  295.                 if ( ++gluk_regs[GLUK_REG_MIN] >= 60 )
  296.                 {
  297.                         gluk_regs[GLUK_REG_MIN] = 0;
  298.                         if ( ++gluk_regs[GLUK_REG_HOUR] >= 24 )
  299.                         {
  300.                                 gluk_regs[GLUK_REG_HOUR] = 0;
  301.                                 if ( ++gluk_regs[GLUK_REG_DAY_WEEK] > 7  )
  302.                                 {
  303.                                         gluk_regs[GLUK_REG_DAY_WEEK] = 1;
  304.                                 }
  305.                                 if ( ++gluk_regs[GLUK_REG_DAY_MONTH] > days_of_months() )
  306.                                 {
  307.                                         gluk_regs[GLUK_REG_DAY_MONTH] = 1;
  308.                                         if ( ++gluk_regs[GLUK_REG_MONTH] > 12 )
  309.                                         {
  310.                                                 gluk_regs[GLUK_REG_MONTH] = 1;
  311.                                                 if( ++gluk_regs[GLUK_REG_YEAR] >= 100 )
  312.                                                 {
  313.                                                         gluk_regs[GLUK_REG_YEAR] = 0;
  314.                                                 }
  315.                                         }
  316.                                 }
  317.                         }
  318.                 }
  319.         }
  320.  
  321.         //set update flag
  322.         gluk_regs[GLUK_REG_C] |= GLUK_C_UPDATE_FLAG;
  323.  
  324. //#ifdef LOGENABLE
  325. //{
  326. //      char log_int_rtc[] = "00.00.00\r\n";
  327. //      log_int_rtc[0] = '0' + gluk_regs[GLUK_REG_HOUR]/10;
  328. //      log_int_rtc[1] = '0' + gluk_regs[GLUK_REG_HOUR]%10;
  329. //      log_int_rtc[3] = '0' + gluk_regs[GLUK_REG_MIN]/10;
  330. //      log_int_rtc[4] = '0' + gluk_regs[GLUK_REG_MIN]%10;
  331. //      log_int_rtc[6] = '0' + gluk_regs[GLUK_REG_SEC]/10;
  332. //      log_int_rtc[7] = '0' + gluk_regs[GLUK_REG_SEC]%10;
  333. //      to_log(log_int_rtc);
  334. //}
  335. //#endif
  336. }
  337.  
  338. UBYTE gluk_get_reg(UBYTE index)
  339. {
  340.         UBYTE tmp;
  341.  
  342.         if( index < sizeof(gluk_regs)/sizeof(gluk_regs[0]) )
  343.         {
  344.                 //clock registers from array
  345.                 tmp = gluk_regs[index];
  346.                 if ( ( index<10 ) && ( (gluk_regs[GLUK_REG_B]&GLUK_B_DATA_MODE) == 0 ) )
  347.                 {
  348.                         //clock registers mast be in BCD if HEX-bit not set in reg B
  349.                         tmp = hex_to_bcd(tmp);
  350.                 }
  351.  
  352.                 if ( index == GLUK_REG_C )
  353.                 {
  354.                         //clear update flag
  355.                         gluk_regs[GLUK_REG_C] &= ~GLUK_C_UPDATE_FLAG;
  356.  
  357.                         //3 bit - SD card detect
  358.                         //2 bit - SD WRP detect
  359.                         tmp |= (((~SD_PIN)&((1<<SDWRP)|(1<<SDDET)))>>2);
  360.  
  361.                         //0 - bit numlock led status on read
  362.                     if ( (PS2KEYBOARD_LED_NUMLOCK&modes_register)!=0 )
  363.                         {
  364.                                 tmp |= GLUK_C_NUM_LED_FLAG;
  365.                         }
  366.                         else
  367.                         {
  368.  
  369.                                 tmp &= ~GLUK_C_NUM_LED_FLAG;
  370.                         }
  371.                 }
  372.  
  373.                 if ( index == GLUK_REG_D )
  374.                 {
  375.                         //return keyboard statuses
  376.                         tmp &= ~(KB_LCTRL_MASK|KB_RCTRL_MASK|KB_LALT_MASK|KB_RALT_MASK|KB_LSHIFT_MASK|KB_RSHIFT_MASK|KB_F12_MASK);
  377.                         tmp |= (kb_ctrl_status&(KB_LCTRL_MASK|KB_RCTRL_MASK|KB_LALT_MASK|KB_RALT_MASK|KB_LSHIFT_MASK|KB_RSHIFT_MASK|KB_F12_MASK));
  378.                 }
  379.         }
  380.         else
  381.         {
  382.                 if ( index >= 0xF0 )
  383.                 {
  384.                         if ( (gluk_regs[GLUK_REG_C]&GLUK_C_EEPROM_FLAG)!=0 )
  385.                         {
  386.                                 //read from eeprom
  387.                                 tmp = read_eeprom(index);
  388.                         }
  389.                         else
  390.                         {
  391.                                 //read version
  392.                                 tmp = GetVersionByte( index&0x0F );
  393.                         }
  394.                 }
  395.                 else
  396.                 {
  397.                         //other from nvram
  398.                         //- on PCF8583 nvram started from #10
  399.                         //- on 512vi1[DS12887] nvram started from #0E
  400.                         tmp = rtc_read( (index/*&0x3F*/)+2 );
  401.                 }
  402.         }
  403.  
  404. #ifdef LOGENABLE
  405.         {
  406.                 char log_gs[] = "GR[..]..\r\n";
  407.                 UBYTE b = index;
  408.                 log_gs[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  409.                 log_gs[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  410.                 b = tmp;
  411.                 log_gs[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  412.                 log_gs[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  413.                 to_log(log_gs);
  414.         }
  415. #endif
  416.         return tmp;
  417. }
  418.  
  419. void gluk_set_reg(UBYTE index, UBYTE data)
  420. {
  421. #ifdef LOGENABLE
  422.         char log_gs[] = "GS[..]..\r\n";
  423.         UBYTE b = index;
  424.         log_gs[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  425.         log_gs[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  426.         b=data;
  427.         log_gs[6] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
  428.         log_gs[7] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
  429.         to_log(log_gs);
  430. #endif
  431.  
  432.         if( index < sizeof(gluk_regs)/sizeof(gluk_regs[0]) )
  433.         {
  434.                 if ( index<10 )
  435.                 {
  436.                         //write to clock registers
  437.                         if ( (gluk_regs[GLUK_REG_B]&GLUK_B_DATA_MODE) == 0 )
  438.                         {
  439.                                 //array of registers must be in Hex, but data in BCD if HEX-bit not set in reg B
  440.                                 data = bcd_to_hex(data);
  441.                         }
  442.                         gluk_regs[index] = data;
  443.  
  444.                         //write to nvram if need
  445.                         switch( index )
  446.                         {
  447.                                 case GLUK_REG_SEC:
  448.                                         if( data <= 59 ) rtc_write(2, hex_to_bcd(data/*gluk_regs[GLUK_REG_SEC]*/));
  449.                                         break;
  450.                                 case GLUK_REG_MIN:
  451.                                         if( data <= 59) rtc_write(3, hex_to_bcd(data/*gluk_regs[GLUK_REG_MIN]*/));
  452.                                         break;
  453.                                 case GLUK_REG_HOUR:
  454.                                         if( data <= 23) rtc_write(4, 0x3F&hex_to_bcd(data/*gluk_regs[GLUK_REG_HOUR]*/));
  455.                                         break;
  456.                                 case GLUK_REG_MONTH:
  457.                                 case GLUK_REG_DAY_WEEK:
  458.                                         if( ( gluk_regs[GLUK_REG_DAY_WEEK]-1 <= 6 ) &&
  459.                                                 ( gluk_regs[GLUK_REG_MONTH] > 0 ) &&
  460.                                                 ( gluk_regs[GLUK_REG_MONTH] <= 12 ) )
  461.                                         {
  462.                                                 //DS12788 dayweek 1..7 => PC8583 dayweek 0..6
  463.                                                 rtc_write(6, ((gluk_regs[GLUK_REG_DAY_WEEK]-1)<<5)+(0x1F&hex_to_bcd(gluk_regs[GLUK_REG_MONTH])));
  464.                                         }
  465.                                         break;
  466.                                 case GLUK_REG_YEAR:
  467.                                         rtc_write(RTC_YEAR_ADD_REG, gluk_regs[GLUK_REG_YEAR]);
  468.                                 case GLUK_REG_DAY_MONTH:
  469.                                         rtc_write(5, (gluk_regs[GLUK_REG_YEAR]<<6)+(0x3F&hex_to_bcd(gluk_regs[GLUK_REG_DAY_MONTH])));
  470.                                         break;
  471.                         }
  472.                 }
  473.                 else
  474.                 {
  475.                         switch( index )
  476.                         {
  477.                                 case GLUK_REG_A:
  478.                                         //EEPROM address
  479.                                         gluk_regs[GLUK_REG_A]=data;
  480.                                         break;
  481.  
  482.                                 case GLUK_REG_B:
  483.                                         //BCD or Hex mode set
  484.                                         gluk_regs[GLUK_REG_B]=(data&GLUK_B_DATA_MODE)|GLUK_B_INIT_VALUE;
  485.                                         break;
  486.  
  487.                                 case GLUK_REG_C:
  488.                                         if ( (data&GLUK_C_CLEAR_LOG_FLAG) != 0 )
  489.                                         {
  490.                                                 //clear PS2 keyboard log
  491.                                                 ps2keyboard_reset_log();
  492.                                         }
  493.                                         if ( (data&GLUK_C_CAPS_LED_FLAG) != (gluk_regs[GLUK_REG_C]&GLUK_C_CAPS_LED_FLAG) )
  494.                                         {
  495.                                                 //switch state of CAPS LED on PS2 keyboard
  496.                                                 gluk_regs[GLUK_REG_C] = gluk_regs[GLUK_REG_C]^GLUK_C_CAPS_LED_FLAG;
  497.                                                 modes_register = modes_register^MODE_CAPSLED;
  498.                                                 //set led on keyboard
  499.                                                 ps2keyboard_send_cmd(PS2KEYBOARD_CMD_SETLED);
  500.                                         }
  501.                                         if ( (data&GLUK_C_EEPROM_FLAG) != (gluk_regs[GLUK_REG_C]&GLUK_C_EEPROM_FLAG) )
  502.                                         {
  503.                                                 //switch EEPROM mode
  504.                                                 gluk_regs[GLUK_REG_C] = gluk_regs[GLUK_REG_C]^GLUK_C_EEPROM_FLAG;
  505.                                         }
  506.                                         break;
  507.                         }
  508.                 }
  509.         }
  510.         else
  511.         {
  512.                 if ( index >= 0xF0 )
  513.                 {
  514.                         if ( (gluk_regs[GLUK_REG_C]&GLUK_C_EEPROM_FLAG)!=0 )
  515.                         {
  516.                                 //write to eeprom
  517.                                 write_eeprom(index, data);
  518.                         }
  519.                         else
  520.                         {
  521.                                 //set version data type
  522.                                 SetVersionType( data );
  523.                         }
  524.                 }
  525.                 else
  526.                 {
  527.                         //write to nvram
  528.                         //- on PCF8583 nvram started from #10
  529.                         //- on 512vi1[DS12887] nvram started from #0E
  530.                         rtc_write( (index/*&0x3F*/)+2, data);
  531.                 }
  532.         }
  533. }
  534.  
  535.