Minix1.5/commands/ibm/readclock.c

Compare this file to the similar file:
Show the results in this format:

/* readclock - read the AT real time clock	Authors: T. Holm & E. Froese */

/************************************************************************/
/*									*/
/*   readclock.c							*/
/*									*/
/*		Read the AT real time clock, write the time to		*/
/*		standard output in a form usable by date(1).		*/
/*		If the system is an AT then the time is read		*/
/*		from the built-in clock, and written to standard	*/
/*		output in the form:					*/
/*									*/
/*			mmddyyhhmmss					*/
/*									*/
/*		If the system is not an AT then ``-q'' is written 	*/
/*		to standard output. This is useful for placement in	*/
/*		the ``/etc/rc'' script:					*/
/*									*/
/*	 	  /usr/bin/date `/usr/bin/readclock` </dev/tty  	*/
/*									*/
/************************************************************************/
/*    origination          1987-Dec-29              efth                */
/************************************************************************/



#define CPU_TYPE_SEGMENT   0xFFFF	/* BIOS segment for CPU type 	 */
#define CPU_TYPE_OFFSET    0x000E	/* BIOS offset for CPU type 	 */
#define PC_AT              0xFC	/* IBM code for PC-AT (0xFFFFE) */
#define PS_386		0xF8 /* IBM code for 386 PS/2's */	


#define CLK_ELE 0x70		/* ptr corresponding to element of time to be*/
#define CLK_IO 0x71		/* read or written is written to port clk_ele*/
/* The element can then be read or written by */
/* Reading or writing port clk_io.            */

#define  YEAR             9	/* Clock register addresses	 */
#define  MONTH            8
#define  DAY              7
#define  HOUR             4
#define  MINUTE           2
#define  SECOND           0
#define  STATUS           0x0b

#define  BCD_TO_DEC(x)	  ( (x>>4) * 10 + (x & 0x0f) )


struct time {
  unsigned year;
  unsigned month;
  unsigned day;
  unsigned hour;
  unsigned minute;
  unsigned second;
};



main()
{
  struct time time1;
  struct time time2;
  int i;
  int cpu_type;	

  cpu_type = peek(CPU_TYPE_SEGMENT, CPU_TYPE_OFFSET);
  if (cpu_type != PS_386 && cpu_type != PC_AT) {
	printf("-q\n");
	exit(1);
  }
  for (i = 0; i < 10; i++) {
	get_time(&time1);
	get_time(&time2);

	if (time1.year == time2.year &&
	    time1.month == time2.month &&
	    time1.day == time2.day &&
	    time1.hour == time2.hour &&
	    time1.minute == time2.minute &&
	    time1.second == time2.second) {
		printf("%02d%02d%02d%02d%02d%02d\n",
		       time1.month, time1.day, time1.year,
		       time1.hour, time1.minute, time1.second);
		exit(0);
	}
  }

  printf("-q\n");
  exit(1);
}



/***********************************************************************/
/*                                                                     */
/*    get_time( time )                                                 */
/*                                                                     */
/*    Update the structure pointed to by time with the current time    */
/*    as read from the hardware real-time clock of the AT.             */
/*    If necessary, the time is converted into a binary format before  */
/*    being stored in the structure.                                   */
/*                                                                     */
/***********************************************************************/

get_time(t)
struct time *t;
{
  t->year = read_register(YEAR);
  t->month = read_register(MONTH);
  t->day = read_register(DAY);
  t->hour = read_register(HOUR);
  t->minute = read_register(MINUTE);
  t->second = read_register(SECOND);



  if ((read_register(STATUS) & 0x04) == 0) {
	/* Convert BCD to binary if necessary */
	t->year = BCD_TO_DEC(t->year);
	t->month = BCD_TO_DEC(t->month);
	t->day = BCD_TO_DEC(t->day);
	t->hour = BCD_TO_DEC(t->hour);
	t->minute = BCD_TO_DEC(t->minute);
	t->second = BCD_TO_DEC(t->second);
  }
}


read_register(reg_addr)
char reg_addr;
{
  int val;

  if (port_out(CLK_ELE, reg_addr) < 0 || port_in(CLK_IO, &val) < 0) {
	printf("-q\n");
	exit(1);
  }
  return(val);
}