DOS Video BIOS INT 10h: Modes, Pages, Cursor State, and Compatibility
Use INT 10h video services while preserving mode, active-page, cursor, and adapter state instead of assuming every PC BIOS behaves like VGA.
The PC video BIOS exposes a family of INT 10h services for setting display modes, positioning the cursor, selecting text pages, and writing characters. DOS programs use these calls to communicate with display hardware through a compatibility layer instead of embedding adapter-specific register programming in every application. That layer is only useful when the program observes its state correctly: mode number, active page, cursor location, and adapter capabilities are related but not interchangeable.
The central operational mistake is to treat a familiar mode number or text-memory address as universal. IBM-compatible adapters evolved from CGA, MDA, and EGA to VGA and later video BIOS extensions; clones differ in supported modes and behavior. FreeDOS can run on legacy machines, virtual machines, and modern firmware environments, each exposing a different mix of BIOS services. Probe state, use the documented calls appropriate to the target, and preserve an explicit fallback.
Changing mode can change more than resolution
The traditional INT 10h mode-set call uses AH=00h and supplies a mode in AL. The operation can reset display state and clear video memory. Some VGA BIOS interfaces define a bit-7 convention to request preserving display memory for supported mode sets, but that behavior is not a universal promise for every early adapter or BIOS. Do not use the preservation bit as a substitute for saving application data.
Mode numbers also do not establish every physical property of the display. The same number may be unsupported, implemented differently, or exposed through extensions on a particular adapter. Query current state after a mode change and use the proper capability discovery interface when the program requires a specific resolution, color depth, or framebuffer. VESA VBE functions use an extended AX=4Fxxh interface and have their own return/status rules; they are not simply additional legacy AL mode numbers.
Treat a mode transition as an application lifecycle boundary: stop drawing, select the intended mode, re-read supported state, establish the active page and cursor, repaint the whole logical screen, then resume normal updates. On exit, restore the previous mode and any state your program changed when the target environment expects it. If the process can crash or be terminated, plan a recovery path rather than assuming the program always performs a clean restore.
Query before assuming which page is visible
The AH=0Fh service reports the current mode in AL, the number of text columns in AH, and the active page in BH on the documented interface. The returned columns and page are useful for validating assumptions before issuing page-specific calls. A separate BIOS function selects the active display page; the page number passed to cursor and output functions must refer to the intended page.
Page selection changes which display page is active, but does not mean that all memory is cleared, that every adapter supports the same number of pages, or that the BIOS’s cursor state for all pages has been initialized by your application. Keep the page identity in your own display state and verify the result after changing it. If a title bar appears on one page while the cursor moves on another, inspect the BH argument to each operation before blaming the display adapter.
Cursor coordinates are page-relative text state
The common AH=02h cursor-position call takes the page in BH, row in DH, and column in DL. AH=03h reads cursor position and shape for a selected page. These are character-cell coordinates, not pixel coordinates, and valid row/column bounds depend on the active text mode. A program that hard-codes 80 columns and 25 rows should verify that the queried display state actually matches.
Cursor visibility and shape are also adapter-specific enough to warrant caution. The BIOS exposes a cursor-shape function, but different text cell heights and firmware behavior affect its interpretation. Instead of assuming one scan-line geometry, use the BIOS’s documented convention for the selected mode and test on the supported adapters. Updating the cursor position after drawing directly to memory may be necessary because a direct memory write does not automatically tell the BIOS where your application considers the text cursor to be.
BIOS teletype output and DOS standard output are different APIs
The video BIOS teletype function, conventionally AH=0Eh, displays a character, advances the cursor, and may scroll the screen. It is useful for simple low-level diagnostics and boot-time text, but it targets display behavior. DOS standard output can instead be redirected to a file, pipe, or device by the shell. A command-line utility that must honor redirection should use DOS handle-based output, not assume that BIOS video output reaches the intended destination.
Conversely, a program that must draw to a specific screen page or use character-cell display state may intentionally use video BIOS services. Decide at the API boundary whether the output is a console stream or a screen operation. Mixing the two casually can produce duplicated text, output that vanishes under redirection, or a cursor position inconsistent with the rest of the display.
Direct video memory is a separate ownership model
Many DOS programs write directly to video memory for speed or special effects. This bypasses INT 10h services and can be legitimate when the program deliberately owns the hardware mode and knows the adapter layout. It also bypasses BIOS state maintenance: the BIOS may not know the cursor, active page, or contents your application assumes. A later BIOS call can overwrite or reinterpret state based on its own model.
Do not write to the common text-memory segment merely because it worked under one VGA emulator. Monochrome and color adapters use different address windows; banked and graphics modes have different memory layouts; protected-mode or UEFI environments may not provide a usable real-mode video BIOS. For a controlled retro platform, document the adapter/mode contract and use a dedicated hardware driver. For a portable DOS program, stay within the documented BIOS or DOS interface and probe optional extensions.
Handle unsupported modes and BIOS status carefully
The legacy mode-set interface predates richer standardized capability reporting. A return register may not reliably prove support on every BIOS. VBE functions include signature and status results that need their own validation. Never assume that an interrupt call succeeded merely because it returned without crashing; query the resulting mode or extension information and compare it with the requirements your renderer needs.
Use a fallback ladder: standard text mode first for diagnostics; then a known mode whose behavior has been validated on the target; then optional VBE modes after confirming the VBE interface and mode attributes. Keep the program usable in a basic mode even when a high-resolution mode is missing. When a video BIOS call fails or behaves inconsistently, log the current adapter/emulator, the requested mode, returned values, and the exact BIOS call sequence.
Build a video-state test matrix
Test startup in the machine’s initial mode, a change to a supported text mode, page switching, cursor move/readback, teletype output, restore on exit, and a deliberately unsupported mode. Repeat on each adapter class or emulator profile you claim to support. Include a redirected-output run to prove that the program distinguishes DOS stdout from video BIOS drawing. Verify screen state after a crash or reset if your software writes directly to hardware memory.
Ralf Brown’s Interrupt List is a reverse-engineered compatibility index, while vendor technical references document the behavior of particular adapters. Use both with explicit target information. A BIOS call is a useful abstraction, not a guarantee that all PC-compatible graphics devices implement the same capabilities or quirks.
Related:
- How to Set Up a Development Environment on FreeDOS
- ANSI Console Drivers on FreeDOS: Escape Sequences, NANSI, and Compatibility
Sources: