1. 18
    1. 4

      Hi all! I mentioned in a couple of the “What are you doing…” threads that I was writing a post on memory management in the DOS days. It sounded like there were a handful of people interested based on upvotes and comments, so I’m sharing the finished article now :)

      A lot of the content in here is stuff I did not know about from before (I was very familiar with real mode vs. protected mode, for example, but I had never read on the differences between EMS, XMS, and HMA) – so I had to do some research and write this with fresh knowledge. There may be some inaccuracies because I had to piece various other documents together, so if you have corrections, please share. I also had to omit many details to keep this constrained in length, and it’s already way too long.

      Lastly, this feels in context based on the article that showed up yesterday on x86_64 memory paging (https://lobste.rs/s/iafplb/understanding_x86_64_paging). This one on real mode is “the opposite end” of the story!

      1. 2

        This brings back memories! I never really understood what I was doing with my AUTOEXEC.BAT and CONFIG.SYS, just that if I didn’t do it my games wouldn’t work. It’s great fun to read this now, after decades as a software engineer who no longer has time to play games :)

        1. 2

          Right? I remember running MemMaker and taking advantage of DOS 6’s boot menus to enable/disable drivers… but it was mostly black magic. I never stopped to understand all these details, and I found it fascinating to do so while writing this piece.

      2. 2

        Another thorn in the PC side was the A20 gate “required” to run MS-DOS on 80286s (which could address 16MB of physical memory). The issue was software that relied upon memory wrapping around the 1MB boundary, but amusingly enough, I think the only software that relied on that was … MS-DOS itself! To remain compatible (somewhat) with CP/M. Sigh.

        1. 1

          http://www.os2museum.com/wp/who-needs-the-address-wraparound-anyway/ goes into details on this. Does anybody know of any program in the wild that actually used call 5. I assume that there must have been at least a few in the early days that were the result of running a program through one of the 8080 to 8086 translators. Maybe those programs got quickly displaced by native ones so that there are no examples left to easily find?

        2. 1

          I could have sworn that I once used loadhigh on a 286. The article seems to suggest that doing this without emm386.exe is not possible but emm386.exe won’t work on a 286 so I couldn’t have been using that. Maybe I’m misremembering? Or maybe I had a third-party driver to make this work?

          I think I was overlaying the monochrome text video memory at B000-B7FF. That worked fine as long as you never switched into monochrome text video mode. If you ever did then your PC would crash. This worked without remapping any RAM from extended memory since there was already memory at that address.

          I was kind of hoping for some mention of the Extended BIOS Data Area. But if you’re only going to mention the BIOS Data Area in one sentence then it probably doesn’t make sense to spend time talking about the XBDA.

          The memory map reserved two chunks of the address space for video: one for monochrome displays and one for color displays. But only one of them can be in use at any given time.

          I don’t think this is strictly true. It was possible to have both a CGA card and an MDA card in a single machine with a monitor connected to each. This was useful for programmers who could have a program under development running on the CGA card and use the MDA card to show a debugger at the same time. Early multi-monitor support!

          You have a small typo: “When UBMs are available…”

          1. 1

            I think you may be right. In principle, UMBs could be offered by the chipset or other hardware given the right drivers, and I think I read a note on that in my research. But then I couldn’t find more details so I chose to simplify the story in the post. Would love to know more though!

            Will fix the typo tomorrow. Thanks.

            1. 1

              I could have sworn that I once used loadhigh on a 286.

              With stock DOS, be it MS-DOS, PC DOS or DR DOS, it was impossible.

              But there were a handful of relatively expensive specialist memory managers that only worked on specific 80286 motherboard chipsets which could use the chipset (rather than the CPU) to map UMBs on 286s. I never saw a single one in a decade in the DOS industry but I read about them.

              The best known was from the vendors of 386Max (now GPL!) and it was called BlueMax, because it only ran on 286 IBM PS/2 machines. “Big Blue” -> Blue Max, geddit?

              1. 1

                Yes one could, but it was chipset specific, and specific chipset drivers were available to link UMB’s in to the chain. This seems to mention a few:

                https://retrocomputing.stackexchange.com/questions/7785/what-286-chipsets-support-umbs

                Err - from memory, the monochome memory was 64k from A000, the colour 64k from B000, and the colour text mode started at B800. So (pre DOS 5/6), one could claw back 96k before the the text (CGA/EGA/VGA) region.

                Yes, one could use both cards at the same time (or 2 VGAs, one in mono mode). I’d often use that form when debugging, especially device drivers, as one could be used for simple direct logging via memory writes, w/o affecting the use of the other.

                As to load high without specific DOS (or driver support), that was easy. Link the UMBs in to the main chain, use the Int 21 call to change the memory allocation strategy to “last fit”, then load the program. However many TSRs had their own ability to relocate themselves, assuming the chains were linked, and the system was still in “first fit” mode.

                Usage did rather change once DR-DOS (then MS-DOS) got the ability to relocate the major portion of their code in to UMBs, and the choice of what to juggle where was altered.

                1. 3

                  EGA/VGA graphics mode address space was 64K from A000-AFFF. MDA (monochrome) text mode address space was 32K from B000-B7FF. CGA address space was 32K from B800-BFFF, used for both text and graphics modes. These latter two ranges were designed to not overlap so that you could have both a CGA and an MDA card in a single machine at the same time with no conflicts. I think this also worked when combining an EGA card with an MDA card.

                  VGA was mostly backward compatible with CGA and had some limited MDA support so a VGA card would have memory at the entire region A000-BFFF. If you limited yourself to just CGA modes then you’d only be using B800-BFFF and all of A000-B7FF would be available. But making it into regular conventional memory was complicated by the XBDA that lived just below A000, putting an inconvenient hole in the middle of your free space. And there were probably also a few programs that would get confused if they saw more than 640K of available conventional memory.

                  I liked to play games and those would use VGA graphics modes and thus would need A000-AFFF. And totally avoiding 80x25 color text mode was basically impossible so that meant that B800-BFFF was also in use. But B000-B7FF was only used for MDA monochrome text modes and basically nothing used those so this space was very convenient to use as a UMB.

                  1. 1

                    You’re correct, I misremembered where the MDA area was.

                    However many early clones simply simply did not have an Extended BIOS Data Area (like the one I used in 1990), or when such started appearing, had a BIOS option to relocate it to low memory. Hence there was no impediment having the main memory region grow beyond 640k.

                    As to program now liking it, possibly. At the time, we were mainly using text mode, CLI based development tools, and they relished the extra memory. My first machine at work had an MDA, so I reclaimed the A000 region, I eventually got a colour card in it, and the reclaimed the next 32k.

                    Some colleagues had 386sx machines with 1M of RAM, once I got one I was able to add UMB’s, and move various things there, so gaining an even larger TPA.

                    1. 1

                      MDA (monochrome) text mode address space was 32K from B000-B7FF.

                      Yup. I fairly routinely used

                      device=c:\dos\emm386.exe ram frame=none I=b000-b7ff 
                      

                      … to use that mono space, unneeded on a colour machine, and enable EMS for disk caching etc. without dedicating a 64kB UMB to the page frame. It usually worked on almost all machines.