8

How do you access more memory (above the 1MB) in DOS if the 640KB of conventional memory are not enough?

I have read a lot about this, but I couldn't figure out how to do this in actual code. Is there an API for this (like HIMEM.SYS), or can I code it myself? Any answer is fine, whether it uses the XMS or the EMS standard or manually written code. From what I read, though, EMS requires specialized hardware, which is not very convenient.

If you can, please also explain if there are any differences between doing it on an Intel 80286 or an Intel 80386. Does it necessarily require switching to protected mode?

  • 3
    The question is way to broad as it stands. There are various extenders and API and they do differ for 286 as well 386 and above, as do the ways to do it without. Answering this thruout would require a whole tour about memory management, which is past what the stack exchange format can do. Please narrow this down to a concrete issue (what you want to do), environment (OS, extenders) and platform (286, 386, ...) – Raffzahn Mar 21 at 18:02
  • 2
    @BrianH you are confusing expanded memory (EMS) with extended memory (XMS). 8088/8086 have no XMS, but 286/386 have XMS. – Justme Mar 21 at 19:44
  • 1
    @Raffzahn I think it's safe to assume that the OP may not well understand the details of XMS vs. EMS etc. (I certainly can't even remember which is which off-hand.) Rather than declaring the question "too broad" and sending people to other sites for the information they need, just write an answer that gives a high-level overview of what one needs to know about using "more memory than the first megabyte" under DOS. Then we end up with a useful answer instead of just a dead question. – cjs Mar 22 at 0:23
  • 1
    @cjs Please do not start meta discussions (that is about what someone means or someone else got to do) on the main site. This is not adequate here. – Raffzahn Mar 22 at 0:33
  • 2
    @DarkAtom Oh, no problem; just edit the question to explain that more clearly, then! That will encourage alternative answers that you (and others following this question) might find more convenient. – cjs Mar 22 at 11:51
10

The eXtended Memory Specification (XMS) 2.0 may be found here and the 3.0 version here. The various function calls are invoked by obtaining the driver's entry point via the muxing interrupt (Int 2Fh). XMS allows for accessing both extended (above the 1MB boundary) and high memory areas.

XMS works much like the original Windows 16-bit memory management: When your program allocates extended memory, XMS returns a handle rather than a pointer to the block. To use the memory, your program calls XMS to lock the handle, which returns a pointer to use. When your program is finished accessing the memory, it should unlock the block, which allows the memory manager to move it in memory without disturbing its contents. You can also move memory blocks between conventional and extended memory without locking the handle.

To answer your other questions: No, there are no differences using XMS on 80286 and 80386 (although as with all things DOS, it's never so simple, such as if your program needs access to the physical pages), and no, your program does not need to switch to Protected Mode to use XMS.

| improve this answer | |
  • 2
    To add to this, the lock/unlock design pattern means that you must forget any pointers to anything in XMS memory when you unlock it. Failing to do so was a common programming problem on 16-bit Windows, and Classic Mac OS, which are quite similar in this respect. 32-bit Windows and Mac OS X both abandoned that idea as far more trouble than it was worth, given a larger address space. – John Dallman Mar 21 at 20:44
  • 1
    XMS extended memory doesn't have to be locked to use it. Indeed some XMMs do not even allow locking extended memory blocks. The idiomatic way of accessing XMS extended memory is by filling an XMS memory move structure to transfer data between 86-Mode memory and an extended memory block, or between two extended memory blocks. Locking is only useful to a. access memory in protected mode or b. use it for device DMA or such. – ecm Mar 22 at 12:09
5

Before the 286, x86 CPUs can only access 1MiB, so the only way to use memory beyond 1MiB is to use some form of bank switching. The de facto standard for that is Lotus/Intel/Microsoft EMS, which provides access to expanded memory by switching into a “page frame” (typically located in the UMA, between 640KiB and 1MiB). EMS requires hardware on CPUs before the 386, but many 286 chipsets provide support (along with the appropriate driver). On 386 and later, drivers such as EMM386.EXE provide expanded memory. The EMS API is available via interrupt 67h, services 40h to 5Dh. See the full specification for details.

On the 286 and above, the XMS API (implemented for example by HIMEM.SYS) provides access to extended memory, along with UMBs and the HMA. For real mode programs, this is used by copying blocks of memory from conventional to extended and back. The XMS API is accessed through a control function; first use interrupt 2Fh service 00h to check whether XMS is available, then service 10h to obtain the control function’s address. See the full specification for details.

286 PCs introduced another API, provided by the BIOS, which is less often encountered in practice: interrupt 15h, service 87h copies memory specified by 24-bit linear addresses (so it can be used to copy conventional to extended and back, but also extended to extended, or conventional to conventional). Memory can be “allocated” by reducing the amount returned by service 88h which indicates the size of extended memory; this is how the VDISK.SYS RAM drive allocates memory for its drives (when extended memory is available).

On the 286 and later, it is also possible to switch to protected mode (using an API such as DPMI, or not) and access extended memory directly, but it’s important to still use APIs to allocate memory. Another approach is to use LOADALL. Many large DOS programs use a DOS extender, which takes care of handling all that for them.

| improve this answer | |
  • Oh, I remember the days of the AST RAMpage paged RAM card. What a pain in the behind all those workarounds were :) – Scott Earle Mar 23 at 1:56
3

The HIMEM.SYS is the driver which provides an API that complies with the XMS specification for you to allocate extended memory and move data between conventional memory and extended memory. The XMS specification can be found very easily. Accessing extended memory via XMS driver does not require any protected mode programming from the user and extended memory is used via the API identically regardless of CPU type, it is the XMS driver itself that must work differently on 286 and 386 CPUs.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.