/*-----------------------------------------------------------------------*/
/* filename=demo_07.c							 */
/*									 */
/* watch dog timer							 */
/* IO BASE address = 0x200, all DIP switchs of SW1 in OFF position	 */
/* CH9 select CLOCK2=80K --> 80K/65535 = 1.2 Hz 			 */
/*			 --> Watchdog time interval = 0.82 sec (about)	 */
/* IRQ level  select IRQ5						 */
/* IRQ source select CH9=COUT9						 */
/* COUT9 can trigger another hardware to perform hardware-protection	 */
/*-----------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>

#define  BASE 0x200		/* IO BASE address = 0x200 */

static void   interrupt irq5_service();
int watchdog;

void main(void)
{
int i;

watchdog=0;
init_watchdog();

disable();
setvect (5+8,irq5_service);
outportb (0x21,inportb(0x21) & 0xdf);	/* 8259a irq5 enable */
enable();

for (;;)
	{
	reflesh_watchdog();	/* reflesh cycle must small than 0.82 sec */

	/* normal program run here */

	printf("\npress any key to simulate watchdog failure,watchdog=%d",watchdog);
	if (kbhit()!=0) {getch(); goto wait_watchdog;}
	}
wait_watchdog:
/* simulate program fail --> no reflesh_watchdog --> IRQ will interrupt CPU */
for(;;)
	{
	printf(" Wait");
	if (watchdog==1)
		{
		disable();
		outportb (0x21,inportb(0x21) | 0x20); /* 8259a irq5 disable */
		enable();
		printf("\nWatchdog failure");
		return;
		}
	if (kbhit()!=0) {getch(); return;}
	}
}

/* ----------------------------------------------------------------------*/
init_watchdog()
{
outportb(BASE+4,2);	/* select 8254 chip_3 --> counter_7,8,9 */
outportb(BASE+3,0xb0);	/* mode_0, counter_9 */
outportb(BASE+2,0xff);	/* counter_9 low byte first */
outportb(BASE+2,0xff);	/* counter_9 high byte ,0xffff=65535 */
}
/* ----------------------------------------------------------------------*/
reflesh_watchdog()
{
outportb(BASE+3,0xb0);	/* mode_0, counter_9 */
outportb(BASE+2,0xff);	/* counter_9 low byte first */
outportb(BASE+2,0xff);	/* counter_9 high byte ,0xffff=65535 */
}
/* ----------------------------------------------------------------------*/
void  interrupt irq5_service()
{
int i;
char c;

/* This program can process proper software protection */

watchdog=1;
outportb(0x20,0x20);
}

