[comp.sys.att] Dealing with the 6300's clock/cal chip

wtm@neoucom.UUCP (Bill Mayhew) (09/09/87)

Hi,

A while back, a kind soul mailed me the following c program.  I
think this pretty much says it all.  Note that the years are modulo
1984 in the case of the 6300.  The program below compiles
correectly under turbo C, and should be suitable food for most PC
compatible compilers...

---------------------------cut here----------------------

/**************************************************************************
* This routine is used to access the hardware clock chip for PC-DOS.      *
*                                                                         *
* Options:                                                                *
*    No options: Prompts for new date and time.                           *
*      -s or /s: Sets the DOS clock only and reports the time and date.   *
*                                                                         *
*                                                                         *
*  Version 0.0  9-11-86 by Jim Seley   using Microsoft C Ver 3.0          *
*************************************************************************/
#include <stdio.h>
#include <dos.h>

#define TESTMODE 0x70
#define START_STOP 0x7e
#define SEC    0x72
#define SEC10  0x73
#define MIN    0x74
#define MIN10  0x75
#define HR     0x76
#define HR10   0x77
#define DAY    0x78
#define DAY10  0x79
#define MONTH  0x7b
#define MONTH10 0x7c
#define YEAR   0x7f

union REGS inregs, outregs;          /* storage for dos interrupts */
int sec, min, hr, day, month,year;   /* time date data */

main(argc,argv)
int argc;
char *argv[];
{

    int i, s_flag;

    read_clock();

    set_dos_time();

    s_flag = 0;
    if ( argc>1 )
        if ( *(argv[1]+1) == 'S' || *(argv[1]+1) == 's' )
            s_flag=1;
        else {
            printf("Illegal option: %s\n",argv[1]);
            return(3);
            }

    if( s_flag )
        printf("%d-%d-%d  %d:%02d:%02d\n",month,day,year,hr,min,sec);
    else {
        if ( get_date() ) {
            printf("Invalid Date\n");
            return(1);
            }

        if ( get_time() ) {
            printf("Invalid Time\n");
            return(2);
            }

        i=set_dos_time();
        if (i == 1)
            printf("Invalid Date\n");
        else if ( i == 2)
            printf("Invalid Time\n");
        else
            set_clock();

        return(i);
    }
}

set_dos_time()  /* Set the DOS date and time */
{

    inregs.h.ah = 0x2b;      /* set date function */
    inregs.x.cx = (unsigned int)year;
    inregs.h.dh = (unsigned char)month;
    inregs.h.dl = (unsigned char)day;
    intdos(&inregs,&outregs);
    if (outregs.h.al)
        return(1);

    inregs.h.ah = 0x2d;      /* set time function */
    inregs.h.ch = (unsigned char)hr;
    inregs.h.cl = (unsigned char)min;
    inregs.h.dh = (unsigned char)sec;
    inregs.h.dl = 0;
    intdos(&inregs,&outregs);
    if (outregs.h.al)
        return(2);
    return(0);
    }


read_clock()   /* Read the hardware clock registors */
{

    outp(TESTMODE,0);  /* clear test mode */
    sec = in(SEC);
    sec += in(SEC10)*10;
    min = in(MIN);
    min += in(MIN10)*10;
    hr = in(HR);
    hr += in(HR10)*10;
    day = in(DAY);
    day += in(DAY10)*10;
    month = in(MONTH);
    month += in(MONTH10)*10;
    year = in(YEAR) & 0x7;
    year += 1984;
    return(0);
    }
    

get_date()    /* Input a new date */
{
    char t[81], *p1, *p2, *p3;

    printf("Current date is %d-%d-%d\nEnter new date: ",month,day,year);
    gets(t);
    if ( t[0] != '\0' ){

        p1 = t;                  /* p1 points to month */
        p2 = strchr(t,'-');
        if( p1 == NULL ) return(1);
        *p2++ = '\0';            /* p2 points to day */
        p3 = strchr(p2,'-');
        if( p3 == NULL ) return(1);
        *p3++ = '\0';            /* p3 points to year */
        year = atoi(p3);
        if ( year < 100 )
            year = year + 1900;
        day = atoi(p2);
        month = atoi(p1);
        }
    return(0);
}

get_time()  /* Input a new time */
{
    char t[81], *p1, *p2, *p3;

    printf("\nCurrent time is %d:%02d:%02d\nEnter new time: ",hr,min,sec);
    gets(t);
    if ( t[0] != '\0' ){

        p1 = t;                  /* p1 points to hr */
        p2 = strchr(t,':');
        if (p2 == NULL)
            return(1);
        *p2++ = '\0';            /* p2 points to min */

        hr = atoi(p1);
        min = atoi(p2);
        sec = 0;
        }
    return(0);
}

set_clock()     /* Set the hardware clock */
{
    outp(TESTMODE,0);
    outp(START_STOP,0);           /* stop clock */
    outp(MIN,min%10);
    outp(MIN10,min/10);
    outp(HR,hr%10);
    outp(HR10,hr/10);
    outp(DAY,day%10);
    outp(DAY10,day/10);
    outp(MONTH,month%10);
    outp(MONTH10,month/10);
    year = year-1984;
    year |= 0x08;                 /* set repeated interrupt bit */
    outp(YEAR,year);
    inp(YEAR);                    /* make the clock chip happy */
    inp(YEAR);
    inp(YEAR);
    outp(START_STOP,0xff);        /* start clock */
    return(0);
}

in( port )
int port;
{
    int i;
    do  {
        i=inp(port) & 0xf;
        } while( i == 0xf );
    return( i );
}
---------------------end of the file--------------------

Bill Mayhew, Electrical Engineer
Division of Basic Medical Sciences
Northeastern Ohio Universities' College of Medicine
Rootstown, OH  44272-9989    phone:  216-325-2511
(wtm@neoucom.UUCP   ...!cbatt!neoucom!wtm)