How MS-DOS 6.22 Handles Serial Port Interrupts
MS-DOS 6.22 does not natively implement interrupt-driven handling for serial communications ports; instead, the operating system relies on polling through the system BIOS for basic I/O, while delegating true hardware interrupt handling to user applications, third-party device drivers, or TSR (Terminate and Stay Resident) programs. To handle incoming serial data reliably at standard modem and transfer speeds, software running under MS-DOS 6.22 bypasses default DOS kernel routines to directly configure the 8259 Programmable Interrupt Controller (PIC), hook the CPU's Interrupt Vector Table (IVT), and manage the registers of the system’s Universal Asynchronous Receiver-Transmitter (UART).
Native MS-DOS and BIOS Limitations
At the operating system level, MS-DOS 6.22 provides serial access
through logical device names (AUX, COM1,
COM2, COM3, and COM4) via MS-DOS
Interrupt 21h services. Internally, these calls map to BIOS Interrupt
14h.
The standard PC BIOS implementation of Interrupt 14h uses polled I/O rather than interrupt-driven I/O. During polled operations, the CPU repeatedly reads the UART’s Line Status Register (LSR) to determine if a character has arrived or if the transmitter is empty. Because the CPU does not respond to asynchronous hardware signals in this mode, polling frequently causes data loss (buffer overruns) at transfer rates exceeding 2400 to 9600 baud when the CPU is busy with disk I/O, display updates, or calculations.
Hardware Mapping and IRQ Routing
IBM-compatible PCs assign specific Interrupt Requests (IRQs) to serial hardware ports:
- COM1 and COM3: Assigned to IRQ 4, which maps to CPU interrupt vector INT 0Ch.
- COM2 and COM4: Assigned to IRQ 3, which maps to CPU interrupt vector INT 0Bh.
Because COM1/COM3 and COM2/COM4 share interrupt lines, MS-DOS 6.22 environments generally require that shared ports are not used simultaneously unless specialized multi-port serial cards with bus-arbitration logic are installed.
Both IRQ 3 and IRQ 4 are managed by the primary 8259 PIC, which
prioritizes and forwards hardware interrupt signals directly to the
CPU's INTR pin.
The Interrupt-Driven Handling Process
To achieve stable communications, MS-DOS software (such as terminal emulators, FOSSIL drivers, or packet drivers) takes over interrupt management directly. The execution flow follows these specific stages:
1. Hardware Initialization
The application or driver enables the hardware interrupt logic on the UART (8250, 16450, or 16550 chip):
- Interrupt Enable Register (IER): The program writes to the IER (base I/O address + 1) to enable specific conditions, typically "Received Data Available" (bit 0) and occasionally "Transmitter Holding Register Empty" (bit 1).
- Modem Control Register (MCR): The program asserts
bit 3 (
OUT2). In standard PC serial hardware,OUT2acts as a tri-state gate that connects the UART's interrupt line to the system bus. IfOUT2is low, hardware interrupts never reach the 8259 PIC.
2. Vector Table Redirection
The software saves the existing vector address stored in the
Interrupt Vector Table (IVT) in conventional memory (at
0000:0030h for INT 0Ch, or 0000:002Ch for INT
0Bh) and writes the memory address of its own custom Interrupt Service
Routine (ISR). This is accomplished either via direct memory
modification or through MS-DOS Interrupt 21h, Function 25h (Set
Interrupt Vector).
3. Unmasking the 8259 PIC
The driver reads the 8259 Interrupt Mask Register (IMR) at I/O port
21h, clears the bit corresponding to the serial port's IRQ
line (bit 3 for IRQ 3, bit 4 for IRQ 4), and writes the modified mask
back to port 21h. This permits the PIC to signal the CPU
when the UART fires an interrupt.
4. ISR Execution Cycle
When the UART receives a byte or its transmit FIFO empties:
- The UART pulls the IRQ line high.
- The 8259 PIC signals the CPU and places the vector number (0Bh or 0Ch) on the data bus.
- The CPU pauses current execution, pushes flags and return addresses onto the stack, and transfers execution to the custom ISR.
- The ISR reads the Interrupt Identification Register (IIR) at base address + 2 to determine the cause of the interrupt.
- If incoming data triggered the interrupt, the ISR reads the byte from the Receiver Buffer Register (RBR) at base address + 0, which automatically resets the UART's interrupt condition, and places the byte into a software-managed circular ring buffer in RAM.
- The ISR issues a non-specific End of Interrupt (EOI) command by
writing
20hto port20h(the 8259 PIC command register). - The ISR executes an
IRETinstruction, returning CPU execution to the interrupted task.
5. Teardown
When the communication application terminates, it must reverse this setup. It masks the IRQ on the PIC, disables the UART's IER and MCR lines, and restores the original interrupt vectors to the IVT via MS-DOS Function 25h to prevent system crashes when subsequent interrupts fire into deallocated memory.