/*
  Program 	: Pacer-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 DIP switch SW1 should be set as following :
		1 : OFF    2 : ON   3 : ON   4 : DON'T CARE
		 5  ,  6  : pacer clock input select.
		 ON   ON  :  RTC (real time clock 32.768K Hz )
		 ON   OFF :  2.0 M Hz
		 OFF  ON  :  1.0 M Hz
		 OFF  OFF :  4.0 M Hz

  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			0x2C0
#define TIMER0			0x0C
#define TIMER1			0x0D
#define TIMER2			0x0E

int irq_gen;

void interrupt ( *old_irq10)(__CPPARGS);

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

   control = 0x36 | ( (port==TIMER2) ?  0x80 : 0x40 );
   outp(BASE+0x0F,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+0xF,control);
  outp(BASE+port,0x00);
  outp(BASE+port,0x00);
}

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

void main(void)
{

  disable_8254(TIMER1);
  disable_8254(TIMER2);
  inp(BASE+3);			// clear previous irq
  old_irq10 = getvect(0x0d);
  setvect(0x0d, irq10_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 IRQ generate ... ");
  } while((getch()|32)!='q');
  setvect(0x0d, old_irq10);
  outp(0x21, inp(0x21) | 0x20);		// disable irq 10 interrupt
  getch();
}