After establishing that the memory-manager software is present, the application program communicates with it directly by means of the "user interrupt" 67H, bypassing MS-DOS/PC-DOS. The calling sequence for the EMM is as follows:
mov ah,function ; AH determines service type
. ; load other registers with
. ; values specific to the
. ; requested service
int 67h
In general, AH contains the EMM function number, AL holds the subfunction number (if any), BX holds a number of pages (if applicable), and DX contains an EMM handle. Registers DS:SI and ES:DI are used to pass the addresses of arrays or buffers. Section 4 of this book, "Lotus/Intel/Microsoft EMS Functions Reference," details each of the expanded memory functions.
Upon return from an EMM function, the AH register contains zero if the function was successful; otherwise, it contains an error code with the most significant bit set (Figures 11-6 and 11-7). Other values are typically returned in the AL and BX registers or in a user-specified buffer.
Error code Meaning
00H Function successful.
80H Internal error in Expanded Memory Manager software
(could be caused by corrupted memory image of driver).
81H Malfunction in expanded-memory hardware.
82H Memory manager busy.
83H Invalid handle.
84H Function requested by application not defined.
85H No more handles available.
86H Error in save or restore of mapping context.
87H Allocation request specified more logical pages than
physically available in system; no pages allocated.
88H Allocation request specified more logical pages than
currently available in system (request does not exceed
physical pages that exist, but some are already
allocated to other handles); no pages allocated.
Zero pages; cannot be allocated.
8AH Logical page requested to be mapped located outside
range of logical pages assigned to handle.
8BH Illegal physical page number in mapping request (not in
range
0—3).
8CH Page-mapping hardware-state save area full.
8DH Save of mapping context failed; save area already
contains context associated with requested handle.
8EH Restore of mapping context failed; save area does not
contain context for requested handle.
8FH Subfunction parameter not defined.
Figure 11-6. Expanded Memory Manager error codes common to EMS versions 3.0, 3.2, and 4.0. After a call to EMM, the AH register contains zero if the function was successful or an error code in the range 80H through 8FH if the function failed.
Error code Meaning
90H Attribute type not defined.
91H Feature not supported.
92H Source and destination memory regions have same handle
and overlap; requested move was performed, but part of
source region was overwritten.
93H Specified length for source or destination memory
region is longer than actual allocated length.
94H Conventional-memory region and expanded-memory region
overlap.
95H Specified offset is outside logical page.
96H Region length exceeds 1 MB.
97H Source and destination memory regions have same handle
and overlap; exchange cannot be performed.
98H Memory source and destination types undefined.
99H This error code currently unused.
9AH Alternate map or DMA register sets supported, but the
alternate register set specified is not supported.
9BH Alternate map or DMA register sets supported, but all
alternate register sets currently allocated.
9CH Alternate map or DMA register sets not supported, and
specified alternate register set not zero.
9DH Alternate map or DMA register sets supported, but
alternate register set specified is either not defined
or not allocated.
Dedicated DMA channels not supported.
9FH Dedicated DMA channels supported, but specified DMA
channel not supported.
A0H No handle found for specified name.
A1H Handle with this name already exists.
A2H Memory address wrap; sum of the source or destination
region base address and length exceeds 1 MB.
A3H Invalid pointer passed to function, or contents of
source array corrupted.
A4H Access to function denied by operating system.
Figure 11-7. Expanded Memory Manager error codes unique to EMS version 4.0. Most of these errors are related to the EMS functions for use by operating systems and would not normally be encountered by application programs.
An application program that uses expanded memory should regard that memory as a system resource, like a file or a device, and employ only the documented EMM services to allocate, access, and release expanded-memory pages. Such a program can use the following general strategy:
1.Establish the presence of the Expanded Memory Manager by one of the two methods demonstrated in Figures 11-4 and 11-5.
2.After the driver is known to be present, check its operational status with EMS Function 40H.
3.Check the version number of EMM with EMS Function 46H, to ensure that all services the application will request are available.
4.Obtain the segment of the page frame used by EMM with EMS Function 41H.
5.Allocate the desired number of expanded-memory pages with EMS Function 43H. If the allocation is successful, EMM returns a handle that the application can use to refer to the expanded-memory pages that it owns. This step is exactly analogous to opening a file and using the handle obtained from the open function for read/write operations on the file.
6.If the requested number of pages are not available, the application can query EMM for the actual number of pages available (EMS Function 42H) and determine whether it can continue.
7.After the application has successfully allocated the needed number of expanded-memory pages, it uses EMS Function 44H to map logical pages in and out of the physical page frame in order to store and retrieve data in expanded memory.
8.When the program finishes using its expanded-memory pages, it must release them by calling EMS Function 45H. Otherwise, the pages will be lost to use by other programs until the system is restarted.
Figure 11-8 shows a skeleton program that illustrates this general approach.
An interrupt handler or device driver that uses EMS follows the same general procedure outlined in steps 1 through 8, with a few minor variations. It may need to acquire an EMS handle and allocate pages before the operating system is fully functional; in particular, you cannot assume that the MS-DOS Open File or Device, IOCTL, and Get Interrupt Vector functions are available. Thus, such a handler or driver must use a modified version of the "get interrupt vector" technique (Figure 11-5) to test for the existence of EMM, fetching the contents of the Int 67H vector directly.
A device driver or interrupt handler typically owns its expanded-memory pages permanently (until the system is restarted) and never deallocates them. Such a program must also take care to save and restore EMM's page-mapping context (EMS Functions 47H and 48H) whenever it accesses expanded memory, so that use of EMS by a foreground program will not be disturbed.
The EMM relies on the good behavior of application software to avoid the corruption of expanded memory. If several applications that use expanded memory are running under a multitasking manager such as Microsoft Windows and one or more of them does not abide strictly by EMM conventions, the data of some or all of the applications may be destroyed.
.
.
.
mov ah,40h ; test EMM status
int 67h
or ah,ah
jnz error ; jump if bad status from EMM
mov ah,46h ; check EMM version
int 67h
or ah,ah
jnz error ; jump if couldn't get version
cmp al,030h ; make sure at least ver 3.0
jb error ; jump if wrong EMM version
mov ah,41h ; get page frame segment
int 67h
or ah,ah
jnz error ; jump if failed to get frame
mov page_frame,bx ; save segment of page frame
mov ah,42h ; get number of available pages
int 67h
or ah,ah
jnz error ; jump if get pages error
mov total_pages,dx ; save total EMM pages
mov avail_pages,bx ; save available EMM pages
or bx,bx
jz error ; abort if no pages available
mov ah,43h ; try to allocate EMM pages
mov bx,needed_pages
int 67h ; if allocation is successful
or ah,ah
jnz error ; jump if allocation failed
mov emm_handle,dx ; save handle for allocated pages
.
. ; now we are ready for other
. ; processing using EMM pages
.
; map in EMS memory page...
mov bx,log_page ; BX <- EMS logical page number
mov al,phys_page ; AL <- EMS physical page (0-3)
mov dx,emm_handle ; EMM handle for our pages
mov ah,44h ; function 44h = map EMS page
int 67h
or ah,ah
jnz error ; jump if mapping error
.
.
. ; program ready to terminate,
; give up allocated EMM pages...
mov dx,emm_handle ; handle for our pages
mov ah,45h ; EMS function 45h = release pages
int 67h
or ah,ah
jnz error ; jump if release failed
.
.
.
Figure 11-8. A program illustrating the general strategy for using expanded memory.