How MS-DOS Detects an Intel 80387 Coprocessor

MS-DOS 6.22 detects an Intel 80387 numeric coprocessor through a sequence of hardware probing techniques and standard x87 assembly routines executed during system initialization or utility queries (such as MSD.EXE). The detection routine first verifies whether any floating-point hardware exists by resetting the coprocessor state, evaluates register behavior to rule out older chips like the 8087 and 80287, and checks processor control flags to confirm 80387-level capabilities.

Step 1: Testing for Coprocessor Presence

The detection algorithm begins by determining if any Floating-Point Unit (FPU) is installed on the motherboard:

  1. Initialization: The CPU issues the FNINIT (Initialize Coprocessor without waiting) instruction. This command sets the FPU control word to 037Fh and clears the status word to 0000h.
  2. Reading the Status Word: The CPU pre-populates a memory variable with a non-zero value (typically 0FFFFh) and then executes FNSTSW (Store Status Word) to write the FPU status word into that memory address.
  3. Verification: If the value in the memory address remains unchanged, no coprocessor is installed. If the value changes to 0000h, an FPU is physically present and responsive on the bus.

Step 2: Distinguishing the 8087 from Newer Coprocessors

Once an FPU is confirmed, the routine determines whether it is an original 8087 or a newer generation (80287/80387):

  1. The CPU loads a custom control word using FLDCW to inspect the coprocessor's handling of the interrupt-enable mask (bit 7) and infinity control (bit 12).
  2. On an 8087, the interrupt mask can be modified via the control word.
  3. On the 80287 and 80387, interrupts are handled directly through system hardware rather than the FPU control word, meaning bit 7 is fixed. If the interrupt mask bit cannot be modified, the chip is an 80287 or higher.

Step 3: Distinguishing the 80287 from the 80387

Because an 80386 CPU can interface with either an 80287 or an 80387 coprocessor, software must explicitly test for 80387-specific mathematical behavior:

  1. Infinity Evaluation Test: The primary differentiator between the 80287 and the 80387 is how each chip handles infinity. The 8087 and 80287 support projective infinity by default, where positive infinity (\(+\infty\)) and negative infinity (\(-\infty\)) are treated as equal. The 80387 strictly adheres to the updated IEEE-754 standard and uses affine infinity, where \(+\infty\) and \(-\infty\) are distinct values.
  2. Execution: The routine loads \(+0.0\) and \(-0.0\) onto the FPU stack, generates \(+\infty\) and \(-\infty\) through division, and compares them using the FCOMP instruction.
  3. Evaluation: The CPU transfers the comparison result to the processor flags using FSTSW combined with SAHF. If the comparison shows that \(+\infty \neq -\infty\), the hardware is recognized as an 80387 (or an integrated 80486DX/Pentium FPU). If they evaluate as equal, an 80287 is present.

Step 4: System Register Coordination

At the system software level, MS-DOS coordinates with the CPU's Control Register 0 (CR0):

  • During system startup, BIOS and DOS set the Extension Type (ET) bit (bit 4 of CR0) to indicate the coprocessor protocol.
  • If an 80387 is identified, the ET bit is set to 1, instructing the 80386 CPU to use the faster 32-bit 80387 coprocessor protocol instead of the 16-bit 80287 protocol.
  • DOS also configures the Emulation (EM) bit to 0 and the Math Present (MP) bit to 1 in CR0, allowing software applications to directly execute native 387 floating-point instructions without triggering software-emulation interrupts.