www.pudn.com > 访问AT机CMOS和时钟.zip > CMOSCLK.C


#define MSC		1 
#define MSDOS	1 
 
#include  
#if MSC  
#include  
#include  
#endif 
 
 
/* 
 * cmosclk. 
 * 
 * 
 * See below for more information. 
 * 
 */ 
 
 
char	*documentation[] = { 
"cmosclk either sets the CMOS date/time from the MS-DOS date/time", 
"    or         sets the MS-DOS date/time from the CMOS date/time", 
"   cmosclk [flags]", 
"", 
"Flags are single characters preceeded by '-':", 
"   -w      Write the CMOS date/time from the MS-DOS date/time", 
"   -r      Read the CMOS date/time into the MS-DOS date/time", 
"   -s      Write the CMOS date/time to STDOUT (mm/dd/yy hh:mm:ss)", 
"   -t      Write the CMOS time only to STDOUT (hh:mm:ss)", 
"   -d      Write the CMOS date only to STDOUT (mm/dd/yy)", 
"", 
0 }; 
 
 
#ifndef stdin 
#define stdin STDIN 
#define stdout STDOUT 
#define stderr STDERR 
#endif 
 
#define LMAX	512		/* max number of entries per directory */ 
 
int	wflag = 0; 
int	rflag = 1;		/* default to read the CMOS time into the MS-DOS time */ 
int	sflag = 0; 
int	tflag = 0; 
int	dflag = 0; 
 
int	debug	=	0;	   /* Set for debug code      */ 
 
 
/*******************************************************/ 
 
main(argc, argv) 
char *argv[]; 
int argc; 
{ 
	register int c; 
	register char *p; 
	int nfile, i; 
 
   if (argc <= 1) 
      usage("No arguments"); 
   if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) { 
      help(documentation); 
      return; 
      } 
   nfile = argc-1; 
   for (i=1; i < argc; ++i) { 
      p = argv[i]; 
      if (*p == '-') { 
	 ++p; 
	 while (c = *p++) { 
	    switch(tolower(c)) { 
 
	    case '?': 
	       help(documentation); 
	       return; 
 
	    case 'x': 
	       ++debug; 
	       break; 
 
	    case 's': 
	       tflag = dflag = sflag = 1; 
	       rflag = wflag = 0; 
	       break; 
 
	    case 't': 
	       sflag = tflag = 1; 
	       rflag = wflag = 0; 
	       break; 
 
	    case 'd': 
	       sflag = dflag = 1; 
	       rflag = wflag = 0; 
	       break; 
 
	    case 'r': 
	       rflag = 1; 
	       sflag = wflag = 0; 
	       break; 
 
	    case 'w': 
	       wflag = 1; 
	       rflag = sflag = 0; 
	       break; 
 
 
	    default: 
	       usage("Unknown flag"); 
	    } 
	 } 
	 argv[i] = 0; 
	 --nfile; 
      }  
   } 
   if (nfile != 0) 
      usage("No filenames are allowed.  cmosclk -? for instructions."); 
 
   if (sflag || rflag) 
   		readcmos();			/* read cmos date/time */ 
   else if (wflag) 
   		writecmos();		/* write cmos date/time */ 
   else 
   		usage("No flags set. cmosclk -? for instructions."); 
} 
 
 
/*******************************************************/ 
 
int writecmos() 
{ 
	union REGS inregs, outregs; 
 
/*   set CMOS date from MS-DOS date */ 
	inregs.h.ah = 0x2a;			/* get date BDOS call */ 
	intdos(&inregs, &outregs); 
	inregs.x.cx = b2bcd(outregs.x.cx);	/* yr */	/* convert to BCD */ 
	inregs.h.dh = b2bcd(outregs.h.dh);  /* mon */ 
	inregs.h.dl = b2bcd(outregs.h.dl);  /* day */ 
	inregs.h.ah = 5;						/* set date function */ 
	int86(0x1a, &inregs, &outregs);		/* call Real Time Clock interrupt */ 
 
/* set CMOS time from MS-DOS time */ 
	inregs.h.ah = 0x2c;		/* get time BDOS call */ 
	intdos(&inregs, &outregs); 
	inregs.h.ch = b2bcd(outregs.h.ch);  /* hour */		/* convert to BCD */ 
	inregs.h.cl = b2bcd(outregs.h.cl);  /* min */ 
	inregs.h.dh = b2bcd(outregs.h.dh);  /* sec */ 
	inregs.h.dl = 0;					/* hundredths */ 
	inregs.h.ah = 3;						/* set time function */ 
	int86(0x1a, &inregs, &outregs);		/* call Real Time Clock interrupt */ 
 
} 
 
/*******************************************************/ 
 
int readcmos() 
{ 
	union REGS inregs, outregs; 
 
/*   set MS-DOS date from CMOS date */ 
	inregs.h.ah = 04;						/* get date function */ 
	int86(0x1a, &inregs, &outregs);		/* call Real Time Clock interrupt */ 
	inregs.x.cx = bcd2b(outregs.x.cx);	/* yr */	/* convert to BCD */ 
	inregs.h.dh = bcd2b(outregs.h.dh);  /* mon */ 
	inregs.h.dl = bcd2b(outregs.h.dl);  /* day */ 
	if (rflag) { 
		inregs.h.ah = 0x2b;			/* set date BDOS call */ 
		intdos(&inregs, &outregs); 
	} 
	else if (dflag) { 
		printf("%02d/%02d/%02d ", inregs.h.dh, inregs.h.dl, inregs.x.cx % 100); 
	} 
 
/* set MS-DOS time from CMOS time */ 
	inregs.h.ah = 02;						/* get time function */ 
	int86(0x1a, &inregs, &outregs);		/* call Real Time Clock interrupt */ 
	inregs.h.ch = bcd2b(outregs.h.ch);  /* hour */		/* convert to BCD */ 
	inregs.h.cl = bcd2b(outregs.h.cl);  /* min */ 
	inregs.h.dh = bcd2b(outregs.h.dh);  /* sec */ 
	inregs.h.dl = 0;					/* hundredths */ 
	if (rflag) { 
		inregs.h.ah = 0x2d;		/* set time BDOS call */ 
		intdos(&inregs, &outregs); 
	} 
	else if (tflag) { 
		printf("%02d:%02d:%02d\n ", inregs.h.ch, inregs.h.cl, inregs.h.dh); 
	} 
 
} 
 
/*******************************************************/ 
 
int b2bcd(bin) 
int bin; 
{ 
	int quotient, remainder, ret; 
 
	if (bin > 9999)			/* BCD would overflow */ 
		return 0; 
 
	ret = bin / 1000;	/* get first nibble */ 
	remainder = bin - (ret * 1000); 
	quotient = remainder / 100; 
	ret = (ret << 4) | quotient; 
	remainder -= (quotient * 100); 
	quotient = remainder / 10; 
	ret = (ret << 4) | quotient; 
	remainder -= (quotient * 10); 
	ret = (ret << 4) | remainder; 
 
	return ret; 
} 
		 
/*******************************************************/ 
 
int bcd2b(bin) 
int bin; 
{ 
	int ret; 
 
	ret = (bin & 0x0f) 						/* one's digit */ 
		+ ((bin >> 4) & 0x0f) * 10			/* ten's digit */ 
		+ ((bin >> 8) & 0x0f) * 100			/* hundred's digit */ 
		+ ((bin >> 12) & 0x0f) * 1000;		/* thousand's digit */ 
 
	return ret; 
} 
		 
/*******************************************************/ 
 
usage(s) 
char	*s; 
{ 
   fputs("?CMOSCLK-E-", stdout); 
   fputs(s, stdout); 
   fputs("\n", stdout); 
   fputs("Usage: cmosclk [-srw].   cmosclk ? for help\n", stdout); 
   exit(1); 
}