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