#include <stdio.h>
#include <dos.h>

/* global variables */
struct time timer;
void interrupt (far *int1c)(void);

/* function declarations */
void interrupt timertick(void);
void update_time(int interval);

main()
{
	unsigned program_size;
	printf("This is a memory resident program that displays\n");
	printf("the current time in the upper right corner of the\n");
	printf("screen. It intercepts the timer tick interrupt\n");
	printf("number 0x1c and displays the time every 5 seconds\n");
	/* store current time in timer variable */
	gettime(&timer);
	/* get vector for timer tick interrupt 0x1c */
	int1c = getvect(0x1c);
	/* set vector for interrupt 0x1c to timertick function */
	setvect(0x1c, timertick);
	/* set size of far heap to 0 and get total program size */
	program_size = farsetsize(0);
	/* terminate program and keep it memory resident */
	keep(0, program_size);
}
void interrupt timertick(void)
{     /* gets control approximately 18.2 times per second */
	static int synchronized, counter = 1;
	static char far *crtptr;  /* pointer to screen memory */
	char far *ptr;		/* pointer to screen memory */
	disable();		/* disable interrupts */
	counter--;		/* count clock ticks */
	if (counter == 0) {	/* update time when counter is 0 */
		if (synchronized) {	/* check synchronization flag */
		counter = 91;		/* set counter to 5 second interval */
		update_time(5);	/* incerment time by 5 seconds */
	}
	else {
	if ((timer.ti_sec %5 ) == 0) { /* check for multible of 5 */
		counter = 91;		/* set counter to 5 seconds interval */
		synchronized++;		/* set synchronization flag */
	}
	else {				/* seconds not multiple of 5 */
		counter = 18;		/* set counter to 1 second interval */
		update_time(1);		/* increment time by 1 second */
	}
   }
if (crtptr == 0) {  	/* initialize pointer to screen memory */
	if ((biosequip() & 0x30) == 0x30) 	/* card type? */
		crtptr = MK_FP(0xB000, 144);	/* monochrome card */
	else crtptr = MK_FP(0xB800, 144);	/* color card */
}
ptr = crtptr;	/* ptr points to screen memory */
/*		display time		   reverse video */
*ptr++ = (timer.ti_hour / 10) + '0';	*ptr++ = '\x0B';
*ptr++ = (timer.ti_hour % 10) + '0';	*ptr++ = '\x0B';
*ptr++ = ':' 			   ;	*ptr++ = '\x0A';
*ptr++ = (timer.ti_min  / 10) + '0';	*ptr++ = '\x0B';
*ptr++ = (timer.ti_min  % 10) + '0';	*ptr++ = '\x0B';
*ptr++ = ':'			   ;	*ptr++ = '\x0A';
*ptr++ = (timer.ti_sec	/ 10) + '0';	*ptr++ = '\x0B';
*ptr++ = (timer.ti_sec  % 10) + '0';	*ptr++ = '\x0B';
}
enable(); /* enable interruptes */
int1c();  /* call original vector to give control to other memory
	     resident programs (if any) that trap intrrupt 0x09 */

}

void update_time(int interval)
{   /* adds interval seconds to the time */
	if (timer.ti_sec == (60 - interval)) {
		timer.ti_sec = 0;
		if (timer.ti_min == 59) {
		timer.ti_min = 0;
		if (timer.ti_hour == 23)
		timer.ti_hour = 0;
	else timer.ti_hour++;
	}
	else timer.ti_min++;
   }
   else timer.ti_sec += interval;
}

