Page 1 of 1

DATE & TIME

Posted: Wed Mar 30, 2011 4:07 pm
by Pes88
Hello,
I have a problem with the function that must get the date and time by cmos memory. The value of minutes and the month isn't always correct... I use qemu emulator, the problem can this be?
I post the code of my funcitons :
I have read these wiki : http://wiki.osdev.org/CMOS http://wiki.osdev.org/Time_And_Date

code :

Code: Select all

#define RTCaddress 0x70
#define RTCdata         0x71

#define SECONDS                0x00
#define MINUTES                  0x02
#define HOURS                     0x04 
#define WEEKDAY                0x06       
#define DAY_OF_MONTH   0x07
#define MONTH                     0x08
#define YEAR                         0x09
#define CENTURY  0x32   
#define REG_A        0x0A
#define REG_B        0x0B 

/*return  
 * First  seconds 0-60 binary 
 * Second minutes 0-60  binary
 * third hours   0-24 binary
 */ 

extern "C" natl  c_get_time () { 
  
  natl time = 0; 
  natb byte=0; 
  natb century=0; 
  bool bcd=false;   
  bool pm =false;  


  flog(LOG_WARN, "TIME"); 
  do {
    outputb(REG_A, RTCaddress); 
    inputb(RTCdata, byte); 
  } while( (byte & 0x80) );          


  outputb(REG_B,RTCaddress); 
  inputb(RTCdata,byte); 

    bcd= (byte & 0x04) ? false:true;

    flog(LOG_WARN, "TIME %s ", (byte & 0x04) ?" BYNARY" : "BCD" ); 
  
    outputb(REG_B, CENTURY); 
    inputb(RTCdata,byte); 
    century=byte; 
   

    outputb(SECONDS,RTCaddress); 
    inputb(RTCdata,byte);   
    if (bcd)
      byte = (byte >> 1) + (byte >> 3) + (byte & 0xf); 
    time = (natl)(byte); 


    outputb(SECONDS,RTCaddress); 
    inputb(RTCdata,byte);   
    if (bcd)
      byte =((byte/ 16) * 10) + (byte & 0xf);

    time  = ((natl)byte <<8 ) | time  ; 

    outputb( HOURS,RTCaddress); 
    inputb(RTCdata,byte);   
    pm= (byte&0x80) ? true: false;
    flog(LOG_WARN," ore am_pm :%d", pm); 

    if (bcd)
	byte = (byte >> 1) + (byte >> 3) + (byte & 0xf); 

    if (pm) 
      byte+=12;
 
    byte+=century; 

     time  = ((natl)byte << 16  ) | time  ; 


  return time; 
}

 /*return  
 * First  date of month 1-31 binary 
 * Second month 0-12  binary
 * third years   0-99 binary
 */ **********************************************************************************************/

extern "C" natl  c_get_date ()  {

  natl date = 0; 
  natb byte=0; 
  bool  bcd=false;  
 
  flog(LOG_WARN, "DATE"); 
  do {
    outputb(REG_A, RTCaddress); 
    inputb(RTCdata, byte); 
    flog(LOG_WARN, "%x", byte); 
  } while( (byte & 0x80) );       

 
 
  outputb(REG_B,RTCaddress); 
  inputb(RTCdata,byte); 
  

    bcd= (byte & 0x04) ? false:true;


    outputb(DAY_OF_MONTH,RTCaddress); 
    inputb(RTCdata,byte);   
    if (bcd)
	byte = (byte >> 1) + (byte >> 3) + (byte & 0xf); 
   date = (natl)(byte); 

    outputb(MONTH,RTCaddress); 
    inputb(RTCdata,byte);   
     if (bcd)
       byte = ((byte / 16) * 10) + (byte & 0xf);
    date  = ((natl)byte <<8 ) | date  ; 


    outputb(YEAR,RTCaddress); 
    inputb(RTCdata,byte);  
       if (bcd)
	byte = (byte >> 1) + (byte >> 3) + (byte & 0xf); 
    date  = ((natl)byte << 16  ) | date  ; 

   
  return date; 

}

Re: DATE & TIME

Posted: Wed Mar 30, 2011 4:20 pm
by gerryg400

Code: Select all

outputb(SECONDS,RTCaddress);
    inputb(RTCdata,byte);   
    if (bcd)
      byte = (byte >> 1) + (byte >> 3) + (byte & 0xf);
    time = (natl)(byte);


    outputb(SECONDS,RTCaddress);
    inputb(RTCdata,byte);   
    if (bcd)
      byte =((byte/ 16) * 10) + (byte & 0xf);

    time  = ((natl)byte <<8 ) | time  ;

    outputb( HOURS,RTCaddress);
    inputb(RTCdata,byte);   
    pm= (byte&0x80) ? true: false;
    flog(LOG_WARN," ore am_pm :%d", pm);
You are reading seconds twice.

Re: DATE & TIME

Posted: Wed Mar 30, 2011 4:44 pm
by Pes88
Sorry, I've pasted the previous code... :oops: :oops: :oops: :oops:
But there is the error on the code and on the wiki :
the expression (bcd >> 1) + (bcd >> 3) + (bcd & 0xf) isn't equal to ((bcd / 16) * 10) + (bcd & 0xf).

Code: Select all

#include <stdio.h>
#include <stdlib.h>

int main () {

        unsigned char bcd=3;

        printf("Optimizated :%d\n", (bcd >> 1) + (bcd >> 3) + (bcd & 0xf));
        printf("normal :%d\n",((bcd / 16) * 10) + (bcd & 0xf));

        return 0;

}
Output :
Optimizated :4
normal :3
~
~
~

Re: DATE & TIME

Posted: Wed Mar 30, 2011 9:50 pm
by Brendan
Hi,
Pes88 wrote:But there is the error on the code and on the wiki :
the expression (bcd >> 1) + (bcd >> 3) + (bcd & 0xf) isn't equal to ((bcd / 16) * 10) + (bcd & 0xf).
You're right. It should be "( (bcd & 0xF0) >> 1) + ( (bcd & 0xF0) >> 3) + (bcd & 0x0F)".


Cheers,

Brendan