16-bit IBM PC Compatible DOS (whether PC-DOS, MS-DOS or DR-DOS or similar) has a wide variety of memory configurations. There are a number of terms that surround the subject of memory configuration. Types of memory include conventional/lower, high, upper, expanded, extended. There are acronyms like HMA, UMB, UMA, EMS, XMS. Complicating the discussion are the inherent limitations of DOS and the ways programmers got around them.
This article addresses these issues from the gamer's perspective. We will answer the following question:
How do I configure memory to make games run with the best feature support?
Historical Perspective
It is important for gamers to understand what the various limitations are, why they exist, how they were overcome and what games need and why. In order to understand DOS memory configurations throughout DOS's functional lifetime, you have to start at the very beginning of the life of the IBM PC.
I. 8088/8086 PCs
In 1981, IBM released its Personal Computer, Model 5150. This computer used the Intel 8088 Processor. This processor used 16-bit data values (internally) and had an 8-bit external data bus and a 20-bit addressing bus. The 20-bit addressing bus allowed the 8088 to read and/or write to a maximum of 1MB of memory, whether RAM and/or ROM. This was considered huge at the time. By comparison, the Apple II's 6502 CPU could only address 64KB of memory.
When IBM designed the PC, it decided to allocate a certain portion (called lower memory) of the 8088's addressing space for RAM which all the programs, including DOS, would use. The remainder (called upper memory) would be used by ROM on the motherboard (for the BIOS and ROM BASIC) and expansion cards. Video memory and most memory that appeared on expansion cards would also be assigned to the upper memory portion of the address space.
Within a year of the PC's life, IBM and Microsoft, decided to allocate the address space in the following manner:
The lower 640KB of physical memory was designated as RAM and made available for program use. This became known as Conventional Memory and the 640KB of addressing space the Conventional Memory Area.
The upper 384KB of physical memory could be a combination ROM and RAM and was reserved for hardware and system use. This became known as called Upper Memory and the 384KB of addressing space the Upper Memory Area. Thus the PC Memory Map was very simple:
00000-9FFFF Conventional Memory
A0000-FFFFF Upper Memory
Although the 8088 could address a large amount of memory for the time, this was only as meaningful as the amount of physical memory installed. The earliest IBM PCs could only have 64KB of RAM installed on the motherboard. The remainder had to be installed by inserting memory cards in the system. (The IBM PC also needed a ROM BIOS upgrade to recognize 640KB of Conventional Memory, otherwise it would be limited to 544KB).
The early PCs had what would later be known as ISA slots which were used for adding Conventional Memory as well as hardware peripherals. Before the late 1980s, PCs did not usually come with the maximum of 640KB of Conventional Memory installed. Games from this early period often needed only 128KB, 256KB or 512KB of RAM to run, with or without DOS.
I know of no PC game released during the 1980s — whether as a booter or for DOS — that required or utilized more than 640KB of Conventional Memory or any other type of memory. Games from this period would rarely see a measurable speed benefit from additional RAM in the system than the game required. Speed was almost entirely dependent upon the processor.
What did the upper memory area contain at this point? Configurations varied considerably even during the early days of the PC, but the following was common: The whole segment F0000-FFFFF was essentially reserved from the ROM BIOS, and in IBM machines, ROM BASIC.
ROM BASIC would be included in IBM machines into the early 90s for compatibility with BASIC software, including games, that used the routines contained within the ROM BASIC. Even an otherwise excellent clone like the Compaq Portable would fail to run programs that relied on ROM BASIC. The lower 32KB of the B0000-BFFFF segement was reserved for the RAM contained on the Monochrome Graphics and Printer Adapter (MDA, only 4 KB used) and Hercules Graphics Cards (32KB used in graphics mode). This was called the monochrome text/graphics area.
The upper 32KB of the B0000-BFFFF segment was reserved for the Color/Grapics Adapter (CGA, 16KB used) This was the color text/graphics RAM area. Even if the graphics card contained less than 32KB of RAM, the whole half of the segment was often unusable by any other card. PCs could have both monochrome and color cards within the same system. Each card would be connected to a separate monitor, which made the whole B0000-BFFFF segment reserved for graphics. The early graphical games designed or ported to the IBM PC platform supported CGA or Hercules graphics only. Text only games allowed either CGA or MDA/Hercules to be used.
The hard drive, very expensive in those days, would have been connected to an adapter card with a firmware ROM that would boot the drive. Early firmware was 8KB in size and located in an 8KB slice in the C0000-CFFFF or D0000-DFFFF area. The most popular area was the C8000-C9FFFF area. Other peripherals, such as SCSI and tape adapters firmware would be located somewhere in the C, D or E segments. On many cards, the memory locations the firmware could use was configurable by setting jumpers on the card.
If there was no BIOS or firmware ROM or peripheral RAM located in a portion of upper memory, that area would be useless. Very rarely would a machine put RAM in this area that was not dedicated to a peripheral's use. Even during this early period, large spreadsheet and databases could use more memory than the 640KB of Conventional Memory. The only well-supported solutions were Expanded Memory Boards.
These were 8-bit ISA cards that typically could be populated with up to 2MB RAM. As the 8088 could not access more than 1MB of RAM directly, the Expanded Memory Specification (EMS by Lotus, Intel, Microsoft or LIM EMS) allowed programs that supported Expanded Memory to circumvent this limitation.
An Expanded Memory board took control of any unused 64KB segment of Upper Memory, which could point to a 64KB block (in 4 x 16KB slices) of RAM on the card. The programmer would access the control registers on the card to change the 64KB block and 16KB slice being accessed. Games would not use Expanded Memory until the 1990s, and by that time Expanded Memory Boards were almost obselete. (See below for the benefits, need and limitations of Expanded Memory).
II. 80286 PCs
When IBM released the IBM PC AT in 1984, it went fully 16-bit by utilizing the Intel 80286 processor. 286 machines were not affordable for the average consumer or gamer until 1987. The IBM PC used an 8088, which had an external 8-bit data bus. The IBM PC AT used a 286, which had a 16-bit external data bus. This meant that in almost all cases, 16-bit RAM would be required and new memory boards would be needed to add more RAM. The ISA bus for expansion cards and memory was also increased to 16-bit to accommodate the memory accesses from the 286.
The 286 had a 24-bit address bus, which allowed it to access 16MB of memory. However, to maintain compatibility with the IBM PC, the processor started up with the 8088's RAM addressing limitations. This was called "real mode", which meant that the 286 acted like a fast 8088/8086.
DOS was written for real mode and its memory limitations. In order to access the full 16MB of addressing capability, the processor had to enter "protected mode." To be compatible with the new mode, DOS would have had to be rewritten. As DOS did not need more than the 640KB of Conventional Memory available at the time, this was not done.
Moreover, in order to switch from protected mode to real mode, the processor had to undergo a soft reset. Protected mode, allowing multiple programs to be run at the same time by giving them their own memory to play with, was something of the future. DOS was a single-task operating system. IBM and Microsoft eyed newer operating systems like OS/2 and Windows to utilize multi-tasking capabilities.
The first memory configuration addition of the 286 machines was what would become known as Extended Memory. This was defined as any physical memory over and above the 1MB RAM limitation of real mode. In the early 286 systems, motherboards could hold up to 640KB of RAM. Extended Memory could be added with 16-bit ISA memory boards.
In later 80286 systems, the speed of the processor (10MHz and above) outpaced the speed of the bus (8.33MHz maximum), necessitating dedicated memory expansion slots, generally supporting 30-pin SIMMs. In PC and AT systems, memory boards could be accessed just as quickly as memory on the motherboard. However, as explained above, memory beyond the 640KB limit was not especially useful for DOS programs at the time. DOS games that ran on a 80286 would rarely, if at all, use Extended Memory. By the time DOS games began to use Extended Memory, the 286 was fast becoming obselete.
The second memory configuration addition of the 286 would become known as High Memory. In short, when the 286 operated in real mode, it was emulating the memory addressing characteristics of an 8088. The creators of the IBM PC AT discovered and exploited a bug that allowed the 286 to access the first 64KB (minus 16 bytes) of RAM beyond the 1MB limit when in real mode.
RAM was extremely expensive until the late 80s Since the computer needed more than 640KB of RAM installed, the extra 64KB (known as the High Memory Area or HMA) was not often available at the time. The 64KB segment could not be used by programs or games directly, being akin to an extension of the Upper Memory Area, but DOS could load part of itself into it, freeing up Conventional Memory.
When IBM released the AT, one important development was introduced in Upper Memory. The Upper Memory Area remained confined to peripheral card RAM, firmware, BIOS and BASIC ROM. However, IBM also introduced the Enhanced Graphics Adapter (EGA), which became a widely adopted graphics standard for games of the late 1980s.
EGA emulated either of its predecessors, MDA and CGA. EGA used the memory ranges of MDA or CGA for text modes, which DOS uses, and in CGA's case to emulate CGA graphics. This behavior was typically set by jumpers or dipswitches. If the card was emulating MDA or connected to a monochrome monitor, it would use the lower 32KB portion of the B0000-BFFFF segment; if it were emulating CGA or connected to a color monitor, it would use the upper 32KB portion of the B0000-BFFFF segment. EGA would not use both segments at the same time, which meant the 32KB not being used could be used for other purposes. EGA tended to be used on color monitors, making the upper 32KB portion of the B0000-BFFFF segment unavailable for other uses.
In addition to half of the B0000-BFFFF segment, EGA also utilized two other segments or a portion thereof. For its advanced graphics modes, EGA took over the entire 64KB segment of A0000-AFFFF. EGA also had a firmware BIOS of its own to handle all the new graphics capabilities and the emulation of the old, and this took usually the first 16KB of the C0000-CFFFF segment.
Games that ran on a 286 and could take advantage of Expanded Memory needed to have hardware EMS boards installed in the system. These EMS boards should have 16-bit RAM installed in them or there will be a severe performance penalty if the board uses 8-bit RAM.
III. 80386 and Beyond
The last major processor to have an impact on DOS Memory Configurations would be the Intel 80386. First used on Compaq machines, it really did not become available to the average PC gamer until 1990. The 386 in its DX variant had 32-bit addressing and data buses, allowing it to access 4GB of memory in protected mode. (I doubt there was a 386 board in which you could install more than 32MB at best). The SX variant was more popular and cheaper at the beginning, it had a 16-bit external/32-bit internal data bus (which meant 286 board designs could be used with few modifications) and a 24-bit addressing bus to access 16MB of memory.
The greatest advancement to DOS memory was the 386's Memory Management Unit, which allowed for very flexible memory configurations. And the games of the early 1990s quickly needed them. When 386 machines shipped, they often included more memory installed on the motherboard than the 640KB of the 286 machines. The 386 allowed the memory to be used to its fullest. The 386 could also freely switch between the various processor modes (real, protected, etc.) without a CPU reset.
The first thing that the 386 did was to allow programmers access to the RAM contained in the Upper Memory Area. In 286 machines, the RAM upgrades mapped themselves outside the Upper Memory Area because it was considered useless. Thus, physical RAM would be present in the 640KB Conventional Memory Area and 1MB and above in the Extended Memory Area. The cards would leave a memory hole in the Upper Memory Area, as there was no need. 386 motherboards did not leave a hole, which meant there was RAM present throughout in the Upper Memory Area to use. If there was something else in the Upper Memory Area, such as graphics card RAM, that portion of system RAM would be unavailable. If ROM was present, the 386 could copy the contents to the RAM also present at the same address, which allowed access to the "ROM" to become much faster. This is known as ROM Shadowing, enabled in the BIOS and there was seldom a good reason not to use it.
The Upper Memory Area was tricky to use, as there were certain areas of RAM that could be used and other areas that contained ROM or perhiperal card RAM and was therefore off-limits. It was up to the user to identify the segments or portions thereof in the Upper Memory Area that were useful and which were not. The user needed to consult the system and peripheral user manuals to figure out which segments were taken and which were available. Manuals were not always clear on this matter. Available segments of Upper Memory, typically B0000-B7FFF, CC000-CFFFF, D0000-DFFFF, E0000-EFFFF (which is often not available because the BIOS is in this area, IBM PS/2 machines are a good examples of this), are called Upper Memory Blocks (UMBs).
At this point, several devices were using up a lot of the Upper Memory Area. VGA was ubiquitous with 386 machines, and it used the same memory areas as EGA, with one exception. EGA cards generally used 16KB for their BIOS extensions, but VGA cards almost always used 32KB. This meant that the upper 32KB of the C0000-CFFFF segment was unusable as an Upper Memory Block. Hard Drive BIOS extension ROMs generally were 16KB at this time, generally taking the next 16KB of the C0000-CFFFF. Some BIOS ROMs, which had been 64KB in earlier systems, now were 128KB and took over the E0000-EFFFF segment (IBM PS/2s).
Games could not use Upper Memory directly. DOS could load itself into an available UMB, as could device drivers, which mice and CD-ROM drives required to be loaded in order to work in DOS. However, DOS and the drivers had to fit within a Upper Memory Block, they could not straddle blocks. The loading priority of DOS and drivers needed to be optimized in order to utilize UMBs effectively.
By the time of the 386, 640KB of RAM was no longer sufficient to run the latest games. Games relied on the operating system, and the standards were not yet in place to allow DOS games to access the megabytes of RAM directly that the 32-bit protected mode offered. So DOS games used multiple methods to access more than 640KB of RAM.
The most common method in the early 1990s was to use Expanded Memory. Due to its Memory Management Unit, the 386 did not need Expanded Memory Boards to use Expanded Memory, it emulated Expanded Memory through software using a portion of Extended Memory. Like the Expanded Memory Boards, the software-supplied Expanded Memory needed at 64KB UMB to act as a window or page frame for the Expanded Memory. Using the Expanded Memory Manager (EMM) in DOS 4.01 and above, the user could designate virtually all his Extended Memory as Expanded Memory. Expanded Memory could be slow and was cumbersome to use as the programmer could only access 64KB at a time.
The next method was to use extended memory directly through DOS. One way to do this was through the eXtended Memory Specification (XMS), which Microsoft provided in DOS to give a method to access extended memory for code. To enable extended memory in this way, an eXtended Memory Manager (XMM) was required to be loaded in DOS. XMM would also enable HMA for DOS and driver loading. The other method was to use the processor to enter Unreal Mode, which allowed the processor to access 32-bit data segments instead of the 16-bit data segments of real mode. Each method allowed a game or program to use extended memory for storing data, but not for running executable code.
IV. 32-bit DOS Extenders
In the mid 1990s, DOS games were progressing so greatly that the kludges described above to enable them to work with 640KB of RAM just were no longer feasible. A game like DOOM, with its 2.5D spacial rendering required a more flexible memory arrangement than Expanded Memory or the various methods to use Extended Memory. Microsoft developed the DOS Protected Mode Interface (DPMI) to allow Windows 3.0 to use 16-bit DOS services and programs while in Protected Mode. There is also the Virtual Program Control Interface (VPCI) that does the same thing. Programs using one of these interfaces were called DOS Extenders.
DOS Extenders were great. They came with the game and allowed it to access extended memory in protected mode, which meant all the extended memory in the system was available for use. In DOS, which is a single task operating system, this meant virtually all the system memory was available to the program. The limit was only the amount of memory installed in the system. Unfortunately, DOS extenders were not always compatible with Windows 3.x or 9x. No more need for Expanded Memory, since Protected Mode memory access was infinitely more preferable. Extended Memory could be used for code, data or anything else memory could be used for. The extender did all the configuring. When you see files with names like DOS4GW.EXE, CWSDPMI.EXE or DOS32A.EXE in your game's directory, then you can be sure that it is using a 32-bit DOS Extender.
Another benefit was that the games using extenders did not need as much conventional memory free as games of a similar vintage that did not use an extender. Typically, a technologically advanced game from the mid 90s might require something like 590K free. When the limit is 640K and device drivers to load, that becomes a real issue. A game with a DOS extender may only require 520K, which is much easier to achieve.
V. Configuring Memory in DOS
Now that I have given a historical overview of the various DOS memory schemes, I would now turn to how we actually configure DOS to utilize the memory most effectively. Memory configuration begins with the config.sys file. When DOS starts, it loads the parameters from this file first.
The first parameter to be loaded is HIMEM.SYS. In fact, in Windows 9x versions of DOS (7.0-7.1), this is loaded automatically. HIMEM.SYS does three things: 1. It allows DOS access to the High Memory Area; 2. It loads DOS into the High Memory Area, freeing up to 64K of Conventional Memory that would otherwise be gone for DOS services. 3. It functions as an XMM allowing DOS programs to access Extended Memory. HIMEM.SYS is useless unless the system has a 286 or better processor and memory above 1MB. Loading this parameter is essentially harmless for almost any DOS game. The line in your config.sys will be:
"DEVICE=C:\DOS\HIMEM.SYS"
The second parameter, which is often loaded, is EMM386.EXE. This is the MS-DOS version of an EMM. It uses the Memory Management Unit of a 386 or better processor to emulate the functionality of Expanded Memory with Extended Memory. It will allocate as much expanded memory as your game needs. Many game require this to be loaded in config.sys. More importantly, it allows DOS to load itself and other drivers into the UMA. Through its parameters, it can specify the areas in which to create Upper Memory Blocks. EMM386.EXE requires HIMEM.SYS to be loaded first. It does not work on a 286 or lesser processor.
Some games may refuse to run if they detect an EMM in the system. The principal reason is that EMM386.EXE puts the processor into Virtual 8086 Mode. The 386 and better processors use Virtual 8086 Mode to allow DOS to access protected mode features while maintaining a real-mode like environment for each program for compatibility. EMM386.EXE puts the processor into Virtual 8086 Mode, which would be great if all DOS games were well-behaved. If they are not, such as using Unreal Mode, then EMM386.EXE cannot be loaded.
Here are two typical lines in your config.sys in which to configure EMM386.EXE:
"DEVICE=C:\DOS\EMM386.EXE RAM"
This line enables Expanded Memory emulation and UMBs. It aslo robs you of a 64KB UMB, so you should only use it if your games requires it.
"DEVICE=C:\DOS\EMM386.EXE NOEMS"
This line enables UMBs but not Expanded Memory. This frees up 64KB of UMBs for loading DOS or device drivers.
Those are the basic lines. However, if you can discover exactly which areas of upper memory are free, you should use the following switches to designate the range: I= (include) or X= (exclude). You can string as many areas as you may need:
I=B000-B7FF I=CC00-CFFF I=D000-DFFF I=E000-EFFF
All ranges are in hexidecimal and refer only to the memory segment, the offset is always 0000. Thus our preferred line will be:
"DEVICE=C:\DOS\EMM386.EXE NOEMS I=B000-B7FF I=CC00-CFFF I=D000-DFFF I=E000-EFFF"
Next time, I intend to give a comprehensive overview of config.sys and autoexec.bat
0 comments:
Post a Comment