Skip to content
FreeDOSDeep Dive Published Updated 4 min readViews unavailable

FreeDOS DPMI Host Detection: The INT 2Fh AX=1687h Contract

Use the DPMI real-mode probe to distinguish a host from a mode check, read its capability fields, and avoid entering protected mode prematurely.

A DOS utility can run on a 386-class PC and still have no DPMI host. The processor’s ability to enter protected mode is not evidence that a host has installed the DPMI services a client needs. The DPMI 1.0 committee specification defines a narrow real-mode discovery call for that question: software interrupt 2Fh, with AX=1687h.

This is a preflight check, not the transition itself. The host-presence result, the returned capability fields, and the far entry point belong to one startup protocol. A diagnostic that only wants to report availability should stop after checking the result and must not jump through the returned pointer.

What the host returns

Call INT 2Fh with AX=1687h while still in real mode. A successful response sets AX to zero. If no host is present, AX is nonzero. The remaining registers describe the available interface: bit 0 of BX reports whether 32-bit programs are supported; CL identifies the processor family; DH and DL carry the DPMI major and minor version as decimal numbers represented in binary; SI is the number of paragraphs reserved for host-private data; and ES:DI is the real-to-protected-mode entry point.

The version fields are easy to misread. A DPMI 0.9 host reports major version 0 and minor value 90 decimal, which is hexadecimal 5Ah; this is not a pair of ASCII digits or a packed-BCD version. A successful presence test also does not mean a 32-bit client is supported. Check BX separately when the executable requires that capability.

The first transition entry point returned by 1687h is for a DPMI client’s initial switch to protected mode. The client must follow the specification’s complete initialization protocol, including the host-private data requirement and the defined call convention. It is not a generic far routine to invoke with arbitrary register contents. Subsequent DPMI services use the protected-mode INT 31h interface after the client has entered the host-managed environment.

A read-only probe

The following 16-bit real-mode fragment answers only whether a host responded. It deliberately does not allocate SI paragraphs or call ES:DI:

; Real-mode startup diagnostic only
mov ax,1687h
int 2fh
or ax,ax
jnz no_host

; AX = 0: a DPMI host answered.
; BX bit 0 reports 32-bit-client support.
; SI and ES:DI are transition-protocol data, not probe targets.
jmp short probe_done

no_host:
; AX is nonzero: no DPMI host answered.

probe_done:

The interrupt changes machine state only through the host’s defined query handler and returns to the caller; this example never requests a mode switch. Keep the branch target and register logging separate from any later client startup code so a “host found” diagnostic cannot accidentally become an incomplete DPMI entry sequence.

Do not substitute 1686h

INT 2Fh AX=1686h answers a different question: whether the caller is currently executing in protected mode. The DPMI specification explicitly warns that this function must not be used to decide whether a DPMI host is installed. A real-mode program may have a host available before it has entered protected mode, so a mode test can report “real mode” while the startup interface is present. Conversely, using a mode result as proof of a DPMI API can lead software to invoke services that have not been established.

This distinction is useful when debugging a FreeDOS launch. FreeDOS supplies a DOS environment; the application or its documented startup path still has to arrange a compatible DPMI host when required. The 1687h call neither installs a host nor chooses one. It lets a loader avoid blindly starting a second host when a supported host is already present, and lets a small utility report a clear “DPMI unavailable” result before it attempts a protected-mode operation.

Test the boundary, not just the happy path

Use a disposable emulator profile and capture the returned registers before changing startup configuration. Run one case with no host and one with the application-recommended host. Verify that the probe treats any nonzero AX as absence, distinguishes host presence from 32-bit support, and never invokes the far pointer. If a real application then enters protected mode, test that as a separate stage with the host’s documented client protocol and the exact executable model.

When a program fails after startup, record the host name and version, CPU or emulator profile, and the BX, CL, DH, and DL values. Do not infer host compatibility from the processor model, available RAM, an INT 2Fh vector alone, or an AX=1686h result. Also avoid loading two DPMI providers just to make a probe pass; host ownership of processor mode, memory, and interrupts is part of the environment being diagnosed.

The useful conclusion from 1687h is deliberately small: a DPMI host answered this real-mode request, and its returned fields describe a possible client startup path. Whether that host supports the application’s required bitness and services, and whether the client can complete the transition correctly, are separate tests.

Related:

Sources:

Comments