
#include "dos.h"
#include "conio.h"

/**** save previous internal values			****/
unsigned char 	old_8259;	
unsigned char 	old_146818_a;
unsigned char 	old_146818_b;

/**** our interrupt	routine					****/
void interrupt	timer_check( void);

/**** old 0x70 interrupt					****/
void interrupt	(*old_int_70)( void);

/**** interrupt setup routine				****/
void setup_periodic_interrupt( void);

/**** interrupt stop routine				****/
void clear_periodic_interrupt( void);

/**** write a byte to 146818			    ****/
void write_146818( unsigned char port,
				   unsigned char data);

/**** read a byte from 146818 chip			****/
unsigned char	read_146818( unsigned char port);

/**** interrupt occurred flag				****/
int	time_out = 0;


void main( void)

	{/* test program to check out clock chip   */
	/*	periodic interrupt					   */


	/**** setup for periodic interrupt		****/
	setup_periodic_interrupt();

	/**** clear the screen					****/
	clrscr();						

	/**** until a keypress happens			****/
	while ( !kbhit())							
		{ 
		/**** timer interrupt ?				****/
		 if ( time_out) 
			{
			 time_out = 0;
			 putch('T');	
			}
		}			

	/**** stop periodic interrupt			****/
	clear_periodic_interrupt();			
}


void setup_periodic_interrupt( void)

	{/* do the housekeeping to start interrupt	*/

	/**** change interrupt vector 			****/
	old_int_70 = getvect( 0x70);
	setvect( 0x70, timer_check);

	/**** read timer register				****/
	old_146818_a = read_146818( 0xa);	

	/**** set to 2 hz rate					****/
	write_146818( 0xa, old_146818_a | 0xf);

	/**** enable periodic timer				****/
	old_146818_b = read_146818( 0xb);	
	write_146818( 0xb, old_146818_b | 0x40);

	/**** read interrupt mask				****/
	old_8259 = inportb( 0xa1);

	/**** enable INT 0						****/			
	outportb( 0xa1, old_8259 & 0xfe );

	/**** clear PF 	flag					****/
	read_146818( 0xc);

	}


void clear_periodic_interrupt( void)

	{/* do the housekeeping to stop interrupt	*/

		/***** disable periodic timer			****/
	write_146818( 0xa, old_146818_a);
	write_146818( 0xb, old_146818_b);

	/**** fix 8259 chip						****/			
	outportb( 0xa1, old_8259);

	/**** fix interrupt vector 				****/
	setvect( 0x70, old_int_70);

	}


void interrupt	timer_check( void)

	{/* timer interrupt handler				   */

	/**** read the timer C register			****/
	outportb( 0x70, 0xc);
	time_out = inportb( 0x071);	
	enable();

	/**** write EOI to 8259					****/
	outportb( 0xa0, 0x20);		
	outportb( 0x20, 0x20);

	 /***** mask periodic interrupt			****/
	time_out &= 0x40;	

	/***** call old interrupt, if needed	****/
	if ( !time_out)
			(*old_int_70)();
	} 


void	write_146818( unsigned char port,
					  unsigned char data)

	{/* write a byte to the real-time chip	   */

	/**** no interrupts during this			****/
	disable();

	/**** send the address to latch			****/
	outportb( 0x70, port);
	/**** write the data					****/
	outportb( 0x71, data);

	enable();
	}

unsigned char	read_146818( unsigned char port)

	{/* read a byte from the real-time chip		*/

	/**** temp for input storage			****/
	char data;	

	/**** no interrupts during this			****/
	disable();
	/**** send the address to latch			****/
	outportb( 0x70, port);
	/**** read the data						****/
	data = inportb( 0x71);
	enable();
	return data;
	}
