cmostime3 part 02/02 (was Re: Program to set clock to NBS time)

Warren Tucker wht at n4hgf.Mt-Park.GA.US
Sat Dec 29 14:09:29 AEST 1990


---- Cut Here and unpack ----
#!/bin/sh
# this is cmostime3.02 (part 2 of cmostime3)
# do not concatenate these parts, unpack them in order with /bin/sh
# file NBSsetclk.c continued
#
touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
if [ -s /tmp/s3_touch$$ ]
then
    TOUCH=can
else
    TOUCH=cannot
fi
rm -f /tmp/s3_touch$$
CurArch=2
if test ! -r s3_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s3_seq_.tmp || exit 1
echo "x - Continuing file NBSsetclk.c"
sed 's/^X//' << 'SHAR_EOF' >> NBSsetclk.c
X	lclose()
X------------------------------------------------------------------------*/
Xvoid
Xlclose()
X{
X	if(Liofd < 0)
X		return;
X	ioctl(Liofd,(int)TCGETA,(char *)&Ltermio); /* save initial state */
X	Ltermio.c_cflag |= HUPCL;
X	ioctl(Liofd,(int)TCSETA,(char *)&Ltermio);
X	close(Liofd);
X	Liofd = -1;
X	unlock_tty();		/* kill lock file */
X
X}	/* end of lclose */
X
X/*+-------------------------------------------------------------------------
X	ltoggle_dtr()
X--------------------------------------------------------------------------*/
Xvoid
Xltoggle_dtr()
X{
X	lclose();
X	nap(300L);
X	lopen();
X	ioctl(Liofd,TCSETA,(char *)&Ltermio);
X	nap(100L);
X}	/* end of ltoggle_dtr */
X
X/*+-------------------------------------------------------------------------
X	hayes_modem_init(cmd)
X--------------------------------------------------------------------------*/
Xhayes_modem_init(cmd)
Xchar *cmd;
X{
Xregister char *cptr;
Xint retry_count = 0;
Xint itmp;
Xchar s32[32];
X
XLRWT	lr;
X
X	while(!Lmodem_already_init)
X	{
X		lkill_buf();
X		lputs_paced(20,"ATQ0V1E1\r");
X		itmp = 0;
X		while(itmp != '\r')
X		{
X			if((itmp = lgetc_timeout(300L)) < 0)
X			{
X				if(retry_count > 3)
X					return(-1);
X				retry_count++;
X				ltoggle_dtr();
X				break;
X			}
X		}
X		if(itmp < 0)
X			continue;
X
X		lr.to1 = 300L;
X		lr.to2 = 100L;
X		lr.raw_flag = 0;
X		lr.buffer = s32;
X		lr.bufsize = sizeof(s32);
X		fflush(se);
X		lgets_timeout(&lr);
X		if(strcmp(s32,"OK"))
X		{
X			if(retry_count > 3)
X				return(-1);
X			retry_count++;
X				ltoggle_dtr();
X			continue;
X		}
X		nap(300L);
X		Lmodem_already_init = 1;
X	}
X
X	return(0);
X
X}	/* end of hayes_modem_init */
X
X/*+-------------------------------------------------------------------------
X	hayes_send_cmd(cmd)
X--------------------------------------------------------------------------*/
Xhayes_send_cmd(cmd)
Xchar *cmd;
X{
Xregister char *cptr;
Xint itmp;
Xchar s32[32];
X
X	hayes_modem_init();
X	cptr = cmd;
X	while(*cptr)
X	{
X		lputc(*cptr++);
X		if(lgetc_timeout(500L) < 0)
X			return(-1);
X	}
X	lputc('\r');
X	if(lgetc_timeout(500L) < 0)
X		return(-1);
X	return(0);
X
X}	/* end of hayes_send_cmd */
X
X/*+-----------------------------------------------------------------------
X	hayes_dial()
Xreturns 1 on success (CONNECT), 
X		0 if failure to connect
X		-1 if cannot talk to modem
X------------------------------------------------------------------------*/
Xint
Xhayes_dial()
X{
Xregister int itmp;
Xchar s128[128];
Xint rtn_code = -1;	/* assume fail, CONNECT will chg to zero */
Xint s7;
XLRWT	lr;
X
X	s7 = 30;
X	strcpy(s128,"ATV1E1S11=45DT" );
X	strcat(s128,Ltelno);
X
X	if(itmp = hayes_send_cmd(s128))
X		return(itmp);
X
X/* some modems (ahem, the older Hayes 2400) do not accurately honor S7 */
X	lr.to1 = s7 * 2 * 1000L;
X	lr.to2 = 100L;
X	lr.raw_flag = 0;
X	lr.buffer = s128;
X	lr.bufsize = sizeof(s128);
X	ff(se,"dialing %s ... INT to abort ... ",Ltelno);
X	fflush(se);
X	lgets_timeout(&lr);
X	if(lr.count)
X		ff(se,"%s\n",s128);
X	if(strncmp(s128,"CONNECT",7) == 0)
X		return(1);
X	return(0);
X
X}	/* end of hayes_dial */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv,envp)
X
X  main() program forks to create rcvr process; then main()
X  becomes the xmtr process
X------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xchar *cptr;
Xint iargv;
Xint swchar;
Xint itmp;
XLRWT lr;
Xchar rd_buf[64];
Xlong now;
Xlong julian;
Xlong time_at_connect;
Xint day_of_year,year,month,day,hour,min,sec;
Xint fdcmos;
Xint have_time = 0;
Xint max_tries;
Xstruct tm *lt;
Xstruct tm *gmtime();
Xstruct tm *localtime();
Xextern char *optarg;
X
X	setbuf(stderr,NULL);
X	setbuf(stdout,NULL);
X
X/* init line variables */
X	strcpy(Lline,"/dev/tty1a");
X	strcpy(Ltelno,"1(202)653-0351");
X	Liofd = -1;
X	Lbaud = 1200;
X	Lparity = 0;
X
X	if(argc < 2)
X		usage();
X
X	if((argc == 2) && (!strcmp(argv[1],"-")))
X		;
X	else
X	{
X		while((swchar = getopt(argc,argv,"eonb:t:l:")) != -1)
X		{
X			switch(swchar)
X			{
X				case 'e': Lparity = 'e'; break;
X				case 'o': Lparity = 'o'; break;
X				case 'n': Lparity =  0 ; break;
X				case 'b': Lbaud = atoi(optarg); break;
X				case 't': strcpy(Ltelno,optarg); break;
X				case 'l': strcpy(Lline,optarg); break;
X				default:  usage();
X			}
X		}
X	}
X
X	uid = getuid();
X	euid = geteuid();
X	if((euid == 0) || (uid == 0))	/* if root running or prog text ... */
X		nice(-40);
X	else
X	{
X		ff(se,"must be root\n");
X		exit(252);
X	}
X
X	if((fdcmos = open(cmos,O_RDWR,0)) < 0)
X	{
X		perror(cmos);
X		exit(251);
X	}
X
X	signal(SIGHUP,hangup);
X	signal(SIGQUIT,hangup);
X	signal(SIGINT,hangup);
X	signal(SIGTERM,hangup);
X
X	ff(se,"using %s, ",Lline);
X	if(itmp = lopen())
X	{
X		switch(itmp)
X		{
X			case LOPEN_INVALID:
X				ff(se,"invalid line name\n"); break;
X			case LOPEN_UNKPID:
X				ff(se,"unknown pid is using line\n"); break;
X			case LOPEN_LCKERR:
X				ff(se,"lock file error\n"); break;
X			case LOPEN_NODEV:
X				ff(se,"line does not exist\n"); break;
X			case LOPEN_ALREADY:
X				ff(se,"line already open\n"); break;
X			case LOPEN_OPNFAIL:
X				ff(se,"line open error\n"); break;
X			default:
X				ff(se,"pid %d using line\n",itmp); break;
X		}
X		exit(250);
X	}
X
X	lr.to1 = 1100L;
X	lr.to2 =  100L;
X	lr.raw_flag = 0;	/* full raw read */
X	lr.buffer = rd_buf;
X	lr.bufsize = sizeof(rd_buf);
X
X/* spend money on long distance call ... only time freaks can understand */
X	if(!hayes_dial())
X	{
X		fputs("\ndial failed\n",se);
X		hangup(255);
X	}
X
X	time_at_connect = time((long *)0);
X
X	max_tries = 40;		/* 40 sec max connect time (charged for 1 min anyway) */
X	while(!have_time)
X	{
X		for(itmp = 0; itmp < 30; itmp++)		/* look for asterisk */
X		{
X			if(lgetc_timeout(500L) == NBSTONE)
X				break;
X		}
X
X		lgets_timeout(&lr);		/* get date/time string */
X
X		if(sscanf(lr.buffer,NBSFMT,&julian,&day_of_year,&hour,&min,&sec) != 5)
X		{
X			ff(se,"garbled result: '%s'  ",lr.buffer);
X			if(--max_tries)
X			{
X				puts("... retrying");
X				continue;
X			}
X			puts("... aborting");
X			break;		/* too many retries ... BAAAAD line condx */
X		}
X		have_time = 1;
X	}
X
X	lclose();
X
X/* no longer spending money */
X
X	fprintf(stdout,"Connect time %ld second(s)\n",
X		time((long *)0) - time_at_connect);
X
X	if(have_time)
X	{
X		now = (((julian - EPOCH) * 24 + hour) * 60 + min) * 60 + sec;
X		now--; /* off by one */
X		if(stime(&now) < 0)
X		{
X			perror("stime");
X			exit(249);
X		}
X		fputs("Time retrieved from standard: ",stdout);
X		fputs(ctime(&now),stdout);
X		time(&now);
X		get_clock(fdcmos,&year,&month,&day,&hour,&min,&sec);
X		printf("cmos time before setting: %02d/%02d/%04d %02d:%02d:%02d %s\n",
X			month+1,day+1,year,hour,min,sec,
X#if defined(M_UNIX)
X			"UTC"
X#else
X			"local"
X#endif
X			);
X		fputs("           after setting: ",stdout);
X#if defined(M_UNIX)
X		lt = gmtime(&now);
X#else
X		lt = localtime(&now);
X#endif
X		set_clock(fdcmos,lt->tm_year,lt->tm_mon,lt->tm_mday,
X				lt->tm_hour,lt->tm_min,lt->tm_sec);
X		get_clock(fdcmos,&year,&month,&day,&hour,&min,&sec);
X		printf("%02d/%02d/%04d %02d:%02d:%02d %s\n",
X			month+1,day+1,year,hour,min,sec,
X#if defined(M_UNIX)
X			"UTC"
X#else
X			"local"
X#endif
X			);
X		exit(0);
X	}
X	else
X	{
X		puts("Did not get time ... sorry");
X		exit(254);
X	}
X
X}	/* end of main */
X/* end of NBSsetclk.c */
X
SHAR_EOF
echo "File NBSsetclk.c is complete"
chmod 0644 NBSsetclk.c || echo "restore of NBSsetclk.c fails"
if [ $TOUCH = can ]
then
    touch -m 0105205390 NBSsetclk.c
fi
echo "x - extracting at_cmos.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > at_cmos.h &&
X/* CHK=0x9C84 */
X/* vi: set tabstop=4 shiftwidth=4: */
X/*+-------------------------------------------------------------------------
X	at_cmos.h -- AT 286/386 cmos ram definitions (some problems in here)
X	...!gatech!kd4nc!n4hgf!wht
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:02-03-1989-19:50-wht-386 release */
X/*:07-23-1988-19:06-wht-release */
X/*:07-23-1988-15:12-wht-break out from cmos_disp.c */
X
X#ifndef uchar
X#define uchar	unsigned char
X#endif
X
Xtypedef struct at_cmos
X{
X	uchar	sec;
X	uchar	sec_alarm;
X	uchar	min;
X	uchar	min_alarm;
X	uchar	hour;
X	uchar	hour_alarm;
X	uchar	day;			/* 0-6 */
X	uchar	date;			/* 1-31 */
X	uchar	month;
X	uchar	year;
X	uchar	srA;			/* status register A */
X	uchar	srB;			/* status register B */
X	uchar	srC;			/* status register C */
X	uchar	srD;			/* status register D */
X
X	uchar	dsb;			/* diagnostic status byte */
X	uchar	ssb;			/* shutdown status byte */
X	uchar	ddtb;			/* diskette drive type byte */
X	uchar	rsvd11;			/* byte at address 0x11 reserved */
X	uchar	fdtb;			/* fixed disk type byte */
X	uchar	rsvd13;			/* byte at address 0x13 reserved */
X	uchar	equip;			/* equipment byte */
X
X/* base size of memory = (contents(byte 0x16) << 8) + contents(byte 0x15) */
X	uchar	base_low;		/* low base memory byte */
X	uchar	base_high;		/* hi base memory byte */
X	
X/* memory expansion size similar calculation (0x17 low order byte, 0x18 hi) */
X	uchar	expand_low;
X	uchar	expand_high;
X
X/* reserved bytes */
X	uchar	rsvd19_2D[ 0x2D - 0x19 + 1 ];
X
X/* checksum (on bytes in addresses 0x10 - 0x20) */
X	uchar	cksum_high;		/* tech ref sez these bytes in other order */
X	uchar	cksum_low;
X
X/* > 1 mb expansion size (in cmos ram addresses 0x30-31) */
X	uchar	exp2_low;
X	uchar	exp2_high;
X
X	uchar	century;		/* date century byte */
X	uchar	info_flag;		/* see IF_ bits below */
X
X	uchar	rsvd34_3F[ 0x3F - 0x34 + 1];
X
X} AT_CMOS;
X
Xunion cmos_union
X{
X	uchar		a[64];
X	AT_CMOS		s;
X};
X
X/*+-----------------------------------------------------------------------
X	AT Real Time Clock Status Register bit assignments
X------------------------------------------------------------------------*/
X#define SRA_UIP		0x80	/* update in progress */
X#define SRA_DV22	0x70	/* 3-bit time-base divider */
X#define SRA_DVOUT	0x0F	/* 4-bit time-base divider output freq */
X
X#define SRB_SET		0x80	/* when 1, no tick advance (set mode) */
X#define SRB_PIE		0x40	/* when 1, periodic interrupt */
X#define SRB_AIE		0x20	/* when 1, alarm enabled */
X#define SRB_UIE		0x10	/* enabled update-ended interrupt */
X#define SRB_SQWE	0x08	/* square wave enabled */
X#define SRB_DM		0x04	/* data mode 1==binary, 0==BCD */
X#define SRB_24HR	0x02	/* 1==24 hour mode, 0==12 hour mode */
X#define SRB_DSE		0x01	/* daylight savings time enabled */
X
X#define SRC_IRQF	0x80
X#define SRC_PF		0x40
X#define SRC_AF		0x20
X#define SRC_UF		0x10
X							/* remaining bits in status register C reserved */
X
X#define SRD_VRB		0x80	/* valid ram (==0 when power has been lost)
X							 * remaining bits in status register D reserved */
X
X/*+-----------------------------------------------------------------------
X	Diagnostic Status Byte
X------------------------------------------------------------------------*/
X#define DSB_RTLOST	0x80	/* ==1 if real time clock chip lost power */
X#define DSB_CSI		0x40	/* checksum status indicator == 1 if bad */
X#define DSB_ICI		0x20	/* invalid configuration information (if ==1) */
X#define DSB_MSM		0x10	/* memory size miscompare (==1 if different) */
X#define DSB_HDBAD	0x08	/* fixed disk bad if == 1 */
X#define DSB_TSI		0x04	/* time status indicator (==1 if time bad) */
X
X#ifdef NEEDED	/* not under XENIX! */
X#define		cmos_ctrl_dev		0x70		/* cmos address control port */
X#define		cmos_data_dev		0x71		/* cmos data i/o port */
X#endif
X
SHAR_EOF
chmod 0644 at_cmos.h || echo "restore of at_cmos.h fails"
if [ $TOUCH = can ]
then
    touch -m 0105205390 at_cmos.h
fi
echo "x - extracting cmos_disp.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > cmos_disp.c &&
X/* CHK=0x373F */
X/* vi: set tabstop=4 shiftwidth=4: */
X/*+-------------------------------------------------------------------------
X	cmos_disp.c -- interprets /dev/cmos 286/386 AT CMOS ram
X	...!gatech!kd4nc!n4hgf!wht
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:02-03-1989-19:50-wht-386 release */
X/*:02-03-1989-19:28-wht-fix bad itmp assigned,used in same func call */
X/*:07-23-1988-19:05-wht-release */
X/*:07-23-1988-14:17-wht-BIG face life on old program */
X
X#include <stdio.h>
X#include <fcntl.h>
X#include "at_cmos.h"
X#include "dev_cmos.h"
X
Xunion cmos_union	cmos;
X
Xchar	*day_of_week[] =
X{
X	"Sun","Mon","Tue","Wed","Thu","Fri","Sat"
X};
X
Xchar	*cmosname = "/dev/cmos";
X
Xmain(argc,argv)
Xint argc;
Xchar	**argv;
X{
Xregister int icmos;
Xregister int itmp;
Xchar	*format;
Xint fdcmos;
Xint clock_bcd_mode;			/* true if clock in bcd mode */
Xunsigned short calc_cksum;		/* calculated checksum */
Xunsigned short cmos_cksum;		/* checksum in cmos */
X
X	if((fdcmos = open(cmosname,O_RDONLY)) < 0)
X	{
X		perror(cmosname);
X		exit(1);
X	}
X	get_cmos(fdcmos,&cmos);
X	close(fdcmos);
X
X	for(icmos = 0; icmos < 64; icmos++)
X	{
X		if(icmos % 16 == 0)
X			printf("\n %02x:  ",icmos);
X		printf("%02x ",cmos.a[icmos]);
X		if(icmos % 4 == 3)
X			printf(" ");
X	}
X	printf("\n\n");
X
X	clock_bcd_mode = (cmos.s.srB & SRB_DM) ? 0 : 1;
X
X	itmp = cmos.s.base_high << 8 | cmos.s.base_low;
X	printf("Base memory:       %6dk  (%8lx bytes hex)\n",
X					itmp,(long)itmp * (long)1024);
X
X	itmp = cmos.s.expand_high << 8 | cmos.s.expand_low;
X	printf("Expansion memory:  %6dk  (%8lx bytes hex)\n",
X					itmp,(long)itmp * (long)1024);
X
X	itmp = cmos.s.exp2_high << 8 | cmos.s.exp2_low;
X	printf("Memory above 1MB:  %6dk  (%8lx bytes hex)\n",
X					itmp,(long)itmp * (long)1024);
X
X	printf("\n");
X
X	printf("Diag status byte: %02x  Shutdown status byte: %02x\n",
X					cmos.s.dsb,cmos.s.ssb);
X
X	if(cmos.s.dsb)
X	{
X		itmp = cmos.s.dsb;
X		printf("  Diagnostic Status Byte (DSB) says:\n");
X		if(itmp & 0x80)
X			printf("      Real-time clock has lost power.\n");
X		if(itmp & 0x40)
X			printf("      Bad configuration record checksum.\n");
X		if(itmp & 0x20)
X			printf("      Incorrect configuration information.\n");
X		if(itmp & 0x10)
X			printf("      Memory size miscompare.\n");
X		if(itmp & 0x08)
X			printf("      Fixed disk adapter failed init.\n");
X		if(itmp & 0x04)
X			printf("      Time is invalid.\n");
X		printf("\n");
X	}
X
X	printf("Clock: %d-hour mode, %s time, alarm %s, %s mode\n",
X					(cmos.s.srB & SRB_24HR) ? 24 : 12,
X					(cmos.s.srB & SRB_DSE) ? "daylight" : "standard",
X					(cmos.s.srB & SRB_AIE) ? "enabled" : "disabled",
X					(clock_bcd_mode) ? "bcd" : "hex");
X
X	if(clock_bcd_mode)
X		format = "Date: %02x-%02x-%02x%02x  ";
X	else
X		format = "Date: %02d-%02d-%02d%02d  ";
X	printf(format,cmos.s.month,cmos.s.date,cmos.s.century,cmos.s.year);
X
X	if(clock_bcd_mode)
X		format = "Time: %02x:%02x:%02x  Alarm: %02x:%02x:%02x\n";
X	else
X		format = "Time: %02d:%02d:%02d  Alarm: %02d:%02d:%02d\n";
X	printf(format,cmos.s.hour,cmos.s.min,cmos.s.sec,
X		cmos.s.hour_alarm,cmos.s.min_alarm,cmos.s.sec_alarm);
X
X	printf("Number of diskette drives: %d   Math coprocessor %s\n",
X					(int)(cmos.s.equip & 0xC0) >> 6,
X					(cmos.s.equip & 0x02) ? "present" : "not present"
X					);
X
X	printf("Primary display:  ");
X	switch( itmp = (cmos.s.equip & 0x30) >> 4)
X	{
X		case 1:
X			format = "Color/Graphics 40 column\n";
X			break;
X		case 2:
X			format = "Color/Graphics 80 column\n";
X			break;
X		case 3:
X			format = "Monochrome display\n";
X			break;
X		default:
X			format = "unknown type: %d\n";
X			break;
X	}
X	printf(format,itmp);
X
X/* tech ref doesn't say: empirically determined checksum algorithm (correct?) */
X	calc_cksum = 0;
X	for(itmp = 0x10; itmp < 0x21; itmp++)
X		calc_cksum += cmos.a[itmp];
X	calc_cksum++;
X
X	cmos_cksum = (cmos.s.cksum_high << 8) | cmos.s.cksum_low;
X	printf("Checksum: in ram: %04x  calculated: %04x\n",cmos_cksum,calc_cksum);
X
X	exit(0);	/* for now */
X	
X}	/* end of main() */
X
SHAR_EOF
chmod 0644 cmos_disp.c || echo "restore of cmos_disp.c fails"
if [ $TOUCH = can ]
then
    touch -m 0105205390 cmos_disp.c
fi
echo "x - extracting dev_cmos.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > dev_cmos.c &&
X/* CHK=0x1DB0 */
X/* vi: set tabstop=4 shiftwidth=4: */
X/*+-------------------------------------------------------------------------
X	dev_cmos.c -- XENIX /dev/cmos routines
X	...!gatech!kd4nc!n4hgf!wht
X
X  Defined functions:
X	bcdch_to_uchar(bcdch)
X	get_clock(fdcmos,year,month,day,hour,min,sec)
X	get_cmos(fdcmos,cmosbuf)
X	set_clock(fdcmos,year,month,day,hour,min,sec)
X	uchar_to_bcdch(uch)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:02-03-1989-19:50-wht-386 release */
X/*:07-23-1988-19:06-wht-release */
X/*:07-23-1988-13:53-wht-creation */
X
X#include "at_cmos.h"
X#include "dev_cmos.h"
X
Xlong seek(int,long,int);
Xint read(int,char *,int);
X
Xunion cmos_union cu;
X
X#define SEEKPOS(elem)	((long)((char *)&cu.s.elem - (char *)&cu))
X
X/*+-------------------------------------------------------------------------
X	bcdch_to_uchar(bcdch) -- convert two-nibble bcd to binary
X--------------------------------------------------------------------------*/
Xunsigned char
Xbcdch_to_uchar(bcdch)
Xunsigned char bcdch;
X{
X	return((((bcdch & 0xF0) >> 4) * 10) + (bcdch & 0x0F));
X}	/* end of bcdch_to_uchar */
X
X/*+-------------------------------------------------------------------------
X	uchar_to_bcdch(uch) -- convert binary to two-nibble bcd
X--------------------------------------------------------------------------*/
Xunsigned char
Xuchar_to_bcdch(uch)
Xunsigned char uch;
X{
X	return(((uch / 10) << 4) | (uch % 10));
X}	/* end of uchar_to_bcdch */
X
X/*+-------------------------------------------------------------------------
X	get_cmos(fdcmos,cmosbuf)
X--------------------------------------------------------------------------*/
Xvoid
Xget_cmos(fdcmos,cmosbuf)
Xint fdcmos;
Xunion cmos_union *cmosbuf;
X{
Xunsigned int wait_counter;
Xunsigned char stat_reg_A;
X
X/* check for clock update in progress and wait til done */
X	wait_counter = 32768;
X	while(1)
X	{
X		if(--wait_counter == 0)
X		{
X			puts("/dev/cmos: clock update in progress for too long");
X			exit(200);
X		}
X		
X		lseek(fdcmos,SEEKPOS(srA),0);		/* position to status register A */
X		read(fdcmos,&stat_reg_A,1);
X		if(!(stat_reg_A & SRA_UIP))			/* check update bit */
X			break;							/* and break out of loop if not */
X	}
X
X/* read the cmos ram */
X	lseek(fdcmos,0L,0);
X	read(fdcmos,(char *)cmosbuf,sizeof(AT_CMOS));
X
X}	/* end of get_cmos */
X
X/*+-------------------------------------------------------------------------
X	get_clock(fdcmos,year,month,day,hour,min,sec) -- read /dev/cmos clock
X
Xfdcmos open fd to /dev/cmos
Xreturn values:
Xyear is full year (e.g., 1988)
Xmonth is 0-11
Xday is 0-30
Xhour is 0-23
Xmin is 0-59
X--------------------------------------------------------------------------*/
Xvoid
Xget_clock(fdcmos,year,month,day,hour,min,sec)
Xint fdcmos;
Xint *year;
Xint *month;
Xint *day;
Xint *hour;
Xint *min;
Xint *sec;
X{
X	get_cmos(fdcmos,&cu);
X
X	*year  = (int)bcdch_to_uchar(cu.s.year) + 1900;
X	*month = (int)bcdch_to_uchar(cu.s.month) - 1;
X	*day   = (int)bcdch_to_uchar(cu.s.date) - 1;
X	*hour  = (int)bcdch_to_uchar(cu.s.hour);
X	*min   = (int)bcdch_to_uchar(cu.s.min);
X	*sec   = (int)bcdch_to_uchar(cu.s.sec);
X
X}	/* end of get_clock */
X
X/*+-------------------------------------------------------------------------
X	set_clock(fdcmos,year,month,day,hour,min,sec) -- write /dev/cmos clock
Xfdcmos open fd to /dev/cmos
Xother values: as returned by localtime()
X--------------------------------------------------------------------------*/
Xvoid
Xset_clock(fdcmos,year,month,day,hour,min,sec)
Xint fdcmos;
Xint year;
Xint month;
Xint day;
Xint hour;
Xint min;
X{
Xunsigned char stat_reg_B;
Xunsigned char wchar;
X
X	month++;			/* month to 1-n */
X	year %= 100;		/* think ahead (ha) */
X
X/* set no tick advance */
X	lseek(fdcmos,SEEKPOS(srB),0);
X	read(fdcmos,&stat_reg_B,1);		/* get current value */
X	stat_reg_B |= SRB_SET;
X	lseek(fdcmos,SEEKPOS(srB),0);
X	write(fdcmos,&stat_reg_B,1);	/* plug new value */
X
X/* set clock */
X	wchar = uchar_to_bcdch((uchar)year);
X	lseek(fdcmos,SEEKPOS(year),0);
X	write(fdcmos,&wchar,1);
X
X	wchar = uchar_to_bcdch((uchar)month);
X	lseek(fdcmos,SEEKPOS(month),0);
X	write(fdcmos,&wchar,1);
X
X	wchar = uchar_to_bcdch((uchar)day);
X	lseek(fdcmos,SEEKPOS(date),0);
X	write(fdcmos,&wchar,1);
X
X	wchar = uchar_to_bcdch((uchar)hour);
X	lseek(fdcmos,SEEKPOS(hour),0);
X	write(fdcmos,&wchar,1);
X
X	wchar = uchar_to_bcdch((uchar)min);
X	lseek(fdcmos,SEEKPOS(min),0);
X	write(fdcmos,&wchar,1);
X
X	wchar = uchar_to_bcdch((uchar)sec);
X	lseek(fdcmos,SEEKPOS(sec),0);
X	write(fdcmos,&wchar,1);
X	
X/* set no tick advance */
X	lseek(fdcmos,SEEKPOS(srB),0);
X	stat_reg_B &= ~SRB_SET;
X	write(fdcmos,&stat_reg_B,1);	/* plug new value */
X
X}	/* end of set_clock */
X
SHAR_EOF
chmod 0644 dev_cmos.c || echo "restore of dev_cmos.c fails"
if [ $TOUCH = can ]
then
    touch -m 0105205490 dev_cmos.c
fi
echo "x - extracting dev_cmos.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > dev_cmos.h &&
X/* CHK=0xB3E6 */
X/* vi: set tabstop=4 shiftwidth=4: */
X/*+-------------------------------------------------------------------------
X	dev_cmos.h -- prototypes for dev_cmos.c functions
X	...!gatech!kd4nc!n4hgf!wht
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:02-03-1989-19:50-wht-386 release */
X/*:07-23-1988-19:07-wht-release */
X/*:07-23-1988-13:55-wht-creation */
X
Xunsigned char bcdch_to_uchar(unsigned char );
Xunsigned char uchar_to_bcdch(unsigned char );
Xvoid get_cmos(int ,union cmos_union  *);
Xvoid get_clock(int ,int  *,int  *,int  *,int  *,int  *,int  *);
Xvoid set_clock(int ,int ,int ,int ,int ,int ,int );
SHAR_EOF
chmod 0644 dev_cmos.h || echo "restore of dev_cmos.h fails"
if [ $TOUCH = can ]
then
    touch -m 0105205490 dev_cmos.h
fi
echo "x - extracting set_24hr.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > set_24hr.c &&
X/* CHK=0x0EC7 */
X/*+-------------------------------------------------------------------------
X	set_24hr.c
X	...!gatech!kd4nc!n4hgf!wht
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:05-18-1989-13:03-wht-creation */
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/types.h>
X
X#include "at_cmos.h"
X
Xchar	*cmos = "/dev/cmos";
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xint fdcmos;
XAT_CMOS *base;
Xlong srB_pos = (long)((char *)&base->srB - (char *)base);
Xuchar srB;
Xlong lseek();
X
X	setbuf(stdout,NULL);
X	setbuf(stderr,NULL);
X
X	if((fdcmos = open(cmos,O_RDWR,0)) < 0)
X	{
X		perror("/dev/cmos open");
X		exit(1);
X	}
X
X	if(lseek(fdcmos,srB_pos,0) != srB_pos)
X	{
X		perror("/dev/cmos seek 1");
X		exit(1);
X	}
X
X	if(read(fdcmos,&srB,1) != 1)
X	{
X		perror("/dev/cmos read");
X		exit(1);
X	}
X
X	srB |= SRB_24HR;
X
X	if(lseek(fdcmos,srB_pos,0) != srB_pos)
X	{
X		perror("/dev/cmos seek 2");
X		exit(1);
X	}
X
X	if(write(fdcmos,&srB,1) != 1)
X	{
X		perror("/dev/cmos write");
X		exit(1);
X	}
X
X	system("cmos_disp");
X	exit(0);
X}	/* end of main */
SHAR_EOF
chmod 0644 set_24hr.c || echo "restore of set_24hr.c fails"
if [ $TOUCH = can ]
then
    touch -m 0105205590 set_24hr.c
fi
rm -f s3_seq_.tmp
echo "You have unpacked the last part"
exit 0
 
----------------------------------------------------------------------------
Warren Tucker                     emory!n4hgf!wht or wht at n4hgf.Mt-Park.GA.US
"I was 35 years old before I knew a pie was meant to be eaten." - Moe Howard



More information about the Alt.sources mailing list