
/*
 * rtc.c -- Routines to access the real time clock.
 * copyright (c) 1984  American Information Systems Corporation
 * Dock Williams
 * July, 1984
 *
 */

#include "3200config.h"
#include "monitor.h"
#include "ascii.h"
#include "vctype.h"
#include "rtc.h"

#define IBUFSIZE 32

/*
 * set the real time clock 
 */
setrtc()
{
    register int i;
    register char c;
    register char *string;
    register struct time_val *val;
    struct time_val tval;
    char ibuf[IBUFSIZE];

    printf("format--> hh:mm:ss mm/dd/yy d (in decimal)\nnew date> ");

    for (i=0; i<IBUFSIZE; i++) {
	c = INCHR();
	c = tolower(c);
	ibuf[i] = c;
	switch(c) {
	case RUBOUT:
	case '\b':
	    if(i-->0) {
		i--;
		printf("\b \b");
	    }
	case ESC:
	    printf("\n");
	    return('\0');
	case CR:
	case LF:
	    printf("\n");
	    goto gotinput;
	default:
	    printf("%c",c);
	    break;
	}
    }

gotinput:	/* check format */

    val = &tval;
    string = ibuf;
    if (isdigit(*string)) val->tenhour = ctod(*string++);
    if (isdigit(*string)) val->hour = ctod(*string++);
    if (*string == ':') string++;
    else {
	printf("bad format\n");
	return;
    }
    if (isdigit(*string)) val->tenmin = ctod(*string++);
    if (isdigit(*string)) val->min = ctod(*string++);
    if (*string == ':') string++;
    else {
	printf("bad format\n");
	return;
    }
    if (isdigit(*string)) val->tensec = ctod(*string++);
    if (isdigit(*string)) val->sec = ctod(*string++);
    if (*string == ' ') string++;
    else {
	printf("bad format\n");
	return;
    }
    while (isspace(*string)) string++;

    if (isdigit(*string)) val->tenmonth = ctod(*string++);
    if (isdigit(*string)) val->month = ctod(*string++);
    if (*string == '/') string++;
    else {
	printf("bad format\n");
	return;
    }
    if (isdigit(*string)) val->tendayom = ctod(*string++);
    if (isdigit(*string)) val->dayom = ctod(*string++);
    if (*string == '/') string++;
    else {
	printf("bad format\n");
	return;
    }
    if (isdigit(*string)) val->tenyear = ctod(*string++);
    if (isdigit(*string)) val->year = ctod(*string++);
    while (isspace(*string)) string++;
    if (isdigit(*string)) val->weekday = ctod(*string++);

    writertc(&tval);

    /* print out the just set date and time */
    printtod();

}

/*
 * print the current TOD as kept by the real time clock
 */
printtod()
{
    register struct time_val *val;
    struct time_val tval;
    int tenth;

    tenth = readrtc(val = &tval);

    printf("%x%1x:%1x%1x:%1x%1x.%1x   %x%1x/%x%1x/%1x%1x\n",
	    val->tenhour, val->hour,
	    val->tenmin, val->min,
	    val->tensec, val->tensec, tenth,
	    val->tenmonth, val->month,
	    val->tendayom, val->dayom,
	    val->tenyear, val->year );

}

/*
 * read the current TOD from the real time clock
 */
readrtc(val)
    register struct time_val *val;
{
    register struct real_time_clock *rtc;
    register int	abort;
    char	tenth;

    rtc = (struct real_time_clock *)TODCLK;

    for (abort = 0 ; tenth != rtc->tenthsec; abort++) {

	/* if at bottom of loop tenths of seconds doesn't */
	/* read the same we have to reread the time because */
	/* it changed while we were reading */
	tenth = rtc->tenthsec;

	/* read time */
	val->sec = rtc->sec;		/* unit seconds */
	val->tensec = rtc->tensec;	/* tens of seconds */
	val->min = rtc->min;		/* unit minutes */
	val->tenmin = rtc->tenmin;	/* tens of minutes */
	val->hour = rtc->hour;		/* unit hours */
	val->tenhour = rtc->tenhour;	/* tens of hours */
	val->dayom = rtc->dayom;	/* unit day on month */
	val->tendayom = rtc->tendayom;	/* tens of day of month */
	val->month = rtc->month;	/* unit of month */
	val->tenmonth = rtc->tenmonth;	/* tens of month */
	val->year = rtc->year;		/* unit of year */
	val->tenyear = rtc->tenyear;	/* tens of year */
	val->weekday = rtc->weekday;	/* day of week */

	if (abort == 5) printf("aborting rtc-read\n");
    }

    printf("%x%1x:%1x%1x:%1x%1x.%1x   %x%1x/%x%1x/%1x%1x\n",
		val->tenhour, val->hour,
		val->tenmin, val->min,
		val->tensec, val->sec, tenth,
		val->tenmonth, val->month,
		val->tendayom, val->dayom,
		val->tenyear, val->year );

}

/*
 * write the current TOD to the real time clock
 */
writertc(val)
    register struct time_val *val;
{
    register struct real_time_clock *rtc;

    rtc = (struct real_time_clock *)TODCLK;

    rtc->control = RTC_INIT;		/* disable interrupts */
					/* stop clock and interrupt timers */

    rtc->interrupt = RTC_NOINTS;	/* no interrupts programmed */
    rtc->control = RTC_CLKSET;		/* select normal, clock setting */

    /* initialize time: */
    rtc->sec = val->sec;		/* unit seconds */
    rtc->tensec = val->tensec;		/* tens of seconds */
    rtc->min = val->min;		/* unit minutes */
    rtc->tenmin = val->tenmin;		/* tens of minutes */
    rtc->hour = val->hour;		/* unit hours */
    rtc->tenhour = val->tenhour;	/* tens of hours */
    rtc->dayom = val->dayom;		/* unit day on month */
    rtc->tendayom = val->tendayom;	/* tens of day of month */
    rtc->month = val->month;		/* unit of month */
    rtc->tenmonth = val->tenmonth;	/* tens of month */
    rtc->year = val->year;		/* unit of year */
    rtc->tenyear = val->tenyear;	/* tens of year */
    rtc->weekday = val->weekday;	/* day of week */
				    
    /* start the RTC running */
    rtc->control = RTC_START;		/* time begins here */

}

