/*
  Program 	: Event-trigger IRQ test program.

  Description 	: This program toggle PORTC bit 0 which generate clock pulse
		to 8254. After a certain number of clock pulses are generated,
		the on-board controller will acknowledge PC by the IRQ signal.

  Hardware setting: The DIP switch SW1 should be set as following :
		1 : ON    2 : ON    3 : ON    4 : ON    5,6 : DON'T CARE
		CN1 and CN2 should be connected together.

  Note		: This program can be compiled both in Turbo C 2.0 or
		  or Turbo C++ 3.0 and running under DOS environment.
*/
#include	<stdio.h>
#include	<conio.h>
#include	<stdlib.h>
#include	<dos.h>

#pragma	inline

#ifdef __cplusplus
   #define __CPPARGS		...
#else
   #define __CPPARGS
#endif

#define	BASE			0x2C0

int irq_gen;

void interrupt ( *old_irq10)(__CPPARGS);

void set_8254(unsigned int value)
{
   outp(BASE+0x0F,0x30);
   outp(BASE+0x0C,value & 0xff);
   outp(BASE+0x0C,(value & 0xff00) >> 8);
}

void disable_8254()
{
  outp(BASE+0x0F,0x30);
  outp(BASE+0x0C,0x00);
  outp(BASE+0x0C,0x00);
}

void interrupt irq10_isr(__CPPARGS)
{
    disable();
    irq_gen = 1;
    inp(BASE+3);		// clear irq
//    outp(0xa0,0x20);	// re-enable 8259
    outp(0x20,0x20);
    enable();
}

void toggle_pc0(void)
{
  outp(BASE+6,0xfe);			// toggle bit 0 only
  outp(BASE+6,0xff);
}


void main(void)
{
  unsigned long i;

  outp(BASE+3,0x9B);		// port a,b,c as input
  outp(BASE+7,0x80);		// port d,e,f as output
  outp(BASE+6,0xff);		// set initial high !!
  inp(BASE+3);			// clear previous irq
  disable_8254();
  old_irq10 = getvect(0x0D);
  setvect(0x0D, irq10_isr);
  outp(0x21, inp(0x21) & 0xDF);		// enable 8259
//  outp(0xa1, inp(0xa1) & 0xfb);
  do {
    set_8254(0x3);
    irq_gen = 0;
    for(i=0;i<0x4;i++) toggle_pc0();
    if(irq_gen == 1)  printf("\n IRQ generate !!");
    else    printf("\n No IRQ generated !!");
  } while((getch()|32)!='q');
  setvect(0x0D, old_irq10);
  outp(0x21, inp(0x21) | 0x20);		// disable irq 10 interrupt
  getch();
}