How MS-DOS 6.22 Handles 32-Bit DOS Extender Memory
MS-DOS 6.22 is a 16-bit real-mode operating system natively limited to addressing 1 MB of physical memory, yet it frequently hosted complex 32-bit protected-mode software like games and professional suites. To achieve this, 32-bit programs relied on DOS extenders (such as DOS/4GW, Causeway, or PMODE/W) that acted as an intermediary translation layer. MS-DOS 6.22 does not manage 32-bit extended memory directly; instead, it delegates extended memory requests to specialized device drivers like HIMEM.SYS and EMM386.EXE, while managing only low conventional memory and I/O translation buffers through standard DOS interrupt handlers.
The Real-Mode Boundary and Extender Initialization
When a 32-bit application executes in MS-DOS 6.22, the file begins execution as a standard 16-bit real-mode stub. This stub queries MS-DOS using Interrupt 21h, Function 48h (Allocate Memory) or Function 4Ah (Modify Allocated Memory Block) to allocate conventional memory. This base allocation is recorded in the DOS Memory Control Block (MCB) chain within the first 640 KB of RAM.
This conventional memory footprint is reserved exclusively for the extender's real-mode routines, interrupt translation wrappers, and real-mode transfer buffers used for future I/O operations. Once this footprint is established, the extender queries the operating environment to determine how it can obtain large blocks of extended memory (memory above 1 MB) and safely transition the CPU from real mode to 32-bit protected mode.
The Memory Negotiation Hierarchy
Because MS-DOS 6.22 cannot process 32-bit linear address spaces, the extender probes for system memory interfaces in a strict, prioritized hierarchy:
DOS Protected Mode Interface (DPMI):
The extender first checks for an existing DPMI host (via Interrupt 2Fh, Function 1687h), which is common if the application is running under Windows 3.1 or a dedicated third-party manager. If present, the extender requests memory pages directly using Interrupt 31h (Function 0501h). The DPMI host handles all descriptor table management, physical page allocation, and virtual-to-physical address mappings.Virtual Control Program Interface (VCPI):
If no DPMI host exists, the extender checks for VCPI support through an expanded memory manager like EMM386.EXE via Interrupt 67h. When EMM386 is active, the CPU runs in Virtual 8086 (V86) mode. Under VCPI, the extender requests 4 KB physical memory pages through INT 67h, Function DE04h/DE05h. EMM386 allocates these physical addresses, and the extender then switches the processor into 32-bit protected mode while maintaining coexistence with the underlying V86 DOS session.Extended Memory Specification (XMS):
If EMM386 is absent and only HIMEM.SYS is loaded, the processor remains in pure 16-bit real mode. The extender issues requests to HIMEM.SYS using the XMS driver entry point (obtained via Interrupt 2Fh, Function 4310h). It calls Function 09h (Allocate Extended Memory Block) to reserve contiguous blocks of physical memory above the 1 MB boundary.BIOS / Int 15h Fallback:
If neither an XMS nor a VCPI driver is installed, the extender accesses memory directly using BIOS Interrupt 15h (Function 88h or the newer Function E820h/E801h), manually switching the processor into protected mode and managing the Global Descriptor Table (GDT) and physical address space on its own.
Page Tables and Flat 32-Bit Addressing
Once extended memory blocks are allocated via XMS, VCPI, or DPMI, the extender constructs its own Global Descriptor Table (GDT), Interrupt Descriptor Table (IDT), and paging structures (CR3 and Page Directory/Page Tables).
The extender establishes a 32-bit flat memory model where code and
data segments span a theoretical 4 GB linear address space. When the
protected-mode application invokes runtime memory allocation routines
(such as standard C malloc() or sbrk()), the
extender's runtime fulfills the request out of the pre-allocated
extended memory pool, updating internal page tables without
communicating with the MS-DOS 6.22 kernel.
Memory Buffering and System Call Translation (Thunking)
MS-DOS 6.22 kernel routines and BIOS interrupts cannot execute in 32-bit protected mode, nor can they access memory addresses above the 1 MB mark. When a 32-bit program needs an OS service—such as reading a file into a high-memory buffer:
- The extender intercepts the 32-bit application's Interrupt 21h call.
- If data transfer is involved, the extender uses the conventional memory transfer buffer it reserved at startup.
- The extender copies necessary parameters or data from the high-memory buffer down to the conventional memory buffer below 1 MB.
- The extender temporarily transitions the CPU to real mode (or V86 mode) and issues the genuine 16-bit MS-DOS Interrupt 21h.
- Once MS-DOS 6.22 completes the operation and returns, the extender switches the CPU back to 32-bit protected mode.
- The extender copies the resulting data from the low-memory transfer buffer into the application's 32-bit target address space and returns control to the running program.
Through this separation, MS-DOS 6.22 remains completely unaware of 32-bit operations, managing only its standard real-mode resources while the extender handles high-memory addressing and processor state transitions.