Chapter 3
Programming Overview
3-5
The code fragment in Example 3.A is an example of how to enable
interrupts and set the interrupt vector for a given hardware interrupt and
ISR under DOS.
First, the hardware interrupt number is converted to a software interrupt
number by adding 8 and then adding 60h if the interrupt number is greater
than 7. This is done to match the PC’s mapping of hardware to software
interrupt numbers. The old interrupt vector is then saved for later use and
the new ISR address is set as the new vector. Finally, the appropriate bit in
the PIC is set to 0 to enable the interrupt.
Example 3.A
Installing and enabling interrupts
#define LowPICPort 0x20
/* Port address for Prog. Interrupt Controller for ints 0–7 */
#define HighPICPort 0xA0
/* Port address for Prog. Interrupt Controller for ints 8–15 */
void interrupt (*OldInterruptServiceRoutine)(); /* pointer to store old interrupt handler */
void InitInterrupt(unsigned char InterruptNumber, void interrupt (*InterruptServiceRoutine)())
{
unsigned char
PICMask,
/* storage for prog. interrupt controller mask */
PICPortBase,
/* Port address of either first PIC or second PIC */
SWInterruptNumber;
/* Software Interrupt number, converted from HW */
/* Insure that InterruptNumber is valid one for KTX – leave in for debug only */
assert((InterruptNumber > 2) && (InterruptNumber < 16));
/* Set the base port of the Programmable Interrupt Controller depending on
whether the interrupt is on the first or second PIC */
if (InterruptNumber < 8) PICPortBase = LowPICPort;
else PICPortBase = HighPICPort;
/* Convert from hardware interrupt numbers (0–7) to software interrupt numbers
0x8–0xf and hardware interrupt numbers (8–15) to software interrupt
numbers 0x70–0x78 */
SWInterruptNumber = Interrupt 0x8;
if (SWInterruptNumber > 0xf) SWInterrupt= 0x60;
/* Save the old interrupt handler vector, and install the new one */
/* Need to disable interrupts when changing vectors */
disable ();
OldInterruptServiceRoutine = getvect(SWInterruptNumber);
setvect(SWInterruptNumber, InterruptServiceRoutine);
/* Enable the interrupt by setting the appropriate bit in the PICMask to 0 */
PICMask = inportb(PICP1);
delay(50);
/* Delay for PIC to settle */
outportb(PICP1, PICMask & ~(1 << (InterruptNumber % 8)));
delay(50);
/* Delay for PIC to settle */
}
Installing and Enabling
the Interrupt