READ THIS FIRST The Lotus/Intel/Microsoft Expanded Memory Specification changes from time to time, so you should contact Intel occasionally to ensure that you are using the most recent version. You can reach us at one of our Customer Support numbers. o If you live in the continental United States but outside Oregon, call (800) 538-3373. o If you live in Oregon, Hawaii, Alaska, or outside the continental United States, call (503) 629-7354. o If you live in Canada, call (800) 234-0444. Customer Support representatives are ready to answer your call Monday through Friday, from 7 a.m. to 5 p.m. Pacific time. THE LOTUS(R)/INTEL(R)/MICROSOFT(R) EXPANDED MEMORY SPECIFICATION Version 3.20 Part number: 300275-003 September, 1985 Copyright (c) 1985 Lotus Development Corporation, 55 Cambridge Ave., Cambridge, MA 02142 Intel Corporation, 3065 Bowers Ave., Santa Clara, CA 95051 Microsoft Corporation, 10700 Northup Way, Bellevue, WA 98009 ii 300275-003 Note: This specification was jointly developed by Lotus Development Corporation, Intel Corporation, and Microsoft Corporation. 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 MICROSOFT 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 MODIFICATION OF THIS SPECIFICATION. 300275-003 iii How to use this specification If you're already familiar with the concept of expanded memory or if you're interested in only parts of the spec reading this preface can save you time. It gives a brief summary of each chapter so you can decide what you need to read. Chapter 1 -- Introduction to expanded memory This chapter introduces the concept of expanded memory and discusses the following topics: o Memory addressing capabilities of the Intel 8086, 8088, and 80286 microprocessors o Accessing expanded memory o Frequently used terminology You can skip this chapter if you're already familiar with the Intel 8086, 8088, and 80286 microprocessors and you understand expanded memory. Chapter 2 -- Writing programs that use expanded memory This chapter provides guidelines to help you create programs that use expanded memory. It also describes the individual Expanded Memory Manager (EMM) functions in detail, with assembly language examples, parameter passing conventions, and an explanation of the status and results returned by the function. You should read this chapter if you want to write programs that use expanded memory. Chapter 3 -- Testing for the presence of the Expanded Memory Manager This chapter describes two methods your program can use to test for the presence of the EMM. You should read this chapter if you want to write programs that use expanded memory. Chapter 4 -- Example expanded memory programs This chapter presents examples of expanded memory programs. iv 300275-003 Glossary The Glossary defines some of the terms that are used frequently in this specification. Most of the terms are defined for readers who understand technical terminology and are familiar with IBM PCs, XTs, and ATs, or compatibles. 300275-003 v Contents How to use this specification Chapter 1 -- Introduction The Intel 8086 and 8088 microprocessors......................1-1 The Intel 80286 microprocessor...............................1-1 How expanded memory is accessed..............................1-1 Limitations of the 8086, 8088, and 80286 microprocessors.....1-2 Terminology..................................................1-2 Chapter 2 -- Writing programs that use expanded memory Designing your program.......................................2-1 The operating environment..................................2-1 Mechanics of the EMM.......................................2-1 Programming guidelines.....................................2-2 The EMM functions............................................2-3 Overview of the EMM functions..............................2-3 FUNCTION 1 -- Get status...................................2-5 FUNCTION 2 -- Get page frame address.......................2-6 FUNCTION 3 -- Get unallocated page count...................2-7 FUNCTION 4 -- Allocate pages...............................2-9 FUNCTION 5 -- Map handle pages.............................2-11 FUNCTION 6 -- Deallocate pages.............................2-13 FUNCTION 7 -- Get EMM version..............................2-15 FUNCTION 8 -- Save page map................................2-16 FUNCTION 9 -- Restore page map.............................2-18 FUNCTION 10 -- Reserved....................................2-20 FUNCTION 11 -- Reserved....................................2-21 FUNCTION 12 -- Get EMM handle count........................2-22 FUNCTION 13 -- Get EMM handle pages........................2-23 FUNCTION 14 -- Get all EMM handle pages....................2-25 FUNCTION 15 -- Get/set page map............................2-27 Summary of status codes......................................2-33 Chapter 3 -- Testing for presence of the manager Which method should my program use?..........................3-1 The "open handle" technique..................................3-1 Using the "open handle" technique..........................3-1 An example of the "open handle" technique..................3-4 vi 300275-003 The "get interrupt vector" technique.........................3-6 Using the "get interrupt vector" technique.................3-6 An example of the "get interrupt vector" technique.........3-7 Chapter 4 -- Example expanded memory programs Characteristics of the example procedures....................4-1 Transient application program................................4-1 Flow chart of a transient application program..............4-1 Explanation of the transient application program flow chart.................................................4-2 Initialization procedures................................4-2 Processing procedures....................................4-3 Terminating procedures...................................4-3 Resident application program.................................4-3 Flow chart of a resident application program...............4-4 Explanation of the resident application program flow chart.................................................4-5 Initializing the resident program and the EMM............4-5 Saving the current state of the CPU......................4-6 Resident processing performed before accessing expanded memory..........................................4-6 Saving the state of the expanded memory hardware.........4-6 Accessing expanded memory................................4-6 Restoring the state of the expanded memory hardware......4-7 Terminating the resident program.........................4-7 Restoring the CPU state..................................4-7 Example EMM procedures.......................................4-8 Glossary 300275-003 vii CHAPTER 1. INTRODUCTION TO EXPANDED MEMORY This specification describes a way to expand the memory addressing capabilities of the Intel 8086, 8088, and 80286 microprocessors. It introduces a "paging" mechanism to access very large amounts of memory. This memory paging (also known as bank switching or bank swapping) uses a type of memory called "expanded memory." The rest of this chapter describes the memory addressing capabilities of the Intel 8086, 8088, and 80286 microprocessors and how the interface described in this specification overcomes their limitations. The Intel 8086 and 8088 microprocessors The Intel 8086 and 8088 microprocessors let programs or operating systems directly access up to 1M byte of address space. DOS, the most frequently used operating system for 8086 and 8088-based IBM personal computers and compatibles, allows application programs to use only up to 640K bytes of memory. This memory space often is not enough for application programs which require large amounts of memory to implement spreadsheets, databases, and other memory-intensive functions. The Intel 80286 microprocessor Although the Intel 80286 microprocessor can address more memory space (up to 16M bytes) than the 8086 and 8088 microprocessors, the amount of memory DOS can access directly is still limited to 640K bytes. This limitation is imposed because the 80286 microprocessor operates under one of two modes: Real Mode or Protected Virtual Addressing Mode (PVAM). When operating in Real Mode, the 80286 microprocessor lets programs or operating systems directly access only up to 1M byte of address space. This is the mode that DOS uses, so application programs which run on IBM's AT or AT-compatible machines are still limited to 640K bytes of usable memory space. When operating in PVAM, the 80286 microprocessor lets programs that run under the XENIX operating system address up to 16M bytes of memory. However, since most IBM AT or AT-compatible machines operate under DOS, application programs can rarely take advantage of this extra memory. Introduction 300275-003 1-1 How expanded memory is accessed Much as your computer screen acts as a small "window" into a much larger spreadsheet, memory paging provides one or more small "windows" of memory through which a much larger memory space can be accessed. These windows are called physical pages. This specification describes a method where four contiguous physical pages of 16K bytes each (forming a block of 64K bytes) can access up to 8M bytes of expanded memory space via the Expanded Memory Manager (EMM). Limitations of the 8086, 8088, and 80286 microprocessors You can use the Expanded Memory Manager (EMM) to overcome the memory limitations of the Intel 8086, 8088, and 80286 microprocessors. The EMM is a set of standard interface routines which allow programs, running on IBM PCs, XTs, ATs, or compatibles, to use up to 8M bytes of expanded memory. Because the EMM is a standard, programs that adhere to the Lotus/Intel/Microsoft Expanded Memory Specification can avoid potential compatibility problems. Expanded memory application programs that deal directly with the hardware or that don't strictly adhere to the specification run this risk. Chapter 3 of this specification describes the EMM in detail. Terminology The following terms are used frequently in this specification: o Conventional memory Conventional memory refers to the memory DOS recognizes. In PCs, XTs, and ATs, this is memory between 0 and 640K bytes. Because application programs let DOS manage their memory, they can use only conventional memory. o Expanded memory Expanded memory is a special kind of memory that goes beyond DOS's 640K-byte limit. Application programs that adhere to the Lotus/Intel Expanded Memory Specification can use the Expanded Memory Manager (EMM) to manage expanded memory just as other programs use DOS to manage conventional memory. o Extended memory 1-2 300275-003 Introduction Extended memory is the 15M-byte address space on an IBM AT or compatible computer outside the memory DOS can access. This address space is of little use to those application programs that use DOS. DOS does not recognized memory above 640K bytes; the XENIX operating system manages extended memory. Other terms are defined in the Glossary near the end of this specification. Introduction 300275-003 1-3 CHAPTER 2. WRITING PROGRAMS THAT USE EXPANDED MEMORY This chapter is divided into two major sections. The first section provides guidelines to help you create programs that use expanded memory. The second section describes the individual EMM functions in detail, with assembly language examples, parameter passing conventions, and an explanation of the status and results returned by the function. Designing your program While designing or planning a program that uses expanded memory, consider the following topics: o The operating environment o The mechanics of the Expanded Memory Manager (EMM) o The programming guidelines presented here This section discusses these topics and lists some guidelines to help you to create programs that use expanded memory. The operating environment The guidelines in this section help ensure that your program works in systems that use expanded memory. To be "safe," your program should assume the system for which you're writing the program contains: o Multiple expanded memory boards. o Other resident programs which also use expanded memory. An example of a resident program is an interrupt service routine or a device driver. It can also be a program invoked by an interrupt service routine or just a program that preempts the active program. o Registers whose contents are modified by function invocations. This means your program can't rely on the contents of certain registers after a function invocation. (The registers that a particular function modifies are listed in the description of the function; all others are unchanged) Mechanics of the EMM Version 3.20 of the EMM is re-entrant and its critical regions are protected from interrupts. This means you'll never encounter a "busy" condition. However, the EMM requires programs to follow these rules: 2-4 300275-003 Writing programs o The physical size of each page is fixed at 16K bytes. o Four 16K-byte pages can be mapped into the system memory address space simultaneously and contiguously. The 64K-byte region which results from this mapping must begin at the address returned by EMM FUNCTION 2 (Get page frame). Note: Throughout the remainder of this document, the 64k-byte region returned by FUNCTION 2 is called the "page frame." Programming guidelines To ensure that your program runs correctly with the EMM, it should: o Not locate its stack within expanded memory. o Test for the presence of the EMM device by using one of two methods. The first method is to use the DOS "open handle" technique. The second method is to use the DOS "get interrupt vector" function to obtain the contents of interrupt vector 67h. Once you get the contents of interrupt vector 67h, you can inspect the device driver header. (Both methods are described Chapter 3 of this specification.) o Not use interrupt 67h. DOS normally sets aside interrupt vector table entries 60h through 67h for non-system software that uses software interrupts. However, the EMM uses interrupt vector 67h. It sets the contents of interrupt vector table entry 67h to the address of the EMM service procedure using the DOS "Set Interrupt Vector" function. Other software that uses this vector won't work once the EMM installs itself because the EMM does not chain to any software previously serviced by this interrupt vector. Note: Resident software that uses INT 67h and installs itself after the EMM, will disable the EMM. o Request the page frame base address after determining that the EMM is installed. This page frame base address is the starting address of the 64K-byte memory segment that contains the four 16K-byte pages. The first 16K-byte physical page address begins at this base address. The second 16K-byte physical page address starts at the base address offset by 4000h. The third 16K-byte physical page address starts at the base address offset by 8000h. The fourth 16K-byte physical page starts at the base address offset by C000h. o Request the number of unallocated 16K-byte pages within the expanded memory system. This determines the maximum number of pages the program can allocate. Writing programs 300275-003 2-5 o "Open" the EMM and allocate the number of 16K-byte pages that it intends to use. The EMM returns a unique "EMM handle" that the program uses to identify itself in all future transactions with the EMM. The EMM uses this handle to identify the memory it allocates to each program. (Your program should obtain EMM handle(s) and allocate pages only once, at the beginning of the program.) The EMM attempts to assign the pages the program requests. If the number of pages it requests is greater than the number of free pages, the EMM returns an "error" status. The status codes the EMM returns are listed in this chapter. Note: A single application program can request multiple EMM handles and as many pages per EMM handle as it desires. The nature of the application determines the number of EMM handles and pages required. o Issue a map request to the EMM. (At this point the program can map any allocated logical page into any one of the four physical pages within the page frame.) The map operation must be performed before any data within the physical page can be accessed. If the logical page has not been assigned to this particular EMM handle, the EMM returns an error and doesn't carry out the mapping procedure. If the physical page (at which the logical page is mapped) isn't in the range 0 thru 3, the EMM returns an error. o Keep track of the contents of each page of expanded memory. The EMM doesn't provide a facility for associating data with a particular logical page. If a page contains data that will be accessed within the program, the program must remember which page contains the data. o "Close" the Expanded Memory Manager prior to terminating. This deallocates all pages previously allocated to the EMM handle. The deallocated pages become available to all other programs using expanded memory. The "close" request has no effect on these other programs. If the program does not perform a "close" before it exits to DOS, the pages allocated to the EMM handle will remain assigned. The only way to deallocate pages left in this condition is to power off the system. The EMM functions This section presents a general overview of the EMM functions, detailed descriptions of the individual functions, and a list that summarizes the status codes the EMM functions return. 2-6 300275-003 Writing programs Overview of the EMM functions The EMM functions provide you with a set of standard expanded memory functions. Because the EMM functions are standard, you avoid potential compatibility problems with other expanded memory programs that also adhere to the EMM specification. Programs that deal directly with the hardware or that don't adhere to the specification run this risk. Functions 1 through 7 -- for general-purpose programming Functions 1 through 7 provide the memory operators that typical application programs require. Of these seven functions, FUNCTION 5 (Map) is the only one that a program may use a great deal while running. Functions 8 and 9 -- for interrupt service routines, device drivers, and other resident software Functions 8 and 9 aren't necessary for most application programs. They are provided only for software that must save the current state of the mapping hardware, switch mapping contexts, manipulate the sections of expanded memory that they "own," and restore the original context of the memory mapping hardware. Examples of this type of software are interrupt service routines, device drivers, and resident software such as print spoolers that use expanded memory. Functions 10 and 11 -- reserved In previous versions of the Lotus/Intel/Microsoft Expanded Memory Specification, Function 10 retrieved the page mapping register I/O array and Function 11 retrieved the logical-to-physical page translation array. These functions are now reserved and new programs should not use them. However, existing programs that use these functions will still work correctly. Functions 12, 13, and 14 -- for utility programs Functions 12, 13, and 14 are also not necessary for most application programs. They are provided for utility programs that need to keep track of how expanded memory is being used. Writing programs 300275-003 2-7 Function 15 -- for multitasking operating systems Function 15 is for multitasking operating systems that must save the current state of the mapping hardware within each expanded memory board before modifying the state of the mapping hardware on any of the boards. 2-8 300275-003 Writing programs FUNCTION 1 Get Status The Get Status function returns a status code that tells you whether the EMM is present and if the hardware is working correctly. This function doesn't require an EMM handle. Parameter passing convention AH The AH register contains the function number (40h). Example invocation in assembly language This example shows how to invoke the Get Status function in assembly language. MOV AH, 40h INT 67h OR AH, AH JNZ error_handler Registers modified The Get Status function modifies the contents of the AX register. Status returned The Get Status function returns one of the following status codes. AH = 0 The manager is present in the system and the hardware is working correctly. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. Writing programs 300275-003 2-5 FUNCTION 2 Get Page Frame Address The Get Page Frame Address function tells your program where the page frame is located. It returns the segment portion of the page frame address in the BX register. This function doesn't require an EMM handle. Parameter passing convention AH The AH register contains the function number for the Get Page Frame function (41h). Example invocation in assembly language This example shows how to invoke the Get Page Frame Address function in assembly language. MOV AH, 41h INT 67h OR AH, AH JNZ error_handler MOV page_segment, BX Registers modified The Get Page Frame Address function modifies the contents of the AX and BX registers. Status returned The Get Page Frame Address function returns one of the following status codes. AH = 0 The manager has returned the page frame address. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. Results returned The Get Page Frame Address function returns these results. BX = segment The BX register contains the segment address of the page frame. The value in BX has no meaning if AH <> 0. 2-6 300275-003 Writing programs FUNCTION 3 Get Unallocated Page Count The Get Unallocated Page Count function tells your program the number of unallocated pages as well as the total number of pages in expanded memory. This function doesn't require an EMM handle. Parameter passing convention AH The AH register contains the function number for the Get Unallocated Page Count function (42h). Example invocation in assembly language This example shows how to invoke the Get Unallocated Pages Count function in assembly language. MOV AH, 42h INT 67h OR AH, AH JNZ error_handler MOV un_alloc_pages, BX MOV total_pages, DX Registers modified The Get Unallocated Pages Count function modifies the contents of the AX, BX, and DX registers. Status returned The Get Unallocated Pages Count function returns one of the following status codes. AH = 0 The manager has returned the number unallocated pages and the number of total pages in expanded memory. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. Writing programs 300275-003 2-7 FUNCTION 3 Get Unallocated Page Count (continued) Results returned The Get Unallocated Page Count function returns these results. BX = 0 All pages in expanded memory have already been allocated. None are currently available for expanded memory. BX <> 0 The number of pages that are currently available. DX <> 0 The total number of pages in expanded memory 2-8 300275-003 Writing programs FUNCTION 4 Allocate Pages The Allocate Pages function allocates the number of pages your program requests and assigns a unique EMM handle to these pages. The EMM handle "owns" these pages until your program deallocates them. Parameter passing convention AH The AH register contains the function number for the Allocate Pages function (43h). BX The BX register contains the number of pages your program wishes to allocate. Example invocation in assembly language This example shows how to invoke the Allocate Pages function in assembly language. MOV AH, 43h MOV BX, num_of_pages_to_alloc INT 67h OR AH, AH JNZ error_handler MOV emm_handle, DX Registers modified The Allocate Pages function modifies the contents of the AX and DX registers. Status returned The Allocate Pages function returns one of the following status codes. AH = 0 The manager has allocated the pages to an assigned EMM handle. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. AH = 85h All EMM handles are being used. AH = 87h There aren't enough expanded memory pages to supply your program's request. Writing programs 300275-003 2-9 FUNCTION 4 Allocate Pages (continued) AH = 88h There aren't enough unallocated pages to supply your program's request. AH = 89h Can't allocate zero pages. Results returned The Allocate Pages function returns these results. DX = handle The DX register contains a unique EMM handle. Your program must use this EMM handle (as a parameter) in any function invocations that map or deallocate expanded memory. 2-10 300275-003 Writing programs FUNCTION 5 Map Handle Page The Map Handle Page function lets your program access the information stored in logical page (i) at physical page (j) within the page frame. Parameter passing convention AH The AH register contains the function number for the Map Handle Page function (44h). BX The BX register contains the logical page (i) that is mapped into the physical page within the page frame. The logical page must be in the range 0 through (number of pages allocated to an EMM handle - 1). AL The AL register contains the physical page (j) into which the logical page (i) is mapped. This physical page must be in the range 0 thru 3. DX The DX register contains the EMM handle your program received from FUNCTION 4 (Allocate Pages). Example invocation in assembly language This example shows how to invoke the Map Handle Page function in assembly language. MOV DX, emm_handle MOV BX, i MOV AL, j MOV AH, 44h INT 67h OR AH, AH JNZ error_handler Registers modified The Map Handle Page function modifies the contents of the AX register. Status returned The Map Handle Page function returns one of the following status codes. AH = 0 The manager has mapped the page. The page is now ready to be accessed. AH = 80h The manager detected a malfunction in the EMM software. Writing programs 300275-003 2-11 FUNCTION 5 Map Handle Page (continued) AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 83h The EMM couldn't find the EMM handle your program specified. AH = 84h The function code passed to the EMM is not defined. AH = 8Ah The logical page is out of the range of logical pages which are allocated to the EMM handle. AH = 8Bh The physical page at which the logical page was supposed to be mapped is out of the range of physical pages. 2-12 300275-003 Writing programs FUNCTION 6 Deallocate Pages The Deallocate Pages function deallocates the pages currently allocated to an EMM handle. After your program invokes this function, other application programs can use these pages. Caution: Your program must perform this function before it exits to DOS. If it doesn't, no other programs can use these pages or their handle. Parameter passing convention AH The AH register contains the function number for the Deallocate Pages function (45h). DX The DX register contains the EMM handle returned by FUNCTION 4 (Allocate Pages). Example invocation in assembly language This example shows how to invoke the Deallocate Pages function in assembly language. MOV DX, emm_handle MOV AH, 45h INT 67h OR AH, AH JNZ error_handler Registers modified The Deallocate Pages function modifies the contents of the AX register. Status returned The Deallocate Pages function returns one of the following status codes. AH = 0 The manager has deallocated the pages previously allocated to the EMM handle. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 83h The EMM couldn't find the EMM handle your program specified. Writing programs 300275-003 2-13 FUNCTION 6 Deallocate Pages (continued) AH = 84h The function code passed to the EMM is not defined. AH = 86h The EMM 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 EMM handle specified. Save Page Map (FUNCTION 8) placed it there and it has not been removed by a subsequent Restore Page Map (FUNCTION 9). You need to restore the contents of the page mapping register before you deallocate the EMM handle's page(s). 2-14 300275-003 Writing programs FUNCTION 7 Get EMM Version The Get EMM Version function returns the version number of the Expanded Memory Manager software. Parameter passing convention AH The AH register contains the function number for the Get EMM Version function (46h). Example invocation in assembly language This example shows how to invoke the Get EMM Version function in assembly language. MOV AH, 46h INT 67h OR AH, AH JNZ error_handler Registers modified The Get EMM Version function modifies the contents of the AX register. Status returned The Get EMM Version function returns one of the following status codes. AH = 0 The manager is present in the system and the hardware is working correctly. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. Results returned The Get EMM Version function returns these results. AL = version The AL register contains the Expanded Memory Manager's version number in BCD. The upper four bits in the AL register contain the integer digit (3.x) of the version number. The lower four bits in the AL register contain the fractional digit of (x.2) version number. Writing programs 300275-003 2-15 FUNCTION 7 Get EMM Version The value contained in AL has no meaning if AH <> 0. 2-16 300275-003 Writing programs FUNCTION 8 Save Page Map (continued) The Save Page Map function saves the contents of the page mapping registers from all expanded memory boards. These registers contain 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 facilitates saving the state of the mapping hardware. 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.) Chapter 4 of this specification discusses resident software in general. It explains the assignment of an EMM handle and the allocation of pages to resident programs. Parameter passing convention AH The AH register contains the function number for the Save Page Map function (47h). DX The DX register 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 (FUNCTION 5). Example invocation in assembly language This example shows how to invoke the Save Page Map function in assembly language. MOV DX, emm_handle MOV AH, 47h INT 67h OR AH, AH JNZ error_handler Registers modified The Save Page Map function modifies the contents of the AX register. Writing programs 300275-003 2-17 FUNCTION 8 Save Page Map Status returned The Save Page Map function returns one of the following status codes. AH = 0 The manager has saved the state of the page mapping hardware. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 83h The EMM couldn't find the EMM handle your program specified. AH = 84h The function code passed to the EMM is not defined. AH = 8Ch There is no room in the "save" area to store the state of the page mapping registers. AH = 8Dh The "save area" already contains the page mapping register state for the EMM handle your program specified.. 2-18 300275-003 Writing programs FUNCTION 9 Restore Page Map (continued) The Restore Page Map function restores the contents of the page mapping registers on the expanded memory boards for a particular EMM handle. This function lets your program restore the contents of the mapping registers which its EMM handle saved. (See FUNCTION 8 -- Save Page Map for the "save" operation.) 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 restore 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 Restore Page Map function facilitates restoring the state of the mapping hardware. 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.) Chapter 4 of this specification discusses resident software in general. It explains the assignment of an EMM handle and the allocation of pages to resident programs. Parameter passing convention AH The AH register contains the function number for the Restore Page Map function (48h). DX The DX register 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. Example invocation in assembly language This example shows how to invoke the Restore Page Map function in assembly language. MOV DX, emm_handle MOV AH, 48h INT 67h OR AH, AH JNZ error_handler Registers modified The Restore Page Map function modifies the contents of the AX register. Writing programs 300275-003 2-19 FUNCTION 9 Restore Page Map Status returned The Restore Page Map function returns one of the following status codes. AH = 0 The manager has restored the state of the page mapping registers. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 83h The EMM couldn't find the EMM handle your program specified. AH = 84h The function code passed to the EMM is not defined. AH = 8Eh There is no page mapping register state in the save area for the EMM handle your program specified. Your program didn't save the contents of the page mapping hardware, so Restore Page Map can't restore it. 2-20 300275-003 Writing programs FUNCTION 10 Reserved In previous versions of the Lotus/Intel/Microsoft Expanded Memory Specification, Function 10 retrieved the page mapping register I/O array. This function is now reserved and new programs should not use it. Note: Existing programs that use this function will still work correctly. Writing programs 300275-003 2-21 FUNCTION 11 Reserved In previous versions of the Lotus/Intel/Microsoft Expanded Memory Specification, Function 10 retrieved the logical-to-physical page translation array. This function is now reserved and new programs should not use it. Note: Existing programs that use this function will still work correctly. 2-22 300275-003 Writing programs FUNCTION 12 Get EMM Handle Count The Get EMM Handle Count function return the number of active EMM handles. Parameter passing convention AH The AH register contains the function number for the Get EMM Handle Count function (4Bh). Example invocation in assembly language This example shows how to invoke the Get EMM Handle Count function in assembly language. MOV AH, 4Bh INT 67h OR AH, AH JNZ error_handler MOV total_active_emm_handles, BX Registers modified The Get EMM Handle Count function modifies the contents of the AX and BX registers. Status returned The Get EMM Handle Count function returns one of the following status codes. AH = 0 The manager has returned the number of active EMM handles. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 83h The EMM couldn't find the EMM handle your program specified. AH = 84h The function code passed to the EMM is not defined. Results returned The Get EMM Handle Count function returns these results. BX = x The BX register contains the number of active EMM handles. This number never exceeds 255. Writing programs 300275-003 2-23 FUNCTION 13 Get EMM Handle Pages (continued) The Get EMM Handle Pages function returns the number of pages allocated to a specific EMM handle. Parameter passing convention AH The AH register contains the function number for the Get EMM Handle Pages function (4Ch). DX The DX register contains the EMM handle. Example invocation in assembly language This example shows how to invoke the Get EMM Handle Pages function in assembly language. MOV DX, emm_handle MOV AH, 4Ch INT 67h OR AH, AH JNZ error_handler MOV num_pages_alloc_to_emm_handle, BX Registers modified The Get EMM Handle Pages function modifies the contents of the AX and BX registers. Status returned The Get EMM Handle Pages function returns one of the following status codes. AH = 0 The manager has returned the number of pages allocated to the EMM handle. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 83h THe EMM couldn't find the EMM handle your program specified. AH = 84h The function code passed to the EMM is not defined. 2-24 300275-003 Writing programs FUNCTION 13 Get EMM Handle Pages Results returned The Get EMM Handle Pages function returns these results. BX <> 0 The BX register contains the number of pages allocated to the EMM handle. The number returned is never zero because you can't allocate zero pages to an EMM handle. This number never exceeds 512 because the EMM allows, at most, 512 pages of expanded memory. Writing programs 300275-003 2-25 FUNCTION 14 Get All EMM Handle Pages (continued) The Get All EMM Handle Pages function returns an array of the active EMM handles and the number of pages allocated to each one. Parameter passing convention AH The AH register contains the function number for the Get All EMM Handle Pages function (4Dh). ES:DI The ES:DI address points to an array where a copy of all active EMM handles and the number of pages allocated to each is stored. Each entry in the array is composed of two words. The first word contains the active EMM handle. The second word contains the number of pages allocated to the EMM handle. To ensure that the array space your program must supply is large enough, use this formula to calculate the amount of memory required: number of bytes = 2 * 2 * number of EMM required in array handles returned (Each EMM handle requires 2 bytes as does each page number.) The array can never contain more than 1 K bytes. Caution: Be careful when you specify the array address in ES:DI so as not to cause "segment wrap" when the array is transferred. Example invocation in assembly language This example shows how to invoke the Return Open EMM Handle Pages function in assembly language. MOV AX, dseg MOV ES, AX MOV DI, OFFSET handle_pages_array MOV AH, 4Dh INT 67h OR AH, AH JNZ error_handler MOV total_active_emm_handles, BX Registers modified The Get All EMM Handle Pages function modifies the contents of the AX and BX registers. 2-26 300275-003 Writing programs FUNCTION 14 Get All EMM Handle Pages Status returned The Get All EMM Handle Pages function returns one of the following status codes. AH = 0 The manager has returned the array. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. Results returned The Return Open EMM Handle Pages function returns these results. BX = x The BX register contains the number of active EMM handles. If the number is 0 this indicates that the manager is "idle." This number never exceeds 255. Writing programs 300275-003 2-27 FUNCTION 15 Get/Set Page Map (continued) When a task switch occurs, a multitasking operating system must save (and later restore) the mapping context of the active EMM handle. The set of subfunctions that make up the Get/Set Page Map function let your operating system perform these operations. The Get/Set Page Map function is really a set of subfunctions. These subfunctions allow a multitasking operating system to: o "Get" the contents of the page mapping registers from the expanded memory boards. o "Set" the contents of the page mapping registers on the expanded memory boards. o "Get and Set" the contents of the page mapping registers on the expanded memory boards. This subfunction allows the operating system to perform both "get" and "set" in only one EMM invocation. o "Return Size" of the page mapping hardware state array for the operating system. This function is described a bit differently than the rest of the functions in this chapter. Since it is made up of four subfunctions, there are four subsections which contain the parameter passing convention, example invocation, status codes, and results returned for each service within the Get/Set Page Map function. Get the contents of the page mapping registers The Get subfunction copies the contents of the mapping registers from each expanded memory board to a destination array. The operating system must point to the destination array. This subfunction doesn't require an EMM handle. Parameter passing convention AH The AH register contains the function number for the Get/Set Page Map function (4Eh). AL = 0 When the AL register equals 0, the invocation requests the Get subfunction. It copies the map registers to an array pointed to by the ES:DI address. ES:DI The ES:DI address points to the destination array address in SEGMENT:OFFSET format. This address is required only for the Get or Get and Set services. Caution: Be careful when you specify the array address in ES:DI so as not to cause "segment wrap" when the array is transferred. 2-28 300275-003 Writing programs FUNCTION 15 Get/Set Page Map Example invocation in assembly language This example shows how to invoke the Get subfunction in assembly language. MOV AX, dseg MOV ES, AX MOV DI, OFFSET destination_page_map_array MOV AH, 4Eh MOV AL, 0 INT 67h OR AH, AH JNZ error_handler Registers modified The Get subfunction modifies the contents of the AX register. Status returned The Get subfunction returns one of the following status codes. AH = 0 The manager has returned the array. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. AH = 8Fh The subfunction parameter isn't equal to a Get request. Results returned The Get subfunction returns these results. ES:DI = addr The ES:DI address points to the memory area where the operating system has stored the state of all the mapping registers on all boards in the system. This memory area also contains any additional information necessary to restore the boards to their original state when the program invokes a Set subfunction. Set the contents of the page mapping registers The Set subfunction copies the contents of a source array into the mapping registers on each expanded memory board in the system. The operating system must point to the source array. This subfunction doesn't require an EMM handle. Writing programs 300275-003 2-29 FUNCTION 15 Get/Set Page Map (continued) Parameter passing convention AH The AH register contains the function number for the Get/Set Page Map function (4Eh). AL = 1 When the AL register equals 1, the invocation requests the Set subfunction. It copies the contents of the array pointed to by the DS:SI address to the map registers. DS:SI The DS:SI address points to the source array address in SEGMENT:OFFSET format. The operating system must point to an array which contains the mapping register state. This address is required only for the Set or Get and Set services. Caution: Be careful when you specify the array address in DS:SI so as not to cause "segment wrap" when the array is transferred. Example invocation in assembly language This example shows how to invoke the Set subfunction in assembly language. MOV AX, dseg MOV DS, AX MOV SI, OFFSET source_page_map_array MOV AH, 4Eh MOV AL, 1 INT 67h OR AH, AH JNZ error_handler Registers modified The Set subfunction modifies the contents of the AX register. Status returned The Set subfunction returns one of the following status codes. AH = 0 The manager has passed the array. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. 2-30 300275-003 Writing programs FUNCTION 15 Get/Set Page Map (continued) AH = 8Fh The subfunction parameter isn't equal to a Set request or the length of the array passed during the Set request doesn't match the number of mapping registers in the system. Writing programs 300275-003 2-31 FUNCTION 15 Get/Set Page Map (continued) Results returned The Set subfunction doesn't return any results. If the operating system used the Get subfunction correctly, the Set service should restore the expanded memory boards to their original state. (The Get subfunction, described previously in this chapter, saves the contents of the mapping register from each expanded memory board.) Get and set the contents of the page mapping registers The Get and Set subfunction first copies the contents of the mapping registers from each expanded memory board in the system into a destination array. (The operating system must point 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 operating system must point to the source array.) This subfunction doesn't require an EMM handle. Parameter passing convention AH The AH register contains the function number for the Get/Set Page Map function (4Eh). AL = 2 When the AL register equals 2, the invocation requests the Get and Set subfunction. This subfunction first copies the map registers to an array pointed to by the ES:DI address. And then, it copies the contents of the array pointed to by the DS:SI address to the map registers. ES:DI The ES:DI address points to the destination array address in SEGMENT:OFFSET format. This address is required only for the Get or Get and Set services. DS:SI The DS:SI address points to the source array address in SEGMENT:OFFSET format. The operating system must point to an array which contains the mapping register state. This address is required only for the Set or Get and Set services. Caution: Be careful when you specify the array address in ES:DI and DS:SI so as not to cause "segment wrap" when the array is transferred. 2-32 300275-003 Writing programs FUNCTION 15 Get/Set Page Map (continued) Example invocation in assembly language This example shows how to invoke the Get and Set subfunction in assembly language. MOV AX, dseg MOV ES, AX MOV DI, OFFSET destination_page_map_array MOV DS, AX MOV SI, OFFSET source_page_map_array MOV AH, 4Eh MOV AL, 2 INT 67h OR AH, AH JNZ error_handler Registers modified The Get and Set subfunction modifies the contents of the AX register. Status returned The Get and Set subfunction returns one of the following status codes. AH = 0 The manager has returned and passed both arrays AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. AH = 8Fh The subfunction parameter isn't equal to a Get and Set request. Results returned The Get and Set subfunction returns these results. ES:DI = addr The ES:DI address points to the memory area where the operating system stores the state of all the mapping registers on all boards in the system. (This happens during a Get subfunction.) This memory area also contains any additional information necessary to restore the boards to their original state when the program invokes a Set subfunction. Writing programs 300275-003 2-33 FUNCTION 15 Get/Set Page Map (continued) Return the size of the mapping context array for the operating system The Return Size subfunction determines the storage requirements for the array passed by the other three functions prior to invoking them. This subfunction doesn't require an EMM handle. 2-34 300275-003 Writing programs FUNCTION 15 Get/Set Page Map (continued) Parameter passing convention AH The AH register contains the function number for the Get/Set Page Map function (4Eh). AL = 3 When the AL register equals 3, the invocation requests the Return Size subfunction. This subfunction returns the size (in bytes) of the array that the Get, Set, or Get and Set subfunctions transfer to or from the operating system. Example invocation in assembly language This example shows how to invoke the Return Size subfunction in assembly language. MOV AH, 4Eh MOV AL, 3 INT 67h OR AH, AH JNZ error_handler MOV size_of_array, AL Registers modified The Return Size subfunction modifies the contents of the AX register. Status returned The Return Size subfunction returns one of the following status codes. AH = 0 The manager has returned the array size. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 84h The function code passed to the EMM is not defined. AH = 8Fh The subfunction parameter isn't equal to a Return Size request. Results returned The Return Size subfunction returns these results. Writing programs 300275-003 2-35 FUNCTION 15 Get/Set Page Map (continued) AL = n The contents of the AL register equals the number of bytes transferred to the memory area supplied by an operating system whenever a program requests the Get, Set, or Get and Set subfunction. 2-36 300275-003 Writing programs SUMMARY OF STATUS CODES -- ALL EMM FUNCTIONS Table 2-1 lists the possible status codes that the EMM functions can return. This table is for quick reference; the individual EMM functions list the status codes they return. Table 2-1. Summary of status codes Code Definition AH = 0 The manager is present in the system and the hardware is working correctly. AH = 80h The manager detected a malfunction in the EMM software. AH = 81h The manager detected a malfunction in the expanded memory hardware. AH = 83h The EMM couldn't find the EMM handle your program specified. AH = 84h The function code passed to the EMM is not defined. AH = 85h All EMM handles are being used. AH = 86h The EMM detected a "save" or "restore" page mapping context error. AH = 87h There aren't enough expanded memory pages to satisfy your program's request. Writing programs 300275-003 2-37 AH = 88h There aren't enough unallocated pages to satisfy your program's request. AH = 89h Can't allocate zero (0) pages. 2-38 300275-003 Writing programs Table 2-1. Summary of status codes (continued) Code Definition AH = 8Ah The logical page is out of the range of logical pages which are allocated to the EMM handle. AH = 8Bh The physical page to which the logical page is mapped is out of the range of physical pages. AH = 8Ch The page mapping hardware state save area is full. AH = 8Dh The page mapping hardware state save area already has a state associated with the EMM handle. AH = 8Eh The page mapping hardware state save area doesn't have a state associated with the EMM handle. AH = 8Fh The subfunction parameter passed to the function isn't defined. Writing programs 300275-003 2-39 CHAPTER 3. TESTING FOR THE PRESENCE OF THE EXPANDED MEMORY MANAGER Before an application program can take advantage of the Expanded Memory Manager (EMM), it must determine whether the manager has been loaded by DOS. This chapter describes two methods your program can use to test for the presence of the EMM 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 my program use? The majority of application programs can use either the "open file" 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 programs. The "open handle" technique Most application programs can use the DOS "open handle" technique to test for the presence of the EMM. 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 chapter. Using the "open handle" technique This section describes how to use the DOS "open handle" technique to test for the presence of the EMM. Follow these steps in order: 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 EMM. 3-2 3000275-003Testing for the presence of the EMM You should format the ASCII string as follows: ASCII_device_name DB "EMMXXXX0", 0 where 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 thru DOS. Go to Step 6. 4. If DOS returns a "File/Path not found" the EMM is not installed. If your application requires its presence the user will have to reboot the system with a disk containing the EMM 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 = 0h). DOS function 44h determines whether EMMXXXX0 is a device or a file. It also requires a pointer to a buffer (register set DS:DX). The EMM does not use the buffer for anything and will not pass information in it. You can set the number of bytes this function requires to perform read/write operations to zero (register CX) since no data is passed back in the buffer. 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. Testing for the presence of the EMM300275-003 3-3 7. If DOS returns any error status code, you should assume that the EMM device driver is not installed. If your application requires its presence the user will have to reboot the system with a disk containing the EMM 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 EMM device driver is not present. If your application requires its presence, the user will have to reboot the system with a disk containing the EMM 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 = 7h). This function requires a pointer to a buffer (register set DS:DX). The EMM does not use the buffer for anything and will not pass information in it. You can set the number of bytes (register CX) this function requires to perform read/write operations to zero since no data is passed back in the buffer. 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 EMM passes a status value of "0FFh" in register AL. The status value is "00h" if the device driver is "not ready." If the the EMM device driver is "not ready" and your application requires its presence, the user will have to reboot the system with a disk containing the EMM and the appropriate CONFIG.SYS file before proceeding. If the EMM device driver is "ready", go to Step 12. 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). 3-4 3000275-003Testing for the presence of the EMM 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 D S______________________________________________________________ ___________________________________________________________PUSH C S ____________________________________________________________POP D S ____________________________________________________________MOV A H, 3Dh__________________________________________; issue "device ____________________________________________________________LEA D X, ASCII_device_name___________________________; open" in "read ____________________________________________________________MOV A L, 0_______________________________________________; only" mode ____________________________________________________________INT 2 1h _____________________________________________________________JC f irst_test_for_EMM_error_exit___________________; test for error _______________________________________________________________ ; during "device _______________________________________________________________ ; open" ____________________________________________________________MOV B X, AX___________________________________________; get the "file _______________________________________________________________ ; handle" returned _______________________________________________________________ ; by DOS ____________________________________________________________MOV A X, 44h__________________________________________; issue "IOCTL" ____________________________________________________________MOV A L, 00h______________________________________; "get device info" ____________________________________________________________INT 2 1h Testing for the presence of the EMM300275-003 3-5 _____________________________________________________________JC f irst_test_for_EMM_err_exit_____________________; test for error _______________________________________________________________ ; during "get device _______________________________________________________________ ; info" ___________________________________________________________TEST D X, 0080h_________________________________; test to determine if _____________________________________________________________JZ f irst_test_for_EMM_err_exit__________________; ASCII_device_name _______________________________________________________________ ; is a device or a _______________________________________________________________ ; file ____________________________________________________________MOV A H, 44h__________________________________________; issue "IOCTL" ____________________________________________________________LEA D X, dummy_buffer___________________________________; "get output ____________________________________________________________MOV C X, 0__________________________________________________; status" ____________________________________________________________MOV A L, 07h ____________________________________________________________INT 2 1h _____________________________________________________________JC f irst_test_for_EMM_error_exit___________________; test for error _______________________________________________________________ ; during "IOCTL" ___________________________________________________________PUSH A X________________________________________________; save "IOCTL" _______________________________________________________________ ; status 3-6 3000275-003Testing for the presence of the EMM ____________________________________________________________MOV A H, 3Eh___________________________________________; issue "close ____________________________________________________________INT 2 1h_______________________________________________; file handle" ______________________________________________________________ ____________________________________________________________POP A X_____________________________________________; restore "IOCTL" _______________________________________________________________ ; status ____________________________________________________________CMP A L, 0FFh______________________________________; test for "device ____________________________________________________________JNE f irst_test_for_EMM_error_exit____________________; ready" status _______________________________________________________________ ; returned by the _______________________________________________________________ ; driver first_test_for_EMM_exit: ____________________________________________________________POP D S______________________________________________; EMM is present ____________________________________________________________STC ; in the system ____________________________________________________________RET first_test_for_EMM_error_exit: ____________________________________________________________POP D S__________________________________________; EMM is NOT present ____________________________________________________________CLC ; in the system ____________________________________________________________RET ASCII_device_name: DB "EMMXXXX0", 0 dummy_buffer DB 0 first_test_for_EMM ENDP Testing for the presence of the EMM300275-003 3-7 The "get interrupt vector" technique Any type of program can use the DOS "get interrupt vector" technique to test for the presence of the EMM. 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 EMM. 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:019C thru 0000:019F). The EMM 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 Expanded Memory Manager at boot time this name field will have the name of the device in it. Since the Expanded 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 the device is referenced by DOS. If the result of the "string compare" in this technique is positive you can be certain that the EMM driver is present. 3-8 3000275-003Testing for the presence of the EMM 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 E MM_____________________________________________________________ ; ;___in the system. It returns the CARRY FLAG SET if the EMM is ______________________________________________________________; ;___present. It returns the CARRY FLAG CLEAR if the EMM is not ______________________________________________________________; ;______________________________________________________present. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; second_test_for_EMM PROC NEAR ___________________________________________________________PUSH D S ___________________________________________________________PUSH C S ____________________________________________________________POP D S ____________________________________________________________MOV A H, 35h___________________________________; issue "get interrupt ____________________________________________________________MOV A L, 67h________________________________________________; vector" ____________________________________________________________INT 2 1h ____________________________________________________________MOV D I, 000Ah___________________________________; use the SEGMENT in _______________________________________________________________ ; ES returned by DOS, _______________________________________________________________ ; place the "device _______________________________________________________________ ; name field"OFFSET in DI ____________________________________________________________LEA S I, ASCII_device_name______________________; place the OFFSET of _______________________________________________________________ ; the EMMXXXX0 name _______________________________________________________________ ; string in SI, the _______________________________________________________________ ; SEGMENT is already in DS Testing for the presence of the EMM300275-003 3-9 ____________________________________________________________MOV C X, 8_________________________________; compare the name strings ____________________________________________________________CLD __________________________________________________________REPE C MPSB ___________________________________________________________JNE s econd_test_for_EMM_error_exit second_test_for_EMM_exit: ____________________________________________________________POP D S___________________________________________; EMM is present in ____________________________________________________________STC ; the system ____________________________________________________________RET second_test_for_EMM_error_exit: ____________________________________________________________POP D S__________________________________________; EMM is NOT present ____________________________________________________________CLC ; in the system ____________________________________________________________RET ASCII_device_name: DB "EMMXXXX0" second_test_for_EMM ENDP 3-10 3000275-003Testing for the presence of the EMM CHAPTER 4. EXAMPLE EXPANDED MEMORY PROGRAMS This chapter presents example procedures that use expanded memory. The first part of this chapter lists the basic characteristics of the example procedures. Later sections present annotated outlines (or flow charts) for writing transient and resident application programs that use expanded memory. The actual example code (with comments) is listed at the end of the chapter. Characteristics of the example procedures The example procedures in this chapter illustrate the EMM operations that a typical transient or resident program carries out when using expanded memory. When reading the examples, keep in mind that they: 1. Are implemented in assembly language. 2. Assume that all variables reside in the same segment and that DS is already set up for access to all the variables. 3. Assume that the application program will determine what to do with EMM error conditions when they are returned from the example procedures. The example procedures do not provide any error processing when an EMM error is detected. You could include a simple EMM error handling procedure that displays the function which was invoked and the status which was returned. Transient application program A transient program is loaded by DOS, executes, and doesn't remain resident in the system after it returns control to DOS. After a transient program returns control to DOS, the memory it used is available for other programs. This section presents an outline (or flow chart) which illustrates the structure of an example transient application program. It also includes a detailed explanation of the outline. Flow chart of a transient application program The following flow chart shows the structure of an example transient application program that uses expanded memory. The next section contains detailed explanations of the individual processes. Example expanded memory programs300275-003 4-11 Explanation of the transient application program flow chart This example transient application program is invoked from the DOS command line and loaded by DOS. It first executes some initialization procedures, then some processing procedures that use expanded memory, and finally, some terminating procedures. After the program terminates, it returns control to DOS. The following subsections describe the individual procedures within the flow chart. These subsections refer you to the actual code for each procedure. 4-12 300275-003Example expanded memory programs Initialization procedures The block labeled "transient application initialization" represents any preliminary processing and interaction with the user that the program may need to perform. After the transient program performs these operations, it should initialize the EMM. The block labeled "EMM transient initialization" represents code that prepares the EMM so it can run with the application program. An example of this type of procedure (called EMM_transient_init) is shown on page 4-10. This procedure uses the "open handle" technique to determine whether the EMM is present in the system. (The "open handle" technique is described in Chapter 3 of this specification.) The procedure also ensures that the version of the EMM loaded in the system is compatible with the version required by the application program, and it obtains the number of expanded memory pages your application code requests. Processing procedures The block labeled "transient application processing (not requiring expanded memory)" represents processing the program performs which does not require access to expanded memory. The block labeled "EMM access" represents the code that the application must execute before it can access expanded memory. (The expanded memory was allocated to it by the "EMM transient initialization" procedure.) An example of this type of procedure (called EMM_access) is shown on page 4-16. The example procedure maps the logical page allocated to the EMM handle into the physical page the application program specified. (The "EMM_transient_init" procedure assigned the EMM handle.) The block labeled "transient application processing (requiring expanded memory)" represents the processing within the program that uses the expanded memory area. The application can use the expanded memory area for data or code. An application program can locate code in the page frame and execute it, or it can just store data and access it. Your program can use the page frame to store anything except its stack; there is no code restriction. The loop to the block labeled "EMM access" represents a possible iterative process. The application may have a requirement to access many pages within expanded memory. The process of calling the "EMM_access" procedure and accessing the data in the mapped page is iterative. Terminating procedure Once the application completes its task, it must return the expanded memory that the EMM allocated to it. Example expanded memory programs300275-003 4-13 The block labeled "EMM termination" represents this phase of the application program's execution. An example of this type of procedure (called EMM_termination) is shown on page 4-17. This example procedure returns both the EMM handle and the logical pages to the EMM. (The EMM handle was issued and the logical pages were allocated by "EMM_transient_init" procedure.) The block labeled "transient application termination" represents the code the application needs to execute by before it terminates and returns control to DOS. Resident application program A resident application program is loaded by DOS, executes, and remains resident in the system after it returns control to DOS. This type of program is usually invoked by the operating system, a hardware interrupt, or a software interrupt. This section presents an outline (or flow chart) which illustrates the structure of an example resident application program. It also includes a detailed explanation of the flow chart. Flow Chart of a resident application program The following flow chart shows the structure of an example resident application program that uses expanded memory. The next section contains detailed explanations of the individual processes. 4-14 300275-003Example expanded memory programs Explanation of the resident application program flow chart Resident application programs are loaded from the CONFIG.SYS file as drivers or they are loaded by DOS and use the DOS "terminate and stay resident" function. Resident programs have special characteristics which must be taken into consideration when using expanded memory. They must initialize their own data structures as well as initializing the EMM (getting the page frame address, getting a handle assigned and allocating pages). Resident programs also consume a portion of conventional memory, making it unavailable for use by transient programs. Since they may interrupt transient programs which use expanded memory, resident programs must save and restore the state of the page mapping registers when using expanded memory. Functions 8 and 9 (described in Chapter 2) are provided for just this purpose. This example resident application program illustrated by the previous flow chart performs the following operations: o initializes its internal data structures as well as initializing the EMM o saves the CPU state o performs any processing it requires before accessing expanded memory o saves the state of the expanded memory hardware o accesses expanded memory o restores the state of the expanded memory hardware o terminates o restores the CPU state The remainder of this section describes these operations in detail. Initializing the resident program and the EMM The block labeled "resident application initialization " represents any preliminary processing the resident program may need to perform. The block labeled "EMM resident initialization" represents the code that prepares the EMM so it can run with the resident application program. A example of this type of procedure (called EMM_resident_init) is shown on page 4-13. Example expanded memory programs300275-003 4-15 This procedure uses the "get interrupt vector" test described in Chapter 3 to determine whether the EMM is present in the system. The procedure also ensures that the version of the EMM loaded in the system is compatible with the version required by the application program. In addition this procedure obtains an EMM handle and allocates the required number of pages for the resident program. Typically, the resident program will keep the handle assigned to it as well as the pages allocated to it until the system is rebooted. The first two blocks in the flow chart aren't directly connected to the blocks that follow. This flow chart depicts a common situation encountered in resident programs. Resident programs can be divided into a section of code which executes and then isn't needed afterwards. The programs usually return the memory consumed by the initialization section of the resident program to DOS for re-use by other programs. The "resident" section of the resident program remains in the memory until the system is rebooted. Typically, this code is executed whenever a particular hardware or software interrupt occurs, or when it is "called" by DOS. The first two blocks represent initialization code, which after it executes, never needed again. So, the code returns the memory which it used to DOS. The succeeding blocks in the flow chart represent the resident section of the code which is executed only when some event, such as a hardware or software interrupt, occurs. For this reason, the first two blocks in the flow chart are not connected to the succeeding blocks. Saving the current state of the CPU The block labeled "suspend transient program's execution" represents the code responsible for saving the current state of the CPU when the resident code begins executing. A hardware or software interrupt usually causes the resident code to begin executing. Saving the CPU's state is essential. At some point, the resident program must return control to the previously-executing program. Before the original program can continue to function correctly, the CPU must be returned to the exact state it was in before the resident program began executing. Resident processing performed before accessing expanded memory The block labeled "resident processing (not requiring expanded memory)" represents processing which must be performed by the resident application before it needs to access expanded memory. 4-16 300275-003Example expanded memory programs Saving the state of the expanded memory hardware The block labeled "save EMM map state" represents the code that must be executed before the resident program attempts to access expanded memory. This code must save the state of the expanded memory hardware before the resident program can map any of its pages into the page frame. Saving the state of the expanded memory hardware is essential, because another program may have been using it when the resident program took over. Saving the mapping state of the expanded memory hardware ensures that both the resident program and any transient program that may have been executing when the resident program started are not corrupted. An example of such a procedure (called EMM_save_map_state) is shown on page 4-18. Accessing expanded memory The block labeled "EMM access" represents the code that the resident program must execute before it can access expanded memory. (The expanded memory was allocated to it by "EMM resident initialization" procedure described earlier.) An example of this type of procedure (called EMM_access) is shown on page 4-16. The example procedure simply maps one of the logical pages allocated to the EMM handle assigned by the "EMM_resident_init" procedure into the physical page the resident program specified. The block labeled "resident application processing (requiring expanded memory)" represents the processing within the resident program which uses expanded memory. The resident program can use expanded memory for data or code. A resident program can locate code in the page frame and execute it or it can just store data and access it. Your program can use the page frame to store anything except its stack; there is no code restriction. The loop to the block labeled "EMM access" represents a possible iterative process. The resident program may have a requirement to access many pages within expanded memory. The process of calling the "EMM_access" procedure and accessing the data in the mapped page is iterative. Restoring the state of the expanded memory hardware The block labeled "restore EMM map state" represents the code in a resident program that restores the state of the expanded memory hardware. This code restores the expanded memory hardware to the state it was in before the resident program mapped its pages into the page frame. An example procedure (called EMM_restore_map_state) is shown on page 4-19. Example expanded memory programs300275-003 4-17 Terminating the resident program The block labeled "resident processing termination" represents any processing that the resident program must do before it terminates. After the resident program terminates, it returns control to the transient program that was executing before it took control. Restoring the CPU state The block labeled "restore CPU state" represents the code responsible for restoring the CPU to the state it was before the resident program took control. 4-18 300275-003Example expanded memory programs Example EMM procedures This section lists the code for all the EMM procedures referenced in the previous examples. ;; ;______________________________________________________________ ______________________________________________________________; ;___________FUNCTIONAL "EQUATES" USED THROUGHOUT THESE EXAMPLES ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; EMM_interrupt EQU 67h get_page_frame_address EQU 41h get_unalloc_page_count EQU 42h allocate_pages EQU 43h map_handle_page EQU 44h deallocate_pages EQU 45h get_emm_version EQU 46h save_page_map EQU 47h restore_page_map EQU 48h ;; ;______________________________________________________________ ______________________________________________________________; ;_______________STATUS "EQUATES" USED THROUGHOUT THESE EXAMPLES ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; function_passed EQU 00h ; status which indicates ; that the function ; invocation completed ; successfully EMM_not_resident EQU 01h ; status which indicates ; the the EMM is not ; loaded in the system EMM_version_mismatch EQU 02h ; status which indicates ; that the version of EMM ; is not compatible with ; the version required by Example expanded memory programs300275-003 4-19 ; the application program insuff_total_pages EQU 87h ; status which EMM ; returns if an attempt ; was made to allocate ; more pages than exist ; in expanded memory insuff_unalloc_pages EQU 88h ; status which EMM ; returns if an attempt ; was made to allocate ; more pages than are ; currently un- allocated 4-20 300275-003Example expanded memory programs ;; ;______________________________________________________________ ______________________________________________________________; ;______________________VARIABLES USED THROUGHOUT THESE EXAMPLES ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; application_EMM_version DB 30h ; the lowest version ; number of the EMM which ; the application is ; compatible with application_pages_req DW 0 ; number of pages the ; application requires EMM_handle DW 0 ; storage for the handle ; which the EMM assigns ; to the application EMM_status DB 0 ; storage for the status ; which the EMM returns ; to the application logical_page DW 0 ; specifies the logical ; page which the ; application needs to ; access physical_page DB 0 ; specifies where within ; the page frame the ; application needs to ; access the logical page page_frame_segment DW 0 ; specifies the page ; frame base segment ; address at which the ; EMM has located the ; physical pages Example expanded memory programs300275-003 4-21 ;; ;______________________________________________________________ ______________________________________________________________; ;___________EXAMPLE PROCEDURE #1 EMM TRANSIENT INITIALIZATION ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;_______This example PROCEDURE determines whether or not EMM is ______________________________________________________________; ;_present in your your system. Next, it determines whether the ______________________________________________________________; ;____application can run with the version of EMM present in the ______________________________________________________________; ;___system and whether the application will "fit" in the number ______________________________________________________________; ;_____of unallocated pages the EMM has available for use. The, ______________________________________________________________; ;__procedure then locates the page frame segment, and allocates ______________________________________________________________; ;__________________________________________the pages requested. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;___If the application does not "fit" in the available expanded ______________________________________________________________; ;__memory, or if some other EMM error is encountered, then this ______________________________________________________________; ;____________________________________________________procedure: ______________________________________________________________; ;__________________1. Returns the status returned by the EMM in E MM_status._____________________________________________________ ; ;________________________________2. Returns to the application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;____If the application "fits" in the available expanded memory ______________________________________________________________; ;_______________________________________________then it should: ______________________________________________________________; ;__________1. Get the version number and determines whether the ______________________________________________________________; ;________ application is compatible with this version of EMM. ______________________________________________________________; ;________2. Get the page frame segment address from the EMM and ______________________________________________________________; ;_____________________________ save it in page_frame_segment. ______________________________________________________________; ;___________________3. Get a handle from the EMM and save it in ______________________________________________________________; ;________________________________________________ EMM_handle. ______________________________________________________________; ;____________________________4. Allocate the pages specified in ______________________________________________________________; ;_____________________________________ application_pages_req. ______________________________________________________________; 4-22 300275-003Example expanded memory programs ;_________________5. Return an EMM passed status in emm_status. ______________________________________________________________; ;_________________________________6. Return to the application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; EMM_transient_init PROC NEAR ;; ; DETERMINE WHETHER OR NOT EMM IS RESIDENT IN THE SYSTEM ___ _______________________________________________________________ ; ;; _______________________________________________________________ ____________________________________________________________MOV B YTE PTR EMM_status, EMM_not_resident___________________________ _______________________________________________________________ ; assume that the test ___________________________________________________________CALL f irst_test_for_EMM_________________________; for the presence of ____________________________________________________________JNC E MM_transient_init_exit__________________________; EMM will fail ;; ; DETERMINE WHETHER RESIDENT VERSION OF EMM IS_______________ ______________________________________________________________; ; COMPATIBLE WITH APPLICATION________________________________ ______________________________________________________________; ;; ____________________________________________________________MOV A H, get_emm_version________________________; get the EMM version ____________________________________________________________INT 6 7h ____________________________________________________________MOV E MM_status, AH_________________________________; save the status Example expanded memory programs300275-003 4-23 ____________________________________________________________ORA A H, AH_________________________________________; if the function ____________________________________________________________JNZ E MM_transient_init_exit___________________; failed return to the _______________________________________________________________ ; application ____________________________________________________________MOV B YTE PTR emm_status,emm_version mismatch ____________________________________________________________CMP A L, application_emm_version__; assume that the installed version _____________________________________________________________JB e mm_transient_init_exit_______________; is incompatible with the _______________________________________________________________ ; application version ;; ; GET THE PAGE FRAME SEGMENT ADDRESS_________________________ ______________________________________________________________; ;; ____________________________________________________________MOV A H, get_page_frame_address__________________; get the page frame ____________________________________________________________INT E MM_interrupt__________________________________; segment address ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ____________________________________________________________ORA A H, AH_________________________________________; if the function ____________________________________________________________JNZ E MM_transient_init_exit___________________; failed return to the _______________________________________________________________ ; application ____________________________________________________________MOV p age_frame_segment, BX_____________________; save the page frame _______________________________________________________________ ; segment address ;; ; GET THE NUMBER OF TOTAL AND UNALLOCATED PAGES PRESENT______ ______________________________________________________________; ;; ____________________________________________________________MOV A H, get_unalloc_page_count___________________; get the total and ____________________________________________________________INT E MM_interrupt_______________________________; un-allocated pages _______________________________________________________________ ; in the system 4-24 300275-003Example expanded memory programs ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ____________________________________________________________ORA A H, AH_________________________________________; if the function ____________________________________________________________JNZ E MM_transient_init_exit___________________; failed return to the _______________________________________________________________ ; application ;; ; DETERMINE WHETHER APPLICATION CAN RUN WITH THIS NUMBER_____ ______________________________________________________________; ; OF TOTAL AND UNALLOCATED______________________________PAGES ______________________________________________________________; ;; ____________________________________________________________MOV B YTE PTR EMM_status, insuff_total_pages_________________________ _______________________________________________________________ ; check total pages ____________________________________________________________CMP a pplication_pages_req, DX_________________________; not required _____________________________________________________________JA E MM_transient_init_exit ____________________________________________________________MOV B YTE PTR EMM_status, insuff_unalloc_pages ____________________________________________________________CMP a pplication_pages_req, BX______________; check unallocated pages _____________________________________________________________JA E MM_transient_init_exit Example expanded memory programs300275-003 4-25 ;; ; GET AN EMM HANDLE AND SAVE IT______________________________ ______________________________________________________________; ; ALLOCATE THE NUMBER OF PAGES THE APPLICATION REQUIRES______ ______________________________________________________________; ;; ____________________________________________________________MOV A H, allocate_pages____________________________; get a handle and ____________________________________________________________MOV B X, application_pages_req_______________________; allocate pages ____________________________________________________________INT E MM_interrupt___________________________________; to that handle ____________________________________________________________MOV E MM_status, AH_________________________________; save the status EMM_transient_init_exit: ;; ; RETURN TO THE APPLICATION__________________________________ ______________________________________________________________; ;; ____________________________________________________________RET ; return to the _______________________________________________________________ ; application EMM_transient_init ENDP 4-26 300275-003Example expanded memory programs ;; ;______________________________________________________________ ______________________________________________________________; ;____________EXAMPLE PROCEDURE #2 EMM RESIDENT INITIALIZATION ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;_______This example PROCEDURE determines whether or not EMM is ______________________________________________________________; ;_present in your your system. Next, it determines whether the ______________________________________________________________; ;____application can run with the version of EMM present in the ______________________________________________________________; ;___system and whether the application will "fit" in the number ______________________________________________________________; ;_____of unallocated pages the EMM has available for use. The, ______________________________________________________________; ;__procedure then locates the page frame segment, and allocates ______________________________________________________________; ;__________________________________________the pages requested. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;___If the application does not "fit" in the available expanded ______________________________________________________________; ;__memory, or if some other EMM error is encountered, then this ______________________________________________________________; ;____________________________________________________procedure: ______________________________________________________________; ;__________________1. Returns the status returned by the EMM in E MM_status._____________________________________________________ ; ;________________________________2. Returns to the application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;____If the application "fits" in the available expanded memory ______________________________________________________________; ;_______________________________________________then it should: ______________________________________________________________; ;__________1. Get the version number and determines whether the ______________________________________________________________; ;________ application is compatible with this version of EMM. ______________________________________________________________; ;________2. Get the page frame segment address from the EMM and ______________________________________________________________; ;_____________________________ save it in page_frame_segment. ______________________________________________________________; ;___________________3. Get a handle from the EMM and save it in ______________________________________________________________; ;________________________________________________ EMM_handle. ______________________________________________________________; ;____________________________4. Allocate the pages specified in ______________________________________________________________; ;_____________________________________ application_pages_req. ______________________________________________________________; Example expanded memory programs300275-003 4-27 ;______________________5. Return a passed status in EMM_status. ______________________________________________________________; ;_________________________________6. Return to the application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; EMM_resident_init PROC NEAR ;; ; DETERMINE WHETHER EMM IS RESIDENT IN THE SYSTEM ___________ _______________________________________________________________ ; ;; _______________________________________________________________ ____________________________________________________________MOV B YTE PTR EMM_status, EMM_not_resident___________________________ _______________________________________________________________ ; assume that the test ___________________________________________________________CALL s econd_first_test_for_EMM__________________; for the presence of ____________________________________________________________JNC E MM_resident_init_exit___________________________; EMM will fail ;; ; DETERMINE WHETHER RESIDENT VERSION OF EMM IS_______________ ______________________________________________________________; ; COMPATIBLE WITH APPLICATION________________________________ ______________________________________________________________; ;; ____________________________________________________________MOV A H, get_EMM_version________________________; get the EMM version ____________________________________________________________INT 6 7h ____________________________________________________________MOV E MM_status, AH_________________________________; save the status 4-28 300275-003Example expanded memory programs ____________________________________________________________ORA A H, AH_________________________________________; if the function ____________________________________________________________JNZ E MM_resident_init_exit____________________; failed return to the _______________________________________________________________ ; application ____________________________________________________________MOV B YTE PTR EMM_status, EMM_version_mismatch_______________________ _______________________________________________________________ ;assume that the installed ____________________________________________________________CMP A L, application_EMM_version______;version of EMM is incompatible _____________________________________________________________JB E MM_resident_init_exit_______; incompatible with the application _______________________________________________________________ ; version ;; ; GET THE PAGE FRAME SEGMENT ADDRESS_________________________ ______________________________________________________________; ;; ____________________________________________________________MOV A H, get_page_frame_address__________________; get the page frame ____________________________________________________________INT E MM_interrupt__________________________________; segment address ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ____________________________________________________________ORA A H, AH_________________________________________; if the function ____________________________________________________________JNZ E MM_resident_init_exit____________________; failed return to the _______________________________________________________________ ; application ____________________________________________________________MOV p age_frame_segment, BX_____________________; save the page frame _______________________________________________________________ ; segment address ;; ; GET THE NUMBER OF TOTAL AND UNALLOCATED PAGES PRESENT______ ______________________________________________________________; ;; ____________________________________________________________MOV A H, get_unalloc_page_count___________________; get the total and ____________________________________________________________INT E MM_interrupt________________________________; un-allocated page _______________________________________________________________ ; in the system Example expanded memory programs300275-003 4-29 ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ____________________________________________________________ORA A H, AH_________________________________________; if the function ____________________________________________________________JNZ E MM_resident_init_exit____________________; failed return to the _______________________________________________________________ ; application ;; ; DETERMINE WHETHER APPLICATION CAN RUN WITH THIS NUMBER_____ ______________________________________________________________; ; OF TOTAL AND UNALLOCATED______________________________PAGES ______________________________________________________________; ;; ____________________________________________________________MOV B YTE PTR EMM_status, insuff_total_pages_________________________ _______________________________________________________________ ;check total pages ____________________________________________________________CMP a pplication_pages_req, DX _____________________________________________________________JA E MM_resident_init_exit ____________________________________________________________MOV B YTE PTR EMM_status, insuff_unalloc_pages ____________________________________________________________CMP a pplication_pages_req, BX_______________;check unallocated pages _____________________________________________________________JA E MM_resident_init_exit ;; ; GET AN EMM HANDLE AND SAVE IT______________________________ ______________________________________________________________; ; ALLOCATE THE NUMBER OF PAGES THE APPLICATION REQUIRES______ ______________________________________________________________; ;; ____________________________________________________________MOV A H, allocate_pages____________________________; get a handle and ____________________________________________________________MOV B X, application_pages_req_______________________; allocate pages ____________________________________________________________INT E MM_interrupt___________________________________; to that handle ____________________________________________________________MOV E MM_status, AH_________________________________; save the status EMM_resident_init_exit: 4-30 300275-003Example expanded memory programs ;; ; RETURN TO THE APPLICATION__________________________________ ______________________________________________________________; ;; ____________________________________________________________RET ; return to the _______________________________________________________________ ; application EMM_resident_init ENDP Example expanded memory programs300275-003 4-31 ;; ;______________________________________________________________ ______________________________________________________________; ;_____________________________EXAMPLE PROCEDURE #3 EMM ACCESS ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;_____This example PROCEDURE performs the following processing: ______________________________________________________________; ;_________1. Maps the logical page specified by logical_page at ______________________________________________________________; ;___________ the physical page specified by physical_page. It ______________________________________________________________; ;_______________________ uses the handle saved in EMM_handle. ______________________________________________________________; ;_________2. Save the status returned by the EMM in EMM_status. ______________________________________________________________; ;_________________________________3. Return to the application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; EMM_access PROC NEAR _______________________________________________________________ ;; ; MAP THE LOGICAL PAGE SPECIFIED BY logical_page AT THE______ ______________________________________________________________; ; PHYSICAL PAGE SPECIFIED BY physical_page___________________ ______________________________________________________________; ;; ____________________________________________________________MOV A H, map_handle_page_______________________________; map the page ____________________________________________________________MOV D X, EMM_handle ____________________________________________________________MOV B X, logical_page ____________________________________________________________MOV A L, physical_page ____________________________________________________________INT E MM_interrupt ;; ; RETURN THE STATUS_______________________________________ ______________________________________________________________; ;; ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ;; 4-32 300275-003Example expanded memory programs ; RETURN TO THE APPLICATION_______________________________ ______________________________________________________________; ;; ____________________________________________________________RET ; return to the _______________________________________________________________ ; application EMM_access ENDP Example expanded memory programs300275-003 4-33 ;; ;______________________________________________________________ ______________________________________________________________; ;________________________EXAMPLE PROCEDURE #4 EMM TERMINATION ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;_____This example PROCEDURE performs the following processing: ______________________________________________________________; ;____________1. "Close" the EMM handle assigned to your program ______________________________________________________________; ;____________ and deallocates the pages EMM allocated to your ______________________________________________________________; ;___________ program. It uses the handle saved in EMM_handle. ______________________________________________________________; ;_________2. Save the status returned by the EMM in EMM_status. ______________________________________________________________; ;_________________________________3. Return to the application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; EMM_terminate PROC NEAR ;; ; CLOSE THE EMM HANDLE_______________________________________ ______________________________________________________________; ; DEALLOCATE ALL PAGES ALLOCATED TO IT_______________________ ______________________________________________________________; ;; ____________________________________________________________MOV A H, deallocate_pages______________________; close the handle and ____________________________________________________________MOV D X, EMM_handle____________________________; deallocate all pages ____________________________________________________________INT E MM_interrupt__________________________________; allocated to it ;; ; RETURN THE STATUS__________________________________________ ______________________________________________________________; ;; ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ;; ; RETURN TO THE APPLICATION__________________________________ ______________________________________________________________; ;; 4-34 300275-003Example expanded memory programs ____________________________________________________________RET ; return to the _______________________________________________________________ ; application EMM_terminate ENDP Example expanded memory programs300275-003 4-35 ;; ;______________________________________________________________ ______________________________________________________________; ;_____________________EXAMPLE PROCEDURE #5 EMM SAVE MAP STATE ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;_____This example PROCEDURE performs the following processing: ______________________________________________________________; ;_____________________1. Saves the page mapping register state. ______________________________________________________________; ;_________________________2. Save the EMM status in EMM_status. ______________________________________________________________; ;________________________3. Return to the resident application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; EMM_save_map_state PROC NEAR ____________________________________________________________MOV A H, save_page_map_________________________; save the contents of ____________________________________________________________MOV D X, EMM_handle________________________________; the page mapping ____________________________________________________________INT E MM_interrupt________________________________________; registers ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ____________________________________________________________RET ; return to the _______________________________________________________________ ; application EMM_save_map_state ENDP 4-36 300275-003Example expanded memory programs ;; ;______________________________________________________________ ______________________________________________________________; ;__________________EXAMPLE PROCEDURE #6 EMM RESTORE MAP STATE ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;_____This example PROCEDURE performs the following processing: ______________________________________________________________; ;________________1. Restore the page mapping register state, if p ossible._______________________________________________________ ; ;_________________________2. Save the EMM status in EMM_status. ______________________________________________________________; ;________________________3. Return to the resident application. ______________________________________________________________; ;______________________________________________________________ ______________________________________________________________; ;; EMM_restore_map_state PROC NEAR ____________________________________________________________MOV A H, restore_page_map______________________; restore the contents ____________________________________________________________MOV D X, EMM_handle_____________________________; of the page mapping ____________________________________________________________INT E MM_interrupt________________________________________; registers ____________________________________________________________MOV E MM_status, AH_________________________________; save the status ____________________________________________________________RET ; return to the _______________________________________________________________ ; application EMM_restore_map_state ENDP Example expanded memory programs300275-003 4-37 GLOSSARY This glossary defines some of the terms that are used frequently in this specification. The terms are listed in alphabetical order. Most of these terms are defined for readers who understand technical terminology and are familiar with IBM PCs, XTs, and ATs or compatibles. 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 Conventional memory refers to the memory DOS recognizes. In PCs, XTs, and ATs, this is memory between 0 and 640K bytes. Because application programs let DOS manage their memory, they can use only conventional memory. EMM See Expanded Memory Manager. EMM functions The EMM functions are a set of standard interfaces to expanded memory. They provide application programs with the operators required to use expanded memory. EMM handle An EMM handle is a value that the EMM assigns to a file or a device. Previous versions of this specification referred to an EMM handle as a Process ID. EMM Status code A code that an EMM function returns which indicates something about the result of running the function. Some status codes may indicate whether the function worked correctly and others may tell you something about the expanded memory hardware or software. Glossary-38 300275-003 Expanded memory Expanded memory is a special kind of memory that goes beyond DOS's 640K-byte limit. Application programs that adhere to the Lotus/Intel Expanded Memory Specification can use the Expanded Memory Manager (EMM) to manage expanded memory just as other programs use DOS to manage conventional memory. Expanded Memory Manager The Expanded Memory Manager (EMM) is a standard device driver that manages expanded memory in much the same way DOS manages conventional memory. Extended memory Extended memory is the 15M-byte address space outside the memory DOS can access. This address space is of little use to those application programs that use DOS. DOS does not recognized memory above 640K bytes; the XENIX operating system uses extended memory. Logical page The EMM allocates expanded memory in 16K-byte units called logical pages. Mapping Mapping is the process of making a logical page of memory available for the processor to use. Mapping is done within one of the four physical pages defined by this specification. Page frame A page frame is the collection of four 16k-byte contiguous, physical pages from which an application program accesses expanded memory. Page frame base address A page frame base address is the location (in segment format) of the first byte of the page frame. 300275-003 Glossary-39 Physical page A physical page is the range of memory addresses occupied by a single 16k-byte page. The 16k-byte page is one of the four pages defined as a page frame. Process ID See EMM handle. Resident application program A resident application program is loaded 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 examples of resident application programs are RAM disk drivers, print spoolers, and "pop-up" desktop programs. Transient application program A transient application program is 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. Glossary-40 300275-003