Skip to content
FreeDOSDeep Dive Published Updated 7 min readViews unavailable

DOS BIOS INT 17h: Printer Calls, Status Bits, and Their Limits

Interpret IBM-compatible BIOS INT 17h printer calls without mistaking status bits for a reliable printer-health check or a complete DOS spooler.

The IBM PC BIOS printer interface at INT 17h is a small firmware service for the parallel-printer ports known to that BIOS. It can send a byte, initialize a port, and return status bits. It is not a print spooler, a printer-language driver, or a guarantee that a printer has rendered a page. Understanding that boundary helps separate a DOS application’s output path from firmware polling and from the printer’s own state.

The original IBM-compatible call convention uses DX to select a printer index and AH to select the operation. Function 00h sends the byte in AL; function 01h initializes the selected printer; function 02h reads status. Functions 00h and 01h return a status value in AH in the documented IBM BIOS interface. BIOS clones and later machines may implement different details, so validate the target rather than treating an old PC/XT behavior as a universal firmware standard.

Decode the status as a snapshot, not a health verdict

The classic status byte exposes several parallel-port signal states. IBM’s PC BIOS reference documents the commonly recognized bits as:

Bit Traditional meaning when set
7 Printer not busy / ready state
6 Acknowledge signal
5 Paper out
4 Printer selected
3 I/O error
0 Timeout

Bits 1 and 2 are described as unused in this interface. Multiple status bits can be set at once, and the returned value reflects what the adapter/firmware can observe at the moment of the call. A bit pattern is not an authenticated identity check for a printer and does not prove that a paper path, ribbon, toner, or print language is correct. Some hardware does not wire or report every legacy signal in a useful way.

The “not busy” name is especially easy to invert. In the classic status definition, bit 7 set means not busy; a cleared bit indicates busy. A diagnostic should label the bit explicitly instead of printing an unexplained decimal status. Likewise, bit 5 being clear does not establish that paper is loaded if the adapter cannot report the signal accurately.

The call boundary and a careful probe

An assembly caller selects the operation in AH, places a byte in AL for the write call, selects a port index in DX, then invokes the BIOS interrupt. A minimal call sketch is:

mov dx, 0          ; BIOS printer index zero, commonly LPT1
mov al, 'X'        ; character to send for AH=00h
mov ah, 00h
int 17h
; AH contains the classic status result on return.

This is an interface sketch, not a complete application. A real program must preserve the registers required by its ABI, check the returned status using the target BIOS documentation, and avoid assuming that the index-to-port mapping is identical on every machine. The returned status should be captured before another call overwrites it. Function 02h can be called to read status without transmitting a byte, while function 01h requests initialization and should not be called casually during another program’s active print job.

A safe test uses a printer or parallel-port test fixture whose behavior is understood, sends a short non-sensitive test sequence, and confirms output at the physical device. Record the BIOS vendor/version, base address mapping, DX index, byte sent, returned AH, and observed result. Do not probe arbitrary port indexes on unknown hardware and infer that an unsupported index is a printer failure.

BIOS output is not a queue

The BIOS call processes a byte-level request. Depending on firmware and hardware, the call can wait for a ready condition or report timeout/error status. It does not offer a DOS file handle, a high-level page description language, a rendering model, or a durable queue with job identifiers and cancellation semantics. A returned status after sending one byte cannot prove that a complete multi-kilobyte document has been accepted or printed.

DOS may expose printer devices such as LPT1 through character-device or handle interfaces, while a separate utility can spool or queue a file. A DOS application that opens LPT1 and writes bytes is not automatically using the same path as a program that calls the BIOS directly. MODE may redirect a printer port to a serial device on supported FreeDOS configurations, and software may also hook printer services. The installed software stack therefore matters more than the name printed on a cable.

This distinction is important when diagnosing a legacy application. If a short INT 17h test succeeds but an application fails, inspect the application’s printer driver, output language, and whether it uses DOS file I/O, BIOS services, or direct hardware access. If a DOS file-handle write fails while the BIOS call works, the issue may be in the DOS device path. If bytes leave the PC but the printer produces garbage, the port may be functioning while the application and printer disagree about PCL, PostScript, escape sequences, or character encoding.

Interpret failures conservatively

Do not build an unattended workflow around one status bit. A robust service routine has a finite wait policy, captures the complete returned status, and reports a failure to the caller rather than looping forever on a busy printer. The historical BIOS interface does not define modern queue retry/backoff policy; applications that add it should bound retries and let an operator inspect persistent paper-out, offline, or timeout conditions.

Avoid resetting the printer for every record. Initialization can disturb device state and may discard buffered content. Do not treat an ACK as proof that a whole job is complete: it is a low-level handshake signal. For long jobs, compare the byte count the application intended to send with the count accepted by the output layer, and check the actual device result. Keep an independent copy of the source document so diagnosis never requires reconstructing output from a half-completed print.

In virtual machines, determine what the virtual firmware implements and where the guest’s LPT port is routed. A BIOS status byte may be synthesized by the emulator and have no relationship to a host printer. Test the virtual port mapping separately from the host print bridge. An emulator that reports a ready bit but discards output is not behaving like a physical printer path end-to-end.

A layered troubleshooting sequence

  1. Identify the physical or virtual parallel adapter, BIOS, selected printer index, and any DOS redirector or TSR that hooks output.
  2. Read status with function 02h and decode the bit fields against the IBM-compatible BIOS convention, while noting that some signals may be unavailable.
  3. Send a short known test byte with function 00h; capture the post-call status and check the external device.
  4. Compare that result with the application’s actual route: BIOS, DOS LPT device, redirected handle, spooler, or direct port access.
  5. Validate a complete document using the exact printer protocol and encoding expected by the device.

The test is successful only at the layer actually exercised. A status read proves that firmware returned a byte. A byte write with no timeout proves at most that the BIOS accepted or attempted that character according to its own contract. A printed page is stronger evidence of the full application-to-device path.

Use INT 17h when writing or diagnosing software that specifically needs the classic BIOS printer interface. For ordinary application output, prefer a documented DOS device/handle or queue interface and test the whole route. The BIOS service remains useful on compatible hardware, but its compact call contract should never be mistaken for a modern print subsystem or a reliable remote printer monitor.

Related:

Sources:

Comments