inf2007@vax.rz.uni-wuerzburg.dbp.de (inf2007) (12/15/89)
We have Minix running on several PS2/30 for teaching. This PC has a non AT- compatible clock. The new readclock.c can read it. Robert Regn regn@uniwue.unido.uucp or ..!uunet!mcvax!unido!uniwue!regn /* 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 */ /************************************************************************/ /* On a IBM PS/2 Model 30 you have to read the components from */ /* different addresses. The clock registers are directly mapped */ /* to IO-addresses. This version can be compiled with "-DPS2". */ /* M. Roetzer and Robert Regn University of Wuerzburg */ /************************************************************************/ /* 1989-Dec-14 */ /************************************************************************/ #ifndef PS2 #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 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 #else #define YEAR 0xe9 #define MONTH 0xe7 #define DAY 0xe6 #define HOUR 0xe4 #define MINUTE 0xe3 #define SECOND 0xe2 #define STATUS 0xb0 #endif #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; #ifndef PS2 if ( peek( CPU_TYPE_SEGMENT, CPU_TYPE_OFFSET ) != PC_AT ) { printf( "-q\n" ); exit( 1 ); } #endif 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 ) #ifndef PS2 char reg_addr; #else int reg_addr; #endif { int val; #ifndef PS2 port_out( CLK_ELE, reg_addr ); port_in(CLK_IO, &val); #else port_in(reg_addr, &val); #endif return( val ); }