IBM PS/2 INT 15h C2h: The BIOS Pointing-Device Interface
Use the optional PS/2 BIOS pointing-device service with explicit capability checks, reset semantics, bounded errors, and a clear boundary from INT 33h.
On IBM Personal System/2-compatible systems, BIOS INT 15h, function AH=C2h, provides a pointing-device control interface. Its subfunctions can enable or disable the device, reset it, set sample rate or resolution, report device type, and initialize the interface. This service sits below the familiar DOS mouse-driver API: it controls a BIOS-managed PS/2 pointing path, while an installed driver commonly exposes INT 33h operations to applications.
The service is optional and machine-family dependent. IBM documents that original PC/PCjr and older XT/AT firmware may reject it. A DOS program must check the carry flag and returned status, not assume that any machine with a PS/2-shaped connector implements this BIOS call. This article covers the BIOS contract, not direct 8042 programming or the serial/USB mouse protocols.
Function and return conventions
The general call uses AH=C2h and places the operation in AL. For the documented subfunctions, BH carries a mode or value. Examples include AL=00h to enable or disable, AL=01h to reset, AL=02h to set sample rate, AL=03h to set resolution, and AL=04h to read device type. AL=05h initializes the pointing-device interface; later subfunctions include extended behavior whose availability should be checked against the BIOS reference for the target family.
On success, IBM documents CF=0 and AH=00h. On failure, CF=1 and AH reports an error such as unsupported function, invalid input, interface error, resend, or missing far-call installation. The exact unsupported status can vary with the machine generation. Always inspect both carry and status before using a returned device ID or assuming the device state changed.
The caller should preserve registers according to its language and interrupt-wrapper conventions. A C wrapper may make the BIOS call appear simpler, but it can obscure carry or alter register widths. Keep the raw input and output register values available in diagnostic mode. The code below is pseudocode, because compiler interrupt syntax differs:
registers.AH = C2h
registers.AL = 01h ; reset device
invoke INT 15h
if carry is set:
report unsupported or device error from AH
else:
record returned device ID from BH
Reset changes state
Reset is not a passive discovery query. The documented PS/2 BIOS behavior resets pointing-device parameters and leaves the device disabled. IBM’s reference describes default sample rate, resolution, and scaling after reset; applications that need different values should explicitly configure them and then enable the device. Resetting a device while another driver owns it can disrupt that driver’s state, so a generic DOS application should normally use the resident mouse driver rather than reinitializing the BIOS-managed hardware behind its back.
The sample-rate subfunction accepts defined enumerated values, not an arbitrary integer rate. The resolution call likewise uses documented codes for counts per millimeter. A BIOS may reject an unsupported value with an input or interface error. Do not assume that the requested value was applied unless the call succeeds, and do not translate “reports per second” directly into the application event rate without accounting for BIOS and driver processing.
The initialization subfunction may alter more than one parameter and the device’s data packet configuration. It is not equivalent to merely enabling an existing mouse. Consult the exact IBM interface revision for the supported packet size, defaults, and return values. Extended functions should be kept out of the baseline compatibility path unless the target BIOS explicitly documents them.
For the enable/disable subfunction, the documented BH value selects the requested state: zero disables and one enables. Treat other values as invalid input rather than relying on a BIOS to mask unused bits. Reset and initialization have different side effects, so expose them as separate operations in a maintenance utility and require an explicit choice before either is issued. A read-device-type call can help identify the interface, but its returned ID is still a firmware/device report, not a health test or a complete model number. Preserve the status and ID exactly as returned instead of mapping unknown values to a familiar mouse class.
When building a test harness, include a no-op mode that only checks whether the BIOS accepts the call and never resets or enables the device. Then run state-changing tests in a separate boot profile with no resident mouse driver. This makes it possible to distinguish “the function exists” from “the hardware reacted,” while avoiding accidental disruption to a user’s active pointer configuration.
The BIOS interface is not INT 33h
INT 15h C2h is a BIOS-level device-control facility. INT 33h is the common application-facing mouse API installed by a resident DOS mouse driver. An application that wants pointer coordinates, button state, press counts, or callbacks generally depends on INT 33h, not on the BIOS subfunctions described here. The BIOS service is more relevant to a driver or platform component that owns the PS/2 device initialization path.
Do not invoke BIOS reset after CuteMouse or another driver has initialized the device unless that driver explicitly documents the operation. Doing so can desynchronize the driver’s assumptions about sample rate, scaling, packet size, and interrupt state. Similarly, changing resolution through BIOS while an application is using INT 33h can create apparent scaling changes that are difficult to attribute.
An installed INT 33h handler also does not prove that INT 15h C2h works. A mouse driver can support a serial mouse, bus mouse, USB compatibility layer, or emulator interface that the BIOS service does not control. Conversely, a BIOS may enumerate a PS/2 pointing device even when no DOS mouse driver has installed the application API.
Keep device ownership with BIOS or driver, not both
The IBM PS/2 BIOS manages the pointing-device controller and its interrupt path. A low-level program that separately polls controller ports, sends device commands, or hooks the hardware interrupt can race BIOS and driver operations. DOS does not automatically serialize those transactions. If the application only needs mouse input, install and use the supported DOS mouse driver. If you are writing that driver, define which component owns reset, interrupt routing, packet parsing, and restoration.
The BIOS call reports operation success, not physical health. A success response does not prove that every later movement packet arrives, that all buttons work, or that the device remains connected. Test actual movement and button behavior through the consumer interface. A failure response may mean unsupported firmware rather than a bad mouse. Distinguish service availability from device-level diagnostics in logs.
Compatibility and failure handling
The function is associated with PS/2 BIOS generations, but third-party AT clones may implement only part of it. An old BIOS can return a family-specific unsupported status; a clone may return a generic error. A virtual machine may provide an emulated pointing device through a different BIOS service. Never infer support from the connector, the machine’s marketing name, or the success of INT 33h.
Keep a harmless fallback when the BIOS service is absent. A DOS utility can state that BIOS control is unavailable and direct the operator to the resident mouse driver. It should not silently fall through to raw port I/O. If reset succeeds but a later operation fails, report the exact subfunction and returned status; do not repeatedly reset in a loop because each reset can destroy state again.
Acceptance tests
Test a BIOS known to support C2h, a machine where it is documented as unavailable, and an emulator if that environment is a supported target. Verify carry/status handling, reset’s disabled state, enumerated sample-rate and resolution values, and the result of enable/disable. Keep a mouse driver out of the test initially, then separately verify that the normal driver can initialize and that no test utility leaves the device in a changed configuration.
For a production driver, also test the defined initialization and extended subfunctions against the precise BIOS revision. Record model, BIOS version, subfunction, input registers, returned flags/registers, and whether the device produced subsequent events. Do not report “mouse works” from a successful BIOS return alone.
The compatibility boundary is the main lesson: use INT 15h C2h only when the target BIOS documents it and your code owns the device state. Use INT 33h for ordinary DOS application input. Keeping those layers separate prevents a BIOS reset or raw controller operation from unexpectedly breaking an already-loaded mouse driver.
Related:
- Programming the DOS Mouse API: INT 33h State, Coordinates, and Events
- How to Configure CuteMouse on FreeDOS Without Wasting Conventional Memory
Sources: