Path: utzoo!mnetor!uunet!husc6!bloom-beacon!gatech!udel!mmdf From: Leisner.Henr@xerox.com (marty) Newsgroups: comp.os.minix Subject: Re: Prg needed to query realtime clock on PC-AT Message-ID: <2444@louie.udel.EDU> Date: 9 May 88 13:17:04 GMT Sender: mmdf@udel.EDU Lines: 104 Chris, The answer is to get the time when you boot from the pc-at. I have the following code in kernel/clock.c #ifdef i286 #define CMOS_SECONDS 0 #define CMOS_MINUTES 2 #define CMOS_HOURS 4 #define CMOS_DATE 7 #define CMOS_MONTH 8 #define CMOS_YEAR 9 #define SECS_PER_DAY (24L*60L*60L) #define SECS_PER_YEAR (365L*SECS_PER_DAY) /* get the cmos time off the battery backed up clock (6845) */ static real_time get_cmos_time() { extern unsigned char read_cmos_ram(); real_time temp; static int month_to_days[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; int year; int month; int day; year = convert_bcd(read_cmos_ram(CMOS_YEAR)); month = convert_bcd(read_cmos_ram(CMOS_MONTH)); if(month > 2 && !(year % 4)) month_to_days[month - 1]++; /* leap year */ year -= 70; /* only want years since 1970 */ day = month_to_days[month - 1]; day += convert_bcd(read_cmos_ram(CMOS_DATE)) -1; day += (year + 1)/4; /* take into account leap years */ temp = (real_time) year * SECS_PER_YEAR; temp += (real_time) day*SECS_PER_DAY; temp += (real_time) convert_bcd(read_cmos_ram(CMOS_HOURS))*3600L; temp += (real_time) convert_bcd(read_cmos_ram(CMOS_MINUTES))*60L; temp += (real_time) convert_bcd(read_cmos_ram(CMOS_SECONDS)); return temp; } #endif And in init_clock: #ifdef i286 real_time get_cmos_time(); /* get time off cmos battery backed up ram */ ps = disable(); lost_ticks = 0; realtime = 0; boot_time = get_cmos_time(); #endif And stick the following in assembler somewhere: CMOS_ADDR = 070H CMOS_DATA = 071H procdef read_cmos_ram,<> pushf cli mov ax,in_address out CMOS_ADDR,al xor ah,ah in al,CMOS_DATA popf pret pend read_cmos_ram procdef convert_bcd,<> mov al,to_convert ; convert from bcd to decimal mov bl,al shr al,4 mov cl,10 mul cl and bl,0fH add al,bl pret pend convert_bcd Please note the above code is quick and dirty. It seems to work fine. If anyone sees any bugs, please let me know. Telling time is not one of my strong points ;-). I'm only dealing with local time, no GMT stuff. It is definitely a bad idea to let applications play with hardware ports directly. I believe Xenix/Microport systems have some sortta clock device to let setuid applications set the hardware real-time clock. Non-protected mode Minix systems will allow you to do the above in user code, if you want to. As for a history mechanism, I'm planning on bringing up the Alan Holub shell written up in Dr. Dobb's Journal a couple of years ago. I use it under Ms/Dos and it supplies reasonable capability. It should run nicely on Minix. marty ARPA: leisner.henr@xerox.com GV: leisner.henr NS: martin leisner:henr801c:xerox UUCP: nsc!nscimg!amps!marty