Category : Recently Uploaded Files
Archive   : PCGPE.ZIP
Filename : LIMEMS41.DOC

 
Output of file : LIMEMS41.DOC contained in archive : PCGPE.ZIP


The associated file (LIMEMS41.DOC) is a complete transcription of
the Lotus/Intel/Microsoft (LIM) Expanded Memory Specification
(EMS) Version 4.0, updated October 1987. It can be printed by
"COPY LIMEMS41.DOC PRN:"

I created this transcription because of the difficulty I origin-
ally had finding a copy of the document, because of the number of
people who have subsequently expressed an interest in having
access to a machine-readable copy of the specification, and,
finally, because of the annoying number of typographical errors
contained in the original and updated documents.

This transcription is not an exact letter-for-letter duplicate of
the original document. Some minor changes were necessitated by
the simple fact that the document's proportionally-spaced, multi-
fonted typography and line drawings did not lend themselves to
the generic fixed-spacing, single-fonted, non-graphical ASCII
transcription I wanted to produce for general dissemination.

Other minor changes were made to correct obvious typographical
and grammatical errors, or to simply improve the visual aes-
thetics of the presented material.

In one area, however, I simply trashed their original material
and substituted my own. This area is the Index. The original
document contains an Index that is little more than a reformatt-
ing of the Table of Contents. As anyone who has ever indexed a
large document knows, it is very difficult to produce an Index
that is both complete AND easy to use. I didn't have time to
produce one that was both, so I aimed for the former. In fact,
the Index I have provided is more of an alphabetical listing of
key words and phrases and the pages where they are referenced,
than it is a more typical Index with its multi-level headings and
subheadings.

You should be able obtain a printed, 3-hole-punched, 5.5 x 8.5"
copy of the original (and uncorrected) document directly from
Intel by calling their "Information Department" at 1-800-538-3373
and asking for a copy of the "LIM EMS 4.0 Developer's Kit." It
is available free of charge and mine arrived in about two weeks.
(European availability, however, is reported to be from poor to
non-existent.)

It is my intent to provide this transcription as a public
service. I am, therefore, releasing it into the public domain.
The original document has also been released into the public
domain by Lotus, Intel, and Microsoft, though it remains their
copyrighted property (I'm not quite sure how they manage to do
that).

I have tried as best I can to provide an accurate and corrected
transcription of the original document. It is inevitable,
however, that some typographical errors have slipped through in
spite of my hours of bleary-eyed proof reading. For these errors
I apologize and plead simple human frailty.

THIS TRANSCRIPTION IS PROVIDED WITHOUT ANY GUARANTEES
OR WARRANTIES OF ANY KIND, AND I ASSUME ABSOLUTELY NO
LIABILITY FOR ITS ACCURACY, CONTENT, OR SUBSEQUENT USE.

Dick Flanagan, W6OLD, Ben Lomond, California November 1987











LOTUS(R)/INTEL(R)/MICROSOFT(R)

EXPANDED MEMORY SPECIFICATION [1]












Version 4.0
300275-005
October, 1987












Copyright (C) 1987

Lotus Development Corporation
55 Cambridge Parkway
Cambridge, MA 02142

Intel Corporation
5200 NE Elam Young Parkway
Hillsboro, OR 97124

Microsoft Corporation
16011 NE 35th Way
Box 97017
Redmond, WA 98073


[1] Transcribed into machine-readable form by Dick Flanagan,
Ben Lomond, California. This transcription is released into the
public domain without warranty or assumption of liability.





This specification was jointly developed by Lotus Develop-
ment Corporation, Intel Corporation, and Microsoft Corpora-
tion. Although it has been released into the public domain
and is not confidential or proprietary, the specification is
still the copyright and property of Lotus Development
Corporation, Intel Corporation, and Microsoft Corporation.


DISCLAIMER OF WARRANTY

LOTUS DEVELOPMENT CORPORATION, INTEL CORPORATION, AND MICRO-
SOFT CORPORATION EXCLUDE ANY AND ALL IMPLIED WARRANTIES,
INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. NEITHER LOTUS NOR INTEL NOR MICROSOFT
MAKE ANY WARRANTY OF REPRESENTATION, EITHER EXPRESS OR
IMPLIED, WITH RESPECT TO THIS SPECIFICATION, ITS QUALITY,
PERFORMANCE, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR
PURPOSE. NEITHER LOTUS NOR INTEL NOR MICROSOFT SHALL HAVE
ANY LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES ARISING OUT OF OR RESULTING FROM THE USE OR MODIF-
ICATION OF THIS SPECIFICATION.



This specification uses the following trademarks:

Intel is a trademark of Intel Corporation
Lotus is a trademark of Lotus Development Corporation
Microsoft is a trademark of Microsoft Corporation
























ii





CONTENTS



Chapter 1
INTRODUCTION
What is Expanded Memory? . . . . . . . . . . . . . . . . . 1
How Expanded Memory Works . . . . . . . . . . . . . . . . 1

Chapter 2
WRITING PROGRAMS THAT USE EXPANDED MEMORY
What Every Program Must Do . . . . . . . . . . . . . . . . 4
Advanced Programming . . . . . . . . . . . . . . . . . . . 5
Saving The State of Mapping Hardware . . . . . . . . . . 6
Retrieving Handle and Page Counts . . . . . . . . . . . 6
Mapping and Unmapping Multiple Pages . . . . . . . . . . 6
Reallocating Pages . . . . . . . . . . . . . . . . . . . 6
Using Handles and Assigning Names to Handles . . . . . . 6
Using Handle Attributes . . . . . . . . . . . . . . . . 7
Altering Page Maps and Jumping/Calling . . . . . . . . . 7
Moving or Exchanging Memory Regions . . . . . . . . . . 7
Getting the Amount of Mappable Memory . . . . . . . . . 8
Operating System Functions . . . . . . . . . . . . . . . 8
Programming Guidelines . . . . . . . . . . . . . . . . . . 12
Examples . . . . . . . . . . . . . . . . . . . . . . . . . 14
Example 1 . . . . . . . . . . . . . . . . . . . . . . . 14
Example 2 . . . . . . . . . . . . . . . . . . . . . . . 19
Example 3 . . . . . . . . . . . . . . . . . . . . . . . 30
Example 4 . . . . . . . . . . . . . . . . . . . . . . . 32

Chapter 3
EMM FUNCTIONS
Function 1. Get Status . . . . . . . . . . . . . . . . . . 37
Function 2. Get Page Frame Address . . . . . . . . . . . . 38
Function 3. Get Unallocated Page Count . . . . . . . . . . 40
Function 4. Allocate Pages . . . . . . . . . . . . . . . . 42
Function 5. Map/Unmap Handle Pages . . . . . . . . . . . . 46
Function 6. Deallocate Pages . . . . . . . . . . . . . . . 49
Function 7. Get Version . . . . . . . . . . . . . . . . . 51
Function 8. Save Page Map . . . . . . . . . . . . . . . . 53
Function 9. Restore Page Map . . . . . . . . . . . . . . . 55
Function 10. Reserved . . . . . . . . . . . . . . . . . . 57
Function 11. Reserved . . . . . . . . . . . . . . . . . . 58
Function 12. Get Handle Count . . . . . . . . . . . . . . 59
Function 13. Get Handle Pages . . . . . . . . . . . . . . 61
Function 14. Get All Handle Pages . . . . . . . . . . . . 63
Function 15. Get/Set Page Map . . . . . . . . . . . . . . 65
Get Page Map subfunction . . . . . . . . . . . . . . . . 65
Set Page Map subfunction . . . . . . . . . . . . . . . . 67
Get & Set Page Map subfunction . . . . . . . . . . . . . 69
Get Size of Page Map Save Array subfunction . . . . . . 71


iii





Function 16. Get/Set Partial Page Map . . . . . . . . . . 73
Get Partial Page Map subfunction . . . . . . . . . . . . 73
Set Partial Page Map subfunction . . . . . . . . . . . . 76
Get Size of Partial Page Map Save Array subfunction . . 78
Function 17. Map/Unmap Multiple Handle Pages . . . . . . . 80
Mapping Multiple Pages . . . . . . . . . . . . . . . . . 80
Unmapping Multiple Pages . . . . . . . . . . . . . . . . 80
Mapping and Unmapping Multiple Pages Simultaneously . . 80
Alternate Mapping and Unmapping Methods . . . . . . . . 81
Logical Page/Physical Page Method . .OF THE EXPANDED MEMORY MANAGER
Which method should your program use? . . . . . . . . . . 199
The "open handle" technique . . . . . . . . . . . . . . . 199
The "get interrupt vector" technique . . . . . . . . . . . 204

Appendix C
EXPANDED MEMORY MANAGER IMPLEMENTATION GUIDELINES
The amount of expanded memory supported . . . . . . . . . 206
The number of handles supported . . . . . . . . . . . . . 206
Handle Numbering . . . . . . . . . . . . . . . . . . . . . 206
New handle type: Handles versus Raw Handles . . . . . . . 206
The system Raw Handle (Raw Handle = 0000h) . . . . . . . . 207
Terminate and Stay Resident (TSR) Program Cooperation . . 208
Accelerator Cards . . . . . . . . . . . . . . . . . . . . 208

Appendix D
OPERATING SYSTEM/ENVIRONMENT USE OF FUNCTION 28
Examples . . . . . . . . . . . . . . . . . . . . . . . . . 209
Example 1 . . . . . . . . . . . . . . . . . . . . . . . 209
Example 2 . . . . . . . . . . . . . . . . . . . . . . . 210
Example 3 . . . . . . . . . . . . . . . . . . . . . . . 211

GLOSSARY

INDEX















v





Chapter 1
INTRODUCTION


Because even the maximum amount (640K bytes) of conventional
memory isn't always enough for large application programs,
Lotus Development Corporation, Intel Corporation, and Micro-
soft Corporation created the Lotus/Intel/Microsoft (LIM)
Expanded Memory Specification.

The LIM Expanded Memory Specification defines the software
interface between the Expanded Memory Manager (EMM) -- a
device driver that controls and manages expanded memory --
and application programs that use expanded memory.


What is Expanded Memory?

Expanded memory is memory beyond DOS's 640K-byte limit. The
LIM specification supports up to 32M bytes of expanded
memory. Because the 8086, 8088, and 80286 (in real mode)
microprocessors can physically address only 1M bytes of
memory, they access expanded memory through a window in
their physical address range. The next section explains how
this is done.


How Expanded Memory Works

Expanded memory is divided into segments called logical
pages. These pages are typically 16K bytes of memory. Your
computer accesses logical pages through a physical block of
memory called a page frame. The page frame contains
multiple physical pages, pages that the microprocessor can
address directly. Physical pages are also typically 16K
bytes of memory.

This page frame serves as a window into expanded memory.
Just as your computer screen is a window into a large
spreadsheet, so the page frame is a window into expanded
memory.

A logical page of expanded memory can be mapped into (made
to appear in) any one of the physical pages in the page
frame. Thus, a read or write to the physical page actually
becomes a read or write to the associated logical page. One
logical page can be mapped into the page frame for each
physical page.

Figure 1-1 shows the relationship among the page frame,
physical pages, and logical pages.


Introduction 1





32M +--------------+
/| |
| |
/ | |
| |
/ | |
| |
/ | |
| Expanded |
/ | Memory |
1024K +--------------+ | |
| / / / / / / | / | |
960K +--------------+ | |
| Page Frame | | |
| | | |
| 12 16K-Byte | | |
| Physical | | |
| Pages | | |
768K +--------------+ | Divided into |
| / / / / / / | \ | logical |
640K +--------------+ | pages |
| | \ | |
| | | |
| | \ | |
| | | |
| 24 16K-Byte | \ | |
| Physical | | |
| Pages* | \ | |
| | | |
| | \ | |
| | | |
| | \ | |
256K +--------------+ | |
| | \ | |
| / / / / / / | | |
| | \ | |
| / / / / / / | | |
| | \ | |
| / / / / / / | | |
| | \ | |
0 +--------------+ | |
\ | |
| |
*Intended for operating \ | |
system/environment use only 0 +--------------+



Figure 1-1. Expanded Memory




Introduction 2





The page frame is located above 640K bytes. Normally, only
video adapters, network cards, and similar devices exist
between 640K and 1024K.

This specification also defines methods for operating
systems and environments to access expanded memory through
physical pages below 640K bytes. These methods are intended
for operating system/environment developers only.














































Introduction 3





Chapter 2
WRITING PROGRAMS THAT USE EXPANDED MEMORY


This chapter describes what every program must do to use
expanded memory and describes more advanced techniques of
using expanded memory.

This chapter also lists programming guidelines you should
follow when writing programs that use expanded memory and
provides the listings of some example programs.


What Every Program Must Do

This section describes the steps every program must take to
use expanded memory.

In order to use expanded memory, applications must perform
these steps in the following order:

1. Determine if EMM is installed.

2. Determine if enough expanded memory pages exist for your
application. (Function 3)

3. Allocate expanded memory pages. (Function 4, 18, or 27)

4. Get the page frame base address. (Function 2)

5. Map in expanded memory pages. (Function 5 or 17)

6. Read/write/execute data in expanded memory, just as if
it were conventional memory.

7. Return expanded memory pages to expand memory pool
before exiting. (Function 6 or 18)

Table 2-1 overviews the functions while Chapter 3 describes
each of these functions in detail. Example programs at the
end of this chapter illustrate using expanded memory.












Writing Programs That Use Expanded Memory 4





Table 2-1. The Basic Functions
----------------------------------------------------------------

Function Description

----------------------------------------------------------------

1 The Get Status Function returns a status code
indicating whether the memory manager hardware is
working correctly.

2 The Get Page Frame Address function returns the
address where the 64K-byte page frame is located.

3 The Get Unallocated Page Count function returns the
number of unallocated pages (pages available to your
program) and the total number of pages in expanded
memory.

4 The Allocate Pages function allocates the number of
pages requested and assigns a unique EMM handle to
these pages.

5 The Map/Unmap Handle Page function maps a logical
page to a specific physical page anywhere in the
mappable regions of system memory.

6 The Deallocate Pages deallocates the logical pages
currently allocated to an EMM handle.

7 The Get Version function returns the version number
of the memory manager software.

----------------------------------------------------------------



Advanced Programming

In addition to the basic functions, the Lotus/Intel/Micro-
soft Expanded Memory Specification provides several advanced
functions which enhance the capabilities of software that
uses expanded memory.

The following sections describe the advanced programming
capabilities and list the advanced EMM functions.


Note............................................................
Before using the advanced functions, programs should first
call Function 7 (Get Version) to determine whether the
installed version of EMM supports these functions.

Writing Programs That Use Expanded Memory 5





Saving The State of Mapping Hardware

Some software (such as interrupt service routines, device
drivers, and resident software) must save the current state
of the mapping hardware, switch mapping contexts, manipulate
sections of expanded memory, and restore the original
context of the memory mapping hardware. Use Functions 8 and
9 or 15 and 16 to save the state of the hardware.


Retrieving Handle and Page Counts

Some utility programs need to keep track of how expanded
memory is being used; use Functions 12 through 14 to do
this.


Mapping and Unmapping Multiple Pages

Mapping multiple pages reduces the overhead an application
must perform during mapping. Function 17 lets a program map
(or unmap) multiple pages at one time.

In addition, you can map pages using segment addresses
instead of physical pages. For example, if the page frame
base address is set to D000, you can map to either physical
page 0 or segment D000. Function 25 (Get Mappable Physical
Address Array) returns a cross reference between all
expanded memory physical pages and their corresponding
segment values.


Reallocating Pages

Reallocating pages (Function 18) lets applications dynami-
cally allocate expanded memory pages without acquiring
another handle or obtain a handle without allocating pages.
Reallocating pages is an efficient means for applications to
obtain and release expanded memory pages.


Using Handles and Assigning Names to Handles

This specification lets you associate a name with a handle,
so a family of applications can share information in
expanded memory. For example, a software package consisting
of a word processor, spreadsheet, and print spooler can
share the same data among the different applications. The
print spooler could use a handle name to reference data that
either the spreadsheet or word processor put in expanded
memory and could check for data in a particular handle
name's expanded memory pages.

Writing Programs That Use Expanded Memory 6





Use Function 20 (Set Handle Name subfunction) to assign a
handle name to an EMM handle or Function 21 (Search for
Named Handle subfunction) to obtain the EMM handle as-
sociated with the handle name. In addition, you can use
Function 14 (Get Handle Pages) to determine the number of
expanded memory pages allocated to an EMM handle.


Using Handle Attributes

In addition to naming a handle, you can use Function 19 to
associate an attribute (volatile or non-volatile) with a
handle name. A non-volatile attribute enables expanded
memory pages to preserve their data through a warmboot.
With a volatile attribute, the data is not preserved. The
default attribute for handles is volatile.

Because using this function depends on the capabilities of
the expanded memory hardware installed in the system, you
should use the Get Attribute Capability subfunction before
attempting to assign an attribute to a handle's pages.


Altering Page Maps and Jumping/Calling

You can use Functions 22 (Alter Page Map & Jump) and 23
(Alter Page Map & Call) to map a new set of values into the
map registers and transfer program control to a specified
address within expanded memory. These functions can be used
to load and execute code in expanded memory. An application
using this feature can significantly reduce the amount of
conventional memory it requires. Programs can load needed
modules into expanded memory at run time and use Functions
22 and 23 to transfer control to these modules.

Using expanded memory to store code can improve program
execution in many ways. For example, sometimes programs
need to be divided into small overlays because of conven-
tional memory size limitations. Overlays targeted for
expanded memory can be very large because LIM EMS 4.0
supports up to 32M bytes of expanded memory. This method of
loading overlays improves overall system performance by
conserving conventional memory and eliminating conventional
memory allocation errors.


Moving or Exchanging Memory Regions

Using Function 24 (Move/Exchange Memory Region), you can
easily move and exchange data between conventional and
expanded memory. Function 24 can manipulate up to one
megabyte of data with one function call. Although applica-

Writing Programs That Use Expanded Memory 7





tions can perform this operation without this function,
having the expanded memory manager do it reduces the amount
of overhead for the application.

In addition, this function checks for overlapping regions
and performs all the necessary mapping, preserving the
mapping context from before the exchange/move call.


Getting the Amount of Mappable Memory

Function 25 enables applications to determine the total
amount of mappable memory the hardware/system currently
supports. Not all expanded memory boards supply the same
number of physical pages (map registers).

The Get Mappable Physical Address Array Entries subfunction
returns the total number of physical pages the expanded
memory hardware/system is capable of supporting. The Get
Mappable Physical Array subfunction returns a cross refer-
ence between physical page numbers and the actual segment
address for each of the physical pages.


Operating System Functions

In addition to the functions for application programs, this
specification defines functions for operating systems/en-
vironments. These functions can be disabled at any time by
the operating system/environment, so programs should not
depend on their presence. Applications that avoid this
warning and use these functions run a great risk of being
incompatible with other programs, including the operating
system.



















Writing Programs That Use Expanded Memory 8





Table 2-2. The Advanced Functions
----------------------------------------------------------------

Function Description

----------------------------------------------------------------

8 The Save Page Map saves the contents of the page
mapping registers from all expanded memory boards in
an internal save area.

9 The Restore Page Map function restores (from an
internal save area) the page mapping register
contents on the expanded memory boards for a
particular EMM handle.

10 Reserved.

11 Reserved.

12 The Get Handle Count function returns the number of
open EMM handles in the system.

13 The Get Handle Pages function returns the number of
pages allocated to a specific EMM handle.

14 The Get All Handle Pages function returns an array
of the active EMM handles and the number of pages
allocated to each one.

15 The Get/Set Page Map subfunction saves or restores
the mapping context for all mappable memory regions
(conventional and expanded) in a destination array
which the application supplies.

16 The Get/Set Partial Page Map subfunction provides a
mechanism for saving a partial mapping context for
specific mappable memory regions in a system.

17 The Map/Unmap Multiple Handle Pages function can, in
a single invocation, map (or unmap) logical pages
into as many physical pages as the system supports.

18 The Reallocate Pages function can increase or
decrease the amount of expanded memory allocated to
a handle.

19 The Get/Set Handle Attribute function allows an
application program to determine and set the
attribute associated with a handle.



Writing Programs That Use Expanded Memory 9





Table 2-2. The Advanced Functions (continued)
----------------------------------------------------------------

Function Description

----------------------------------------------------------------

20 The Get/Set Handle Name function gets the eight
character name currently assigned to a handle and
can assign an eight character name to a handle.

21 The Get Handle Directory function returns informa-
tion about active handles and the names assigned to
each.

22 The Alter Page Map & Jump function alters the memory
mapping context and transfers control to the
specified address.

23 The Alter Page Map & Call function alters the speci-
fied mapping context and transfers control to the
specified address. A return can then restore the
context and return control to the caller.

24 The Move/Exchange Memory Region function copies or
exchanges a region of memory from conventional to
conventional memory, conventional to expanded
memory, expanded to conventional memory, or expanded
to expanded memory.

25 The Get Mappable Physical Address Array function
returns an array containing the segment address and
physical page number for each mappable physical page
in a system.

26 The Get Expanded Memory Hardware Information
function returns an array containing the hardware
capabilities of the expanded memory system.

27 The Allocate Standard/Raw Pages function allocates
the number of standard or non-standard size pages
that the operating system requests and assigns a
unique EMM handle to these pages.

28 The Alternate Map Register Set function enables an
application to simulate alternate sets of hardware
mapping registers.

29 The Prepare Expanded Memory Hardware for Warm Boot
function prepares the expanded memory hardware for
an "impending" warm boot.


Writing Programs That Use Expanded Memory 10





Table 2-2. The Advanced Functions (continued)
----------------------------------------------------------------

Function Description

----------------------------------------------------------------

30 The Enable/Disable OS/E function enables operating
systems developers to enable and disable functions
designed for operating system use.

----------------------------------------------------------------









































Writing Programs That Use Expanded Memory 11





Programming Guidelines

The following section contains guidelines for programmers
writing applications that use EMM.

o Do not put a program's stack in expanded memory.

o Do not replace interrupt 67h. This is the interrupt
vector the EMM uses. Replacing interrupt 67h could
result in disabling the Expanded Memory Manager.

o Do not map into conventional memory address space your
application doesn't own. Applications that use the EMM
to swap into conventional memory space, must first
allocate this space from the operating system. If the
operating system is not aware that a region of memory it
manages is in use, it will think it is available. This
could have disastrous results. EMM should not be used
to "allocate" conventional memory. DOS is the proper
manager of conventional memory space. EMM should only
be used to swap data in conventional memory space
previously allocated from DOS.

o Applications that plan on using data aliasing in
expanded memory must check for the presence of expanded
memory hardware. Data aliasing occurs when mapping one
logical page into two or more mappable segments. This
makes one 16K-byte expanded memory page appear to be in
more than one 16K-byte memory address space. Data
aliasing is legal and sometimes useful for applications.

Software-only expanded memory emulators cannot perform
data aliasing. A simple way to distinguish software
emulators from actual expanded memory hardware is to
attempt data aliasing and check the results. For
example, map one logical page into four physical pages.
Write to physical page 0. Read physical pages 1-3 to
see if the data is there as well. If the data appears
in all four physical pages, then expanded memory
hardware is installed in the system, and data aliasing
is supported.

o Applications should always return expanded memory pages
to the expanded memory manager upon termination. These
pages will be made available for other applications. If
unneeded pages are not returned to the expanded memory
manager, the system could "run out" of expanded memory
pages or expanded memory handles.

o Terminate and stay resident programs (TSR's) should
ALWAYS save the state of the map registers before
changing them. Since TSR's may interrupt other programs

Writing Programs That Use Expanded Memory 12





which may be using expanded memory, they must not change
the state of the page mapping registers without first
saving them. Before exiting, TSR's must restore the
state of the map registers.

The following sections describe the three ways to save
and restore the state of the map registers.

1. Save Page Map and Restore Page Map (Functions 8 and
9). This is the simplest of the three methods. The
EMM saves the map register contents in its own data
structures -- the application does not need to
provide extra storage locations for the mapping
context. The last mapping context to be saved,
under a particular handle, will be restored when a
call to Restore Page Map is issued with the same
handle. This method is limited to one mapping
context for each handle and saves the context for
only LIM standard 64K-byte page frames.

2. Get/Set Page Map (Function 15). This method
requires the application to allocate space for the
storage array. The EMM saves the mapping context in
an array whose address is passed to the EMM. When
restoring the mapping context with this method, an
application passes the address of an array which
contains a previously stored mapping context.

This method is preferable if an application needs to
do more than one save before a restore. It provides
a mechanism for switching between more than one
mapping context.

3. Get/Set Partial Page Map (Function 16). This method
provides a way for saving a partial mapping context.
It should be used when the application does not need
to save the context of all mappable memory. This
function also requires that the storage array be
part of the application's data.

o All functions using pointers to data structures must
have those data structures in memory which will not be
mapped out. Functions 22 and 23 (Alter Map & Call and
Alter Map & Jump) are the only exceptions.









Writing Programs That Use Expanded Memory 13





Examples

This section lists four example programs that demonstrate
the use of expanded memory.


Example 1

This program was written using the Microsoft C compiler
Version 3.0. EMM function calls are made with the int86
function found in the dos.h library. To create an ex-
ecutable program use the following compile command line:

msc /Gs /Oat /Ml program,,program;

#include
#include

#define EMM_INT 0x67 /* EMM interrupt number */
#define GET_PAGE_FRAME 0x41 /* EMM get page frame */
/* function number */
#define GET_UNALLOC_PAGE_COUNT 0x42 /* EMM get unallocated */
/* page count */
/* function number */
#define ALLOCATE_PAGES 0x43 /* EMM allocate pages */
/* function number */
#define MAP_PAGES 0x44 /* EMM map pages */
/* function number */
#define DEALLOCATE_PAGES 0x45 /* EMM deallocate pages */
/* function number */
#define DEVICE_NAME_LENGTH 8 /* length of a device */
/* name string */
#define TRUE 1
#define FALSE 0

union REGS input_regs, output_regs;
struct SREGS segment_regs;
int pf_addr;

/*------------------------------------------------------------*/
/* Routine to convert a segment:offset pair to a far ptr. */
/*------------------------------------------------------------*/
char *build_ptr (segment, offset)

unsigned int segment;
unsigned int offset;
{
char *ptr;

ptr = (char *)(((unsigned long)segment << 16) + offset);
return (ptr);
}

Writing Programs That Use Expanded Memory 14





/*------------------------------------------------------------*/
/* Function which determines whether EMM device driver */
/* is installed. */
/*------------------------------------------------------------*/
char emm_installed()

{
char *EMM_device_name = "EMMXXXX0";
char *int_67_device_name_ptr;

/*--------------------------------------------------------*/
/* AH = DOS get interrupt vector function. */
/*--------------------------------------------------------*/
input_regs.h.ah = 0x35;

/*--------------------------------------------------------*/
/* AL = EMM interrupt vector number. */
/*--------------------------------------------------------*/
input_regs.h.al = EMM_INT;
intdosx (&input_regs, &output_regs, &segment_regs);

/*--------------------------------------------------------*/
/* Upon return ES:0Ah points to location where */
/* device name should be. */
/*--------------------------------------------------------*/
int_67_device_name_ptr = build_ptr (segment_regs.es, 0x0A);

/*--------------------------------------------------------*/
/* Compare memory with EMM device name. */
/*--------------------------------------------------------*/
if (memcmp (EMM_device_name, int_67_device_name_ptr,
DEVICE_NAME_LENGTH) == 0)
return (TRUE);
else
return (FALSE);
}

/*------------------------------------------------------------*/
/* Function which determines if there are enough unallocated */
/* expanded memory pages for the application. */
/*------------------------------------------------------------*/
char enough_unallocated_pages (pages_needed)

int pages_needed;
{
input_regs.h.ah = GET_UNALLOCATED_PAGE_COUNT;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah != 0 || pages_needed > output_regs.x.bx)
return (FALSE);
else
return (TRUE);
}

Writing Programs That Use Expanded Memory 15





/*------------------------------------------------------------*/
/* Function which allocates expanded memory pages and passes */
/* back to the main EMM handle. */
/*------------------------------------------------------------*/
char allocate_expanded_memory_pages (pages_needed,emm_handle_ptr)

int pages_needed;
unsigned int *emm_handle_ptr;
{
input_regs.h.ah = ALLOCATE_PAGES;
input_regs.x.bx = pages_needed;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah == 0) {
*emm_handle_ptr = output_regs.x.dx;
return (TRUE);
}
else
return (FALSE);
}

/*------------------------------------------------------------*/
/* Routine to map a logical page to a physical page. */
/*------------------------------------------------------------*/
char map_expanded_memory_pages (emm_handle, physical_page,
logical_page)
unsigned int emm_handle;
int physical_page;
int logical_page;
{
input_regs.h.ah = MAP_PAGES;
input_regs.h.al = physical_page;
input_regs.x.bx = logical_page;
input_regs.x.dx = emm_handle;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah == 0)
return (TRUE);
else
return (FALSE);
}














Writing Programs That Use Expanded Memory 16





/*------------------------------------------------------------*/
/* Routine which gets the page frame base address from EMM. */
/*------------------------------------------------------------*/
char get_page_frame_address (pf_ptr)

char **pf_ptr;
{
input_regs.h.ah = GET_PAGE_FRAME;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah != 0) /* check EMM status */
return (FALSE);
else
*pf_ptr = build_ptr (output_regs.x.bx, 0);
return (TRUE);
}

/*------------------------------------------------------------*/
/* Routine to release all expanded memory pages allocated */
/* by an EMM handle. */
/*------------------------------------------------------------*/

char deallocate_expanded_memory_pages (emm_handle)

unsigned int emm_handle;
{
input_regs.h.ah = DEALLOCATE_PAGES;
input_regs.x.dx = emm_handle;
int86 (EMM_INT, &input_regs, &output_regs);
if (output_regs.h.ah == 0)
return (TRUE);
else
return (FALSE);
}

main()

{
unsigned int emm_handle;
char *pf_addr;
int pages_needed;
int physical_page;
int logical_page;
int index;

/*--------------------------------------------------------*/
/* Determine if EMM is installed. */
/*--------------------------------------------------------*/
if (!emm_installed())
exit(1);




Writing Programs That Use Expanded Memory 17





/*--------------------------------------------------------*/
/* Determine if enough expanded memory pages exist for */
/* application. */
/*--------------------------------------------------------*/
pages_needed = 1;
if (!enough_unallocated_pages (pages_needed))
exit(1);

/*--------------------------------------------------------*/
/* Allocate expanded memory pages. */
/*--------------------------------------------------------*/
if (!allocate_expanded_memory_pages (pages_needed,
&emm_handle))
exit(1);

/*--------------------------------------------------------*/
/* Map in the required pages. */
/*--------------------------------------------------------*/
physical_page = 0;
logical_page = 0;
if (!map_expanded_memory_pages (emm_handle, physical_page,
logical_page))
exit(1);

/*--------------------------------------------------------*/
/* Get expanded memory page frame address. */
/*--------------------------------------------------------*/
if (!get_page_frame_address (&pf_addr))
exit(1);

/*--------------------------------------------------------*/
/* Write to expanded memory. */
/*--------------------------------------------------------*/
for (index = 0; index < 0x3fff; index++)
pf_addr[index] = index;

/*--------------------------------------------------------*/
/* Return expanded memory pages before exiting. */
/*--------------------------------------------------------*/
if (!deallocate_expanded_memory_pages (emm_handle))
exit(1);
}











Writing Programs That Use Expanded Memory 18





Example 2

This program shows you how to use the basic functions of the LIM
Expanded Memory Specification with Turbo Pascal. The program
does the following:

1. Makes sure the LIM Expanded Memory Manager (EMM) has
been installed.

2. Displays the version number of the EMM.

3. Determines if there are enough pages of memory for the
program. It then displays the total number of EMM pages
present in the system and the number available for use.

4. Requests the desired number of pages from the EMM.

5. Maps a logical page into one of the physical pages.

6. Displays the base address of our EMM memory page frame.
Performs a simple read/write test on the EMM memory.

7. Returns the EMM memory given to us back to the EMM.

8. Exits.

All the calls are structured to return the result or error code
of the Expanded Memory function performed as an integer. If the
error code is not zero, an error has occurred, a simple error
procedure is called, and the program terminates.

Type
ST3 = string[3];
ST80 = string[80];
ST5 = string[5];

Registers = record
case integer of
1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS: Integer);
2: (AL,AH,BL,BH,CL,CH,DL,DH : Byte);
end;

Const
EMM_INT = $67;
DOS_Int = $21;
GET_PAGE_FRAME = $41;
GET_UNALLOCATED_PAGE_COUNT = $42;
ALLOCATE_PAGES = $43;
MAP_PAGES = $44;
DEALLOCATE_PAGES = $45;
GET_VERSION = $46;
STATUS_OK = 0;

Writing Programs That Use Expanded Memory 19





{------------------------------------------------------------}
{ Assume the application needs one EMM page. }
{------------------------------------------------------------}
APPLICATION_PAGE_COUNT = 1;

Var
Regs: Registers;

Emm_handle,
Page_Frame_Base_Address,
Pages_Needed,
Physical_Page,
Logical_Page,
Offset,
Error_Code,
Pages_EMM_Available,
Total_EMM_Pages,
Available_EMM_Pages: Integer;

Version_Number,
Pages_Number_String: ST3;

Verify: Boolean;

{------------------------------------------------------------}
{ The function Hex_String converts an integer into a four }
{ character hexadecimal number (string) with leading zeros. }
{------------------------------------------------------------}
Function Hex_String (Number: Integer): ST5;
Function Hex_Char (Number: Integer): Char;
Begin
If Number < 10 then
Hex_Char := Char (Number + 48)
else
Hex_Char := Char (Number + 55);
end; { Function Hex_char }

Var
S: ST5;

Begin
S := '';
S := Hex_Char ((Number shr 1) div 2048);
Number := (((Number shr 1) mod 2048) shl 1) + (Number and 1);
S := S + Hex_Char (Number div 256);
Number := Number mod 256;
S := S + Hex_Char (Number div 16);
Number := Number mod 16;
S := S + Hex_Char (Number);
Hex_String := S + 'h';
end; { Function Hex_String }


Writing Programs That Use Expanded Memory 20





{------------------------------------------------------------}
{ The function Emm_Installed checks to see if the }
{ EMM is loaded in memory. It does this by looking }
{ for the string 'EMMXXXX0', which should be located }
{ at 10 bytes from the beginning of the code segment the }
{ EMM interrupt, 67h, points to. }
{------------------------------------------------------------}
Function Emm_Installed: Boolean;
Var
Emm_Device_Name : string[8];
Int_67_Device_Name: string[8];
Position : integer;
Regs : registers;

Begin
Int_67_Device_Name := '';
Emm_Device_Name := 'EMMXXXX0';
with Regs do
Begin
{----------------------------------------------------}
{ Get the code segment interrupt 67h points to }
{ the EMM interrupt by using DOS function 35h. }
{ (get interrupt vector) }
{----------------------------------------------------}
AH := $35;
AL := EMM_INT;
Intr (DOS_Int, Regs);
{----------------------------------------------------}
{ The ES pseudo-register contains the segment }
{ address pointed to by interrupt 67h. Create an }
{ eight character string from the eight successive }
{ bytes at address ES:$000A (10 bytes from ES) }
{----------------------------------------------------}
For Position := 0 to 7 do
Int_67_Device_Name :=
Int_67_Device_Name + Chr (mem[ES:Position + $0A]);
Emm_Installed := True;
{----------------------------------------------------}
{ If the string is the EMM manager signature, }
{ 'EMMXXXX0', then EMM is installed and ready for }
{ use. If not, then EMM is not present. }
{----------------------------------------------------}
If Int_67_Device_Name <> Emm_Device_Name
then Emm_Installed := False;
end; { with Regs do }
end; { Function Emm_Installed }







Writing Programs That Use Expanded Memory 21





{------------------------------------------------------------}
{ This function returns the total number of EMM pages }
{ present in the system, and the number of EMM pages that }
{ are available. }
{------------------------------------------------------------}
Function EMM_Pages_Available
(Var Total_EMM_Pages, Pages_Available: Integer): Integer;
Var
Regs: Registers;

Begin
with Regs do
Begin
{----------------------------------------------------}
{ Get the number of currently unallocated pages and }
{ the total number of pages in the system from EMM. }
{ Load pseudo-registers prior to invoking EMM. }
{ AH = get unallocated page count function }
{----------------------------------------------------}
AH := GET_UNALLOCATED_PAGE_COUNT;
Intr (EMM_INT, Regs);
{----------------------------------------------------}
{ Unload the pseudo-registers after invoking EMM. }
{ BX = currently unallocated pages }
{ DX = total pages in the system }
{ AH = status }
{----------------------------------------------------}
Pages_Available := BX;
Total_EMM_Pages := DX;
EMM_Pages_Available := AH;
end;
end; { Function EMM_Pages_Available }


{------------------------------------------------------------}
{ This function requests the specified number of pages }
{ from the EMM. }
{------------------------------------------------------------}
Function Allocate_Expanded_Memory_Pages
(Pages_Needed: Integer; Var Handle: Integer): Integer;
Var
Regs: Registers;











Writing Programs That Use Expanded Memory 22





Begin
with Regs do
Begin
{----------------------------------------------------}
{ Allocate the specified number of pages from EMM. }
{ Load pseudo-registers prior to invoking EMM. }
{ AH = allocate pages function. }
{ BX = number of pages to allocate. }
{----------------------------------------------------}
AH := ALLOCATE_PAGES;
BX := Pages_Needed;
Intr (EMM_INT, Regs);
{----------------------------------------------------}
{ Unload the pseudo-registers after invoking EMM. }
{ DX = EMM handle }
{ AH = status }
{----------------------------------------------------}
Handle := DX;
Allocate_Expanded_Memory_Pages := AH;
end;
end; { Function Allocate_Expanded_Memory_Pages }


{------------------------------------------------------------}
{ This function maps a logical page allocated by the }
{ Allocate_Expanded_Memory_Pages function into one of the }
{ four physical pages. }
{------------------------------------------------------------}
Function Map_Expanded_Memory_Pages
(Handle, Logical_Page, Physical_Page: Integer): Integer;
Var
Regs: Registers;

Begin
with Regs do
Begin
{----------------------------------------------------}
{ Map a logical page at a physical page. }
{ Load pseudo-registers prior to invoking EMM. }
{ AH = map page function }
{ DX = handle }
{ BX = logical page number }
{ AL = physical page number }
{----------------------------------------------------}
AH := MAP_PAGES;
DX := Handle;
BX := Logical_Page;
AL := Physical_Page;
Intr (EMM_INT, Regs);




Writing Programs That Use Expanded Memory 23





{----------------------------------------------------}
{ Unload the pseudo-registers after invoking EMM. }
{ AH = status }
{----------------------------------------------------}
Map_Expanded_Memory_Pages := AH;
end; { with Regs do }
end; { Function Map_Expanded_Memory_Pages }


{------------------------------------------------------------}
{ This function gets the physical address of the EMM page }
{ frame we are using. The address returned is the segment }
{ of the page frame. }
{------------------------------------------------------------}
Function Get_Page_Frame_Base_Address
(Var Page_Frame_Address: Integer): Integer;
Var
Regs: Registers;

Begin
with Regs do
Begin
{----------------------------------------------------}
{ Get the page frame segment address from EMM. }
{ Load pseudo-registers prior to invoking EMM. }
{ AH = get page frame segment function }
{----------------------------------------------------}
AH := GET_PAGE_FRAME;
Intr (EMM_INT, Regs);
{----------------------------------------------------}
{ Unload the pseudo-registers after invoking EMM. }
{ BX = page frame segment address }
{ AH = status }
{----------------------------------------------------}
Page_Frame_Address := BX;
Get_Page_Frame_Base_Address := AH;
end; { with Regs do }
end; { Function Get_Page_Frame_Base_Address }


{------------------------------------------------------------}
{ This function releases the EMM memory pages allocated to }
{ us, back to the EMM memory pool. }
{------------------------------------------------------------}
Function Deallocate_Expanded_Memory_Pages
(Handle: Integer): Integer;
Var
Regs: Registers;





Writing Programs That Use Expanded Memory 24





Begin
with Regs do
Begin
{----------------------------------------------------}
{ Deallocate the pages allocated to an EMM handle. }
{ Load pseudo-registers prior to invoking EMM. }
{ AH = deallocate pages function }
{ DX = EMM handle }
{----------------------------------------------------}
AH := DEALLOCATE_PAGES;
DX := Handle;
Intr (EMM_INT, Regs);
{----------------------------------------------------}
{ Unload the pseudo-registers after invoking EMM. }
{ AH = status }
{----------------------------------------------------}
Deallocate_Expanded_Memory_Pages := AH;
end; { with Regs do }
end; { Function Deallocate_Expanded_Memory_Pages }


{------------------------------------------------------------}
{ This function returns the version number of the EMM as }
{ a three-character string. }
{------------------------------------------------------------}
Function Get_Version_Number (Var Version_String: ST3): Integer;
Var
Regs: Registers;
Integer_Part, Fractional_Part: Char;

Begin
with Regs do
Begin
{----------------------------------------------------}
{ Get the version of EMM. }
{ Load pseudo-registers prior to invoking EMM. }
{ AH = get EMM version function }
{----------------------------------------------------}
AH := GET_VERSION;
Intr (EMM_INT, Regs);













Writing Programs That Use Expanded Memory 25






{----------------------------------------------------}
{ If the version number returned was OK, then }
{ convert it to a three-character string. }
{----------------------------------------------------}
If AH=STATUS_OK then
Begin
{------------------------------------------------}
{ The upper four bits of AH are the integer }
{ portion of the version number, the lower four }
{ bits are the fractional portion. Convert the }
{ integer value to ASCII by adding 48. }
{------------------------------------------------}
Integer_Part := Char (AL shr 4 + 48);
Fractional_Part := Char (AL and $F + 48);
Version_String := Integer_Part + '.' +
Fractional_Part;
end; { If AH=STATUS_OK }
{----------------------------------------------------}
{ Unload the pseudo-registers after invoking EMM. }
{ AH = status }
{----------------------------------------------------}
Get_Version_Number := AH;
end; { with Regs do }
end; { Function Get_Version_Number }


{------------------------------------------------------------}
{ This procedure prints an error message passed by the }
{ caller, prints the error code passed by the caller in hex, }
{ and then terminates the program with an error level of 1. }
{------------------------------------------------------------}
Procedure Error (Error_Message: ST80; Error_Number: Integer);
Begin
Writeln (Error_Message);
Writeln (' Error_Number = ', Hex_String (Error_Number));
Writeln ('EMM test program aborting.');
Halt (1);
end; { Procedure Error }


{--------------------------------------------------------------}
{ This program is an example of the basic EMM functions that }
{ you need in order to use EMM memory with Turbo Pascal. }
{--------------------------------------------------------------}
Begin
ClrScr;
Window (5,2,77,22);






Writing Programs That Use Expanded Memory 26





{------------------------------------------------------------}
{ Determine if the Expanded Memory Manager is installed. If }
{ not, then terminate 'main' with an ErrorLevel code of 1. }
{------------------------------------------------------------}
If not (Emm_Installed) then
Begin
Writeln ('The LIM EMM is not installed.');
Halt (1);
end
else
Begin
{ Get the version number and display it }
Error_Code := Get_Version_Number (Version_Number);
If Error_Code <> STATUS_OK then
Error ('Error getting EMM version number.', Error_Code)
else
Writeln ('LIM Expanded Memory Manager, version ',
Version_Number, ' is ready for use.');
end;
Writeln;

{------------------------------------------------------------}
{ Determine if there are enough expanded memory pages for }
{ this application. }
{------------------------------------------------------------}
Pages_Needed := APPLICATION_PAGE_COUNT;
Error_Code := EMM_Pages_Available (Total_EMM_Pages,
Available_EMM_Pages);
If Error_Code <> STATUS_OK then
Error ('Error determining number of EMM pages available.',
Error_Code);
Writeln ('There are a total of ', Total_EMM_Pages,
' expanded memory pages present in this system.');
Writeln (' ', Available_EMM_Pages,
' of those pages are available for use.');
Writeln;

{------------------------------------------------------------}
{ If there is an insufficient number of pages for the }
{ application, then report the error and terminate the EMM }
{ example program. }
{------------------------------------------------------------}
If Pages_Needed > Available_EMM_Pages then
Begin
Str (Pages_Needed, Pages_Number_String);
Error ('We need ' + Pages_Number_String +
' EMM pages. There are not that many available.',
Error_Code);
end; { Pages_Needed > Available_EMM_Pages }




Writing Programs That Use Expanded Memory 27





{------------------------------------------------------------}
{ Allocate expanded memory pages for our use. }
{------------------------------------------------------------}
Error_Code :=
Allocate_Expanded_Memory_Pages (Pages_Needed, Emm_Handle);
Str (Pages_Needed, Pages_Number_String);
If Error_Code <> STATUS_OK then
Error ('EMM test program failed trying to allocate '
+ Pages_Number_String
+ ' pages for usage.', Error_Code);
Writeln (APPLICATION_PAGE_COUNT,
' EMM page(s) allocated for the EMM test program.');
Writeln;

{------------------------------------------------------------}
{ Map in the required logical pages to the physical pages }
{ given to us, in this case just one page. }
{------------------------------------------------------------}
Logical_Page := 0;
Physical_Page := 0;
Error_Code := Map_Expanded_Memory_Pages (Emm_Handle,
Logical_Page,
Physical_Page);
If Error_Code <> STATUS_OK then
Error ('EMM test program failed trying to map '
+ 'logical pages into physical pages.',
Error_Code);

Writeln ('Logical Page ',
Logical_Page,
' successfully mapped into Physical Page ',
Physical_Page);
Writeln;

{------------------------------------------------------------}
{ Get the expanded memory page frame address. }
{------------------------------------------------------------}
Error_Code := Get_Page_Frame_Base_Address
(Page_Frame_Base_Address);
If Error_Code <> STATUS_OK then
Error ('EMM test program unable to get the base Page'
+ ' Frame Address.',
Error_Code);
Writeln ('The base address of the EMM page frame is = '
+ Hex_String (Page_Frame_Base_Address));
Writeln;







Writing Programs That Use Expanded Memory 28





{------------------------------------------------------------}
{ Write a test pattern to expanded memory. }
{------------------------------------------------------------}
For Offset := 0 to 16382 do
Begin
Mem[Page_Frame_Base_Address:Offset] := Offset mod 256;
end;

{------------------------------------------------------------}
{ Make sure that what is in EMM memory is what was just }
{ written. }
{------------------------------------------------------------}
Writeln ('Testing EMM memory.');

Offset := 1;
Verify := True;
while (Offset <= 16382) and (Verify = True) do
Begin
If Mem[Page_Frame_Base_Address:Offset] <> Offset mod 256
then Verify := False;
Offset := Succ (Offset);
end; { while (Offset <= 16382) and (Verify = True) }

{------------------------------------------------------------}
{ If what is read does not match what was written, }
{ an error occurred. }
{------------------------------------------------------------}
If not Verify then
Error ('What was written to EMM memory was not found during'
+ ' memory verification test.',
0);
Writeln ('EMM memory test successful.');
Writeln;

{------------------------------------------------------------}
{ Return the expanded memory pages given to us back to the }
{ EMM memory pool before terminating our test program. }
{------------------------------------------------------------}
Error_Code := Deallocate_Expanded_Memory_Pages (Emm_Handle);
If Error_Code <> STATUS_OK then
Error ('EMM test program was unable to deallocate '
+ 'the EMM pages in use.',
Error_Code);
Writeln (APPLICATION_PAGE_COUNT,
' pages(s) deallocated.');
Writeln;
Writeln ('EMM test program completed.');

end.




Writing Programs That Use Expanded Memory 29





Example 3

This program is written in Microsoft's macro assembler.


CODE SEGMENT
ASSUME CS:CODE, DS:CODE

MOV AX,CS
MOV DX,AX
.
.
.
check_emm_installed:

MOV AH,35h ; AH = DOS get interrupt vector
; function
MOV AL,67h ; AL = EMM interrupt vector number
INT 21h
MOV DI,0Ah ; ES:DI points to where device
; name should be
LEA SI,EMM_device_name ; DS:SI points to ASCII string
; containing EMM device name

MOV CX,device_name_length ; set up loop counter for string op
CLD ; set up direction flag for forward
REPE CMPSB ; Compare the strings
JNE exit ; IF strings not equal THEN exit
; ELSE
check_enough_unallocated_pages:

MOV AH,41h ; AH = EMM get unallocated page
; count function code
INT 67h
OR AH,AH ; Check EMM status
JNZ emm_error_handler ; IF error THEN goto error handler
; ELSE
allocate_expanded_memory_pages:

MOV AH,43h ; AH = EMM allocate pages
; function code
MOV BX,2 ; BX = number of pages needed
INT 67h
OR AH,AH ; Check EMM status
JNZ emm_error_handler ; IF error THEN goto error handler
; ELSE
MOV emm_handle,DX ; save EMM handle

map_expanded_memory_pages:

MOV AH,44h ; AH = EMM map pages function
MOV DX,emm_handle ; DX = application's handle

Writing Programs That Use Expanded Memory 30





map_0_to_0:

MOV BX,0 ; BX = logical page 0
MOV AL,0 ; AL = physical page 0
INT 67h
OR AH,AH ; Check EMM status
JNZ emm_error_handler ; If error THEN goto error handler
; ELSE
get_page_frame_address:

MOV AH,41h ; AH = EMM get page frame base
; address function
INT 67h
OR AH,AH ; Check EMM status
JNZ emm_error_handler ; IF error THEN goto error handler
MOV pf_addr,BX ; ELSE save pf_addr

write_to_expanded_memory: ; Write zeros to memory mapped at
; physical page 0
MOV AX,pf_addr
MOV ES,AX ; ES points to physical page 0
MOV DI,0 ; DI indexes into physical page 0
MOV AL,0 ; Initialize AL for string STOSB
MOV CX,4000h ; Initialize loop counter to length
; of expanded memory page size
CLD ; set up direction flag for forward
REP STOSB

deallocate_pages:

MOV AH,45h ; AH = EMM deallocate pages
; function
MOV DX,emm_handle
INT 67h ; return handle's pages to EMM
OR AH,AH ; Check EMM status
JNZ emm_error_handler ; IF error THEN goto error handler

exit:

MOV AH,4Ch ; AH = DOS exit function
INT 21h ; return to DOS


EMM_device_name DB 'EMMXXXX0' ; ASCII EMM device name string

device_name_length EQU 8

CODE ENDS
END




Writing Programs That Use Expanded Memory 31





Example 4

This program is an example of how to exchange a 256K-byte
block of data from conventional memory to expanded memory.


CODE SEGMENT
ASSUME CS:CODE, DS:CODE
.
.
.
xchg_packet_set_up:

;DS:SI = xchg_packet

MOV AX,SEG xchg_packet
MOV DS,AX
MOV SI,OFFSET xchg_packet

;Moving 256K of data from conventional memory to expanded memory

MOV WORD PTR [SI].region_length[0],0
MOV WORD PTR [SI].region_length[2],4
MOV [SI].src_mem_type,0
MOV [SI].dest_mem_type,1

;starting at segment: 4000h, offset: 0

MOV [SI].src_init_seg_page,4000h
MOV [SI].src_init_offset,0

;Move data into expanded memory logical page 0, offset 0.

MOV [SI].dest_init_seg_page,0
MOV [SI].dest_init_offset,0

;Initialize for future compatibility

MOV [SI].src_handle,0

;Need handle for expanded memory destination.

MOV DX,emm_handle
MOV [SI].dest_handle,DX

;AX = EMM Exchange Memory function

MOV AX,5701h
INT 67h
OR AH,AH
JNZ emm_error_handler


Writing Programs That Use Expanded Memory 32





xchg_struct STRUC
region_length DD ?
src_mem_type DB ?
src_handle DW ?
src_init_offset DW ?
src_init_seg_page DW ?
dest_mem_type DB ?
dest_handle DW ?
dest_init_offset DW ?
dest_init_seg_page DW ?
xchg_struct ENDS

xchg_packet xchg_struct

CODE ENDS
END





































Writing Programs That Use Expanded Memory 33





Chapter 3
EMM FUNCTIONS


This chapter provides you with a standardized set of
expanded memory functions. Because they are standardized,
you avoid potential compatibility problems with other
expanded memory programs that also adhere to the memory
manager specification. Programs that deal directly with the
hardware or that don't adhere to this specification will be
incompatible.

Table 3-1 presents a sequential list of the EMM functions.
The remainder of this chapter provides detailed descriptions
of each function.


Table 3-1. List of EMM Functions
----------------------------------------------------------------

Number Function Name Hex Value Page

----------------------------------------------------------------

1 Get Status 40h 37

2 Get Page Frame Address 41h 38

3 Get Unallocated Page Count 42h 40

4 Allocate Pages 43h 42

5 Map/Unmap Handle Page 44h 46

6 Deallocate Pages 45h 49

7 Get Version 46h 51

8 Save Page Map 47h 53

9 Restore Page Map 48h 55

10 Reserved 49h 57

11 Reserved 4Ah 58

12 Get Handle Count 4Bh 59

13 Get Handle Pages 4Ch 61

14 Get All Handle Pages 4Dh 63


EMM Functions 34





Table 3-1. List of EMM Functions (continued)
----------------------------------------------------------------

Number Function Name Hex Value Page

----------------------------------------------------------------

15 Get Page Map 4E00h 65
Set Page Map 4E01h 67
Get & Set Page Map 4E02h 69
Get Size of Page Map Save Array 4E03h 71

16 Get Partial Page Map 4F00h 73
Set Partial Page Map 4F01h 76
Get Size of Partial Page Map
Save Array 4F02h 78

17 Map/Unmap Multiple Handle Pages
(Physical page number mode) 5000h 82
Map/Unmap Multiple Handle Pages
(Segment address mode) 5001h 85

18 Reallocate Pages 51h 88

19 Get Handle Attribute 5200h 92
Set Handle Attribute 5201h 94
Get Handle Attribute Capability 5202h 96

20 Get Handle Name 5300h 98
Set Handle Name 5301h 100

21 Get Handle Directory 5400h 102
Search for Named Handle 5401h 105
Get Total Handles 5402h 107

22 Alter Page Map & Jump
(Physical page number mode) 5500h 109
Alter Page Map & Jump
(Segment address mode) 5501h 109

23 Alter Page Map & Call
(Physical page number mode) 5600h 113
Alter Page Map & Call
(Segment address mode) 5601h 113
Get Page Map Stack Space Size 5602h 118

24 Move Memory Region 5700h 120
Exchange Memory Region 5701h 126

25 Get Mappable Physical Address Array 5800h 132
Get Mappable Physical Address Array
Entries 5801h 136

EMM Functions 35





Table 3-1. List of EMM Functions (continued)
----------------------------------------------------------------

Number Function Name Hex Value Page

----------------------------------------------------------------

26 Get Hardware Configuration Array 5900h 138
Get Unallocated Raw Page Count 5901h 142

27 Allocate Standard Pages 5A00h 144
Allocate Raw Pages 5A01h 147

28 Get Alternate Map Register Set 5B00h 153
Set Alternate Map Register Set 5B01h 157
Get Alternate Map Save Array Size 5B02h 161
Allocate Alternate Map Register Set 5B03h 163
Deallocate Alternate Map Register Set 5B04h 166
Allocate DMA Register Set 5B05h 168
Enable DMA on Alternate Map
Register Set 5B06h 170
Disable DMA on Alternate Map
Register Set 5B07h 173
Deallocate DMA Register Set 5B08h 175

29 Prepare Expanded Memory Hardware
for Warmboot 5Ch 177

30 Enable OS/E Function Set 5D00h 179
Disable OS/E Function Set 5D01h 182
Return OS/E Access Key 5D02h 185

----------------------------------------------------------------




















EMM Functions 36





Function 1. Get Status



PURPOSE

The Get Status function returns a status code indicating
whether the memory manager is present and the hardware is
working correctly.


CALLING PARAMETERS

AH = 40h
Contains the Get Status Function.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager is present in the system, and the hardware
is working correctly.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.


EXAMPLE

MOV AH,40h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error






EMM Functions 37





Function 2. Get Page Frame Address



PURPOSE

The Get Page Frame Address function returns the segment
address where the page frame is located.


CALLING PARAMETERS

AH = 41h
Contains the Get Page Frame Address function.


RESULTS

These results are valid only if the status returned is zero.

BX = page frame segment address
Contains the segment address of the page frame.


REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the page frame address in the
BX register.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.







EMM Functions 38





Function 2. Get Page Frame Address



EXAMPLE

page_frame_segment DW ?

MOV AH,41h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV page_frame_segment,BX ; save page frame address








































EMM Functions 39





Function 3. Get Unallocated Page Count



PURPOSE

The Get Unallocated Page Count function returns the number
of unallocated pages and the total number of expanded memory
pages.


CALLING PARAMETERS

AH = 42h
Contains the Get Unallocated Page Count function.


RESULTS

These results are valid only if the status returned is zero.

BX = unallocated pages
The number of expanded memory pages that are currently
available for use (unallocated).

DX = total pages
The total number of expanded memory pages.


REGISTERS MODIFIED

AX, BX, DX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the number of unallocated pages
and the number of total pages in expanded memory.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.


EMM Functions 40





Function 3. Get Unallocated Page Count



EXAMPLE

un_alloc_pages DW ?
total_pages DW ?

MOV AH,42h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV un_alloc_pages,BX ; save unallocated page count
MOV total_pages,DX ; save total page count






































EMM Functions 41





Function 4. Allocate Pages



The Allocate Pages function allocates the number of pages
requested and assigns a unique EMM handle to these pages.
The EMM handle owns these pages until the application
deallocates them.

Handles which are assigned using this function will have
16K-byte pages, the size of a standard expanded memory page.
If the expanded memory board hardware isn't able to supply
16K-byte pages, it will emulate them by combining multiple
non-standard size pages to form a single 16K-byte page. All
application programs and functions that use the handles this
function returns will deal with 16K-byte pages.

The numeric value of the handles the EMM returns are in the
range of 1 to 254 decimal (0001h to 00FEh). The OS handle
(handle value 0) is never returned by the Allocate Pages
function. Also, the uppermost byte of the handle will be
zero and cannot be used by the application. A memory
manager should be able to supply up to 255 handles, includ-
ing the OS handle. An application can use Function 21 to
find out how many handles an EMM supports.

Allocating zero pages to a handle is not valid. If an
application needs to allocate 0 pages to a handle it should
use Function 27 (Allocate Standard Pages subfunction)
provided for this purpose.

Note............................................................
This note affects expanded memory manager implementors and
operating system developers only. Applications should not
use the following characteristics of the memory manager. An
application violating this rule will be incompatible with
future versions of Microsoft's operating systems and
environments.

To be compatible with this specification, an expanded memory
manager will provide a special handle which is available to
the operating system only. This handle will have a value of
0000h and will have a set of pages allocated to it when the
expanded memory manager driver installs. The pages that the
memory manager will automatically allocate to handle 0000h
are those that backfill conventional memory. Typically,
this backfill occurs between addresses 40000h (256K) and
9FFFFh (640K). However, the range can extend below and
above this limit if the hardware and memory manager have the
capability.



EMM Functions 42





Function 4. Allocate Pages



An operating system won't have to invoke Function 4 to
obtain this handle because it can assume the handle already
exists and is available for use immediately after the
expanded memory device driver installs. When an operating
system wants to use this handle, it uses the special handle
value of 0000h. The operating system will be able to invoke
any EMM function using this special handle value. To
allocate pages to this handle, the operating system need
only invoke Function 18 (Reallocate Pages).

There are two special cases for this handle:

1. Function 4 (Allocate Pages). This function must never
return zero as a handle value. Applications must always
invoke Function 4 to allocate pages and obtain a handle
which identifies the pages which belong to it. Since
Function 4 never returns a handle value of zero, an
application will never gain access to this special
handle.

2. Function 6 (Deallocate Pages). If the operating system
uses it to deallocate the pages which are allocated to
this special handle, the pages the handle owns will be
returned to the manager for use. But the handle will
not be available for reassignment. The manager should
treat a deallocate pages function request for this
handle the same as a reallocate pages function request,
where the number of pages to reallocate to this handle
is zero.


CALLING PARAMETERS

AH = 43h
Contains the Allocate Pages function.

BX = num_of_pages_to_alloc
Contains the number of pages you want your program to
allocate.










EMM Functions 43





Function 4. Allocate Pages



RESULTS

These results are valid only if the status returned is zero.

DX = handle
Contains a unique EMM handle. Your program must use
this EMM handle (as a parameter) in any function that
requires it. You can use up to 255 handles. The
uppermost byte of the handle will be zero and cannot be
used by the application.


REGISTERS MODIFIED

AX, DX


STATUS

AH = 0 SUCCESSFUL.
The manager has allocated the requested pages to the
assigned EMM handle.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 85h RECOVERABLE.
All EMM handles are being used.

AH = 87h RECOVERABLE.
There aren't enough expanded memory pages present in the
system to satisfy your program's request.

AH = 88h RECOVERABLE.
There aren't enough unallocated pages to satisfy your
program's request.

AH = 89h RECOVERABLE.
Your program attempted to allocate zero pages.

EMM Functions 44





Function 4. Allocate Pages



EXAMPLE

num_of_pages_to_alloc DW ?
emm_handle DW ?

MOV BX,num_of_pages_to_alloc ; load number of pages
MOV AH,43h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV emm_handle,DX ; save EMM handle






































EMM Functions 45





Function 5. Map/Unmap Handle Pages



PURPOSE

The Map/Unmap Handle Page function maps a logical page at a
specific physical page anywhere in the mappable regions of
system memory. The lowest valued physical page numbers are
associated with regions of memory outside the conventional
memory range. Use Function 25 (Get Mappable Physical
Address Array) to determine which physical pages within a
system are mappable and determine the segment addresses
which correspond to a specific physical page number.
Function 25 provides a cross reference between physical page
numbers and segment addresses.

This function can also unmap physical pages, making them
inaccessible for reading or writing. You unmap a physical
page by setting its associated logical page to FFFFh.

You might unmap an entire set of mapped pages, for example,
before loading and executing a program. Doing so ensures
the loaded program, if it accesses expanded memory, won't
access the pages your program has mapped. However, you must
save the mapped context before you unmap the physical pages.
This enables you to restore it later so you can access the
memory you mapped there. To save the mapping context, use
Function 8, 15, or 16. To restore the mapping context, use
Function 9, 15, or 16.

The handle determines what type of pages are being mapped.
Logical pages allocated by Function 4 and Function 27
(Allocate Standard Pages subfunction) are referred to as
pages and are 16K bytes long. Logical pages allocated by
Function 27 (Allocate Raw Pages subfunction) are referred to
as raw pages and might not be the same size as logical
pages.


CALLING PARAMETERS

AH = 44h
Contains the Map Handle Page function.

AL = physical_page_number
Contains the number of the physical page into which the
logical page number is to be mapped. Physical pages are
numbered zero-relative.




EMM Functions 46





Function 5. Map/Unmap Handle Pages



BX = logical_page_number
Contains the number of the logical page to be mapped at
the physical page within the page frame. Logical pages
are numbered zero-relative. The logical page must be in
the range zero through (number of pages allocated to the
EMM handle - 1). However, if BX contains logical page
number FFFFh, the physical page specified in AL will be
unmapped (be made inaccessible for reading or writing).

DX = emm_handle
Contains the EMM handle your program received from
Function 4 (Allocate Pages).


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has mapped the page. The page is ready to
be accessed.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The memory manager couldn't find the EMM handle your
program specified.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager isn't
defined.

AH = 8Ah RECOVERABLE.
The logical page is out of the range of logical pages
which are allocated to the EMM handle. This status is
also returned if a program attempts to map a logical
page when no logical pages are allocated to the handle.



EMM Functions 47





Function 5. Map/Unmap Handle Pages



AH = 8Bh RECOVERABLE.
The physical page number is out of the range of allow-
able physical pages. The program can recover by
attempting to map into memory at a physical page which
is within the range of allowable physical pages.


EXAMPLE

emm_handle DW ?
logical_page_number DW ?
physical_page_number DB ?

MOV DX,emm_handle ; load EMM handle
MOV BX,logical_page_number ; load logical page number
MOV AL,physical_page_number ; load physical page number
MOV AH,44h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error





























EMM Functions 48





Function 6. Deallocate Pages



PURPOSE

Deallocate Pages deallocates the logical pages currently
allocated to an EMM handle. Only after the application
deallocates these pages can other applications use them.
When a handle is deallocated, its name is set to all ASCII
nulls (binary zeros).

Note............................................................
A program must perform this function before it exits to DOS.
If it doesn't, no other programs can use these pages or the
EMM handle. This means that a program using expanded memory
should trap critical errors and control-break if there is a
chance that the program will have allocated pages when
either of these events occur.


CALLING PARAMETERS

AH = 45h
Contains the Deallocate Pages function.

DX = handle
Contains the EMM handle returned by Function 4 (Allocate
Pages).


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has deallocated the pages previously allo-
cated to the EMM handle.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager couldn't find the specified EMM handle.

EMM Functions 49





Function 6. Deallocate Pages



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 86h RECOVERABLE.
The memory manager detected a save or restore page
mapping context error (Function 8 or 9). There is a
page mapping register state in the save area for the
specified EMM handle. Save Page Map (Function 8) placed
it there and a subsequent Restore Page Map (Function 9)
has not removed it.

If you have saved the mapping context, you must restore
it before you deallocate the EMM handle's pages.


EXAMPLE

emm_handle DW ?

MOV DX,emm_handle ; load EMM handle
MOV AH,45h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
























EMM Functions 50





Function 7. Get Version



PURPOSE

The Get Version function returns the version number of the
memory manager software.


CALLING PARAMETERS

AH = 46h
Contains the Get Version function.


RESULTS

These results are valid only if the status returned is zero.

AL = version number
Contains the memory manager's version number in binary
coded decimal (BCD) format. The upper four bits contain
the integer digit of the version number. The lower four
bits contain the fractional digit of version number.
For example, version 4.0 is represented like this:

0100 0000
/ \
4 . 0

When checking for a version number, an application
should check for a version number or greater. Vendors
may use the fractional digit to indicate enhancements or
corrections to their memory managers. Therefore, to
allow for future versions of memory managers, an
application shouldn't depend on an exact version number.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager is present in the system and the hardware is
working correctly.




EMM Functions 51





Function 7. Get Version



AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.


EXAMPLE

emm_version DB ?

MOV AH,46h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV emm_version,AL ; save version number



























EMM Functions 52





Function 8. Save Page Map



PURPOSE

Save Page Map saves the contents of the page mapping
registers on all expanded memory boards in an internal save
area. The function is typically used to save the memory
mapping context of the EMM handle that was active when a
software or hardware interrupt occurred. (See Function 9,
Restore Page Map, for the restore operation.)

If you're writing a resident program, an interrupt service
routine, or a device driver that uses expanded memory, you
must save the state of the mapping hardware. You must save
this state because application software using expanded
memory may be running when your program is invoked by a
hardware interrupt, a software interrupt, or DOS.

The Save Page Map function requires the EMM handle that was
assigned to your resident program, interrupt service
routine, or device driver at the time it was initialized.
This is not the EMM handle that the application software was
using when your software interrupted it.

The Save Page Map function saves the state of the map
registers for only the 64K-byte page frame defined in
versions 3.x of this specification. Since all applications
written to LIM versions 3.x require saving the map register
state of only this 64K-byte page frame, saving the entire
mapping state for a large number of mappable pages would be
inefficient use of memory. Applications that use a mappable
memory region outside the LIM 3.x page frame should use
Function 15 or 16 to save and restore the state of the map
registers.


CALLING PARAMETERS

AH = 47h
Contains the Save Page Map function.

DX = handle
Contains the EMM handle assigned to the interrupt
service routine that's servicing the software or
hardware interrupt. The interrupt service routine needs
to save the state of the page mapping hardware before
mapping any pages.




EMM Functions 53





Function 8. Save Page Map



REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has saved the state of the page mapping
hardware.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The memory manager couldn't find the EMM handle your
program specified.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Ch NON-RECOVERABLE.
There is no room in the save area to store the state of
the page mapping registers. The state of the map
registers has not been saved.

AH = 8Dh CONDITIONALLY-RECOVERABLE.
The save area already contains the page mapping register
state for the EMM handle your program specified.


EXAMPLE

emm_handle DW ?

MOV DX,emm_handle ; load EMM handle
MOV AH,47h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error



EMM Functions 54





Function 9. Restore Page Map



PURPOSE

The Restore Page Map function restores the page mapping
register contents on the expanded memory boards for a
particular EMM handle. This function lets your program
restore the contents of the mapping registers its EMM handle
saved. (See Function 8, Save Page Map for the save opera-
tion.)

If you're writing a resident program, an interrupt service
routine, or a device driver that uses expanded memory, you
must restore the mapping hardware to the state it was in
before your program took over. You must save this state
because application software using expanded memory might
have been running when your program was invoked.

The Restore Page Map function requires the EMM handle that
was assigned to your resident program, interrupt service
routine, or device driver at the time it was initialized.
This is not the EMM handle that the application software was
using when your software interrupted it.

The Restore Page Map function restores the state of the map
registers for only the 64K-byte page frame defined in
versions 3.x of this specification. Since all applications
written to LIM versions 3.x require restoring the map
register state of only this 64K-byte page frame, restoring
the entire mapping state for a large number of mappable
pages would be inefficient use of memory. Applications that
use a mappable memory region outside the LIM 3.x page frame
should use Function 15 or 16 to save and restore the state
of the map registers.


CALLING PARAMETERS

AH = 48h
Contains the Restore Page Map function.

DX = emm_handle
Contains the EMM handle assigned to the interrupt
service routine that's servicing the software or
hardware interrupt. The interrupt service routine needs
to restore the state of the page mapping hardware.





EMM Functions 55





Function 9. Restore Page Map



REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has restored the state of the page mapping
registers.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The memory manager couldn't find the EMM handle your
program specified.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Eh CONDITIONALLY-RECOVERABLE.
There is no page mapping register state in the save area
for the specified EMM handle. Your program didn't save
the contents of the page mapping hardware, so Restore
Page can't restore it.


EXAMPLE

emm_handle DW ?

MOV DX,emm_handle ; load EMM handle
MOV AH,48h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error






EMM Functions 56





Function 10. Reserved



In earlier versions of the Lotus/Intel/Microsoft Expanded
Memory Specification, Function 10 returned the page mapping
register I/O array. This function is now reserved and new
programs should not use it.

Existing programs that use this function may still work
correctly if the hardware is capable of supporting them.
However, programs that use Functions 16 through 30 in
Version 4.0 of this specification must not use Functions 10
and 11. These functions won't work correctly if your
program attempts to mix the use of the new functions
(Functions 16 through 30) and Functions 10 and 11. Func-
tions 10 and 11 are specific to the hardware on Intel
expanded memory boards and will not work correctly on all
vendors' expanded memory boards.


































EMM Functions 57





Function 11. Reserved



In earlier versions of the Lotus/Intel/Microsoft Expanded
Memory Specification, Function 11 returned a page transla-
tion array. This function is now reserved and new programs
should not use it.

Existing programs that use this function may still work
correctly if the hardware is capable of supporting them.
However, programs that use Functions 16 through 30 in
Version 4.0 of this specification must not use Functions 10
and 11. These functions won't work correctly if your
program attempts to mix the use of the new functions
(Functions 16 through 30) and Functions 10 and 11. Func-
tions 10 and 11 are specific to the hardware on Intel
expanded memory boards and will not work correctly on all
vendors' expanded memory boards.


































EMM Functions 58





Function 12. Get Handle Count



PURPOSE

The Get Handle Count function returns the number of open EMM
handles (including the operating system handle 0) in the
system.


CALLING PARAMETERS

AH = 4Bh
Contains the Get Handle Count function.


RESULTS

These results are valid only if the status returned is zero.

BX = total_open_emm_handles
Contains the number of open EMM handles [including the
operating system handle (0)]. This number will not
exceed 255.


REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the number of active EMM
handles.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.




EMM Functions 59





Function 12. Get Handle Count



EXAMPLE

total_open_emm_handles DW ?

MOV AH,4Bh ; load function code
INT 67h ; call the memory manger
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error
MOV total_open_emm_handles,BX ; save total active handle
; count






































EMM Functions 60





Function 13. Get Handle Pages



PURPOSE

The Get Handle Pages function returns the number of pages
allocated to a specific EMM handle.


CALLING PARAMETERS

AH = 4Ch
Contains the Get Handle Pages function.

DX = emm_handle
Contains the EMM handle.


RESULTS

These results are valid only if the status returned is zero.

BX = num_pages_alloc_to_emm_handle
Contains the number of logical pages allocated to the
specified EMM handle. This number never exceeds 2048
because the memory manager allows a maximum of 2048
pages (32M bytes) of expanded memory.


REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the number of pages allocated
to the EMM handle.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The memory manager couldn't find the EMM handle your
program specified.

EMM Functions 61





Function 13. Get Handle Pages



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.


EXAMPLE

emm_handle DW ?
pages_alloc_to_handle DW ?

MOV DX,emm_handle ; load EMM handle
MOV AH,4Ch ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error
MOV pages_alloc_to_handle,BX ; save number of pages
; allocated to specified
; handle






























EMM Functions 62





Function 14. Get All Handle Pages



PURPOSE

The Get All Handle Pages function returns an array of the
open EMM handles and the number of pages allocated to each
one.


CALLING PARAMETERS

AH = 4Dh
Contains the Get All Handle Pages function.

handle_page_struct STRUC
emm_handle DW ?
pages_alloc_to_handle DW ?
handle_page_struct ENDS

ES:DI = pointer to handle_page
Contains a pointer to an array of structures where a
copy of all open EMM handles and the number of pages
allocated to each will be stored. Each structure has
these two members:

.emm_handle
The first member is a word which contains the value
of the open EMM handle. The values of the handles
this function returns will be in the range of 0 to
255 decimal (0000h to 00FFh). The uppermost byte of
the handle is always zero.

.pages_alloc_to_handle
The second member is a word which contains the
number of pages allocated to the open EMM handle.


RESULTS

These results are valid only if the status returned is zero.

BX = total_open_emm_handles
Contains the number of open EMM handles (including the
operating system handle [0]). The number cannot be zero
because the operating system handle is always active and
cannot be deallocated. This number will not exceed 255.





EMM Functions 63





Function 14. Get All Handle Pages



REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the array.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.


EXAMPLE

handle_page handle_page_struct 255 DUP (?)
total_open_handles DW ?

MOV AX,SEG handle_page
MOV ES,AX
LEA DI,handle_page ; ES:DI points to handle_page
MOV AH,4Dh ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check the EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV total_open_handles,BX ; save total open handle count













EMM Functions 64





Function 15. Get/Set Page Map
Get Page Map subfunction



PURPOSE

The Get Page Map subfunction saves the mapping context for
all mappable memory regions (conventional and expanded) by
copying the contents of the mapping registers from each
expanded memory board to a destination array. The applica-
tion must pass a pointer to the destination array. This
subfunction doesn't require an EMM handle.

Use this function instead of Functions 8 and 9 if you need
to save or restore the mapping context but don't want (or
have) to use a handle.


CALLING PARAMETERS

AX = 4E00h
Contains the Get Page Map subfunction.

ES:DI = dest_page_map
Contains a pointer to the destination array address in
segment:offset format. Use the Get Size of Page Map
Save Array subfunction to determine the size of the
desired array.


RESULTS

These results are valid only if the status returned is zero.

dest_page_map
The array contains the state of all the mapping regis-
ters on all boards in the system. It also contains any
additional information necessary to restore the boards
to their original state when the program invokes a Set
subfunction.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the array.

EMM Functions 65





Function 15. Get/Set Page Map
Get Page Map subfunction



AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

dest_page_map DB ? DUP (?)

MOV AX,SEG dest_page_map
MOV ES,AX
LEA DI,dest_page_map ; ES:DI points to dest_page_map
MOV AX,4E00h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error





















EMM Functions 66





Function 15. Get/Set Page Map
Set Page Map subfunction



PURPOSE

The Set Page Map subfunction restores the mapping context
for all mappable memory regions (conventional and expanded)
by copying the contents of a source array into the mapping
registers on each expanded memory board in the system. The
application must pass a pointer to the source array. This
subfunction doesn't require an EMM handle.

Use this function instead of Functions 8 and 9 if you need
to save or restore the mapping context but don't want (or
have) to use a handle.


CALLING PARAMETERS

AX = 4E01h
Contains the Set Page Map subfunction.

DS:SI = source_page_map
Contains a pointer to the source array address in
segment:offset format. The application must point to an
array which contains the mapping register state. Use
the Get Size of Page Map Save Array subfunction to
determine the size of the desired array.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has passed the array.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.




EMM Functions 67





Function 15. Get/Set Page Map
Set Page Map subfunction



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A3h NON-RECOVERABLE.
The contents of the source array have been corrupted, or
the pointer passed to the subfunction is invalid.


EXAMPLE

source_page_map DB ? DUP (?)

MOV AX,SEG source_page_map
MOV DS,AX
LEA SI,source_page_map ; DS:SI points to source_page_map
MOV AX,4E01h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error

























EMM Functions 68





Function 15. Get/Set Page Map
Get & Set Page Map subfunction



PURPOSE

The Get & Set Page Map subfunction simultaneously saves a
current mapping context and restores a previous mapping
context for all mappable memory regions (both conventional
and expanded). It first copies the contents of the mapping
registers from each expanded memory board in the system into
a destination array. (The application must pass a pointer
to the destination array.) Then, the subfunction copies the
contents of a source array into the mapping registers on
each of the expanded memory boards. (The application must
pass a pointer to the source array.)

Use this function instead of Functions 8 and 9 if you need
to save or restore the mapping context but don't want (or
have) to use a handle.


CALLING PARAMETERS

AX = 4E02h
Contains the Get & Set Page Map subfunction.

ES:DI = dest_page_map
Contains a pointer to the destination array address in
segment:offset format. The current contents of the map
registers will be saved in this array.

DS:SI = source_page_map
Contains a pointer to the source array address in
segment:offset format. The contents of this array will
be copied into the map registers. The application must
point to an array which contains the mapping register
state. This address is required only for the Set or Get
and Set subfunctions.


RESULTS


These results are valid only if the status returned is zero.

dest_page_map
The array contains the mapping state. It also contains
any additional information necessary to restore the
original state when the program invokes a Set subfunc-
tion.


EMM Functions 69





Function 15. Get/Set Page Map
Get & Set Page Map subfunction



REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned and passed both arrays.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A3h NON-RECOVERABLE.
The contents of the source array have been corrupted, or
the pointer passed to the subfunction is invalid.


EXAMPLE

dest_page_map DB ? DUP (?)

source_page_map DB ? DUP (?)

MOV AX,SEG dest_page_map
MOV ES,AX
MOV AX,SEG source_page_map
MOV DS,AX
LEA DI,dest_page_map ; ES:DI points to dest_page_map
LEA SI,source_page_map ; DS:SI points to source_page_map
MOV AX,4E02h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error


EMM Functions 70





Function 15. Get/Set Page Map
Get Size of Page Map Save Array subfunction



PURPOSE

The Get Size of Page Map Save Array subfunction returns the
storage requirements for the array passed by the other three
subfunctions. This subfunction doesn't require an EMM
handle.


CALLING PARAMETERS

AX = 4E03h
Contains the Get Size of Page Map Save Array subfunc-
tion. The size of this array depends on how the
expanded memory system is configured and how the
expanded memory manager is implemented. Therefore, the
size must be determined after the memory manager is
loaded.


RESULTS

These results are valid only if the status returned is zero.

AL = size_of_array
Contains the number of bytes that will be transferred to
the memory area an application supplies whenever a
program requests the Get, Set, or Get and Set subfunc-
tions.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the array size.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

EMM Functions 71





Function 15. Get/Set Page Map
Get Size of Page Map Save Array subfunction



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

size_of_array DB ?

MOV AX,4E03h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV size_of_array,AL ; save array size































EMM Functions 72





Function 16. Get/Set Partial Page Map
Get Partial Page Map subfunction



PURPOSE

The Get Partial Page Map subfunction saves a partial mapping
context for specific mappable memory regions in a system.
Because this function saves only a subset of the entire
mapping context, it uses much less memory for the save area
and may be potentially faster than Function 15. The
subfunction does this by copying the contents of selected
mapping registers from each expanded memory board to a
destination array.

The application must pass a pair of pointers. The first
points to a structure which specifies which mappable
segments to save; the second points to the destination
array.

Use this function instead of Functions 8 and 9 if you need
to save or restore the mapping context but don't want (or
have) to use a handle.


CALLING PARAMETERS

AX = 4F00h
Contains the Get Partial Page Map subfunction.

partial_page_map_struct STRUC
mappable_segment_count DW ?
mappable_segment DW (?) DUP (?)
partial_page_map_struct ENDS

DS:SI = partial_page_map
Contains a pointer to a structure which specifies only
those mappable memory regions which are to have their
mapping context saved. The structure members are
described below.

.mappable_segment_count
The first member is a word which specifies the
number of members in the word array which immediate-
ly follows it. This number should not exceed the
number of mappable segments in the system.






EMM Functions 73





Function 16. Get/Set Partial Page Map
Get Partial Page Map subfunction



.mappable_segment
The second member is a word array which contains the
segment addresses of the mappable memory regions
whose mapping contexts are to be saved. The segment
address must be a mappable segment. Use Function 25
to determine which segments are mappable.

ES:DI = dest_array
Contains a pointer to the destination array address in
segment:offset format. To determine the size of the
required array, see the Get Size of Partial Page Map
Save Array subfunction.


RESULTS

These results are valid only if the status returned is zero.

dest_array
The array contains the partial mapping context and any
additional information necessary to restore this context
to its original state when the program invokes a Set
subfunction.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has saved the partial map context.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.


EMM Functions 74





Function 16. Get/Set Partial Page Map
Get Partial Page Map subfunction



AH = 8Bh NON-RECOVERABLE.
One of the specified segments is not a mappable segment.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A3h NON-RECOVERABLE.
The contents of the partial page map structure have been
corrupted, the pointer passed to the subfunction is
invalid, or the mappable_segment_count exceeds the
number of mappable segments in the system.


EXAMPLE

partial_page_map partial_page_map_struct <>

dest_array DB ? DUP (?)

MOV AX,SEG partial_page_map
MOV DS,AX
LEA SI,partial_page_map ; DS:SI points to partial_page_map
MOV AX,SEG dest_array
MOV ES,AX
LEA DI,dest_array ; ES:DI points to dest_array
MOV AX,4F00h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error



















EMM Functions 75





Function 16. Get/Set Partial Page Map
Set Partial Page Map subfunction



PURPOSE

The Set Partial Page Map subfunction provides a mechanism
for restoring the mapping context for a partial mapping
context for specific mappable memory regions in a system.
Because this function restores only a subset of the entire
mapping context and not the entire systems mapping context,
it uses much less memory for the save area and is potential-
ly faster than Function 15. The subfunction does this by
copying the contents of the source array to selected mapping
registers on each expanded memory board. The application
passes a pointer to the source array.

Use this function instead of Functions 8 and 9 if you need
to save or restore the mapping context but don't want (or
have) to use a handle.


CALLING PARAMETERS

AX = 4F01h
Contains the Set Partial Page Map subfunction

source_array DB ? DUP (?)

DS:SI = source_array
Contains a pointer to the source array in segment:offset
format. The application must point to an array which
contains the partial mapping register state. To deter-
mine the size of the required array, see the Get Size of
Partial Page Map Save Array subfunction.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has restored the partial mapping context.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.


EMM Functions 76





Function 16. Get/Set Partial Page Map
Set Partial Page Map subfunction



AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A3h NON-RECOVERABLE.
The contents of the source array have been corrupted, or
the pointer passed to the subfunction is invalid.


EXAMPLE

MOV AX,SEG source_array
MOV DS,AX
LEA SI,source_array ; DS:SI points to source_array
MOV AX,4F01h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error























EMM Functions 77





Function 16. Get/Set Partial Page Map
Get Size of Partial Page Map Save Array subfunction



PURPOSE

The Get Size of Partial Page Map Save Array subfunction
returns the storage requirements for the array passed by the
other two subfunctions. This subfunction doesn't require an
EMM handle.


CALLING PARAMETERS

AX = 4F02h
Contains the Get Size of Partial Page Map Save Array
subfunction. The size of this array depends on the
expanded memory system configuration and the implementa-
tion of the expanded memory manager. Therefore, it will
vary between hardware configurations and implementations
and must be determined after a specific memory manager
is loaded.

BX = number of pages in the partial array
Contains the number of pages in the partial map to be
saved by the Get/Set Partial Page Map subfunctions.
This number should be the same as the mappable_seg-
ment_count in the Get Partial Page Map subfunction.


RESULTS

These results are valid only if the status returned is zero.

AL = size_of_partial_save_array
Contains the number of bytes that will be transferred to
the memory areas supplied by an application whenever a
program requests the Get or Set subfunction.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the array size.



EMM Functions 78





Function 16. Get/Set Partial Page Map
Get Size of Partial Page Map Save Array subfunction



AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Bh NON-RECOVERABLE.
The number of pages in the partial array is outside the
range of physical pages in the system.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

number_of_pages_to_map DW ?
size_of_partial_save_array DB ?

MOV BX,number_of_pages_to_map
MOV AX,4F02h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error
MOV size_of_partial_save_array,AL ; save array size
















EMM Functions 79





Function 17. Map/Unmap Multiple Handle Pages



PURPOSE

This function can, in a single invocation, map (or unmap)
logical pages into as many physical pages as the system
supports. Consequently, it has less execution overhead than
mapping pages one at a time. For applications which do a
lot of page mapping, this is the preferred mapping method.


Mapping Multiple Pages

The handle passed to this function determines what type of
logical pages are being mapped. Logical pages that Function
4 and Function 27 (Allocate Standard Pages subfunction)
allocate are referred to as pages and are 16K bytes.
Logical pages that Function 27 (Allocate Raw Pages subfunc-
tion) allocates are referred to as raw pages and might not
be the same size as the pages Function 4 and Function 27
(Allocate Standard Pages subfunction) allocate.


Unmapping Multiple Pages

This function can make specific physical pages unavailable
for reading or writing. A logical page which is unmapped
from a specific physical page cannot be read or written from
that physical page. The logical page which is unavailable
(unmapped) can be made available again by mapping it, or a
new logical page, at the physical page that was unmapped.
Unmapping a physical page is accomplished by setting the
logical page it is associated with to FFFFh.

You might unmap an entire set of mapped pages, for example,
before loading and executing a program. This ensures that
the loaded program won't be able to access the pages your
program has mapped. However, you must save the mapping
context before you unmap the physical pages. This enables
you to restore it later so that you may access the memory
you had mapped there. You can save the mapping context with
Functions 8, 15, or 16. You can restore the mapping context
with Functions 9, 15, or 16.


Mapping and Unmapping Multiple Pages Simultaneously

Both mapping and unmapping pages can be done in the same
invocation.


EMM Functions 80





Function 17. Map/Unmap Multiple Handle Pages



Mapping or unmapping no pages is not considered an error.
If a request to map or unmap zero pages is made, nothing is
done and no error is returned.


Alternate Mapping and Unmapping Methods

You can map or unmap pages using two methods. Both methods
produce identical results.

1. The first method specifies both a logical page and a
physical page at which the logical page is to be mapped.
This method is an extension of Function 5 (Map Handle
Page).

2. The second method specifies both a logical page and a
corresponding segment address at which the logical page
is to be mapped. While this is functionally the same as
the first method, it may be easier to use the actual
segment address of a physical page than to use a number
which only represents its location. The memory manager
verifies whether the specified segment address falls on
the boundary of a mappable physical page. The manager
then translates the segment address passed to it into
the necessary internal representation to map the pages.
























EMM Functions 81





Function 17. Map/Unmap Multiple Handle Pages
Logical Page/Physical Page Method


CALLING PARAMETERS

AX = 5000h
Contains the Map/Unmap Multiple Handle Pages subfunction
using the logical page/physical page method.

log_to_phys_map_struct STRUC
log_page_number DW ?
phys_page_number DW ?
log_to_phys_map_struct ENDS

DX = handle
Contains the EMM handle.

CX = log_to_phys_map_len
Contains the number of entries in the array. For
example, if the array contained four pages to map or
unmap, then CX would contain 4. The number in CX should
not exceed the number of mappable pages in the system.

DS:SI = pointer to log_to_phys_map array
Contains a pointer to an array of structures that
contains the information necessary to map the desired
pages. The array is made up of the following two
elements:

.log_page_number
The first member is a word which contains the number
of the logical page which is to be mapped. Logical
pages are numbered zero-relative, so the number for
a logical page can only range from zero to (maximum
number of logical pages allocated to the handle -
1).

If the logical page number is set to FFFFh, the
physical page associated with it is unmapped rather
than mapped. Unmapping a physical page makes it
inaccessible for reading or writing.

.phys_page_number
The second member is a word which contains the
number of the physical page at which the logical
page is to be mapped. Physical pages are numbered
zero-relative, so the number for a physical page can
only range from zero to (maximum number of physical
pages supported in the system - 1).



EMM Functions 82





Function 17. Map/Unmap Multiple Handle Pages
Logical Page/Physical Page Method



REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The logical pages have been mapped, or unmapped, at the
specified physical pages.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager couldn't find the specified EMM handle. The
manager doesn't currently have any information pertain-
ing to the specified EMM handle. The program has
probably corrupted its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Ah RECOVERABLE.
One or more of the mapped logical pages is out of the
range of logical pages allocated to the EMM handle. The
program can recover by attempting to map a logical page
which is within the bounds for the specified EMM handle.
When this error occurs, the only pages mapped were the
ones valid up to the point that the error occurred.

AH = 8Bh RECOVERABLE.
One or more of the physical pages is out of the range of
mappable physical pages, or the log_to_phys_map_len
exceeds the number of mappable pages in the system. The
program can recover from this condition by attempting to
map into memory at the physical page which is in the
range of the physical page numbers supported by the
system. When this error occurs, the only pages mapped
were the ones valid up to the point that the error
occurred.


EMM Functions 83





Function 17. Map/Unmap Multiple Handle Pages
Logical Page/Physical Page Method



AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

log_to_phys_map log_to_phys_map_struct ? DUP (?)

emm_handle DW ?

MOV AX,SEG log_to_phys_map
MOV DS,AX
LEA SI,log_to_phys_map ; DS:SI points to
; log_to_phys_map
MOV CX,LENGTH log_to_phys_map ; set length field
MOV DX,emm_handle
MOV AX,5000h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error



























EMM Functions 84





Function 17. Map/Unmap Multiple Handle Pages
Logical Page/Segment Address Method


CALLING PARAMETERS

AX = 5001h
Contains the Map/Unmap Multiple Handle Pages subfunction
using the logical page/segment address method.

log_to_seg_map_struct STRUC
log_page_number DW ?
mappable_segment_address DW ?
log_to_seg_map_struct ENDS

DX = handle
Contains the EMM handle.

CX = log_to_segment_map_len
Contains the number of entries in the array. For
example, if the array contained four pages to map or
unmap, then CX would contain four.

DS:SI = pointer to log_to_segment_map array
Contains a pointer to an array of structures that
contains the information necessary to map the desired
pages. The array is made up of the following elements:

.log_page_number
The first member is a word which contains the number
of the logical pages to be mapped. Logical pages
are numbered zero-relative, so the number for a
logical page can range from zero to (maximum number
of logical pages allocated to the handle - 1).

If the logical page number is set to FFFFh, the
physical page associated with it is unmapped rather
than mapped. Unmapping a physical page makes it
inaccessible for reading or writing.

.mappable_segment_address
The second member is a word which contains the
segment address at which the logical page is to be
mapped. This segment address must correspond
exactly to a mappable segment address. The mappable
segment addresses are available with Function 25
(Get Mappable Physical Address Array).


REGISTERS MODIFIED

AX

EMM Functions 85





Function 17. Map/Unmap Multiple Handle Pages
Logical Page/Segment Address Method



STATUS

AH = 0 SUCCESSFUL.
The logical pages have been mapped (or unmapped) at the
specified physical pages.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager could not find the specified EMM handle.
The manager doesn't currently have any information
pertaining to the specified EMM handle. The program has
probably corrupted its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Ah RECOVERABLE.
One or more of the logical pages to be mapped is out of
the range of logical pages allocated to the EMM handle.
The program can recover from this condition by mapping a
logical page which is within the bounds for the speci-
fied EMM handle. When this error occurs, the only pages
mapped or unmapped were the ones valid up to the point
that the error occurred.

AH = 8Bh RECOVERABLE.
One or more of the mappable segment addresses specified
is not mappable, the segment address doesn't fall
exactly on a mappable address boundary, or the log_to_-
segment_map_len exceeds the number of mappable segments
in the system. The program can recover from this
condition by mapping into memory on an exact mappable
segment address. When this error occurs, the only pages
mapped were the ones valid up to the point that the
error occurred.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.



EMM Functions 86





Function 17. Map/Unmap Multiple Handle Pages
Logical Page/Segment Address Method



EXAMPLE

log_to_seg_map log_to_seg_map_struct 4 DUP (?)

emm_handle DW ?

MOV AX,SEG log_to_seg_map
MOV DS,AX
LEA SI,log_to_seg_map ; DS:SI points to
; log_to_seg_map
MOV CX,LENGTH log_to_seg_map
MOV DX,emm_handle
MOV AX,5001h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error































EMM Functions 87





Function 18. Reallocate Pages



PURPOSE

This function allows an application program to increase or
decrease (reallocate) the number of logical pages allocated
to an EMM handle. There are four reallocation cases of
interest:

1. A reallocation count of zero. The handle assigned to
the application remains assigned and is still available
for use by the application. The memory manager won't
reassign the handle to any other application. However,
the handle will have any currently allocated pages
returned to the memory manager. The application must
invoke the Deallocate Pages function (Function 6) before
returning to DOS, or the handle will remain assigned and
no other application will be able to use it.

2. A reallocation count equal to the current allocation
count. This is not treated as an error, and a success-
ful status is returned.

3. A reallocation count greater than the current allocation
count. The memory manager will attempt to add new pages
to those pages already allocated to the specified EMM
handle. The number of new pages added is the difference
between the reallocation count and the current alloca-
tion count. The sequence of logical pages allocated to
the EMM handle remains continuous after this operation.
The newly allocated pages have logical page numbers
which begin where the previously allocated pages ended,
and continue in ascending sequence.

4. A reallocation count less than the current allocation
count. The memory manager will attempt to subtract some
of the currently allocated pages and return them to the
memory manager. The number of old pages subtracted is
the difference between the current allocation count and
the re-allocation count. The pages are subtracted from
the end of the sequence of pages currently allocated to
the specified EMM handle. The sequence of logical pages
allocated to the EMM handle remains continuous after
this operation.







EMM Functions 88





Function 18. Reallocate Pages



The handle determines what type of logical pages are being
reallocated. Logical pages which were originally allocated with
Function 4 or Function 27 (Allocate Standard Pages subfunction)
are called pages and are 16K bytes long. Logical pages which
were allocated with Function 27 (Allocate Raw Pages subfunction)
are called raw pages and might not be the same size as pages
allocated with Function 4.


CALLING PARAMETERS

AH = 51h
Contains the Reallocate Handle Pages function.

DX = handle
Contains the EMM handle.

BX = reallocation_count
Contains the total number of pages this handle should
have allocated to it after this function is invoked.


RESULTS

BX = number of pages allocated to handle after reallocation
Contains the number of pages now allocated to the EMM
handle after the pages have been added or subtracted.
If the status returned is not zero, the value in BX is
equal to the number of pages allocated to the handle
prior to the invocation of this function. This informa-
tion can be used to verify that the request generated
the expected results.


REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The pages specified have been added to or subtracted
from the handle specified.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

EMM Functions 89





Function 18. Reallocate Pages



AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager could not find the specified EMM handle.
The manager doesn't have any information pertaining to
the specified EMM handle. The program may have cor-
rupted its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 87h RECOVERABLE.
The number of pages that are available in the system is
insufficient for the new allocation request. The
program can recover from this condition by specifying
fewer pages be allocated to the EMM handle.

AH = 88h RECOVERABLE.
The number of unallocated pages is insufficient for the
new allocation request. The program can recover from
this condition by either requesting again when addition-
al pages are available or specifying fewer pages.


EXAMPLE

emm_handle DW ?
realloc_count DW ?
current_alloc_page_count DW ?

MOV DX,emm_handle ; specify EMM handle
MOV BX,realloc_count ; specify count
MOV AH,51h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error
MOV current_alloc_page_count,BX









EMM Functions 90





Function 19. Get/Set Handle Attribute



Design Considerations

This function is an option which will probably not be
available in a typical expanded memory manager, system, or
memory board. Most personal computer systems disable memory
refresh signals for a considerable period during a warm
boot. This can corrupt some of the data in memory boards,
even though there is no problem with the design of the
memory board, its operation, or the memory chips. This
memory refresh deficiency is present in the software design
of the ROM BIOS in most personal computer systems.

The majority of memory board designs, chip types, or
personal computer systems won't be able to support the non-
volatility feature. The reason that this ROM BIOS deficien-
cy is not evident in the conventional or extended memory
area is that the ROM BIOS always initializes this area
during a warm boot. Memory data integrity is not a problem
with the conventional or extended memory region, because it
isn't physically possible to have data retained there across
a warm boot event -- the ROM BIOS sets it to zero.

Consequently, expanded memory board manufacturers should not
supply this function unless their board can guarantee the
integrity of data stored in the board's memory during a warm
boot. Generally, this means the memory board has an
independent memory refresh controller which does not depend
on the system board's memory refresh.

If the expanded memory manager, system, or memory board
cannot support this feature, it should return the not
supported status described in the function.

















EMM Functions 91





Function 19. Get/Set Handle Attribute
Get Handle Attribute subfunction



PURPOSE

This subfunction returns the attribute associated with a
handle. The attributes are volatile or non-volatile.
Handles with non-volatile attributes enable the memory
manager to save the contents of a handle's pages between
warm boots. However, this function may be disabled with a
user option or may not be supported by the memory board or
system hardware.

If the handle's attribute has been set to non-volatile, the
handle, its name (if it is assigned one), and the contents
of the pages allocated to the handle are all maintained
after a warm boot.


CALLING PARAMETERS

AX = 5200h
Contains the Get Handle Attribute subfunction.

DX = handle
Contains the EMM handle.


RESULTS

These results are valid only if the status returned is zero.

AL = handle attribute
Contains the EMM handle's attribute. The only at-
tributes a handle may have are volatile or non-volatile.
A value of zero indicates the handle is volatile. A
value of one indicates that the handle is non-volatile.


REGISTERS MODIFIED

AX



STATUS

AH = 0 SUCCESSFUL.
The handle's attribute has been obtained.



EMM Functions 92





Function 19. Get/Set Handle Attribute
Get Handle Attribute subfunction



AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager couldn't find the specified EMM handle. The
manager doesn't have any information pertaining to the
specified EMM handle. The program may have corrupted
its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 91h NON-RECOVERABLE.
This feature is not supported.


EXAMPLE

emm_handle DW ?
handle_attrib DB ?

MOV DX,emm_handle ; specify EMM handle
MOV AX,5200h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV handle_attrib,AL ; save handle attribute













EMM Functions 93





Function 19. Get/Set Handle Attribute
Set Handle Attribute subfunction



PURPOSE

This subfunction can be used to modify the attribute which a
handle has associated with it. The attributes which a
handle may have are volatile or non-volatile. The non-
volatile attribute enables the EMM to save the contents of a
handle's pages between warm boots. However, this function
may be disabled with a user option or may not be supported
by the memory board or system hardware.

If the handle's attribute has been set to non-volatile, the
handle, its name (if it is assigned one), and the contents
of the pages allocated to the handle are all maintained
after a warm boot.


CALLING PARAMETERS

AX = 5201h
Contains the Set Handle Attribute function.

DX = handle
Contains the EMM handle.

BL = new handle attribute
Contains the handle's new attribute. A value of zero
indicates that the handle should be made volatile. A
value of one indicates that the handle should be made
non-volatile.

A volatile handle attribute instructs the memory manager
to deallocate both the handle and the pages allocated to
it after a warm boot. If all handles have the volatile
attribute (the default attribute) at warm boot, the
handle directory will be empty and all of expanded
memory will be initialized to zero immediately after a
warm boot.


REGISTERS MODIFIED

AX






EMM Functions 94





Function 19. Get/Set Handle Attribute
Set Handle Attribute subfunction



STATUS

AH = 0 SUCCESSFUL.
The handle's attribute has been modified.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager could not find the specified EMM handle.
The manager doesn't have any information pertaining to
the specified EMM handle. The program may have cor-
rupted its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 90h NON-RECOVERABLE.
The attribute type is undefined.

AH = 91h NON-RECOVERABLE.
This feature is not supported.


EXAMPLE

emm_handle DW ?
new_handle_attrib DB ?

MOV DX,emm_handle ; specify EMM handle
MOV BL,new_handle_attrib ; specify the set attribute
MOV AX,5201h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error





EMM Functions 95





Function 19. Get/Set Handle Attribute
Get Attribute Capability subfunction



PURPOSE

This subfunction can be used to determine whether the memory
manager can support the non-volatile attribute.


CALLING PARAMETERS

AX = 5202h
Contains the Get Attribute Capability subfunction.


RESULTS

These results are valid only if the status returned is zero.

AL = attribute capability
Contains the attribute capability. A value of zero
indicates that the memory manager and hardware supports
only volatile handles. A value of one indicates that
the memory manager/hardware supports both volatile and
non-volatile handles.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The attribute capability has been returned.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

EMM Functions 96





Function 19. Get/Set Handle Attribute
Get Attribute Capability subfunction



EXAMPLE

attrib_capability DB ?

MOV AX,5202h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV attrib_capability,AL ; save attribute capability







































EMM Functions 97





Function 20. Get/Set Handle Name
Get Handle Name subfunction



PURPOSE

This subfunction gets the eight character name currently
assigned to a handle. There is no restriction on the
characters which may be used in the handle name (that is,
anything from 00h through FFh).

The handle name is initialized to ASCII nulls (binary zeros)
three times: when the memory manager is installed, when a
handle is allocated, and when a handle is deallocated. A
handle with a name which is all ASCII nulls, by definition,
has no name. When a handle is assigned a name, at least one
character in the name must be a non-null character in order
to distinguish it from a handle without a name.


CALLING PARAMETERS

AX = 5300h
Contains the Get Handle Name function.

DX = handle number
Contains the EMM handle.

ES:DI = pointer to handle_name array
Contains a pointer to an eight-byte array into which the
name currently assigned to the handle will be copied.


RESULTS

These results are valid only if the status returned is zero.

handle_name array
Contains the name associated with the specified handle.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The handle name has been returned.


EMM Functions 98





Function 20. Get/Set Handle Name
Get Handle Name subfunction



AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager couldn't find the specified EMM handle. The
manager doesn't have any information on the specified
EMM handle. The program may have corrupted its EMM
handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

handle_name DB 8 DUP (?)
emm_handle DW ?

MOV AX,SEG handle_name
MOV ES,AX
LEA DI,handle_name ; ES:DI points to handle_name
MOV DX,emm_handle ; specify EMM handle
MOV AX,5300h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error














EMM Functions 99





Function 20. Get/Set Handle Name
Set Handle Name subfunction



PURPOSE

This subfunction assigns an eight character name to a
handle. There is no restriction on the characters which may
be used in the handle name. The full range of values may be
assigned to each character in a name (that is, 00h through
FFh).

At installation, all handles have their name initialized to
ASCII nulls (binary zeros). A handle with a name consisting
of all ASCII nulls has no name. When a handle is assigned a
name, at least one character in the name must be a non-null
character in order to distinguish it from a handle without a
name. No two handles may have the same name.

A handle can be renamed at any time by setting the handle's
name to a new value. A handle can have its name removed by
setting the handle's name to all ASCII nulls. When a handle
is deallocated, its name is removed (set to ASCII nulls).


CALLING PARAMETERS

AX = 5301h
Contains the Set Handle Name function.

DX = handle number
Contains the EMM handle.

DS:SI = pointer to handle_name
Contains a pointer to a byte array which contains the
name that is to be assigned to the handle. The handle
name must be padded with nulls if the name is less than
eight characters long.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The handle name has been assigned.



EMM Functions 100





Function 20. Get/Set Handle Name
Set Handle Name subfunction



AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager couldn't find the specified EMM handle. The
manager doesn't currently have any information pertain-
ing to the specified EMM handle. The program may have
corrupted its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A1h RECOVERABLE.
A handle with this name already exists. The specified
handle was not assigned a name.


EXAMPLE

handle_name DB 'AARDVARK'
emm_handle DW ?

MOV AX,SEG handle_name
MOV DS,AX
LEA SI,handle_name ; DS:SI points to handle_name
MOV DX,emm_handle ; specify EMM handle
MOV AX,5301h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error










EMM Functions 101





Function 21. Get Handle Directory
Get Handle Directory subfunction



PURPOSE

This function returns an array which contains all active
handles and the names associated with each. Handles which
have not been assigned names have a default name of all
ASCII nulls (binary zeros). When a handle is first allo-
cated, or when all the pages belonging to a handle are
deallocated (that is, an open handle is closed), its default
name is set to ASCII nulls. It takes a subsequent assign-
ment of a name for a handle to have a name after it has been
opened. The full range of values may be assigned to each
character in a name (that is, 00h through FFh).

The number of bytes required by the array is:

10 bytes * total number of handles

The maximum size of this array is:

(10 bytes/entry) * 255 entries = 2550 bytes.


CALLING PARAMETERS

AX = 5400h
Contains the Get Handle Directory function.

handle_dir_struct STRUC
handle_value DW ?
handle_name DB 8 DUP (?)
handle_dir_struct ENDS

ES:DI = pointer to handle_dir
Contains a pointer to an area of memory into which the
memory manager will copy the handle directory. The
handle directory is an array of structures. There are
as many entries in the array as there are open EMM
handles. The structure consists of the following
elements:

.handle_value
The first member is a word which contains the value
of the open EMM handle.





EMM Functions 102





Function 21. Get Handle Directory
Get Handle Directory subfunction



.handle_name
The second member is an 8 byte array which contains
the ASCII name associated with the EMM handle. If
there is no name currently associated with the
handle, it has a value of all zeros (ASCII nulls).


RESULTS

These results are valid only if the status returned is zero.

handle_dir
Contains the handle values and handle names associated
with each handle value.

AL = number of entries in the handle_dir array
Contains the number of entries in the handle directory
array. This is also the same as the number of open
handles. For example, if only one handle is active, AL
will contain a one.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The handle directory has been returned.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.



EMM Functions 103





Function 21. Get Handle Directory
Get Handle Directory subfunction



EXAMPLE

handle_dir handle_dir_struct 255 DUP (?)

num_entries_in_handle_dir DB ?

MOV AX,SEG handle_dir
MOV ES,AX
LEA DI,handle_dir ; ES:DI points to handle_dir
MOV AX,5400h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error
MOV num_entries_in_handle_dir,AL ; save number of entries

































EMM Functions 104





Function 21. Get Handle Directory
Search For Named Handle subfunction



PURPOSE

This subfunction searches the handle name directory for a

handle with a particular name. If the named handle is
found, this subfunction returns the handle number associated
with the name. At the time of installation, all handles
have their names initialized to ASCII nulls. A handle with
a name which is all ASCII nulls has, by definition, no name.
When a handle is assigned a name, at least one character in
the name must be a non-null character in order to distin-
guish it from a handle without a name.


CALLING PARAMETERS

AX = 5401h
Contains the Search for Named Handle subfunction.

DS:SI = handle_name
Contains a pointer to an 8-byte string that contains the
name of the handle being searched for.


RESULTS

These results are valid only if the status returned is zero.

DX = value of named handle
The value of the handle which matches the handle name
specified.


REGISTERS MODIFIED

AX, DX


STATUS

AH = 0 SUCCESSFUL.
The handle value for the named handle has been found.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.



EMM Functions 105





Function 21. Get Handle Directory
Search For Named Handle subfunction



AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A0h NON-RECOVERABLE.
No corresponding handle could be found for the handle
name specified.

AH = A1h NON-RECOVERABLE.
A handle found had no name (all ASCII nulls).


EXAMPLE

named_handle DB 'AARDVARK'
named_handle_value DW ?

MOV AX,SEG named_handle
MOV DS,AX
LEA SI,named_handle ; DS:SI points to named_handle
MOV AX,5401h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV named_handle_value,DX ; save value of named handle

















EMM Functions 106





Function 21. Get Handle Directory
Get Total Handles subfunction



PURPOSE

This subfunction returns the total number of handles that
the memory manager supports, including the operating system
handle (handle value 0).


CALLING PARAMETERS

AX = 5402h
Contains the Get Total Handles subfunction.


RESULTS

These results are valid only if the status returned is zero.

BX = total_handles
The value returned represents the maximum number of
handles which a program may request the memory manager
to allocate memory to. The value returned includes the
operating system handle (handle value 0).


REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The total number of handles supported has been returned.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

EMM Functions 107





Function 21. Get Handle Directory
Get Total Handles subfunction



EXAMPLE

total_handles DW ?

MOV AX,5402h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV total_handles,BX ; save total handle count







































EMM Functions 108





Function 22. Alter Page Map & Jump



PURPOSE

This function alters the memory mapping context and trans-
fers control to the specified address. It is analogous to
the FAR JUMP in the 8086 family architecture. The memory
mapping context which existed before the invocation of this
function is lost.

Mapping no pages and jumping is not considered an error. If
a request to map zero pages and jump is made, control is
transferred to the target address, and this function
performs a far jump.


CALLING PARAMETERS

AH = 55h
Contains the Alter Page Map & Jump function.

log_phys_map_struct STRUC
log_page_number DW ?
phys_page_number_seg DW ?
log_phys_map_struct ENDS

map_and_jump_struct STRUC
target_address DD ?
log_phys_map_len DB ?
log_phys_map_ptr DD ?
map_and_jump_struct ENDS

AL = physical page number/segment selector
Contains a code which indicates whether the value
contained in the

.log_phys_map.phys_page_number_seg

members are physical page numbers or are the segment
address representation of the physical page numbers. A
zero in AL indicates that the values are physical page
numbers. A one in AL indicates that the values in these
members are the segment address representations of the
physical page numbers.

DX = handle number
Contains the EMM handle.




EMM Functions 109





Function 22. Alter Page Map & Jump



DS:SI = pointer to map_and_jump structure
Contains a pointer to a structure that contains the
information necessary to map the desired physical pages
and jump to the target address. The structure consists
of the following elements:

.target_address
The first member is a far pointer which contains the
target address to which control is to be trans-
ferred. The address is represented in segment:of-
fset format. The offset portion of the address is
stored in the low portion of the double word.

.log_phys_map_len
The second member is a byte which contains the
number of entries in the array of structures which
immediately follows it. The array is as long as the
application developer needs in order to map the
desired logical pages into physical pages. The
number of entries cannot exceed the number of
mappable pages in the system.

.log_phys_map_ptr
The third member is a pointer to an array of struc-
tures which contain the logical page numbers and
physical pages or segment address at which they are
to be mapped. Each entry in the array of structures
contains the following two elements:

.log_page_number
The first member of this structure is a word which
contains the number of the logical page to be
mapped.

.phys_page_number_seg
The second member of this structure is a word which
contains either the physical page number or the
segment address representation of the physical page
number at which the previous logical page number is
to be mapped. The value passed in AL determines the
type of representation.


REGISTERS MODIFIED

AX



EMM Functions 110





Function 22. Alter Page Map & Jump



Note............................................................
Values in registers which don't contain required parameters
maintain the values across the jump. The values in regis-
ters (with the exception of AX) and the flag state at the
beginning of the function are still in the registers and
flags when the target address is reached.


STATUS

AH = 0 SUCCESSFUL.
Control has been transferred to the target address.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager could not find the specified EMM handle.
The manager does not currently have any information
pertaining to the specified EMM handle. The program may
have corrupted its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Ah RECOVERABLE.
One or more of the logical pages to map into a cor-
responding physical page is out of the range of logical
pages which are allocated to the EMM handle. The
program can recover from this condition by mapping a
logical page which is within the bounds for the EMM
handle.

AH = 8Bh RECOVERABLE.
One or more of the physical pages is out of the range of
allowable physical pages, or the log_phys_map_len
exceeds the number of mappable pages in the system.
Physical page numbers are numbered zero-relative. The
program can recover from this condition by mapping into
memory at a physical page which is in the range of
supported physical pages.



EMM Functions 111





Function 22. Alter Page Map & Jump



AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

log_phys_map log_phys_map_struct (?) DUP (?)

map_and_jump map_and_jump_struct (?)

emm_handle DW ?
phys_page_or_seg_mode DB ?

MOV AX,SEG map_and_jump
MOV DS,AX
LEA SI,map_and_jump ; DS:SI points to
; map_and_jump
MOV DX,emm_handle
MOV AH,55h ; load function code
MOV AL,phys_page_or_seg_mode ; specify physical page
; or segment mode
INT 67h ; call memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error
























EMM Functions 112





Function 23. Alter Page Map & Call
Alter Page Map & Call subfunction



PURPOSE

This subfunction saves the current memory mapping context,
alters the specified memory mapping context, and transfers
control to the specified address. It is analogous to the
FAR CALL in the 8086 family architecture. Just as a return
from a FAR CALL restores the original value in the code
segment register, this subfunction restores the state of the
specified mapping context after the return.

There is no explicit expanded memory subfunction which
emulates a return from a FAR CALL. However, this facility
is implicitly available through the standard return from a
FAR CALL. The following paragraphs describe how this works:

After this function is invoked, unless an error is detected,
the memory manager will transfer control to the address
specified. If an error occurs, the memory manager returns
immediately with the error code in the AH register.
Otherwise, the memory manager pushes on the stack informa-
tion which enables it to restore the mapping context after
the return.

When the called procedure wants to return to the calling
procedure, it simply issues a standard FAR RETURN. The
memory manager traps this return, restores the specified
mapping context, and returns to the calling procedure. The
memory manager also returns a status from a successful
return just as it does for all functions.

Developers using this subfunction must make allowances for
the additional stack space this subfunction will use.


CALLING PARAMETERS

AH = 56h
Contains the Alter Page Map & Call function.

log_phys_map_struct STRUC
log_page_number DW ?
phys_page_number_seg DW ?
log_phys_map_struct ENDS





EMM Functions 113





Function 23. Alter Page Map & Call
Alter Page Map & Call subfunction



map_and_call_struct STRUC
target_address DD ?
new_page_map_len DB ?
new_page_map_ptr DD ?
old_page_map_len DB ?
old_page_map_ptr DD ?
reserved DW 4 DUP (?)
map_and_call_struct ENDS

AL = physical page number/segment selector
Contains a code which indicates whether the value
contained in the

.new_page_map.phys_page_number_seg
.old_page_map.phys_page_number_seg

members are physical page numbers or are the segment
address representation of the physical page numbers. A
value of zero in AL indicates that the values in these
members are physical page numbers. A value of one in AL
indicates that the values in these members are the
segment address representations of the physical page
numbers.

DX = handle number
Contains the EMM handle.

DS:SI = pointer to map_and_call structure
Contains a pointer to a structure which contains the
information necessary to map the desired physical pages
and call the target address. The structure members are
described here:

.target_address
The first member is a far pointer which contains the
target address to which control is to be trans-
ferred. The address is represented in segment:of-
fset format. The offset portion of the address is
stored in the low portion of the pointer. The
application must supply this value.

.new_page_map_len
The second member is a byte which contains the
number of entries in the new mapping context to
which new_page_map_ptr points. This number cannot
exceed the number of mappable pages in the system.


EMM Functions 114





Function 23. Alter Page Map & Call
Alter Page Map & Call subfunction



.new_page_map_ptr
The third member is a far pointer that points to an
array of structures which contains a list of the
logical page numbers and the physical page num-
bers/segments at which they are to be mapped im-
mediately after the call. The contents of the new
array of structures are described at the end of the
map_and_call structure.

.old_page_map_len
The fourth member is a byte which contains the
number of entries in the old mapping context to
which old_page_map_ptr points. This number cannot
exceed the number of mappable pages in the system.

.old_page_map_ptr
The fifth member is a far pointer that points to an
array of structures which contains a list of the
logical page numbers and the physical page num-
bers/segments at which they are to be mapped im-
mediately after the return. The contents of the old
array of structures are described at the end of the
map_and_call structure.

.reserved
The sixth member is reserved for use by the memory
manager.

Each entry in the old and new array of structures contains
two elements:

.log_page_number
The first member of this structure is a word which
contains a logical page number which is to be mapped
at the succeeding physical page number/segment
immediately after the CALL (in the case of the new
array of structures) or after the RETURN (in the
case of the old array of structures).

.phys_page_number_seg
The second member of this structure is a word which
contains either the physical page number or the
segment address representation of the physical page
number/segment at which the preceding logical page
is to be mapped immediately after the CALL (in the
case of the new array of structures) or after the
RETURN (in the case of the old array of structures).

EMM Functions 115





Function 23. Alter Page Map & Call
Alter Page Map & Call subfunction



REGISTERS MODIFIED

AX

Note............................................................
Values in registers which don't contain required parameters
maintain the values across the call. The values in regis-
ters (with the exception of AX) and the flag state at the
beginning of the function are still in the registers and
flags when the target address is reached.


STATUS

AH = 0 SUCCESSFUL.
Control has been transferred to the target address.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager couldn't find the specified EMM handle. The
manager doesn't have any information pertaining to the
specified EMM handle. The program may have corrupted
its EMM handle.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Ah RECOVERABLE.
One or more of the logical pages to map into a cor-
responding physical page is out of the range of logical
pages which are allocated to the EMM handle. The
program can recover from this condition by mapping a
logical page which is within the bounds for the EMM
handle.







EMM Functions 116





Function 23. Alter Page Map & Call
Alter Page Map & Call subfunction



AH = 8Bh RECOVERABLE.
One or more of the physical pages is out of the range of
allowable physical pages, or you've specified more
physical pages than exist in the system. Physical page
numbers are numbered zero-relative. The program can
recover from this condition by mapping a physical page
which is in the range from zero to three.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

new_page_map log_phys_map_struct (?) DUP (?)

old_page_map log_phys_map_struct (?) DUP (?)

map_and_call map_and_call_struct (?)

emm_handle DW ?
phys_page_or_seg_mode DB ?

MOV AX,SEG map_and_call
MOV DS,AX
LEA SI,map_and_call ; DS:SI points to
; map_and_call
MOV DX,emm_handle ; specify EMM handle
MOV AH,56h ; load function code
MOV AL,phys_page_or_seg_mode ; specify physical page
; or segment mode
INT 67h ; control is actually
; transferred to the called
; procedure at this point
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error











EMM Functions 117





Function 23. Alter Page Map & Call
Get Page Map Stack Space Size subfunction



PURPOSE

Since the Alter Page Map & Call function pushes additional
information onto the stack, this subfunction returns the
number of bytes of stack space the function requires.


CALLING PARAMETERS

AX = 5602h
Contains the Get Page Map Stack Space Size subfunction.


RESULTS

These results are valid only if the status returned is zero.

BX = stack space required
Contains the number of bytes which the Alter Page Map &
Call function will require. In other words, BX contains
the number (including the return address) which has to
be added to the stack pointer to remove all elements
from the stack.


REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The size of the array has been returned.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.



EMM Functions 118





Function 23. Alter Page Map & Call
Get Page Map Stack Space Size subfunction



AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

stack_space_reqd DW ?

MOV AX,5602h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV stack_space_reqd,BX ; save required stack size count



































EMM Functions 119





Function 24. Move/Exchange Memory Region
Move Memory Region subfunction



PURPOSE

This subfunction copies a region of memory in the following
memory source/destination combinations.

o conventional memory to conventional memory

o conventional memory to expanded memory

o expanded memory to conventional memory

o expanded memory to expanded memory

You do not have to save and restore the expanded memory
mapping context to perform these move operations. The
current mapping context is maintained throughout this
operation.

The length of the region is limited by the amount of
expanded memory allocated to the handles specified.
However, in most practical applications, the region length
will be considerably smaller. A region length of zero is
not an error, and no move will be performed.

A region length which exceeds 16K bytes is not an error. In
this case the function assumes that a group of logical pages
is the target for the move. The logical page specified
represents the first logical page in which the move will
take place. If the region length exceeds 16K bytes, or if
the region is less than 16K bytes but spans logical pages,
there must be sufficient logical pages remaining after the
first logical page for the entire region to fit.

If your application needs to save a region of conventional
memory in expanded memory, you can move it without having to
perform a save or restore of the current mapping context.
The memory manager maintains the context. A move of up to
1M bytes may be performed, although practical lengths are
substantially less than this value.

If the source and destination handles are identical, the
source and destination regions are tested for overlap before
the move. If they overlap, the move direction is chosen so
that the destination region receives an intact copy of the
source region. A status will be returned indicating that
this overlap has occurred.


EMM Functions 120





Function 24. Move/Exchange Memory Region
Move Memory Region subfunction



CALLING PARAMETERS

AX = 5700h
Contains the Move Memory Region function.

move_source_dest_struct STRUC
region_length DD ?
source_memory_type DB ?
source_handle DW ?
source_initial_offset DW ?
source_initial_seg_page DW ?
dest_memory_type DB ?
dest_handle DW ?
dest_initial_offset DW ?
dest_initial_seg_page DW ?
move_source_dest_struct ENDS

DS:SI = pointer to move_source_dest structure
Contains a pointer to a data structure which contains
the source and destination information for the move.
The structure members are described here:

.region_length
The first member is a double word which specifies
the length of the memory region (in bytes) to be
moved.

.source_memory_type
The second member is a byte which specifies the type
of memory where the source region resides. A value
of zero indicates that the source region resides in
conventional memory (excluding the page frame seg-
ment). A value of one indicates that the source
region resides in expanded memory.

.source_handle
If the source region resides in expanded memory, the
third member is a word which specifies the handle
number associated with the source memory region. If
the source region resides in conventional memory,
this variable has no meaning and should be set to
zero for future compatibility.

.source_initial_offset
The fourth member is a word which specifies the
offset within the source region from which to begin
the move.

EMM Functions 121





Function 24. Move/Exchange Memory Region
Move Memory Region subfunction



If the source region resides in expanded memory, the
source_initial_offset is relative to the beginning
of the 16K logical page. Because the offset is
relative to the beginning of a 16K expanded memory
page, it may only take on values between 0000h and
3FFFh.

If the source region resides in conventional memory,
the source_initial_offset is a word which specifies
the offset, relative to the beginning of the source
segment, from which to begin the move. Because the
offset is relative to the beginning of a 64K-byte
conventional memory segment, it may take on values
between 0000h and FFFFh.

.source_initial_seg_page
The fifth member is a word which specifies the
initial segment or logical page number within the
source region from which to begin the move.

If the source region resides in expanded memory, the
value specifies the logical page within the source
region from which to begin the move.

If the source region resides in conventional memory,
the source_initial_seg_page specifies the initial
segment address within conventional memory from
which to begin the move.

.dest_memory_type
The sixth member is a byte which specifies the type
of memory where the destination region resides. A
value of zero indicates conventional memory; a value
of one indicates expanded memory.

.dest_handle
If the destination region resides in expanded
memory, the seventh member is a word which specifies
the handle number associated with the destination
memory region. If the destination region resides in
conventional memory, this variable has no meaning
and should be set to zero for future compatibility.

.dest_initial_offset
The eighth member is a word which specifies the
offset within the destination region from which to
begin the move.

EMM Functions 122





Function 24. Move/Exchange Memory Region
Move Memory Region subfunction



If the destination region resides in expanded
memory, the dest_initial_offset is relative to the
beginning of the 16K-byte logical page. Because the
offset is relative to the beginning of a 16K-byte
expanded memory page, it may only take on values
between 0000h and 3FFFh.

If the destination region resides in conventional
memory, the dest_initial_offset is a word which
specifies the offset, relative to the beginning of
the destination segment, to begin the move. Because
the offset is relative to the beginning of a 64K
conventional memory segment, it may take on values
between 0000h and FFFFh.

.dest_initial_seg_page
The ninth member is a word which specifies the
initial segment or logical page number within the
destination region from which to begin the move.

If the destination region resides in expanded memory
then the value specifies the logical page within the
destination region from which to begin the move.

If the destination region resides in conventional
memory, the dest_initial_seg_page specifies the
initial segment address within conventional memory
from which to begin the move.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The memory regions have been moved.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

EMM Functions 123





Function 24. Move/Exchange Memory Region
Move Memory Region subfunction



AH = 83h NON-RECOVERABLE.
The manager couldn't find either the source or destina-
tion EMM handles. The memory manager doesn't have any
information on the handles specified. The program may
have corrupted its EMM handles.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Ah NON-RECOVERABLE.
One or more of the logical pages is out of the range of
logical pages allocated to the source/destination
handle.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 92h SUCCESSFUL.
The source and destination expanded memory regions have
the same handle and overlap. This is valid for a move.
The move has been completed and the destination region
has a full copy of the source region. However, at least
a portion of the source region has been overwritten by
the move. Note that the source and destination expanded
memory regions with different handles will never physi-
cally overlap because the different handles specify
totally different regions of expanded memory.

AH = 93h CONDITIONALLY-RECOVERABLE.
The length of the source or destination expanded memory
region specified exceeds the length of the expanded
memory region allocated either the source or destination
handle. Insufficient pages are allocated to this handle
to move a region of the size specified. The program can
recover from this condition by allocating additional
pages to the destination or source handle and attempting
to execute the function again. However, if the applica-
tion program allocated as much expanded memory as it
thought it needed, this may be a program error and is
not recoverable.

AH = 94h NON-RECOVERABLE.
The conventional memory region and expanded memory
region overlap. This is invalid, the conventional
memory region cannot overlap the expanded memory region.



EMM Functions 124





Function 24. Move/Exchange Memory Region
Move Memory Region subfunction



AH = 95h NON-RECOVERABLE.
The offset within the logical page exceeds the length of
the logical page. The initial source or destination
offsets within an expanded memory region must be between
0000h and 3FFFh (16383 or (length of a logical page
- 1)).

AH = 96h NON-RECOVERABLE.
Region length exceeds 1M bytes.

AH = 98h NON-RECOVERABLE.
The memory source and destination types are undefined.

AH = A2h NON-RECOVERABLE.
An attempt was made to wrap around the 1M-byte address
space of conventional memory during the move. The
combination of source/destination starting address and
length of the region to be moved exceeds 1M bytes. No
data was moved.


EXAMPLE

move_source_dest move_source_dest_struct (?)

MOV AX,SEG move_source_dest
MOV DS,AX
LEA SI,move_source_dest ; DS:SI points to move_source_dest
MOV AX,5700h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
















EMM Functions 125





Function 24. Move/Exchange Memory Region
Exchange Memory Region subfunction



PURPOSE

This subfunction exchanges (using a string move) a region of
memory in any of the following memory source/destination
combinations.

o conventional memory to conventional memory

o conventional memory to expanded memory

o expanded memory to conventional memory

o expanded memory to expanded memory

The term expanded memory region refers only to the area of
memory above 640K bytes (9FFFFh). If a system provides
mappable conventional memory, this function treats the
mappable conventional memory regions as ordinary convention-
al memory. The contents of the source region and the
destination region are exchanged.

The exchange operation can be performed without having to
save and restore the expanded memory mapping context. The
current mapping context is maintained throughout this
operation. The length of the region is limited to the
amount of expanded memory allocated to the specified EMM
handles. A length of zero is not an error; however, no
exchange will be performed. A region length which exceeds
16K bytes is not an error. In this case the function
assumes that a group of logical pages is the target for the
exchange. The logical page specified represents the first
logical page in which the exchange will take place. If the
region length exceeds 16K bytes, or if the region is less
than 16K bytes but spans logical pages, there must be
sufficient logical pages remaining after the first logical
page for the entire region to fit.

If your application needs to exchange a region of conven-
tional memory with expanded memory, you can simply exchange
it with the region of interest without having to perform a
save or restore of the current mapping context. An exchange
of up to 1M bytes may be performed, although practical
lengths are obviously below that value. Checking is done
before starting the exchange to prevent the possibility of
overlap during the exchange operation. Overlapping source
and destination regions for an exchange are invalid, and the
exchange will not take place.

EMM Functions 126





Function 24. Move/Exchange Memory Region
Exchange Memory Region subfunction



CALLING PARAMETERS

AX = 5701h
Contains the Exchange Memory Region function.

xchg_source_dest_struct STRUC
region_length DD ?
source_memory_type DB ?
source_handle DW ?
source_initial_offset DW ?
source_initial_seg_page DW ?
dest_memory_type DB ?
dest_handle DW ?
dest_initial_offset DW ?
dest_initial_seg_page DW ?
xchg_source_dest_struct ENDS

DS:SI = pointer to xchg_source_dest structure
Contains a pointer to the data structure which contains
the source and destination information for the exchange.
The structure members are described here:

.region_length
The first member is a double word which specifies
the length of the memory region to be exchanged.

.source_memory_type
The second member is a byte which specifies the type
of memory where the source region resides. A value
of zero indicates that the source region resides in
conventional memory. A value of one indicates that
the source region resides in expanded memory.

.source_handle
If the source region resides in expanded memory, the
third member is a word which specifies the handle
number associated with the source memory region. If
the source region resides in conventional memory,
this variable has no meaning and should be set to
zero for future compatibility.

.source_initial_offset
The fourth member is a word which specifies the
offset within the source region from which to begin
the exchange.



EMM Functions 127





Function 24. Move/Exchange Memory Region
Exchange Memory Region subfunction



If the source region resides in expanded memory, the
source_initial_offset is relative to the beginning
of the 16K logical page. Because the offset is
relative to the beginning of a 16K expanded memory
page, it may only take on values between 0000h and
3FFFh.

If the source region resides in conventional memory,
the source_initial_offset is a word which specifies
the offset, relative to the beginning of the source
segment, from which to begin the exchange at.
Because the offset is relative to the beginning of a
64K-byte conventional memory segment, it may take on
values between 0000h and FFFFh.

.source_initial_seg_page
The fifth member is a word which specifies the
initial segment or logical page number within the
source region from which to begin the exchange.

If the source region resides in expanded memory then
the value specifies the logical page within the
source region from which to begin the exchange.

If the source region resides in conventional memory,
the source_initial_seg_page specifies the initial
segment address within conventional memory from
which to begin the exchange.

.dest_memory_type
The sixth member is a byte which specifies the type
of memory where the destination region resides. A
value of zero indicates that the destination region
resides in conventional memory (excluding the page
frame segment). A value of one indicates that the
destination region resides in expanded memory.

.dest_handle
If the destination region resides in expanded
memory, the seventh member is a word which specifies
the handle number associated with the destination
memory region. If the destination region resides in
conventional memory, this variable has no meaning
and should be set to zero for future compatibility.




EMM Functions 128





Function 24. Move/Exchange Memory Region
Exchange Memory Region subfunction



.dest_initial_offset
The eighth member is a word which specifies the
offset within the destination region from which to
begin the exchange.

If the destination region resides in expanded
memory, the dest_initial_offset is relative to the
beginning of the 16K-byte logical page. Because the
offset is relative to the beginning of a 16K-byte
expanded memory page, it may only take on values
between 0000h and 3FFFh.

If the destination region resides in conventional
memory, the dest_initial_offset is a word which
specifies the offset, relative to the beginning of
the destination segment, to begin the exchange at.
Because the offset is relative to the beginning of a
64K conventional memory segment, it may take on
values between 0000h and FFFFh.

.dest_initial_seg_page
The ninth member is a word which specifies the
initial segment or logical page number within the
destination region from which to begin the exchange.

If the destination region resides in expanded memory
then the value specifies the logical page within the
destination region from which to begin the exchange.

If the destination region resides in conventional
memory, the dest_initial_seg_page specifies the
initial segment address within conventional memory
from which to begin the exchange.



REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The memory regions have been exchanged.



EMM Functions 129





Function 24. Move/Exchange Memory Region
Exchange Memory Region subfunction



AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 83h NON-RECOVERABLE.
The manager could not find either the source or destina-
tion EMM handles. The memory manager does not currently
have any information pertaining to the handles speci-
fied. The program may have corrupted its EMM handles.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Ah NON-RECOVERABLE.
One or more of the logical pages is out of the range of
logical pages allocated to the source/destination
handle.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 93h CONDITIONALLY-RECOVERABLE.
The length of the source or destination expanded memory
region specified, exceeds the length of the expanded
memory region allocated to the source or destination
specified EMM handle. There are insufficient pages
allocated to this handle to exchange a region of the
size specified. The program can recover from this
condition by attempting to allocate additional pages to
the destination or source handle and attempting to
execute the function again. However, if the application
program was allocated as much expanded memory as it
thought it needed, this may be a program error and is
therefore not recoverable.

AH = 94h NON-RECOVERABLE.
The conventional memory region and expanded memory
region overlap. This is invalid, the conventional
memory region cannot overlap the expanded memory region.





EMM Functions 130





Function 24. Move/Exchange Memory Region
Exchange Memory Region subfunction



AH = 95h NON-RECOVERABLE.
The offset within the logical page exceeds the length of
the logical page. The initial source or destination
offsets within an expanded memory region must be between
0000h and 3FFFh (16383 or (length of a logical page
- 1)).

AH = 96h NON-RECOVERABLE.
Region length exceeds 1M-byte limit.

AH = 97h NON-RECOVERABLE.
The source and destination expanded memory regions have
the same handle and overlap. This is invalid, the
source and destination expanded memory regions cannot
have the same handle and overlap when they are being
exchanged. Note that the source and destination
expanded memory regions which have different handles
will never physically overlap because the different
handles specify totally different regions of expanded
memory.

AH = 98h NON-RECOVERABLE.
The memory source and destination types are undefined.

AH = A2h NON-RECOVERABLE.
An attempt was made to wrap around the 1M-byte address
space of conventional memory during the exchange. The
combination of source/destination starting address and
length of the region to be exchanged exceeds 1M bytes.
No data was exchanged.


EXAMPLE

xchg_source_dest xchg_source_dest_struct (?)

MOV AX,SEG xchg_source_dest
MOV DS,AX
LEA SI,xchg_source_dest ; DS:SI points to xchg_source_dest
MOV AX,5701h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error





EMM Functions 131





Function 25. Get Mappable Physical Address Array
Get Mappable Physical Address Array subfunction



PURPOSE

This subfunction returns an array containing the segment
address and physical page number for each mappable physical
page in a system. The contents of this array provide a
cross reference between physical page numbers and the actual
segment addresses for each mappable page in the system. The
array is sorted in ascending segment order. This does not
mean that the physical page numbers associated with the
segment addresses are also in ascending order.


CALLING PARAMETERS

AX = 5800h
Contains the Get Mappable Physical Address Array
subfunction

mappable_phys_page_struct STRUC
phys_page_segment DW ?
phys_page_number DW ?
mappable_phys_page_struct ENDS

ES:DI = mappable_phys_page
Contains a pointer to an application-supplied memory
area where the memory manager will copy the physical
address array. Each entry in the array is a structure
containing two members:

.phys_page_segment
The first member is a word which contains the
segment address of the mappable physical page
associated with the physical page number following
it. The array entries are sorted in ascending
segment address order.

.phys_page_number
The second member is a word which contains the
physical page number which corresponds to the
previous segment address. The physical page numbers
are not necessarily in ascending order.







EMM Functions 132





Function 25. Get Mappable Physical Address Array
Get Mappable Physical Address Array subfunction



Example 1

An expanded memory board has its page frame starting
at address C0000h and has no mappable conventional
memory. For this configuration, physical page 0
corresponds to segment address C000h, physical page
1 corresponds to segment address C400h, etc. The
array would contain the following data (in this
order):

C000h, 00h
C400h, 01h
C800h, 02h
CC00h, 03h


Example 2

An expanded memory board has a large page frame
starting at address C0000h and has mappable conven-
tional memory from 90000h through 9FFFFh. For this
configuration, physical page 0 corresponds to
segment address C000h, physical page 1 corresponds
to segment address C400h, etc. The array would
contain the following data in the order specified.
Note that the expanded memory region always has the
lowest numerically valued physical page numbers.

9000h, 0Ch
9400h, 0Dh
9800h, 0Eh
9C00h, 0Fh
C000h, 00h
C400h, 01h
C800h, 02h
CC00h, 03h
D000h, 04h
D400h, 05h
D800h, 06h
DC00h, 07h
E000h, 08h
E400h, 09h
E800h, 0Ah
EC00h, 0Bh




EMM Functions 133





Function 25. Get Mappable Physical Address Array
Get Mappable Physical Address Array subfunction



RESULTS

These results are valid only if the status returned is zero.

CX = number of entries in the mappable_phys_page
Multiply this number by (SIZE mappable_phys_page_struct)
to determine the number of bytes the physical page
address array requires.


REGISTERS MODIFIED

AX, CX


STATUS

AH = 0 SUCCESSFUL.
The hardware configuration array has been returned.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.















EMM Functions 134





Function 25. Get Mappable Physical Address Array
Get Mappable Physical Address Array subfunction



EXAMPLE

mappable_phys_page mappable_phys_page_struct (?)

mappable_page_entry_count DW ?

MOV AX,SEG mappable_phys_page
MOV ES,AX
LEA DI,mappable_phys_page ; ES:DI points to
; mappable_phys_page
MOV AX,5800h ; load function code
INT 67h ; call the memory
; manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler
; on error
MOV mappable_page_entry_count,CX ; save mappable
; page entry count






























EMM Functions 135





Function 25. Get Mappable Physical Address Array
Get Mappable Physical Address Array Entries subfunction



PURPOSE

This subfunction gets the number of entries which will be
required for the array the first subfunction returns.


CALLING PARAMETERS

AX = 5801h
Contains the Get Physical Page Address Array Entries
subfunction. This subfunction returns a word which
represents the number of entries in the array returned
by the previous subfunction. This number also repre-
sents the number of mappable physical pages in a system.


RESULTS

These results are valid only if the status returned is zero.

CX = number of entries in the mappable_phys_page
Multiply this number by (SIZE mappable_phys_page_struct)
to determine the number of bytes the physical page
address array will require.


REGISTERS MODIFIED

AX, CX


STATUS

AH = 0 SUCCESSFUL.
The number of mappable physical pages has been returned.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.


EMM Functions 136





Function 25. Get Mappable Physical Address Array
Get Mappable Physical Address Array Entries subfunction



AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

mappable_page_entry_count DW ?

MOV AX,5801h ; load function code
INT 67h ; call memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler
; on error
MOV mappable_page_entry_count,CX ; save mappable
; page entry count

































EMM Functions 137





Function 26. Get Expanded Memory Hardware Information
Get Hardware Configuration Array subfunction



Note............................................................
This function is for use by operating systems only. This
function can be disabled at any time by the operating
system. Refer to Function 30 for a description of how an
operating system does this.


PURPOSE

This subfunction returns an array containing expanded memory
hardware configuration information for use by an operating
system/environment.


CALLING PARAMETERS

AX = 5900h
Contains the Get Hardware Configuration Array subfunc-
tion.

hardware_info_struct STRUC
raw_page_size DW ?
alternate_register_sets DW ?
context_save_area_size DW ?
DMA_register_sets DW ?
DMA_channel_operation DW ?
hardware_info_struct ENDS

ES:DI = hardware_info
Contains a pointer to a memory area that the operating
system supplies where the memory manager will copy
expanded memory hardware information. The structure
contains these five members:

.raw_page_size
The first member is a word which contains the size
of a raw mappable physical page in paragraphs (16
bytes). LIM standard pages are always 16K bytes.
However, other implementations of expanded memory
boards do not necessarily comply with this standard
and can emulate a 16K-byte page by mapping in
multiple smaller pages. This member specifies the
size of a mappable physical page viewed from the
hardware implementation level.




EMM Functions 138





Function 26. Get Expanded Memory Hardware Information
Get Hardware Configuration Array subfunction



.alternate_register_sets
The second member is a word which specifies the
number of alternate mapping register sets. The
additional mapping register sets are termed alter-
nate mapping register sets in this document.

All expanded memory boards have at least one set of
hardware registers to perform the logical to
physical page mapping. Some expanded memory boards
have more than one set of these mapping registers.
This member specifies how many of these alternate
mapping register sets exist (beyond the one set that
all expanded memory boards have) on the expanded
memory boards in the system. If an expanded memory
card has only one set of mapping registers (that is,
no alternate mapping register sets) this member has
a value of zero.

.context_save_area_size
The third member is a word which contains the
storage requirements for the array required to save
a mapping context. The value returned in this
member is exactly the same as that returned by
Function 15 (Get Size of Page Map Save Array
subfunction).

.DMA_register_sets
The fourth member is a word which contains the
number of register sets that can be assigned to DMA
channels. These DMA register sets, although similar
in use to alternate register sets, are for DMA
mapping and not task mapping.

If the expanded memory hardware does not support DMA
register sets, care must be taken when DMA is taking
place.

In a multitasking operating system, when one task is
waiting for DMA to complete, it is useful to be able
to switch to another task. However, if the DMA is
taking place in memory that the second task will
need to remap, remapping would be disastrous.






EMM Functions 139





Function 26. Get Expanded Memory Hardware Information
Get Hardware Configuration Array subfunction



If the expanded memory hardware can detect when DMA
is occurring, the OS/E should allow task switches
and remapping during DMA. If no special support for
DMA is available, no remapping should be done when
DMA is in progress.

.DMA_channel_operation
The fifth member is a word which specifies a special
case for the DMA register sets. A value of zero
specifies that the DMA register sets behave as
described in Function 28. A value of one specifies
that the expanded memory hardware has only one DMA
register set. In addition, if any channel is mapped
through this register set, then all channels are
mapped through it. For LIM standard boards, this
value is zero.


RESULTS

These results are valid only if the status returned is zero.

hardware_info
Contains the expanded memory hardware-specific informa-
tion described above.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The hardware configuration array has been returned.

AH = 80h NON-RECOVERABLE.
The manager has detected a malfunction in the memory
manager software.

AH = 81h NON-RECOVERABLE.
The manager has detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the manager is not defined.

EMM Functions 140





Function 26. Get Expanded Memory Hardware Information
Get Hardware Configuration Array subfunction



AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A4h NON-RECOVERABLE.
Access to this function has been denied by the operating
system. The function cannot be used at this time.


EXAMPLE

hardware_info hardware_info_struct (?)

MOV AX,SEG hardware_info
MOV ES,AX
LEA DI,hardware_info ; ES:DI points to hardware_info
MOV AX,5900h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error





























EMM Functions 141





Function 26. Get Expanded Memory Hardware Information
Get Unallocated Raw Page Count subfunction



PURPOSE

The Get Unallocated Raw Page Count subfunction returns the
number of unallocated non-standard length mappable pages as
well as the total number of non-standard length mappable
pages in expanded memory to the operating system.

One variety of expanded memory board has a page size which
is a sub-multiple of 16K bytes. An expanded memory page
which is a sub-multiple of 16K is termed a raw page. An
operating system may deal with mappable physical page sizes
which are sub-multiples of 16K bytes.

If the expanded memory board supplies pages in exact
multiples of 16K bytes, the number of pages this function
returns is identical to the number Function 3 (Get Unallo-
cated Page Count) returns. In this case, there is no
difference between a page and a raw page.


CALLING PARAMETERS

AX = 5901h
Contains the Get Unallocated Raw Page Count subfunction.


RESULTS

These results are valid only if the status returned is zero.

BX = unallocated raw pages
The number of raw pages that are currently available for
use.

DX = total raw pages
The total number of raw pages in expanded memory.


REGISTERS MODIFIED

AX, BX, DX







EMM Functions 142





Function 26. Get Expanded Memory Hardware Information
Get Unallocated Raw Page Count subfunction



STATUS

AH = 0 SUCCESSFUL.
The manager has returned the number of unallocated raw
pages and the number of total raw pages in expanded
memory.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

unalloc_raw_pages DW ?
total_raw_pages DW ?

MOV AX,5901h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV unalloc_raw_pages,BX ; save unallocated raw page count
MOV total_raw_pages,DX ; save total raw page count














EMM Functions 143





Function 27. Allocate Standard/Raw Pages
Allocate Standard Pages subfunction



PURPOSE

The Allocate Standard Pages subfunction allocates the number
of standard size (16K bytes) pages that the operating system
requests and assigns a unique EMM handle to these pages.
The EMM handle owns these pages until the operating system
deallocates them. This subfunction allows you to allocate
zero pages to a handle, unlike Function 4 (Allocate Pages).

Note............................................................
This note affects expanded memory manager implementors and
operating system developers only. Applications should not
use the following characteristic of the memory manager. An
application violating this rule will be incompatible with
future versions of Microsoft's operating systems and
environments.

To be compatible with this specification, an expanded memory
manager will provide a special handle which is available to
the operating system only. This handle will have a value of
0000h and will have a set of pages allocated to it when the
expanded memory manager driver installs. The pages that the
memory manager will automatically allocate to handle 0000h
are those that backfill conventional memory. Typically,
this backfill occurs between addresses 40000h (256K) and
9FFFFh (640K). However, the range can extend below and
above this limit if the hardware and memory manager have the
capability.

An operating system won't have to invoke Function 27 to
obtain this handle because it can assume the handle already
exists and is available for use immediately after the
expanded memory device driver installs. When an operating
system wants to use this handle, it uses the special handle
value of 0000h. The operating system will be able to invoke
any EMM function using this special handle value. To
allocate pages to this handle, the operating system need
only invoke Function 18 (Reallocate Pages).

There are two special cases for this handle:

1. Function 27 (Allocate Standard Pages subfunction). This
function must never return zero as a handle value.
Applications must always invoke Function 27 to allocate
pages and obtain a handle which identifies the pages
which belong to it. Since Function 27 never returns a


EMM Functions 144





Function 27. Allocate Standard/Raw Pages
Allocate Standard Pages subfunction



handle value of zero, an application will never gain
access to this special handle.

2. Function 6 (Deallocate Pages). If the operating system
uses it to deallocate the pages which are allocated to
this handle, the pages the handle owns will be returned
to the manager for use. But the handle will not be
available for reassignment. The manager should treat a
deallocate pages function request for this handle the
same as a reallocate pages function request, where the
number of pages to reallocate to this handle is zero.


CALLING PARAMETERS

AX = 5A00h
Contains the Allocate Standard Pages subfunction.

BX = num_of_standard_pages_to_alloc
Contains the number of standard pages the operating
system wants to allocate.


RESULTS

These results are valid only if the status returned is zero.

DX = handle
Contains a unique EMM handle. The operating system must
use this EMM handle as a parameter in any function that
requires it. Up to 255 handles may be obtained. (Both
Function 27 and Function 4 must share the same 255
handles.)

For all functions using this handle, the length of the
physical and logical pages allocated to it are standard
length (that is, 16K bytes).


REGISTERS MODIFIED

AX, DX






EMM Functions 145





Function 27. Allocate Standard/Raw Pages
Allocate Standard Pages subfunction



STATUS

AH = 0 SUCCESSFUL.
The manager has allocated the pages to an assigned EMM
standard handle.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 85h RECOVERABLE.
All EMM handles are being used.

AH = 87h RECOVERABLE.
There aren't enough expanded memory pages present in the
system to satisfy the operating system's request.

AH = 88h RECOVERABLE.
There aren't enough unallocated pages to satisfy the
operating system's request.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

num_of_standard_pages_to_alloc DW ?
emm_handle DW ?

MOV BX,num_of_standard_pages_to_alloc
MOV AX,5A00h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on
; error
MOV emm_handle,DX ; save handle



EMM Functions 146





Function 27. Allocate Standard/Raw Pages
Allocate Raw Pages subfunction



PURPOSE

The Allocate Raw Pages function allocates the number of non-
standard size pages that the operating system requests and
assigns a unique EMM handle to these pages. The EMM handle
owns these pages until the operating system deallocates
them. This function allows you to allocate zero pages to a
handle, unlike Function 4 (Allocate Pages).

A hardware vendor may design an expanded memory board that
has a page size which is a sub-multiple of 16K bytes. A
physical page which is a sub-multiple of 16K is termed a raw
page. The operating system may deal with page sizes which
are sub-multiples of 16K bytes. The memory manager must
treat any function using a handle with raw pages allocated
to it by Function 27 (Allocate Raw Pages subfunction)
differently than it does a handle that has normal 16K-byte
pages allocated to it.

Handles which are assigned using Function 4 (Allocate Pages)
or Function 27 (Allocate Standard Pages subfunction) must
have pages which are 16K bytes -- this is the length of a
standard expanded memory page. If the expanded memory board
hardware is not able to supply 16K-byte pages, the memory
manager must emulate pages which are 16K bytes combining
multiple non-standard size pages to form a single 16K-byte
page.

Handles which are assigned using Function 27 (Allocate Raw
Pages subfunction) are called raw handles. All logical
pages allocated to a raw handle may have a non-standard
length (that is, not 16K bytes). However, once the operat-
ing system has allocated a number of raw pages to a handle,
it is the responsibility of the memory manager to recognize
that raw handle as one that has non-standard size pages
allocated to it. The memory manager must identify these
handles and treat all functions which use handles which have
non-standard page lengths differently. The logical page
length becomes the length of the non-standard size page for
any raw handle that Function 27 assigns.

Note............................................................
This note affects expanded memory manager implementors and
operating system developers only. Applications should not
use the following characteristic of the memory manager. An
application violating this rule will be incompatible with


EMM Functions 147





Function 27. Allocate Standard/Raw Pages
Allocate Raw Pages subfunction



future versions of Microsoft's operating systems and
environments.

To be compatible with this specification, an expanded memory
manager will provide a special handle which is available to
the operating system only. This handle will have a value of
0000h and will have a set of pages allocated to it when the
expanded memory manager driver installs. The pages that the
memory manager will automatically allocate to handle 0000h
are those that backfill conventional memory. Typically,
this backfill occurs between addresses 40000h (256K) and
9FFFFh (640K). However, the range can extend below and
above this limit if the hardware and memory manager have the
capability.

An operating system won't have to invoke Function 27 to
obtain this handle because it can assume the handle already
exists and is available for use immediately after the
expanded memory device driver installs. When an operating
system wants to use this handle, it uses the special handle
value of 0000h. The operating system will be able to invoke
any EMM function using this special handle value. To
allocate pages to this handle, the operating system need
only invoke Function 18 (Reallocate Pages).

There are two special cases for this handle:

1. Function 27 (Allocate Raw Pages subfunction). This
function must never return zero as a handle value.
Applications must always invoke Function 27 to allocate
pages and obtain a handle which identifies the pages
which belong to it. Since Function 27 never returns a
handle value of zero, an application will never gain
access to this special handle.

2. Function 6 (Deallocate Pages). If the operating system
uses it to deallocate the pages which are allocated to
this handle, the pages the handle owns will be returned
to the manager for use. But the handle will not be
available for reassignment. The manager should treat a
deallocate pages function request for this handle the
same as a reallocate pages function request, where the
number of pages to reallocate to this handle is zero.





EMM Functions 148





Function 27. Allocate Standard/Raw Pages
Allocate Raw Pages subfunction



CALLING PARAMETERS

AX = 5A01h
Contains the Allocate Raw Pages subfunction.

BX = num_of_raw_pages_to_alloc
Contains the number of raw pages the operating system
wishes to allocate.


RESULTS

These results are valid only if the status returned is zero.

DX = raw handle
Contains a unique EMM raw handle. The operating system
must use this EMM raw handle as a parameter in any
function that requires it. Up to 255 handles may be
obtained. (Both Function 4 and Function 27 must share
the same 255 handles).

For all functions using this raw handle, the length of
the physical and logical pages allocated to it may be
non-standard (that is, not 16K bytes).


REGISTERS MODIFIED

AX, DX


STATUS

AH = 0 SUCCESSFUL.
The manager has allocated the raw pages to an assigned
EMM raw handle.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.




EMM Functions 149





Function 27. Allocate Standard/Raw Pages
Allocate Raw Pages subfunction



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 85h RECOVERABLE.
All EMM handles are being used.

AH = 87h RECOVERABLE.
There aren't enough expanded memory raw pages present in
the system to satisfy the operating system's request.

AH = 88h RECOVERABLE.
There aren't enough unallocated raw pages to satisfy the
operating system's request.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.


EXAMPLE

num_of_raw_pages_to_alloc DW ?
emm_raw_handle DW ?

MOV BX,num_of_raw_pages_to_alloc
MOV AX,5A01h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler
; on error
MOV emm_raw_handle,DX ; save raw handle

















EMM Functions 150





Function 28. Alternate Map Register Set



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


Design Considerations

The hardware support for the entire set of subfunctions
described is generally not present on every expanded memory
board from every vendor of expanded memory board products.
For some of the subfunctions, software emulation is provid-
ed. For other subfunctions, a certain protocol in their use
must be observed. The subfunctions for which this is most
crucial are those which address system DMA capabilities.


System DMA Capabilities & Expanded Memory Support of DMA

In a multitasking operating system, when one task is waiting
for DMA to complete, it is useful to be able to switch to
another task. This specification describes a capability
which may be designed into expanded memory boards to provide
DMA into memory regions which may be mapped out while the
DMA is occurring. For expanded memory boards that do not
provide this, it is crucial to understand that while DMA is
in progress into a region of mappable memory, the memory
mapping context cannot be changed. That is, all DMA action
must be complete before any remapping of pages can be done.


Expanded Memory Support of DMA Register Sets

Expanded memory boards which have DMA register sets could
support DMA into a region of mappable memory while the
memory mapping context is being switched. It is important
to realize that these DMA register sets are separate from
the alternate map register sets. An example of how an OS/E
might use DMA register sets follows:

Example 1

1. Allocate a DMA register set.

2. Get current register set.

3. Set the DMA register set.

EMM Functions 151





Function 28. Alternate Map Register Set



4. Map in the memory desired.

5. Get the DMA register set.

6. Set the original register set.

7. Assign the desired DMA channel to the DMA register set.

The preceding set of calls makes all DMA accesses for the
desired DMA channel get mapped through the current DMA
register set regardless of the current register set. In
other words, the DMA register set overrides the current
mapping register set for DMA operations on the DMA channel
specified. A DMA channel that is not assigned to a DMA
register set has all its DMA operations mapped through the
current mapping register set.

































EMM Functions 152





Function 28. Alternate Map Register Set
Get Alternate Map Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

The subfunction does one of two things depending on the map
register set which is active at the time this function is
invoked:

1. If the preceding Set Alternate Map Register Set call was
done with the alternate map register set equal to zero
(BL = 0), these points apply:

a. The context save area pointer saved within EMM by
the Set Alternate Map Register subfunction is
returned by this call. This pointer is always
returned for boards which do not supply alternate
mapping register sets.

b. If the context save area pointer returned is not
equal to zero, this subfunction copies the contents
of the mapping registers on each expanded memory
board in the system into the save area specified by
the pointer. The format of this save area is the
same as that returned by Function 15 (Get Page Map
subfunction). This is intended to simulate getting
an alternate map register set. Note that the memory
manager does not allocate the space for the context:
the operating system must do so.

c. If the context save area pointer returned is equal
to zero, this subfunction does not copy the contents
of the mapping registers on each expanded memory
board in the system into the save area specified by
the pointer.

d. The context save area pointer must have been
initialized by a previous Set Alternate Map Register
Set call. Note that the value of the context save
area pointer saved within EMM is zero immediately
after installation.



EMM Functions 153





Function 28. Alternate Map Register Set
Get Alternate Map Register Set subfunction



e. The context save area must be initialized by a
previous Get Page Map call (Function 15).

2. If the preceding Set Alternate Map Register Set call was
done with the alternate map register set greater than
zero (BL > 0), then the number of the alternate map
register set which is in use at the time that this
function is invoked is returned. The context save area
pointer is not returned in this case.


CALLING PARAMETERS

AX = 5B00h
Contains the Get Alternate Map Register Set subfunction.


RESULTS

These results are valid only if the status returned is zero.

If BL <> 0, current active alternate map register set number
Contains the alternate map register set which was active
at the time that this function was invoked.

ES:DI Unaffected.

If BL = 0
Indicates that a pointer to an area which contains the
state of all the map registers on all boards in the
system, and any additional information necessary to
restore the boards to their original state, has been
returned.

ES:DI = pointer to a map register context save area
Contains a pointer to an operating system supplied
context save area. The pointer is in standard seg-
ment:offset format. This pointer is always returned if
the expanded memory hardware does not supply alternate
mapping register sets.








EMM Functions 154





Function 28. Alternate Map Register Set
Get Alternate Map Register Set subfunction



The operating system first passes this pointer to the
memory manager whenever it invokes a Set Alternate Map
Register Set subfunction (the description follows). If
the OS/E invokes this function before invoking a Set
Alternate Map Register Set subfunction, this function
returns a pointer value of zero. The OS/E must have
allocated the space for the save area. However, the OS
must request that the memory manager initialize the
contents of this save area before it contains any useful
information.

The OS/E must initialize the save area it has allocated
by invoking Function 15 (Get Page Map subfunction).
After the OS/E has done this, the save area will contain
the state of all the map registers on all boards in the
system. The save area will also contain any additional
information necessary to restore the boards to their
original state when the operating system invokes a Set
Alternate Map Register Set subfunction.


REGISTERS MODIFIED

AX, BX, ES:DI


STATUS

AH = 0 SUCCESSFUL.
The manager got the alternate map register set.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.



EMM Functions 155





Function 28. Alternate Map Register Set
Get Alternate Map Register Set subfunction



AH = A4h NON-RECOVERABLE.
The operating system denied access to this function.
The function cannot be used at this time.


EXAMPLE

alt_map_reg_set DB ?
context_save_area_ptr_seg DW ?
context_save_area_ptr_offset DW ?

MOV AX,5B00h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler
; on error
MOV alt_map_reg_set,BL
TEST BL,BL
JNZ no_ptr_returned

MOV context_save_area_ptr_seg,ES ; save pointer values
MOV context_save_area_ptr_offset,DI

no_ptr_returned:
























EMM Functions 156





Function 28. Alternate Map Register Set
Set Alternate Map Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

The subfunction does one of two things, depending on the map
register set specified:

1. If the alternate map register set specified is zero, map
register set zero is activated. If the map register
context restore area pointer is not equal to zero, the
contents of the restore area pointed to by ES:DI are
copied into register set zero on each expanded memory
board in the system. If the pointer is equal to zero,
the contents are not copied.

Regardless of its value, the map register context
restore area pointer is saved within the memory manager.
It will be used during the Get Alternate Map Register
Set subfunction.

The operating system must supply the pointer to the
area. This subfunction is intended to simulate setting
an alternate map register set. Note that the operating
system must allocate the space for the context. The
memory manager saves the context save area pointer
internally.

2. If the alternate map register set specified is not zero,
the alternate map register set specified is activated.
The restore area, which the operating system is pointing
to, is not used.


CALLING PARAMETERS

AX = 5B01h
Contains the Set Alternate Map Register Set subfunction.






EMM Functions 157





Function 28. Alternate Map Register Set
Set Alternate Map Register Set subfunction



BL = new alternate map register set number
Contains the number of the alternate map register set
which is to be activated.

If BL <> 0
A pointer to a map register context restore area is
not required and the contents of ES:DI is unaffected
and ignored. The alternate map register set
specified in BL is activated if the board supports
it.

If BL = 0
A pointer to an area which contains the state of all
the map registers on all boards in the system, and
any additional information necessary to restore the
boards to their original state, has been passed in
ES:DI.

ES:DI = pointer to a map register context restore area
Contains a pointer to an OS/E supplied map register
context restore area. The pointer is in standard
segment:offset format. This pointer must always be
passed if the expanded memory hardware does not supply
alternate mapping register sets.

The memory manager must save this pointer whenever the
OS/E invokes this function. The OS/E must have allo-
cated the space for the restore area. Additionally, the
contents of this restore area must have been initialized
by the memory manager before it will contain any useful
information. The OS/E initializes the restore area it
has allocated by invoking Function 15 (Get Page Map
subfunction). After the OS/E has done this, the restore
area will contain the state of the map registers on all
boards in the system, and any additional information
necessary to restore the boards to their original state
when the operating system invokes a Set Alternate Map
Register Set subfunction.


REGISTERS MODIFIED

AX





EMM Functions 158





Function 28. Alternate Map Register Set
Set Alternate Map Register Set subfunction



STATUS

AH = 0 SUCCESSFUL.
The manager set the alternate map register set.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 9Ah NON-RECOVERABLE.
Alternate map register sets are supported, but the
alternate map register set specified is not supported.

AH = 9Ch NON-RECOVERABLE.
Alternate map register sets are not supported, and the
alternate map register set specified is not zero.

AH = 9Dh NON-RECOVERABLE.
Alternate map register sets are supported, but the
alternate map register set specified is either not
defined or not allocated.

AH = A3h NON-RECOVERABLE.
The contents of the source array have been corrupted, or
the pointer passed to the subfunction is invalid.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time.








EMM Functions 159





Function 28. Alternate Map Register Set
Set Alternate Map Register Set subfunction



EXAMPLE

alt_map_reg_set DB ?
context_restore_area_ptr_seg DW ?
context_restore_area_ptr_offset DW ?

MOV AX,5B01h ; load function code
MOV BL,alt_map_reg_set
TEST BL,BL
JZ no_ptr_passed

MOV ES,context_restore_area_ptr_seg
MOV DI,context_restore_area_ptr_offset

no_ptr_passed:

INT 67h ; call the memory manger
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler
; on error




























EMM Functions 160





Function 28. Alternate Map Register Set
Get Alternate Map Save Array Size subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

This subfunction returns the storage requirements for the
map register context save area referenced by the other
subfunctions.


CALLING PARAMETERS

AX = 5B02h
Contains the Get Alternate Map Save Array Size subfunc-
tion.


RESULTS

These results are valid only if the status returned is zero.

DX = size_of_array
Contains the number of bytes that will be transferred to
the memory area supplied by an operating system whenever
an operating system requests the Get, Set, or Get and
Set subfunction.


REGISTERS MODIFIED

AX, DX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the array size.


AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.



EMM Functions 161





Function 28. Alternate Map Register Set
Get Alternate Map Save Array Size subfunction



AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time.


EXAMPLE

size_of_array DW ?


MOV AX,5B02h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV size_of_array,DX ; save size of array























EMM Functions 162





Function 28. Alternate Map Register Set
Allocate Alternate Map Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

The Allocate Alternate Map Register Set subfunction gets the
number of an alternate map register set for an operating
system if an alternate map register set is currently
available for use. If the hardware does not support
alternate map register sets, an alternate map register set
number of zero will be returned.

The alternate map register set allocated may be referred to
by this number when using the Get or Set Alternate Map
Register Set subfunctions. The operating system can use
these subfunctions to switch map contexts very rapidly on
expanded memory boards with alternate map register sets.

This subfunction copies the currently active alternate map
register set's contents into the newly allocated alternate
map register set's mapping registers. This is done so that
when the OS/E performs a Set Alternate Map Register Set
subfunction the memory mapped before the allocation of the
new alternate map will be available for reading and writing.
This function does not actually change the alternate map
register set in use, but in addition to allocating a new
alternate map register set, it prepares the new alternate
map register set for a subsequent Set Alternate Map Register
Set subfunction.


CALLING PARAMETERS

AX = 5B03h
Contains the Allocate Alternate Map Register Set
subfunction.








EMM Functions 163





Function 28. Alternate Map Register Set
Allocate Alternate Map Register Set subfunction



RESULTS

These results are valid only if the status returned is zero.

BL = alternate map register set number
Contains the number of an alternate map register set.
If there are no alternate map register sets supported by
the hardware, a zero will be returned. In this case,
the Get Alternate Map function (Function 28) should be
invoked in order to obtain a pointer to a map register
context save area. The OS/E must supply this area. The
save area is necessary because the hardware doesn't
support alternate map register sets.


REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The manager has returned the alternate map register set
number.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 9Bh NON-RECOVERABLE.
Alternate map register sets are supported. However, all
alternate map register sets are currently allocated.




EMM Functions 164





Function 28. Alternate Map Register Set
Allocate Alternate Map Register Set subfunction



AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time.


EXAMPLE

alt_map_reg_num DB ?

MOV AX,5B03h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV alt_map_reg_num,BL ; save number of
; alternate map register set

































EMM Functions 165





Function 28. Alternate Map Register Set
Deallocate Alternate Map Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

The Deallocate Alternate Map Register Set subfunction
returns the alternate map register set to the memory manager
for future use. The memory manager may reallocate the
alternate map register set when needed.

This subfunction also makes the mapping context of the
alternate map register specified unavailable for reading or
writing (unmapping). This protects the pages previously
mapped in an alternate map register set by making them
inaccessible. Note that the current alternate map register
set cannot be deallocated. This makes all memory which was
currently mapped into conventional and expanded memory
inaccessible.


CALLING PARAMETERS

AX = 5B04h
Contains the Deallocate Alternate Map Register Set
subfunction.

BL = alternate register set number
Contains the number of the alternate map register set to
deallocate. Map register set zero cannot be allocated
or deallocated. However, if alternate map register set
zero is specified and this subfunction is invoked, no
error will be returned. The function invocation is
ignored in this case.


REGISTERS MODIFIED

AX






EMM Functions 166





Function 28. Alternate Map Register Set
Deallocate Alternate Map Register Set subfunction



STATUS

AH = 0 SUCCESSFUL.
The manager has deallocated the alternate map register
set.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 9Ch NON-RECOVERABLE.
Alternate map register sets are not supported and the
alternate map register set specified is not zero.

AH = 9Dh NON-RECOVERABLE.
Alternate map register sets are supported, but the
alternate map register set specified is either not
defined or not allocated.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time.


EXAMPLE

alternate_map_reg_set DB ?

MOV BL,alternate_map_reg_set ; specify alternate map
; register set
MOV AX,5B04h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler
; on error


EMM Functions 167





Function 28. Alternate Map Register Set
Allocate DMA Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

The Allocate DMA Register Set subfunction gets the number of
a DMA register set for an OS/E, if a DMA register set is
currently available for use. If the hardware does not
support DMA register sets, a DMA register set number of zero
will be returned.

In a multitasking operating system, when one task is waiting
for DMA to complete, it is useful to be able to switch to
another task. However, if the DMA is being mapped through
the current register set, the switching cannot occur. That
is, all DMA action must be complete before any remapping of
pages can be done.

The operating system would initiate a DMA operation on a
specific DMA channel using a specific alternate map register
set. This alternate map register set would not be used
again, by the operating system or an application, until
after the DMA operation is complete. The operating system
guarantees this by not changing the contents of the alter-
nate map register set, or allowing an application to change
the contents of the alternate map register set, for the
duration of the DMA operation.


CALLING PARAMETERS

AX = 5B05h
Contains the Allocate DMA Register Set subfunction.


RESULTS

These results are valid only if the status returned is zero.

BL = DMA register set number
Contains the number of a DMA register set. If there are
no DMA register sets supported by the hardware, a zero
will be returned.

EMM Functions 168





Function 28. Alternate Map Register Set
Allocate DMA Register Set subfunction



REGISTERS MODIFIED

AX, BX


STATUS

AH = 0 SUCCESSFUL.
The manager has allocated the DMA register set.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 9Bh NON-RECOVERABLE.
DMA register sets are supported. However, all DMA
register sets are currently allocated.

AH = A4h NON-RECOVERABLE.
Access to this function has been denied by the operating
system. The function cannot be used at this time.


EXAMPLE

DMA_reg_set_number DB ?

MOV AX,5B05h ; load function code
INT 67h ; call memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler
; on error
MOV DMA_reg_set_number,BL ; save number of DMA
; register set



EMM Functions 169





Function 28. Alternate Map Register Set
Enable DMA on Alternate Map Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

This subfunction allows DMA accesses on a specific DMA
channel to be associated with a specific alternate map
register set. In a multitasking operating system, when a
task is waiting for the completion of DMA, it is useful to
be able to switch to another task until the DMA operation
completes.

Any DMA on the specified channel will go through the speci-
fied DMA register set regardless of the current register
set. If a DMA channel is not assigned to a DMA register
set, DMA for that channel will be mapped through the current
register set.


CALLING PARAMETERS

AX = 5B06h
Contains the Enable DMA on Alternate Map Register Set
subfunction.

BL = DMA register set number
Contains the number of the alternate map register set to
be used for DMA operations on the DMA channel specified
by DL. If the alternate map register set specified is
zero, no special action will be taken on DMA accesses
for the DMA channel specified.

DL = DMA channel number
Contains the DMA channel which is to be associated with
the DMA map register set specified in BL.


REGISTERS MODIFIED

AX




EMM Functions 170





Function 28. Alternate Map Register Set
Enable DMA on Alternate Map Register Set subfunction




STATUS

AH = 0 SUCCESSFUL.
The manager has enabled DMA on the DMA register set and
the DMA channel specified.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 9Ah NON-RECOVERABLE.
Alternate DMA register sets are supported, but the
alternate DMA register set specified is not supported.

AH = 9Ch NON-RECOVERABLE.
Alternate DMA register sets are not supported, and the
DMA register set specified is not zero.

AH = 9Dh NON-RECOVERABLE.
DMA register sets are supported, but the DMA register
set specified is either not defined or not allocated.

AH = 9Eh NON-RECOVERABLE.
Dedicated DMA channels are not supported.

AH = 9Fh NON-RECOVERABLE.
Dedicated DMA channels are supported, but the DMA
channel specified is not supported.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time.





EMM Functions 171





Function 28. Alternate Map Register Set
Enable DMA on Alternate Map Register Set subfunction



EXAMPLE

alt_map_reg_set DB ?
DMA_channel_num DB ?

MOV BL,alt_map_reg_set
MOV DL,DMA_channel_num
MOV AX,5B06h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error





































EMM Functions 172





Function 28. Alternate Map Register Set
Disable DMA on Alternate Map Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

This subfunction disables DMA accesses for all DMA channels
which were associated with a specific alternate map register
set.


CALLING PARAMETERS

AX = 5B07h
Contains the Disable DMA on Alternate Map Register Set
subfunction.

BL = alternate register set number
Contains the number of the DMA register set for which
all operations are to be disabled. If the alternate map
register set specified is zero, no action will be taken.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has disabled DMA operations on the alternate
DMA register set.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.




EMM Functions 173





Function 28. Alternate Map Register Set
Disable DMA on Alternate Map Register Set subfunction



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 9Ah NON-RECOVERABLE.
Alternate DMA register sets are supported, but the
alternate DMA register set specified is not supported.

AH = 9Ch NON-RECOVERABLE.
Alternate DMA register sets are not supported, and the
DMA register set specified is not zero.

AH = 9Dh NON-RECOVERABLE.
DMA register sets are supported, but the DMA register
set specified is either not defined or not allocated.

AH = 9Eh NON-RECOVERABLE.
Dedicated DMA channels are not supported.

AH = 9Fh NON-RECOVERABLE.
Dedicated DMA channels are supported, but the DMA
channel specified is not supported.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time.


EXAMPLE

DMA_reg_set DB ?

MOV BL,DMA_reg_set
MOV AX,5B07h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error








EMM Functions 174





Function 28. Alternate Map Register Set
Deallocate DMA Register Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.
Refer to Function 30 for a description of how an operating
system can enable or disable this function.


PURPOSE

The Deallocate DMA Register Set subfunction deallocates the
specified DMA register set.


CALLING PARAMETERS

AX = 5B08h
Contains the Deallocate DMA Register Set subfunction.

BL = DMA register set number
Contains the number of the DMA register set which should
not be used for DMA operations any longer. The DMA
register set would have been previously allocated and
enabled for DMA operations on a specific DMA channel.
If the DMA register set specified is zero, no action
will be taken.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has deallocated the DMA register set.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.




EMM Functions 175





Function 28. Alternate Map Register Set
Deallocate DMA on Alternate Map Register Set subfunction



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = 9Ch NON-RECOVERABLE.
DMA register sets are not supported, and the DMA
register set specified is not zero.

AH = 9Dh NON-RECOVERABLE.
DMA register sets are supported, but the DMA register
set specified is either not defined or not allocated.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time.


EXAMPLE

DMA_reg_set_num DB ?

MOV BL,DMA_reg_set_num
MOV AX,5B08h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error



















EMM Functions 176





Function 29. Prepare Expanded Memory Hardware For Warm Boot



PURPOSE

This function prepares the expanded memory hardware for an
impending warm boot. This function assumes that the next
operation that the operating system performs is a warm boot
of the system. In general, this function will effect the
current mapping context, the alternate register set in use,
and any other expanded memory hardware dependencies which
need to be initialized at boot time. If an application
decides to map memory below 640K, the application must trap
all possible conditions leading to a warm boot and invoke
this function before performing the warm boot itself.


CALLING PARAMETERS

AH = 5Ch
Contains the Prepare Expanded Memory Hardware for Warm
Boot function.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The manager has prepared the expanded memory hardware
for a warm boot.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.






EMM Functions 177





Function 29. Prepare Expanded Memory Hardware for Warm Boot



EXAMPLE

MOV AH,5Ch ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error











































EMM Functions 178





Function 30. Enable/Disable OS/E Function Set Functions
Enable OS/E Function Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.


PURPOSE

This subfunction provides an OS/E with the ability to enable
all programs or device drivers to use the OS/E specific
functions. The capability is provided only for an OS/E
which manages regions of mappable conventional memory and
cannot permit programs to use any of the functions which
affect mappable conventional memory regions, but must be
able to use these functions itself. When an OS/E disables
these functions and a program attempts to use them, the
memory manager returns a status to the program indicating
that the OS/E has denied the program access to the function.
In other words, the functions will not work when disabled.
However, all programs may use them when enabled.

The OS/E (Operating System/Environment) functions this
subfunction enables are:

Function 26. Get Expanded Memory Hardware Information.
Function 28. Alternate Map Register Sets.
Function 30. Enable/Disable Operating System Functions.

It appears contradictory that the OS/E can re-enable these
functions when the function which re-enables them is itself
disabled. An overview of the process follows.

The memory manager enables all the OS/E specific functions,
including this one, when it is loaded. The OS/E gets
exclusive access to these functions by invoking either of
the Enable/Disable OS/E Function Set subfunctions before any
other software does.

On the first invocation of either of these subfunctions, the
memory manager returns an access_key which the OS/E must use
in all future invocations of either of these subfunctions.
The memory manager does not require the access_key on the
first invocation of the Enable/Disable OS/E Function Set
subfunctions.





EMM Functions 179





Function 30. Enable/Disable OS/E Function Set Functions
Enable OS/E Function Set subfunction



On all subsequent invocations, the access_key is required
for either the Enable or Disable OS/E Function Set subfunc-
tions. Since the access_key is returned only on the first
invocation of the Enable/Disable OS/E Function Set subfunc-
tions, and presumably the OS/E is the first software to
invoke this function, only the OS/E obtains a copy of this
key. The memory manager must return an access key with a
random value, a fixed value key defeats the purpose of
providing this level of security for an OS/E.


CALLING PARAMETERS

AX = 5D00h
Contains the Enable OS/E Function Set subfunction.

BX,CX = access_key
Required on all function invocations after the first.
The access_key value returned by the first function
invocation is required.


RESULTS

These results are valid only if the status returned is zero.

BX,CX = access_key
Returned only on the first function invocation, the
memory manager returns a random valued key which will be
required thereafter for the execution of this function.
On all invocations after the first, this key is not
returned. Neither BX nor CX is affected after the first
time this function is invoked.


REGISTERS MODIFIED

AX, BX, CX


STATUS

AH = 0 SUCCESSFUL.
The operating system function set has been enabled.




EMM Functions 180





Function 30. Enable/Disable OS/E Function Set Functions
Enable OS/E Function Set subfunction



AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time. The value of
the key which was passed to this function does not
entitle the program to execute this function.


EXAMPLE

First invocation

access_key DW 2 DUP (?)

MOV AX,5D00h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV access_key[0],BX
MOV access_key[2],CX


All invocations after the first

access_key DW 2 DUP (?)

MOV BX,access_key[0]
MOV CX,access_key[2]
MOV AX,5D00h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error


EMM Functions 181





Function 30. Enable/Disable OS/E Function Set Functions
Disable OS/E Function Set subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.


PURPOSE

This subfunction provides an OS/E with the ability to
disable all programs or device drivers from using the OS/E
specific functions. The capability is provided only for an
OS/E which manages regions of mappable conventional memory
and cannot permit programs to use any of the functions which
would affect mappable conventional memory regions. When an
OS/E disables these functions and a program attempts to use
them, the memory manager returns a status to the program
indicating that the OS/E has denied the program access to
the function. In other words, the functions will not work
when disabled.

The OS/E (Operating System) functions which are disabled by
this subfunction are:

Function 26. Get Expanded Memory Hardware Information.
Function 28. Alternate Map Register Sets.
Function 30. Enable/Disable Operating System Functions.


CALLING PARAMETERS

AX = 5D01h
Contains the Disable OS/E Function Set subfunction.

BX,CX = access_key
Required on all function invocations after the first.
The access_key value returned by the first function
invocation is required.












EMM Functions 182





Function 30. Enable/Disable OS/E Function Set Functions
Disable OS/E Function Set subfunction



RESULTS

These results are valid only if the status returned is zero.

BX,CX = access_key
Returned only on the first function invocation, the
memory manager returns a random valued key which will be
required thereafter for the execution of this function.
On all invocations after the first, this key is not
returned. Neither BX nor CX is affected after the first
time this function is invoked.


REGISTERS MODIFIED

AX, BX, CX


STATUS

AH = 0 SUCCESSFUL.
The operating system function set has been disabled.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.

AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time. The value of
the key which was passed to this function does not
entitle the program to execute this function.





EMM Functions 183





Function 30. Enable/Disable OS/E Function Set Functions
Disable OS/E Function Set subfunction



EXAMPLE

First Function invocation

access_key DW 2 DUP (?)

MOV AX,5D01h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
MOV access_key[0],BX
MOV access_key[2],CX


All invocations after the first

access_key DW 2 DUP (?)

MOV BX,access_key[0]
MOV CX,access_key[2]
MOV AX,5D01h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
























EMM Functions 184





Function 30. Enable/Disable OS/E Function Set Functions
Return Access Key subfunction



Note............................................................
This function is for use by operating systems only. The
operating system can disable this function at any time.


PURPOSE

This subfunction provides an OS/E with the ability to return
the access key to the memory manager. Returning the access
key to the memory manager places the memory manager in the
state it is in at installation time (regarding the use of
the OS/E function set and the access key). That is, access
to the OS/E function set is enabled. Upon execution of the
next enable/disable OS/E function set subfunction, the
access key will once again be returned.


CALLING PARAMETERS

AX = 5D02h
Contains the Return Access Key subfunction.

BX,CX = access_key
Required on all function invocations. The access_key
value returned by the first function invocation of the
enable or disable subfunctions is required.


REGISTERS MODIFIED

AX


STATUS

AH = 0 SUCCESSFUL.
The access key has been returned to the memory manager.

AH = 80h NON-RECOVERABLE.
The manager detected a malfunction in the memory manager
software.

AH = 81h NON-RECOVERABLE.
The manager detected a malfunction in the expanded
memory hardware.



EMM Functions 185





Function 30. Enable/Disable OS/E Function Set Functions
Return Access Key subfunction



AH = 84h NON-RECOVERABLE.
The function code passed to the memory manager is not
defined.

AH = 8Fh NON-RECOVERABLE.
The subfunction parameter is invalid.

AH = A4h NON-RECOVERABLE.
The operating system has denied access to this function.
The function cannot be used at this time. The value of
the key which was passed to this function does not
entitle the program to execute this function.


EXAMPLE

access_key DW 2 DUP (?)

MOV BX,access_key[0]
MOV CX,access_key[2]
MOV AX,5D02h ; load function code
INT 67h ; call the memory manager
OR AH,AH ; check EMM status
JNZ emm_err_handler ; jump to error handler on error
























EMM Functions 186





Appendix A
FUNCTION AND STATUS CODE CROSS REFERENCE TABLES



This appendix contains two cross reference tables: one
lists the function codes and the status codes they return;
the other lists the status codes and the functions that
return them.


Table A-1. Function and Status Code Cross Reference
----------------------------------------------------------------

Function Status Description

----------------------------------------------------------------

40h 00h, 80h, 81h, 84h Get Memory Manager Status

41h 00h, 80h, 81h, 84h Get Page Frame Segment Address

42h 00h, 80h, 81h, 84h Get Unallocated Page Count

43h 00h, 80h, 81h, 84h Allocate Pages
85h, 87h, 88h, 89h

44h 00h, 80h, 81h, 83h Map/Unmap Handle Page
84h, 8Ah, 8Bh

45h 00h, 80h, 81h, 83h Deallocate Pages
84h, 86h

46h 00h, 80h, 81h, 84h Get EMM Version

47h 00h, 80h, 81h, 83h Save Page Map
84h, 8Ch, 8Dh

48h 00h, 80h, 81h, 83h Restore Page Map
84h, 8Eh

49h Reserved

4Ah Reserved

4Bh 00h, 80h, 81h, 84h Get EMM Handle Count

4Ch 00h, 80h, 81h, 83h Get EMM Handle Pages
84h

4Dh 00h, 80h, 81h, 84h Get All EMM Handle Pages


Cross Reference Tables 187





Table A-1. Function and Status Code Cross Reference (continued)
----------------------------------------------------------------

Function Status Description

----------------------------------------------------------------

4E00h 00h, 80h, 81h, 84h Get Page Map
8Fh

4E01h 00h, 80h, 81h, 84h Set Page Map
8Fh, A3h

4E02h 00h, 80h, 81h, 84h Get & Set Page Map
8Fh, A3h

4E03h 00h, 80h, 81h, 84h Get Size of Page Map Save Array
8Fh

4F00h 00h, 80h, 81h, 84h Get Partial Page Map
8Bh, 8Fh, A3h

4F01h 00h, 80h, 81h, 84h Set Partial Page Map
8Fh, A3h

4F02h 00h, 80h, 81h, 84h Get Size of Partial Page Map Array
8Bh, 8Fh

5000h 00h, 80h, 81h, 83h Map/Unmap Multiple Handle Pages
84h, 8Ah, 8Bh, 8Fh (physical page number mode)

5001h 00h, 80h, 81h, 83h Map/Unmap Multiple Handle Pages
84h, 8Ah, 8Bh, 8Fh (segment address mode)

51h 00h, 80h, 81h, 83h Reallocate Pages
84h, 87h, 88h

5200h 00h, 80h, 81h, 83h Get Handle Attribute
84h, 8Fh, 91h

5201h 00h, 80h, 81h, 83h Set Handle Attribute
84h, 8Fh, 90h, 91h

5202h 00h, 80h, 81h, 84h Get Handle Attribute Capability
8Fh

5300h 00h, 80h, 81h, 83h Get Handle Name
84h, 8Fh

5301h 00h, 80h, 81h, 83h Set Handle Name
84h, 8Fh, A1h


Cross Reference Tables 188





Table A-1. Function and Status Code Cross Reference (continued)
----------------------------------------------------------------

Function Status Description

----------------------------------------------------------------

5400h 00h, 80h, 81h, 84h Get Handle Directory
8Fh

5401h 00h, 80h, 81h, 84h Search for Named Handle
8Fh, A0h, A1h

5402h 00h, 80h, 81h, 84h Get Total Handles
8Fh

5500h 00h, 80h, 81h, 83h Alter Page Map & Jump (Physical
84h, 8Ah, 8Bh, 8Fh page mode)

5501h 00h, 80h, 81h, 83h Alter Page Map & Jump (Segment
84h, 8Ah, 8Bh, 8Fh address mode)

5600h 00h, 80h, 81h, 83h Alter Page Map & Call (Physical
84h, 8Ah, 8Bh, 8Fh page mode)

5601h 00h, 80h, 81h, 83h Alter Page Map & Call (Segment
84h, 8Ah, 8Bh, 8Fh address mode)

5602h 00h, 80h, 81h, 84h Get Alter Page Map & Call Stack
8Fh Space Size

5700h 00h, 80h, 81h, 83h Move Memory Region
84h, 8Ah, 8Fh, 92h
93h, 94h, 95h, 96h
98h, A2h

5701h 00h, 80h, 81h, 83h Exchange Memory Region
84h, 8Ah, 8Fh, 93h
94h, 95h, 96h, 97h
98h, A2h

5800h 00h, 80h, 81h, 84h Get Mappable Physical Address
8Fh Array

5801h 00h, 80h, 81h, 84h Get Mappable Physical Address
8Fh Array Entries

5900h 00h, 80h, 81h, 84h Get Expanded Memory Hardware
8Fh, A4h Information

5901h 00h, 80h, 81h, 84h Get Unallocated Raw Page Count
8Fh

Cross Reference Tables 189





Table A-1. Function and Status Code Cross Reference (continued)
----------------------------------------------------------------

Function Status Description

----------------------------------------------------------------

5A00h 00h, 80h, 81h, 84h Allocate Standard Pages
85h, 87h, 88h, 8Fh

5A01h 00h, 80h, 81h, 84h Allocate Raw Pages
85h, 87h, 88h, 8Fh

5B00h 00h, 80h, 81h, 84h Get Alternate Map Register Set
8Fh, A4h

5B01h 00h, 80h, 81h, 84h Set Alternate Map Register Set
8Fh, 9Ah, 9Ch, 9Dh
A3h, A4h

5B02h 00h, 80h, 81h, 84h Get Alternate Map Save Array Size
8Fh, A4h

5B03h 00h, 80h, 81h, 84h Allocate Alternate Map Register
8Fh, 9Bh, A4h Set

5B04h 00h, 80h, 81h, 84h Deallocate Alternate Map Register
8Fh, 9Ch, 9Dh, A4h Set

5B05h 00h, 80h, 81h, 84h Allocate DMA Register Set
8Fh, 9Bh, A4h

5B06h 00h, 80h, 81h, 84h Enable DMA on Alternate Map
8Fh, 9Ah, 9Ch, 9Dh Register Set
9Eh, 9Fh, A4h

5B07h 00h, 80h, 81h, 84h Disable DMA on Alternate Map
8Fh, 9Ah, 9Ch, 9Dh Register Set
9Eh, 9Fh, A4h

5B08h 00h, 80h, 81h, 84h Deallocate DMA Register Set
8Fh, 9Ch, 9Dh, A4h

5Ch 00h, 80h, 81h, 84h Prepare Expanded Memory Hardware
for Warmboot

5D00h 00h, 80h, 81h, 84h Enable Operating System Function
8Fh, A4h Set

5D01h 00h, 80h, 81h, 84h Disable Operating System Function
8Fh, A4h Set


Cross Reference Tables 190





Table A-1. Function and Status Code Cross Reference (continued)
----------------------------------------------------------------

Function Status Description

----------------------------------------------------------------

5D02h 00h, 80h, 81h, 84h Return Operating System Access Key
8Fh, A4h
----------------------------------------------------------------











































Cross Reference Tables 191





Table A-2. Status and Function Code Cross Reference
----------------------------------------------------------------

Status Function Description

----------------------------------------------------------------

00h All The function completed normally.

80h All The memory manager has detected a
malfunction in the expanded memory
software. A condition has been
detected which would not have
occurred if the memory manager had
been operating correctly.

81h All The memory manager has detected a
malfunction in the expanded memory
hardware. A condition has been
detected which would not occur if the
memory hardware were working correct-
ly. Diagnostics should be run on the
expanded memory system to determine
the source of the problem.

82h None This error code is not returned in
version 3.2 of the memory manager or
above. In earlier versions of the
memory manager this code meant a
"busy" status. This status indicated
that the memory manager was already
processing an expanded memory request
when the current request was made and
is unable to process another request.
In versions 3.2 of the memory manager
and above, the memory manager is
never "busy" and can always honor
requests.

83h 44h, 45h, 47h, 48h The memory manager can not find the
4Ch, 5000h, 5001h handle specified. The program has
51h, 5200h, 5201h probably corrupted its specified
5300h, 5301h handle. The memory manager does not
5500h, 5501h have any information pertaining to
5600h, 5601h the specified handle. The program
5700h, 5701h has probably corrupted its handle.

84h All The function code passed to the
manager is not currently defined.
Function codes in the range 40h
through 5Dh are currently defined.


Cross Reference Tables 192





Table A-2. Status and Function Code Cross Reference (continued)
----------------------------------------------------------------

Status Function Description

----------------------------------------------------------------

85h 43h, 5A00h, 5A01h No handles are currently available.
All assignable handles are currently
in use. The program may re-request
the assignment of a handle in the
hope that another program has
released a handle. The maximum
number of handles that may be
supported is 255.

86h 45h A mapping context restoration error
has been detected. This error occurs
when a program attempts to return a
handle and there is still a "mapping
context" on the context stack for the
indicated handle. A program can
recover from this error by restoring
the mapping context before returning
the handle.

87h 43h, 51h, 5A00h, The number of total pages that are
5A01h available in the system is insuffi-
cient to honor the request. The
program can recover from this
condition by requesting fewer pages.

88h 43h, 51h, 5A00h, The number of unallocated pages
5A01h currently available is insufficient
to honor the allocation request. The
program can recover from this
condition by re-posting the request
or by requesting fewer pages.

89h 43h A Function 4 (Allocate Pages) request
has been made specifying zero pages.
Zero pages cannot be assigned to a
handle with Function 4 (Allocate
Pages). If it is necessary to assign
zero pages to a handle, Function 27
(Allocate Standard Pages and Allocate
Raw Pages subfunctions) may be used.






Cross Reference Tables 193





Table A-2. Status and Function Code Cross Reference (continued)
----------------------------------------------------------------

Status Function Description

----------------------------------------------------------------

8Ah 44h, 5000h, 5001h The logical page to map into memory
5500h, 5501h is out of the range of logical pages
5600h, 5601h which are allocated to the handle.
5700h, 5701h The program can recover from this
condition by attempting to map a
logical page which is within the
bounds for the handle.

8Bh 44h, 4F00h, 4F02h One or more of the physical pages is
5000h, 5001h out of the range of allowable
5600h, 5601h physical pages. Physical page
5500h, 5501 numbers are numbered zero-relative.
The program can recover from this
condition by mapping at a physical
page which is in the range from zero
to three.

8Ch 47h The mapping register context save
area is full. The program can
recover from this condition by
attempting to save the mapping
registers again.

8Dh 47h The mapping register context stack
already has a context associated with
the handle. The program has at-
tempted to save the mapping register
context when there was already a
context for the handle on the stack.
The program can recover from this
condition by not attempting to save
the context again (this assumes the
mapping register context on the stack
for the handle is correct).












Cross Reference Tables 194





Table A-2. Status and Function Code Cross Reference (continued)
----------------------------------------------------------------

Status Function Description

----------------------------------------------------------------

8Eh 48h The mapping register context stack
does not have a context associated
with the handle. The program has
attempted to restore the mapping
register context when there was no
context for the handle on the stack.
The program can recover from this
condition by not attempting to
restore the context again (this
assumes the current mapping register
context is correct).

8Fh All functions The subfunction parameter passed to
requiring the function is not defined.
subfunction codes

90h 5201h The attribute type is undefined.

91h 5200h, 5201h The system configuration does not
support non-volatility.

92h 5700h The source and destination expanded
memory regions have the same handle
and overlap. This is valid for a
move. The move has been completed
and the destination region has a full
copy of the source region. However,
at least a portion of the source
region has been overwritten by the
move. Note that the source and
destination expanded memory regions
with different handles will never
physically overlap because the
different handles specify totally
different regions of expanded memory.











Cross Reference Tables 195





Table A-2. Status and Function Code Cross Reference (continued)
----------------------------------------------------------------

Status Function Description

----------------------------------------------------------------

93h 5700h, 5701h The length of the specified source or
destination expanded memory region
exceeds the length of the expanded
memory region allocated to the
specified source or destination
handle. There are insufficient pages
allocated to this handle to move/ex-
change a region of the size speci-
fied. The program can recover from
this condition by attempting to
allocate additional pages to the
destination or source handle or by
reducing the specified length.
However, if the application program
has allocated as much expanded memory
as it thought it needed, this may be
a program error and is therefore not
recoverable.

94h 5700h, 5701h The conventional memory region and
expanded memory region overlap. This
is invalid, the conventional memory
region cannot overlap the expanded
memory region.

95h 5700h, 5701h The offset within the logical page
exceeds the length of the logical
page. The initial source or destina-
tion offsets within an expanded
memory region must be between 0 and
the (length of a logical page - 1) or
16383 (3FFFh).

96h 5700h, 5701h Region length exceeds 1M-byte limit.












Cross Reference Tables 196





Table A-2. Status and Function Code Cross Reference (continued)
----------------------------------------------------------------

Status Function Description

----------------------------------------------------------------

97h 5701h The source and destination expanded
memory regions have the SAME handle
AND overlap. This is invalid; the
source and destination expanded
memory regions cannot have the same
handle and overlap when they are
being exchanged. Note that the
source and destination expanded
memory regions with different handles
will never physically overlap because
the different handles specify totally
different regions of expanded memory.

98h 5700h, 5701h The memory source and destination
types are undefined/not supported.

9Ah 5B01h, 5B06h Alternate map register sets are
5B07h supported, but the alternate map
register set specified is not
supported.

9Bh 5B03h, 5B05h Alternate map/DMA register sets are
supported. However, all alternate
map/DMA register sets are currently
allocated.

9Ch 5B01h, 5B04h Alternate map/DMA register sets are
5B06h, 5B07h not supported, and the alternate
5B08h map/DMA register set specified is not
zero.

9Dh 5B01h, 5B04h Alternate map/DMA register sets are
5B06h, 5B07h supported, but the alternate map
5B08h register set specified is not
defined, not allocated, or is the
currently allocated map register set.

9Eh 5B06h, 5B07h Dedicated DMA channels are not
supported.

9Fh 5B06h, 5B07h Dedicated DMA channels are supported.
But the DMA channel specified is not
supported.



Cross Reference Tables 197





Table A-2. Status and Function Code Cross Reference (continued)
----------------------------------------------------------------

Status Function Description

----------------------------------------------------------------

A0h 5401h No corresponding handle value could
be found for the handle name speci-
fied.

A1h 5301h, 5401h A handle with this name already
exists. The specified handle was not
assigned a name.

A2h 5700h, 5701h An attempt was made to "wrap around"
the 1M-byte address space during the
move/exchange. The source starting
address together with the length of
the region to be moved/exchanged
exceeds 1M bytes. No data was
moved/exchanged.

A3h 4E01h, 4E02h The contents of the data structure
4F00h, 4F01h passed to the function have either
5B01h been corrupted or are meaningless.

A4h 5900h, 5B00h The operating system has denied
5B01h, 5B02h access to this function. The
5B03h, 5B04h function cannot be used at this time.
5B05h, 5B06h
5B07h, 5B08h
5D00h, 5D01h
5D02h

----------------------------------------------------------------

















Cross Reference Tables 198





Appendix B
TESTING FOR THE PRESENCE OF THE EXPANDED MEMORY MANAGER



Before an application program can use the Expanded Memory
Manager, it must determine whether DOS has loaded the
manager. This appendix describes two methods your program
can use to test for the presence of the memory manager and
how to choose the correct one for your situation.

The first method uses the DOS "open handle" technique; the
second method uses the DOS "get interrupt vector" technique.


Which method should your program use?

The majority of application programs can use either the
"open handle" or the "get interrupt vector" method.
However, if your program is a device driver or if it
interrupts DOS during file system operations, you must use
only the "get interrupt vector" method.

Device drivers execute from within DOS and can't access the
DOS file system; programs that interrupt DOS during file
system operations have a similar restriction. During their
interrupt processing procedures, they can't access the DOS
file system because another program may be using the system.
Since the "get interrupt vector" method doesn't require the
DOS file system, you must use it for these types of pro-
grams.


The "open handle" technique

Most application programs can use the DOS "open handle"
technique to test for the presence of the memory manager.
This section describes how to use the technique and gives an
example.

Caution.........................................................
Don't use this technique if your program is a device driver
or if it interrupts DOS during file system operations. Use
the "get interrupt vector" technique described later in this
appendix.


Using the "open handle" technique

This section describes how to use the DOS "open handle"
technique to test for the presence of the memory manager.
Follow these steps in order:

Testing For The Presence Of The EMM 199





1. Issue an "open handle" command (DOS function 3Dh) in
"read only" access mode (register AL = 0). This
function requires your program to point to an ASCII
string which contains the path name of the file or
device in which you're interested (register set DS:DX
contains the pointer). In this case the file is
actually the name of the memory manager.

You should format the ASCII string as follows:

ASCII_device_name DB 'EMMXXXX0', 0

The ASCII codes for the capital letters EMMXXXX0 are
terminated by a byte containing a value of zero.

2. If DOS returns no error status code, skip Steps 3 and 4
and go to Step 5. If DOS returns a "Too many open
files" error status code, go to Step 3. If DOS returns
a "File/Path not found" error status code, skip Step 3
and go to Step 4.

3. If DOS returns a "Too many open files" (not enough
handles) status code, your program should invoke the
"open file" command before it opens any other files.
This will guarantee that at least one file handle will
be available to perform the function without causing
this error.

After the program performs the "open file" command, it
should perform the test described in Step 6 and close
the "file handle" (DOS function 3Eh). Don't keep the
manager "open" after this status test is performed since
"manager" functions are not available through DOS. Go
to Step 6.

4. If DOS returns a "File/Path not found," the memory
manager is not installed. If your application requires
the memory manager, the user will have to reboot the
system with a disk containing the memory manager and the
appropriate CONFIG.SYS file before proceeding.

5. If DOS doesn't return an error status code you can
assume that either a device with the name EMMXXXX0 is
resident in the system, or a file with this name is on
disk in the current disk drive. Go to Step 6.

6. Issue an "I/O Control for Devices" command (DOS function
44h) with a "get device information" command (register
AL = 0). DOS function 44h determines whether EMMXXXX0
is a device or a file.



Testing For The Presence Of The EMM 200





You must use the file handle (register BX) which you
obtained in Step 1 to access the "EMM" device.

This function returns the "device information" in a word
(register DX). Go to Step 7.

7. If DOS returns any error status code, you should assume
that the memory manager device driver is not installed.
If your application requires the memory manager, the
user will have to reboot the system with a disk contain-
ing the memory manager and the appropriate CONFIG.SYS
file before proceeding.

8. If DOS didn't return an error status, test the contents
of bit 7 (counting from 0) of the "device information"
word (register DX) the function returned. Go to Step 9.

9. If bit 7 of the "device information" word contains a
zero, then EMMXXXX0 is a file, and the memory manager
device driver is not present. If your application
requires the memory manager, the user will have to
reboot the system with a disk containing the memory
manager and the appropriate CONFIG.SYS file before
proceeding.

If bit 7 contains a one, then EMMXXXX0 is a device. Go
to Step 10.

10. Issue an "I/O Control for Devices" command (DOS function
44h) with a "get output status" command (register AL =
7).

You must use the file handle you obtained in Step 1 to
access the "EMM" device (register BX). Go to Step 11.

11. If the expanded memory device driver is "ready," the
memory manager passes a status value of "FFh" in
register AL. The status value is "00h" if the device
driver is "not ready."

If the memory manager device driver is "not ready" and
your application requires its presence, the user will
have to reboot the system with a disk containing the
memory manager and the appropriate CONFIG.SYS file
before proceeding.

If the memory manager device driver is "ready," go to
Step 12.





Testing For The Presence Of The EMM 201





12. Issue a "Close File Handle" command (DOS function 3Eh)
to close the expanded memory device driver. You must
use the file handle you obtained in Step 1 to close the
"EMM" device (register BX).

















































Testing For The Presence Of The EMM 202





An example of the "open handle" technique

The following procedure is an example of the "open handle"
technique outlined in the previous section.

;--------------------------------------------------------------;
; The following procedure tests for the presence of the ;
; EMM in the system. It returns the CARRY FLAG SET if ;
; the EMM is present. If the EMM is not present, this ;
; procedure returns the CARRY FLAG CLEAR. ;
;--------------------------------------------------------------;

first_test_for_EMM PROC NEAR
PUSH DS
PUSH CS
POP DS
MOV AX,3D00h ; issue "device open" in
LEA DX,ASCII_device_name ; "read only" mode
INT 21h
JC first_test_for_EMM_error_exit ; test for error
; during "device open"
MOV BX,AX ; get the "file
; handle" returned by DOS
MOV AX,4400h ; issue "IOCTL
INT 21h ; get device info"
JC first_test_for_EMM_error_exit ; test for error
; during "get device info"
TEST DX,0080h ; test to determine
JZ first_test_for_EMM_error_exit ; ASCII_device_name
; is a device or a file
MOV AX,4407h ; issue "IOCTL"
INT 21h
JC first_test_for_EMM_error_exit ; test for error
; during "IOCTL"
PUSH AX ; save "IOCTL" status
MOV AH,3Eh ; issue "close
INT 21h ; file handle"
POP AX ; restore "IOCTL" status
CMP AL,0FFh ; test for "device
JNE first_test_for_EMM_error_exit ; ready" status
; returned by the driver
first_test_for_EMM_exit:
POP DS ; EMM is present
STC ; in the system
RET

first_test_for_EMM_error_exit:
POP DS ; EMM is NOT present
CLC ; in the system
RET
ASCII_device_name DB 'EMMXXXX0', 0
first_test_for_EMM ENDP

Testing For The Presence Of The EMM 203





The "get interrupt vector" technique

Any type of program can use the DOS "get interrupt vector"
technique to test for the presence of the memory manager.
This section describes how to use the technique and gives an
example.

Caution.........................................................
Be sure to use this technique (and not the "open handle"
technique) if your program is a device driver or if it
interrupts DOS during file system operations.


Using the "get interrupt vector" technique

This section describes how to use the DOS "get interrupt
vector" technique to test for the presence of the memory
manager. Follow these steps in order:

1. Issue a "get vector" command (DOS function 35h) to
obtain the contents of interrupt vector array entry
number 67h (addresses 0000:019Ch thru 0000:019Fh).

The memory manager uses this interrupt vector to perform
all manager functions. The offset portion of this
interrupt service routine address is stored in the word
located at address 0000:019Ch; the segment portion is
stored in the word located at address 0000:019Eh.

2. Compare the "device name field" with the contents of the
ASCII string which starts at the address specified by
the segment portion of the contents of interrupt vector
address 67h and a fixed offset of 000Ah. If DOS loaded
the memory manager at boot time this name field will
have the name of the device in it.

Since the memory manager is implemented as a character
device driver, its program origin is 0000h. Device
drivers are required to have a "device header" located
at the program origin. Within the "device header" is an
8 byte "device name field." For a character mode device
driver this name field is always located at offset 000Ah
within the device header. The device name field
contains the name of the device which DOS uses when it
references the device.

If the result of the "string compare" in this technique
is positive, the memory manager is present.





Testing For The Presence Of The EMM 204





An example of the "get interrupt vector" technique

The following procedure is an example of the "get interrupt
vector" technique outlined in the previous section.


;--------------------------------------------------------------;
; The following procedure tests for the presence of the ;
; EMM in the system. It returns the CARRY FLAG SET if ;
; the EMM is present. If the EMM is not present, this ;
; procedure returns the CARRY FLAG CLEAR. ;
;--------------------------------------------------------------;


second_test_for_EMM PROC NEAR
PUSH DS
PUSH CS
POP DS
MOV AX,3567h ; issue "get interrupt
; vector"
INT 21h
MOV DI,000Ah ; use the segment in ES
; returned by DOS, place
; the "device name field"
; OFFSET in DI
LEA SI,ASCII_device_name ; place the OFFSET of the
; device name string in SI,
; the SEGMENT is already
; in DS
MOV CX,8 ; compare the name strings
CLD
REPE CMPSB
JNE second_test_for_EMM_error_exit

second_test_for_EMM_exit:
POP DS ; EMM is present in
STC ; the system
RET

second_test_for_EMM_error_exit:
POP DS ; EMM is NOT present
CLC ; in the system
RET

ASCII_device_name DB 'EMMXXXX0'
second_test_for_EMM ENDP







Testing For The Presence Of The EMM 205





Appendix C
EXPANDED MEMORY MANAGER IMPLEMENTATION GUIDELINES



In addition to the functional specification, the expanded
memory manager should provide certain resources. The
following guidelines are provided so required resources are
present in expanded memory managers which comply with this
version of the LIM specification.

o The amount of expanded memory supported:
Up to a maximum of 32M bytes of expanded memory should
be supported.

o The number of handles supported:
The maximum number of expanded memory handles provided
should be 255, the minimum should be 64.

o Handle Numbering:
Although a handle is a word quantity, there is a maximum
of 255 handles, including the operating system handle.
This specification defines the handle word as follows:
the low byte of the word is the actual handle value, the
high byte of the handle is set to 00h by the memory
manager. Previous versions of this specification did
not specify the value of handles.

o New handle type: Handles versus Raw Handles:
The difference between a raw handle and a regular handle
is slight. If you use Function 27 to "Allocate raw
pages to a handle," what is returned in DX is termed a
raw handle. The raw handle does not necessarily refer
to 16K-byte pages. Instead it refers to the "raw" page
size, which depends on the expanded memory hardware.

An application program can use Function 26 to find the
raw page size, and by using the raw handle Function 27
returns, it can access them with the finer resolution
that a particular expanded memory board may allow.

On the other hand, applications which use Function 4 to
"allocate pages to handle" receive a handle which always
refers to 16K-byte pages. On expanded memory boards
with smaller raw pages, the EMM driver will allocate and
maintain the number of raw pages it takes to create a
single composite 16K-byte page. The difference between
the expanded memory boards' raw page size and the 16K-
byte LIM page size is transparent to the application
when it is using a handle obtained with Function 4.



EMM Implementation Guidelines 206





The memory manager must differentiate between pages
allocated to handles and pages allocated to raw handles.
The meaning of a call to the driver changes depending on
whether a handle or a raw handle is passed to the memory
manager. If, for example, a handle is passed to
Function 18 (Reallocate), the memory manager will
increase or decrease the number of 16K-byte pages
allocated to the handle. If Function 18 is passed a raw
handle, the memory manager will increase or decrease the
number of raw (non-16K-byte) pages allocated to the raw
handle. For LIM standard boards, there is no difference
between pages and raw pages.

o The system Raw Handle (Raw Handle = 0000h):
For expanded memory boards that can remap the memory in
the lower 640K-byte address space, managing the pages of
memory which are used to fill in the lower 640K can be a
problem. To solve this problem, the memory manager will
create a raw handle with a value of 0000h when DOS loads
the manager. This raw handle is called the system
handle.

At power up, the memory manager will allocate all of the
pages that are mapped into the lower 640K bytes to the
system handle. These pages should be mapped in their
logical order. For example, if the system board
supplies 256K bytes of RAM, and the 384K bytes above it
is mappable, the system handle should have its logical
page zero mapped into the first physical page at 256K,
its logical page one mapped into the next physical page,
and so on.

The system handle should deal with raw pages. To
release some of these pages so application programs can
use them, an operating system could decrease the number
of pages allocated to the system handle with the
"Reallocate" function. Invoking the "Deallocate"
function would decrease the system handle to zero size,
but it must not deallocate the raw handle itself. The
"Deallocate" function treats the system handle dif-
ferently than it treats other raw handles. If the
operating system can ever be "exited" (for example, the
way Windows can be exited), it must increase the size of
the system handle back to what is needed to fill 640K
and map these logical pages back into physical memory
before returning to DOS.







EMM Implementation Guidelines 207






There are two functional special cases for this handle:

- The first special case deals with Function 4
(Allocate Pages). This function must never return
zero as a handle value. Applications must always
invoke Function 4 to allocate pages and obtain a
handle which identifies its pages. Since Function 4
will never return a handle value of zero, an
application will never gain access to this special
handle.

- The second special case deals with Function 6
(Deallocate Pages). If the operating system uses
Function 6 to deallocate the pages which are
allocated to the system handle, the pages will be
returned to the manager for use, but the handle will
not be available for reassignment. The manager
should treat a "deallocate pages" function request
for this handle the same as a "reallocate pages"
function request, where the number of pages to
reallocate to this handle is zero.

o Terminate and Stay Resident (TSR) Program Cooperation:
In order for TSR's to cooperate with each other and with
other applications, TSR's must follow this rule: a
program may only remap the DOS partition it lives in.
This rule applies at all times, even when no expanded
memory is present.

o Accelerator Cards:
To support generic accelerator cards, the support of
Function 34, as defined by AST, is encouraged.





















EMM Implementation Guidelines 208





Appendix D
OPERATING SYSTEM/ENVIRONMENT USE OF FUNCTION 28



All expanded memory boards have a set of registers that
"remember" the logical to physical page mappings. Some
boards have extra (or alternate) sets of these mapping
registers. Because no expanded memory board can supply an
infinite number of alternate map register sets, this
specification provides a way to simulate them using Function
28 (Alternate Map Register Set).


Examples

For the examples in this section, assume the hardware
supports alternate map register sets. First Windows is
brought up, then "Reversi" is started. Then control is
switched back to the MS-DOS Executive. For this procedure,
here are the calls to the expanded memory manager:

Example 1

Allocate alt reg set ; Start up the MS-DOS
(for MS-DOS Executive) ; Executive

Set alt reg set
(for MS-DOS Executive)

Allocate alt reg set ; Start up Reversi
(for Reversi)

Set alt reg set
(for Reversi)

Map pages
(for Reversi)

Set alt ret set ; Switch back to MS-DOS
(for MS-DOS Executive) ; Executive












Operating System Use Of Function 28 209





Notice this procedure needed no "get" calls because the
register set contained all the information needed to save a
context. However, using "Get" calls would have no ill
effects.

Example 2

Allocate alt reg set ; Start up MS-DOS
(for MS-DOS Executive) ; Executive

Set alt reg set
(for MS-DOS Executive)

Get alt reg set
(for MS-DOS Executive)

Allocate alt reg set ; Start up Reversi
(for Reversi)

Set alt reg set
(for Reversi)

Map pages
(for Reversi)

Get alt reg set
(for Reversi)

Set alt reg set ; Switch back to MS-DOS
(for MS-DOS Executive) ; Executive

The important point to follow is that a Set must always
precede a Get. The model of Set then Get is the inverse of
what interrupt handlers use, which is Get then Set (Get the
old map context and Set the new one). Another crucial point
is that an alternate map register set must have the current
mapping when allocated; otherwise, the Set will create
chaos.

What happens if this is simulated in software? The same Set
and Get model applies. The main difference is where the
context is saved.











Operating System Use Of Function 28 210





Since the allocate call is dynamic and there is no limit on
the number of sets allocated, the OS/E must supply the space
required. Device drivers cannot allocate space dynamically,
since the request would fail. If the Allocate register set
call returns a status indicating the alternate map register
sets aren't supported, the OS/E must allocate space for the
context. It must also initialize the context using Function
15. At that point it can do the Set, passing a pointer to
the map context space. On the Get call, the EMM driver is
to return a pointer to the same context space.

Example 3

Allocate alt reg set ; Start up MS-DOS
(for MS-DOS Executive) ; Executive

Get Page Map
(for MS-DOS Executive)

Set alt reg set
(for MS-DOS Executive)

Allocate alt reg set ; Start up Reversi
(for Reversi)

Set alt reg set
(for Reversi)

Map pages
(for Reversi)

Get Page Map
(for Reversi)

Set alt ret set ; Switch back to MS-DOS
(for MS-DOS Executive) ; Executive

















Operating System Use Of Function 28 211





GLOSSARY



The following terms are used frequently in this specifica-
tion:


Allocate To reserve a specified amount of
expanded memory pages.

Application Program An application program is the program
you write and your customer uses. Some
categories of application software are
word processors, database managers,
spreadsheet managers, and project
managers.

Conventional memory The memory between 0 and 640K bytes,
address range 00000h thru 9FFFFh.

Deallocate To return previously allocated expanded
memory to the memory manager.

EMM See Expanded Memory Manager.

Expanded memory Expanded memory is memory outside DOS's
640K-byte limit (usually in the range of
C0000h thru EFFFFh).

Expanded Memory A device driver that controls the

Manager (EMM) interface between DOS application
programs and expanded memory.

Extended memory The 15M-byte address range between
100000h thru FFFFFFh available on an
80286 processor when it is operating in
protected virtual address mode.

Handle A value that the EMM assigns and uses to
identify a block of memory requested by
an application program. All allocated
logical pages are associated with a
particular handle.

Logical Page The EMM allocates expanded memory in
units (typically 16K bytes) called
logical pages.

Mappable Segment A 16K-byte region of memory which can
have a logical page mapped at it.


Glossary 212





Map Registers The set of registers containing the
current mapping context of the EMM
hardware.

Mapping The process of making a logical page of
memory appear at a physical page.

Mapping Context The contents of the mapping registers at
a specific instant. This context
represents a map state.

Page Frame A collection of 16K-byte contiguous
physical pages from which an application
program accesses expanded memory.

Page Frame A page frame base address is the
Base Address location (in segment format) of the
first byte of the page frame.

Physical Page A physical page is the range of memory
addresses occupied by a single 16K-byte
page.

Raw Page The smallest unit of mappable memory
that an expanded memory board can
supply.

Resident Application A resident application program is loaded
Program by DOS, executes, and remains resident
in the system after it returns control
to DOS. This type of program occupies
memory and is usually invoked by the
operating system, an application
program, or the hardware. Some example
of resident application programs are RAM
disks, print spoolers, and "pop-up"
desktop programs.

Status code A code that an EMM function returns
which indicates something about the
result of running the function. Some
status codes indicate whether the
function worked correctly and others may
tell you something about the expanded
memory hardware or software.








Glossary 213





Transient Application A transient application program is
Program loaded by DOS, executes, and doesn't
remain in the system after it returns
control to DOS. After a transient
application program returns control to
DOS, the memory it used is available for
other programs.

Unmap To make a logical page inaccessible for
reading or writing.











































Glossary 214





INDEX



Allocate Alternate Map Register Set 36, 163
Allocate DMA Register Set 36, 168, 190
Allocate Pages 5, 14, 23, 30, 34, 42, 43, 47, 49, 144,
147, 148, 193, 206, 208
Allocate Raw Pages 36, 46, 80, 89, 147-149, 190, 193,
206
Allocate Standard Pages 36, 42, 46, 80, 89, 144, 145,
147, 190, 193
Alter Page Map & Call 7, 10, 35, 113, 118, 189
Alter Page Map & Jump 7, 10, 35, 109, 189
Alternate Map 10, 36, 151, 153-155, 157-159, 161, 163,
164, 165-168, 170, 173, 175, 179, 182, 190, 197,
209, 210, 211
Alternate Map Register Set 10, 36, 151, 153-155, 157,
158, 159, 161, 163-168, 170, 173, 175, 190, 197,
209, 210
Alternate Mapping and Unmapping Methods 81
Alternate Register 139, 166, 173, 177
Data Aliasing 12
Deallocate Alternate Map Register Set 36, 166
Deallocate DMA Register Set 36, 175, 190
Deallocate Pages 5, 14, 25, 31, 34, 43, 49, 88, 145,
148, 208
Design Considerations 91, 151
Device Driver 1, 15, 43, 53, 55, 144, 148, 199, 201,
202, 204, 212
Disable DMA on Alternate Map Register Set 173
Disable OS/E Function Set 36, 179, 180, 182, 185
DMA 36, 138-140, 151, 152, 168-176, 190, 197
DMA Channels 139, 171, 173, 174, 197
DMA Register 36, 139, 140, 151, 152, 168-171, 173-176,
190, 197
DOS 1, 12, 14, 15, 19, 21, 30, 31, 49, 53, 88, 199-205,
207-214
Enable DMA on Alternate Map Register Set 170
Enable OS/E Function Set 36, 179, 180
Enable/Disable OS/E Function Set 179, 180, 182, 185
Exchange Memory Region 7, 10, 35, 120, 126, 127, 189
Expanded Memory Support of DMA 151
Expanded Memory Support of DMA Register Sets 151
Extended Memory 91
Function 1 37
Function 10 57
Function 11 58
Function 12 59
Function 13 61
Function 14 7, 63


Index 215





Function 15 13, 53, 55, 65, 67, 69, 71, 73, 76, 139,
153, 154, 155, 158, 211
Function 16 13, 73, 76, 78
Function 17 6, 80, 82, 85
Function 18 6, 43, 88, 144, 148, 207
Function 19 7, 91, 92, 94, 96
Function 2 4, 38
Function 20 7, 98, 100
Function 21 7, 42, 102, 105, 107
Function 22 109
Function 23 113, 118
Function 24 7, 120, 126
Function 25 6, 8, 46, 74, 85, 132, 136
Function 26 138, 142, 179, 182, 206
Function 27 42, 46, 80, 89, 144, 145, 147-149, 193, 206
Function 28 140, 151, 153, 157, 161, 163, 164, 166,
168, 170, 173, 175, 179, 182, 209
Function 29 177
Function 3 4, 40, 142
Function 30 138, 151, 153, 157, 161, 163, 166, 168,
170, 173, 175, 179, 182, 185
Function 4 4, 42, 43, 46, 47, 49, 80, 89, 144, 145,
147, 149, 193, 206, 208
Function 5 4, 46, 81
Function 6 4, 43, 49, 88, 145, 148, 208
Function 7 5, 51
Function 8 46, 50, 53, 55
Function 9 46, 50, 53, 55
Get & Set Page Map 35, 69
Get All Handle Pages 9, 34, 63
Get Alternate Map Register Set 36, 153, 154, 157, 190
Get Alternate Map Save Array Size 36, 161, 190
Get Attribute Capability 7, 96
Get Expanded Memory Hardware Information 10, 138, 142,
179, 182
Get Handle Attribute 35, 92
Get Handle Count 9, 34, 59
Get Handle Directory 10, 35, 102, 105, 107
Get Handle Name 35, 98
Get Handle Pages 7, 9, 34, 61
Get Hardware Configuration Array 36, 138
Get Interrupt Vector 15, 21, 30, 199, 204, 205
Get Mappable Physical Address Array 6, 8, 10, 35, 46,
85, 132, 136
Get Mappable Physical Address Array Entries 8, 136
Get Page Frame Address 5, 34, 38
Get Page Map 35, 65, 118, 153-155, 158, 211
Get Page Map Stack Space Size 35, 118
Get Partial Page Map 35, 73, 78
Get Size of Page Map Save Array 35, 65, 67, 71, 139
Get Size of Partial Page Map Save Array 74, 76, 78
Get Status 5, 34, 37

Index 216





Get Total Handles 35, 107
Get Unallocated Page Count 5, 22, 34, 40, 142
Get Unallocated Raw Page Count 36, 142, 189
Get Version 5, 34, 51
Get/Set Handle Attribute 9, 91, 92, 94, 96
Get/Set Handle Name 10, 98, 100
Get/Set Page Map 9, 13, 65, 67, 69, 71
Get/Set Partial Page Map 9, 13, 73, 76, 78
Handle Attribute 9, 35, 91-94, 96, 188
Handle Name 6, 7, 10, 35, 98, 100, 105, 106, 188, 198
Intel i, ii, 1, 5, 57, 58
Interrupt Vector 12, 15, 21, 30, 199, 204, 205
LIM 1, 7, 13, 19, 27, 53, 55, 138, 140, 206, 207
Logical Page 1, 5, 12, 16, 19, 23, 28, 31, 32, 46-48,
80-83, 85, 86, 88, 110, 111, 115, 116, 120, 122,
123, 125, 126, 128, 129, 131, 147, 194, 196, 207,
212-214
Logical Page/Physical Page Method 82
Logical Page/Segment Address Method 85
Lotus i, ii, 1, 5, 57, 58
Map Register 10, 13, 36, 53, 55, 151, 153-155, 157-159,
161, 163-168, 170, 173, 175, 179, 182, 190, 197,
209-211
Map/Unmap Handle Pages 46
Map/Unmap Multiple Handle Pages 9, 35, 80, 82, 85
Mapping and Unmapping Multiple Pages Simultaneously 80
Mapping Multiple Pages 6, 80
Microsoft i, ii, 1, 5, 14, 30, 42, 57, 58, 144, 148
Move Memory Region 35, 120, 121, 189
Move/Exchange Memory Region 7, 10, 120, 126
Open Handle 64, 102, 199, 200, 203, 204
Operating System 3, 8, 10-12, 42, 43, 59, 63, 107, 138,
139, 141, 142, 144-151, 153-159, 161-163, 165-171,
173-177, 179-183, 185, 186, 190, 191, 198, 206,
207-209, 213
Page Frame 1-6, 14, 17-19, 24, 28, 31, 34, 38, 39, 47,
53, 55, 121, 128, 133, 187, 213
Page Map 7, 9, 10, 13, 34, 35, 50, 53, 55, 65, 67, 69,
71, 73-76, 78, 109, 113, 118, 139, 153-155, 158,
187, 188, 189, 211
Page Mapping Register I/O Array 57
Page Translation Array 58
Physical Page 1, 5, 6, 8, 10, 12, 16, 23, 28, 31, 35,
46, 47, 48, 80-83, 85, 109-112, 114-117, 132-134,
136, 138, 139, 142, 147, 188, 194, 207, 209, 213
Prepare Expanded Memory Hardware For Warm Boot 10, 177
Raw Handle 147, 149, 150, 206, 207
Raw Page 36, 142, 143, 147, 189, 206
Reallocate Pages 9, 35, 43, 88, 144, 145, 148, 208
Restore Page Map 9, 13, 34, 50, 53, 55
Return Access Key 185
Save Page Map 9, 13, 34, 50, 53, 55

Index 217





Search For Named Handle 7, 35, 105
Set Alternate Map Register Set 36, 153-155, 157, 158,
163, 190
Set Handle Attribute 9, 35, 91, 92, 94, 96
Set Handle Name 7, 10, 35, 98, 100
Set Page Map 9, 13, 35, 65, 67, 69, 71, 188
Set Partial Page Map 9, 13, 35, 73, 76, 78
Standard Handle 146
Standard Page 147
System DMA Capabilities 151
TSR 12, 13, 208
Unmapping Multiple Pages 6, 80









































Index 218

 MµpALLINFO.TXT
Following are BBSes that are members of DV-NET. DV-Net is an informal
network of BBS's that carry files that would be useful to DESQview users.
Not all BBSes that carry the DESQview conference are members of DV-Net.

All address are NetMail addresses.

----------------------------------------------
DVNet DESQview Support File Network
----------------------------------------------
DESQview is a trademark of Quarterdeck Office Systems
-----------------------------------------------------------
DVNet is not affiliated with Quarterdeck Office Systems
----------------------------------------------------------------

Name, City and State NetAddress Telephone Maxbaud
------------------------------- ---------- ------------ -------
*65'North, Fairbanks, AK 1:17/38 907-452-1460 9600HSTV32
Opus 386, Davis, CA 1:203/910 916-753-6321 2400
Carl's Corner, San Jose, CA 1:10/1 408-248-9704 9600HSTV32
Carl's Corner, San Jose, CA 1:10/2 408-248-0198 2400
SeaHunt BBS, Burlingame, CA 1:125/20 415-344-4348 9600HST
Stingray!, Clovis CA 1:205/12 209-298-9461 9600HST
SF PCUG BBS, San Francisco CA 1:1/310 415-621-2609 9600HSTV32RE
Bink of an Aye, Portland, OR 1:105/42 503-297-9043 9600PEPV32MO
P C Support, Portland, OR 1:105/66 503-297-9078 2400
Atarian BBS, Portland, OR 1:105/10 503-245-9730 9600HSTV32
Busker's BoneYard, Portland,OR 1:105/14 503-771-4773 9600PEP
Busker's Boneyard, Portland,OR 1:105/41 503-775-7926 9600HSTV32
Pacifier BBS, Vancouver, WA 1:105/103 206-253-9770 9600HSTV32
Puget Sound Gtwy., Puyallup, WA 1:138/3 206-566-8854 9600HST
Rampart General,Kansas City,MO 1:280/6 816-761-4039 9600HST
Oregon Trail XRoads, Casper WY 1:303/5 307-472-3615 9600H96
Dawg Byte, Nashville, TN 1:116/29 615-385-4268 9600HST
Dickson County, Dickson, TN 1:116/25 615-446-4475 2400
Programmers' Attic, Will., MI 1:159/850 517-655-3347 2400
Dark Side Of the Moon,Savoy IL 1:233/493 217-356-6922 9600HSTV32
Ecclesia Place, Monroeville, PA 1:129/75 412-373-8612 9600HST
The Other BBS, Harrisburg PA 1:270/101 717-657-2223 9600HST
IBM Tech Fido, Pepperell, MA 1:322/1 508-433-8452 9600HSTV32
Waystar BBS, Marlborough, MA 1:322/14 508-481-7147 9600HST
Andromeda Galaxy, Troy NY 1:267/167 518-273-8313 9600HST
Treasure Island, Danbury, CT 1:141/730 203-791-8532, 9600HST
Addict's Attic,Germantown MD 1:109/423 301-428-8998 9600HST
Maple Shade Opus,Maple Shade NJ 1:266/12 609-482-8604 9600HSTV32
Capital City , Burlington NJ 99:9230/1 609-386-1989 9600HSTV32
Capital City , Burlington NJ 8:950/10 609-386-1989 9600HSTV32
Southern Cross BBS, Miami FL 1:135/69 305-220-8752 9600HST
Software Designer, Albany, GA 1:3617/1 912-432-2440 9600HSTV32
Software Designer, Albany, GA 8:928/1 912-432-2440 9600HSTV32
Dragon's Lair, Galveston, TX 1:386/451 409-762-2761 9600HST
Dragon's Lair, Galveston, TX 1:386/1451 409-762-7456 2400MNP
Conch Opus, Houston, TX 1:106/357 713-667-7213 2400PCP
Inns of Court, Dallas, TX 1:124/6101 214-458-2620 9600HSTV32
Dallas Email, Dallas, TX 8:930/101 214-358-1205 9600HSTV32MO
Spare Parts, Bedford, TX 1:130/38 817-540-3527 9600HST
QE2, Austin TX 1:382/58 512-328-1229 2400
Ned's Opus HST Ottawa,ON Canada 1:163/211 613-523-8965 9600HST
Ned's Opus, Ottawa ON Canada 1:163/210 613-731-8132 2400
Imperial Terran, St Cath,ON 1:247/102 416-646-7105 9600HST
Arcane BBS, Laval PQ Canada 1:167/116 514-687-9586 9600HST
Zone 2 & Zone 3
------------------------------ --------- ------------- -------
The HEKOM Board (Netherlands) 2:286/3 31-3483-4072 2400MNP5
BBS_D.C.V.V., Maaseik (Belgium) 2:295/26 32-11-568620

  3 Responses to “Category : Recently Uploaded Files
Archive   : PCGPE.ZIP
Filename : LIMEMS41.DOC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/