E-2
GUIDELINES FOR WRITING FPU EXCEPTIONS HANDLERS
E.1.ORIGIN OF THE MS-DOS* COMPATIBILITY MODE FOR
HANDLING FPU EXCEPTIONS
The first generations of IA processors (starting with the Intel 8086 and 8088 processors and go-
ing through the Intel 286 and Intel386 processors) did not have an on-chip floating-point unit.
Instead, floating-point capability was provided on a separate numeric coprocessor chip. The first
of these numeric coprocessors was the Intel 8087, which was followed by the Intel 287 and Intel
387 numeric coprocessors.
To allow the 8087 to signal floating-point exceptions to its companion 8086 or 8088, the 8087
has an output pin, INT, which it asserts when an unmasked floating-point exception occurs. The
designers of the 8087 recommended that the output from this pin be routed through a program-
mable interrupt controller (PIC) such as the Intel 8259A to the INTR pin of the 8086 or 8088.
The accompanying interrupt vector number could then be used to access the floating-point ex-
ception handler.
However, the original IBM PC design and MS-DOS operating system used a different mecha-
nism for handling the INT output from the 8087. It connected the INT pin directly to the NMI
input pin of the 8086 or 8088. The NMI interrupt handler then had to determine if the interrupt
was caused by a floating-point exception or another NMI event. This mechanism is the origin
of what is now called the MS-DOS compatibility mode. The decision to use this latter float-
ing-point exception handling mechanism came about because when the IBM PC was first de-
signed, the 8087 was not available. When the 8087 did become available, other functions had
already been assigned to the eight inputs to the PIC. One of these functions was a BIOS video
interrupt, which was assigned to interrupt number 16 for the 8086 and 8088.
The Intel 286 processor created the native mode for handling floating-point exceptions by pro-
viding a dedicated input pin (ERROR#) for receiving floating-point exception signals and a ded-
icated interrupt number, 16. Interrupt 16 was used to signal floating-point errors (also called
math faults). It was intended that the ERROR# pin on the Intel 286 be connected to a corre-
sponding ERROR# pin on the Intel 287 numeric coprocessor. When the Intel 287 signals a float-
ing-point exception using this mechanism, the Intel 286 generates an interrupt 16, to invoke the
floating-point exception handler.
To maintain compatibility existing PC software, the native floating-point exception handling
mode of the Intel 286 and 287 was not used in the IBM PC AT* system design. Instead, the ER-
ROR# pin on the Intel 286 was tied permanently high, and the ERROR# pin from the Intel 287
was routed to a second (cascaded) PIC. The resulting output of this PIC was routed through an
exception handler and eventually caused an interrupt 2 (NMI interrupt). Here the NMI interrupt
was shared with PC ATs new parity checking feature. Interrupt 16 remained assigned to the
BIOS video interrupt handler. The external hardware for the MS-DOS compatibility mode must
prevent the Intel 286 processor from executing past the next FPU instruction when an unmasked
exception has been generated. To do this, it asserts the BUSY# signal into the Intel 286 when
the ERROR# signal is asserted by the Intel 287.
The Intel386 processor and its companion Intel 387 numeric coprocessor provided the same
hardware mechanism for signaling and handling floating-point exceptions as the Intel 286 and
287 processors. And again, to maintain compatibility with existing MS-DOS software, basically