Page 27 of 31
such operations. The general rule is do not call any functions that use the screen, read keyboard
input or any file I/O routines, these should not be used in ISR's.
The same problem of reentrancy also exists for many floating-point emulators. This effectively
means that you should also avoid floating point mathematical operations in your ISR.
Note that the problem of reentrancy exists, no matter what programming language you use. Even,
if you are writing your ISR in Assembly language, DOS and many floating point emulators are not
re-entrant. Of course there are ways to avoid this problem, such as those which activate when
your ISR is called. Such solutions are, however, beyond the scope of this manual.
The second major concern when writing ISR's is to make them as short as possible in term of
execution time. Spending long times in interrupt service routines may mean that other important
interrupts are not serviced. Also, if you spend too long in your ISR, it may be called again before
you have exited. This will lead to your computer hanging up and will require a reboot.
Your ISR should have the following structure:
Push any processor registers used in your ISR.
Put the body of your routine here
Clear the interrupt bit by reading GPRS6055 RXD register
Issue the EOI command to the 8259 by writing 20h to 20h
Pop all registers. Most C compilers do this automatically
The following C example shows what the shell of your ISR should be like:
/*-------------------------------------------------------------------------------
| Function: new_IRQ_handler
| Inputs: Nothing
| Returns: Nothing
|-------------------------------------------------------------------------------*/
void interrupt far new_IRQ_handler(void)
{
IRQ_flag = 1; // Indicate to process interrupt has occurred
{
// Your program code to read UART
// read to a data buffer for example:
Guc_buffer[Gi_bufpos++] = inp(gi_SERIAL_DATA);
}
outp(0x20, 0x20); // Acknowledge the interrupt controller
}
Saving the Startup Interrupt Mask Register (IMR) and interrupt vector
The next step after writing the ISR is to save the startup-state of the interrupt mask register, (IMR)
and the original interrupt vector you are using. The IMR is located in address 21h. The interrupt
vector you will be using is located in the interrupt vector table which is an array of pointers
(addresses) and it is locate din the first 1024 bytes of the memory (Segment 0 offset 0). You can
read this value directly, but it is better practice to use DOS function 35h (get interrupt vector) to
do this. Most C compilers have a special function available for doing this. The vectors for the
hardware interrupts on the XT - bus are vectors 8-15, where IRQ0 uses vector 8 and IRQ7 uses
vector 15. Thus if your GPRS6055 is using IRQ5 it corresponds to vector number 13.
Before you install your ISR, temporarily mask out the IRQ you will be using. This prevents the
IRQ from requesting an interrupt while you are installing and initializing your ISR. To mask the
IRQ, read the current IMR at I/O port 21h, and set the bit that corresponds to the IRQ. The IMR is
Comments to this Manuals