Information Technology Reference
In-Depth Information
outportb(IMR, ch); /* enable interrupts for IRQ4 */
enable();
}
At the end of the program the function
disable_interrupts()
sets the IER register to all 0s.
This disables interrupts on the
COM1:
port. Bit 4 of the IMR is also set to a 1 which disables
IRQ4
interrupts.
void disable_interrupts(void)
{
int ch;
disable();
ch = inportb(IMR) | ~IRQ4; /* disable IRQ4 interrupt */
outportb(IMR, ch);
outportb(IER, 0);
enable();
}
The ISR for the
IRQ4
function is set to
rs_interrupt()
. When it is called, the Interrupt
Status Register (this is named IIR to avoid confusion with the interrupt service routine) is
tested to determine if a character has been received. Its address is offset by 2 from the base
address of the port (that is, 0x3FA for
COM1:
). The first 3 bits give the status of the interrupt.
A
000b
indicates that there are no interrupts pending, a
100b
that data has been received, or a
111b
that an error or break has occurred. The statement
if ((inportb(IIR) & 0x7) ==
0x4)
tests if data has been received. If this statement is true then data has been received and
the character is then read from the receiver buffer array with the statement
buffer[endbuf]
= inportb(RXR);
. The end of the buffer variable (
endbuf
) is then incremented by 1.
At the end of this ISR the end of interrupt flag is set in the interrupt control register with
the statement
outportb(ICR, 0x20);
. The
startbuf
and
endbuf
variables are global, thus
all parts of the program have access to them.
Turbo/Borland functions
enable()
and
disable()
in
rs_interrupt()
are used to enable
and disable interrupts, respectively.
void interrupt rs_interrupt(void)
{
disable();
if ((inportb(IIR) & RX_MASK) == RX_ID)
{
buffer[endbuf] = inportb(RXR);
endbuf++;
if (endbuf == RSBUFSIZE) endbuf=0;
}
/* Set end of interrupt flag */
outportb(ICR, EOI);
enable();
}
The
get_buffer()
function is given next. It is called from the main program and it tests the
variables
startbuf
and
endbuf
. If they are equal then it returns -1 to the
main()
. This indi-
cates that there are no characters in the buffer. If there are characters in the buffer then the
function returns, the character pointed to by the
startbuf
variable. This variable is then in-
cremented. The difference between
startbuf
and
endbuf
gives the number of characters in
the buffer. Note that when
startbuf
or
endbuf
reach the end of the buffer (
RSBUFSIZE
) they
are set back to the first character, that is, element 0.