Handling an External Interrupt
/* Program INTR_1.C
**
** Routine first flashes an LED on P2.6 10 times.
**
** Then flashes LED each time a pushbutton on P1.1 (PINT0) is depressed.
**
** Illustrates the use of handling an external interrupt.
**
** Bit 1 of PMC1 is configured for external interrupt PINT0 by setting
** the bit to a one.
**
** The interrupt vector 24 is set to the address of the interrupt service
** routine.
**
** The external interrupt is configured for interrupt on a falling edge
** by setting bit ES0 of the External Interrupt Mode Register (INTM) to
** to a zero. Thus, pokeb(SEG, INTM, 0x00).
**
** The PINT0 interrupt is configured for vectored service without bank
** switching by setting bits MS/INT and ENCS of the EXIC0 register to
** zero. The interrupt is enabled or disabled by setting the
** IMK bit of EXIC0 to either a 0 or 1, respectively.
**
** Thus, to enable the interrupt; pokeb(SEG, EXICO, 0x07). To disable;
** pokeb(SEG, EXICO, 0x47).
**
** As this was my first experience with interrupts using the Flashlite
** V25, I was cautious. The interrupt service routine, simply sets a
** variable to true. When main recognizes this, it disables further
** interrupts, sets the variable to false and performs the task of
** flashing the LED and then again enables the interrupt.
**
** One troublesome item was that prior to exiting the isr, the assembly
** instruction FINT (must be executed). This requires use of the TASM
** assembler. To avoid the tedium of performing this chore each time
** the program is compiled, the fint() routine was compiled to a separate
** .obj file. Thus, the project consists of this file and fint.obj.
**
** The implementation of "fint()" is illustrated at the bottom of this
** page.
**
** copyright, Peter H. Anderson, Baltimore, MD, Oct, '00
*/
#include <stdio.h>
#include <dos.h>
#define SEG 0xf000
#define P1_OFFSET 0xff08
#define PM1_OFFSET 0xff09
#define PMC1_OFFSET 0xff0a
#define P2_OFFSET 0xff10
#define PM2_OFFSET 0xff11
#define PMC2_OFFSET 0xff12
#define INTM 0xff40
#define EXICO 0xff4c
#define FALSE 0
#define TRUE !0
typedef unsigned char byte;
void interrupt far isr_intp0(void);
void flash(int num);
extern void fint(void);
int intp0_flag;
byte far *p2, far *pm2, far *pmc2;
void main(void)
{
int ad_val;
p2 = (byte far *) MK_FP(SEG, P2_OFFSET);
pm2 = (byte far *) MK_FP(SEG, PM2_OFFSET);
pmc2 = (byte far *)MK_FP(SEG, PMC2_OFFSET);
*pmc2 = 0x00; /* not special purpose */
*pm2 = 0x0f; /* bit 6 is an output */
*p2 = 0x00; /* turn LED off */
flash(10);
pokeb(SEG, PMC1_OFFSET, 0x02); /* intp0 on bit 1*/
pokeb(SEG, PM1_OFFSET, 0xff);
pokeb(SEG, INTM, 0x00); /* falling edge */
setvect(24, isr_intp0); /* set new vector */
intp0_flag = FALSE;
while(1)
{
printf(".");
pokeb(SEG, EXICO, 0x07); /* enable interrupts */
if (intp0_flag) /* an interrupt occurred */
{
pokeb(SEG, EXICO, 0x47); /* disable */
flash(10);
intp0_flag = FALSE;
}
}
}
void interrupt far isr_intp0(void)
{
intp0_flag = TRUE;
fint();
}
void flash(int num)
{
int n;
for (n=0; n<num; n++)
{
*p2 = 0x40;
delay(250);
*p2 = 0x00;
delay(250);
}
}
/* Program fint.c
**
** Implements the FINT instruction.
**
** copyright, Peter H. Anderson, Baltimore, MD, Oct, '00
*/
#include <stdio.h>
void fint(void);
void fint(void)
{
asm db 0x0f
asm db 0x92
}