Windows 98 IVT Processing in MS-DOS Mode

This article examines how Microsoft Windows 98 managed the Interrupt Vector Table (IVT) during MS-DOS execution, detailing the architectural mechanics behind both real MS-DOS mode and virtualized MS-DOS sessions. It outlines the memory structures, interrupt reflection techniques, and mode-switching mechanisms that allowed legacy real-mode software to access hardware and software interrupts without destabilizing the operating system.

Understanding the Execution Environments

Windows 98 handled MS-DOS execution through two distinct environments, each processing the Interrupt Vector Table differently:

  1. Native (Real) MS-DOS Mode: The graphical environment and 32-bit protected-mode kernel completely unloaded, dropping the x86 processor into 16-bit Real Address Mode.
  2. Virtual 8086 (V86) Mode: MS-DOS ran inside a virtual machine (VM) managed by the Virtual Machine Manager (VMM32.VXD) alongside the protected-mode Windows operating system.

Real MS-DOS Mode IVT Architecture

When a user selected "Restart in MS-DOS mode," Windows 98 unloaded protected-mode drivers, terminated the Graphical Device Interface (GDI), and transferred system control back to IO.SYS. In this native state, interrupt processing adhered strictly to original IBM PC real-mode specifications:

  • Direct Memory Location: The IVT occupied the first 1,024 bytes of physical RAM, spanning memory addresses 0000:0000 to 0000:03FF.
  • Table Layout: The table held 256 four-byte pointers structured as segment:offset pairs representing the entry points for Interrupt Service Routines (ISRs).
  • Hardware Execution: When a hardware interrupt (IRQ) or software interrupt (INT n) fired, the CPU directly referenced the index at n * 4, pushed the FLAGS, CS, and IP registers onto the stack, and branched immediately to the specified handler. Windows 98 protected-mode supervisors were inactive, meaning no virtualization or interception occurred.

Virtual 8086 Mode and Interrupt Reflection

When executing MS-DOS applications inside a Windows 98 window or full-screen prompt within the GUI, the processor operated in Protected Mode using Virtual 8086 mode. The operating system virtualized the IVT to maintain multitasking integrity.

The Virtual IVT

Each MS-DOS virtual machine received its own virtualized 1 MB memory address space. Within this virtual address space, an apparent IVT existed at 0000:0000 to 0000:03FF. DOS programs could read and modify these addresses freely, believing they were altering physical hardware tables.

Trapping and Interrupt Reflection

Because real-mode interrupt modifications could compromise concurrent processes, Windows 98 relied on hardware-level trapping:

  1. Instruction Trapping: Sensitive instructions such as CLI (Clear Interrupt Flag), STI (Set Interrupt Flag), and software interrupt instructions (INT n) caused a General Protection Fault (GPF / Exception 13) or trapped into Ring 0.
  2. VMM Interception: The Virtual Machine Manager (VMM32) intercepted the trap before the application could execute it directly.
  3. Interrupt Routing via VPICD: The Virtual Programmable Interrupt Controller Device (VPICD.VXD) evaluated hardware interrupts. If a hardware device generated an interrupt designated for the DOS application, VPICD routed it to the active virtual machine.
  4. Reflection: If the interrupt belonged to the MS-DOS program, Windows 98 performed interrupt reflection. The VMM manually simulated the CPU’s hardware interrupt sequence: it pushed the virtual FLAGS, CS, and IP onto the virtual machine's stack and redirected execution to the pointer found inside the virtual machine’s local IVT.

Transition and Vector State Restoration

When switching between native Windows and pure MS-DOS mode, Windows 98 managed IVT state transitions via IO.SYS:

  • Saving the Real-Mode Vectors: During Windows 98 bootup, the real-mode loaders preserved a pristine copy of the base real-mode IVT established by CONFIG.SYS and AUTOEXEC.BAT.
  • Restoration: When exiting to pure MS-DOS mode, Windows restored hardware interrupt controllers (the master and slave 8259 PICs) to their standard real-mode vector mappings (IRQs 0–7 mapped to vectors 08h–0Fh, and IRQs 8–15 mapped to 70h–77h) and loaded the preserved interrupt pointers back into 0000:0000. This ensured that legacy device drivers and BIOS routines resumed operation without residual conflicts from the 32-bit protected-mode environment.