/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:time.c 12.0$ */
/* $ACIS:time.c 12.0$ */
/* $Source: /ibm/acis/usr/sys/standca/RCS/time.c,v $ */

#ifndef lint
static char *rcsid = "$Header:time.c 12.0$";
#endif

#include "../machine/clock.h"

#ifdef ATR
#include "sa.h"
#include "../ca_atr/pcif.h"
#endif ATR

#ifdef IBMRTPC
#define XCLOCK_SEC	0xf0008800
#define XCLOCK_SAL	0xf0008801
#define XCLOCK_MIN	0xf0008802
#define XCLOCK_MAL	0xf0008803
#define XCLOCK_HRS	0xf0008804
#define XCLOCK_HAL	0xf0008805
#define XCLOCK_DOW	0xf0008806
#define XCLOCK_DOM	0xf0008807
#define XCLOCK_MON	0xf0008808
#define XCLOCK_YR	0xf0008809
#define XCLOCK_A	0xf000880A
#define XCLOCK_B	0xf000880B
#define XCLOCK_C	0xf000880C
#define XCLOCK_D	0xf000880D
#endif IBMRTPC

struct XCLOCK {
	unsigned char sec;
	unsigned char sal;
	unsigned char min;
	unsigned char mal;
	unsigned char hrs;
	unsigned char hal;
	unsigned char dow;
	unsigned char dom;
	unsigned char mon;
	unsigned char year;
	unsigned char a;
	unsigned char b;
	unsigned char c;
	unsigned char d;
#ifdef IBMRTPC
} *xclock = (struct XCLOCK *)XCLOCK_SEC;
#endif IBMRTPC
#ifdef ATR
} *xclock;
#endif ATR 

/* Reset the clock XLOCK_A */
#define XCLOCK_RS	0x26
 /* Start the external clock for timer XCLOCK_B */
#define XCLOCK_SET	0x80		  /* 0 - Update normal, 1 - Halt and init */
#define XCLOCK_PIE	0x40		  /* 0/1 disable/enable periodic interrupt */
#define XCLOCK_AIE	0x20		  /* 0/1 disable/enable alarm interrupt */
#define XCLOCK_UIE	0x10		  /* 0/1 disable/enable update-ended interrupt */
#define XCLOCK_SQWE	0x08		  /* 0/1 disable/enable sqware-wave signal */
#define XCLOCK_DM	0x04		  /* data mode, 0 - BCD, 1 - Binary */
#define XCLOCK_24HR	0x02		  /* 0 - 12 hour mode, 1 - 24 hour mode */
#define XCLOCK_DSE	0x01		  /* 0/1 diable/enable daylight savings */



/*
 * Initialze the time of day structure.
 */
long time(timeptr)
long *timeptr;
{
	register unsigned i;
	int secpast69 = 0;

#ifdef ATR
	register int oldwindow = get_512_window();

       	xclock = (struct XCLOCK *) (set_512_window(get_pc_cb(CLENT)) + pcif_512_fw);

	bzero((char *) xclock, sizeof (struct XCLOCK));	/* zero it first */

	pc_req(CB_TODREAD,(char *)0,CLENT);

	/*
	 * Wait for the PS/2 code to fill in the data.
	 */
	if(pc_poll((char *)xclock,0xff00) < 0)
	   printf("inittodr: WARNING: PS/2 failed to update the TOD structure!\n");
	
#endif ATR

	{
#ifdef CLOCKDEBUG
		printf("yr (%d) mon (%d) dom (%d) hrs (%d) min (%d) sec (%d)\n",
		    xclock->year, xclock->mon, xclock->dom, xclock->hrs,
		    xclock->min, xclock->sec);
#endif CLOCKDEBUG

		for (i = 70; i < xclock->year; i++)
			secpast69 += SECYR + (LEAPYEAR(i) ? SECDAY : 0);

		for (i = 1; i < xclock->mon; i++) {
			adjustmonth(i, &secpast69, xclock->year, 1);
		}
		secpast69 += SECDAY * (xclock->dom - 1);
		secpast69 += SECHR * xclock->hrs;
		secpast69 += SECMIN * xclock->min;
		secpast69 += xclock->sec;
	}
	if (timeptr)
		*timeptr = secpast69;
#ifdef ATR
	set_512_window(oldwindow);
#endif ATR
	return(secpast69);
}

/*
 * add/subtract number of seconds in month 'i' to/from *s69.
 */
adjustmonth(i, s69, year, add)
	register int i;
	register int *s69;
	register int year;
	register int add;
{
	register int secs;

	switch (i) {
	case 1:				  /* Jan */
	case 3:				  /* Mar */
	case 5:				  /* May */
	case 7:				  /* Jul */
	case 8:				  /* Aug */
	case 10:			  /* Oct */
	case 12:			  /* Dec */
		secs = 31 * SECDAY;
		break;
	case 4:				  /* Apr */
	case 6:				  /* Jun */
	case 9:				  /* Sep */
	case 11:			  /* Nov */
		secs = 30 * SECDAY;
		break;
	case 2:				  /* Feb */
		secs = 28 * SECDAY + (LEAPYEAR(year) ? SECDAY : 0);
		break;
	}
	if (add)
		*s69 += secs;
	else
		*s69 -= secs;
}
