
/*
 * 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 TIMEVAL *val;
    char inpbuf[IBUFSIZE];
    TIMEVAL tval;

    printf("> hhmmss d mmddyy (decimal)\n> ");

    for (i=0; i<IBUFSIZE; i++) {
	c = INCHR();
	c = tolower(c);
	inpbuf[i] = c;
	switch(c) {
	case RUBOUT:
	case '\b':
	    if(i-->0) {
		i--;
		printf("\b \b");
	    }
	    break;
	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 = inpbuf;
    if (isdigit(*string)) val->tenhour = ctod(*string++);
    if (isdigit(*string)) val->hour = ctod(*string++);
    if (isdigit(*string)) val->tenmin = ctod(*string++);
    if (isdigit(*string)) val->min = ctod(*string++);
    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->weekday = 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 (isdigit(*string)) val->tendayom = ctod(*string++);
    if (isdigit(*string)) val->dayom = ctod(*string++);
    if (isdigit(*string)) val->tenyear = ctod(*string++);
    if (isdigit(*string)) val->year = ctod(*string++);

    writertc(&tval);

    /* print out the just set date and time */
    printtod();
    printf("\n");

}

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

    readrtc(val = &tval);
    printf("%x%1x:%1x%1x:%1x%1x %1x %x%1x/%x%1x/%1x%1x",
	    val->tenhour, val->hour,
	    val->tenmin, val->min,
	    val->tensec, val->sec,
	    val->weekday,
	    val->tenmonth, val->month,
	    val->tendayom, val->dayom,
	    val->tenyear, val->year );
}

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

    rtc = (RTC *)TODCLK;

    for (abort = 0 ; tenth != (0xf & rtc->tenthsec.c); 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 = (0xf & rtc->tenthsec.c) ;

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

	if (abort > 64) {		/* try 64 times, then give up */
		printf("aborting rtc-read, ");
		break;
	}
    }
}

/*
 * write the current TOD to the real time clock
 */
writertc(val)
    register TIMEVAL *val;
{
    register RTC *rtc;
    int leap, year;

    rtc = (RTC *)TODCLK;

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

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

    /* set 24 hour mode and leapyear (assmumes year is after 1960) */
    year = ( (val->tenyear * 10) + val->year );
    leap = ( (year - 60) % 4 );
    rtc->interrupt.c = (char) ( ((leap << 2) | RTC_24HOUR ) & 0x0f);

#ifdef notdef
    printf("input value before writing to TOD:\n");
    printf("%x%1x:%1x%1x:%1x%1x   %x%1x/%x%1x/%1x%1x\n",
	    val->tenhour, val->hour,
	    val->tenmin, val->min,
	    val->tensec, val->sec,
	    val->tenmonth, val->month,
	    val->tendayom, val->dayom,
	    val->tenyear, val->year );
#endif

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

}

looptime()
{
    for(;;) {
	printtod(); printf("\r");
	if ( quitchk() )  { printf("\n"); break; }
    }
}

