How MS-DOS 6.22 Processes Mouse Hardware Interrupts

This article explains the mechanism by which MS-DOS 6.22 handles hardware interrupts generated by mouse pointing devices. Because MS-DOS operates in real mode and lacks native, built-in mouse handling within its kernel files (IO.SYS and MSDOS.SYS), it relies on a dedicated mouse driver to bridge hardware signals and software applications. The following sections break down the end-to-end path of a mouse interrupt, spanning physical signal generation, Programmable Interrupt Controller (PIC) translation, Interrupt Service Routine (ISR) execution, and delivery to user applications via the INT 33h interface.

The Role of the Mouse Driver in MS-DOS 6.22

MS-DOS 6.22 does not actively monitor pointing devices on its own. Instead, it delegates this task to a resident driver—typically MOUSE.COM loaded via AUTOEXEC.BAT or MOUSE.SYS loaded via CONFIG.SYS.

During initialization, the driver performs two critical setup actions:

  1. It registers an Interrupt Service Routine (ISR) in the Real-Mode Interrupt Vector Table (IVT) corresponding to the hardware interrupt (IRQ) line used by the mouse interface.
  2. It hooks the software interrupt INT 33h, establishing the standard API that DOS applications use to query mouse coordinates, button states, and register asynchronous event handlers.

Hardware Signal Generation and PIC Routing

When a user moves the mouse or presses a button, the device transmits raw data packets to the host system interface. The specific hardware path depends on the bus type:

  • PS/2 Mice: The pointing device sends data packets to the Intel 8042 keyboard/auxiliary controller, which asserts IRQ 12.
  • Serial Mice: The serial port's UART (e.g., 8250/16550) detects incoming serial data from the RS-232 line and asserts IRQ 4 (for COM1/COM3) or IRQ 3 (for COM2/COM4).
  • Bus/InPort Mice: A dedicated ISA expansion card decodes positional quadrature signals directly and triggers an assigned line, typically IRQ 2 or IRQ 5.

The asserted IRQ line reaches the 8259A Programmable Interrupt Controller (PIC). In PC-compatible architectures running MS-DOS:

  • Serial mice trigger the Primary (Master) PIC, which maps IRQ 3 to INT 0Bh and IRQ 4 to INT 0Ch.
  • PS/2 mice trigger the Secondary (Slave) PIC on IRQ 12, which maps to INT 74h.

Once the PIC determines that the interrupt line is unmasked and has priority, it raises the CPU's INTR line.

CPU Vectoring via the Real-Mode IVT

When the CPU acknowledges the interrupt signal, the 8259A places the corresponding interrupt vector number (such as 0Ch or 74h) onto the data bus. Operating in 16-bit real mode, the CPU calculates the memory offset in the Interrupt Vector Table located at physical address 0000:0000h to 0000:03FFh:

\[\text{Vector Address} = \text{Vector Number} \times 4\]

The CPU pushes the FLAGS register, clears the Interrupt Flag (IF) to disable further interrupts, pushes the current CS and IP registers onto the stack, and loads the segment and offset pointing directly into the resident DOS mouse driver's hardware ISR.

ISR Execution and Packet Processing

Once control shifts to the mouse driver's ISR, the routine performs the following operations:

  1. Register Preservation: The ISR pushes the general-purpose registers onto the active stack to preserve application state.

  2. Port I/O Retrieval: The ISR reads incoming bytes directly from the hardware ports using IN instructions:

    • For PS/2, it reads from I/O port 60h after checking the status register at 64h.
    • For serial mice, it reads from the Receiver Buffer Register (e.g., 3F8h for COM1).
  3. Packet Assembly: Mouse communication protocols transmit data in multi-byte packets (typically 3 bytes for standard Microsoft Serial and PS/2 mice, or 4 bytes for extended/wheel formats). Because an interrupt occurs per byte, the driver maintains an internal state machine to buffer incoming bytes until a full packet is collected.

  4. Coordinate Calculation: Once a complete packet arrives, the driver extracts:

    • Relative horizontal movement (\(\Delta X\))
    • Relative vertical movement (\(\Delta Y\))
    • Button states (left, right, middle press/release)

    The driver converts these raw "mickey" counts into internal virtual screen coordinates based on current sensitivity and threshold multipliers.

  5. End of Interrupt (EOI): The driver signals the interrupt controller that processing is complete by writing an EOI command byte (20h) to port 20h (Master PIC) and, if handling a slave line such as IRQ 12, to port A0h (Slave PIC).

  6. IRET Execution: The ISR pops the saved registers and executes an IRET instruction, restoring the previous CPU state and resuming the interrupted program.

Exposing Data to Applications

After updating its internal coordinates, the driver makes this information available to running software using two methods:

  • Polling (Synchronous): Applications call INT 33h with function code AX = 0003h to retrieve current horizontal (\(CX\)) and vertical (\(DX\)) positions alongside button masks (\(BX\)).
  • User Callbacks (Asynchronous): Applications can register an internal subroutine using INT 33h function AX = 000Ch, supplying a call mask (e.g., trigger on movement or button press). When a hardware interrupt completes packet assembly, the driver's ISR switches execution context to the application's callback routine before issuing IRET, passing updated coordinates directly in registers without requiring constant polling from the main program loop.