/*
  Program       : Timer-trigger IRQ test program.

  Description   : This program generate the pacer signal by control 8254. And
		 8254 will acknowledge PC by generating IRQ.

  Hardware setting: The Jumper setting should be set as following :

		    JP1: X1
		    JP2: IRQ 5
		    JP3: TMEIRQ
		    SW1: off on off on off on   (0x2C0)
			  1   2  3   4  5   6

  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        <dos.h>

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

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

#define BASE                    0x2A0
#define TIMER0                  0x08
#define TIMER1                  0x09
#define TIMER2                  0x0A

int irq_gen;

void interrupt ( *old_irq5)(__CPPARGS);

void set_8254(unsigned int port,unsigned int value)
{
   unsigned int control;

   control = 0x36 | ( (port==TIMER2) ?  0x80 : 0x40 );
   outp(BASE+0x0B,control);
   outp(BASE+port,value & 0xff);
   outp(BASE+port,(value & 0xff00) >> 8 );
}

void disable_8254(unsigned int port)
{
  unsigned int control;

  control = 0x30 | ( (port==TIMER2) ?  0x80 : 0x40 );
  outp(BASE+0x0B,control);
  outp(BASE+port,0x00);
  outp(BASE+port,0x00);
}

void interrupt irq5_isr(__CPPARGS)
{
    disable();
    irq_gen = 1;
    disable_8254(TIMER1);
    disable_8254(TIMER2);
			   /*  outp(0xa0,0x20);  re-enable 8259    */
    outp(0x20,0x20);
    enable();
}

void main(void)
{

  disable_8254(TIMER1);
  disable_8254(TIMER2);
  old_irq5 = getvect(0x0d);
  setvect(0x0d, irq5_isr);
  outp(0x21, inp(0x21) & 0xdf);           /*  enable 8259  */
  /* outp(0xa1, inp(0xa1) & 0xfb);*/

  do {
    irq_gen = 0;
    set_8254(TIMER1,0x3);
    set_8254(TIMER2,0xff);
    while(irq_gen==0);                 /* wait till irq happen */
    printf("\n Timer trigger IRQ5 generate ... ");
  } while((getch()|32)!='q');
  setvect(0x0d, old_irq5);
  outp(0x21, inp(0x21) | 0x20);       /* disable irq 5 interrupt */
  getch();
}
