2.11BSD/src/sbin/gt307/gt307.c

Compare this file to the similar file:
Show the results in this format:

/*
 *  GT307
 *
 * Read and set a Computer Products inc GT307 clock calendar card
 *
 * Author  R Birch
 * Date    July 1999
 *
 * You can use this in two ways.  If you use Daylight Savings Time when
 * the card is intialised then it can be used to maintain local time.
 * If DST is not used then this is probably best used to maintain the card
 * on UTC.
 *
 * Usage:
 *
 *    gt307 [-d n][-l] [yymmddhhmm.ss]
 *
 *    -d sets DST on or off n = 1 (on) n = 0 (off)
 *    -l switches output between long or short.  Short is suitable
 *      as an input into date(8)
 *    The time string is the same as date(8) for input.
*/

#if !defined(lint) && defined(DOSCCS)
static char sccsid[] = "@(#)GT307.c 1.00 (2.11BSD) 99/7/4";
#endif

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include <sys/errno.h>
#include <sys/types.h>

#define BASE_ADDR 0177704
#define IO_VEC 0450
#define SEG_REG 6
#define IO_SIZE 1

#define REG_A   012
#define REG_B   013
#define REG_C   014
#define REG_D   015

#define UIP    0200
#define DV2    0100
#define DV1     040
#define DV0     020
#define RS3     010
#define RS2      04
#define RS1      02
#define RS0      01

#define SET    0200
#define PIE    0100
#define AIE     040
#define UIE     020
#define SQWE    010
#define DM       04
#define D24      02
#define DSE      01

#define IRQF    0200
#define PF      0100
#define AF       040
#define UF       020

#define VRT     0200

#define CONST   1

char *days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
char *months[] = {"Jan","Feb","Mar","Apr","May","Jun",
		  "Jul","Aug","Sep","Oct","Nov","Dec"};

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

        register unsigned char   *io_ptr;
        char    time_str[80];
        unsigned int    seg_reg = SEG_REG;
        unsigned int    io_size = IO_SIZE;
        unsigned int    physaddr = BASE_ADDR;
        unsigned char   memval;
        int     ch;
        int     lflag;
        int     dst_flag;
        int     year;
        int     bigyear;
        int     month;
        int     date;
        int     day;
        int     hours;
        int     minutes;
        int     seconds;

/*
 * Set up the page address pointer.  This is written to allow simple
 * changing of the #defines at the start of the program to ripple through
 * to the rest of the code.  Do not allow 0 because that would collide
 * with the first 8kb of code or data.  Do not allow 7 because that would
 * collide with our stack.
*/
	assert(seg_reg > 0 && seg_reg < 7);
	io_ptr = (unsigned char *)((u_int)020000 * seg_reg);
/*
 * Map the new page to the physical address of the card.
*/
        if	(phys(seg_reg, io_size, physaddr) == -1)
		err(1, "phys(%d, %d, 0%o)", seg_reg, io_size, physaddr);
/*
 * process command line
*/
        dst_flag = 0;           /* Set defaults */
        lflag = 0;

        while	((ch = getopt(argc, argv,"d:l")) != EOF)
                switch((char)ch){
                        case 'd':
                                dst_flag = atoi(optarg) ? 1 : 0;
                                break;
                        case 'l':
                                lflag = 1;
                                break;
                        default:
                                errx(1,"invalid parameters.\n");
                        }
        argc -= optind;
        argv += optind;

        if	(argc > 1)
                errx(1,"invalid parameters.");

/*
 * If we still have an argument left then we are setting the clock,
 * otherwise we are displaying what is in the card.
*/
        if	(!argc)
                goto display;
        goto setup;

display:
/*
 * Look at the card to check whether the time on the card is
 * valid or not.
*/
        memval = (unsigned char)*(io_ptr + REG_D);
        if	((memval & VRT) == 0)
                errx(1," board clock invalid, reinitialise.");
/*
        Get the time from the card
*/
        memval = (unsigned char)*(io_ptr + REG_A);
        while((memval & UIP) == 1)
                memval = (unsigned char)*(io_ptr + REG_A);

        seconds = (int)*(io_ptr);
        minutes = (int)*(io_ptr + 2);
        hours = (int)*(io_ptr + 4);
        day = (int)*(io_ptr + 6);
        date = (int)*(io_ptr + 7);
        month = (int)*(io_ptr + 8);
        year = (int)*(io_ptr + 9);

        if(year <= 70)
                bigyear = year + 2000;
        else
                bigyear = year + 1900;

        if	(lflag == 0)
                printf("%02d%02d%02d%02d%02d.%02d\n",year,month,date,
                        hours,minutes,seconds);
        else
                printf("%s %s %d %02d:%02d:%02d %04d\n",
                        days[weekday(date,month, bigyear)],months[month - 1],
                        date,hours,minutes,seconds,bigyear);
        exit(0);

/*
 * set the card up given the input time contained in command line.
*/
setup:

/*
 *      Reset card for interrupts
*/
        memval = (unsigned char)(SET | D24 | DM);
        if	(dst_flag == 1)
                memval = memval | DSE;
        *(io_ptr + REG_B) = (unsigned char)memval;

        memval = (unsigned char)DV1;
        *(io_ptr + REG_A) = (unsigned char)memval;

        strcpy(time_str,*argv);

        seconds = 0;
        minutes = 0;
        hours = 0;
        day = 0;
        date = 0;
        month = 0;
        year = 0;

        (void)sscanf(time_str,"%2d%2d%2d%2d%2d.%2d",&year,&month,&date,&hours,
                &minutes,&seconds);

        if	(year <= 70)
                bigyear = year + 2000;
        else
                bigyear = year + 1900;

        day = weekday(date,month,bigyear) + 1;

        *(io_ptr) = (unsigned char)seconds;
        *(io_ptr + 2) = (unsigned char)minutes;
        *(io_ptr + 4) = (unsigned char)hours;
        *(io_ptr + 6) = (unsigned char)day;
        *(io_ptr + 7) = (unsigned char)date;
        *(io_ptr + 8) = (unsigned char)month;
        *(io_ptr + 9) = (unsigned char)year;

/*
 *      Start the card
*/
        memval = (unsigned char)*(io_ptr + 013);
        memval = memval & 0177;
        *(io_ptr + 013) = (unsigned char)memval;

        exit(0);
	}

int weekday(day, month, year)
int day, month, year;
{
        int index, yrndx, mondx;
        
        if(month <= 2)
        {
                month += 12;
                year--;
        }

        yrndx = year + (year/4) - (year/100) + (year/400);
        mondx = (2 * month) + (3 * (month + 1)) / 5;
        index = day + mondx + yrndx + CONST;

        return(index % 7);
}