home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / PCGPEV10.ZIP / LIMEMS41.DOC < prev    next >
Text File  |  1994-05-10  |  449KB  |  13,224 lines

  1.  
  2.  
  3.           The associated file (LIMEMS41.DOC) is a complete transcription of
  4.           the Lotus/Intel/Microsoft (LIM) Expanded Memory Specification
  5.           (EMS) Version 4.0, updated October 1987.  It can be printed by
  6.           "COPY LIMEMS41.DOC PRN:"
  7.  
  8.           I created this transcription because of the difficulty I origin-
  9.           ally had finding a copy of the document, because of the number of
  10.           people who have subsequently expressed an interest in having
  11.           access to a machine-readable copy of the specification, and,
  12.           finally, because of the annoying number of typographical errors
  13.           contained in the original and updated documents.
  14.  
  15.           This transcription is not an exact letter-for-letter duplicate of
  16.           the original document.  Some minor changes were necessitated by
  17.           the simple fact that the document's proportionally-spaced, multi-
  18.           fonted typography and line drawings did not lend themselves to
  19.           the generic fixed-spacing, single-fonted, non-graphical ASCII
  20.           transcription I wanted to produce for general dissemination.
  21.  
  22.           Other minor changes were made to correct obvious typographical
  23.           and grammatical errors, or to simply improve the visual aes-
  24.           thetics of the presented material.
  25.  
  26.           In one area, however, I simply trashed their original material
  27.           and substituted my own.  This area is the Index.  The original
  28.           document contains an Index that is little more than a reformatt-
  29.           ing of the Table of Contents.  As anyone who has ever indexed a
  30.           large document knows, it is very difficult to produce an Index
  31.           that is both complete AND easy to use.  I didn't have time to
  32.           produce one that was both, so I aimed for the former.  In fact,
  33.           the Index I have provided is more of an alphabetical listing of
  34.           key words and phrases and the pages where they are referenced,
  35.           than it is a more typical Index with its multi-level headings and
  36.           subheadings.
  37.  
  38.           You should be able obtain a printed, 3-hole-punched, 5.5 x 8.5"
  39.           copy of the original (and uncorrected) document directly from
  40.           Intel by calling their "Information Department" at 1-800-538-3373
  41.           and asking for a copy of the "LIM EMS 4.0 Developer's Kit."  It
  42.           is available free of charge and mine arrived in about two weeks. 
  43.           (European availability, however, is reported to be from poor to
  44.           non-existent.)
  45.  
  46.           It is my intent to provide this transcription as a public
  47.           service.  I am, therefore, releasing it into the public domain. 
  48.           The original document has also been released into the public
  49.           domain by Lotus, Intel, and Microsoft, though it remains their
  50.           copyrighted property (I'm not quite sure how they manage to do
  51.           that).
  52.  
  53.           I have tried as best I can to provide an accurate and corrected
  54.           transcription of the original document.  It is inevitable,
  55.           however, that some typographical errors have slipped through in
  56.           spite of my hours of bleary-eyed proof reading.  For these errors
  57.           I apologize and plead simple human frailty.
  58.  
  59.                THIS TRANSCRIPTION IS PROVIDED WITHOUT ANY GUARANTEES
  60.                OR WARRANTIES OF ANY KIND, AND I ASSUME ABSOLUTELY NO
  61.                LIABILITY FOR ITS ACCURACY, CONTENT, OR SUBSEQUENT USE.
  62.  
  63.           Dick Flanagan, W6OLD, Ben Lomond, California        November 1987
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.                            LOTUS(R)/INTEL(R)/MICROSOFT(R)
  76.  
  77.                           EXPANDED MEMORY SPECIFICATION [1]
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.                                      Version 4.0
  91.                                      300275-005
  92.                                     October, 1987
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.           Copyright (C) 1987
  106.  
  107.           Lotus Development Corporation
  108.           55 Cambridge Parkway
  109.           Cambridge, MA  02142
  110.  
  111.           Intel Corporation
  112.           5200 NE Elam Young Parkway
  113.           Hillsboro, OR  97124
  114.  
  115.           Microsoft Corporation
  116.           16011 NE 35th Way
  117.           Box 97017
  118.           Redmond, WA  98073
  119.  
  120.  
  121.                [1] Transcribed into machine-readable form by Dick Flanagan,
  122.           Ben Lomond, California.  This transcription is released into the
  123.           public domain without warranty or assumption of liability.
  124.  
  125.  
  126.  
  127.  
  128.  
  129.                This specification was jointly developed by Lotus Develop-
  130.                ment Corporation, Intel Corporation, and Microsoft Corpora-
  131.                tion.  Although it has been released into the public domain
  132.                and is not confidential or proprietary, the specification is
  133.                still the copyright and property of Lotus Development
  134.                Corporation, Intel Corporation, and Microsoft Corporation.
  135.  
  136.  
  137.           DISCLAIMER OF WARRANTY
  138.  
  139.                LOTUS DEVELOPMENT CORPORATION, INTEL CORPORATION, AND MICRO-
  140.                SOFT CORPORATION EXCLUDE ANY AND ALL IMPLIED WARRANTIES,
  141.                INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  142.                PARTICULAR PURPOSE.  NEITHER LOTUS NOR INTEL NOR MICROSOFT
  143.                MAKE ANY WARRANTY OF REPRESENTATION, EITHER EXPRESS OR
  144.                IMPLIED, WITH RESPECT TO THIS SPECIFICATION, ITS QUALITY,
  145.                PERFORMANCE, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR
  146.                PURPOSE.  NEITHER LOTUS NOR INTEL NOR MICROSOFT SHALL HAVE
  147.                ANY LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  148.                DAMAGES ARISING OUT OF OR RESULTING FROM THE USE OR MODIF-
  149.                ICATION OF THIS SPECIFICATION.
  150.  
  151.  
  152.  
  153.           This specification uses the following trademarks:
  154.  
  155.           Intel is a trademark of Intel Corporation
  156.           Lotus is a trademark of Lotus Development Corporation
  157.           Microsoft is a trademark of Microsoft Corporation
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.                                                                          ii
  183.  
  184.  
  185.  
  186.  
  187.  
  188.           CONTENTS
  189.  
  190.  
  191.  
  192.           Chapter 1
  193.           INTRODUCTION
  194.             What is Expanded Memory? . . . . . . . . . . . . . . . . .    1
  195.             How Expanded Memory Works  . . . . . . . . . . . . . . . .    1
  196.  
  197.           Chapter 2
  198.           WRITING PROGRAMS THAT USE EXPANDED MEMORY
  199.             What Every Program Must Do . . . . . . . . . . . . . . . .    4
  200.             Advanced Programming . . . . . . . . . . . . . . . . . . .    5
  201.               Saving The State of Mapping Hardware . . . . . . . . . .    6
  202.               Retrieving Handle and Page Counts  . . . . . . . . . . .    6
  203.               Mapping and Unmapping Multiple Pages . . . . . . . . . .    6
  204.               Reallocating Pages . . . . . . . . . . . . . . . . . . .    6
  205.               Using Handles and Assigning Names to Handles . . . . . .    6
  206.               Using Handle Attributes  . . . . . . . . . . . . . . . .    7
  207.               Altering Page Maps and Jumping/Calling . . . . . . . . .    7
  208.               Moving or Exchanging Memory Regions  . . . . . . . . . .    7
  209.               Getting the Amount of Mappable Memory  . . . . . . . . .    8
  210.               Operating System Functions . . . . . . . . . . . . . . .    8
  211.             Programming Guidelines . . . . . . . . . . . . . . . . . .   12
  212.             Examples . . . . . . . . . . . . . . . . . . . . . . . . .   14
  213.               Example 1  . . . . . . . . . . . . . . . . . . . . . . .   14
  214.               Example 2  . . . . . . . . . . . . . . . . . . . . . . .   19
  215.               Example 3  . . . . . . . . . . . . . . . . . . . . . . .   30
  216.               Example 4  . . . . . . . . . . . . . . . . . . . . . . .   32
  217.  
  218.           Chapter 3
  219.           EMM FUNCTIONS
  220.             Function 1. Get Status . . . . . . . . . . . . . . . . . .   37
  221.             Function 2. Get Page Frame Address . . . . . . . . . . . .   38
  222.             Function 3. Get Unallocated Page Count . . . . . . . . . .   40
  223.             Function 4. Allocate Pages . . . . . . . . . . . . . . . .   42
  224.             Function 5. Map/Unmap Handle Pages . . . . . . . . . . . .   46
  225.             Function 6. Deallocate Pages . . . . . . . . . . . . . . .   49
  226.             Function 7. Get Version  . . . . . . . . . . . . . . . . .   51
  227.             Function 8. Save Page Map  . . . . . . . . . . . . . . . .   53
  228.             Function 9. Restore Page Map . . . . . . . . . . . . . . .   55
  229.             Function 10. Reserved  . . . . . . . . . . . . . . . . . .   57
  230.             Function 11. Reserved  . . . . . . . . . . . . . . . . . .   58
  231.             Function 12. Get Handle Count  . . . . . . . . . . . . . .   59
  232.             Function 13. Get Handle Pages  . . . . . . . . . . . . . .   61
  233.             Function 14. Get All Handle Pages  . . . . . . . . . . . .   63
  234.             Function 15. Get/Set Page Map  . . . . . . . . . . . . . .   65
  235.               Get Page Map subfunction . . . . . . . . . . . . . . . .   65
  236.               Set Page Map subfunction . . . . . . . . . . . . . . . .   67
  237.               Get & Set Page Map subfunction . . . . . . . . . . . . .   69
  238.               Get Size of Page Map Save Array subfunction  . . . . . .   71
  239.  
  240.  
  241.                                                                         iii
  242.  
  243.  
  244.  
  245.  
  246.  
  247.             Function 16. Get/Set Partial Page Map  . . . . . . . . . .   73
  248.               Get Partial Page Map subfunction . . . . . . . . . . . .   73
  249.               Set Partial Page Map subfunction . . . . . . . . . . . .   76
  250.               Get Size of Partial Page Map Save Array subfunction  . .   78
  251.             Function 17. Map/Unmap Multiple Handle Pages . . . . . . .   80
  252.               Mapping Multiple Pages . . . . . . . . . . . . . . . . .   80
  253.               Unmapping Multiple Pages . . . . . . . . . . . . . . . .   80
  254.               Mapping and Unmapping Multiple Pages Simultaneously  . .   80
  255.               Alternate Mapping and Unmapping Methods  . . . . . . . .   81
  256.               Logical Page/Physical Page Method  . .OF THE EXPANDED MEMORY MANAGER
  257.             Which method should your program use?  . . . . . . . . . .  199
  258.             The "open handle" technique  . . . . . . . . . . . . . . .  199
  259.             The "get interrupt vector" technique . . . . . . . . . . .  204
  260.  
  261.           Appendix C
  262.           EXPANDED MEMORY MANAGER IMPLEMENTATION GUIDELINES
  263.             The amount of expanded memory supported  . . . . . . . . .  206
  264.             The number of handles supported  . . . . . . . . . . . . .  206
  265.             Handle Numbering . . . . . . . . . . . . . . . . . . . . .  206
  266.             New handle type:  Handles versus Raw Handles . . . . . . .  206
  267.             The system Raw Handle (Raw Handle = 0000h) . . . . . . . .  207
  268.             Terminate and Stay Resident (TSR) Program Cooperation  . .  208
  269.             Accelerator Cards  . . . . . . . . . . . . . . . . . . . .  208
  270.  
  271.           Appendix D
  272.           OPERATING SYSTEM/ENVIRONMENT USE OF FUNCTION 28
  273.             Examples . . . . . . . . . . . . . . . . . . . . . . . . .  209
  274.               Example 1  . . . . . . . . . . . . . . . . . . . . . . .  209
  275.               Example 2  . . . . . . . . . . . . . . . . . . . . . . .  210
  276.               Example 3  . . . . . . . . . . . . . . . . . . . . . . .  211
  277.  
  278.           GLOSSARY
  279.  
  280.           INDEX
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.                                                                           v
  297.  
  298.  
  299.  
  300.  
  301.  
  302.           Chapter 1
  303.           INTRODUCTION
  304.  
  305.  
  306.                Because even the maximum amount (640K bytes) of conventional
  307.                memory isn't always enough for large application programs,
  308.                Lotus Development Corporation, Intel Corporation, and Micro-
  309.                soft Corporation created the Lotus/Intel/Microsoft (LIM)
  310.                Expanded Memory Specification.
  311.  
  312.                The LIM Expanded Memory Specification defines the software
  313.                interface between the Expanded Memory Manager (EMM) -- a
  314.                device driver that controls and manages expanded memory --
  315.                and application programs that use expanded memory.
  316.  
  317.  
  318.           What is Expanded Memory?
  319.  
  320.                Expanded memory is memory beyond DOS's 640K-byte limit.  The
  321.                LIM specification supports up to 32M bytes of expanded
  322.                memory.  Because the 8086, 8088, and 80286 (in real mode)
  323.                microprocessors can physically address only 1M bytes of
  324.                memory, they access expanded memory through a window in
  325.                their physical address range.  The next section explains how
  326.                this is done.
  327.  
  328.  
  329.           How Expanded Memory Works
  330.  
  331.                Expanded memory is divided into segments called logical
  332.                pages.  These pages are typically 16K bytes of memory.  Your
  333.                computer accesses logical pages through a physical block of
  334.                memory called a page frame.  The page frame contains
  335.                multiple physical pages, pages that the microprocessor can
  336.                address directly.  Physical pages are also typically 16K
  337.                bytes of memory.
  338.  
  339.                This page frame serves as a window into expanded memory. 
  340.                Just as your computer screen is a window into a large
  341.                spreadsheet, so the page frame is a window into expanded
  342.                memory.
  343.  
  344.                A logical page of expanded memory can be mapped into (made
  345.                to appear in) any one of the physical pages in the page
  346.                frame.  Thus, a read or write to the physical page actually
  347.                becomes a read or write to the associated logical page.  One
  348.                logical page can be mapped into the page frame for each
  349.                physical page.
  350.  
  351.                Figure 1-1 shows the relationship among the page frame,
  352.                physical pages, and logical pages.
  353.  
  354.  
  355.           Introduction                                                    1
  356.  
  357.  
  358.  
  359.  
  360.  
  361.                                                        32M +--------------+
  362.                                                           /|              |
  363.                                                            |              |
  364.                                                      /     |              |
  365.                                                            |              |
  366.                                                 /          |              |
  367.                                                            |              |
  368.                                            /               |              |
  369.                                                            |   Expanded   |
  370.                                       /                    |    Memory    |
  371.           1024K +--------------+                           |              |
  372.                 | / / / / / /  | /                         |              |
  373.            960K +--------------+                           |              |
  374.                 |  Page Frame  |                           |              |
  375.                 |              |                           |              |
  376.                 | 12 16K-Byte  |                           |              |
  377.                 |   Physical   |                           |              |
  378.                 |    Pages     |                           |              |
  379.            768K +--------------+                           | Divided into |
  380.                 | / / / / / /  | \                         |   logical    |
  381.            640K +--------------+                           |    pages     |
  382.                 |              |   \                       |              |
  383.                 |              |                           |              |
  384.                 |              |     \                     |              |
  385.                 |              |                           |              |
  386.                 | 24 16K-Byte  |       \                   |              |
  387.                 |   Physical   |                           |              |
  388.                 |    Pages*    |         \                 |              |
  389.                 |              |                           |              |
  390.                 |              |           \               |              |
  391.                 |              |                           |              |
  392.                 |              |             \             |              |
  393.            256K +--------------+                           |              |
  394.                 |              |               \           |              |
  395.                 | / / / / / /  |                           |              |
  396.                 |              |                 \         |              |
  397.                 | / / / / / /  |                           |              |
  398.                 |              |                   \       |              |
  399.                 | / / / / / /  |                           |              |
  400.                 |              |                     \     |              |
  401.               0 +--------------+                           |              |
  402.                                                        \   |              |
  403.                                                            |              |
  404.           *Intended for operating                        \ |              |
  405.            system/environment use only                   0 +--------------+
  406.  
  407.  
  408.  
  409.           Figure 1-1.  Expanded Memory
  410.  
  411.  
  412.  
  413.  
  414.           Introduction                                                    2
  415.  
  416.  
  417.  
  418.  
  419.  
  420.                The page frame is located above 640K bytes.  Normally, only
  421.                video adapters, network cards, and similar devices exist
  422.                between 640K and 1024K.
  423.  
  424.                This specification also defines methods for operating
  425.                systems and environments to access expanded memory through
  426.                physical pages below 640K bytes.  These methods are intended
  427.                for operating system/environment developers only.
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.           Introduction                                                    3
  474.  
  475.  
  476.  
  477.  
  478.  
  479.           Chapter 2
  480.           WRITING PROGRAMS THAT USE EXPANDED MEMORY
  481.  
  482.  
  483.                This chapter describes what every program must do to use
  484.                expanded memory and describes more advanced techniques of
  485.                using expanded memory.
  486.  
  487.                This chapter also lists programming guidelines you should
  488.                follow when writing programs that use expanded memory and
  489.                provides the listings of some example programs.
  490.  
  491.  
  492.           What Every Program Must Do
  493.  
  494.                This section describes the steps every program must take to
  495.                use expanded memory.
  496.  
  497.                In order to use expanded memory, applications must perform
  498.                these steps in the following order:
  499.  
  500.                1.  Determine if EMM is installed.
  501.  
  502.                2.  Determine if enough expanded memory pages exist for your
  503.                    application.  (Function 3)
  504.  
  505.                3.  Allocate expanded memory pages.  (Function 4, 18, or 27)
  506.  
  507.                4.  Get the page frame base address.  (Function 2)
  508.  
  509.                5.  Map in expanded memory pages.  (Function 5 or 17)
  510.  
  511.                6.  Read/write/execute data in expanded memory, just as if
  512.                    it were conventional memory.
  513.  
  514.                7.  Return expanded memory pages to expand memory pool
  515.                    before exiting.  (Function 6 or 18)
  516.  
  517.                Table 2-1 overviews the functions while Chapter 3 describes
  518.                each of these functions in detail.  Example programs at the
  519.                end of this chapter illustrate using expanded memory.
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.           Writing Programs That Use Expanded Memory                       4
  533.  
  534.  
  535.  
  536.  
  537.  
  538.           Table 2-1.  The Basic Functions
  539.           ----------------------------------------------------------------
  540.  
  541.           Function                        Description
  542.  
  543.           ----------------------------------------------------------------
  544.  
  545.              1         The Get Status Function returns a status code
  546.                        indicating whether the memory manager hardware is
  547.                        working correctly.
  548.  
  549.              2         The Get Page Frame Address function returns the
  550.                        address where the 64K-byte page frame is located.
  551.  
  552.              3         The Get Unallocated Page Count function returns the
  553.                        number of unallocated pages (pages available to your
  554.                        program) and the total number of pages in expanded
  555.                        memory.
  556.  
  557.              4         The Allocate Pages function allocates the number of
  558.                        pages requested and assigns a unique EMM handle to
  559.                        these pages.
  560.  
  561.              5         The Map/Unmap Handle Page function maps a logical
  562.                        page to a specific physical page anywhere in the
  563.                        mappable regions of system memory.
  564.  
  565.              6         The Deallocate Pages deallocates the logical pages
  566.                        currently allocated to an EMM handle.
  567.  
  568.              7         The Get Version function returns the version number
  569.                        of the memory manager software.
  570.  
  571.           ----------------------------------------------------------------
  572.  
  573.  
  574.  
  575.           Advanced Programming
  576.  
  577.                In addition to the basic functions, the Lotus/Intel/Micro-
  578.                soft Expanded Memory Specification provides several advanced
  579.                functions which enhance the capabilities of software that
  580.                uses expanded memory.
  581.  
  582.                The following sections describe the advanced programming
  583.                capabilities and list the advanced EMM functions.
  584.  
  585.  
  586.           Note............................................................
  587.                Before using the advanced functions, programs should first
  588.                call Function 7 (Get Version) to determine whether the
  589.                installed version of EMM supports these functions.
  590.  
  591.           Writing Programs That Use Expanded Memory                       5
  592.  
  593.  
  594.  
  595.  
  596.  
  597.           Saving The State of Mapping Hardware
  598.  
  599.                Some software (such as interrupt service routines, device
  600.                drivers, and resident software) must save the current state
  601.                of the mapping hardware, switch mapping contexts, manipulate
  602.                sections of expanded memory, and restore the original
  603.                context of the memory mapping hardware.  Use Functions 8 and
  604.                9 or 15 and 16 to save the state of the hardware.
  605.  
  606.  
  607.           Retrieving Handle and Page Counts
  608.  
  609.                Some utility programs need to keep track of how expanded
  610.                memory is being used; use Functions 12 through 14 to do
  611.                this.
  612.  
  613.  
  614.           Mapping and Unmapping Multiple Pages
  615.  
  616.                Mapping multiple pages reduces the overhead an application
  617.                must perform during mapping.  Function 17 lets a program map
  618.                (or unmap) multiple pages at one time.
  619.  
  620.                In addition, you can map pages using segment addresses
  621.                instead of physical pages.  For example, if the page frame
  622.                base address is set to D000, you can map to either physical
  623.                page 0 or segment D000.  Function 25 (Get Mappable Physical
  624.                Address Array) returns a cross reference between all
  625.                expanded memory physical pages and their corresponding
  626.                segment values.
  627.  
  628.  
  629.           Reallocating Pages
  630.  
  631.                Reallocating pages (Function 18) lets applications dynami-
  632.                cally allocate expanded memory pages without acquiring
  633.                another handle or obtain a handle without allocating pages. 
  634.                Reallocating pages is an efficient means for applications to
  635.                obtain and release expanded memory pages.
  636.  
  637.  
  638.           Using Handles and Assigning Names to Handles
  639.  
  640.                This specification lets you associate a name with a handle,
  641.                so a family of applications can share information in
  642.                expanded memory.  For example, a software package consisting
  643.                of a word processor, spreadsheet, and print spooler can
  644.                share the same data among the different applications.  The
  645.                print spooler could use a handle name to reference data that
  646.                either the spreadsheet or word processor put in expanded
  647.                memory and could check for data in a particular handle
  648.                name's expanded memory pages.
  649.  
  650.           Writing Programs That Use Expanded Memory                       6
  651.  
  652.  
  653.  
  654.  
  655.  
  656.                Use Function 20 (Set Handle Name subfunction) to assign a
  657.                handle name to an EMM handle or Function 21 (Search for
  658.                Named Handle subfunction) to obtain the EMM handle as-
  659.                sociated with the handle name.  In addition, you can use
  660.                Function 14 (Get Handle Pages) to determine the number of
  661.                expanded memory pages allocated to an EMM handle.
  662.  
  663.  
  664.           Using Handle Attributes
  665.  
  666.                In addition to naming a handle, you can use Function 19 to
  667.                associate an attribute (volatile or non-volatile) with a
  668.                handle name.  A non-volatile attribute enables expanded
  669.                memory pages to preserve their data through a warmboot. 
  670.                With a volatile attribute, the data is not preserved.  The
  671.                default attribute for handles is volatile.
  672.  
  673.                Because using this function depends on the capabilities of
  674.                the expanded memory hardware installed in the system, you
  675.                should use the Get Attribute Capability subfunction before
  676.                attempting to assign an attribute to a handle's pages.
  677.  
  678.  
  679.           Altering Page Maps and Jumping/Calling
  680.  
  681.                You can use Functions 22 (Alter Page Map & Jump) and 23
  682.                (Alter Page Map & Call) to map a new set of values into the
  683.                map registers and transfer program control to a specified
  684.                address within expanded memory.  These functions can be used
  685.                to load and execute code in expanded memory.  An application
  686.                using this feature can significantly reduce the amount of
  687.                conventional memory it requires.  Programs can load needed
  688.                modules into expanded memory at run time and use Functions
  689.                22 and 23 to transfer control to these modules.
  690.  
  691.                Using expanded memory to store code can improve program
  692.                execution in many ways.  For example, sometimes programs
  693.                need to be divided into small overlays because of conven-
  694.                tional memory size limitations.  Overlays targeted for
  695.                expanded memory can be very large because LIM EMS 4.0
  696.                supports up to 32M bytes of expanded memory.  This method of
  697.                loading overlays improves overall system performance by
  698.                conserving conventional memory and eliminating conventional
  699.                memory allocation errors.
  700.  
  701.  
  702.           Moving or Exchanging Memory Regions
  703.  
  704.                Using Function 24 (Move/Exchange Memory Region), you can
  705.                easily move and exchange data between conventional and
  706.                expanded memory.  Function 24 can manipulate up to one
  707.                megabyte of data with one function call.  Although applica-
  708.  
  709.           Writing Programs That Use Expanded Memory                       7
  710.  
  711.  
  712.  
  713.  
  714.  
  715.                tions can perform this operation without this function,
  716.                having the expanded memory manager do it reduces the amount
  717.                of overhead for the application.
  718.  
  719.                In addition, this function checks for overlapping regions
  720.                and performs all the necessary mapping, preserving the
  721.                mapping context from before the exchange/move call.
  722.  
  723.  
  724.           Getting the Amount of Mappable Memory
  725.  
  726.                Function 25 enables applications to determine the total
  727.                amount of mappable memory the hardware/system currently
  728.                supports.  Not all expanded memory boards supply the same
  729.                number of physical pages (map registers).
  730.  
  731.                The Get Mappable Physical Address Array Entries subfunction
  732.                returns the total number of physical pages the expanded
  733.                memory hardware/system is capable of supporting.  The Get
  734.                Mappable Physical Array subfunction returns a cross refer-
  735.                ence between physical page numbers and the actual segment
  736.                address for each of the physical pages.
  737.  
  738.  
  739.           Operating System Functions
  740.  
  741.                In addition to the functions for application programs, this
  742.                specification defines functions for operating systems/en-
  743.                vironments.  These functions can be disabled at any time by
  744.                the operating system/environment, so programs should not
  745.                depend on their presence.  Applications that avoid this
  746.                warning and use these functions run a great risk of being
  747.                incompatible with other programs, including the operating
  748.                system.
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.           Writing Programs That Use Expanded Memory                       8
  769.  
  770.  
  771.  
  772.  
  773.  
  774.           Table 2-2.  The Advanced Functions
  775.           ----------------------------------------------------------------
  776.  
  777.           Function                        Description
  778.  
  779.           ----------------------------------------------------------------
  780.  
  781.              8         The Save Page Map saves the contents of the page
  782.                        mapping registers from all expanded memory boards in
  783.                        an internal save area.
  784.  
  785.              9         The Restore Page Map function restores (from an
  786.                        internal save area) the page mapping register
  787.                        contents on the expanded memory boards for a
  788.                        particular EMM handle.
  789.  
  790.              10        Reserved.
  791.  
  792.              11        Reserved.
  793.  
  794.              12        The Get Handle Count function returns the number of
  795.                        open EMM handles in the system.
  796.  
  797.              13        The Get Handle Pages function returns the number of
  798.                        pages allocated to a specific EMM handle.
  799.  
  800.              14        The Get All Handle Pages function returns an array
  801.                        of the active EMM handles and the number of pages
  802.                        allocated to each one.
  803.  
  804.              15        The Get/Set Page Map subfunction saves or restores
  805.                        the mapping context for all mappable memory regions
  806.                        (conventional and expanded) in a destination array
  807.                        which the application supplies.
  808.  
  809.              16        The Get/Set Partial Page Map subfunction provides a
  810.                        mechanism for saving a partial mapping context for
  811.                        specific mappable memory regions in a system.
  812.  
  813.              17        The Map/Unmap Multiple Handle Pages function can, in
  814.                        a single invocation, map (or unmap) logical pages
  815.                        into as many physical pages as the system supports.
  816.  
  817.              18        The Reallocate Pages function can increase or
  818.                        decrease the amount of expanded memory allocated to
  819.                        a handle.
  820.  
  821.              19        The Get/Set Handle Attribute function allows an
  822.                        application program to determine and set the
  823.                        attribute associated with a handle.
  824.  
  825.  
  826.  
  827.           Writing Programs That Use Expanded Memory                       9
  828.  
  829.  
  830.  
  831.  
  832.  
  833.           Table 2-2.  The Advanced Functions (continued)
  834.           ----------------------------------------------------------------
  835.  
  836.           Function                        Description
  837.  
  838.           ----------------------------------------------------------------
  839.  
  840.              20        The Get/Set Handle Name function gets the eight
  841.                        character name currently assigned to a handle and
  842.                        can assign an eight character name to a handle.
  843.  
  844.              21        The Get Handle Directory function returns informa-
  845.                        tion about active handles and the names assigned to
  846.                        each.
  847.  
  848.              22        The Alter Page Map & Jump function alters the memory
  849.                        mapping context and transfers control to the
  850.                        specified address.
  851.  
  852.              23        The Alter Page Map & Call function alters the speci-
  853.                        fied mapping context and transfers control to the
  854.                        specified address.  A return can then restore the
  855.                        context and return control to the caller.
  856.  
  857.              24        The Move/Exchange Memory Region function copies or
  858.                        exchanges a region of memory from conventional to
  859.                        conventional memory, conventional to expanded
  860.                        memory, expanded to conventional memory, or expanded
  861.                        to expanded memory.
  862.  
  863.              25        The Get Mappable Physical Address Array function
  864.                        returns an array containing the segment address and
  865.                        physical page number for each mappable physical page
  866.                        in a system.
  867.  
  868.              26        The Get Expanded Memory Hardware Information
  869.                        function returns an array containing the hardware
  870.                        capabilities of the expanded memory system.
  871.  
  872.              27        The Allocate Standard/Raw Pages function allocates
  873.                        the number of standard or non-standard size pages
  874.                        that the operating system requests and assigns a
  875.                        unique EMM handle to these pages.
  876.  
  877.              28        The Alternate Map Register Set function enables an
  878.                        application to simulate alternate sets of hardware
  879.                        mapping registers.
  880.  
  881.              29        The Prepare Expanded Memory Hardware for Warm Boot
  882.                        function prepares the expanded memory hardware for
  883.                        an "impending" warm boot.
  884.  
  885.  
  886.           Writing Programs That Use Expanded Memory                      10
  887.  
  888.  
  889.  
  890.  
  891.  
  892.           Table 2-2.  The Advanced Functions (continued)
  893.           ----------------------------------------------------------------
  894.  
  895.           Function                        Description
  896.  
  897.           ----------------------------------------------------------------
  898.  
  899.              30        The Enable/Disable OS/E function enables operating
  900.                        systems developers to enable and disable functions
  901.                        designed for operating system use.
  902.  
  903.           ----------------------------------------------------------------
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.           Writing Programs That Use Expanded Memory                      11
  946.  
  947.  
  948.  
  949.  
  950.  
  951.           Programming Guidelines
  952.  
  953.                The following section contains guidelines for programmers
  954.                writing applications that use EMM.
  955.  
  956.                o   Do not put a program's stack in expanded memory.
  957.  
  958.                o   Do not replace interrupt 67h.  This is the interrupt
  959.                    vector the EMM uses.  Replacing interrupt 67h could
  960.                    result in disabling the Expanded Memory Manager.
  961.  
  962.                o   Do not map into conventional memory address space your
  963.                    application doesn't own.  Applications that use the EMM
  964.                    to swap into conventional memory space, must first
  965.                    allocate this space from the operating system.  If the
  966.                    operating system is not aware that a region of memory it
  967.                    manages is in use, it will think it is available.  This
  968.                    could have disastrous results.  EMM should not be used
  969.                    to "allocate" conventional memory.  DOS is the proper
  970.                    manager of conventional memory space.  EMM should only
  971.                    be used to swap data in conventional memory space
  972.                    previously allocated from DOS.
  973.  
  974.                o   Applications that plan on using data aliasing in
  975.                    expanded memory must check for the presence of expanded
  976.                    memory hardware.  Data aliasing occurs when mapping one
  977.                    logical page into two or more mappable segments.  This
  978.                    makes one 16K-byte expanded memory page appear to be in
  979.                    more than one 16K-byte memory address space.  Data
  980.                    aliasing is legal and sometimes useful for applications.
  981.  
  982.                    Software-only expanded memory emulators cannot perform
  983.                    data aliasing.  A simple way to distinguish software
  984.                    emulators from actual expanded memory hardware is to
  985.                    attempt data aliasing and check the results.  For
  986.                    example, map one logical page into four physical pages. 
  987.                    Write to physical page 0.  Read physical pages 1-3 to
  988.                    see if the data is there as well.  If the data appears
  989.                    in all four physical pages, then expanded memory
  990.                    hardware is installed in the system, and data aliasing
  991.                    is supported.
  992.  
  993.                o   Applications should always return expanded memory pages
  994.                    to the expanded memory manager upon termination.  These
  995.                    pages will be made available for other applications.  If
  996.                    unneeded pages are not returned to the expanded memory
  997.                    manager, the system could "run out" of expanded memory
  998.                    pages or expanded memory handles.
  999.  
  1000.                o   Terminate and stay resident programs (TSR's) should
  1001.                    ALWAYS save the state of the map registers before
  1002.                    changing them.  Since TSR's may interrupt other programs
  1003.  
  1004.           Writing Programs That Use Expanded Memory                      12
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.                    which may be using expanded memory, they must not change
  1011.                    the state of the page mapping registers without first
  1012.                    saving them.  Before exiting, TSR's must restore the
  1013.                    state of the map registers.
  1014.  
  1015.                    The following sections describe the three ways to save
  1016.                    and restore the state of the map registers.
  1017.  
  1018.                    1.  Save Page Map and Restore Page Map (Functions 8 and
  1019.                        9).  This is the simplest of the three methods.  The
  1020.                        EMM saves the map register contents in its own data
  1021.                        structures -- the application does not need to
  1022.                        provide extra storage locations for the mapping
  1023.                        context.  The last mapping context to be saved,
  1024.                        under a particular handle, will be restored when a
  1025.                        call to Restore Page Map is issued with the same
  1026.                        handle.  This method is limited to one mapping
  1027.                        context for each handle and saves the context for
  1028.                        only LIM standard 64K-byte page frames.
  1029.  
  1030.                    2.  Get/Set Page Map (Function 15).  This method
  1031.                        requires the application to allocate space for the
  1032.                        storage array.  The EMM saves the mapping context in
  1033.                        an array whose address is passed to the EMM.  When
  1034.                        restoring the mapping context with this method, an
  1035.                        application passes the address of an array which
  1036.                        contains a previously stored mapping context.
  1037.  
  1038.                        This method is preferable if an application needs to
  1039.                        do more than one save before a restore.  It provides
  1040.                        a mechanism for switching between more than one
  1041.                        mapping context.
  1042.  
  1043.                    3.  Get/Set Partial Page Map (Function 16).  This method
  1044.                        provides a way for saving a partial mapping context. 
  1045.                        It should be used when the application does not need
  1046.                        to save the context of all mappable memory.  This
  1047.                        function also requires that the storage array be
  1048.                        part of the application's data.
  1049.  
  1050.                o   All functions using pointers to data structures must
  1051.                    have those data structures in memory which will not be
  1052.                    mapped out.  Functions 22 and 23 (Alter Map & Call and
  1053.                    Alter Map & Jump) are the only exceptions.
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.           Writing Programs That Use Expanded Memory                      13
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.           Examples
  1070.  
  1071.                This section lists four example programs that demonstrate
  1072.                the use of expanded memory.
  1073.  
  1074.  
  1075.           Example 1
  1076.  
  1077.                This program was written using the Microsoft C compiler
  1078.                Version 3.0.  EMM function calls are made with the int86
  1079.                function found in the dos.h library.  To create an ex-
  1080.                ecutable program use the following compile command line:
  1081.  
  1082.                          msc /Gs /Oat /Ml program,,program;
  1083.  
  1084.           #include <dos.h>
  1085.           #include <stdio.h>
  1086.  
  1087.           #define EMM_INT                 0x67  /* EMM interrupt number */
  1088.           #define GET_PAGE_FRAME          0x41  /* EMM get page frame */
  1089.                                                 /* function number */
  1090.           #define GET_UNALLOC_PAGE_COUNT  0x42  /* EMM get unallocated */
  1091.                                                 /* page count */
  1092.                                                 /* function number */
  1093.           #define ALLOCATE_PAGES          0x43  /* EMM allocate pages */
  1094.                                                 /* function number */
  1095.           #define MAP_PAGES               0x44  /* EMM map pages */
  1096.                                                 /* function number */
  1097.           #define DEALLOCATE_PAGES        0x45  /* EMM deallocate pages */
  1098.                                                 /* function number */
  1099.           #define DEVICE_NAME_LENGTH      8     /* length of a device */
  1100.                                                 /* name string */
  1101.           #define TRUE                    1
  1102.           #define FALSE                   0
  1103.  
  1104.           union REGS input_regs, output_regs;
  1105.           struct SREGS segment_regs;
  1106.           int pf_addr;
  1107.  
  1108.           /*------------------------------------------------------------*/
  1109.           /* Routine to convert a segment:offset pair to a far ptr.     */
  1110.           /*------------------------------------------------------------*/
  1111.           char *build_ptr (segment, offset)
  1112.  
  1113.               unsigned int segment;
  1114.               unsigned int offset;
  1115.           {
  1116.               char *ptr;
  1117.  
  1118.               ptr = (char *)(((unsigned long)segment << 16) + offset);
  1119.               return (ptr);
  1120.           }
  1121.  
  1122.           Writing Programs That Use Expanded Memory                      14
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.           /*------------------------------------------------------------*/
  1129.           /* Function which determines whether EMM device driver        */
  1130.           /* is installed.                                              */
  1131.           /*------------------------------------------------------------*/
  1132.           char emm_installed()
  1133.  
  1134.           {
  1135.               char *EMM_device_name = "EMMXXXX0";
  1136.               char *int_67_device_name_ptr;
  1137.  
  1138.               /*--------------------------------------------------------*/
  1139.               /* AH = DOS get interrupt vector function.                */
  1140.               /*--------------------------------------------------------*/
  1141.               input_regs.h.ah = 0x35;
  1142.  
  1143.               /*--------------------------------------------------------*/
  1144.               /* AL = EMM interrupt vector number.                      */
  1145.               /*--------------------------------------------------------*/
  1146.               input_regs.h.al = EMM_INT;
  1147.               intdosx (&input_regs, &output_regs, &segment_regs);
  1148.  
  1149.               /*--------------------------------------------------------*/
  1150.               /* Upon return ES:0Ah points to location where            */
  1151.               /* device name should be.                                 */
  1152.               /*--------------------------------------------------------*/
  1153.               int_67_device_name_ptr = build_ptr (segment_regs.es, 0x0A);
  1154.  
  1155.               /*--------------------------------------------------------*/
  1156.               /* Compare memory with EMM device name.                   */
  1157.               /*--------------------------------------------------------*/
  1158.               if (memcmp (EMM_device_name, int_67_device_name_ptr,
  1159.                                              DEVICE_NAME_LENGTH) == 0)
  1160.                   return (TRUE);
  1161.               else
  1162.                   return (FALSE);
  1163.           }
  1164.  
  1165.           /*------------------------------------------------------------*/
  1166.           /* Function which determines if there are enough unallocated  */
  1167.           /* expanded memory pages for the application.                 */
  1168.           /*------------------------------------------------------------*/
  1169.           char enough_unallocated_pages (pages_needed)
  1170.  
  1171.               int pages_needed;
  1172.           {
  1173.               input_regs.h.ah = GET_UNALLOCATED_PAGE_COUNT;
  1174.               int86 (EMM_INT, &input_regs, &output_regs);
  1175.               if (output_regs.h.ah != 0 || pages_needed > output_regs.x.bx)
  1176.                   return (FALSE);
  1177.               else
  1178.                   return (TRUE);
  1179.           }
  1180.  
  1181.           Writing Programs That Use Expanded Memory                      15
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.           /*------------------------------------------------------------*/
  1188.           /* Function which allocates expanded memory pages and passes  */
  1189.           /* back to the main EMM handle.                               */
  1190.           /*------------------------------------------------------------*/
  1191.           char allocate_expanded_memory_pages (pages_needed,emm_handle_ptr)
  1192.  
  1193.               int pages_needed;
  1194.               unsigned int *emm_handle_ptr;
  1195.           {
  1196.               input_regs.h.ah = ALLOCATE_PAGES;
  1197.               input_regs.x.bx = pages_needed;
  1198.               int86 (EMM_INT, &input_regs, &output_regs);
  1199.               if (output_regs.h.ah == 0) {
  1200.                   *emm_handle_ptr = output_regs.x.dx;
  1201.                   return (TRUE);
  1202.               }
  1203.               else
  1204.                   return (FALSE);
  1205.           }
  1206.  
  1207.           /*------------------------------------------------------------*/
  1208.           /* Routine to map a logical page to a physical page.          */
  1209.           /*------------------------------------------------------------*/
  1210.           char map_expanded_memory_pages (emm_handle, physical_page,       
  1211.                                                              logical_page)
  1212.               unsigned int emm_handle;
  1213.               int physical_page;
  1214.               int logical_page;
  1215.           {
  1216.               input_regs.h.ah = MAP_PAGES;
  1217.               input_regs.h.al = physical_page;
  1218.               input_regs.x.bx = logical_page;
  1219.               input_regs.x.dx = emm_handle;
  1220.               int86 (EMM_INT, &input_regs, &output_regs);
  1221.               if (output_regs.h.ah == 0)
  1222.                   return (TRUE);
  1223.               else
  1224.                   return (FALSE);
  1225.           }
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.           Writing Programs That Use Expanded Memory                      16
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.           /*------------------------------------------------------------*/
  1247.           /* Routine which gets the page frame base address from EMM.   */
  1248.           /*------------------------------------------------------------*/
  1249.           char get_page_frame_address (pf_ptr)
  1250.  
  1251.               char **pf_ptr;
  1252.           {
  1253.               input_regs.h.ah = GET_PAGE_FRAME;
  1254.               int86 (EMM_INT, &input_regs, &output_regs);
  1255.               if (output_regs.h.ah != 0)       /* check EMM status */
  1256.                   return (FALSE);
  1257.               else
  1258.                  *pf_ptr = build_ptr (output_regs.x.bx, 0);
  1259.               return (TRUE);
  1260.           }
  1261.  
  1262.           /*------------------------------------------------------------*/
  1263.           /* Routine to release all expanded memory pages allocated     */
  1264.           /* by an EMM handle.                                          */
  1265.           /*------------------------------------------------------------*/
  1266.  
  1267.           char deallocate_expanded_memory_pages (emm_handle)
  1268.  
  1269.               unsigned int emm_handle;
  1270.           {
  1271.               input_regs.h.ah = DEALLOCATE_PAGES;
  1272.               input_regs.x.dx = emm_handle;
  1273.               int86 (EMM_INT, &input_regs, &output_regs);
  1274.               if (output_regs.h.ah == 0)
  1275.                   return (TRUE);
  1276.               else
  1277.                   return (FALSE);
  1278.           }
  1279.  
  1280.           main()
  1281.  
  1282.           {
  1283.               unsigned int emm_handle;
  1284.               char *pf_addr;
  1285.               int pages_needed;
  1286.               int physical_page;
  1287.               int logical_page;
  1288.               int index;
  1289.  
  1290.               /*--------------------------------------------------------*/
  1291.               /* Determine if EMM is installed.                         */
  1292.               /*--------------------------------------------------------*/
  1293.               if (!emm_installed())
  1294.                   exit(1);
  1295.  
  1296.  
  1297.  
  1298.  
  1299.           Writing Programs That Use Expanded Memory                      17
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.               /*--------------------------------------------------------*/
  1306.               /* Determine if enough expanded memory pages exist for    */
  1307.               /* application.                                           */
  1308.               /*--------------------------------------------------------*/
  1309.               pages_needed = 1;
  1310.               if (!enough_unallocated_pages (pages_needed))
  1311.                   exit(1);
  1312.  
  1313.               /*--------------------------------------------------------*/
  1314.               /* Allocate expanded memory pages.                        */
  1315.               /*--------------------------------------------------------*/
  1316.               if (!allocate_expanded_memory_pages (pages_needed,
  1317.                                                              &emm_handle))
  1318.                   exit(1);
  1319.  
  1320.               /*--------------------------------------------------------*/
  1321.               /* Map in the required pages.                             */
  1322.               /*--------------------------------------------------------*/
  1323.               physical_page = 0;
  1324.               logical_page = 0;
  1325.               if (!map_expanded_memory_pages (emm_handle, physical_page,
  1326.                                                             logical_page))
  1327.                   exit(1);
  1328.  
  1329.               /*--------------------------------------------------------*/
  1330.               /* Get expanded memory page frame address.                */
  1331.               /*--------------------------------------------------------*/
  1332.               if (!get_page_frame_address (&pf_addr))
  1333.                   exit(1);
  1334.  
  1335.               /*--------------------------------------------------------*/
  1336.               /* Write to expanded memory.                              */
  1337.               /*--------------------------------------------------------*/
  1338.               for (index = 0; index < 0x3fff; index++)
  1339.                   pf_addr[index] = index;
  1340.  
  1341.               /*--------------------------------------------------------*/
  1342.               /* Return expanded memory pages before exiting.           */
  1343.               /*--------------------------------------------------------*/
  1344.               if (!deallocate_expanded_memory_pages (emm_handle))
  1345.                   exit(1);
  1346.           }
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.           Writing Programs That Use Expanded Memory                      18
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.           Example 2
  1365.  
  1366.           This program shows you how to use the basic functions of the LIM
  1367.           Expanded Memory Specification with Turbo Pascal.  The program
  1368.           does the following:
  1369.  
  1370.                1.  Makes sure the LIM Expanded Memory Manager (EMM) has
  1371.                    been installed.
  1372.  
  1373.                2.  Displays the version number of the EMM.
  1374.  
  1375.                3.  Determines if there are enough pages of memory for the
  1376.                    program.  It then displays the total number of EMM pages
  1377.                    present in the system and the number available for use.
  1378.  
  1379.                4.  Requests the desired number of pages from the EMM.
  1380.  
  1381.                5.  Maps a logical page into one of the physical pages.
  1382.  
  1383.                6.  Displays the base address of our EMM memory page frame. 
  1384.                    Performs a simple read/write test on the EMM memory.
  1385.  
  1386.                7.  Returns the EMM memory given to us back to the EMM.
  1387.  
  1388.                8.  Exits.
  1389.  
  1390.           All the calls are structured to return the result or error code
  1391.           of the Expanded Memory function performed as an integer.  If the
  1392.           error code is not zero, an error has occurred, a simple error
  1393.           procedure is called, and the program terminates.
  1394.  
  1395.           Type
  1396.             ST3  = string[3];
  1397.             ST80 = string[80];
  1398.             ST5  = string[5];
  1399.  
  1400.             Registers = record
  1401.               case integer of
  1402.                 1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS: Integer);
  1403.                 2: (AL,AH,BL,BH,CL,CH,DL,DH         : Byte);
  1404.               end;
  1405.  
  1406.           Const
  1407.             EMM_INT                    = $67;
  1408.             DOS_Int                    = $21;
  1409.             GET_PAGE_FRAME             = $41;
  1410.             GET_UNALLOCATED_PAGE_COUNT = $42;
  1411.             ALLOCATE_PAGES             = $43;
  1412.             MAP_PAGES                  = $44;
  1413.             DEALLOCATE_PAGES           = $45;
  1414.             GET_VERSION                = $46;
  1415.             STATUS_OK                  = 0;
  1416.  
  1417.           Writing Programs That Use Expanded Memory                      19
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.             {------------------------------------------------------------}
  1424.             { Assume the application needs one EMM page.                 }
  1425.             {------------------------------------------------------------}
  1426.             APPLICATION_PAGE_COUNT = 1;
  1427.  
  1428.           Var
  1429.             Regs: Registers;
  1430.  
  1431.             Emm_handle,
  1432.             Page_Frame_Base_Address,
  1433.             Pages_Needed,
  1434.             Physical_Page,
  1435.             Logical_Page,
  1436.             Offset,
  1437.             Error_Code,
  1438.             Pages_EMM_Available,
  1439.             Total_EMM_Pages,
  1440.             Available_EMM_Pages: Integer;
  1441.  
  1442.             Version_Number,
  1443.             Pages_Number_String: ST3;
  1444.  
  1445.             Verify: Boolean;
  1446.  
  1447.             {------------------------------------------------------------}
  1448.             { The function Hex_String converts an integer into a four    }
  1449.             { character hexadecimal number (string) with leading zeros.  }
  1450.             {------------------------------------------------------------}
  1451.             Function Hex_String (Number: Integer): ST5;
  1452.               Function Hex_Char (Number: Integer): Char;
  1453.                 Begin
  1454.                   If Number < 10 then
  1455.                     Hex_Char := Char (Number + 48)
  1456.                   else
  1457.                     Hex_Char := Char (Number + 55);
  1458.                 end; { Function Hex_char }
  1459.  
  1460.             Var
  1461.               S: ST5;
  1462.  
  1463.             Begin
  1464.               S := '';
  1465.               S := Hex_Char ((Number shr 1) div 2048);
  1466.               Number := (((Number shr 1) mod 2048) shl 1) + (Number and 1);
  1467.               S := S + Hex_Char (Number div 256);
  1468.               Number := Number mod 256;
  1469.               S := S + Hex_Char (Number div 16);
  1470.               Number := Number mod 16;
  1471.               S := S + Hex_Char (Number);
  1472.               Hex_String := S + 'h';
  1473.             end; { Function Hex_String }
  1474.  
  1475.  
  1476.           Writing Programs That Use Expanded Memory                      20
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.             {------------------------------------------------------------}
  1483.             { The function Emm_Installed checks to see if the            }
  1484.             { EMM is loaded in memory.  It does this by looking          }
  1485.             { for the string 'EMMXXXX0', which should be located         }
  1486.             { at 10 bytes from the beginning of the code segment the     }
  1487.             { EMM interrupt, 67h, points to.                             }
  1488.             {------------------------------------------------------------}
  1489.             Function Emm_Installed: Boolean;
  1490.               Var
  1491.                 Emm_Device_Name   : string[8];
  1492.                 Int_67_Device_Name: string[8];
  1493.                 Position          : integer;
  1494.                 Regs              : registers;
  1495.  
  1496.               Begin
  1497.                 Int_67_Device_Name := '';
  1498.                 Emm_Device_Name    := 'EMMXXXX0';
  1499.                 with Regs do
  1500.                   Begin
  1501.                     {----------------------------------------------------}
  1502.                     { Get the code segment interrupt 67h points to       }
  1503.                     { the EMM interrupt by using DOS function 35h.       }
  1504.                     { (get interrupt vector)                             }
  1505.                     {----------------------------------------------------}
  1506.                     AH := $35;
  1507.                     AL := EMM_INT;
  1508.                     Intr (DOS_Int, Regs);
  1509.                     {----------------------------------------------------}
  1510.                     { The ES pseudo-register contains the segment        }
  1511.                     { address pointed to by interrupt 67h.  Create an    }
  1512.                     { eight character string from the eight successive   }
  1513.                     { bytes at address ES:$000A (10 bytes from ES)       }
  1514.                     {----------------------------------------------------}
  1515.                     For Position := 0 to 7 do
  1516.                       Int_67_Device_Name :=
  1517.                         Int_67_Device_Name + Chr (mem[ES:Position + $0A]);
  1518.                     Emm_Installed := True;
  1519.                     {----------------------------------------------------}
  1520.                     { If the string is the EMM manager signature,        }
  1521.                     { 'EMMXXXX0', then EMM is installed and ready for    }
  1522.                     { use.  If not, then EMM is not present.             }
  1523.                     {----------------------------------------------------}
  1524.                     If Int_67_Device_Name <> Emm_Device_Name
  1525.                       then Emm_Installed := False;
  1526.                   end; { with Regs do }
  1527.               end; { Function Emm_Installed }
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.           Writing Programs That Use Expanded Memory                      21
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.             {------------------------------------------------------------}
  1542.             { This function returns the total number of EMM pages        }
  1543.             { present in the system, and the number of EMM pages that    }
  1544.             { are available.                                             }
  1545.             {------------------------------------------------------------}
  1546.             Function EMM_Pages_Available
  1547.               (Var Total_EMM_Pages, Pages_Available: Integer): Integer;
  1548.               Var
  1549.                 Regs: Registers;
  1550.  
  1551.               Begin
  1552.                 with Regs do
  1553.                   Begin
  1554.                     {----------------------------------------------------}
  1555.                     { Get the number of currently unallocated pages and  }
  1556.                     { the total number of pages in the system from EMM.  }
  1557.                     { Load pseudo-registers prior to invoking EMM.       }
  1558.                     {    AH = get unallocated page count function        }
  1559.                     {----------------------------------------------------}
  1560.                     AH := GET_UNALLOCATED_PAGE_COUNT;
  1561.                     Intr (EMM_INT, Regs);
  1562.                     {----------------------------------------------------}
  1563.                     { Unload the pseudo-registers after invoking EMM.    }
  1564.                     {    BX = currently unallocated pages                }
  1565.                     {    DX = total pages in the system                  }
  1566.                     {    AH = status                                     }
  1567.                     {----------------------------------------------------}
  1568.                     Pages_Available := BX;
  1569.                     Total_EMM_Pages := DX;
  1570.                     EMM_Pages_Available := AH;
  1571.                   end;
  1572.               end; { Function EMM_Pages_Available }
  1573.  
  1574.  
  1575.             {------------------------------------------------------------}
  1576.             { This function requests the specified number of pages       }
  1577.             { from the EMM.                                              }
  1578.             {------------------------------------------------------------}
  1579.             Function Allocate_Expanded_Memory_Pages
  1580.               (Pages_Needed: Integer; Var Handle: Integer): Integer;
  1581.               Var
  1582.                 Regs: Registers;
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.  
  1594.           Writing Programs That Use Expanded Memory                      22
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.               Begin
  1601.                 with Regs do
  1602.                   Begin
  1603.                     {----------------------------------------------------}
  1604.                     { Allocate the specified number of pages from EMM.   }
  1605.                     { Load pseudo-registers prior to invoking EMM.       }
  1606.                     {    AH = allocate pages function.                   }
  1607.                     {    BX = number of pages to allocate.               }
  1608.                     {----------------------------------------------------}
  1609.                     AH := ALLOCATE_PAGES;
  1610.                     BX := Pages_Needed;
  1611.                     Intr (EMM_INT, Regs);
  1612.                     {----------------------------------------------------}
  1613.                     { Unload the pseudo-registers after invoking EMM.    }
  1614.                     {    DX = EMM handle                                 }
  1615.                     {    AH = status                                     }
  1616.                     {----------------------------------------------------}
  1617.                     Handle := DX;
  1618.                     Allocate_Expanded_Memory_Pages := AH;
  1619.                   end;
  1620.               end; { Function Allocate_Expanded_Memory_Pages }
  1621.  
  1622.  
  1623.             {------------------------------------------------------------}
  1624.             { This function maps a logical page allocated by the         }
  1625.             { Allocate_Expanded_Memory_Pages function into one of the    }
  1626.             { four physical pages.                                       }
  1627.             {------------------------------------------------------------}
  1628.             Function Map_Expanded_Memory_Pages
  1629.               (Handle, Logical_Page, Physical_Page: Integer): Integer;
  1630.               Var
  1631.                 Regs: Registers;
  1632.  
  1633.               Begin
  1634.                 with Regs do
  1635.                   Begin
  1636.                     {----------------------------------------------------}
  1637.                     { Map a logical page at a physical page.             }
  1638.                     { Load pseudo-registers prior to invoking EMM.       }
  1639.                     {    AH = map page function                          }
  1640.                     {    DX = handle                                     }
  1641.                     {    BX = logical page number                        }
  1642.                     {    AL = physical page number                       }
  1643.                     {----------------------------------------------------}
  1644.                     AH := MAP_PAGES;
  1645.                     DX := Handle;
  1646.                     BX := Logical_Page;
  1647.                     AL := Physical_Page;
  1648.                     Intr (EMM_INT, Regs);
  1649.  
  1650.  
  1651.  
  1652.  
  1653.           Writing Programs That Use Expanded Memory                      23
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.                     {----------------------------------------------------}
  1660.                     { Unload the pseudo-registers after invoking EMM.    }
  1661.                     {    AH = status                                     }
  1662.                     {----------------------------------------------------}
  1663.                     Map_Expanded_Memory_Pages := AH;
  1664.                   end; { with Regs do }
  1665.               end; { Function Map_Expanded_Memory_Pages }
  1666.  
  1667.  
  1668.             {------------------------------------------------------------}
  1669.             { This function gets the physical address of the EMM page    }
  1670.             { frame we are using.  The address returned is the segment   }
  1671.             { of the page frame.                                         }
  1672.             {------------------------------------------------------------}
  1673.             Function Get_Page_Frame_Base_Address
  1674.               (Var Page_Frame_Address: Integer): Integer;
  1675.               Var
  1676.                 Regs: Registers;
  1677.  
  1678.               Begin
  1679.                 with Regs do
  1680.                   Begin
  1681.                     {----------------------------------------------------}
  1682.                     { Get the page frame segment address from EMM.       }
  1683.                     { Load pseudo-registers prior to invoking EMM.       }
  1684.                     {    AH = get page frame segment function            }
  1685.                     {----------------------------------------------------}
  1686.                     AH := GET_PAGE_FRAME;
  1687.                     Intr (EMM_INT, Regs);
  1688.                     {----------------------------------------------------}
  1689.                     { Unload the pseudo-registers after invoking EMM.    }
  1690.                     {    BX = page frame segment address                 }
  1691.                     {    AH = status                                     }
  1692.                     {----------------------------------------------------}
  1693.                     Page_Frame_Address := BX;
  1694.                     Get_Page_Frame_Base_Address := AH;
  1695.                   end; { with Regs do }
  1696.               end; { Function Get_Page_Frame_Base_Address }
  1697.  
  1698.  
  1699.             {------------------------------------------------------------}
  1700.             { This function releases the EMM memory pages allocated to   }
  1701.             { us, back to the EMM memory pool.                           }
  1702.             {------------------------------------------------------------}
  1703.             Function Deallocate_Expanded_Memory_Pages
  1704.               (Handle: Integer): Integer;
  1705.               Var
  1706.                 Regs: Registers;
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.           Writing Programs That Use Expanded Memory                      24
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.               Begin
  1719.                 with Regs do
  1720.                   Begin
  1721.                     {----------------------------------------------------}
  1722.                     { Deallocate the pages allocated to an EMM handle.   }
  1723.                     { Load pseudo-registers prior to invoking EMM.       }
  1724.                     {    AH = deallocate pages function                  }
  1725.                     {    DX = EMM handle                                 }
  1726.                     {----------------------------------------------------}
  1727.                     AH := DEALLOCATE_PAGES;
  1728.                     DX := Handle;
  1729.                     Intr (EMM_INT, Regs);
  1730.                     {----------------------------------------------------}
  1731.                     { Unload the pseudo-registers after invoking EMM.    }
  1732.                     {    AH = status                                     }
  1733.                     {----------------------------------------------------}
  1734.                     Deallocate_Expanded_Memory_Pages := AH;
  1735.                   end; { with Regs do }
  1736.               end; { Function Deallocate_Expanded_Memory_Pages }
  1737.  
  1738.  
  1739.             {------------------------------------------------------------}
  1740.             { This function returns the version number of the EMM as     }
  1741.             { a three-character string.                                  }
  1742.             {------------------------------------------------------------}
  1743.             Function Get_Version_Number (Var Version_String: ST3): Integer;
  1744.               Var
  1745.                 Regs: Registers;
  1746.                 Integer_Part, Fractional_Part: Char;
  1747.  
  1748.               Begin
  1749.                 with Regs do
  1750.                   Begin
  1751.                     {----------------------------------------------------}
  1752.                     { Get the version of EMM.                            }
  1753.                     { Load pseudo-registers prior to invoking EMM.       }
  1754.                     {    AH = get EMM version function                   }
  1755.                     {----------------------------------------------------}
  1756.                     AH := GET_VERSION;
  1757.                     Intr (EMM_INT, Regs);
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.           Writing Programs That Use Expanded Memory                      25
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.                     {----------------------------------------------------}
  1778.                     { If the version number returned was OK, then        }
  1779.                     { convert it to a three-character string.            }
  1780.                     {----------------------------------------------------}
  1781.                     If AH=STATUS_OK then
  1782.                       Begin
  1783.                         {------------------------------------------------}
  1784.                         { The upper four bits of AH are the integer      }
  1785.                         { portion of the version number, the lower four  }
  1786.                         { bits are the fractional portion.  Convert the  }
  1787.                         { integer value to ASCII by adding 48.           }
  1788.                         {------------------------------------------------}
  1789.                         Integer_Part    := Char (AL shr 4  + 48);
  1790.                         Fractional_Part := Char (AL and $F + 48);
  1791.                         Version_String  := Integer_Part + '.' +
  1792.                                                           Fractional_Part;
  1793.                       end; { If AH=STATUS_OK }
  1794.                     {----------------------------------------------------}
  1795.                     { Unload the pseudo-registers after invoking EMM.    }
  1796.                     {    AH = status                                     }
  1797.                     {----------------------------------------------------}
  1798.                     Get_Version_Number := AH;
  1799.                   end; { with Regs do }
  1800.               end; { Function Get_Version_Number }
  1801.  
  1802.  
  1803.             {------------------------------------------------------------}
  1804.             { This procedure prints an error message passed by the       }
  1805.             { caller, prints the error code passed by the caller in hex, }
  1806.             { and then terminates the program with an error level of 1.  }
  1807.             {------------------------------------------------------------}
  1808.             Procedure Error (Error_Message: ST80; Error_Number: Integer);
  1809.               Begin
  1810.                 Writeln (Error_Message);
  1811.                 Writeln ('  Error_Number = ', Hex_String (Error_Number));
  1812.                 Writeln ('EMM test program aborting.');
  1813.                 Halt (1);
  1814.               end; { Procedure Error }
  1815.  
  1816.  
  1817.           {--------------------------------------------------------------}
  1818.           { This program is an example of the basic EMM functions that   }
  1819.           { you need in order to use EMM memory with Turbo Pascal.       }
  1820.           {--------------------------------------------------------------}
  1821.           Begin
  1822.             ClrScr;
  1823.             Window (5,2,77,22);
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.           Writing Programs That Use Expanded Memory                      26
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.             {------------------------------------------------------------}
  1837.             { Determine if the Expanded Memory Manager is installed.  If }
  1838.             { not, then terminate 'main' with an ErrorLevel code of 1.   }
  1839.             {------------------------------------------------------------}
  1840.             If not (Emm_Installed) then
  1841.               Begin
  1842.                 Writeln ('The LIM EMM is not installed.');
  1843.                 Halt (1);
  1844.               end
  1845.             else
  1846.               Begin
  1847.                 { Get the version number and display it }
  1848.                 Error_Code := Get_Version_Number (Version_Number);
  1849.                 If Error_Code <> STATUS_OK then
  1850.                   Error ('Error getting EMM version number.', Error_Code)
  1851.                 else
  1852.                   Writeln ('LIM Expanded Memory Manager, version ',
  1853.                            Version_Number, ' is ready for use.');
  1854.               end;
  1855.             Writeln;
  1856.  
  1857.             {------------------------------------------------------------}
  1858.             { Determine if there are enough expanded memory pages for    }
  1859.             { this application.                                          }
  1860.             {------------------------------------------------------------}
  1861.             Pages_Needed := APPLICATION_PAGE_COUNT;
  1862.             Error_Code   := EMM_Pages_Available (Total_EMM_Pages,
  1863.                                                  Available_EMM_Pages);
  1864.             If Error_Code <> STATUS_OK then
  1865.               Error ('Error determining number of EMM pages available.',
  1866.                      Error_Code);
  1867.             Writeln ('There are a total of ', Total_EMM_Pages,
  1868.                      ' expanded memory pages present in this system.');
  1869.             Writeln ('  ', Available_EMM_Pages,
  1870.                      ' of those pages are available for use.');
  1871.             Writeln;
  1872.  
  1873.             {------------------------------------------------------------}
  1874.             { If there is an insufficient number of pages for the        }
  1875.             { application, then report the error and terminate the EMM   }
  1876.             { example program.                                           }
  1877.             {------------------------------------------------------------}
  1878.             If Pages_Needed > Available_EMM_Pages then
  1879.               Begin
  1880.                 Str (Pages_Needed, Pages_Number_String);
  1881.                 Error ('We need ' + Pages_Number_String +
  1882.                        ' EMM pages.  There are not that many available.',
  1883.                        Error_Code);
  1884.               end; { Pages_Needed > Available_EMM_Pages }
  1885.  
  1886.  
  1887.  
  1888.  
  1889.           Writing Programs That Use Expanded Memory                      27
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.             {------------------------------------------------------------}
  1896.             { Allocate expanded memory pages for our use.                }
  1897.             {------------------------------------------------------------}
  1898.             Error_Code :=
  1899.               Allocate_Expanded_Memory_Pages (Pages_Needed, Emm_Handle);
  1900.             Str (Pages_Needed, Pages_Number_String);
  1901.             If Error_Code <> STATUS_OK then
  1902.               Error ('EMM test program failed trying to allocate '
  1903.                      + Pages_Number_String
  1904.                      + ' pages for usage.', Error_Code);
  1905.             Writeln (APPLICATION_PAGE_COUNT,
  1906.                      ' EMM page(s) allocated for the EMM test program.');
  1907.             Writeln;
  1908.  
  1909.             {------------------------------------------------------------}
  1910.             { Map in the required logical pages to the physical pages    }
  1911.             { given to us, in this case just one page.                   }
  1912.             {------------------------------------------------------------}
  1913.             Logical_Page  := 0;
  1914.             Physical_Page := 0;
  1915.             Error_Code := Map_Expanded_Memory_Pages (Emm_Handle,
  1916.                                                      Logical_Page,
  1917.                                                      Physical_Page);
  1918.             If Error_Code <> STATUS_OK then
  1919.               Error ('EMM test program failed trying to map '
  1920.                      + 'logical pages into physical pages.',
  1921.                      Error_Code);
  1922.  
  1923.             Writeln ('Logical Page ',
  1924.                      Logical_Page,
  1925.                      ' successfully mapped into Physical Page ',
  1926.                      Physical_Page);
  1927.             Writeln;
  1928.  
  1929.             {------------------------------------------------------------}
  1930.             { Get the expanded memory page frame address.                }
  1931.             {------------------------------------------------------------}
  1932.             Error_Code := Get_Page_Frame_Base_Address
  1933.                             (Page_Frame_Base_Address);
  1934.             If Error_Code <> STATUS_OK then
  1935.               Error ('EMM test program unable to get the base Page'
  1936.                      + ' Frame Address.',
  1937.                      Error_Code);
  1938.             Writeln ('The base address of the EMM page frame is = '
  1939.                      + Hex_String (Page_Frame_Base_Address));
  1940.             Writeln;
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.           Writing Programs That Use Expanded Memory                      28
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.             {------------------------------------------------------------}
  1955.             { Write a test pattern to expanded memory.                   }
  1956.             {------------------------------------------------------------}
  1957.             For Offset := 0 to 16382 do
  1958.               Begin
  1959.                 Mem[Page_Frame_Base_Address:Offset] := Offset mod 256;
  1960.               end;
  1961.  
  1962.             {------------------------------------------------------------}
  1963.             { Make sure that what is in EMM memory is what was just      }
  1964.             { written.                                                   }
  1965.             {------------------------------------------------------------}
  1966.             Writeln ('Testing EMM memory.');
  1967.  
  1968.             Offset := 1;
  1969.             Verify := True;
  1970.             while (Offset <= 16382) and (Verify = True) do
  1971.               Begin
  1972.                 If Mem[Page_Frame_Base_Address:Offset] <> Offset mod 256
  1973.                   then Verify := False;
  1974.                 Offset := Succ (Offset);
  1975.               end; { while (Offset <= 16382) and (Verify = True) }
  1976.  
  1977.             {------------------------------------------------------------}
  1978.             { If what is read does not match what was written,           }
  1979.             { an error occurred.                                         }
  1980.             {------------------------------------------------------------}
  1981.             If not Verify then
  1982.               Error ('What was written to EMM memory was not found during'
  1983.                      + ' memory verification test.',
  1984.                      0);
  1985.             Writeln ('EMM memory test successful.');
  1986.             Writeln;
  1987.  
  1988.             {------------------------------------------------------------}
  1989.             { Return the expanded memory pages given to us back to the   }
  1990.             { EMM memory pool before terminating our test program.       }
  1991.             {------------------------------------------------------------}
  1992.             Error_Code := Deallocate_Expanded_Memory_Pages (Emm_Handle);
  1993.             If Error_Code <> STATUS_OK then
  1994.               Error ('EMM test program was unable to deallocate '
  1995.                      + 'the EMM pages in use.',
  1996.                      Error_Code);
  1997.             Writeln (APPLICATION_PAGE_COUNT,
  1998.                      ' pages(s) deallocated.');
  1999.             Writeln;
  2000.             Writeln ('EMM test program completed.');
  2001.  
  2002.           end.
  2003.  
  2004.  
  2005.  
  2006.  
  2007.           Writing Programs That Use Expanded Memory                      29
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.           Example 3
  2014.  
  2015.                This program is written in Microsoft's macro assembler.
  2016.  
  2017.  
  2018.           CODE SEGMENT
  2019.                ASSUME CS:CODE, DS:CODE
  2020.  
  2021.           MOV   AX,CS
  2022.           MOV   DX,AX
  2023.                .
  2024.                .
  2025.                .
  2026.           check_emm_installed:
  2027.  
  2028.           MOV   AH,35h                  ; AH = DOS get interrupt vector
  2029.                                         ; function
  2030.           MOV   AL,67h                  ; AL = EMM interrupt vector number
  2031.           INT   21h
  2032.           MOV   DI,0Ah                  ; ES:DI points to where device     
  2033.                                         ; name should be
  2034.           LEA   SI,EMM_device_name      ; DS:SI points to ASCII string     
  2035.                                         ; containing EMM device name
  2036.  
  2037.           MOV   CX,device_name_length   ; set up loop counter for string op
  2038.           CLD                           ; set up direction flag for forward
  2039.           REPE  CMPSB                   ; Compare the strings
  2040.           JNE   exit                    ; IF strings not equal THEN exit
  2041.                                         ; ELSE
  2042.           check_enough_unallocated_pages:
  2043.  
  2044.           MOV   AH,41h                  ;    AH = EMM get unallocated page
  2045.                                         ;    count function code
  2046.           INT   67h
  2047.           OR    AH,AH                   ; Check EMM status
  2048.           JNZ   emm_error_handler       ; IF error THEN goto error handler
  2049.                                         ; ELSE
  2050.           allocate_expanded_memory_pages:
  2051.  
  2052.           MOV   AH,43h                  ;    AH = EMM allocate pages
  2053.                                         ;    function code
  2054.           MOV   BX,2                    ;    BX = number of pages needed
  2055.           INT   67h
  2056.           OR    AH,AH                   ; Check EMM status
  2057.           JNZ   emm_error_handler       ; IF error THEN goto error handler
  2058.                                         ; ELSE
  2059.           MOV   emm_handle,DX           ;    save EMM handle
  2060.  
  2061.           map_expanded_memory_pages:
  2062.  
  2063.           MOV   AH,44h                  ; AH = EMM map pages function
  2064.           MOV   DX,emm_handle           ; DX = application's handle
  2065.  
  2066.           Writing Programs That Use Expanded Memory                      30
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.           map_0_to_0:
  2073.  
  2074.           MOV   BX,0                    ; BX = logical page 0
  2075.           MOV   AL,0                    ; AL = physical page 0
  2076.           INT   67h
  2077.           OR    AH,AH                   ; Check EMM status
  2078.           JNZ   emm_error_handler       ; If error THEN goto error handler
  2079.                                         ; ELSE
  2080.           get_page_frame_address:
  2081.  
  2082.           MOV   AH,41h                  ; AH = EMM get page frame base
  2083.                                         ; address function
  2084.           INT   67h
  2085.           OR    AH,AH                   ; Check EMM status
  2086.           JNZ   emm_error_handler       ; IF error THEN goto error handler
  2087.           MOV   pf_addr,BX              ; ELSE save pf_addr
  2088.  
  2089.           write_to_expanded_memory:     ; Write zeros to memory mapped at
  2090.                                         ; physical page 0
  2091.           MOV   AX,pf_addr
  2092.           MOV   ES,AX                   ; ES points to physical page 0
  2093.           MOV   DI,0                    ; DI indexes into physical page 0
  2094.           MOV   AL,0                    ; Initialize AL for string STOSB
  2095.           MOV   CX,4000h                ; Initialize loop counter to length 
  2096.                                         ; of expanded memory page size
  2097.           CLD                           ; set up direction flag for forward
  2098.           REP   STOSB
  2099.  
  2100.           deallocate_pages:
  2101.  
  2102.           MOV   AH,45h                  ; AH = EMM deallocate pages        
  2103.                                         ; function
  2104.           MOV   DX,emm_handle
  2105.           INT   67h                     ; return handle's pages to EMM
  2106.           OR    AH,AH                   ; Check EMM status
  2107.           JNZ   emm_error_handler       ; IF error THEN goto error handler
  2108.  
  2109.           exit:
  2110.  
  2111.           MOV   AH,4Ch                  ; AH = DOS exit function
  2112.           INT   21h                     ; return to DOS
  2113.  
  2114.  
  2115.           EMM_device_name DB 'EMMXXXX0' ; ASCII EMM device name string
  2116.  
  2117.           device_name_length EQU 8
  2118.  
  2119.           CODE ENDS
  2120.                END
  2121.  
  2122.  
  2123.  
  2124.  
  2125.           Writing Programs That Use Expanded Memory                      31
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.           Example 4
  2132.  
  2133.                This program is an example of how to exchange a 256K-byte
  2134.                block of data from conventional memory to expanded memory.
  2135.  
  2136.  
  2137.           CODE SEGMENT
  2138.                ASSUME CS:CODE, DS:CODE
  2139.                .
  2140.                .
  2141.                .
  2142.           xchg_packet_set_up:
  2143.  
  2144.           ;DS:SI = xchg_packet
  2145.  
  2146.           MOV   AX,SEG xchg_packet
  2147.           MOV   DS,AX
  2148.           MOV   SI,OFFSET xchg_packet
  2149.  
  2150.           ;Moving 256K of data from conventional memory to expanded memory
  2151.  
  2152.           MOV   WORD PTR [SI].region_length[0],0
  2153.           MOV   WORD PTR [SI].region_length[2],4
  2154.           MOV   [SI].src_mem_type,0
  2155.           MOV   [SI].dest_mem_type,1
  2156.  
  2157.           ;starting at segment: 4000h, offset: 0
  2158.  
  2159.           MOV   [SI].src_init_seg_page,4000h
  2160.           MOV   [SI].src_init_offset,0
  2161.  
  2162.           ;Move data into expanded memory logical page 0, offset 0.
  2163.  
  2164.           MOV   [SI].dest_init_seg_page,0
  2165.           MOV   [SI].dest_init_offset,0
  2166.  
  2167.           ;Initialize for future compatibility
  2168.  
  2169.           MOV   [SI].src_handle,0
  2170.  
  2171.           ;Need handle for expanded memory destination.
  2172.  
  2173.           MOV   DX,emm_handle
  2174.           MOV   [SI].dest_handle,DX
  2175.  
  2176.           ;AX = EMM Exchange Memory function
  2177.  
  2178.           MOV   AX,5701h
  2179.           INT   67h
  2180.           OR    AH,AH
  2181.           JNZ   emm_error_handler
  2182.  
  2183.  
  2184.           Writing Programs That Use Expanded Memory                      32
  2185.  
  2186.  
  2187.  
  2188.  
  2189.  
  2190.           xchg_struct                    STRUC
  2191.              region_length               DD ?
  2192.              src_mem_type                DB ?
  2193.              src_handle                  DW ?
  2194.              src_init_offset             DW ?
  2195.              src_init_seg_page           DW ?
  2196.              dest_mem_type               DB ?
  2197.              dest_handle                 DW ?
  2198.              dest_init_offset            DW ?
  2199.              dest_init_seg_page          DW ?
  2200.           xchg_struct                    ENDS
  2201.  
  2202.           xchg_packet                    xchg_struct
  2203.  
  2204.           CODE  ENDS
  2205.                 END
  2206.  
  2207.  
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221.  
  2222.  
  2223.  
  2224.  
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.  
  2241.  
  2242.  
  2243.           Writing Programs That Use Expanded Memory                      33
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.           Chapter 3
  2250.           EMM FUNCTIONS
  2251.  
  2252.  
  2253.                This chapter provides you with a standardized set of
  2254.                expanded memory functions.  Because they are standardized,
  2255.                you avoid potential compatibility problems with other
  2256.                expanded memory programs that also adhere to the memory
  2257.                manager specification.  Programs that deal directly with the
  2258.                hardware or that don't adhere to this specification will be
  2259.                incompatible.
  2260.  
  2261.                Table 3-1 presents a sequential list of the EMM functions. 
  2262.                The remainder of this chapter provides detailed descriptions
  2263.                of each function.
  2264.  
  2265.  
  2266.           Table 3-1.  List of EMM Functions
  2267.           ----------------------------------------------------------------
  2268.  
  2269.           Number             Function Name                Hex Value   Page
  2270.  
  2271.           ----------------------------------------------------------------
  2272.  
  2273.              1    Get Status                                40h         37
  2274.  
  2275.              2    Get Page Frame Address                    41h         38
  2276.  
  2277.              3    Get Unallocated Page Count                42h         40
  2278.  
  2279.              4    Allocate Pages                            43h         42
  2280.  
  2281.              5    Map/Unmap Handle Page                     44h         46
  2282.  
  2283.              6    Deallocate Pages                          45h         49
  2284.  
  2285.              7    Get Version                               46h         51
  2286.  
  2287.              8    Save Page Map                             47h         53
  2288.  
  2289.              9    Restore Page Map                          48h         55
  2290.  
  2291.             10    Reserved                                  49h         57
  2292.  
  2293.             11    Reserved                                  4Ah         58
  2294.  
  2295.             12    Get Handle Count                          4Bh         59
  2296.  
  2297.             13    Get Handle Pages                          4Ch         61
  2298.  
  2299.             14    Get All Handle Pages                      4Dh         63
  2300.  
  2301.  
  2302.           EMM Functions                                                  34
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.           Table 3-1.  List of EMM Functions (continued)
  2309.           ----------------------------------------------------------------
  2310.  
  2311.           Number             Function Name                Hex Value   Page
  2312.  
  2313.           ----------------------------------------------------------------
  2314.  
  2315.             15    Get Page Map                              4E00h       65
  2316.                   Set Page Map                              4E01h       67
  2317.                   Get & Set Page Map                        4E02h       69
  2318.                   Get Size of Page Map Save Array           4E03h       71
  2319.  
  2320.             16    Get Partial Page Map                      4F00h       73
  2321.                   Set Partial Page Map                      4F01h       76
  2322.                   Get Size of Partial Page Map
  2323.                      Save Array                             4F02h       78
  2324.  
  2325.             17    Map/Unmap Multiple Handle Pages
  2326.                   (Physical page number mode)               5000h       82
  2327.                   Map/Unmap Multiple Handle Pages
  2328.                   (Segment address mode)                    5001h       85
  2329.  
  2330.             18    Reallocate Pages                          51h         88
  2331.  
  2332.             19    Get Handle Attribute                      5200h       92
  2333.                   Set Handle Attribute                      5201h       94
  2334.                   Get Handle Attribute Capability           5202h       96
  2335.  
  2336.             20    Get Handle Name                           5300h       98
  2337.                   Set Handle Name                           5301h      100
  2338.  
  2339.             21    Get Handle Directory                      5400h      102
  2340.                   Search for Named Handle                   5401h      105
  2341.                   Get Total Handles                         5402h      107
  2342.  
  2343.             22    Alter Page Map & Jump
  2344.                   (Physical page number mode)               5500h      109
  2345.                   Alter Page Map & Jump
  2346.                   (Segment address mode)                    5501h      109
  2347.  
  2348.             23    Alter Page Map & Call
  2349.                   (Physical page number mode)               5600h      113
  2350.                   Alter Page Map & Call
  2351.                   (Segment address mode)                    5601h      113
  2352.                   Get Page Map Stack Space Size             5602h      118
  2353.  
  2354.             24    Move Memory Region                        5700h      120
  2355.                   Exchange Memory Region                    5701h      126
  2356.  
  2357.             25    Get Mappable Physical Address Array       5800h      132
  2358.                   Get Mappable Physical Address Array
  2359.                      Entries                                5801h      136
  2360.  
  2361.           EMM Functions                                                  35
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.           Table 3-1.  List of EMM Functions (continued)
  2368.           ----------------------------------------------------------------
  2369.  
  2370.           Number             Function Name                Hex Value   Page
  2371.  
  2372.           ----------------------------------------------------------------
  2373.  
  2374.             26    Get Hardware Configuration Array          5900h      138
  2375.                   Get Unallocated Raw Page Count            5901h      142
  2376.  
  2377.             27    Allocate Standard Pages                   5A00h      144
  2378.                   Allocate Raw Pages                        5A01h      147
  2379.  
  2380.             28    Get Alternate Map Register Set            5B00h      153
  2381.                   Set Alternate Map Register Set            5B01h      157
  2382.                   Get Alternate Map Save Array Size         5B02h      161
  2383.                   Allocate Alternate Map Register Set       5B03h      163
  2384.                   Deallocate Alternate Map Register Set     5B04h      166
  2385.                   Allocate DMA Register Set                 5B05h      168
  2386.                   Enable DMA on Alternate Map
  2387.                      Register Set                           5B06h      170
  2388.                   Disable DMA on Alternate Map
  2389.                      Register Set                           5B07h      173
  2390.                   Deallocate DMA Register Set               5B08h      175
  2391.  
  2392.             29    Prepare Expanded Memory Hardware
  2393.                      for Warmboot                           5Ch        177
  2394.  
  2395.             30    Enable OS/E Function Set                  5D00h      179
  2396.                   Disable OS/E Function Set                 5D01h      182
  2397.                   Return OS/E Access Key                    5D02h      185
  2398.  
  2399.           ----------------------------------------------------------------
  2400.  
  2401.  
  2402.  
  2403.  
  2404.  
  2405.  
  2406.  
  2407.  
  2408.  
  2409.  
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419.  
  2420.           EMM Functions                                                  36
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.           Function 1. Get Status
  2427.  
  2428.  
  2429.  
  2430.           PURPOSE
  2431.  
  2432.                The Get Status function returns a status code indicating
  2433.                whether the memory manager is present and the hardware is
  2434.                working correctly.
  2435.  
  2436.  
  2437.           CALLING PARAMETERS
  2438.  
  2439.                AH = 40h
  2440.                    Contains the Get Status Function.
  2441.  
  2442.  
  2443.           REGISTERS MODIFIED
  2444.  
  2445.                AX
  2446.  
  2447.  
  2448.           STATUS
  2449.  
  2450.                AH = 0   SUCCESSFUL.
  2451.                    The manager is present in the system, and the hardware
  2452.                    is working correctly.
  2453.  
  2454.                AH = 80h   NON-RECOVERABLE.
  2455.                    The manager detected a malfunction in the memory manager
  2456.                    software.
  2457.  
  2458.                AH = 81h   NON-RECOVERABLE.
  2459.                    The manager detected a malfunction in the expanded
  2460.                    memory hardware.
  2461.  
  2462.                AH = 84h   NON-RECOVERABLE.
  2463.                    The function code passed to the memory manager is not
  2464.                    defined.
  2465.  
  2466.  
  2467.           EXAMPLE
  2468.  
  2469.           MOV   AH,40h                   ; load function code
  2470.           INT   67h                      ; call the memory manager
  2471.           OR    AH,AH                    ; check EMM status
  2472.           JNZ   emm_err_handler          ; jump to error handler on error
  2473.  
  2474.  
  2475.  
  2476.  
  2477.  
  2478.  
  2479.           EMM Functions                                                  37
  2480.  
  2481.  
  2482.  
  2483.  
  2484.  
  2485.           Function 2. Get Page Frame Address
  2486.  
  2487.  
  2488.  
  2489.           PURPOSE
  2490.  
  2491.                The Get Page Frame Address function returns the segment
  2492.                address where the page frame is located.
  2493.  
  2494.  
  2495.           CALLING PARAMETERS
  2496.  
  2497.                AH = 41h
  2498.                    Contains the Get Page Frame Address function.
  2499.  
  2500.  
  2501.           RESULTS
  2502.  
  2503.                These results are valid only if the status returned is zero.
  2504.  
  2505.                BX = page frame segment address
  2506.                    Contains the segment address of the page frame.
  2507.  
  2508.  
  2509.           REGISTERS MODIFIED
  2510.  
  2511.                AX, BX
  2512.  
  2513.  
  2514.           STATUS
  2515.  
  2516.                AH = 0   SUCCESSFUL.
  2517.                    The manager has returned the page frame address in the
  2518.                    BX register.
  2519.  
  2520.                AH = 80h   NON-RECOVERABLE.
  2521.                    The manager detected a malfunction in the memory manager
  2522.                    software.
  2523.  
  2524.                AH = 81h   NON-RECOVERABLE.
  2525.                    The manager detected a malfunction in the expanded
  2526.                    memory hardware.
  2527.  
  2528.                AH = 84h   NON-RECOVERABLE.
  2529.                    The function code passed to the memory manager is not
  2530.                    defined.
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.           EMM Functions                                                  38
  2539.  
  2540.  
  2541.  
  2542.  
  2543.  
  2544.           Function 2. Get Page Frame Address
  2545.  
  2546.  
  2547.  
  2548.           EXAMPLE
  2549.  
  2550.           page_frame_segment             DW ?
  2551.  
  2552.           MOV   AH,41h                   ; load function code
  2553.           INT   67h                      ; call the memory manager
  2554.           OR    AH,AH                    ; check EMM status
  2555.           JNZ   emm_err_handler          ; jump to error handler on error
  2556.           MOV   page_frame_segment,BX    ; save page frame address
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593.  
  2594.  
  2595.  
  2596.  
  2597.           EMM Functions                                                  39
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.           Function 3. Get Unallocated Page Count
  2604.  
  2605.  
  2606.  
  2607.           PURPOSE
  2608.  
  2609.                The Get Unallocated Page Count function returns the number
  2610.                of unallocated pages and the total number of expanded memory
  2611.                pages.
  2612.  
  2613.  
  2614.           CALLING PARAMETERS
  2615.  
  2616.                AH = 42h
  2617.                    Contains the Get Unallocated Page Count function.
  2618.  
  2619.  
  2620.           RESULTS
  2621.  
  2622.                These results are valid only if the status returned is zero.
  2623.  
  2624.                BX = unallocated pages
  2625.                    The number of expanded memory pages that are currently
  2626.                    available for use (unallocated).
  2627.  
  2628.                DX = total pages
  2629.                    The total number of expanded memory pages.
  2630.  
  2631.  
  2632.           REGISTERS MODIFIED
  2633.  
  2634.                AX, BX, DX
  2635.  
  2636.  
  2637.           STATUS
  2638.  
  2639.                AH = 0   SUCCESSFUL.
  2640.                    The manager has returned the number of unallocated pages
  2641.                    and the number of total pages in expanded memory.
  2642.  
  2643.                AH = 80h   NON-RECOVERABLE.
  2644.                    The manager detected a malfunction in the memory manager
  2645.                    software.
  2646.  
  2647.                AH = 81h   NON-RECOVERABLE.
  2648.                    The manager detected a malfunction in the expanded
  2649.                    memory hardware.
  2650.  
  2651.                AH = 84h   NON-RECOVERABLE.
  2652.                    The function code passed to the memory manager is not
  2653.                    defined.
  2654.  
  2655.  
  2656.           EMM Functions                                                  40
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.           Function 3. Get Unallocated Page Count
  2663.  
  2664.  
  2665.  
  2666.           EXAMPLE
  2667.  
  2668.           un_alloc_pages                 DW ?
  2669.           total_pages                    DW ?
  2670.  
  2671.           MOV   AH,42h                   ; load function code
  2672.           INT   67h                      ; call the memory manager
  2673.           OR    AH,AH                    ; check EMM status
  2674.           JNZ   emm_err_handler          ; jump to error handler on error
  2675.           MOV   un_alloc_pages,BX        ; save unallocated page count
  2676.           MOV   total_pages,DX           ; save total page count
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703.  
  2704.  
  2705.  
  2706.  
  2707.  
  2708.  
  2709.  
  2710.  
  2711.  
  2712.  
  2713.  
  2714.  
  2715.           EMM Functions                                                  41
  2716.  
  2717.  
  2718.  
  2719.  
  2720.  
  2721.           Function 4. Allocate Pages
  2722.  
  2723.  
  2724.  
  2725.                The Allocate Pages function allocates the number of pages
  2726.                requested and assigns a unique EMM handle to these pages. 
  2727.                The EMM handle owns these pages until the application
  2728.                deallocates them.
  2729.  
  2730.                Handles which are assigned using this function will have
  2731.                16K-byte pages, the size of a standard expanded memory page. 
  2732.                If the expanded memory board hardware isn't able to supply
  2733.                16K-byte pages, it will emulate them by combining multiple
  2734.                non-standard size pages to form a single 16K-byte page.  All
  2735.                application programs and functions that use the handles this
  2736.                function returns will deal with 16K-byte pages.
  2737.  
  2738.                The numeric value of the handles the EMM returns are in the
  2739.                range of 1 to 254 decimal (0001h to 00FEh).  The OS handle
  2740.                (handle value 0) is never returned by the Allocate Pages
  2741.                function.  Also, the uppermost byte of the handle will be
  2742.                zero and cannot be used by the application.  A memory
  2743.                manager should be able to supply up to 255 handles, includ-
  2744.                ing the OS handle.  An application can use Function 21 to
  2745.                find out how many handles an EMM supports.
  2746.  
  2747.                Allocating zero pages to a handle is not valid.  If an
  2748.                application needs to allocate 0 pages to a handle it should
  2749.                use Function 27 (Allocate Standard Pages subfunction)
  2750.                provided for this purpose.
  2751.  
  2752.           Note............................................................
  2753.                This note affects expanded memory manager implementors and
  2754.                operating system developers only.  Applications should not
  2755.                use the following characteristics of the memory manager.  An
  2756.                application violating this rule will be incompatible with
  2757.                future versions of Microsoft's operating systems and
  2758.                environments.
  2759.  
  2760.                To be compatible with this specification, an expanded memory
  2761.                manager will provide a special handle which is available to
  2762.                the operating system only.  This handle will have a value of
  2763.                0000h and will have a set of pages allocated to it when the
  2764.                expanded memory manager driver installs.  The pages that the
  2765.                memory manager will automatically allocate to handle 0000h
  2766.                are those that backfill conventional memory.  Typically,
  2767.                this backfill occurs between addresses 40000h (256K) and
  2768.                9FFFFh (640K).  However, the range can extend below and
  2769.                above this limit if the hardware and memory manager have the
  2770.                capability.
  2771.  
  2772.  
  2773.  
  2774.           EMM Functions                                                  42
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.           Function 4. Allocate Pages
  2781.  
  2782.  
  2783.  
  2784.                An operating system won't have to invoke Function 4 to
  2785.                obtain this handle because it can assume the handle already
  2786.                exists and is available for use immediately after the
  2787.                expanded memory device driver installs.  When an operating
  2788.                system wants to use this handle, it uses the special handle
  2789.                value of 0000h.  The operating system will be able to invoke
  2790.                any EMM function using this special handle value.  To
  2791.                allocate pages to this handle, the operating system need
  2792.                only invoke Function 18 (Reallocate Pages).
  2793.  
  2794.                There are two special cases for this handle:
  2795.  
  2796.                1.  Function 4 (Allocate Pages).  This function must never
  2797.                    return zero as a handle value.  Applications must always
  2798.                    invoke Function 4 to allocate pages and obtain a handle
  2799.                    which identifies the pages which belong to it.  Since
  2800.                    Function 4 never returns a handle value of zero, an
  2801.                    application will never gain access to this special
  2802.                    handle.
  2803.  
  2804.                2.  Function 6 (Deallocate Pages).  If the operating system
  2805.                    uses it to deallocate the pages which are allocated to
  2806.                    this special handle, the pages the handle owns will be
  2807.                    returned to the manager for use.  But the handle will
  2808.                    not be available for reassignment.  The manager should
  2809.                    treat a deallocate pages function request for this
  2810.                    handle the same as a reallocate pages function request,
  2811.                    where the number of pages to reallocate to this handle
  2812.                    is zero.
  2813.  
  2814.  
  2815.           CALLING PARAMETERS
  2816.  
  2817.                AH = 43h
  2818.                    Contains the Allocate Pages function.
  2819.  
  2820.                BX = num_of_pages_to_alloc
  2821.                    Contains the number of pages you want your program to
  2822.                    allocate.
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.           EMM Functions                                                  43
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.           Function 4. Allocate Pages
  2840.  
  2841.  
  2842.  
  2843.           RESULTS
  2844.  
  2845.                These results are valid only if the status returned is zero.
  2846.  
  2847.                DX = handle
  2848.                    Contains a unique EMM handle.  Your program must use
  2849.                    this EMM handle (as a parameter) in any function that
  2850.                    requires it.  You can use up to 255 handles.  The
  2851.                    uppermost byte of the handle will be zero and cannot be
  2852.                    used by the application.
  2853.  
  2854.  
  2855.           REGISTERS MODIFIED
  2856.  
  2857.                AX, DX
  2858.  
  2859.  
  2860.           STATUS
  2861.  
  2862.                AH = 0   SUCCESSFUL.
  2863.                    The manager has allocated the requested pages to the
  2864.                    assigned EMM handle.
  2865.  
  2866.                AH = 80h   NON-RECOVERABLE.
  2867.                    The manager detected a malfunction in the memory manager
  2868.                    software.
  2869.  
  2870.                AH = 81h   NON-RECOVERABLE.
  2871.                    The manager detected a malfunction in the expanded
  2872.                    memory hardware.
  2873.  
  2874.                AH = 84h   NON-RECOVERABLE.
  2875.                    The function code passed to the memory manager is not
  2876.                    defined.
  2877.  
  2878.                AH = 85h   RECOVERABLE.
  2879.                    All EMM handles are being used.
  2880.  
  2881.                AH = 87h   RECOVERABLE.
  2882.                    There aren't enough expanded memory pages present in the
  2883.                    system to satisfy your program's request.
  2884.  
  2885.                AH = 88h   RECOVERABLE.
  2886.                    There aren't enough unallocated pages to satisfy your
  2887.                    program's request.
  2888.  
  2889.                AH = 89h   RECOVERABLE.
  2890.                    Your program attempted to allocate zero pages.
  2891.  
  2892.           EMM Functions                                                  44
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.           Function 4. Allocate Pages
  2899.  
  2900.  
  2901.  
  2902.           EXAMPLE
  2903.  
  2904.           num_of_pages_to_alloc          DW ?
  2905.           emm_handle                     DW ?
  2906.  
  2907.           MOV   BX,num_of_pages_to_alloc ; load number of pages
  2908.           MOV   AH,43h                   ; load function code
  2909.           INT   67h                      ; call the memory manager
  2910.           OR    AH,AH                    ; check EMM status
  2911.           JNZ   emm_err_handler          ; jump to error handler on error
  2912.           MOV   emm_handle,DX            ; save EMM handle
  2913.  
  2914.  
  2915.  
  2916.  
  2917.  
  2918.  
  2919.  
  2920.  
  2921.  
  2922.  
  2923.  
  2924.  
  2925.  
  2926.  
  2927.  
  2928.  
  2929.  
  2930.  
  2931.  
  2932.  
  2933.  
  2934.  
  2935.  
  2936.  
  2937.  
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.  
  2944.  
  2945.  
  2946.  
  2947.  
  2948.  
  2949.  
  2950.  
  2951.           EMM Functions                                                  45
  2952.  
  2953.  
  2954.  
  2955.  
  2956.  
  2957.           Function 5. Map/Unmap Handle Pages
  2958.  
  2959.  
  2960.  
  2961.           PURPOSE
  2962.  
  2963.                The Map/Unmap Handle Page function maps a logical page at a
  2964.                specific physical page anywhere in the mappable regions of
  2965.                system memory.  The lowest valued physical page numbers are
  2966.                associated with regions of memory outside the conventional
  2967.                memory range.  Use Function 25 (Get Mappable Physical
  2968.                Address Array) to determine which physical pages within a
  2969.                system are mappable and determine the segment addresses
  2970.                which correspond to a specific physical page number. 
  2971.                Function 25 provides a cross reference between physical page
  2972.                numbers and segment addresses.
  2973.  
  2974.                This function can also unmap physical pages, making them
  2975.                inaccessible for reading or writing.  You unmap a physical
  2976.                page by setting its associated logical page to FFFFh.
  2977.  
  2978.                You might unmap an entire set of mapped pages, for example,
  2979.                before loading and executing a program.  Doing so ensures
  2980.                the loaded program, if it accesses expanded memory, won't
  2981.                access the pages your program has mapped.  However, you must
  2982.                save the mapped context before you unmap the physical pages. 
  2983.                This enables you to restore it later so you can access the
  2984.                memory you mapped there.  To save the mapping context, use
  2985.                Function 8, 15, or 16.  To restore the mapping context, use
  2986.                Function 9, 15, or 16.
  2987.  
  2988.                The handle determines what type of pages are being mapped. 
  2989.                Logical pages allocated by Function 4 and Function 27
  2990.                (Allocate Standard Pages subfunction) are referred to as
  2991.                pages and are 16K bytes long.  Logical pages allocated by
  2992.                Function 27 (Allocate Raw Pages subfunction) are referred to
  2993.                as raw pages and might not be the same size as logical
  2994.                pages.
  2995.  
  2996.  
  2997.           CALLING PARAMETERS
  2998.  
  2999.                AH = 44h
  3000.                    Contains the Map Handle Page function.
  3001.  
  3002.                AL = physical_page_number
  3003.                    Contains the number of the physical page into which the
  3004.                    logical page number is to be mapped.  Physical pages are
  3005.                    numbered zero-relative.
  3006.  
  3007.  
  3008.  
  3009.  
  3010.           EMM Functions                                                  46
  3011.  
  3012.  
  3013.  
  3014.  
  3015.  
  3016.           Function 5. Map/Unmap Handle Pages
  3017.  
  3018.  
  3019.  
  3020.                BX = logical_page_number
  3021.                    Contains the number of the logical page to be mapped at
  3022.                    the physical page within the page frame.  Logical pages
  3023.                    are numbered zero-relative.  The logical page must be in
  3024.                    the range zero through (number of pages allocated to the
  3025.                    EMM handle - 1).  However, if BX contains logical page
  3026.                    number FFFFh, the physical page specified in AL will be
  3027.                    unmapped (be made inaccessible for reading or writing).
  3028.  
  3029.                DX = emm_handle
  3030.                    Contains the EMM handle your program received from
  3031.                    Function 4 (Allocate Pages).
  3032.  
  3033.  
  3034.           REGISTERS MODIFIED
  3035.  
  3036.                AX
  3037.  
  3038.  
  3039.           STATUS
  3040.  
  3041.                AH = 0   SUCCESSFUL.
  3042.                    The manager has mapped the page.  The page is ready to
  3043.                    be accessed.
  3044.  
  3045.                AH = 80h   NON-RECOVERABLE.
  3046.                    The manager detected a malfunction in the memory manager
  3047.                    software.
  3048.  
  3049.                AH = 81h   NON-RECOVERABLE.
  3050.                    The manager detected a malfunction in the expanded
  3051.                    memory hardware.
  3052.  
  3053.                AH = 83h   NON-RECOVERABLE.
  3054.                    The memory manager couldn't find the EMM handle your
  3055.                    program specified.
  3056.  
  3057.                AH = 84h   NON-RECOVERABLE.
  3058.                    The function code passed to the memory manager isn't
  3059.                    defined.
  3060.  
  3061.                AH = 8Ah   RECOVERABLE.
  3062.                    The logical page is out of the range of logical pages
  3063.                    which are allocated to the EMM handle.  This status is
  3064.                    also returned if a program attempts to map a logical
  3065.                    page when no logical pages are allocated to the handle.
  3066.  
  3067.  
  3068.  
  3069.           EMM Functions                                                  47
  3070.  
  3071.  
  3072.  
  3073.  
  3074.  
  3075.           Function 5. Map/Unmap Handle Pages
  3076.  
  3077.  
  3078.  
  3079.                AH = 8Bh   RECOVERABLE.
  3080.                    The physical page number is out of the range of allow-
  3081.                    able physical pages.  The program can recover by
  3082.                    attempting to map into memory at a physical page which
  3083.                    is within the range of allowable physical pages.
  3084.  
  3085.  
  3086.           EXAMPLE
  3087.  
  3088.           emm_handle                     DW ?
  3089.           logical_page_number            DW ?
  3090.           physical_page_number           DB ?
  3091.  
  3092.           MOV   DX,emm_handle            ; load EMM handle
  3093.           MOV   BX,logical_page_number   ; load logical page number
  3094.           MOV   AL,physical_page_number  ; load physical page number
  3095.           MOV   AH,44h                   ; load function code
  3096.           INT   67h                      ; call the memory manager
  3097.           OR    AH,AH                    ; check EMM status
  3098.           JNZ   emm_err_handler          ; jump to error handler on error
  3099.  
  3100.  
  3101.  
  3102.  
  3103.  
  3104.  
  3105.  
  3106.  
  3107.  
  3108.  
  3109.  
  3110.  
  3111.  
  3112.  
  3113.  
  3114.  
  3115.  
  3116.  
  3117.  
  3118.  
  3119.  
  3120.  
  3121.  
  3122.  
  3123.  
  3124.  
  3125.  
  3126.  
  3127.  
  3128.           EMM Functions                                                  48
  3129.  
  3130.  
  3131.  
  3132.  
  3133.  
  3134.           Function 6. Deallocate Pages
  3135.  
  3136.  
  3137.  
  3138.           PURPOSE
  3139.  
  3140.                Deallocate Pages deallocates the logical pages currently
  3141.                allocated to an EMM handle.  Only after the application
  3142.                deallocates these pages can other applications use them. 
  3143.                When a handle is deallocated, its name is set to all ASCII
  3144.                nulls (binary zeros).
  3145.  
  3146.           Note............................................................
  3147.                A program must perform this function before it exits to DOS. 
  3148.                If it doesn't, no other programs can use these pages or the
  3149.                EMM handle.  This means that a program using expanded memory
  3150.                should trap critical errors and control-break if there is a
  3151.                chance that the program will have allocated pages when
  3152.                either of these events occur.
  3153.  
  3154.  
  3155.           CALLING PARAMETERS
  3156.  
  3157.                AH = 45h
  3158.                    Contains the Deallocate Pages function.
  3159.  
  3160.                DX = handle
  3161.                    Contains the EMM handle returned by Function 4 (Allocate
  3162.                    Pages).
  3163.  
  3164.  
  3165.           REGISTERS MODIFIED
  3166.  
  3167.                AX
  3168.  
  3169.  
  3170.           STATUS
  3171.  
  3172.                AH = 0   SUCCESSFUL.
  3173.                    The manager has deallocated the pages previously allo-
  3174.                    cated to the EMM handle.
  3175.  
  3176.                AH = 80h   NON-RECOVERABLE.
  3177.                    The manager detected a malfunction in the memory manager
  3178.                    software.
  3179.  
  3180.                AH = 81h   NON-RECOVERABLE.
  3181.                    The manager detected a malfunction in the expanded
  3182.                    memory hardware.
  3183.  
  3184.                AH = 83h   NON-RECOVERABLE.
  3185.                    The manager couldn't find the specified EMM handle.
  3186.  
  3187.           EMM Functions                                                  49
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.           Function 6. Deallocate Pages
  3194.  
  3195.  
  3196.  
  3197.                AH = 84h   NON-RECOVERABLE.
  3198.                    The function code passed to the memory manager is not
  3199.                    defined.
  3200.  
  3201.                AH = 86h   RECOVERABLE.
  3202.                    The memory manager detected a save or restore page
  3203.                    mapping context error (Function 8 or 9).  There is a
  3204.                    page mapping register state in the save area for the
  3205.                    specified EMM handle.  Save Page Map (Function 8) placed
  3206.                    it there and a subsequent Restore Page Map (Function 9)
  3207.                    has not removed it.
  3208.  
  3209.                    If you have saved the mapping context, you must restore
  3210.                    it before you deallocate the EMM handle's pages.
  3211.  
  3212.  
  3213.           EXAMPLE
  3214.  
  3215.           emm_handle                     DW ?
  3216.  
  3217.           MOV   DX,emm_handle            ; load EMM handle
  3218.           MOV   AH,45h                   ; load function code
  3219.           INT   67h                      ; call the memory manager
  3220.           OR    AH,AH                    ; check EMM status
  3221.           JNZ   emm_err_handler          ; jump to error handler on error
  3222.  
  3223.  
  3224.  
  3225.  
  3226.  
  3227.  
  3228.  
  3229.  
  3230.  
  3231.  
  3232.  
  3233.  
  3234.  
  3235.  
  3236.  
  3237.  
  3238.  
  3239.  
  3240.  
  3241.  
  3242.  
  3243.  
  3244.  
  3245.  
  3246.           EMM Functions                                                  50
  3247.  
  3248.  
  3249.  
  3250.  
  3251.  
  3252.           Function 7. Get Version
  3253.  
  3254.  
  3255.  
  3256.           PURPOSE
  3257.  
  3258.                The Get Version function returns the version number of the
  3259.                memory manager software.
  3260.  
  3261.  
  3262.           CALLING PARAMETERS
  3263.  
  3264.                AH = 46h
  3265.                    Contains the Get Version function.
  3266.  
  3267.  
  3268.           RESULTS
  3269.  
  3270.                These results are valid only if the status returned is zero.
  3271.  
  3272.                AL = version number
  3273.                    Contains the memory manager's version number in binary
  3274.                    coded decimal (BCD) format.  The upper four bits contain
  3275.                    the integer digit of the version number.  The lower four
  3276.                    bits contain the fractional digit of version number. 
  3277.                    For example, version 4.0 is represented like this:
  3278.  
  3279.                                       0100 0000
  3280.                                         /   \
  3281.                                        4  .  0
  3282.  
  3283.                    When checking for a version number, an application
  3284.                    should check for a version number or greater.  Vendors
  3285.                    may use the fractional digit to indicate enhancements or
  3286.                    corrections to their memory managers.  Therefore, to
  3287.                    allow for future versions of memory managers, an
  3288.                    application shouldn't depend on an exact version number.
  3289.  
  3290.  
  3291.           REGISTERS MODIFIED
  3292.  
  3293.                AX
  3294.  
  3295.  
  3296.           STATUS
  3297.  
  3298.                AH = 0   SUCCESSFUL.
  3299.                    The manager is present in the system and the hardware is
  3300.                    working correctly.
  3301.  
  3302.  
  3303.  
  3304.  
  3305.           EMM Functions                                                  51
  3306.  
  3307.  
  3308.  
  3309.  
  3310.  
  3311.           Function 7. Get Version
  3312.  
  3313.  
  3314.  
  3315.                AH = 80h   NON-RECOVERABLE.
  3316.                    The manager detected a malfunction in the memory manager
  3317.                    software.
  3318.  
  3319.                AH = 81h   NON-RECOVERABLE.
  3320.                    The manager detected a malfunction in the expanded
  3321.                    memory hardware.
  3322.  
  3323.                AH = 84h   NON-RECOVERABLE.
  3324.                    The function code passed to the memory manager is not
  3325.                    defined.
  3326.  
  3327.  
  3328.           EXAMPLE
  3329.  
  3330.           emm_version                    DB ?
  3331.  
  3332.           MOV   AH,46h                   ; load function code
  3333.           INT   67h                      ; call the memory manager
  3334.           OR    AH,AH                    ; check EMM status
  3335.           JNZ   emm_err_handler          ; jump to error handler on error
  3336.           MOV   emm_version,AL           ; save version number
  3337.  
  3338.  
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344.  
  3345.  
  3346.  
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.  
  3359.  
  3360.  
  3361.  
  3362.  
  3363.  
  3364.           EMM Functions                                                  52
  3365.  
  3366.  
  3367.  
  3368.  
  3369.  
  3370.           Function 8. Save Page Map
  3371.  
  3372.  
  3373.  
  3374.           PURPOSE
  3375.  
  3376.                Save Page Map saves the contents of the page mapping
  3377.                registers on all expanded memory boards in an internal save
  3378.                area.  The function is typically used to save the memory
  3379.                mapping context of the EMM handle that was active when a
  3380.                software or hardware interrupt occurred.  (See Function 9,
  3381.                Restore Page Map, for the restore operation.)
  3382.  
  3383.                If you're writing a resident program, an interrupt service
  3384.                routine, or a device driver that uses expanded memory, you
  3385.                must save the state of the mapping hardware.  You must save
  3386.                this state because application software using expanded
  3387.                memory may be running when your program is invoked by a
  3388.                hardware interrupt, a software interrupt, or DOS.
  3389.  
  3390.                The Save Page Map function requires the EMM handle that was
  3391.                assigned to your resident program, interrupt service
  3392.                routine, or device driver at the time it was initialized. 
  3393.                This is not the EMM handle that the application software was
  3394.                using when your software interrupted it.
  3395.  
  3396.                The Save Page Map function saves the state of the map
  3397.                registers for only the 64K-byte page frame defined in
  3398.                versions 3.x of this specification.  Since all applications
  3399.                written to LIM versions 3.x require saving the map register
  3400.                state of only this 64K-byte page frame, saving the entire
  3401.                mapping state for a large number of mappable pages would be
  3402.                inefficient use of memory.  Applications that use a mappable
  3403.                memory region outside the LIM 3.x page frame should use
  3404.                Function 15 or 16 to save and restore the state of the map
  3405.                registers.
  3406.  
  3407.  
  3408.           CALLING PARAMETERS
  3409.  
  3410.                AH = 47h
  3411.                    Contains the Save Page Map function.
  3412.  
  3413.                DX = handle
  3414.                    Contains the EMM handle assigned to the interrupt
  3415.                    service routine that's servicing the software or
  3416.                    hardware interrupt.  The interrupt service routine needs
  3417.                    to save the state of the page mapping hardware before
  3418.                    mapping any pages.
  3419.  
  3420.  
  3421.  
  3422.  
  3423.           EMM Functions                                                  53
  3424.  
  3425.  
  3426.  
  3427.  
  3428.  
  3429.           Function 8. Save Page Map
  3430.  
  3431.  
  3432.  
  3433.           REGISTERS MODIFIED
  3434.  
  3435.                AX
  3436.  
  3437.  
  3438.           STATUS
  3439.  
  3440.                AH = 0   SUCCESSFUL.
  3441.                    The manager has saved the state of the page mapping
  3442.                    hardware.
  3443.  
  3444.                AH = 80h   NON-RECOVERABLE.
  3445.                    The manager detected a malfunction in the memory manager
  3446.                    software.
  3447.  
  3448.                AH = 81h   NON-RECOVERABLE.
  3449.                    The manager detected a malfunction in the expanded
  3450.                    memory hardware.
  3451.  
  3452.                AH = 83h   NON-RECOVERABLE.
  3453.                    The memory manager couldn't find the EMM handle your
  3454.                    program specified.
  3455.  
  3456.                AH = 84h   NON-RECOVERABLE.
  3457.                    The function code passed to the memory manager is not
  3458.                    defined.
  3459.  
  3460.                AH = 8Ch   NON-RECOVERABLE.
  3461.                    There is no room in the save area to store the state of
  3462.                    the page mapping registers.  The state of the map
  3463.                    registers has not been saved.
  3464.  
  3465.                AH = 8Dh   CONDITIONALLY-RECOVERABLE.
  3466.                    The save area already contains the page mapping register
  3467.                    state for the EMM handle your program specified.
  3468.  
  3469.  
  3470.           EXAMPLE
  3471.  
  3472.           emm_handle                     DW ?
  3473.  
  3474.           MOV   DX,emm_handle            ; load EMM handle
  3475.           MOV   AH,47h                   ; load function code
  3476.           INT   67h                      ; call the memory manager
  3477.           OR    AH,AH                    ; check EMM status
  3478.           JNZ   emm_err_handler          ; jump to error handler on error
  3479.  
  3480.  
  3481.  
  3482.           EMM Functions                                                  54
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.           Function 9. Restore Page Map
  3489.  
  3490.  
  3491.  
  3492.           PURPOSE
  3493.  
  3494.                The Restore Page Map function restores the page mapping
  3495.                register contents on the expanded memory boards for a
  3496.                particular EMM handle.  This function lets your program
  3497.                restore the contents of the mapping registers its EMM handle
  3498.                saved.  (See Function 8, Save Page Map for the save opera-
  3499.                tion.)
  3500.  
  3501.                If you're writing a resident program, an interrupt service
  3502.                routine, or a device driver that uses expanded memory, you
  3503.                must restore the mapping hardware to the state it was in
  3504.                before your program took over.  You must save this state
  3505.                because application software using expanded memory might
  3506.                have been running when your program was invoked.
  3507.  
  3508.                The Restore Page Map function requires the EMM handle that
  3509.                was assigned to your resident program, interrupt service
  3510.                routine, or device driver at the time it was initialized. 
  3511.                This is not the EMM handle that the application software was
  3512.                using when your software interrupted it.
  3513.  
  3514.                The Restore Page Map function restores the state of the map
  3515.                registers for only the 64K-byte page frame defined in
  3516.                versions 3.x of this specification.  Since all applications
  3517.                written to LIM versions 3.x require restoring the map
  3518.                register state of only this 64K-byte page frame, restoring
  3519.                the entire mapping state for a large number of mappable
  3520.                pages would be inefficient use of memory.  Applications that
  3521.                use a mappable memory region outside the LIM 3.x page frame
  3522.                should use Function 15 or 16 to save and restore the state
  3523.                of the map registers.
  3524.  
  3525.  
  3526.           CALLING PARAMETERS
  3527.  
  3528.                AH = 48h
  3529.                    Contains the Restore Page Map function.
  3530.  
  3531.                DX = emm_handle
  3532.                    Contains the EMM handle assigned to the interrupt
  3533.                    service routine that's servicing the software or
  3534.                    hardware interrupt.  The interrupt service routine needs
  3535.                    to restore the state of the page mapping hardware.
  3536.  
  3537.  
  3538.  
  3539.  
  3540.  
  3541.           EMM Functions                                                  55
  3542.  
  3543.  
  3544.  
  3545.  
  3546.  
  3547.           Function 9. Restore Page Map
  3548.  
  3549.  
  3550.  
  3551.           REGISTERS MODIFIED
  3552.  
  3553.                AX
  3554.  
  3555.  
  3556.           STATUS
  3557.  
  3558.                AH = 0   SUCCESSFUL.
  3559.                    The manager has restored the state of the page mapping
  3560.                    registers.
  3561.  
  3562.                AH = 80h   NON-RECOVERABLE.
  3563.                    The manager detected a malfunction in the memory manager
  3564.                    software.
  3565.  
  3566.                AH = 81h   NON-RECOVERABLE.
  3567.                    The manager detected a malfunction in the expanded
  3568.                    memory hardware.
  3569.  
  3570.                AH = 83h   NON-RECOVERABLE.
  3571.                    The memory manager couldn't find the EMM handle your
  3572.                    program specified.
  3573.  
  3574.                AH = 84h   NON-RECOVERABLE.
  3575.                    The function code passed to the memory manager is not
  3576.                    defined.
  3577.  
  3578.                AH = 8Eh   CONDITIONALLY-RECOVERABLE.
  3579.                    There is no page mapping register state in the save area
  3580.                    for the specified EMM handle.  Your program didn't save
  3581.                    the contents of the page mapping hardware, so Restore
  3582.                    Page can't restore it.
  3583.  
  3584.  
  3585.           EXAMPLE
  3586.  
  3587.           emm_handle                     DW ?
  3588.  
  3589.           MOV   DX,emm_handle            ; load EMM handle
  3590.           MOV   AH,48h                   ; load function code
  3591.           INT   67h                      ; call the memory manager
  3592.           OR    AH,AH                    ; check EMM status
  3593.           JNZ   emm_err_handler          ; jump to error handler on error
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.           EMM Functions                                                  56
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.           Function 10. Reserved
  3607.  
  3608.  
  3609.  
  3610.                In earlier versions of the Lotus/Intel/Microsoft Expanded
  3611.                Memory Specification, Function 10 returned the page mapping
  3612.                register I/O array.  This function is now reserved and new
  3613.                programs should not use it.
  3614.  
  3615.                Existing programs that use this function may still work
  3616.                correctly if the hardware is capable of supporting them. 
  3617.                However, programs that use Functions 16 through 30 in
  3618.                Version 4.0 of this specification must not use Functions 10
  3619.                and 11.  These functions won't work correctly if your
  3620.                program attempts to mix the use of the new functions
  3621.                (Functions 16 through 30) and Functions 10 and 11.  Func-
  3622.                tions 10 and 11 are specific to the hardware on Intel
  3623.                expanded memory boards and will not work correctly on all
  3624.                vendors' expanded memory boards.
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.  
  3639.  
  3640.  
  3641.  
  3642.  
  3643.  
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.  
  3658.  
  3659.           EMM Functions                                                  57
  3660.  
  3661.  
  3662.  
  3663.  
  3664.  
  3665.           Function 11. Reserved
  3666.  
  3667.  
  3668.  
  3669.                In earlier versions of the Lotus/Intel/Microsoft Expanded
  3670.                Memory Specification, Function 11 returned a page transla-
  3671.                tion array.  This function is now reserved and new programs
  3672.                should not use it.
  3673.  
  3674.                Existing programs that use this function may still work
  3675.                correctly if the hardware is capable of supporting them. 
  3676.                However, programs that use Functions 16 through 30 in
  3677.                Version 4.0 of this specification must not use Functions 10
  3678.                and 11.  These functions won't work correctly if your
  3679.                program attempts to mix the use of the new functions
  3680.                (Functions 16 through 30) and Functions 10 and 11.  Func-
  3681.                tions 10 and 11 are specific to the hardware on Intel
  3682.                expanded memory boards and will not work correctly on all
  3683.                vendors' expanded memory boards.
  3684.  
  3685.  
  3686.  
  3687.  
  3688.  
  3689.  
  3690.  
  3691.  
  3692.  
  3693.  
  3694.  
  3695.  
  3696.  
  3697.  
  3698.  
  3699.  
  3700.  
  3701.  
  3702.  
  3703.  
  3704.  
  3705.  
  3706.  
  3707.  
  3708.  
  3709.  
  3710.  
  3711.  
  3712.  
  3713.  
  3714.  
  3715.  
  3716.  
  3717.  
  3718.           EMM Functions                                                  58
  3719.  
  3720.  
  3721.  
  3722.  
  3723.  
  3724.           Function 12. Get Handle Count
  3725.  
  3726.  
  3727.  
  3728.           PURPOSE
  3729.  
  3730.                The Get Handle Count function returns the number of open EMM
  3731.                handles (including the operating system handle 0) in the
  3732.                system.
  3733.  
  3734.  
  3735.           CALLING PARAMETERS
  3736.  
  3737.                AH = 4Bh
  3738.                    Contains the Get Handle Count function.
  3739.  
  3740.  
  3741.           RESULTS
  3742.  
  3743.                These results are valid only if the status returned is zero.
  3744.  
  3745.                BX = total_open_emm_handles
  3746.                    Contains the number of open EMM handles [including the
  3747.                    operating system handle (0)].  This number will not
  3748.                    exceed 255.
  3749.  
  3750.  
  3751.           REGISTERS MODIFIED
  3752.  
  3753.                AX, BX
  3754.  
  3755.  
  3756.           STATUS
  3757.  
  3758.                AH = 0   SUCCESSFUL.
  3759.                    The manager has returned the number of active EMM
  3760.                    handles.
  3761.  
  3762.                AH = 80h   NON-RECOVERABLE.
  3763.                    The manager detected a malfunction in the memory manager
  3764.                    software.
  3765.  
  3766.                AH = 81h   NON-RECOVERABLE.
  3767.                    The manager detected a malfunction in the expanded
  3768.                    memory hardware.
  3769.  
  3770.                AH = 84h   NON-RECOVERABLE.
  3771.                    The function code passed to the memory manager is not
  3772.                    defined.
  3773.  
  3774.  
  3775.  
  3776.  
  3777.           EMM Functions                                                  59
  3778.  
  3779.  
  3780.  
  3781.  
  3782.  
  3783.           Function 12. Get Handle Count
  3784.  
  3785.  
  3786.  
  3787.           EXAMPLE
  3788.  
  3789.           total_open_emm_handles              DW ?
  3790.  
  3791.           MOV   AH,4Bh                        ; load function code
  3792.           INT   67h                           ; call the memory manger
  3793.           OR    AH,AH                         ; check EMM status
  3794.           JNZ   emm_err_handler               ; jump to error handler on   
  3795.                                               ; error
  3796.           MOV   total_open_emm_handles,BX     ; save total active handle   
  3797.                                               ; count
  3798.  
  3799.  
  3800.  
  3801.  
  3802.  
  3803.  
  3804.  
  3805.  
  3806.  
  3807.  
  3808.  
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.  
  3828.  
  3829.  
  3830.  
  3831.  
  3832.  
  3833.  
  3834.  
  3835.  
  3836.           EMM Functions                                                  60
  3837.  
  3838.  
  3839.  
  3840.  
  3841.  
  3842.           Function 13. Get Handle Pages
  3843.  
  3844.  
  3845.  
  3846.           PURPOSE
  3847.  
  3848.                The Get Handle Pages function returns the number of pages
  3849.                allocated to a specific EMM handle.
  3850.  
  3851.  
  3852.           CALLING PARAMETERS
  3853.  
  3854.                AH = 4Ch
  3855.                    Contains the Get Handle Pages function.
  3856.  
  3857.                DX = emm_handle
  3858.                    Contains the EMM handle.
  3859.  
  3860.  
  3861.           RESULTS
  3862.  
  3863.                These results are valid only if the status returned is zero.
  3864.  
  3865.                BX = num_pages_alloc_to_emm_handle
  3866.                    Contains the number of logical pages allocated to the
  3867.                    specified EMM handle.  This number never exceeds 2048
  3868.                    because the memory manager allows a maximum of 2048
  3869.                    pages (32M bytes) of expanded memory.
  3870.  
  3871.  
  3872.           REGISTERS MODIFIED
  3873.  
  3874.                AX, BX
  3875.  
  3876.  
  3877.           STATUS
  3878.  
  3879.                AH = 0   SUCCESSFUL.
  3880.                    The manager has returned the number of pages allocated
  3881.                    to the EMM handle.
  3882.  
  3883.                AH = 80h   NON-RECOVERABLE.
  3884.                    The manager detected a malfunction in the memory manager
  3885.                    software.
  3886.  
  3887.                AH = 81h   NON-RECOVERABLE.
  3888.                    The manager detected a malfunction in the expanded
  3889.                    memory hardware.
  3890.  
  3891.                AH = 83h   NON-RECOVERABLE.
  3892.                    The memory manager couldn't find the EMM handle your
  3893.                    program specified.
  3894.  
  3895.           EMM Functions                                                  61
  3896.  
  3897.  
  3898.  
  3899.  
  3900.  
  3901.           Function 13. Get Handle Pages
  3902.  
  3903.  
  3904.  
  3905.                AH = 84h   NON-RECOVERABLE.
  3906.                    The function code passed to the memory manager is not
  3907.                    defined.
  3908.  
  3909.  
  3910.           EXAMPLE
  3911.  
  3912.           emm_handle                          DW ?
  3913.           pages_alloc_to_handle               DW ?
  3914.  
  3915.           MOV   DX,emm_handle                 ; load EMM handle
  3916.           MOV   AH,4Ch                        ; load function code
  3917.           INT   67h                           ; call the memory manager
  3918.           OR    AH,AH                         ; check EMM status
  3919.           JNZ   emm_err_handler               ; jump to error handler on   
  3920.                                               ; error
  3921.           MOV   pages_alloc_to_handle,BX      ; save number of pages       
  3922.                                               ; allocated to specified     
  3923.                                               ; handle
  3924.  
  3925.  
  3926.  
  3927.  
  3928.  
  3929.  
  3930.  
  3931.  
  3932.  
  3933.  
  3934.  
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944.  
  3945.  
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952.  
  3953.  
  3954.           EMM Functions                                                  62
  3955.  
  3956.  
  3957.  
  3958.  
  3959.  
  3960.           Function 14. Get All Handle Pages
  3961.  
  3962.  
  3963.  
  3964.           PURPOSE
  3965.  
  3966.                The Get All Handle Pages function returns an array of the
  3967.                open EMM handles and the number of pages allocated to each
  3968.                one.
  3969.  
  3970.  
  3971.           CALLING PARAMETERS
  3972.  
  3973.                AH = 4Dh
  3974.                    Contains the Get All Handle Pages function.
  3975.  
  3976.                    handle_page_struct              STRUC
  3977.                        emm_handle                  DW ?
  3978.                        pages_alloc_to_handle       DW ?
  3979.                    handle_page_struct              ENDS
  3980.  
  3981.                ES:DI = pointer to handle_page
  3982.                    Contains a pointer to an array of structures where a
  3983.                    copy of all open EMM handles and the number of pages
  3984.                    allocated to each will be stored.  Each structure has
  3985.                    these two members:
  3986.  
  3987.                    .emm_handle
  3988.                        The first member is a word which contains the value
  3989.                        of the open EMM handle.  The values of the handles
  3990.                        this function returns will be in the range of 0 to
  3991.                        255 decimal (0000h to 00FFh).  The uppermost byte of
  3992.                        the handle is always zero.
  3993.  
  3994.                    .pages_alloc_to_handle
  3995.                        The second member is a word which contains the
  3996.                        number of pages allocated to the open EMM handle.
  3997.  
  3998.  
  3999.           RESULTS
  4000.  
  4001.                These results are valid only if the status returned is zero.
  4002.  
  4003.                BX = total_open_emm_handles
  4004.                    Contains the number of open EMM handles (including the
  4005.                    operating system handle [0]).  The number cannot be zero
  4006.                    because the operating system handle is always active and
  4007.                    cannot be deallocated.  This number will not exceed 255.
  4008.  
  4009.  
  4010.  
  4011.  
  4012.  
  4013.           EMM Functions                                                  63
  4014.  
  4015.  
  4016.  
  4017.  
  4018.  
  4019.           Function 14. Get All Handle Pages
  4020.  
  4021.  
  4022.  
  4023.           REGISTERS MODIFIED
  4024.  
  4025.                AX, BX
  4026.  
  4027.  
  4028.           STATUS
  4029.  
  4030.                AH = 0   SUCCESSFUL.
  4031.                    The manager has returned the array.
  4032.  
  4033.                AH = 80h   NON-RECOVERABLE.
  4034.                    The manager detected a malfunction in the memory manager
  4035.                    software.
  4036.  
  4037.                AH = 81h   NON-RECOVERABLE.
  4038.                    The manager detected a malfunction in the expanded
  4039.                    memory hardware.
  4040.  
  4041.                AH = 84h   NON-RECOVERABLE.
  4042.                    The function code passed to the memory manager is not
  4043.                    defined.
  4044.  
  4045.  
  4046.           EXAMPLE
  4047.  
  4048.           handle_page                    handle_page_struct 255 DUP (?)
  4049.           total_open_handles             DW ?
  4050.  
  4051.           MOV   AX,SEG handle_page
  4052.           MOV   ES,AX
  4053.           LEA   DI,handle_page           ; ES:DI points to handle_page
  4054.           MOV   AH,4Dh                   ; load function code
  4055.           INT   67h                      ; call the memory manager
  4056.           OR    AH,AH                    ; check the EMM status
  4057.           JNZ   emm_err_handler          ; jump to error handler on error
  4058.           MOV   total_open_handles,BX    ; save total open handle count
  4059.  
  4060.  
  4061.  
  4062.  
  4063.  
  4064.  
  4065.  
  4066.  
  4067.  
  4068.  
  4069.  
  4070.  
  4071.  
  4072.           EMM Functions                                                  64
  4073.  
  4074.  
  4075.  
  4076.  
  4077.  
  4078.           Function 15. Get/Set Page Map
  4079.           Get Page Map subfunction
  4080.  
  4081.  
  4082.  
  4083.           PURPOSE
  4084.  
  4085.                The Get Page Map subfunction saves the mapping context for
  4086.                all mappable memory regions (conventional and expanded) by
  4087.                copying the contents of the mapping registers from each
  4088.                expanded memory board to a destination array.  The applica-
  4089.                tion must pass a pointer to the destination array.  This
  4090.                subfunction doesn't require an EMM handle.
  4091.  
  4092.                Use this function instead of Functions 8 and 9 if you need
  4093.                to save or restore the mapping context but don't want (or
  4094.                have) to use a handle.
  4095.  
  4096.  
  4097.           CALLING PARAMETERS
  4098.  
  4099.                AX = 4E00h
  4100.                    Contains the Get Page Map subfunction.
  4101.  
  4102.                ES:DI = dest_page_map
  4103.                    Contains a pointer to the destination array address in
  4104.                    segment:offset format.  Use the Get Size of Page Map
  4105.                    Save Array subfunction to determine the size of the
  4106.                    desired array.
  4107.  
  4108.  
  4109.           RESULTS
  4110.  
  4111.                These results are valid only if the status returned is zero.
  4112.  
  4113.                dest_page_map
  4114.                    The array contains the state of all the mapping regis-
  4115.                    ters on all boards in the system.  It also contains any
  4116.                    additional information necessary to restore the boards
  4117.                    to their original state when the program invokes a Set
  4118.                    subfunction.
  4119.  
  4120.  
  4121.           REGISTERS MODIFIED
  4122.  
  4123.                AX
  4124.  
  4125.  
  4126.           STATUS
  4127.  
  4128.                AH = 0   SUCCESSFUL.
  4129.                    The manager has returned the array.
  4130.  
  4131.           EMM Functions                                                  65
  4132.  
  4133.  
  4134.  
  4135.  
  4136.  
  4137.           Function 15. Get/Set Page Map
  4138.           Get Page Map subfunction
  4139.  
  4140.  
  4141.  
  4142.                AH = 80h   NON-RECOVERABLE.
  4143.                    The manager detected a malfunction in the memory manager
  4144.                    software.
  4145.  
  4146.                AH = 81h   NON-RECOVERABLE.
  4147.                    The manager detected a malfunction in the expanded
  4148.                    memory hardware.
  4149.  
  4150.                AH = 84h   NON-RECOVERABLE.
  4151.                    The function code passed to the memory manager is not
  4152.                    defined.
  4153.  
  4154.                AH = 8Fh   NON-RECOVERABLE.
  4155.                    The subfunction parameter is invalid.
  4156.  
  4157.  
  4158.           EXAMPLE
  4159.  
  4160.           dest_page_map                  DB ? DUP (?)
  4161.  
  4162.           MOV   AX,SEG dest_page_map
  4163.           MOV   ES,AX
  4164.           LEA   DI,dest_page_map         ; ES:DI points to dest_page_map
  4165.           MOV   AX,4E00h                 ; load function code
  4166.           INT   67h                      ; call the memory manager
  4167.           OR    AH,AH                    ; check EMM status
  4168.           JNZ   emm_err_handler          ; jump to error handler on error
  4169.  
  4170.  
  4171.  
  4172.  
  4173.  
  4174.  
  4175.  
  4176.  
  4177.  
  4178.  
  4179.  
  4180.  
  4181.  
  4182.  
  4183.  
  4184.  
  4185.  
  4186.  
  4187.  
  4188.  
  4189.  
  4190.           EMM Functions                                                  66
  4191.  
  4192.  
  4193.  
  4194.  
  4195.  
  4196.           Function 15. Get/Set Page Map
  4197.           Set Page Map subfunction
  4198.  
  4199.  
  4200.  
  4201.           PURPOSE
  4202.  
  4203.                The Set Page Map subfunction restores the mapping context
  4204.                for all mappable memory regions (conventional and expanded)
  4205.                by copying the contents of a source array into the mapping
  4206.                registers on each expanded memory board in the system.  The
  4207.                application must pass a pointer to the source array.  This
  4208.                subfunction doesn't require an EMM handle.
  4209.  
  4210.                Use this function instead of Functions 8 and 9 if you need
  4211.                to save or restore the mapping context but don't want (or
  4212.                have) to use a handle.
  4213.  
  4214.  
  4215.           CALLING PARAMETERS
  4216.  
  4217.                AX = 4E01h
  4218.                    Contains the Set Page Map subfunction.
  4219.  
  4220.                DS:SI = source_page_map
  4221.                    Contains a pointer to the source array address in
  4222.                    segment:offset format.  The application must point to an
  4223.                    array which contains the mapping register state.  Use
  4224.                    the Get Size of Page Map Save Array subfunction to
  4225.                    determine the size of the desired array.
  4226.  
  4227.  
  4228.           REGISTERS MODIFIED
  4229.  
  4230.                AX
  4231.  
  4232.  
  4233.           STATUS
  4234.  
  4235.                AH = 0   SUCCESSFUL.
  4236.                    The manager has passed the array.
  4237.  
  4238.                AH = 80h   NON-RECOVERABLE.
  4239.                    The manager detected a malfunction in the memory manager
  4240.                    software.
  4241.  
  4242.                AH = 81h   NON-RECOVERABLE.
  4243.                    The manager detected a malfunction in the expanded
  4244.                    memory hardware.
  4245.  
  4246.  
  4247.  
  4248.  
  4249.           EMM Functions                                                  67
  4250.  
  4251.  
  4252.  
  4253.  
  4254.  
  4255.           Function 15. Get/Set Page Map
  4256.           Set Page Map subfunction
  4257.  
  4258.  
  4259.  
  4260.                AH = 84h   NON-RECOVERABLE.
  4261.                    The function code passed to the memory manager is not
  4262.                    defined.
  4263.  
  4264.                AH = 8Fh   NON-RECOVERABLE.
  4265.                    The subfunction parameter is invalid.
  4266.  
  4267.                AH = A3h   NON-RECOVERABLE.
  4268.                    The contents of the source array have been corrupted, or
  4269.                    the pointer passed to the subfunction is invalid.
  4270.  
  4271.  
  4272.           EXAMPLE
  4273.  
  4274.           source_page_map                DB ? DUP (?)
  4275.  
  4276.           MOV   AX,SEG source_page_map
  4277.           MOV   DS,AX
  4278.           LEA   SI,source_page_map       ; DS:SI points to source_page_map
  4279.           MOV   AX,4E01h                 ; load function code
  4280.           INT   67h                      ; call the memory manager
  4281.           OR    AH,AH                    ; check EMM status
  4282.           JNZ   emm_err_handler          ; jump to error handler on error
  4283.  
  4284.  
  4285.  
  4286.  
  4287.  
  4288.  
  4289.  
  4290.  
  4291.  
  4292.  
  4293.  
  4294.  
  4295.  
  4296.  
  4297.  
  4298.  
  4299.  
  4300.  
  4301.  
  4302.  
  4303.  
  4304.  
  4305.  
  4306.  
  4307.  
  4308.           EMM Functions                                                  68
  4309.  
  4310.  
  4311.  
  4312.  
  4313.  
  4314.           Function 15. Get/Set Page Map
  4315.           Get & Set Page Map subfunction
  4316.  
  4317.  
  4318.  
  4319.           PURPOSE
  4320.  
  4321.                The Get & Set Page Map subfunction simultaneously saves a
  4322.                current mapping context and restores a previous mapping
  4323.                context for all mappable memory regions (both conventional
  4324.                and expanded).  It first copies the contents of the mapping
  4325.                registers from each expanded memory board in the system into
  4326.                a destination array.  (The application must pass a pointer
  4327.                to the destination array.)  Then, the subfunction copies the
  4328.                contents of a source array into the mapping registers on
  4329.                each of the expanded memory boards.  (The application must
  4330.                pass a pointer to the source array.)
  4331.  
  4332.                Use this function instead of Functions 8 and 9 if you need
  4333.                to save or restore the mapping context but don't want (or
  4334.                have) to use a handle.
  4335.  
  4336.  
  4337.           CALLING PARAMETERS
  4338.  
  4339.                AX = 4E02h
  4340.                    Contains the Get & Set Page Map subfunction.
  4341.  
  4342.                ES:DI = dest_page_map
  4343.                    Contains a pointer to the destination array address in
  4344.                    segment:offset format.  The current contents of the map
  4345.                    registers will be saved in this array.
  4346.  
  4347.                DS:SI = source_page_map
  4348.                    Contains a pointer to the source array address in
  4349.                    segment:offset format.  The contents of this array will
  4350.                    be copied into the map registers.  The application must
  4351.                    point to an array which contains the mapping register
  4352.                    state.  This address is required only for the Set or Get
  4353.                    and Set subfunctions.
  4354.  
  4355.  
  4356.           RESULTS
  4357.  
  4358.                These results are valid only if the status returned is zero.
  4359.  
  4360.                dest_page_map
  4361.                    The array contains the mapping state.  It also contains
  4362.                    any additional information necessary to restore the
  4363.                    original state when the program invokes a Set subfunc-
  4364.                    tion.
  4365.  
  4366.  
  4367.           EMM Functions                                                  69
  4368.  
  4369.  
  4370.  
  4371.  
  4372.  
  4373.           Function 15. Get/Set Page Map
  4374.           Get & Set Page Map subfunction
  4375.  
  4376.  
  4377.  
  4378.           REGISTERS MODIFIED
  4379.  
  4380.                AX
  4381.  
  4382.  
  4383.           STATUS
  4384.  
  4385.                AH = 0   SUCCESSFUL.
  4386.                    The manager has returned and passed both arrays.
  4387.  
  4388.                AH = 80h   NON-RECOVERABLE.
  4389.                    The manager detected a malfunction in the memory manager
  4390.                    software.
  4391.  
  4392.                AH = 81h   NON-RECOVERABLE.
  4393.                    The manager detected a malfunction in the expanded
  4394.                    memory hardware.
  4395.  
  4396.                AH = 84h   NON-RECOVERABLE.
  4397.                    The function code passed to the memory manager is not
  4398.                    defined.
  4399.  
  4400.                AH = 8Fh   NON-RECOVERABLE.
  4401.                    The subfunction parameter is invalid.
  4402.  
  4403.                AH = A3h   NON-RECOVERABLE.
  4404.                    The contents of the source array have been corrupted, or
  4405.                    the pointer passed to the subfunction is invalid.
  4406.  
  4407.  
  4408.           EXAMPLE
  4409.  
  4410.           dest_page_map                  DB ? DUP (?)
  4411.  
  4412.           source_page_map                DB ? DUP (?)
  4413.  
  4414.           MOV   AX,SEG dest_page_map
  4415.           MOV   ES,AX
  4416.           MOV   AX,SEG source_page_map
  4417.           MOV   DS,AX
  4418.           LEA   DI,dest_page_map         ; ES:DI points to dest_page_map
  4419.           LEA   SI,source_page_map       ; DS:SI points to source_page_map
  4420.           MOV   AX,4E02h                 ; load function code
  4421.           INT   67h                      ; call the memory manager
  4422.           OR    AH,AH                    ; check EMM status
  4423.           JNZ   emm_err_handler          ; jump to error handler on error
  4424.  
  4425.  
  4426.           EMM Functions                                                  70
  4427.  
  4428.  
  4429.  
  4430.  
  4431.  
  4432.           Function 15. Get/Set Page Map
  4433.           Get Size of Page Map Save Array subfunction
  4434.  
  4435.  
  4436.  
  4437.           PURPOSE
  4438.  
  4439.                The Get Size of Page Map Save Array subfunction returns the
  4440.                storage requirements for the array passed by the other three
  4441.                subfunctions.  This subfunction doesn't require an EMM
  4442.                handle.
  4443.  
  4444.  
  4445.           CALLING PARAMETERS
  4446.  
  4447.                AX = 4E03h
  4448.                    Contains the Get Size of Page Map Save Array subfunc-
  4449.                    tion.  The size of this array depends on how the
  4450.                    expanded memory system is configured and how the
  4451.                    expanded memory manager is implemented.  Therefore, the
  4452.                    size must be determined after the memory manager is
  4453.                    loaded.
  4454.  
  4455.  
  4456.           RESULTS
  4457.  
  4458.                These results are valid only if the status returned is zero.
  4459.  
  4460.                AL = size_of_array
  4461.                    Contains the number of bytes that will be transferred to
  4462.                    the memory area an application supplies whenever a
  4463.                    program requests the Get, Set, or Get and Set subfunc-
  4464.                    tions.
  4465.  
  4466.  
  4467.           REGISTERS MODIFIED
  4468.  
  4469.                AX
  4470.  
  4471.  
  4472.           STATUS
  4473.  
  4474.                AH = 0   SUCCESSFUL.
  4475.                    The manager has returned the array size.
  4476.  
  4477.                AH = 80h   NON-RECOVERABLE.
  4478.                    The manager detected a malfunction in the memory manager
  4479.                    software.
  4480.  
  4481.                AH = 81h   NON-RECOVERABLE.
  4482.                    The manager detected a malfunction in the expanded
  4483.                    memory hardware.
  4484.  
  4485.           EMM Functions                                                  71
  4486.  
  4487.  
  4488.  
  4489.  
  4490.  
  4491.           Function 15. Get/Set Page Map
  4492.           Get Size of Page Map Save Array subfunction
  4493.  
  4494.  
  4495.  
  4496.                AH = 84h   NON-RECOVERABLE.
  4497.                    The function code passed to the memory manager is not
  4498.                    defined.
  4499.  
  4500.                AH = 8Fh   NON-RECOVERABLE.
  4501.                    The subfunction parameter is invalid.
  4502.  
  4503.  
  4504.           EXAMPLE
  4505.  
  4506.           size_of_array                  DB ?
  4507.  
  4508.           MOV   AX,4E03h                 ; load function code
  4509.           INT   67h                      ; call the memory manager
  4510.           OR    AH,AH                    ; check EMM status
  4511.           JNZ   emm_err_handler          ; jump to error handler on error
  4512.           MOV   size_of_array,AL         ; save array size
  4513.  
  4514.  
  4515.  
  4516.  
  4517.  
  4518.  
  4519.  
  4520.  
  4521.  
  4522.  
  4523.  
  4524.  
  4525.  
  4526.  
  4527.  
  4528.  
  4529.  
  4530.  
  4531.  
  4532.  
  4533.  
  4534.  
  4535.  
  4536.  
  4537.  
  4538.  
  4539.  
  4540.  
  4541.  
  4542.  
  4543.  
  4544.           EMM Functions                                                  72
  4545.  
  4546.  
  4547.  
  4548.  
  4549.  
  4550.           Function 16. Get/Set Partial Page Map
  4551.           Get Partial Page Map subfunction
  4552.  
  4553.  
  4554.  
  4555.           PURPOSE
  4556.  
  4557.                The Get Partial Page Map subfunction saves a partial mapping
  4558.                context for specific mappable memory regions in a system. 
  4559.                Because this function saves only a subset of the entire
  4560.                mapping context, it uses much less memory for the save area
  4561.                and may be potentially faster than Function 15.  The
  4562.                subfunction does this by copying the contents of selected
  4563.                mapping registers from each expanded memory board to a
  4564.                destination array.
  4565.  
  4566.                The application must pass a pair of pointers.  The first
  4567.                points to a structure which specifies which mappable
  4568.                segments to save; the second points to the destination
  4569.                array.
  4570.  
  4571.                Use this function instead of Functions 8 and 9 if you need
  4572.                to save or restore the mapping context but don't want (or
  4573.                have) to use a handle.
  4574.  
  4575.  
  4576.           CALLING PARAMETERS
  4577.  
  4578.                AX = 4F00h
  4579.                    Contains the Get Partial Page Map subfunction.
  4580.  
  4581.                    partial_page_map_struct         STRUC
  4582.                        mappable_segment_count      DW ?
  4583.                        mappable_segment            DW (?) DUP (?)
  4584.                    partial_page_map_struct         ENDS
  4585.  
  4586.                DS:SI = partial_page_map
  4587.                    Contains a pointer to a structure which specifies only
  4588.                    those mappable memory regions which are to have their
  4589.                    mapping context saved.  The structure members are
  4590.                    described below.
  4591.  
  4592.                    .mappable_segment_count
  4593.                        The first member is a word which specifies the
  4594.                        number of members in the word array which immediate-
  4595.                        ly follows it.  This number should not exceed the
  4596.                        number of mappable segments in the system.
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.           EMM Functions                                                  73
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.           Function 16. Get/Set Partial Page Map
  4610.           Get Partial Page Map subfunction
  4611.  
  4612.  
  4613.  
  4614.                    .mappable_segment
  4615.                        The second member is a word array which contains the
  4616.                        segment addresses of the mappable memory regions
  4617.                        whose mapping contexts are to be saved.  The segment
  4618.                        address must be a mappable segment.  Use Function 25
  4619.                        to determine which segments are mappable.
  4620.  
  4621.                ES:DI = dest_array
  4622.                    Contains a pointer to the destination array address in
  4623.                    segment:offset format.  To determine the size of the
  4624.                    required array, see the Get Size of Partial Page Map
  4625.                    Save Array subfunction.
  4626.  
  4627.  
  4628.           RESULTS
  4629.  
  4630.                These results are valid only if the status returned is zero.
  4631.  
  4632.                dest_array
  4633.                    The array contains the partial mapping context and any
  4634.                    additional information necessary to restore this context
  4635.                    to its original state when the program invokes a Set
  4636.                    subfunction.
  4637.  
  4638.  
  4639.           REGISTERS MODIFIED
  4640.  
  4641.                AX
  4642.  
  4643.  
  4644.           STATUS
  4645.  
  4646.                AH = 0   SUCCESSFUL.
  4647.                    The manager has saved the partial map context.
  4648.  
  4649.                AH = 80h   NON-RECOVERABLE.
  4650.                    The manager detected a malfunction in the memory manager
  4651.                    software.
  4652.  
  4653.                AH = 81h   NON-RECOVERABLE.
  4654.                    The manager detected a malfunction in the expanded
  4655.                    memory hardware.
  4656.  
  4657.                AH = 84h   NON-RECOVERABLE.
  4658.                    The function code passed to the memory manager is not
  4659.                    defined.
  4660.  
  4661.  
  4662.           EMM Functions                                                  74
  4663.  
  4664.  
  4665.  
  4666.  
  4667.  
  4668.           Function 16. Get/Set Partial Page Map
  4669.           Get Partial Page Map subfunction
  4670.  
  4671.  
  4672.  
  4673.                AH = 8Bh   NON-RECOVERABLE.
  4674.                    One of the specified segments is not a mappable segment.
  4675.  
  4676.                AH = 8Fh   NON-RECOVERABLE.
  4677.                    The subfunction parameter is invalid.
  4678.  
  4679.                AH = A3h   NON-RECOVERABLE.
  4680.                    The contents of the partial page map structure have been
  4681.                    corrupted, the pointer passed to the subfunction is
  4682.                    invalid, or the mappable_segment_count exceeds the
  4683.                    number of mappable segments in the system.
  4684.  
  4685.  
  4686.           EXAMPLE
  4687.  
  4688.           partial_page_map               partial_page_map_struct <>
  4689.  
  4690.           dest_array                     DB ? DUP (?)
  4691.  
  4692.           MOV   AX,SEG partial_page_map
  4693.           MOV   DS,AX
  4694.           LEA   SI,partial_page_map      ; DS:SI points to partial_page_map
  4695.           MOV   AX,SEG dest_array
  4696.           MOV   ES,AX
  4697.           LEA   DI,dest_array            ; ES:DI points to dest_array
  4698.           MOV   AX,4F00h                 ; load function code
  4699.           INT   67h                      ; call the memory manager
  4700.           OR    AH,AH                    ; check EMM status
  4701.           JNZ   emm_err_handler          ; jump to error handler on error
  4702.  
  4703.  
  4704.  
  4705.  
  4706.  
  4707.  
  4708.  
  4709.  
  4710.  
  4711.  
  4712.  
  4713.  
  4714.  
  4715.  
  4716.  
  4717.  
  4718.  
  4719.  
  4720.  
  4721.           EMM Functions                                                  75
  4722.  
  4723.  
  4724.  
  4725.  
  4726.  
  4727.           Function 16. Get/Set Partial Page Map
  4728.           Set Partial Page Map subfunction
  4729.  
  4730.  
  4731.  
  4732.           PURPOSE
  4733.  
  4734.                The Set Partial Page Map subfunction provides a mechanism
  4735.                for restoring the mapping context for a partial mapping
  4736.                context for specific mappable memory regions in a system. 
  4737.                Because this function restores only a subset of the entire
  4738.                mapping context and not the entire systems mapping context,
  4739.                it uses much less memory for the save area and is potential-
  4740.                ly faster than Function 15.  The subfunction does this by
  4741.                copying the contents of the source array to selected mapping
  4742.                registers on each expanded memory board.  The application
  4743.                passes a pointer to the source array.
  4744.  
  4745.                Use this function instead of Functions 8 and 9 if you need
  4746.                to save or restore the mapping context but don't want (or
  4747.                have) to use a handle.
  4748.  
  4749.  
  4750.           CALLING PARAMETERS
  4751.  
  4752.                AX = 4F01h
  4753.                    Contains the Set Partial Page Map subfunction
  4754.  
  4755.                            source_array     DB ? DUP (?)
  4756.  
  4757.                DS:SI = source_array
  4758.                    Contains a pointer to the source array in segment:offset
  4759.                    format.  The application must point to an array which
  4760.                    contains the partial mapping register state.  To deter-
  4761.                    mine the size of the required array, see the Get Size of
  4762.                    Partial Page Map Save Array subfunction.
  4763.  
  4764.  
  4765.           REGISTERS MODIFIED
  4766.  
  4767.                AX
  4768.  
  4769.  
  4770.           STATUS
  4771.  
  4772.                AH = 0   SUCCESSFUL.
  4773.                    The manager has restored the partial mapping context.
  4774.  
  4775.                AH = 80h   NON-RECOVERABLE.
  4776.                    The manager detected a malfunction in the memory manager
  4777.                    software.
  4778.  
  4779.  
  4780.           EMM Functions                                                  76
  4781.  
  4782.  
  4783.  
  4784.  
  4785.  
  4786.           Function 16. Get/Set Partial Page Map
  4787.           Set Partial Page Map subfunction
  4788.  
  4789.  
  4790.  
  4791.                AH = 81h   NON-RECOVERABLE.
  4792.                    The manager detected a malfunction in the expanded
  4793.                    memory hardware.
  4794.  
  4795.                AH = 84h   NON-RECOVERABLE.
  4796.                    The function code passed to the memory manager is not
  4797.                    defined.
  4798.  
  4799.                AH = 8Fh   NON-RECOVERABLE.
  4800.                    The subfunction parameter is invalid.
  4801.  
  4802.                AH = A3h   NON-RECOVERABLE.
  4803.                    The contents of the source array have been corrupted, or
  4804.                    the pointer passed to the subfunction is invalid.
  4805.  
  4806.  
  4807.           EXAMPLE
  4808.  
  4809.           MOV   AX,SEG source_array
  4810.           MOV   DS,AX
  4811.           LEA   SI,source_array          ; DS:SI points to source_array
  4812.           MOV   AX,4F01h                 ; load function code
  4813.           INT   67h                      ; call the memory manager
  4814.           OR    AH,AH                    ; check EMM status
  4815.           JNZ   emm_err_handler          ; jump to error handler on error
  4816.  
  4817.  
  4818.  
  4819.  
  4820.  
  4821.  
  4822.  
  4823.  
  4824.  
  4825.  
  4826.  
  4827.  
  4828.  
  4829.  
  4830.  
  4831.  
  4832.  
  4833.  
  4834.  
  4835.  
  4836.  
  4837.  
  4838.  
  4839.           EMM Functions                                                  77
  4840.  
  4841.  
  4842.  
  4843.  
  4844.  
  4845.           Function 16. Get/Set Partial Page Map
  4846.           Get Size of Partial Page Map Save Array subfunction
  4847.  
  4848.  
  4849.  
  4850.           PURPOSE
  4851.  
  4852.                The Get Size of Partial Page Map Save Array subfunction
  4853.                returns the storage requirements for the array passed by the
  4854.                other two subfunctions.  This subfunction doesn't require an
  4855.                EMM handle.
  4856.  
  4857.  
  4858.           CALLING PARAMETERS
  4859.  
  4860.                AX = 4F02h
  4861.                    Contains the Get Size of Partial Page Map Save Array
  4862.                    subfunction.  The size of this array depends on the
  4863.                    expanded memory system configuration and the implementa-
  4864.                    tion of the expanded memory manager.  Therefore, it will
  4865.                    vary between hardware configurations and implementations
  4866.                    and must be determined after a specific memory manager
  4867.                    is loaded.
  4868.  
  4869.                BX = number of pages in the partial array
  4870.                    Contains the number of pages in the partial map to be
  4871.                    saved by the Get/Set Partial Page Map subfunctions. 
  4872.                    This number should be the same as the mappable_seg-
  4873.                    ment_count in the Get Partial Page Map subfunction.
  4874.  
  4875.  
  4876.           RESULTS
  4877.  
  4878.                These results are valid only if the status returned is zero.
  4879.  
  4880.                AL = size_of_partial_save_array
  4881.                    Contains the number of bytes that will be transferred to
  4882.                    the memory areas supplied by an application whenever a
  4883.                    program requests the Get or Set subfunction.
  4884.  
  4885.  
  4886.           REGISTERS MODIFIED
  4887.  
  4888.                AX
  4889.  
  4890.  
  4891.           STATUS
  4892.  
  4893.                AH = 0   SUCCESSFUL.
  4894.                    The manager has returned the array size.
  4895.  
  4896.  
  4897.  
  4898.           EMM Functions                                                  78
  4899.  
  4900.  
  4901.  
  4902.  
  4903.  
  4904.           Function 16. Get/Set Partial Page Map
  4905.           Get Size of Partial Page Map Save Array subfunction
  4906.  
  4907.  
  4908.  
  4909.                AH = 80h   NON-RECOVERABLE.
  4910.                    The manager detected a malfunction in the memory manager
  4911.                    software.
  4912.  
  4913.                AH = 81h   NON-RECOVERABLE.
  4914.                    The manager detected a malfunction in the expanded
  4915.                    memory hardware.
  4916.  
  4917.                AH = 84h   NON-RECOVERABLE.
  4918.                    The function code passed to the memory manager is not
  4919.                    defined.
  4920.  
  4921.                AH = 8Bh   NON-RECOVERABLE.
  4922.                    The number of pages in the partial array is outside the
  4923.                    range of physical pages in the system.
  4924.  
  4925.                AH = 8Fh   NON-RECOVERABLE.
  4926.                    The subfunction parameter is invalid.
  4927.  
  4928.  
  4929.           EXAMPLE
  4930.  
  4931.           number_of_pages_to_map              DW ?
  4932.           size_of_partial_save_array          DB ?
  4933.  
  4934.           MOV   BX,number_of_pages_to_map
  4935.           MOV   AX,4F02h                      ; load function code
  4936.           INT   67h                           ; call the memory manager
  4937.           OR    AH,AH                         ; check EMM status
  4938.           JNZ   emm_err_handler               ; jump to error handler on   
  4939.                                               ; error
  4940.           MOV   size_of_partial_save_array,AL ; save array size
  4941.  
  4942.  
  4943.  
  4944.  
  4945.  
  4946.  
  4947.  
  4948.  
  4949.  
  4950.  
  4951.  
  4952.  
  4953.  
  4954.  
  4955.  
  4956.  
  4957.           EMM Functions                                                  79
  4958.  
  4959.  
  4960.  
  4961.  
  4962.  
  4963.           Function 17. Map/Unmap Multiple Handle Pages
  4964.  
  4965.  
  4966.  
  4967.           PURPOSE
  4968.  
  4969.                This function can, in a single invocation, map (or unmap)
  4970.                logical pages into as many physical pages as the system
  4971.                supports.  Consequently, it has less execution overhead than
  4972.                mapping pages one at a time.  For applications which do a
  4973.                lot of page mapping, this is the preferred mapping method.
  4974.  
  4975.  
  4976.           Mapping Multiple Pages
  4977.  
  4978.                The handle passed to this function determines what type of
  4979.                logical pages are being mapped.  Logical pages that Function
  4980.                4 and Function 27 (Allocate Standard Pages subfunction)
  4981.                allocate are referred to as pages and are 16K bytes. 
  4982.                Logical pages that Function 27 (Allocate Raw Pages subfunc-
  4983.                tion) allocates are referred to as raw pages and might not
  4984.                be the same size as the pages Function 4 and Function 27
  4985.                (Allocate Standard Pages subfunction) allocate.
  4986.  
  4987.  
  4988.           Unmapping Multiple Pages
  4989.  
  4990.                This function can make specific physical pages unavailable
  4991.                for reading or writing.  A logical page which is unmapped
  4992.                from a specific physical page cannot be read or written from
  4993.                that physical page.  The logical page which is unavailable
  4994.                (unmapped) can be made available again by mapping it, or a
  4995.                new logical page, at the physical page that was unmapped. 
  4996.                Unmapping a physical page is accomplished by setting the
  4997.                logical page it is associated with to FFFFh.
  4998.  
  4999.                You might unmap an entire set of mapped pages, for example,
  5000.                before loading and executing a program.  This ensures that
  5001.                the loaded program won't be able to access the pages your
  5002.                program has mapped.  However, you must save the mapping
  5003.                context before you unmap the physical pages.  This enables
  5004.                you to restore it later so that you may access the memory
  5005.                you had mapped there.  You can save the mapping context with
  5006.                Functions 8, 15, or 16.  You can restore the mapping context
  5007.                with Functions 9, 15, or 16.
  5008.  
  5009.  
  5010.           Mapping and Unmapping Multiple Pages Simultaneously
  5011.  
  5012.                Both mapping and unmapping pages can be done in the same
  5013.                invocation.
  5014.  
  5015.  
  5016.           EMM Functions                                                  80
  5017.  
  5018.  
  5019.  
  5020.  
  5021.  
  5022.           Function 17. Map/Unmap Multiple Handle Pages
  5023.  
  5024.  
  5025.  
  5026.                Mapping or unmapping no pages is not considered an error. 
  5027.                If a request to map or unmap zero pages is made, nothing is
  5028.                done and no error is returned.
  5029.  
  5030.  
  5031.           Alternate Mapping and Unmapping Methods
  5032.  
  5033.                You can map or unmap pages using two methods.  Both methods
  5034.                produce identical results.
  5035.  
  5036.                1.  The first method specifies both a logical page and a
  5037.                    physical page at which the logical page is to be mapped. 
  5038.                    This method is an extension of Function 5 (Map Handle
  5039.                    Page).
  5040.  
  5041.                2.  The second method specifies both a logical page and a
  5042.                    corresponding segment address at which the logical page
  5043.                    is to be mapped.  While this is functionally the same as
  5044.                    the first method, it may be easier to use the actual
  5045.                    segment address of a physical page than to use a number
  5046.                    which only represents its location.  The memory manager
  5047.                    verifies whether the specified segment address falls on
  5048.                    the boundary of a mappable physical page.  The manager
  5049.                    then translates the segment address passed to it into
  5050.                    the necessary internal representation to map the pages.
  5051.  
  5052.  
  5053.  
  5054.  
  5055.  
  5056.  
  5057.  
  5058.  
  5059.  
  5060.  
  5061.  
  5062.  
  5063.  
  5064.  
  5065.  
  5066.  
  5067.  
  5068.  
  5069.  
  5070.  
  5071.  
  5072.  
  5073.  
  5074.  
  5075.           EMM Functions                                                  81
  5076.  
  5077.  
  5078.  
  5079.  
  5080.  
  5081.           Function 17. Map/Unmap Multiple Handle Pages
  5082.           Logical Page/Physical Page Method
  5083.  
  5084.  
  5085.           CALLING PARAMETERS
  5086.  
  5087.                AX = 5000h
  5088.                    Contains the Map/Unmap Multiple Handle Pages subfunction
  5089.                    using the logical page/physical page method.
  5090.  
  5091.                    log_to_phys_map_struct          STRUC
  5092.                        log_page_number             DW ?
  5093.                        phys_page_number            DW ?
  5094.                    log_to_phys_map_struct          ENDS
  5095.  
  5096.                DX = handle
  5097.                    Contains the EMM handle.
  5098.  
  5099.                CX = log_to_phys_map_len
  5100.                    Contains the number of entries in the array.  For
  5101.                    example, if the array contained four pages to map or
  5102.                    unmap, then CX would contain 4.  The number in CX should
  5103.                    not exceed the number of mappable pages in the system.
  5104.  
  5105.                DS:SI = pointer to log_to_phys_map array
  5106.                    Contains a pointer to an array of structures that
  5107.                    contains the information necessary to map the desired
  5108.                    pages.  The array is made up of the following two
  5109.                    elements:
  5110.  
  5111.                    .log_page_number
  5112.                        The first member is a word which contains the number
  5113.                        of the logical page which is to be mapped.  Logical
  5114.                        pages are numbered zero-relative, so the number for
  5115.                        a logical page can only range from zero to (maximum
  5116.                        number of logical pages allocated to the handle -
  5117.                        1).
  5118.  
  5119.                        If the logical page number is set to FFFFh, the
  5120.                        physical page associated with it is unmapped rather
  5121.                        than mapped.  Unmapping a physical page makes it
  5122.                        inaccessible for reading or writing.
  5123.  
  5124.                    .phys_page_number
  5125.                        The second member is a word which contains the
  5126.                        number of the physical page at which the logical
  5127.                        page is to be mapped.  Physical pages are numbered
  5128.                        zero-relative, so the number for a physical page can
  5129.                        only range from zero to (maximum number of physical
  5130.                        pages supported in the system - 1).
  5131.  
  5132.  
  5133.  
  5134.           EMM Functions                                                  82
  5135.  
  5136.  
  5137.  
  5138.  
  5139.  
  5140.           Function 17. Map/Unmap Multiple Handle Pages
  5141.           Logical Page/Physical Page Method
  5142.  
  5143.  
  5144.  
  5145.           REGISTERS MODIFIED
  5146.  
  5147.                AX
  5148.  
  5149.  
  5150.           STATUS
  5151.  
  5152.                AH = 0   SUCCESSFUL.
  5153.                    The logical pages have been mapped, or unmapped, at the
  5154.                    specified physical pages.
  5155.  
  5156.                AH = 80h   NON-RECOVERABLE.
  5157.                    The manager has detected a malfunction in the memory
  5158.                    manager software.
  5159.  
  5160.                AH = 81h   NON-RECOVERABLE.
  5161.                    The manager has detected a malfunction in the expanded
  5162.                    memory hardware.
  5163.  
  5164.                AH = 83h   NON-RECOVERABLE.
  5165.                    The manager couldn't find the specified EMM handle.  The
  5166.                    manager doesn't currently have any information pertain-
  5167.                    ing to the specified EMM handle.  The program has
  5168.                    probably corrupted its EMM handle.
  5169.  
  5170.                AH = 84h   NON-RECOVERABLE.
  5171.                    The function code passed to the manager is not defined.
  5172.  
  5173.                AH = 8Ah   RECOVERABLE.
  5174.                    One or more of the mapped logical pages is out of the
  5175.                    range of logical pages allocated to the EMM handle.  The
  5176.                    program can recover by attempting to map a logical page
  5177.                    which is within the bounds for the specified EMM handle. 
  5178.                    When this error occurs, the only pages mapped were the
  5179.                    ones valid up to the point that the error occurred.
  5180.  
  5181.                AH = 8Bh   RECOVERABLE.
  5182.                    One or more of the physical pages is out of the range of
  5183.                    mappable physical pages, or the log_to_phys_map_len
  5184.                    exceeds the number of mappable pages in the system.  The
  5185.                    program can recover from this condition by attempting to
  5186.                    map into memory at the physical page which is in the
  5187.                    range of the physical page numbers supported by the
  5188.                    system.  When this error occurs, the only pages mapped
  5189.                    were the ones valid up to the point that the error
  5190.                    occurred.
  5191.  
  5192.  
  5193.           EMM Functions                                                  83
  5194.  
  5195.  
  5196.  
  5197.  
  5198.  
  5199.           Function 17. Map/Unmap Multiple Handle Pages
  5200.           Logical Page/Physical Page Method
  5201.  
  5202.  
  5203.  
  5204.                AH = 8Fh   NON-RECOVERABLE.
  5205.                    The subfunction parameter is invalid.
  5206.  
  5207.  
  5208.           EXAMPLE
  5209.  
  5210.           log_to_phys_map            log_to_phys_map_struct ? DUP (?)
  5211.  
  5212.           emm_handle                 DW ?
  5213.  
  5214.           MOV   AX,SEG log_to_phys_map
  5215.           MOV   DS,AX
  5216.           LEA   SI,log_to_phys_map            ; DS:SI points to
  5217.                                               ; log_to_phys_map
  5218.           MOV   CX,LENGTH log_to_phys_map     ; set length field
  5219.           MOV   DX,emm_handle
  5220.           MOV   AX,5000h                      ; load function code
  5221.           INT   67h                           ; call the memory manager
  5222.           OR    AH,AH                         ; check EMM status
  5223.           JNZ   emm_err_handler               ; jump to error handler on   
  5224.                                               ; error
  5225.  
  5226.  
  5227.  
  5228.  
  5229.  
  5230.  
  5231.  
  5232.  
  5233.  
  5234.  
  5235.  
  5236.  
  5237.  
  5238.  
  5239.  
  5240.  
  5241.  
  5242.  
  5243.  
  5244.  
  5245.  
  5246.  
  5247.  
  5248.  
  5249.  
  5250.  
  5251.  
  5252.           EMM Functions                                                  84
  5253.  
  5254.  
  5255.  
  5256.  
  5257.  
  5258.           Function 17. Map/Unmap Multiple Handle Pages
  5259.           Logical Page/Segment Address Method
  5260.  
  5261.  
  5262.           CALLING PARAMETERS
  5263.  
  5264.                AX = 5001h
  5265.                    Contains the Map/Unmap Multiple Handle Pages subfunction
  5266.                    using the logical page/segment address method.
  5267.  
  5268.                    log_to_seg_map_struct           STRUC
  5269.                        log_page_number             DW ?
  5270.                        mappable_segment_address    DW ?
  5271.                    log_to_seg_map_struct           ENDS
  5272.  
  5273.                DX = handle
  5274.                    Contains the EMM handle.
  5275.  
  5276.                CX = log_to_segment_map_len
  5277.                    Contains the number of entries in the array.  For
  5278.                    example, if the array contained four pages to map or
  5279.                    unmap, then CX would contain four.
  5280.  
  5281.                DS:SI = pointer to log_to_segment_map array
  5282.                    Contains a pointer to an array of structures that
  5283.                    contains the information necessary to map the desired
  5284.                    pages.  The array is made up of the following elements:
  5285.  
  5286.                    .log_page_number
  5287.                        The first member is a word which contains the number
  5288.                        of the logical pages to be mapped.  Logical pages
  5289.                        are numbered zero-relative, so the number for a
  5290.                        logical page can range from zero to (maximum number
  5291.                        of logical pages allocated to the handle - 1).
  5292.  
  5293.                        If the logical page number is set to FFFFh, the
  5294.                        physical page associated with it is unmapped rather
  5295.                        than mapped.  Unmapping a physical page makes it
  5296.                        inaccessible for reading or writing.
  5297.  
  5298.                    .mappable_segment_address
  5299.                        The second member is a word which contains the
  5300.                        segment address at which the logical page is to be
  5301.                        mapped.  This segment address must correspond
  5302.                        exactly to a mappable segment address.  The mappable
  5303.                        segment addresses are available with Function 25
  5304.                        (Get Mappable Physical Address Array).
  5305.  
  5306.  
  5307.           REGISTERS MODIFIED
  5308.  
  5309.                AX
  5310.  
  5311.           EMM Functions                                                  85
  5312.  
  5313.  
  5314.  
  5315.  
  5316.  
  5317.           Function 17. Map/Unmap Multiple Handle Pages
  5318.           Logical Page/Segment Address Method
  5319.  
  5320.  
  5321.  
  5322.           STATUS
  5323.  
  5324.                AH = 0   SUCCESSFUL.
  5325.                    The logical pages have been mapped (or unmapped) at the
  5326.                    specified physical pages.
  5327.  
  5328.                AH = 80h   NON-RECOVERABLE.
  5329.                    The manager has detected a malfunction in the memory
  5330.                    manager software.
  5331.  
  5332.                AH = 81h   NON-RECOVERABLE.
  5333.                    The manager has detected a malfunction in the expanded
  5334.                    memory hardware.
  5335.  
  5336.                AH = 83h   NON-RECOVERABLE.
  5337.                    The manager could not find the specified EMM handle. 
  5338.                    The manager doesn't currently have any information
  5339.                    pertaining to the specified EMM handle.  The program has
  5340.                    probably corrupted its EMM handle.
  5341.  
  5342.                AH = 84h   NON-RECOVERABLE.
  5343.                    The function code passed to the manager is not defined.
  5344.  
  5345.                AH = 8Ah   RECOVERABLE.
  5346.                    One or more of the logical pages to be mapped is out of
  5347.                    the range of logical pages allocated to the EMM handle. 
  5348.                    The program can recover from this condition by mapping a
  5349.                    logical page which is within the bounds for the speci-
  5350.                    fied EMM handle.  When this error occurs, the only pages
  5351.                    mapped or unmapped were the ones valid up to the point
  5352.                    that the error occurred.
  5353.  
  5354.                AH = 8Bh   RECOVERABLE.
  5355.                    One or more of the mappable segment addresses specified
  5356.                    is not mappable, the segment address doesn't fall
  5357.                    exactly on a mappable address boundary, or the log_to_-
  5358.                    segment_map_len exceeds the number of mappable segments
  5359.                    in the system.  The program can recover from this
  5360.                    condition by mapping into memory on an exact mappable
  5361.                    segment address.  When this error occurs, the only pages
  5362.                    mapped were the ones valid up to the point that the
  5363.                    error occurred.
  5364.  
  5365.                AH = 8Fh   NON-RECOVERABLE.
  5366.                    The subfunction parameter is invalid.
  5367.  
  5368.  
  5369.  
  5370.           EMM Functions                                                  86
  5371.  
  5372.  
  5373.  
  5374.  
  5375.  
  5376.           Function 17. Map/Unmap Multiple Handle Pages
  5377.           Logical Page/Segment Address Method
  5378.  
  5379.  
  5380.  
  5381.           EXAMPLE
  5382.  
  5383.           log_to_seg_map             log_to_seg_map_struct 4 DUP (?)
  5384.  
  5385.           emm_handle                 DW ?
  5386.  
  5387.           MOV   AX,SEG log_to_seg_map
  5388.           MOV   DS,AX
  5389.           LEA   SI,log_to_seg_map             ; DS:SI points to
  5390.                                               ; log_to_seg_map
  5391.           MOV   CX,LENGTH log_to_seg_map
  5392.           MOV   DX,emm_handle
  5393.           MOV   AX,5001h                      ; load function code
  5394.           INT   67h                           ; call the memory manager
  5395.           OR    AH,AH                         ; check EMM status
  5396.           JNZ   emm_err_handler               ; jump to error handler on   
  5397.                                               ; error
  5398.  
  5399.  
  5400.  
  5401.  
  5402.  
  5403.  
  5404.  
  5405.  
  5406.  
  5407.  
  5408.  
  5409.  
  5410.  
  5411.  
  5412.  
  5413.  
  5414.  
  5415.  
  5416.  
  5417.  
  5418.  
  5419.  
  5420.  
  5421.  
  5422.  
  5423.  
  5424.  
  5425.  
  5426.  
  5427.  
  5428.  
  5429.           EMM Functions                                                  87
  5430.  
  5431.  
  5432.  
  5433.  
  5434.  
  5435.           Function 18. Reallocate Pages
  5436.  
  5437.  
  5438.  
  5439.           PURPOSE
  5440.  
  5441.                This function allows an application program to increase or
  5442.                decrease (reallocate) the number of logical pages allocated
  5443.                to an EMM handle.  There are four reallocation cases of
  5444.                interest:
  5445.  
  5446.                1.  A reallocation count of zero.  The handle assigned to
  5447.                    the application remains assigned and is still available
  5448.                    for use by the application.  The memory manager won't
  5449.                    reassign the handle to any other application.  However,
  5450.                    the handle will have any currently allocated pages
  5451.                    returned to the memory manager.  The application must
  5452.                    invoke the Deallocate Pages function (Function 6) before
  5453.                    returning to DOS, or the handle will remain assigned and
  5454.                    no other application will be able to use it.
  5455.  
  5456.                2.  A reallocation count equal to the current allocation
  5457.                    count.  This is not treated as an error, and a success-
  5458.                    ful status is returned.
  5459.  
  5460.                3.  A reallocation count greater than the current allocation
  5461.                    count.  The memory manager will attempt to add new pages
  5462.                    to those pages already allocated to the specified EMM
  5463.                    handle.  The number of new pages added is the difference
  5464.                    between the reallocation count and the current alloca-
  5465.                    tion count.  The sequence of logical pages allocated to
  5466.                    the EMM handle remains continuous after this operation. 
  5467.                    The newly allocated pages have logical page numbers
  5468.                    which begin where the previously allocated pages ended,
  5469.                    and continue in ascending sequence.
  5470.  
  5471.                4.  A reallocation count less than the current allocation
  5472.                    count.  The memory manager will attempt to subtract some
  5473.                    of the currently allocated pages and return them to the
  5474.                    memory manager.  The number of old pages subtracted is
  5475.                    the difference between the current allocation count and
  5476.                    the re-allocation count.  The pages are subtracted from
  5477.                    the end of the sequence of pages currently allocated to
  5478.                    the specified EMM handle.  The sequence of logical pages
  5479.                    allocated to the EMM handle remains continuous after
  5480.                    this operation.
  5481.  
  5482.  
  5483.  
  5484.  
  5485.  
  5486.  
  5487.  
  5488.           EMM Functions                                                  88
  5489.  
  5490.  
  5491.  
  5492.  
  5493.  
  5494.           Function 18. Reallocate Pages
  5495.  
  5496.  
  5497.  
  5498.           The handle determines what type of logical pages are being
  5499.           reallocated.  Logical pages which were originally allocated with
  5500.           Function 4 or Function 27 (Allocate Standard Pages subfunction)
  5501.           are called pages and are 16K bytes long.  Logical pages which
  5502.           were allocated with Function 27 (Allocate Raw Pages subfunction)
  5503.           are called raw pages and might not be the same size as pages
  5504.           allocated with Function 4.
  5505.  
  5506.  
  5507.           CALLING PARAMETERS
  5508.  
  5509.                AH = 51h
  5510.                    Contains the Reallocate Handle Pages function.
  5511.  
  5512.                DX = handle
  5513.                    Contains the EMM handle.
  5514.  
  5515.                BX = reallocation_count
  5516.                    Contains the total number of pages this handle should
  5517.                    have allocated to it after this function is invoked.
  5518.  
  5519.  
  5520.           RESULTS
  5521.  
  5522.                BX = number of pages allocated to handle after reallocation
  5523.                    Contains the number of pages now allocated to the EMM
  5524.                    handle after the pages have been added or subtracted. 
  5525.                    If the status returned is not zero, the value in BX is
  5526.                    equal to the number of pages allocated to the handle
  5527.                    prior to the invocation of this function.  This informa-
  5528.                    tion can be used to verify that the request generated
  5529.                    the expected results.
  5530.  
  5531.  
  5532.           REGISTERS MODIFIED
  5533.  
  5534.                AX, BX
  5535.  
  5536.  
  5537.           STATUS
  5538.  
  5539.                AH = 0   SUCCESSFUL.
  5540.                    The pages specified have been added to or subtracted
  5541.                    from the handle specified.
  5542.  
  5543.                AH = 80h   NON-RECOVERABLE.
  5544.                    The manager has detected a malfunction in the memory
  5545.                    manager software.
  5546.  
  5547.           EMM Functions                                                  89
  5548.  
  5549.  
  5550.  
  5551.  
  5552.  
  5553.           Function 18. Reallocate Pages
  5554.  
  5555.  
  5556.  
  5557.                AH = 81h   NON-RECOVERABLE.
  5558.                    The manager has detected a malfunction in the expanded
  5559.                    memory hardware.
  5560.  
  5561.                AH = 83h   NON-RECOVERABLE.
  5562.                    The manager could not find the specified EMM handle. 
  5563.                    The manager doesn't have any information pertaining to
  5564.                    the specified EMM handle.  The program may have cor-
  5565.                    rupted its EMM handle.
  5566.  
  5567.                AH = 84h   NON-RECOVERABLE.
  5568.                    The function code passed to the manager is not defined.
  5569.  
  5570.                AH = 87h   RECOVERABLE.
  5571.                    The number of pages that are available in the system is
  5572.                    insufficient for the new allocation request.  The
  5573.                    program can recover from this condition by specifying
  5574.                    fewer pages be allocated to the EMM handle.
  5575.  
  5576.                AH = 88h   RECOVERABLE.
  5577.                    The number of unallocated pages is insufficient for the
  5578.                    new allocation request.  The program can recover from
  5579.                    this condition by either requesting again when addition-
  5580.                    al pages are available or specifying fewer pages.
  5581.  
  5582.  
  5583.           EXAMPLE
  5584.  
  5585.           emm_handle                          DW ?
  5586.           realloc_count                       DW ?
  5587.           current_alloc_page_count            DW ?
  5588.  
  5589.           MOV   DX,emm_handle                 ; specify EMM handle
  5590.           MOV   BX,realloc_count              ; specify count
  5591.           MOV   AH,51h                        ; load function code
  5592.           INT   67h                           ; call the memory manager
  5593.           OR    AH,AH                         ; check EMM status
  5594.           JNZ   emm_err_handler               ; jump to error handler on   
  5595.                                               ; error
  5596.           MOV   current_alloc_page_count,BX
  5597.  
  5598.  
  5599.  
  5600.  
  5601.  
  5602.  
  5603.  
  5604.  
  5605.  
  5606.           EMM Functions                                                  90
  5607.  
  5608.  
  5609.  
  5610.  
  5611.  
  5612.           Function 19. Get/Set Handle Attribute
  5613.  
  5614.  
  5615.  
  5616.           Design Considerations
  5617.  
  5618.                This function is an option which will probably not be
  5619.                available in a typical expanded memory manager, system, or
  5620.                memory board.  Most personal computer systems disable memory
  5621.                refresh signals for a considerable period during a warm
  5622.                boot.  This can corrupt some of the data in memory boards,
  5623.                even though there is no problem with the design of the
  5624.                memory board, its operation, or the memory chips.  This
  5625.                memory refresh deficiency is present in the software design
  5626.                of the ROM BIOS in most personal computer systems.
  5627.  
  5628.                The majority of memory board designs, chip types, or
  5629.                personal computer systems won't be able to support the non-
  5630.                volatility feature.  The reason that this ROM BIOS deficien-
  5631.                cy is not evident in the conventional or extended memory
  5632.                area is that the ROM BIOS always initializes this area
  5633.                during a warm boot.  Memory data integrity is not a problem
  5634.                with the conventional or extended memory region, because it
  5635.                isn't physically possible to have data retained there across
  5636.                a warm boot event -- the ROM BIOS sets it to zero.
  5637.  
  5638.                Consequently, expanded memory board manufacturers should not
  5639.                supply this function unless their board can guarantee the
  5640.                integrity of data stored in the board's memory during a warm
  5641.                boot.  Generally, this means the memory board has an
  5642.                independent memory refresh controller which does not depend
  5643.                on the system board's memory refresh.
  5644.  
  5645.                If the expanded memory manager, system, or memory board
  5646.                cannot support this feature, it should return the not
  5647.                supported status described in the function.
  5648.  
  5649.  
  5650.  
  5651.  
  5652.  
  5653.  
  5654.  
  5655.  
  5656.  
  5657.  
  5658.  
  5659.  
  5660.  
  5661.  
  5662.  
  5663.  
  5664.  
  5665.           EMM Functions                                                  91
  5666.  
  5667.  
  5668.  
  5669.  
  5670.  
  5671.           Function 19. Get/Set Handle Attribute
  5672.           Get Handle Attribute subfunction
  5673.  
  5674.  
  5675.  
  5676.           PURPOSE
  5677.  
  5678.                This subfunction returns the attribute associated with a
  5679.                handle.  The attributes are volatile or non-volatile. 
  5680.                Handles with non-volatile attributes enable the memory
  5681.                manager to save the contents of a handle's pages between
  5682.                warm boots.  However, this function may be disabled with a
  5683.                user option or may not be supported by the memory board or
  5684.                system hardware.
  5685.  
  5686.                If the handle's attribute has been set to non-volatile, the
  5687.                handle, its name (if it is assigned one), and the contents
  5688.                of the pages allocated to the handle are all maintained
  5689.                after a warm boot.
  5690.  
  5691.  
  5692.           CALLING PARAMETERS
  5693.  
  5694.                AX = 5200h
  5695.                    Contains the Get Handle Attribute subfunction.
  5696.  
  5697.                DX = handle
  5698.                    Contains the EMM handle.
  5699.  
  5700.  
  5701.           RESULTS
  5702.  
  5703.                These results are valid only if the status returned is zero.
  5704.  
  5705.                AL = handle attribute
  5706.                    Contains the EMM handle's attribute.  The only at-
  5707.                    tributes a handle may have are volatile or non-volatile. 
  5708.                    A value of zero indicates the handle is volatile.  A
  5709.                    value of one indicates that the handle is non-volatile.
  5710.  
  5711.  
  5712.           REGISTERS MODIFIED
  5713.  
  5714.                AX
  5715.  
  5716.  
  5717.           STATUS
  5718.  
  5719.                AH = 0   SUCCESSFUL.
  5720.                    The handle's attribute has been obtained.
  5721.  
  5722.  
  5723.  
  5724.           EMM Functions                                                  92
  5725.  
  5726.  
  5727.  
  5728.  
  5729.  
  5730.           Function 19. Get/Set Handle Attribute
  5731.           Get Handle Attribute subfunction
  5732.  
  5733.  
  5734.  
  5735.                AH = 80h   NON-RECOVERABLE.
  5736.                    The manager has detected a malfunction in the memory
  5737.                    manager software.
  5738.  
  5739.                AH = 81h   NON-RECOVERABLE.
  5740.                    The manager has detected a malfunction in the expanded
  5741.                    memory hardware.
  5742.  
  5743.                AH = 83h   NON-RECOVERABLE.
  5744.                    The manager couldn't find the specified EMM handle.  The
  5745.                    manager doesn't have any information pertaining to the
  5746.                    specified EMM handle.  The program may have corrupted
  5747.                    its EMM handle.
  5748.  
  5749.                AH = 84h   NON-RECOVERABLE.
  5750.                    The function code passed to the manager is not defined.
  5751.  
  5752.                AH = 8Fh   NON-RECOVERABLE.
  5753.                    The subfunction parameter is invalid.
  5754.  
  5755.                AH = 91h   NON-RECOVERABLE.
  5756.                    This feature is not supported.
  5757.  
  5758.  
  5759.           EXAMPLE
  5760.  
  5761.           emm_handle                     DW ?
  5762.           handle_attrib                  DB ?
  5763.  
  5764.           MOV   DX,emm_handle            ; specify EMM handle
  5765.           MOV   AX,5200h                 ; load function code
  5766.           INT   67h                      ; call the memory manager
  5767.           OR    AH,AH                    ; check EMM status
  5768.           JNZ   emm_err_handler          ; jump to error handler on error
  5769.           MOV   handle_attrib,AL         ; save handle attribute
  5770.  
  5771.  
  5772.  
  5773.  
  5774.  
  5775.  
  5776.  
  5777.  
  5778.  
  5779.  
  5780.  
  5781.  
  5782.  
  5783.           EMM Functions                                                  93
  5784.  
  5785.  
  5786.  
  5787.  
  5788.  
  5789.           Function 19. Get/Set Handle Attribute
  5790.           Set Handle Attribute subfunction
  5791.  
  5792.  
  5793.  
  5794.           PURPOSE
  5795.  
  5796.                This subfunction can be used to modify the attribute which a
  5797.                handle has associated with it.  The attributes which a
  5798.                handle may have are volatile or non-volatile.  The non-
  5799.                volatile attribute enables the EMM to save the contents of a
  5800.                handle's pages between warm boots.  However, this function
  5801.                may be disabled with a user option or may not be supported
  5802.                by the memory board or system hardware.
  5803.  
  5804.                If the handle's attribute has been set to non-volatile, the
  5805.                handle, its name (if it is assigned one), and the contents
  5806.                of the pages allocated to the handle are all maintained
  5807.                after a warm boot.
  5808.  
  5809.  
  5810.           CALLING PARAMETERS
  5811.  
  5812.                AX = 5201h
  5813.                    Contains the Set Handle Attribute function.
  5814.  
  5815.                DX = handle
  5816.                    Contains the EMM handle.
  5817.  
  5818.                BL = new handle attribute
  5819.                    Contains the handle's new attribute.  A value of zero
  5820.                    indicates that the handle should be made volatile.  A
  5821.                    value of one indicates that the handle should be made
  5822.                    non-volatile.
  5823.  
  5824.                    A volatile handle attribute instructs the memory manager
  5825.                    to deallocate both the handle and the pages allocated to
  5826.                    it after a warm boot.  If all handles have the volatile
  5827.                    attribute (the default attribute) at warm boot, the
  5828.                    handle directory will be empty and all of expanded
  5829.                    memory will be initialized to zero immediately after a
  5830.                    warm boot.
  5831.  
  5832.  
  5833.           REGISTERS MODIFIED
  5834.  
  5835.                AX
  5836.  
  5837.  
  5838.  
  5839.  
  5840.  
  5841.  
  5842.           EMM Functions                                                  94
  5843.  
  5844.  
  5845.  
  5846.  
  5847.  
  5848.           Function 19. Get/Set Handle Attribute
  5849.           Set Handle Attribute subfunction
  5850.  
  5851.  
  5852.  
  5853.           STATUS
  5854.  
  5855.                AH = 0   SUCCESSFUL.
  5856.                    The handle's attribute has been modified.
  5857.  
  5858.                AH = 80h   NON-RECOVERABLE.
  5859.                    The manager has detected a malfunction in the memory
  5860.                    manager software.
  5861.  
  5862.                AH = 81h   NON-RECOVERABLE.
  5863.                    The manager has detected a malfunction in the expanded
  5864.                    memory hardware.
  5865.  
  5866.                AH = 83h   NON-RECOVERABLE.
  5867.                    The manager could not find the specified EMM handle. 
  5868.                    The manager doesn't have any information pertaining to
  5869.                    the specified EMM handle.  The program may have cor-
  5870.                    rupted its EMM handle.
  5871.  
  5872.                AH = 84h   NON-RECOVERABLE.
  5873.                    The function code passed to the manager is not defined.
  5874.  
  5875.                AH = 8Fh   NON-RECOVERABLE.
  5876.                    The subfunction parameter is invalid.
  5877.  
  5878.                AH = 90h   NON-RECOVERABLE.
  5879.                    The attribute type is undefined.
  5880.  
  5881.                AH = 91h   NON-RECOVERABLE.
  5882.                    This feature is not supported.
  5883.  
  5884.  
  5885.           EXAMPLE
  5886.  
  5887.           emm_handle                     DW ?
  5888.           new_handle_attrib              DB ?
  5889.  
  5890.           MOV   DX,emm_handle            ; specify EMM handle
  5891.           MOV   BL,new_handle_attrib     ; specify the set attribute
  5892.           MOV   AX,5201h                 ; load function code
  5893.           INT   67h                      ; call the memory manager
  5894.           OR    AH,AH                    ; check EMM status
  5895.           JNZ   emm_err_handler          ; jump to error handler on error
  5896.  
  5897.  
  5898.  
  5899.  
  5900.  
  5901.           EMM Functions                                                  95
  5902.  
  5903.  
  5904.  
  5905.  
  5906.  
  5907.           Function 19. Get/Set Handle Attribute
  5908.           Get Attribute Capability subfunction
  5909.  
  5910.  
  5911.  
  5912.           PURPOSE
  5913.  
  5914.                This subfunction can be used to determine whether the memory
  5915.                manager can support the non-volatile attribute.
  5916.  
  5917.  
  5918.           CALLING PARAMETERS
  5919.  
  5920.                AX = 5202h
  5921.                    Contains the Get Attribute Capability subfunction.
  5922.  
  5923.  
  5924.           RESULTS
  5925.  
  5926.                These results are valid only if the status returned is zero.
  5927.  
  5928.                AL = attribute capability
  5929.                    Contains the attribute capability.  A value of zero
  5930.                    indicates that the memory manager and hardware supports
  5931.                    only volatile handles.  A value of one indicates that
  5932.                    the memory manager/hardware supports both volatile and
  5933.                    non-volatile handles.
  5934.  
  5935.  
  5936.           REGISTERS MODIFIED
  5937.  
  5938.                AX
  5939.  
  5940.  
  5941.           STATUS
  5942.  
  5943.                AH = 0   SUCCESSFUL.
  5944.                    The attribute capability has been returned.
  5945.  
  5946.                AH = 80h   NON-RECOVERABLE.
  5947.                    The manager has detected a malfunction in the memory
  5948.                    manager software.
  5949.  
  5950.                AH = 81h   NON-RECOVERABLE.
  5951.                    The manager has detected a malfunction in the expanded
  5952.                    memory hardware.
  5953.  
  5954.                AH = 84h   NON-RECOVERABLE.
  5955.                    The function code passed to the manager is not defined.
  5956.  
  5957.                AH = 8Fh   NON-RECOVERABLE.
  5958.                    The subfunction parameter is invalid.
  5959.  
  5960.           EMM Functions                                                  96
  5961.  
  5962.  
  5963.  
  5964.  
  5965.  
  5966.           Function 19. Get/Set Handle Attribute
  5967.           Get Attribute Capability subfunction
  5968.  
  5969.  
  5970.  
  5971.           EXAMPLE
  5972.  
  5973.           attrib_capability              DB ?
  5974.  
  5975.           MOV   AX,5202h                 ; load function code
  5976.           INT   67h                      ; call the memory manager
  5977.           OR    AH,AH                    ; check EMM status
  5978.           JNZ   emm_err_handler          ; jump to error handler on error
  5979.           MOV   attrib_capability,AL     ; save attribute capability
  5980.  
  5981.  
  5982.  
  5983.  
  5984.  
  5985.  
  5986.  
  5987.  
  5988.  
  5989.  
  5990.  
  5991.  
  5992.  
  5993.  
  5994.  
  5995.  
  5996.  
  5997.  
  5998.  
  5999.  
  6000.  
  6001.  
  6002.  
  6003.  
  6004.  
  6005.  
  6006.  
  6007.  
  6008.  
  6009.  
  6010.  
  6011.  
  6012.  
  6013.  
  6014.  
  6015.  
  6016.  
  6017.  
  6018.  
  6019.           EMM Functions                                                  97
  6020.  
  6021.  
  6022.  
  6023.  
  6024.  
  6025.           Function 20. Get/Set Handle Name
  6026.           Get Handle Name subfunction
  6027.  
  6028.  
  6029.  
  6030.           PURPOSE
  6031.  
  6032.                This subfunction gets the eight character name currently
  6033.                assigned to a handle.  There is no restriction on the
  6034.                characters which may be used in the handle name (that is,
  6035.                anything from 00h through FFh).
  6036.  
  6037.                The handle name is initialized to ASCII nulls (binary zeros)
  6038.                three times:  when the memory manager is installed, when a
  6039.                handle is allocated, and when a handle is deallocated.  A
  6040.                handle with a name which is all ASCII nulls, by definition,
  6041.                has no name.  When a handle is assigned a name, at least one
  6042.                character in the name must be a non-null character in order
  6043.                to distinguish it from a handle without a name.
  6044.  
  6045.  
  6046.           CALLING PARAMETERS
  6047.  
  6048.                AX = 5300h
  6049.                    Contains the Get Handle Name function.
  6050.  
  6051.                DX = handle number
  6052.                    Contains the EMM handle.
  6053.  
  6054.                ES:DI = pointer to handle_name array
  6055.                    Contains a pointer to an eight-byte array into which the
  6056.                    name currently assigned to the handle will be copied.
  6057.  
  6058.  
  6059.           RESULTS
  6060.  
  6061.                These results are valid only if the status returned is zero.
  6062.  
  6063.                handle_name array
  6064.                    Contains the name associated with the specified handle.
  6065.  
  6066.  
  6067.           REGISTERS MODIFIED
  6068.  
  6069.                AX
  6070.  
  6071.  
  6072.           STATUS
  6073.  
  6074.                AH = 0   SUCCESSFUL.
  6075.                    The handle name has been returned.
  6076.  
  6077.  
  6078.           EMM Functions                                                  98
  6079.  
  6080.  
  6081.  
  6082.  
  6083.  
  6084.           Function 20. Get/Set Handle Name
  6085.           Get Handle Name subfunction
  6086.  
  6087.  
  6088.  
  6089.                AH = 80h   NON-RECOVERABLE.
  6090.                    The manager has detected a malfunction in the memory
  6091.                    manager software.
  6092.  
  6093.                AH = 81h   NON-RECOVERABLE.
  6094.                    The manager has detected a malfunction in the expanded
  6095.                    memory hardware.
  6096.  
  6097.                AH = 83h   NON-RECOVERABLE.
  6098.                    The manager couldn't find the specified EMM handle.  The
  6099.                    manager doesn't have any information on the specified
  6100.                    EMM handle.  The program may have corrupted its EMM
  6101.                    handle.
  6102.  
  6103.                AH = 84h   NON-RECOVERABLE.
  6104.                    The function code passed to the manager is not defined.
  6105.  
  6106.                AH = 8Fh   NON-RECOVERABLE.
  6107.                    The subfunction parameter is invalid.
  6108.  
  6109.  
  6110.           EXAMPLE
  6111.  
  6112.           handle_name                    DB 8 DUP (?)
  6113.           emm_handle                     DW ?
  6114.  
  6115.           MOV   AX,SEG handle_name
  6116.           MOV   ES,AX
  6117.           LEA   DI,handle_name           ; ES:DI points to handle_name
  6118.           MOV   DX,emm_handle            ; specify EMM handle
  6119.           MOV   AX,5300h                 ; load function code
  6120.           INT   67h                      ; call the memory manager
  6121.           OR    AH,AH                    ; check EMM status
  6122.           JNZ   emm_err_handler          ; jump to error handler on error
  6123.  
  6124.  
  6125.  
  6126.  
  6127.  
  6128.  
  6129.  
  6130.  
  6131.  
  6132.  
  6133.  
  6134.  
  6135.  
  6136.  
  6137.           EMM Functions                                                  99
  6138.  
  6139.  
  6140.  
  6141.  
  6142.  
  6143.           Function 20. Get/Set Handle Name
  6144.           Set Handle Name subfunction
  6145.  
  6146.  
  6147.  
  6148.           PURPOSE
  6149.  
  6150.                This subfunction assigns an eight character name to a
  6151.                handle.  There is no restriction on the characters which may
  6152.                be used in the handle name.  The full range of values may be
  6153.                assigned to each character in a name (that is, 00h through
  6154.                FFh).
  6155.  
  6156.                At installation, all handles have their name initialized to
  6157.                ASCII nulls (binary zeros).  A handle with a name consisting
  6158.                of all ASCII nulls has no name.  When a handle is assigned a
  6159.                name, at least one character in the name must be a non-null
  6160.                character in order to distinguish it from a handle without a
  6161.                name.  No two handles may have the same name.
  6162.  
  6163.                A handle can be renamed at any time by setting the handle's
  6164.                name to a new value.  A handle can have its name removed by
  6165.                setting the handle's name to all ASCII nulls.  When a handle
  6166.                is deallocated, its name is removed (set to ASCII nulls).
  6167.  
  6168.  
  6169.           CALLING PARAMETERS
  6170.  
  6171.                AX = 5301h
  6172.                    Contains the Set Handle Name function.
  6173.  
  6174.                DX = handle number
  6175.                    Contains the EMM handle.
  6176.  
  6177.                DS:SI = pointer to handle_name
  6178.                    Contains a pointer to a byte array which contains the
  6179.                    name that is to be assigned to the handle.  The handle
  6180.                    name must be padded with nulls if the name is less than
  6181.                    eight characters long.
  6182.  
  6183.  
  6184.           REGISTERS MODIFIED
  6185.  
  6186.                AX
  6187.  
  6188.  
  6189.           STATUS
  6190.  
  6191.                AH = 0   SUCCESSFUL.
  6192.                    The handle name has been assigned.
  6193.  
  6194.  
  6195.  
  6196.           EMM Functions                                                 100
  6197.  
  6198.  
  6199.  
  6200.  
  6201.  
  6202.           Function 20. Get/Set Handle Name
  6203.           Set Handle Name subfunction
  6204.  
  6205.  
  6206.  
  6207.                AH = 80h   NON-RECOVERABLE.
  6208.                    The manager has detected a malfunction in the memory
  6209.                    manager software.
  6210.  
  6211.                AH = 81h   NON-RECOVERABLE.
  6212.                    The manager has detected a malfunction in the expanded
  6213.                    memory hardware.
  6214.  
  6215.                AH = 83h   NON-RECOVERABLE.
  6216.                    The manager couldn't find the specified EMM handle.  The
  6217.                    manager doesn't currently have any information pertain-
  6218.                    ing to the specified EMM handle.  The program may have
  6219.                    corrupted its EMM handle.
  6220.  
  6221.                AH = 84h   NON-RECOVERABLE.
  6222.                    The function code passed to the manager is not defined.
  6223.  
  6224.                AH = 8Fh   NON-RECOVERABLE.
  6225.                    The subfunction parameter is invalid.
  6226.  
  6227.                AH = A1h   RECOVERABLE.
  6228.                    A handle with this name already exists.  The specified
  6229.                    handle was not assigned a name.
  6230.  
  6231.  
  6232.           EXAMPLE
  6233.  
  6234.           handle_name                    DB 'AARDVARK'
  6235.           emm_handle                     DW ?
  6236.  
  6237.           MOV   AX,SEG handle_name
  6238.           MOV   DS,AX
  6239.           LEA   SI,handle_name           ; DS:SI points to handle_name
  6240.           MOV   DX,emm_handle            ; specify EMM handle
  6241.           MOV   AX,5301h                 ; load function code
  6242.           INT   67h                      ; call the memory manager
  6243.           OR    AH,AH                    ; check EMM status
  6244.           JNZ   emm_err_handler          ; jump to error handler on error
  6245.  
  6246.  
  6247.  
  6248.  
  6249.  
  6250.  
  6251.  
  6252.  
  6253.  
  6254.  
  6255.           EMM Functions                                                 101
  6256.  
  6257.  
  6258.  
  6259.  
  6260.  
  6261.           Function 21. Get Handle Directory
  6262.           Get Handle Directory subfunction
  6263.  
  6264.  
  6265.  
  6266.           PURPOSE
  6267.  
  6268.                This function returns an array which contains all active
  6269.                handles and the names associated with each.  Handles which
  6270.                have not been assigned names have a default name of all
  6271.                ASCII nulls (binary zeros).  When a handle is first allo-
  6272.                cated, or when all the pages belonging to a handle are
  6273.                deallocated (that is, an open handle is closed), its default
  6274.                name is set to ASCII nulls.  It takes a subsequent assign-
  6275.                ment of a name for a handle to have a name after it has been
  6276.                opened.  The full range of values may be assigned to each
  6277.                character in a name (that is, 00h through FFh).
  6278.  
  6279.                The number of bytes required by the array is:
  6280.  
  6281.                            10 bytes * total number of handles
  6282.  
  6283.                The maximum size of this array is:
  6284.  
  6285.                            (10 bytes/entry) * 255 entries = 2550 bytes.
  6286.  
  6287.  
  6288.           CALLING PARAMETERS
  6289.  
  6290.                AX = 5400h
  6291.                    Contains the Get Handle Directory function.
  6292.  
  6293.                    handle_dir_struct               STRUC
  6294.                        handle_value                DW ?
  6295.                        handle_name                 DB 8 DUP (?)
  6296.                    handle_dir_struct               ENDS
  6297.  
  6298.                ES:DI = pointer to handle_dir
  6299.                    Contains a pointer to an area of memory into which the
  6300.                    memory manager will copy the handle directory.  The
  6301.                    handle directory is an array of structures.  There are
  6302.                    as many entries in the array as there are open EMM
  6303.                    handles.  The structure consists of the following
  6304.                    elements:
  6305.  
  6306.                    .handle_value
  6307.                        The first member is a word which contains the value
  6308.                        of the open EMM handle.
  6309.  
  6310.  
  6311.  
  6312.  
  6313.  
  6314.           EMM Functions                                                 102
  6315.  
  6316.  
  6317.  
  6318.  
  6319.  
  6320.           Function 21. Get Handle Directory
  6321.           Get Handle Directory subfunction
  6322.  
  6323.  
  6324.  
  6325.                    .handle_name
  6326.                        The second member is an 8 byte array which contains
  6327.                        the ASCII name associated with the EMM handle.  If
  6328.                        there is no name currently associated with the
  6329.                        handle, it has a value of all zeros (ASCII nulls).
  6330.  
  6331.  
  6332.           RESULTS
  6333.  
  6334.                These results are valid only if the status returned is zero.
  6335.  
  6336.                handle_dir
  6337.                    Contains the handle values and handle names associated
  6338.                    with each handle value.
  6339.  
  6340.                AL = number of entries in the handle_dir array
  6341.                    Contains the number of entries in the handle directory
  6342.                    array.  This is also the same as the number of open
  6343.                    handles.  For example, if only one handle is active, AL
  6344.                    will contain a one.
  6345.  
  6346.  
  6347.           REGISTERS MODIFIED
  6348.  
  6349.                AX
  6350.  
  6351.  
  6352.           STATUS
  6353.  
  6354.                AH = 0   SUCCESSFUL.
  6355.                    The handle directory has been returned.
  6356.  
  6357.                AH = 80h   NON-RECOVERABLE.
  6358.                    The manager has detected a malfunction in the memory
  6359.                    manager software.
  6360.  
  6361.                AH = 81h   NON-RECOVERABLE.
  6362.                    The manager has detected a malfunction in the expanded
  6363.                    memory hardware.
  6364.  
  6365.                AH = 84h   NON-RECOVERABLE.
  6366.                    The function code passed to the manager is not defined.
  6367.  
  6368.                AH = 8Fh   NON-RECOVERABLE.
  6369.                    The subfunction parameter is invalid.
  6370.  
  6371.  
  6372.  
  6373.           EMM Functions                                                 103
  6374.  
  6375.  
  6376.  
  6377.  
  6378.  
  6379.           Function 21. Get Handle Directory
  6380.           Get Handle Directory subfunction
  6381.  
  6382.  
  6383.  
  6384.           EXAMPLE
  6385.  
  6386.           handle_dir                    handle_dir_struct 255 DUP (?)
  6387.  
  6388.           num_entries_in_handle_dir     DB ?
  6389.  
  6390.           MOV   AX,SEG handle_dir
  6391.           MOV   ES,AX
  6392.           LEA   DI,handle_dir                 ; ES:DI points to handle_dir
  6393.           MOV   AX,5400h                      ; load function code
  6394.           INT   67h                           ; call the memory manager
  6395.           OR    AH,AH                         ; check EMM status
  6396.           JNZ   emm_err_handler               ; jump to error handler on   
  6397.                                               ; error
  6398.           MOV   num_entries_in_handle_dir,AL  ; save number of entries
  6399.  
  6400.  
  6401.  
  6402.  
  6403.  
  6404.  
  6405.  
  6406.  
  6407.  
  6408.  
  6409.  
  6410.  
  6411.  
  6412.  
  6413.  
  6414.  
  6415.  
  6416.  
  6417.  
  6418.  
  6419.  
  6420.  
  6421.  
  6422.  
  6423.  
  6424.  
  6425.  
  6426.  
  6427.  
  6428.  
  6429.  
  6430.  
  6431.  
  6432.           EMM Functions                                                 104
  6433.  
  6434.  
  6435.  
  6436.  
  6437.  
  6438.           Function 21. Get Handle Directory
  6439.           Search For Named Handle subfunction
  6440.  
  6441.  
  6442.  
  6443.           PURPOSE
  6444.  
  6445.                This subfunction searches the handle name directory for a
  6446.                handle with a particular name.  If the named handle is
  6447.                found, this subfunction returns the handle number associated
  6448.                with the name.  At the time of installation, all handles
  6449.                have their names initialized to ASCII nulls.  A handle with
  6450.                a name which is all ASCII nulls has, by definition, no name. 
  6451.                When a handle is assigned a name, at least one character in
  6452.                the name must be a non-null character in order to distin-
  6453.                guish it from a handle without a name.
  6454.  
  6455.  
  6456.           CALLING PARAMETERS
  6457.  
  6458.                AX = 5401h
  6459.                    Contains the Search for Named Handle subfunction.
  6460.  
  6461.                DS:SI = handle_name
  6462.                    Contains a pointer to an 8-byte string that contains the
  6463.                    name of the handle being searched for.
  6464.  
  6465.  
  6466.           RESULTS
  6467.  
  6468.                These results are valid only if the status returned is zero.
  6469.  
  6470.                DX = value of named handle
  6471.                    The value of the handle which matches the handle name
  6472.                    specified.
  6473.  
  6474.  
  6475.           REGISTERS MODIFIED
  6476.  
  6477.                AX, DX
  6478.  
  6479.  
  6480.           STATUS
  6481.  
  6482.                AH = 0   SUCCESSFUL.
  6483.                    The handle value for the named handle has been found.
  6484.  
  6485.                AH = 80h   NON-RECOVERABLE.
  6486.                    The manager has detected a malfunction in the memory
  6487.                    manager software.
  6488.  
  6489.  
  6490.  
  6491.           EMM Functions                                                 105
  6492.  
  6493.  
  6494.  
  6495.  
  6496.  
  6497.           Function 21. Get Handle Directory
  6498.           Search For Named Handle subfunction
  6499.  
  6500.  
  6501.  
  6502.                AH = 81h   NON-RECOVERABLE.
  6503.                    The manager has detected a malfunction in the expanded
  6504.                    memory hardware.
  6505.  
  6506.                AH = 84h   NON-RECOVERABLE.
  6507.                    The function code passed to the manager is not defined.
  6508.  
  6509.                AH = 8Fh   NON-RECOVERABLE.
  6510.                    The subfunction parameter is invalid.
  6511.  
  6512.                AH = A0h   NON-RECOVERABLE.
  6513.                    No corresponding handle could be found for the handle
  6514.                    name specified.
  6515.  
  6516.                AH = A1h   NON-RECOVERABLE.
  6517.                    A handle found had no name (all ASCII nulls).
  6518.  
  6519.  
  6520.           EXAMPLE
  6521.  
  6522.           named_handle                   DB 'AARDVARK'
  6523.           named_handle_value             DW ?
  6524.  
  6525.           MOV   AX,SEG named_handle
  6526.           MOV   DS,AX
  6527.           LEA   SI,named_handle          ; DS:SI points to named_handle
  6528.           MOV   AX,5401h                 ; load function code
  6529.           INT   67h                      ; call the memory manager
  6530.           OR    AH,AH                    ; check EMM status
  6531.           JNZ   emm_err_handler          ; jump to error handler on error
  6532.           MOV   named_handle_value,DX    ; save value of named handle
  6533.  
  6534.  
  6535.  
  6536.  
  6537.  
  6538.  
  6539.  
  6540.  
  6541.  
  6542.  
  6543.  
  6544.  
  6545.  
  6546.  
  6547.  
  6548.  
  6549.  
  6550.           EMM Functions                                                 106
  6551.  
  6552.  
  6553.  
  6554.  
  6555.  
  6556.           Function 21. Get Handle Directory
  6557.           Get Total Handles subfunction
  6558.  
  6559.  
  6560.  
  6561.           PURPOSE
  6562.  
  6563.                This subfunction returns the total number of handles that
  6564.                the memory manager supports, including the operating system
  6565.                handle (handle value 0).
  6566.  
  6567.  
  6568.           CALLING PARAMETERS
  6569.  
  6570.                AX = 5402h
  6571.                    Contains the Get Total Handles subfunction.
  6572.  
  6573.  
  6574.           RESULTS
  6575.  
  6576.                These results are valid only if the status returned is zero.
  6577.  
  6578.                BX = total_handles
  6579.                    The value returned represents the maximum number of
  6580.                    handles which a program may request the memory manager
  6581.                    to allocate memory to.  The value returned includes the
  6582.                    operating system handle (handle value 0).
  6583.  
  6584.  
  6585.           REGISTERS MODIFIED
  6586.  
  6587.                AX, BX
  6588.  
  6589.  
  6590.           STATUS
  6591.  
  6592.                AH = 0   SUCCESSFUL.
  6593.                    The total number of handles supported has been returned.
  6594.  
  6595.                AH = 80h   NON-RECOVERABLE.
  6596.                    The manager has detected a malfunction in the memory
  6597.                    manager software.
  6598.  
  6599.                AH = 81h   NON-RECOVERABLE.
  6600.                    The manager has detected a malfunction in the expanded
  6601.                    memory hardware.
  6602.  
  6603.                AH = 84h   NON-RECOVERABLE.
  6604.                    The function code passed to the manager is not defined.
  6605.  
  6606.                AH = 8Fh   NON-RECOVERABLE.
  6607.                    The subfunction parameter is invalid.
  6608.  
  6609.           EMM Functions                                                 107
  6610.  
  6611.  
  6612.  
  6613.  
  6614.  
  6615.           Function 21. Get Handle Directory
  6616.           Get Total Handles subfunction
  6617.  
  6618.  
  6619.  
  6620.           EXAMPLE
  6621.  
  6622.           total_handles                  DW ?
  6623.  
  6624.           MOV   AX,5402h                 ; load function code
  6625.           INT   67h                      ; call the memory manager
  6626.           OR    AH,AH                    ; check EMM status
  6627.           JNZ   emm_err_handler          ; jump to error handler on error
  6628.           MOV   total_handles,BX         ; save total handle count
  6629.  
  6630.  
  6631.  
  6632.  
  6633.  
  6634.  
  6635.  
  6636.  
  6637.  
  6638.  
  6639.  
  6640.  
  6641.  
  6642.  
  6643.  
  6644.  
  6645.  
  6646.  
  6647.  
  6648.  
  6649.  
  6650.  
  6651.  
  6652.  
  6653.  
  6654.  
  6655.  
  6656.  
  6657.  
  6658.  
  6659.  
  6660.  
  6661.  
  6662.  
  6663.  
  6664.  
  6665.  
  6666.  
  6667.  
  6668.           EMM Functions                                                 108
  6669.  
  6670.  
  6671.  
  6672.  
  6673.  
  6674.           Function 22. Alter Page Map & Jump
  6675.  
  6676.  
  6677.  
  6678.           PURPOSE
  6679.  
  6680.                This function alters the memory mapping context and trans-
  6681.                fers control to the specified address.  It is analogous to
  6682.                the FAR JUMP in the 8086 family architecture.  The memory
  6683.                mapping context which existed before the invocation of this
  6684.                function is lost.
  6685.  
  6686.                Mapping no pages and jumping is not considered an error.  If
  6687.                a request to map zero pages and jump is made, control is
  6688.                transferred to the target address, and this function
  6689.                performs a far jump.
  6690.  
  6691.  
  6692.           CALLING PARAMETERS
  6693.  
  6694.                AH = 55h
  6695.                    Contains the Alter Page Map & Jump function.
  6696.  
  6697.                    log_phys_map_struct             STRUC
  6698.                        log_page_number             DW ?
  6699.                        phys_page_number_seg        DW ?
  6700.                    log_phys_map_struct             ENDS
  6701.  
  6702.                    map_and_jump_struct             STRUC
  6703.                        target_address              DD ?
  6704.                        log_phys_map_len            DB ?
  6705.                        log_phys_map_ptr            DD ?
  6706.                    map_and_jump_struct             ENDS
  6707.  
  6708.                AL = physical page number/segment selector
  6709.                    Contains a code which indicates whether the value
  6710.                    contained in the
  6711.  
  6712.                        .log_phys_map.phys_page_number_seg
  6713.  
  6714.                    members are physical page numbers or are the segment
  6715.                    address representation of the physical page numbers.  A
  6716.                    zero in AL indicates that the values are physical page
  6717.                    numbers.  A one in AL indicates that the values in these
  6718.                    members are the segment address representations of the
  6719.                    physical page numbers.
  6720.  
  6721.                DX = handle number
  6722.                    Contains the EMM handle.
  6723.  
  6724.  
  6725.  
  6726.  
  6727.           EMM Functions                                                 109
  6728.  
  6729.  
  6730.  
  6731.  
  6732.  
  6733.           Function 22. Alter Page Map & Jump
  6734.  
  6735.  
  6736.  
  6737.                DS:SI = pointer to map_and_jump structure
  6738.                    Contains a pointer to a structure that contains the
  6739.                    information necessary to map the desired physical pages
  6740.                    and jump to the target address.  The structure consists
  6741.                    of the following elements:
  6742.  
  6743.                    .target_address
  6744.                        The first member is a far pointer which contains the
  6745.                        target address to which control is to be trans-
  6746.                        ferred.  The address is represented in segment:of-
  6747.                        fset format.  The offset portion of the address is
  6748.                        stored in the low portion of the double word.
  6749.  
  6750.                    .log_phys_map_len
  6751.                        The second member is a byte which contains the
  6752.                        number of entries in the array of structures which
  6753.                        immediately follows it.  The array is as long as the
  6754.                        application developer needs in order to map the
  6755.                        desired logical pages into physical pages.  The
  6756.                        number of entries cannot exceed the number of
  6757.                        mappable pages in the system.
  6758.  
  6759.                    .log_phys_map_ptr
  6760.                        The third member is a pointer to an array of struc-
  6761.                        tures which contain the logical page numbers and
  6762.                        physical pages or segment address at which they are
  6763.                        to be mapped.  Each entry in the array of structures
  6764.                        contains the following two elements:
  6765.  
  6766.                    .log_page_number
  6767.                        The first member of this structure is a word which
  6768.                        contains the number of the logical page to be
  6769.                        mapped.
  6770.  
  6771.                    .phys_page_number_seg
  6772.                        The second member of this structure is a word which
  6773.                        contains either the physical page number or the
  6774.                        segment address representation of the physical page
  6775.                        number at which the previous logical page number is
  6776.                        to be mapped.  The value passed in AL determines the
  6777.                        type of representation.
  6778.  
  6779.  
  6780.           REGISTERS MODIFIED
  6781.  
  6782.                AX
  6783.  
  6784.  
  6785.  
  6786.           EMM Functions                                                 110
  6787.  
  6788.  
  6789.  
  6790.  
  6791.  
  6792.           Function 22. Alter Page Map & Jump
  6793.  
  6794.  
  6795.  
  6796.           Note............................................................
  6797.                Values in registers which don't contain required parameters
  6798.                maintain the values across the jump.  The values in regis-
  6799.                ters (with the exception of AX) and the flag state at the
  6800.                beginning of the function are still in the registers and
  6801.                flags when the target address is reached.
  6802.  
  6803.  
  6804.           STATUS
  6805.  
  6806.                AH = 0   SUCCESSFUL.
  6807.                    Control has been transferred to the target address.
  6808.  
  6809.                AH = 80h   NON-RECOVERABLE.
  6810.                    The manager has detected a malfunction in the memory
  6811.                    manager software.
  6812.  
  6813.                AH = 81h   NON-RECOVERABLE.
  6814.                    The manager has detected a malfunction in the expanded
  6815.                    memory hardware.
  6816.  
  6817.                AH = 83h   NON-RECOVERABLE.
  6818.                    The manager could not find the specified EMM handle. 
  6819.                    The manager does not currently have any information
  6820.                    pertaining to the specified EMM handle.  The program may
  6821.                    have corrupted its EMM handle.
  6822.  
  6823.                AH = 84h   NON-RECOVERABLE.
  6824.                    The function code passed to the manager is not defined.
  6825.  
  6826.                AH = 8Ah   RECOVERABLE.
  6827.                    One or more of the logical pages to map into a cor-
  6828.                    responding physical page is out of the range of logical
  6829.                    pages which are allocated to the EMM handle.  The
  6830.                    program can recover from this condition by mapping a
  6831.                    logical page which is within the bounds for the EMM
  6832.                    handle.
  6833.  
  6834.                AH = 8Bh   RECOVERABLE.
  6835.                    One or more of the physical pages is out of the range of
  6836.                    allowable physical pages, or the log_phys_map_len
  6837.                    exceeds the number of mappable pages in the system. 
  6838.                    Physical page numbers are numbered zero-relative.  The
  6839.                    program can recover from this condition by mapping into
  6840.                    memory at a physical page which is in the range of
  6841.                    supported physical pages.
  6842.  
  6843.  
  6844.  
  6845.           EMM Functions                                                 111
  6846.  
  6847.  
  6848.  
  6849.  
  6850.  
  6851.           Function 22. Alter Page Map & Jump
  6852.  
  6853.  
  6854.  
  6855.                AH = 8Fh   NON-RECOVERABLE.
  6856.                    The subfunction parameter is invalid.
  6857.  
  6858.  
  6859.           EXAMPLE
  6860.  
  6861.           log_phys_map              log_phys_map_struct (?) DUP (?)
  6862.  
  6863.           map_and_jump              map_and_jump_struct (?)
  6864.  
  6865.           emm_handle                          DW ?
  6866.           phys_page_or_seg_mode               DB ?
  6867.  
  6868.           MOV   AX,SEG map_and_jump
  6869.           MOV   DS,AX
  6870.           LEA   SI,map_and_jump               ; DS:SI points to
  6871.                                               ; map_and_jump
  6872.           MOV   DX,emm_handle
  6873.           MOV   AH,55h                        ; load function code
  6874.           MOV   AL,phys_page_or_seg_mode      ; specify physical page
  6875.                                               ; or segment mode
  6876.           INT   67h                           ; call memory manager
  6877.           OR    AH,AH                         ; check EMM status
  6878.           JNZ   emm_err_handler               ; jump to error handler on   
  6879.                                               ; error
  6880.  
  6881.  
  6882.  
  6883.  
  6884.  
  6885.  
  6886.  
  6887.  
  6888.  
  6889.  
  6890.  
  6891.  
  6892.  
  6893.  
  6894.  
  6895.  
  6896.  
  6897.  
  6898.  
  6899.  
  6900.  
  6901.  
  6902.  
  6903.  
  6904.           EMM Functions                                                 112
  6905.  
  6906.  
  6907.  
  6908.  
  6909.  
  6910.           Function 23. Alter Page Map & Call
  6911.           Alter Page Map & Call subfunction
  6912.  
  6913.  
  6914.  
  6915.           PURPOSE
  6916.  
  6917.                This subfunction saves the current memory mapping context,
  6918.                alters the specified memory mapping context, and transfers
  6919.                control to the specified address.  It is analogous to the
  6920.                FAR CALL in the 8086 family architecture.  Just as a return
  6921.                from a FAR CALL restores the original value in the code
  6922.                segment register, this subfunction restores the state of the
  6923.                specified mapping context after the return.
  6924.  
  6925.                There is no explicit expanded memory subfunction which
  6926.                emulates a return from a FAR CALL.  However, this facility
  6927.                is implicitly available through the standard return from a
  6928.                FAR CALL.  The following paragraphs describe how this works:
  6929.  
  6930.                After this function is invoked, unless an error is detected,
  6931.                the memory manager will transfer control to the address
  6932.                specified.  If an error occurs, the memory manager returns
  6933.                immediately with the error code in the AH register. 
  6934.                Otherwise, the memory manager pushes on the stack informa-
  6935.                tion which enables it to restore the mapping context after
  6936.                the return.
  6937.  
  6938.                When the called procedure wants to return to the calling
  6939.                procedure, it simply issues a standard FAR RETURN.  The
  6940.                memory manager traps this return, restores the specified
  6941.                mapping context, and returns to the calling procedure.  The
  6942.                memory manager also returns a status from a successful
  6943.                return just as it does for all functions.
  6944.  
  6945.                Developers using this subfunction must make allowances for
  6946.                the additional stack space this subfunction will use.
  6947.  
  6948.  
  6949.           CALLING PARAMETERS
  6950.  
  6951.                AH = 56h
  6952.                    Contains the Alter Page Map & Call function.
  6953.  
  6954.                    log_phys_map_struct             STRUC
  6955.                        log_page_number             DW ?
  6956.                        phys_page_number_seg        DW ?
  6957.                    log_phys_map_struct             ENDS
  6958.  
  6959.  
  6960.  
  6961.  
  6962.  
  6963.           EMM Functions                                                 113
  6964.  
  6965.  
  6966.  
  6967.  
  6968.  
  6969.           Function 23. Alter Page Map & Call
  6970.           Alter Page Map & Call subfunction
  6971.  
  6972.  
  6973.  
  6974.                    map_and_call_struct             STRUC
  6975.                        target_address              DD ?
  6976.                        new_page_map_len            DB ?
  6977.                        new_page_map_ptr            DD ?
  6978.                        old_page_map_len            DB ?
  6979.                        old_page_map_ptr            DD ?
  6980.                        reserved                    DW 4 DUP (?)
  6981.                    map_and_call_struct             ENDS
  6982.  
  6983.                AL = physical page number/segment selector
  6984.                    Contains a code which indicates whether the value
  6985.                    contained in the
  6986.  
  6987.                        .new_page_map.phys_page_number_seg
  6988.                        .old_page_map.phys_page_number_seg
  6989.  
  6990.                    members are physical page numbers or are the segment
  6991.                    address representation of the physical page numbers.  A
  6992.                    value of zero in AL indicates that the values in these
  6993.                    members are physical page numbers.  A value of one in AL
  6994.                    indicates that the values in these members are the
  6995.                    segment address representations of the physical page
  6996.                    numbers.
  6997.  
  6998.                DX = handle number
  6999.                    Contains the EMM handle.
  7000.  
  7001.                DS:SI = pointer to map_and_call structure
  7002.                    Contains a pointer to a structure which contains the
  7003.                    information necessary to map the desired physical pages
  7004.                    and call the target address.  The structure members are
  7005.                    described here:
  7006.  
  7007.                    .target_address
  7008.                        The first member is a far pointer which contains the
  7009.                        target address to which control is to be trans-
  7010.                        ferred.  The address is represented in segment:of-
  7011.                        fset format.  The offset portion of the address is
  7012.                        stored in the low portion of the pointer.  The
  7013.                        application must supply this value.
  7014.  
  7015.                    .new_page_map_len
  7016.                        The second member is a byte which contains the
  7017.                        number of entries in the new mapping context to
  7018.                        which new_page_map_ptr points.  This number cannot
  7019.                        exceed the number of mappable pages in the system.
  7020.  
  7021.  
  7022.           EMM Functions                                                 114
  7023.  
  7024.  
  7025.  
  7026.  
  7027.  
  7028.           Function 23. Alter Page Map & Call
  7029.           Alter Page Map & Call subfunction
  7030.  
  7031.  
  7032.  
  7033.                    .new_page_map_ptr
  7034.                        The third member is a far pointer that points to an
  7035.                        array of structures which contains a list of the
  7036.                        logical page numbers and the physical page num-
  7037.                        bers/segments at which they are to be mapped im-
  7038.                        mediately after the call.  The contents of the new
  7039.                        array of structures are described at the end of the
  7040.                        map_and_call structure.
  7041.  
  7042.                    .old_page_map_len
  7043.                        The fourth member is a byte which contains the
  7044.                        number of entries in the old mapping context to
  7045.                        which old_page_map_ptr points.  This number cannot
  7046.                        exceed the number of mappable pages in the system.
  7047.  
  7048.                    .old_page_map_ptr
  7049.                        The fifth member is a far pointer that points to an
  7050.                        array of structures which contains a list of the
  7051.                        logical page numbers and the physical page num-
  7052.                        bers/segments at which they are to be mapped im-
  7053.                        mediately after the return.  The contents of the old
  7054.                        array of structures are described at the end of the
  7055.                        map_and_call structure.
  7056.  
  7057.                    .reserved
  7058.                        The sixth member is reserved for use by the memory
  7059.                        manager.
  7060.  
  7061.                Each entry in the old and new array of structures contains
  7062.                two elements:
  7063.  
  7064.                    .log_page_number
  7065.                        The first member of this structure is a word which
  7066.                        contains a logical page number which is to be mapped
  7067.                        at the succeeding physical page number/segment
  7068.                        immediately after the CALL (in the case of the new
  7069.                        array of structures) or after the RETURN (in the
  7070.                        case of the old array of structures).
  7071.  
  7072.                    .phys_page_number_seg
  7073.                        The second member of this structure is a word which
  7074.                        contains either the physical page number or the
  7075.                        segment address representation of the physical page
  7076.                        number/segment at which the preceding logical page
  7077.                        is to be mapped immediately after the CALL (in the
  7078.                        case of the new array of structures) or after the
  7079.                        RETURN (in the case of the old array of structures).
  7080.  
  7081.           EMM Functions                                                 115
  7082.  
  7083.  
  7084.  
  7085.  
  7086.  
  7087.           Function 23. Alter Page Map & Call
  7088.           Alter Page Map & Call subfunction
  7089.  
  7090.  
  7091.  
  7092.           REGISTERS MODIFIED
  7093.  
  7094.                AX
  7095.  
  7096.           Note............................................................
  7097.                Values in registers which don't contain required parameters
  7098.                maintain the values across the call.  The values in regis-
  7099.                ters (with the exception of AX) and the flag state at the
  7100.                beginning of the function are still in the registers and
  7101.                flags when the target address is reached.
  7102.  
  7103.  
  7104.           STATUS
  7105.  
  7106.                AH = 0   SUCCESSFUL.
  7107.                    Control has been transferred to the target address.
  7108.  
  7109.                AH = 80h   NON-RECOVERABLE.
  7110.                    The manager has detected a malfunction in the memory
  7111.                    manager software.
  7112.  
  7113.                AH = 81h   NON-RECOVERABLE.
  7114.                    The manager has detected a malfunction in the expanded
  7115.                    memory hardware.
  7116.  
  7117.                AH = 83h   NON-RECOVERABLE.
  7118.                    The manager couldn't find the specified EMM handle.  The
  7119.                    manager doesn't have any information pertaining to the
  7120.                    specified EMM handle.  The program may have corrupted
  7121.                    its EMM handle.
  7122.  
  7123.                AH = 84h   NON-RECOVERABLE.
  7124.                    The function code passed to the manager is not defined.
  7125.  
  7126.                AH = 8Ah   RECOVERABLE.
  7127.                    One or more of the logical pages to map into a cor-
  7128.                    responding physical page is out of the range of logical
  7129.                    pages which are allocated to the EMM handle.  The
  7130.                    program can recover from this condition by mapping a
  7131.                    logical page which is within the bounds for the EMM
  7132.                    handle.
  7133.  
  7134.  
  7135.  
  7136.  
  7137.  
  7138.  
  7139.  
  7140.           EMM Functions                                                 116
  7141.  
  7142.  
  7143.  
  7144.  
  7145.  
  7146.           Function 23. Alter Page Map & Call
  7147.           Alter Page Map & Call subfunction
  7148.  
  7149.  
  7150.  
  7151.                AH = 8Bh   RECOVERABLE.
  7152.                    One or more of the physical pages is out of the range of
  7153.                    allowable physical pages, or you've specified more
  7154.                    physical pages than exist in the system.  Physical page
  7155.                    numbers are numbered zero-relative.  The program can
  7156.                    recover from this condition by mapping a physical page
  7157.                    which is in the range from zero to three.
  7158.  
  7159.                AH = 8Fh   NON-RECOVERABLE.
  7160.                    The subfunction parameter is invalid.
  7161.  
  7162.  
  7163.           EXAMPLE
  7164.  
  7165.           new_page_map              log_phys_map_struct (?) DUP (?)
  7166.  
  7167.           old_page_map              log_phys_map_struct (?) DUP (?)
  7168.  
  7169.           map_and_call              map_and_call_struct (?)
  7170.  
  7171.           emm_handle                DW ?
  7172.           phys_page_or_seg_mode     DB ?
  7173.  
  7174.           MOV   AX,SEG map_and_call
  7175.           MOV   DS,AX
  7176.           LEA   SI,map_and_call               ; DS:SI points to
  7177.                                               ; map_and_call
  7178.           MOV   DX,emm_handle                 ; specify EMM handle
  7179.           MOV   AH,56h                        ; load function code
  7180.           MOV   AL,phys_page_or_seg_mode      ; specify physical page
  7181.                                               ; or segment mode
  7182.           INT   67h                           ; control is actually
  7183.                                               ; transferred to the called
  7184.                                               ; procedure at this point
  7185.           OR    AH,AH                         ; check EMM status
  7186.           JNZ   emm_err_handler               ; jump to error handler on
  7187.                                               ; error
  7188.  
  7189.  
  7190.  
  7191.  
  7192.  
  7193.  
  7194.  
  7195.  
  7196.  
  7197.  
  7198.  
  7199.           EMM Functions                                                 117
  7200.  
  7201.  
  7202.  
  7203.  
  7204.  
  7205.           Function 23. Alter Page Map & Call
  7206.           Get Page Map Stack Space Size subfunction
  7207.  
  7208.  
  7209.  
  7210.           PURPOSE
  7211.  
  7212.                Since the Alter Page Map & Call function pushes additional
  7213.                information onto the stack, this subfunction returns the
  7214.                number of bytes of stack space the function requires.
  7215.  
  7216.  
  7217.           CALLING PARAMETERS
  7218.  
  7219.                AX = 5602h
  7220.                    Contains the Get Page Map Stack Space Size subfunction.
  7221.  
  7222.  
  7223.           RESULTS
  7224.  
  7225.                These results are valid only if the status returned is zero.
  7226.  
  7227.                BX = stack space required
  7228.                    Contains the number of bytes which the Alter Page Map &
  7229.                    Call function will require.  In other words, BX contains
  7230.                    the number (including the return address) which has to
  7231.                    be added to the stack pointer to remove all elements
  7232.                    from the stack.
  7233.  
  7234.  
  7235.           REGISTERS MODIFIED
  7236.  
  7237.                AX, BX
  7238.  
  7239.  
  7240.           STATUS
  7241.  
  7242.                AH = 0   SUCCESSFUL.
  7243.                    The size of the array has been returned.
  7244.  
  7245.                AH = 80h   NON-RECOVERABLE.
  7246.                    The manager has detected a malfunction in the memory
  7247.                    manager software.
  7248.  
  7249.                AH = 81h   NON-RECOVERABLE.
  7250.                    The manager has detected a malfunction in the expanded
  7251.                    memory hardware.
  7252.  
  7253.                AH = 84h   NON-RECOVERABLE.
  7254.                    The function code passed to the manager is not defined.
  7255.  
  7256.  
  7257.  
  7258.           EMM Functions                                                 118
  7259.  
  7260.  
  7261.  
  7262.  
  7263.  
  7264.           Function 23. Alter Page Map & Call
  7265.           Get Page Map Stack Space Size subfunction
  7266.  
  7267.  
  7268.  
  7269.                AH = 8Fh   NON-RECOVERABLE.
  7270.                    The subfunction parameter is invalid.
  7271.  
  7272.  
  7273.           EXAMPLE
  7274.  
  7275.           stack_space_reqd               DW ?
  7276.  
  7277.           MOV   AX,5602h                 ; load function code
  7278.           INT   67h                      ; call the memory manager
  7279.           OR    AH,AH                    ; check EMM status
  7280.           JNZ   emm_err_handler          ; jump to error handler on error
  7281.           MOV   stack_space_reqd,BX      ; save required stack size count
  7282.  
  7283.  
  7284.  
  7285.  
  7286.  
  7287.  
  7288.  
  7289.  
  7290.  
  7291.  
  7292.  
  7293.  
  7294.  
  7295.  
  7296.  
  7297.  
  7298.  
  7299.  
  7300.  
  7301.  
  7302.  
  7303.  
  7304.  
  7305.  
  7306.  
  7307.  
  7308.  
  7309.  
  7310.  
  7311.  
  7312.  
  7313.  
  7314.  
  7315.  
  7316.  
  7317.           EMM Functions                                                 119
  7318.  
  7319.  
  7320.  
  7321.  
  7322.  
  7323.           Function 24. Move/Exchange Memory Region
  7324.           Move Memory Region subfunction
  7325.  
  7326.  
  7327.  
  7328.           PURPOSE
  7329.  
  7330.                This subfunction copies a region of memory in the following
  7331.                memory source/destination combinations.
  7332.  
  7333.                o   conventional memory to conventional memory
  7334.  
  7335.                o   conventional memory to expanded memory
  7336.  
  7337.                o   expanded memory to conventional memory
  7338.  
  7339.                o   expanded memory to expanded memory
  7340.  
  7341.                You do not have to save and restore the expanded memory
  7342.                mapping context to perform these move operations.  The
  7343.                current mapping context is maintained throughout this
  7344.                operation.
  7345.  
  7346.                The length of the region is limited by the amount of
  7347.                expanded memory allocated to the handles specified. 
  7348.                However, in most practical applications, the region length
  7349.                will be considerably smaller.  A region length of zero is
  7350.                not an error, and no move will be performed.
  7351.  
  7352.                A region length which exceeds 16K bytes is not an error.  In
  7353.                this case the function assumes that a group of logical pages
  7354.                is the target for the move.  The logical page specified
  7355.                represents the first logical page in which the move will
  7356.                take place.  If the region length exceeds 16K bytes, or if
  7357.                the region is less than 16K bytes but spans logical pages,
  7358.                there must be sufficient logical pages remaining after the
  7359.                first logical page for the entire region to fit.
  7360.  
  7361.                If your application needs to save a region of conventional
  7362.                memory in expanded memory, you can move it without having to
  7363.                perform a save or restore of the current mapping context. 
  7364.                The memory manager maintains the context.  A move of up to
  7365.                1M bytes may be performed, although practical lengths are
  7366.                substantially less than this value.
  7367.  
  7368.                If the source and destination handles are identical, the
  7369.                source and destination regions are tested for overlap before
  7370.                the move.  If they overlap, the move direction is chosen so
  7371.                that the destination region receives an intact copy of the
  7372.                source region.  A status will be returned indicating that
  7373.                this overlap has occurred.
  7374.  
  7375.  
  7376.           EMM Functions                                                 120
  7377.  
  7378.  
  7379.  
  7380.  
  7381.  
  7382.           Function 24. Move/Exchange Memory Region
  7383.           Move Memory Region subfunction
  7384.  
  7385.  
  7386.  
  7387.           CALLING PARAMETERS
  7388.  
  7389.                AX = 5700h
  7390.                    Contains the Move Memory Region function.
  7391.  
  7392.                    move_source_dest_struct         STRUC
  7393.                        region_length               DD ?
  7394.                        source_memory_type          DB ?
  7395.                        source_handle               DW ?
  7396.                        source_initial_offset       DW ?
  7397.                        source_initial_seg_page     DW ?
  7398.                        dest_memory_type            DB ?
  7399.                        dest_handle                 DW ?
  7400.                        dest_initial_offset         DW ?
  7401.                        dest_initial_seg_page       DW ?
  7402.                    move_source_dest_struct         ENDS
  7403.  
  7404.                DS:SI = pointer to move_source_dest structure
  7405.                    Contains a pointer to a data structure which contains
  7406.                    the source and destination information for the move. 
  7407.                    The structure members are described here:
  7408.  
  7409.                    .region_length
  7410.                        The first member is a double word which specifies
  7411.                        the length of the memory region (in bytes) to be
  7412.                        moved.
  7413.  
  7414.                    .source_memory_type
  7415.                        The second member is a byte which specifies the type
  7416.                        of memory where the source region resides.  A value
  7417.                        of zero indicates that the source region resides in
  7418.                        conventional memory (excluding the page frame seg-
  7419.                        ment).  A value of one indicates that the source
  7420.                        region resides in expanded memory.
  7421.  
  7422.                    .source_handle
  7423.                        If the source region resides in expanded memory, the
  7424.                        third member is a word which specifies the handle
  7425.                        number associated with the source memory region.  If
  7426.                        the source region resides in conventional memory,
  7427.                        this variable has no meaning and should be set to
  7428.                        zero for future compatibility.
  7429.  
  7430.                    .source_initial_offset
  7431.                        The fourth member is a word which specifies the
  7432.                        offset within the source region from which to begin
  7433.                        the move.
  7434.  
  7435.           EMM Functions                                                 121
  7436.  
  7437.  
  7438.  
  7439.  
  7440.  
  7441.           Function 24. Move/Exchange Memory Region
  7442.           Move Memory Region subfunction
  7443.  
  7444.  
  7445.  
  7446.                        If the source region resides in expanded memory, the
  7447.                        source_initial_offset is relative to the beginning
  7448.                        of the 16K logical page.  Because the offset is
  7449.                        relative to the beginning of a 16K expanded memory
  7450.                        page, it may only take on values between 0000h and
  7451.                        3FFFh.
  7452.  
  7453.                        If the source region resides in conventional memory,
  7454.                        the source_initial_offset is a word which specifies
  7455.                        the offset, relative to the beginning of the source
  7456.                        segment, from which to begin the move.  Because the
  7457.                        offset is relative to the beginning of a 64K-byte
  7458.                        conventional memory segment, it may take on values
  7459.                        between 0000h and FFFFh.
  7460.  
  7461.                    .source_initial_seg_page
  7462.                        The fifth member is a word which specifies the
  7463.                        initial segment or logical page number within the
  7464.                        source region from which to begin the move.
  7465.  
  7466.                        If the source region resides in expanded memory, the
  7467.                        value specifies the logical page within the source
  7468.                        region from which to begin the move.
  7469.  
  7470.                        If the source region resides in conventional memory,
  7471.                        the source_initial_seg_page specifies the initial
  7472.                        segment address within conventional memory from
  7473.                        which to begin the move.
  7474.  
  7475.                    .dest_memory_type
  7476.                        The sixth member is a byte which specifies the type
  7477.                        of memory where the destination region resides.  A
  7478.                        value of zero indicates conventional memory; a value
  7479.                        of one indicates expanded memory.
  7480.  
  7481.                    .dest_handle
  7482.                        If the destination region resides in expanded
  7483.                        memory, the seventh member is a word which specifies
  7484.                        the handle number associated with the destination
  7485.                        memory region.  If the destination region resides in
  7486.                        conventional memory, this variable has no meaning
  7487.                        and should be set to zero for future compatibility.
  7488.  
  7489.                    .dest_initial_offset
  7490.                        The eighth member is a word which specifies the
  7491.                        offset within the destination region from which to
  7492.                        begin the move.
  7493.  
  7494.           EMM Functions                                                 122
  7495.  
  7496.  
  7497.  
  7498.  
  7499.  
  7500.           Function 24. Move/Exchange Memory Region
  7501.           Move Memory Region subfunction
  7502.  
  7503.  
  7504.  
  7505.                        If the destination region resides in expanded
  7506.                        memory, the dest_initial_offset is relative to the
  7507.                        beginning of the 16K-byte logical page.  Because the
  7508.                        offset is relative to the beginning of a 16K-byte
  7509.                        expanded memory page, it may only take on values
  7510.                        between 0000h and 3FFFh.
  7511.  
  7512.                        If the destination region resides in conventional
  7513.                        memory, the dest_initial_offset is a word which
  7514.                        specifies the offset, relative to the beginning of
  7515.                        the destination segment, to begin the move.  Because
  7516.                        the offset is relative to the beginning of a 64K
  7517.                        conventional memory segment, it may take on values
  7518.                        between 0000h and FFFFh.
  7519.  
  7520.                    .dest_initial_seg_page
  7521.                        The ninth member is a word which specifies the
  7522.                        initial segment or logical page number within the
  7523.                        destination region from which to begin the move.
  7524.  
  7525.                        If the destination region resides in expanded memory
  7526.                        then the value specifies the logical page within the
  7527.                        destination region from which to begin the move.
  7528.  
  7529.                        If the destination region resides in conventional
  7530.                        memory, the dest_initial_seg_page specifies the
  7531.                        initial segment address within conventional memory
  7532.                        from which to begin the move.
  7533.  
  7534.  
  7535.           REGISTERS MODIFIED
  7536.  
  7537.                AX
  7538.  
  7539.  
  7540.           STATUS
  7541.  
  7542.                AH = 0   SUCCESSFUL.
  7543.                    The memory regions have been moved.
  7544.  
  7545.                AH = 80h   NON-RECOVERABLE.
  7546.                    The manager has detected a malfunction in the memory
  7547.                    manager software.
  7548.  
  7549.                AH = 81h   NON-RECOVERABLE.
  7550.                    The manager has detected a malfunction in the expanded
  7551.                    memory hardware.
  7552.  
  7553.           EMM Functions                                                 123
  7554.  
  7555.  
  7556.  
  7557.  
  7558.  
  7559.           Function 24. Move/Exchange Memory Region
  7560.           Move Memory Region subfunction
  7561.  
  7562.  
  7563.  
  7564.                AH = 83h   NON-RECOVERABLE.
  7565.                    The manager couldn't find either the source or destina-
  7566.                    tion EMM handles.  The memory manager doesn't have any
  7567.                    information on the handles specified.  The program may
  7568.                    have corrupted its EMM handles.
  7569.  
  7570.                AH = 84h   NON-RECOVERABLE.
  7571.                    The function code passed to the manager is not defined.
  7572.  
  7573.                AH = 8Ah   NON-RECOVERABLE.
  7574.                    One or more of the logical pages is out of the range of
  7575.                    logical pages allocated to the source/destination
  7576.                    handle.
  7577.  
  7578.                AH = 8Fh   NON-RECOVERABLE.
  7579.                    The subfunction parameter is invalid.
  7580.  
  7581.                AH = 92h   SUCCESSFUL.
  7582.                    The source and destination expanded memory regions have
  7583.                    the same handle and overlap.  This is valid for a move. 
  7584.                    The move has been completed and the destination region
  7585.                    has a full copy of the source region.  However, at least
  7586.                    a portion of the source region has been overwritten by
  7587.                    the move.  Note that the source and destination expanded
  7588.                    memory regions with different handles will never physi-
  7589.                    cally overlap because the different handles specify
  7590.                    totally different regions of expanded memory.
  7591.  
  7592.                AH = 93h   CONDITIONALLY-RECOVERABLE.
  7593.                    The length of the source or destination expanded memory
  7594.                    region specified exceeds the length of the expanded
  7595.                    memory region allocated either the source or destination
  7596.                    handle.  Insufficient pages are allocated to this handle
  7597.                    to move a region of the size specified.  The program can
  7598.                    recover from this condition by allocating additional
  7599.                    pages to the destination or source handle and attempting
  7600.                    to execute the function again.  However, if the applica-
  7601.                    tion program allocated as much expanded memory as it
  7602.                    thought it needed, this may be a program error and is
  7603.                    not recoverable.
  7604.  
  7605.                AH = 94h   NON-RECOVERABLE.
  7606.                    The conventional memory region and expanded memory
  7607.                    region overlap.  This is invalid, the conventional
  7608.                    memory region cannot overlap the expanded memory region.
  7609.  
  7610.  
  7611.  
  7612.           EMM Functions                                                 124
  7613.  
  7614.  
  7615.  
  7616.  
  7617.  
  7618.           Function 24. Move/Exchange Memory Region
  7619.           Move Memory Region subfunction
  7620.  
  7621.  
  7622.  
  7623.                AH = 95h   NON-RECOVERABLE.
  7624.                    The offset within the logical page exceeds the length of
  7625.                    the logical page.  The initial source or destination
  7626.                    offsets within an expanded memory region must be between
  7627.                    0000h and 3FFFh (16383 or (length of a logical page
  7628.                    - 1)).
  7629.  
  7630.                AH = 96h   NON-RECOVERABLE.
  7631.                    Region length exceeds 1M bytes.
  7632.  
  7633.                AH = 98h   NON-RECOVERABLE.
  7634.                    The memory source and destination types are undefined.
  7635.  
  7636.                AH = A2h   NON-RECOVERABLE.
  7637.                    An attempt was made to wrap around the 1M-byte address
  7638.                    space of conventional memory during the move.  The
  7639.                    combination of source/destination starting address and
  7640.                    length of the region to be moved exceeds 1M bytes.  No
  7641.                    data was moved.
  7642.  
  7643.  
  7644.           EXAMPLE
  7645.  
  7646.           move_source_dest               move_source_dest_struct (?)
  7647.  
  7648.           MOV   AX,SEG move_source_dest
  7649.           MOV   DS,AX
  7650.           LEA   SI,move_source_dest      ; DS:SI points to move_source_dest
  7651.           MOV   AX,5700h                 ; load function code
  7652.           INT   67h                      ; call the memory manager
  7653.           OR    AH,AH                    ; check EMM status
  7654.           JNZ   emm_err_handler          ; jump to error handler on error
  7655.  
  7656.  
  7657.  
  7658.  
  7659.  
  7660.  
  7661.  
  7662.  
  7663.  
  7664.  
  7665.  
  7666.  
  7667.  
  7668.  
  7669.  
  7670.  
  7671.           EMM Functions                                                 125
  7672.  
  7673.  
  7674.  
  7675.  
  7676.  
  7677.           Function 24. Move/Exchange Memory Region
  7678.           Exchange Memory Region subfunction
  7679.  
  7680.  
  7681.  
  7682.           PURPOSE
  7683.  
  7684.                This subfunction exchanges (using a string move) a region of
  7685.                memory in any of the following memory source/destination
  7686.                combinations.
  7687.  
  7688.                o   conventional memory to conventional memory
  7689.  
  7690.                o   conventional memory to expanded memory
  7691.  
  7692.                o   expanded memory to conventional memory
  7693.  
  7694.                o   expanded memory to expanded memory
  7695.  
  7696.                The term expanded memory region refers only to the area of
  7697.                memory above 640K bytes (9FFFFh).  If a system provides
  7698.                mappable conventional memory, this function treats the
  7699.                mappable conventional memory regions as ordinary convention-
  7700.                al memory.  The contents of the source region and the
  7701.                destination region are exchanged.
  7702.  
  7703.                The exchange operation can be performed without having to
  7704.                save and restore the expanded memory mapping context.  The
  7705.                current mapping context is maintained throughout this
  7706.                operation.  The length of the region is limited to the
  7707.                amount of expanded memory allocated to the specified EMM
  7708.                handles.  A length of zero is not an error; however, no
  7709.                exchange will be performed.  A region length which exceeds
  7710.                16K bytes is not an error.  In this case the function
  7711.                assumes that a group of logical pages is the target for the
  7712.                exchange.  The logical page specified represents the first
  7713.                logical page in which the exchange will take place.  If the
  7714.                region length exceeds 16K bytes, or if the region is less
  7715.                than 16K bytes but spans logical pages, there must be
  7716.                sufficient logical pages remaining after the first logical
  7717.                page for the entire region to fit.
  7718.  
  7719.                If your application needs to exchange a region of conven-
  7720.                tional memory with expanded memory, you can simply exchange
  7721.                it with the region of interest without having to perform a
  7722.                save or restore of the current mapping context.  An exchange
  7723.                of up to 1M bytes may be performed, although practical
  7724.                lengths are obviously below that value.  Checking is done
  7725.                before starting the exchange to prevent the possibility of
  7726.                overlap during the exchange operation.  Overlapping source
  7727.                and destination regions for an exchange are invalid, and the
  7728.                exchange will not take place.
  7729.  
  7730.           EMM Functions                                                 126
  7731.  
  7732.  
  7733.  
  7734.  
  7735.  
  7736.           Function 24. Move/Exchange Memory Region
  7737.           Exchange Memory Region subfunction
  7738.  
  7739.  
  7740.  
  7741.           CALLING PARAMETERS
  7742.  
  7743.                AX = 5701h
  7744.                    Contains the Exchange Memory Region function.
  7745.  
  7746.                    xchg_source_dest_struct         STRUC
  7747.                        region_length               DD ?
  7748.                        source_memory_type          DB ?
  7749.                        source_handle               DW ?
  7750.                        source_initial_offset       DW ?
  7751.                        source_initial_seg_page     DW ?
  7752.                        dest_memory_type            DB ?
  7753.                        dest_handle                 DW ?
  7754.                        dest_initial_offset         DW ?
  7755.                        dest_initial_seg_page       DW ?
  7756.                    xchg_source_dest_struct         ENDS
  7757.  
  7758.                DS:SI = pointer to xchg_source_dest structure
  7759.                    Contains a pointer to the data structure which contains
  7760.                    the source and destination information for the exchange. 
  7761.                    The structure members are described here:
  7762.  
  7763.                    .region_length
  7764.                        The first member is a double word which specifies
  7765.                        the length of the memory region to be exchanged.
  7766.  
  7767.                    .source_memory_type
  7768.                        The second member is a byte which specifies the type
  7769.                        of memory where the source region resides.  A value
  7770.                        of zero indicates that the source region resides in
  7771.                        conventional memory.  A value of one indicates that
  7772.                        the source region resides in expanded memory.
  7773.  
  7774.                    .source_handle
  7775.                        If the source region resides in expanded memory, the
  7776.                        third member is a word which specifies the handle
  7777.                        number associated with the source memory region.  If
  7778.                        the source region resides in conventional memory,
  7779.                        this variable has no meaning and should be set to
  7780.                        zero for future compatibility.
  7781.  
  7782.                    .source_initial_offset
  7783.                        The fourth member is a word which specifies the
  7784.                        offset within the source region from which to begin
  7785.                        the exchange.
  7786.  
  7787.  
  7788.  
  7789.           EMM Functions                                                 127
  7790.  
  7791.  
  7792.  
  7793.  
  7794.  
  7795.           Function 24. Move/Exchange Memory Region
  7796.           Exchange Memory Region subfunction
  7797.  
  7798.  
  7799.  
  7800.                        If the source region resides in expanded memory, the
  7801.                        source_initial_offset is relative to the beginning
  7802.                        of the 16K logical page.  Because the offset is
  7803.                        relative to the beginning of a 16K expanded memory
  7804.                        page, it may only take on values between 0000h and
  7805.                        3FFFh.
  7806.  
  7807.                        If the source region resides in conventional memory,
  7808.                        the source_initial_offset is a word which specifies
  7809.                        the offset, relative to the beginning of the source
  7810.                        segment, from which to begin the exchange at. 
  7811.                        Because the offset is relative to the beginning of a
  7812.                        64K-byte conventional memory segment, it may take on
  7813.                        values between 0000h and FFFFh.
  7814.  
  7815.                    .source_initial_seg_page
  7816.                        The fifth member is a word which specifies the
  7817.                        initial segment or logical page number within the
  7818.                        source region from which to begin the exchange.
  7819.  
  7820.                        If the source region resides in expanded memory then
  7821.                        the value specifies the logical page within the
  7822.                        source region from which to begin the exchange.
  7823.  
  7824.                        If the source region resides in conventional memory,
  7825.                        the source_initial_seg_page specifies the initial
  7826.                        segment address within conventional memory from
  7827.                        which to begin the exchange.
  7828.  
  7829.                    .dest_memory_type
  7830.                        The sixth member is a byte which specifies the type
  7831.                        of memory where the destination region resides.  A
  7832.                        value of zero indicates that the destination region
  7833.                        resides in conventional memory (excluding the page
  7834.                        frame segment).  A value of one indicates that the
  7835.                        destination region resides in expanded memory.
  7836.  
  7837.                    .dest_handle
  7838.                        If the destination region resides in expanded
  7839.                        memory, the seventh member is a word which specifies
  7840.                        the handle number associated with the destination
  7841.                        memory region.  If the destination region resides in
  7842.                        conventional memory, this variable has no meaning
  7843.                        and should be set to zero for future compatibility.
  7844.  
  7845.  
  7846.  
  7847.  
  7848.           EMM Functions                                                 128
  7849.  
  7850.  
  7851.  
  7852.  
  7853.  
  7854.           Function 24. Move/Exchange Memory Region
  7855.           Exchange Memory Region subfunction
  7856.  
  7857.  
  7858.  
  7859.                    .dest_initial_offset
  7860.                        The eighth member is a word which specifies the
  7861.                        offset within the destination region from which to
  7862.                        begin the exchange.
  7863.  
  7864.                        If the destination region resides in expanded
  7865.                        memory, the dest_initial_offset is relative to the
  7866.                        beginning of the 16K-byte logical page.  Because the
  7867.                        offset is relative to the beginning of a 16K-byte
  7868.                        expanded memory page, it may only take on values
  7869.                        between 0000h and 3FFFh.
  7870.  
  7871.                        If the destination region resides in conventional
  7872.                        memory, the dest_initial_offset is a word which
  7873.                        specifies the offset, relative to the beginning of
  7874.                        the destination segment, to begin the exchange at. 
  7875.                        Because the offset is relative to the beginning of a
  7876.                        64K conventional memory segment, it may take on
  7877.                        values between 0000h and FFFFh.
  7878.  
  7879.                    .dest_initial_seg_page
  7880.                        The ninth member is a word which specifies the
  7881.                        initial segment or logical page number within the
  7882.                        destination region from which to begin the exchange.
  7883.  
  7884.                        If the destination region resides in expanded memory
  7885.                        then the value specifies the logical page within the
  7886.                        destination region from which to begin the exchange.
  7887.  
  7888.                        If the destination region resides in conventional
  7889.                        memory, the dest_initial_seg_page specifies the
  7890.                        initial segment address within conventional memory
  7891.                        from which to begin the exchange.
  7892.  
  7893.  
  7894.  
  7895.           REGISTERS MODIFIED
  7896.  
  7897.                AX
  7898.  
  7899.  
  7900.           STATUS
  7901.  
  7902.                AH = 0   SUCCESSFUL.
  7903.                    The memory regions have been exchanged.
  7904.  
  7905.  
  7906.  
  7907.           EMM Functions                                                 129
  7908.  
  7909.  
  7910.  
  7911.  
  7912.  
  7913.           Function 24. Move/Exchange Memory Region
  7914.           Exchange Memory Region subfunction
  7915.  
  7916.  
  7917.  
  7918.                AH = 80h   NON-RECOVERABLE.
  7919.                    The manager has detected a malfunction in the memory
  7920.                    manager software.
  7921.  
  7922.                AH = 81h   NON-RECOVERABLE.
  7923.                    The manager has detected a malfunction in the expanded
  7924.                    memory hardware.
  7925.  
  7926.                AH = 83h   NON-RECOVERABLE.
  7927.                    The manager could not find either the source or destina-
  7928.                    tion EMM handles.  The memory manager does not currently
  7929.                    have any information pertaining to the handles speci-
  7930.                    fied.  The program may have corrupted its EMM handles.
  7931.  
  7932.                AH = 84h   NON-RECOVERABLE.
  7933.                    The function code passed to the manager is not defined.
  7934.  
  7935.                AH = 8Ah   NON-RECOVERABLE.
  7936.                    One or more of the logical pages is out of the range of
  7937.                    logical pages allocated to the source/destination
  7938.                    handle.
  7939.  
  7940.                AH = 8Fh   NON-RECOVERABLE.
  7941.                    The subfunction parameter is invalid.
  7942.  
  7943.                AH = 93h   CONDITIONALLY-RECOVERABLE.
  7944.                    The length of the source or destination expanded memory
  7945.                    region specified, exceeds the length of the expanded
  7946.                    memory region allocated to the source or destination
  7947.                    specified EMM handle.  There are insufficient pages
  7948.                    allocated to this handle to exchange a region of the
  7949.                    size specified.  The program can recover from this
  7950.                    condition by attempting to allocate additional pages to
  7951.                    the destination or source handle and attempting to
  7952.                    execute the function again.  However, if the application
  7953.                    program was allocated as much expanded memory as it
  7954.                    thought it needed, this may be a program error and is
  7955.                    therefore not recoverable.
  7956.  
  7957.                AH = 94h   NON-RECOVERABLE.
  7958.                    The conventional memory region and expanded memory
  7959.                    region overlap.  This is invalid, the conventional
  7960.                    memory region cannot overlap the expanded memory region.
  7961.  
  7962.  
  7963.  
  7964.  
  7965.  
  7966.           EMM Functions                                                 130
  7967.  
  7968.  
  7969.  
  7970.  
  7971.  
  7972.           Function 24. Move/Exchange Memory Region
  7973.           Exchange Memory Region subfunction
  7974.  
  7975.  
  7976.  
  7977.                AH = 95h   NON-RECOVERABLE.
  7978.                    The offset within the logical page exceeds the length of
  7979.                    the logical page.  The initial source or destination
  7980.                    offsets within an expanded memory region must be between
  7981.                    0000h and 3FFFh (16383 or (length of a logical page
  7982.                    - 1)).
  7983.  
  7984.                AH = 96h   NON-RECOVERABLE.
  7985.                    Region length exceeds 1M-byte limit.
  7986.  
  7987.                AH = 97h   NON-RECOVERABLE.
  7988.                    The source and destination expanded memory regions have
  7989.                    the same handle and overlap.  This is invalid, the
  7990.                    source and destination expanded memory regions cannot
  7991.                    have the same handle and overlap when they are being
  7992.                    exchanged.  Note that the source and destination
  7993.                    expanded memory regions which have different handles
  7994.                    will never physically overlap because the different
  7995.                    handles specify totally different regions of expanded
  7996.                    memory.
  7997.  
  7998.                AH = 98h   NON-RECOVERABLE.
  7999.                    The memory source and destination types are undefined.
  8000.  
  8001.                AH = A2h   NON-RECOVERABLE.
  8002.                    An attempt was made to wrap around the 1M-byte address
  8003.                    space of conventional memory during the exchange.  The
  8004.                    combination of source/destination starting address and
  8005.                    length of the region to be exchanged exceeds 1M bytes. 
  8006.                    No data was exchanged.
  8007.  
  8008.  
  8009.           EXAMPLE
  8010.  
  8011.           xchg_source_dest               xchg_source_dest_struct (?)
  8012.  
  8013.           MOV   AX,SEG xchg_source_dest
  8014.           MOV   DS,AX
  8015.           LEA   SI,xchg_source_dest      ; DS:SI points to xchg_source_dest
  8016.           MOV   AX,5701h                 ; load function code
  8017.           INT   67h                      ; call the memory manager
  8018.           OR    AH,AH                    ; check EMM status
  8019.           JNZ   emm_err_handler          ; jump to error handler on error
  8020.  
  8021.  
  8022.  
  8023.  
  8024.  
  8025.           EMM Functions                                                 131
  8026.  
  8027.  
  8028.  
  8029.  
  8030.  
  8031.           Function 25. Get Mappable Physical Address Array
  8032.           Get Mappable Physical Address Array subfunction
  8033.  
  8034.  
  8035.  
  8036.           PURPOSE
  8037.  
  8038.                This subfunction returns an array containing the segment
  8039.                address and physical page number for each mappable physical
  8040.                page in a system.  The contents of this array provide a
  8041.                cross reference between physical page numbers and the actual
  8042.                segment addresses for each mappable page in the system.  The
  8043.                array is sorted in ascending segment order.  This does not
  8044.                mean that the physical page numbers associated with the
  8045.                segment addresses are also in ascending order.
  8046.  
  8047.  
  8048.           CALLING PARAMETERS
  8049.  
  8050.                AX = 5800h
  8051.                    Contains the Get Mappable Physical Address Array
  8052.                    subfunction
  8053.  
  8054.                    mappable_phys_page_struct       STRUC
  8055.                        phys_page_segment           DW ?
  8056.                        phys_page_number            DW ?
  8057.                    mappable_phys_page_struct       ENDS
  8058.  
  8059.                ES:DI = mappable_phys_page
  8060.                    Contains a pointer to an application-supplied memory
  8061.                    area where the memory manager will copy the physical
  8062.                    address array.  Each entry in the array is a structure
  8063.                    containing two members:
  8064.  
  8065.                    .phys_page_segment
  8066.                        The first member is a word which contains the
  8067.                        segment address of the mappable physical page
  8068.                        associated with the physical page number following
  8069.                        it.  The array entries are sorted in ascending
  8070.                        segment address order.
  8071.  
  8072.                    .phys_page_number
  8073.                        The second member is a word which contains the
  8074.                        physical page number which corresponds to the
  8075.                        previous segment address.  The physical page numbers
  8076.                        are not necessarily in ascending order.
  8077.  
  8078.  
  8079.  
  8080.  
  8081.  
  8082.  
  8083.  
  8084.           EMM Functions                                                 132
  8085.  
  8086.  
  8087.  
  8088.  
  8089.  
  8090.           Function 25. Get Mappable Physical Address Array
  8091.           Get Mappable Physical Address Array subfunction
  8092.  
  8093.  
  8094.  
  8095.                    Example 1
  8096.  
  8097.                        An expanded memory board has its page frame starting
  8098.                        at address C0000h and has no mappable conventional
  8099.                        memory.  For this configuration, physical page 0
  8100.                        corresponds to segment address C000h, physical page
  8101.                        1 corresponds to segment address C400h, etc.  The
  8102.                        array would contain the following data (in this
  8103.                        order):
  8104.  
  8105.                        C000h, 00h
  8106.                        C400h, 01h
  8107.                        C800h, 02h
  8108.                        CC00h, 03h
  8109.  
  8110.  
  8111.                    Example 2
  8112.  
  8113.                        An expanded memory board has a large page frame
  8114.                        starting at address C0000h and has mappable conven-
  8115.                        tional memory from 90000h through 9FFFFh.  For this
  8116.                        configuration, physical page 0 corresponds to
  8117.                        segment address C000h, physical page 1 corresponds
  8118.                        to segment address C400h, etc.  The array would
  8119.                        contain the following data in the order specified. 
  8120.                        Note that the expanded memory region always has the
  8121.                        lowest numerically valued physical page numbers.
  8122.  
  8123.                        9000h, 0Ch
  8124.                        9400h, 0Dh
  8125.                        9800h, 0Eh
  8126.                        9C00h, 0Fh
  8127.                        C000h, 00h
  8128.                        C400h, 01h
  8129.                        C800h, 02h
  8130.                        CC00h, 03h
  8131.                        D000h, 04h
  8132.                        D400h, 05h
  8133.                        D800h, 06h
  8134.                        DC00h, 07h
  8135.                        E000h, 08h
  8136.                        E400h, 09h
  8137.                        E800h, 0Ah
  8138.                        EC00h, 0Bh
  8139.  
  8140.  
  8141.  
  8142.  
  8143.           EMM Functions                                                 133
  8144.  
  8145.  
  8146.  
  8147.  
  8148.  
  8149.           Function 25. Get Mappable Physical Address Array
  8150.           Get Mappable Physical Address Array subfunction
  8151.  
  8152.  
  8153.  
  8154.           RESULTS
  8155.  
  8156.                These results are valid only if the status returned is zero.
  8157.  
  8158.                CX = number of entries in the mappable_phys_page
  8159.                    Multiply this number by (SIZE mappable_phys_page_struct)
  8160.                    to determine the number of bytes the physical page
  8161.                    address array requires.
  8162.  
  8163.  
  8164.           REGISTERS MODIFIED
  8165.  
  8166.                AX, CX
  8167.  
  8168.  
  8169.           STATUS
  8170.  
  8171.                AH = 0   SUCCESSFUL.
  8172.                    The hardware configuration array has been returned.
  8173.  
  8174.                AH = 80h   NON-RECOVERABLE.
  8175.                    The manager has detected a malfunction in the memory
  8176.                    manager software.
  8177.  
  8178.                AH = 81h   NON-RECOVERABLE.
  8179.                    The manager has detected a malfunction in the expanded
  8180.                    memory hardware.
  8181.  
  8182.                AH = 84h   NON-RECOVERABLE.
  8183.                    The function code passed to the manager is not defined.
  8184.  
  8185.                AH = 8Fh   NON-RECOVERABLE.
  8186.                    The subfunction parameter is invalid.
  8187.  
  8188.  
  8189.  
  8190.  
  8191.  
  8192.  
  8193.  
  8194.  
  8195.  
  8196.  
  8197.  
  8198.  
  8199.  
  8200.  
  8201.  
  8202.           EMM Functions                                                 134
  8203.  
  8204.  
  8205.  
  8206.  
  8207.  
  8208.           Function 25. Get Mappable Physical Address Array
  8209.           Get Mappable Physical Address Array subfunction
  8210.  
  8211.  
  8212.  
  8213.           EXAMPLE
  8214.  
  8215.           mappable_phys_page             mappable_phys_page_struct (?)
  8216.  
  8217.           mappable_page_entry_count      DW ?
  8218.  
  8219.           MOV   AX,SEG mappable_phys_page
  8220.           MOV   ES,AX
  8221.           LEA   DI,mappable_phys_page         ; ES:DI points to
  8222.                                               ; mappable_phys_page
  8223.           MOV   AX,5800h                      ; load function code
  8224.           INT   67h                           ; call the memory
  8225.                                               ; manager
  8226.           OR    AH,AH                         ; check EMM status
  8227.           JNZ   emm_err_handler               ; jump to error handler
  8228.                                               ; on error
  8229.           MOV   mappable_page_entry_count,CX  ; save mappable
  8230.                                               ; page entry count
  8231.  
  8232.  
  8233.  
  8234.  
  8235.  
  8236.  
  8237.  
  8238.  
  8239.  
  8240.  
  8241.  
  8242.  
  8243.  
  8244.  
  8245.  
  8246.  
  8247.  
  8248.  
  8249.  
  8250.  
  8251.  
  8252.  
  8253.  
  8254.  
  8255.  
  8256.  
  8257.  
  8258.  
  8259.  
  8260.  
  8261.           EMM Functions                                                 135
  8262.  
  8263.  
  8264.  
  8265.  
  8266.  
  8267.           Function 25. Get Mappable Physical Address Array
  8268.           Get Mappable Physical Address Array Entries subfunction
  8269.  
  8270.  
  8271.  
  8272.           PURPOSE
  8273.  
  8274.                This subfunction gets the number of entries which will be
  8275.                required for the array the first subfunction returns.
  8276.  
  8277.  
  8278.           CALLING PARAMETERS
  8279.  
  8280.                AX = 5801h
  8281.                    Contains the Get Physical Page Address Array Entries
  8282.                    subfunction.  This subfunction returns a word which
  8283.                    represents the number of entries in the array returned
  8284.                    by the previous subfunction.  This number also repre-
  8285.                    sents the number of mappable physical pages in a system.
  8286.  
  8287.  
  8288.           RESULTS
  8289.  
  8290.                These results are valid only if the status returned is zero.
  8291.  
  8292.                CX = number of entries in the mappable_phys_page
  8293.                    Multiply this number by (SIZE mappable_phys_page_struct)
  8294.                    to determine the number of bytes the physical page
  8295.                    address array will require.
  8296.  
  8297.  
  8298.           REGISTERS MODIFIED
  8299.  
  8300.                AX, CX
  8301.  
  8302.  
  8303.           STATUS
  8304.  
  8305.                AH = 0   SUCCESSFUL.
  8306.                    The number of mappable physical pages has been returned.
  8307.  
  8308.                AH = 80h   NON-RECOVERABLE.
  8309.                    The manager has detected a malfunction in the memory
  8310.                    manager software.
  8311.  
  8312.                AH = 81h   NON-RECOVERABLE.
  8313.                    The manager has detected a malfunction in the expanded
  8314.                    memory hardware.
  8315.  
  8316.                AH = 84h   NON-RECOVERABLE.
  8317.                    The function code passed to the manager is not defined.
  8318.  
  8319.  
  8320.           EMM Functions                                                 136
  8321.  
  8322.  
  8323.  
  8324.  
  8325.  
  8326.           Function 25. Get Mappable Physical Address Array
  8327.           Get Mappable Physical Address Array Entries subfunction
  8328.  
  8329.  
  8330.  
  8331.                AH = 8Fh   NON-RECOVERABLE.
  8332.                    The subfunction parameter is invalid.
  8333.  
  8334.  
  8335.           EXAMPLE
  8336.  
  8337.           mappable_page_entry_count           DW ?
  8338.  
  8339.           MOV   AX,5801h                      ; load function code
  8340.           INT   67h                           ; call memory manager
  8341.           OR    AH,AH                         ; check EMM status
  8342.           JNZ   emm_err_handler               ; jump to error handler
  8343.                                               ; on error
  8344.           MOV   mappable_page_entry_count,CX  ; save mappable
  8345.                                               ; page entry count
  8346.  
  8347.  
  8348.  
  8349.  
  8350.  
  8351.  
  8352.  
  8353.  
  8354.  
  8355.  
  8356.  
  8357.  
  8358.  
  8359.  
  8360.  
  8361.  
  8362.  
  8363.  
  8364.  
  8365.  
  8366.  
  8367.  
  8368.  
  8369.  
  8370.  
  8371.  
  8372.  
  8373.  
  8374.  
  8375.  
  8376.  
  8377.  
  8378.  
  8379.           EMM Functions                                                 137
  8380.  
  8381.  
  8382.  
  8383.  
  8384.  
  8385.           Function 26. Get Expanded Memory Hardware Information
  8386.           Get Hardware Configuration Array subfunction
  8387.  
  8388.  
  8389.  
  8390.           Note............................................................
  8391.                This function is for use by operating systems only.  This
  8392.                function can be disabled at any time by the operating
  8393.                system.  Refer to Function 30 for a description of how an
  8394.                operating system does this.
  8395.  
  8396.  
  8397.           PURPOSE
  8398.  
  8399.                This subfunction returns an array containing expanded memory
  8400.                hardware configuration information for use by an operating
  8401.                system/environment.
  8402.  
  8403.  
  8404.           CALLING PARAMETERS
  8405.  
  8406.                AX = 5900h
  8407.                    Contains the Get Hardware Configuration Array subfunc-
  8408.                    tion.
  8409.  
  8410.                    hardware_info_struct            STRUC
  8411.                        raw_page_size               DW ?
  8412.                        alternate_register_sets     DW ?
  8413.                        context_save_area_size      DW ?
  8414.                        DMA_register_sets           DW ?
  8415.                        DMA_channel_operation       DW ?
  8416.                    hardware_info_struct            ENDS
  8417.  
  8418.                ES:DI = hardware_info
  8419.                    Contains a pointer to a memory area that the operating
  8420.                    system supplies where the memory manager will copy
  8421.                    expanded memory hardware information.  The structure
  8422.                    contains these five members:
  8423.  
  8424.                    .raw_page_size
  8425.                        The first member is a word which contains the size
  8426.                        of a raw mappable physical page in paragraphs (16
  8427.                        bytes).  LIM standard pages are always 16K bytes. 
  8428.                        However, other implementations of expanded memory
  8429.                        boards do not necessarily comply with this standard
  8430.                        and can emulate a 16K-byte page by mapping in
  8431.                        multiple smaller pages.  This member specifies the
  8432.                        size of a mappable physical page viewed from the
  8433.                        hardware implementation level.
  8434.  
  8435.  
  8436.  
  8437.  
  8438.           EMM Functions                                                 138
  8439.  
  8440.  
  8441.  
  8442.  
  8443.  
  8444.           Function 26. Get Expanded Memory Hardware Information
  8445.           Get Hardware Configuration Array subfunction
  8446.  
  8447.  
  8448.  
  8449.                    .alternate_register_sets
  8450.                        The second member is a word which specifies the
  8451.                        number of alternate mapping register sets.  The
  8452.                        additional mapping register sets are termed alter-
  8453.                        nate mapping register sets in this document.
  8454.  
  8455.                        All expanded memory boards have at least one set of
  8456.                        hardware registers to perform the logical to
  8457.                        physical page mapping.  Some expanded memory boards
  8458.                        have more than one set of these mapping registers. 
  8459.                        This member specifies how many of these alternate
  8460.                        mapping register sets exist (beyond the one set that
  8461.                        all expanded memory boards have) on the expanded
  8462.                        memory boards in the system.  If an expanded memory
  8463.                        card has only one set of mapping registers (that is,
  8464.                        no alternate mapping register sets) this member has
  8465.                        a value of zero.
  8466.  
  8467.                    .context_save_area_size
  8468.                        The third member is a word which contains the
  8469.                        storage requirements for the array required to save
  8470.                        a mapping context.  The value returned in this
  8471.                        member is exactly the same as that returned by
  8472.                        Function 15 (Get Size of Page Map Save Array
  8473.                        subfunction).
  8474.  
  8475.                    .DMA_register_sets
  8476.                        The fourth member is a word which contains the
  8477.                        number of register sets that can be assigned to DMA
  8478.                        channels.  These DMA register sets, although similar
  8479.                        in use to alternate register sets, are for DMA
  8480.                        mapping and not task mapping.
  8481.  
  8482.                        If the expanded memory hardware does not support DMA
  8483.                        register sets, care must be taken when DMA is taking
  8484.                        place.
  8485.  
  8486.                        In a multitasking operating system, when one task is
  8487.                        waiting for DMA to complete, it is useful to be able
  8488.                        to switch to another task.  However, if the DMA is
  8489.                        taking place in memory that the second task will
  8490.                        need to remap, remapping would be disastrous.
  8491.  
  8492.  
  8493.  
  8494.  
  8495.  
  8496.  
  8497.           EMM Functions                                                 139
  8498.  
  8499.  
  8500.  
  8501.  
  8502.  
  8503.           Function 26. Get Expanded Memory Hardware Information
  8504.           Get Hardware Configuration Array subfunction
  8505.  
  8506.  
  8507.  
  8508.                        If the expanded memory hardware can detect when DMA
  8509.                        is occurring, the OS/E should allow task switches
  8510.                        and remapping during DMA.  If no special support for
  8511.                        DMA is available, no remapping should be done when
  8512.                        DMA is in progress.
  8513.  
  8514.                    .DMA_channel_operation
  8515.                        The fifth member is a word which specifies a special
  8516.                        case for the DMA register sets.  A value of zero
  8517.                        specifies that the DMA register sets behave as
  8518.                        described in Function 28.  A value of one specifies
  8519.                        that the expanded memory hardware has only one DMA
  8520.                        register set.  In addition, if any channel is mapped
  8521.                        through this register set, then all channels are
  8522.                        mapped through it.  For LIM standard boards, this
  8523.                        value is zero.
  8524.  
  8525.  
  8526.           RESULTS
  8527.  
  8528.                These results are valid only if the status returned is zero.
  8529.  
  8530.                hardware_info
  8531.                    Contains the expanded memory hardware-specific informa-
  8532.                    tion described above.
  8533.  
  8534.  
  8535.           REGISTERS MODIFIED
  8536.  
  8537.                AX
  8538.  
  8539.  
  8540.           STATUS
  8541.  
  8542.                AH = 0   SUCCESSFUL.
  8543.                    The hardware configuration array has been returned.
  8544.  
  8545.                AH = 80h   NON-RECOVERABLE.
  8546.                    The manager has detected a malfunction in the memory
  8547.                    manager software.
  8548.  
  8549.                AH = 81h   NON-RECOVERABLE.
  8550.                    The manager has detected a malfunction in the expanded
  8551.                    memory hardware.
  8552.  
  8553.                AH = 84h   NON-RECOVERABLE.
  8554.                    The function code passed to the manager is not defined.
  8555.  
  8556.           EMM Functions                                                 140
  8557.  
  8558.  
  8559.  
  8560.  
  8561.  
  8562.           Function 26. Get Expanded Memory Hardware Information
  8563.           Get Hardware Configuration Array subfunction
  8564.  
  8565.  
  8566.  
  8567.                AH = 8Fh   NON-RECOVERABLE.
  8568.                    The subfunction parameter is invalid.
  8569.  
  8570.                AH = A4h   NON-RECOVERABLE.
  8571.                    Access to this function has been denied by the operating
  8572.                    system.  The function cannot be used at this time.
  8573.  
  8574.  
  8575.           EXAMPLE
  8576.  
  8577.           hardware_info                  hardware_info_struct (?)
  8578.  
  8579.           MOV   AX,SEG hardware_info
  8580.           MOV   ES,AX
  8581.           LEA   DI,hardware_info         ; ES:DI points to hardware_info
  8582.           MOV   AX,5900h                 ; load function code
  8583.           INT   67h                      ; call the memory manager
  8584.           OR    AH,AH                    ; check EMM status
  8585.           JNZ   emm_err_handler          ; jump to error handler on error
  8586.  
  8587.  
  8588.  
  8589.  
  8590.  
  8591.  
  8592.  
  8593.  
  8594.  
  8595.  
  8596.  
  8597.  
  8598.  
  8599.  
  8600.  
  8601.  
  8602.  
  8603.  
  8604.  
  8605.  
  8606.  
  8607.  
  8608.  
  8609.  
  8610.  
  8611.  
  8612.  
  8613.  
  8614.  
  8615.           EMM Functions                                                 141
  8616.  
  8617.  
  8618.  
  8619.  
  8620.  
  8621.           Function 26. Get Expanded Memory Hardware Information
  8622.           Get Unallocated Raw Page Count subfunction
  8623.  
  8624.  
  8625.  
  8626.           PURPOSE
  8627.  
  8628.                The Get Unallocated Raw Page Count subfunction returns the
  8629.                number of unallocated non-standard length mappable pages as
  8630.                well as the total number of non-standard length mappable
  8631.                pages in expanded memory to the operating system.
  8632.  
  8633.                One variety of expanded memory board has a page size which
  8634.                is a sub-multiple of 16K bytes.  An expanded memory page
  8635.                which is a sub-multiple of 16K is termed a raw page.  An
  8636.                operating system may deal with mappable physical page sizes
  8637.                which are sub-multiples of 16K bytes.
  8638.  
  8639.                If the expanded memory board supplies pages in exact
  8640.                multiples of 16K bytes, the number of pages this function
  8641.                returns is identical to the number Function 3 (Get Unallo-
  8642.                cated Page Count) returns.  In this case, there is no
  8643.                difference between a page and a raw page.
  8644.  
  8645.  
  8646.           CALLING PARAMETERS
  8647.  
  8648.                AX = 5901h
  8649.                    Contains the Get Unallocated Raw Page Count subfunction.
  8650.  
  8651.  
  8652.           RESULTS
  8653.  
  8654.                These results are valid only if the status returned is zero.
  8655.  
  8656.                BX = unallocated raw pages
  8657.                    The number of raw pages that are currently available for
  8658.                    use.
  8659.  
  8660.                DX = total raw pages
  8661.                    The total number of raw pages in expanded memory.
  8662.  
  8663.  
  8664.           REGISTERS MODIFIED
  8665.  
  8666.                AX, BX, DX
  8667.  
  8668.  
  8669.  
  8670.  
  8671.  
  8672.  
  8673.  
  8674.           EMM Functions                                                 142
  8675.  
  8676.  
  8677.  
  8678.  
  8679.  
  8680.           Function 26. Get Expanded Memory Hardware Information
  8681.           Get Unallocated Raw Page Count subfunction
  8682.  
  8683.  
  8684.  
  8685.           STATUS
  8686.  
  8687.                AH = 0   SUCCESSFUL.
  8688.                    The manager has returned the number of unallocated raw
  8689.                    pages and the number of total raw pages in expanded
  8690.                    memory.
  8691.  
  8692.                AH = 80h   NON-RECOVERABLE.
  8693.                    The manager detected a malfunction in the memory manager
  8694.                    software.
  8695.  
  8696.                AH = 81h   NON-RECOVERABLE.
  8697.                    The manager detected a malfunction in the expanded
  8698.                    memory hardware.
  8699.  
  8700.                AH = 84h   NON-RECOVERABLE.
  8701.                    The function code passed to the memory manager is not
  8702.                    defined.
  8703.  
  8704.                AH = 8Fh   NON-RECOVERABLE.
  8705.                    The subfunction parameter is invalid.
  8706.  
  8707.  
  8708.           EXAMPLE
  8709.  
  8710.           unalloc_raw_pages              DW ?
  8711.           total_raw_pages                DW ?
  8712.  
  8713.           MOV   AX,5901h                 ; load function code
  8714.           INT   67h                      ; call the memory manager
  8715.           OR    AH,AH                    ; check EMM status
  8716.           JNZ   emm_err_handler          ; jump to error handler on error
  8717.           MOV   unalloc_raw_pages,BX     ; save unallocated raw page count
  8718.           MOV   total_raw_pages,DX       ; save total raw page count
  8719.  
  8720.  
  8721.  
  8722.  
  8723.  
  8724.  
  8725.  
  8726.  
  8727.  
  8728.  
  8729.  
  8730.  
  8731.  
  8732.  
  8733.           EMM Functions                                                 143
  8734.  
  8735.  
  8736.  
  8737.  
  8738.  
  8739.           Function 27. Allocate Standard/Raw Pages
  8740.           Allocate Standard Pages subfunction
  8741.  
  8742.  
  8743.  
  8744.           PURPOSE
  8745.  
  8746.                The Allocate Standard Pages subfunction allocates the number
  8747.                of standard size (16K bytes) pages that the operating system
  8748.                requests and assigns a unique EMM handle to these pages. 
  8749.                The EMM handle owns these pages until the operating system
  8750.                deallocates them.  This subfunction allows you to allocate
  8751.                zero pages to a handle, unlike Function 4 (Allocate Pages).
  8752.  
  8753.           Note............................................................
  8754.                This note affects expanded memory manager implementors and
  8755.                operating system developers only.  Applications should not
  8756.                use the following characteristic of the memory manager.  An
  8757.                application violating this rule will be incompatible with
  8758.                future versions of Microsoft's operating systems and
  8759.                environments.
  8760.  
  8761.                To be compatible with this specification, an expanded memory
  8762.                manager will provide a special handle which is available to
  8763.                the operating system only.  This handle will have a value of
  8764.                0000h and will have a set of pages allocated to it when the
  8765.                expanded memory manager driver installs.  The pages that the
  8766.                memory manager will automatically allocate to handle 0000h
  8767.                are those that backfill conventional memory.  Typically,
  8768.                this backfill occurs between addresses 40000h (256K) and
  8769.                9FFFFh (640K).  However, the range can extend below and
  8770.                above this limit if the hardware and memory manager have the
  8771.                capability.
  8772.  
  8773.                An operating system won't have to invoke Function 27 to
  8774.                obtain this handle because it can assume the handle already
  8775.                exists and is available for use immediately after the
  8776.                expanded memory device driver installs.  When an operating
  8777.                system wants to use this handle, it uses the special handle
  8778.                value of 0000h.  The operating system will be able to invoke
  8779.                any EMM function using this special handle value.  To
  8780.                allocate pages to this handle, the operating system need
  8781.                only invoke Function 18 (Reallocate Pages).
  8782.  
  8783.                There are two special cases for this handle:
  8784.  
  8785.                1.  Function 27 (Allocate Standard Pages subfunction).  This
  8786.                    function must never return zero as a handle value. 
  8787.                    Applications must always invoke Function 27 to allocate
  8788.                    pages and obtain a handle which identifies the pages
  8789.                    which belong to it.  Since Function 27 never returns a
  8790.  
  8791.  
  8792.           EMM Functions                                                 144
  8793.  
  8794.  
  8795.  
  8796.  
  8797.  
  8798.           Function 27. Allocate Standard/Raw Pages
  8799.           Allocate Standard Pages subfunction
  8800.  
  8801.  
  8802.  
  8803.                    handle value of zero, an application will never gain
  8804.                    access to this special handle.
  8805.  
  8806.                2.  Function 6 (Deallocate Pages).  If the operating system
  8807.                    uses it to deallocate the pages which are allocated to
  8808.                    this handle, the pages the handle owns will be returned
  8809.                    to the manager for use.  But the handle will not be
  8810.                    available for reassignment.  The manager should treat a
  8811.                    deallocate pages function request for this handle the
  8812.                    same as a reallocate pages function request, where the
  8813.                    number of pages to reallocate to this handle is zero.
  8814.  
  8815.  
  8816.           CALLING PARAMETERS
  8817.  
  8818.                AX = 5A00h
  8819.                    Contains the Allocate Standard Pages subfunction.
  8820.  
  8821.                BX = num_of_standard_pages_to_alloc
  8822.                    Contains the number of standard pages the operating
  8823.                    system wants to allocate.
  8824.  
  8825.  
  8826.           RESULTS
  8827.  
  8828.                These results are valid only if the status returned is zero.
  8829.  
  8830.                DX = handle
  8831.                    Contains a unique EMM handle.  The operating system must
  8832.                    use this EMM handle as a parameter in any function that
  8833.                    requires it.  Up to 255 handles may be obtained.  (Both
  8834.                    Function 27 and Function 4 must share the same 255
  8835.                    handles.)
  8836.  
  8837.                    For all functions using this handle, the length of the
  8838.                    physical and logical pages allocated to it are standard
  8839.                    length (that is, 16K bytes).
  8840.  
  8841.  
  8842.           REGISTERS MODIFIED
  8843.  
  8844.                AX, DX
  8845.  
  8846.  
  8847.  
  8848.  
  8849.  
  8850.  
  8851.           EMM Functions                                                 145
  8852.  
  8853.  
  8854.  
  8855.  
  8856.  
  8857.           Function 27. Allocate Standard/Raw Pages
  8858.           Allocate Standard Pages subfunction
  8859.  
  8860.  
  8861.  
  8862.           STATUS
  8863.  
  8864.                AH = 0   SUCCESSFUL.
  8865.                    The manager has allocated the pages to an assigned EMM
  8866.                    standard handle.
  8867.  
  8868.                AH = 80h   NON-RECOVERABLE.
  8869.                    The manager detected a malfunction in the memory manager
  8870.                    software.
  8871.  
  8872.                AH = 81h   NON-RECOVERABLE.
  8873.                    The manager detected a malfunction in the expanded
  8874.                    memory hardware.
  8875.  
  8876.                AH = 84h   NON-RECOVERABLE.
  8877.                    The function code passed to the memory manager is not
  8878.                    defined.
  8879.  
  8880.                AH = 85h   RECOVERABLE.
  8881.                    All EMM handles are being used.
  8882.  
  8883.                AH = 87h   RECOVERABLE.
  8884.                    There aren't enough expanded memory pages present in the
  8885.                    system to satisfy the operating system's request.
  8886.  
  8887.                AH = 88h   RECOVERABLE.
  8888.                    There aren't enough unallocated pages to satisfy the
  8889.                    operating system's request.
  8890.  
  8891.                AH = 8Fh   NON-RECOVERABLE.
  8892.                    The subfunction parameter is invalid.
  8893.  
  8894.  
  8895.           EXAMPLE
  8896.  
  8897.           num_of_standard_pages_to_alloc      DW ?
  8898.           emm_handle                          DW ?
  8899.  
  8900.           MOV   BX,num_of_standard_pages_to_alloc
  8901.           MOV   AX,5A00h                      ; load function code
  8902.           INT   67h                           ; call the memory manager
  8903.           OR    AH,AH                         ; check EMM status
  8904.           JNZ   emm_err_handler               ; jump to error handler on
  8905.                                               ; error
  8906.           MOV   emm_handle,DX                 ; save handle
  8907.  
  8908.  
  8909.  
  8910.           EMM Functions                                                 146
  8911.  
  8912.  
  8913.  
  8914.  
  8915.  
  8916.           Function 27. Allocate Standard/Raw Pages
  8917.           Allocate Raw Pages subfunction
  8918.  
  8919.  
  8920.  
  8921.           PURPOSE
  8922.  
  8923.                The Allocate Raw Pages function allocates the number of non-
  8924.                standard size pages that the operating system requests and
  8925.                assigns a unique EMM handle to these pages.  The EMM handle
  8926.                owns these pages until the operating system deallocates
  8927.                them.  This function allows you to allocate zero pages to a
  8928.                handle, unlike Function 4 (Allocate Pages).
  8929.  
  8930.                A hardware vendor may design an expanded memory board that
  8931.                has a page size which is a sub-multiple of 16K bytes.  A
  8932.                physical page which is a sub-multiple of 16K is termed a raw
  8933.                page.  The operating system may deal with page sizes which
  8934.                are sub-multiples of 16K bytes.  The memory manager must
  8935.                treat any function using a handle with raw pages allocated
  8936.                to it by Function 27 (Allocate Raw Pages subfunction)
  8937.                differently than it does a handle that has normal 16K-byte
  8938.                pages allocated to it.
  8939.  
  8940.                Handles which are assigned using Function 4 (Allocate Pages)
  8941.                or Function 27 (Allocate Standard Pages subfunction) must
  8942.                have pages which are 16K bytes -- this is the length of a
  8943.                standard expanded memory page.  If the expanded memory board
  8944.                hardware is not able to supply 16K-byte pages, the memory
  8945.                manager must emulate pages which are 16K bytes combining
  8946.                multiple non-standard size pages to form a single 16K-byte
  8947.                page.
  8948.  
  8949.                Handles which are assigned using Function 27 (Allocate Raw
  8950.                Pages subfunction) are called raw handles.  All logical
  8951.                pages allocated to a raw handle may have a non-standard
  8952.                length (that is, not 16K bytes).  However, once the operat-
  8953.                ing system has allocated a number of raw pages to a handle,
  8954.                it is the responsibility of the memory manager to recognize
  8955.                that raw handle as one that has non-standard size pages
  8956.                allocated to it.  The memory manager must identify these
  8957.                handles and treat all functions which use handles which have
  8958.                non-standard page lengths differently.  The logical page
  8959.                length becomes the length of the non-standard size page for
  8960.                any raw handle that Function 27 assigns.
  8961.  
  8962.           Note............................................................
  8963.                This note affects expanded memory manager implementors and
  8964.                operating system developers only.  Applications should not
  8965.                use the following characteristic of the memory manager.  An
  8966.                application violating this rule will be incompatible with
  8967.  
  8968.  
  8969.           EMM Functions                                                 147
  8970.  
  8971.  
  8972.  
  8973.  
  8974.  
  8975.           Function 27. Allocate Standard/Raw Pages
  8976.           Allocate Raw Pages subfunction
  8977.  
  8978.  
  8979.  
  8980.                future versions of Microsoft's operating systems and
  8981.                environments.
  8982.  
  8983.                To be compatible with this specification, an expanded memory
  8984.                manager will provide a special handle which is available to
  8985.                the operating system only.  This handle will have a value of
  8986.                0000h and will have a set of pages allocated to it when the
  8987.                expanded memory manager driver installs.  The pages that the
  8988.                memory manager will automatically allocate to handle 0000h
  8989.                are those that backfill conventional memory.  Typically,
  8990.                this backfill occurs between addresses 40000h (256K) and
  8991.                9FFFFh (640K).  However, the range can extend below and
  8992.                above this limit if the hardware and memory manager have the
  8993.                capability.
  8994.  
  8995.                An operating system won't have to invoke Function 27 to
  8996.                obtain this handle because it can assume the handle already
  8997.                exists and is available for use immediately after the
  8998.                expanded memory device driver installs.  When an operating
  8999.                system wants to use this handle, it uses the special handle
  9000.                value of 0000h.  The operating system will be able to invoke
  9001.                any EMM function using this special handle value.  To
  9002.                allocate pages to this handle, the operating system need
  9003.                only invoke Function 18 (Reallocate Pages).
  9004.  
  9005.                There are two special cases for this handle:
  9006.  
  9007.                1.  Function 27 (Allocate Raw Pages subfunction).  This
  9008.                    function must never return zero as a handle value. 
  9009.                    Applications must always invoke Function 27 to allocate
  9010.                    pages and obtain a handle which identifies the pages
  9011.                    which belong to it.  Since Function 27 never returns a
  9012.                    handle value of zero, an application will never gain
  9013.                    access to this special handle.
  9014.  
  9015.                2.  Function 6 (Deallocate Pages).  If the operating system
  9016.                    uses it to deallocate the pages which are allocated to
  9017.                    this handle, the pages the handle owns will be returned
  9018.                    to the manager for use.  But the handle will not be
  9019.                    available for reassignment.  The manager should treat a
  9020.                    deallocate pages function request for this handle the
  9021.                    same as a reallocate pages function request, where the
  9022.                    number of pages to reallocate to this handle is zero.
  9023.  
  9024.  
  9025.  
  9026.  
  9027.  
  9028.           EMM Functions                                                 148
  9029.  
  9030.  
  9031.  
  9032.  
  9033.  
  9034.           Function 27. Allocate Standard/Raw Pages
  9035.           Allocate Raw Pages subfunction
  9036.  
  9037.  
  9038.  
  9039.           CALLING PARAMETERS
  9040.  
  9041.                AX = 5A01h
  9042.                    Contains the Allocate Raw Pages subfunction.
  9043.  
  9044.                BX = num_of_raw_pages_to_alloc
  9045.                    Contains the number of raw pages the operating system
  9046.                    wishes to allocate.
  9047.  
  9048.  
  9049.           RESULTS
  9050.  
  9051.                These results are valid only if the status returned is zero.
  9052.  
  9053.                DX = raw handle
  9054.                    Contains a unique EMM raw handle.  The operating system
  9055.                    must use this EMM raw handle as a parameter in any
  9056.                    function that requires it.  Up to 255 handles may be
  9057.                    obtained.  (Both Function 4 and Function 27 must share
  9058.                    the same 255 handles).
  9059.  
  9060.                    For all functions using this raw handle, the length of
  9061.                    the physical and logical pages allocated to it may be
  9062.                    non-standard (that is, not 16K bytes).
  9063.  
  9064.  
  9065.           REGISTERS MODIFIED
  9066.  
  9067.                AX, DX
  9068.  
  9069.  
  9070.           STATUS
  9071.  
  9072.                AH = 0   SUCCESSFUL.
  9073.                    The manager has allocated the raw pages to an assigned
  9074.                    EMM raw handle.
  9075.  
  9076.                AH = 80h   NON-RECOVERABLE.
  9077.                    The manager detected a malfunction in the memory manager
  9078.                    software.
  9079.  
  9080.                AH = 81h   NON-RECOVERABLE.
  9081.                    The manager detected a malfunction in the expanded
  9082.                    memory hardware.
  9083.  
  9084.  
  9085.  
  9086.  
  9087.           EMM Functions                                                 149
  9088.  
  9089.  
  9090.  
  9091.  
  9092.  
  9093.           Function 27. Allocate Standard/Raw Pages
  9094.           Allocate Raw Pages subfunction
  9095.  
  9096.  
  9097.  
  9098.                AH = 84h   NON-RECOVERABLE.
  9099.                    The function code passed to the memory manager is not
  9100.                    defined.
  9101.  
  9102.                AH = 85h   RECOVERABLE.
  9103.                    All EMM handles are being used.
  9104.  
  9105.                AH = 87h   RECOVERABLE.
  9106.                    There aren't enough expanded memory raw pages present in
  9107.                    the system to satisfy the operating system's request.
  9108.  
  9109.                AH = 88h   RECOVERABLE.
  9110.                    There aren't enough unallocated raw pages to satisfy the
  9111.                    operating system's request.
  9112.  
  9113.                AH = 8Fh   NON-RECOVERABLE.
  9114.                    The subfunction parameter is invalid.
  9115.  
  9116.  
  9117.           EXAMPLE
  9118.  
  9119.           num_of_raw_pages_to_alloc           DW ?
  9120.           emm_raw_handle                      DW ?
  9121.  
  9122.           MOV   BX,num_of_raw_pages_to_alloc
  9123.           MOV   AX,5A01h                      ; load function code
  9124.           INT   67h                           ; call the memory manager
  9125.           OR    AH,AH                         ; check EMM status
  9126.           JNZ   emm_err_handler               ; jump to error handler
  9127.                                               ; on error
  9128.           MOV   emm_raw_handle,DX             ; save raw handle
  9129.  
  9130.  
  9131.  
  9132.  
  9133.  
  9134.  
  9135.  
  9136.  
  9137.  
  9138.  
  9139.  
  9140.  
  9141.  
  9142.  
  9143.  
  9144.  
  9145.  
  9146.           EMM Functions                                                 150
  9147.  
  9148.  
  9149.  
  9150.  
  9151.  
  9152.           Function 28. Alternate Map Register Set
  9153.  
  9154.  
  9155.  
  9156.           Note............................................................
  9157.                This function is for use by operating systems only.  The
  9158.                operating system can disable this function at any time. 
  9159.                Refer to Function 30 for a description of how an operating
  9160.                system can enable or disable this function.
  9161.  
  9162.  
  9163.           Design Considerations
  9164.  
  9165.                The hardware support for the entire set of subfunctions
  9166.                described is generally not present on every expanded memory
  9167.                board from every vendor of expanded memory board products. 
  9168.                For some of the subfunctions, software emulation is provid-
  9169.                ed.  For other subfunctions, a certain protocol in their use
  9170.                must be observed.  The subfunctions for which this is most
  9171.                crucial are those which address system DMA capabilities.
  9172.  
  9173.  
  9174.           System DMA Capabilities & Expanded Memory Support of DMA
  9175.  
  9176.                In a multitasking operating system, when one task is waiting
  9177.                for DMA to complete, it is useful to be able to switch to
  9178.                another task.  This specification describes a capability
  9179.                which may be designed into expanded memory boards to provide
  9180.                DMA into memory regions which may be mapped out while the
  9181.                DMA is occurring.  For expanded memory boards that do not
  9182.                provide this, it is crucial to understand that while DMA is
  9183.                in progress into a region of mappable memory, the memory
  9184.                mapping context cannot be changed.  That is, all DMA action
  9185.                must be complete before any remapping of pages can be done.
  9186.  
  9187.  
  9188.           Expanded Memory Support of DMA Register Sets
  9189.  
  9190.                Expanded memory boards which have DMA register sets could
  9191.                support DMA into a region of mappable memory while the
  9192.                memory mapping context is being switched.  It is important
  9193.                to realize that these DMA register sets are separate from
  9194.                the alternate map register sets.  An example of how an OS/E
  9195.                might use DMA register sets follows:
  9196.  
  9197.                                       Example 1
  9198.  
  9199.                1.  Allocate a DMA register set.
  9200.  
  9201.                2.  Get current register set.
  9202.  
  9203.                3.  Set the DMA register set.
  9204.  
  9205.           EMM Functions                                                 151
  9206.  
  9207.  
  9208.  
  9209.  
  9210.  
  9211.           Function 28. Alternate Map Register Set
  9212.  
  9213.  
  9214.  
  9215.                4.  Map in the memory desired.
  9216.  
  9217.                5.  Get the DMA register set.
  9218.  
  9219.                6.  Set the original register set.
  9220.  
  9221.                7.  Assign the desired DMA channel to the DMA register set.
  9222.  
  9223.                The preceding set of calls makes all DMA accesses for the
  9224.                desired DMA channel get mapped through the current DMA
  9225.                register set regardless of the current register set.  In
  9226.                other words, the DMA register set overrides the current
  9227.                mapping register set for DMA operations on the DMA channel
  9228.                specified.  A DMA channel that is not assigned to a DMA
  9229.                register set has all its DMA operations mapped through the
  9230.                current mapping register set.
  9231.  
  9232.  
  9233.  
  9234.  
  9235.  
  9236.  
  9237.  
  9238.  
  9239.  
  9240.  
  9241.  
  9242.  
  9243.  
  9244.  
  9245.  
  9246.  
  9247.  
  9248.  
  9249.  
  9250.  
  9251.  
  9252.  
  9253.  
  9254.  
  9255.  
  9256.  
  9257.  
  9258.  
  9259.  
  9260.  
  9261.  
  9262.  
  9263.  
  9264.           EMM Functions                                                 152
  9265.  
  9266.  
  9267.  
  9268.  
  9269.  
  9270.           Function 28. Alternate Map Register Set
  9271.           Get Alternate Map Register Set subfunction
  9272.  
  9273.  
  9274.  
  9275.           Note............................................................
  9276.                This function is for use by operating systems only.  The
  9277.                operating system can disable this function at any time. 
  9278.                Refer to Function 30 for a description of how an operating
  9279.                system can enable or disable this function.
  9280.  
  9281.  
  9282.           PURPOSE
  9283.  
  9284.                The subfunction does one of two things depending on the map
  9285.                register set which is active at the time this function is
  9286.                invoked:
  9287.  
  9288.                1.  If the preceding Set Alternate Map Register Set call was
  9289.                    done with the alternate map register set equal to zero
  9290.                    (BL = 0), these points apply:
  9291.  
  9292.                    a.  The context save area pointer saved within EMM by
  9293.                        the Set Alternate Map Register subfunction is
  9294.                        returned by this call.  This pointer is always
  9295.                        returned for boards which do not supply alternate
  9296.                        mapping register sets.
  9297.  
  9298.                    b.  If the context save area pointer returned is not
  9299.                        equal to zero, this subfunction copies the contents
  9300.                        of the mapping registers on each expanded memory
  9301.                        board in the system into the save area specified by
  9302.                        the pointer.  The format of this save area is the
  9303.                        same as that returned by Function 15 (Get Page Map
  9304.                        subfunction).  This is intended to simulate getting
  9305.                        an alternate map register set.  Note that the memory
  9306.                        manager does not allocate the space for the context: 
  9307.                        the operating system must do so.
  9308.  
  9309.                    c.  If the context save area pointer returned is equal
  9310.                        to zero, this subfunction does not copy the contents
  9311.                        of the mapping registers on each expanded memory
  9312.                        board in the system into the save area specified by
  9313.                        the pointer.
  9314.  
  9315.                    d.  The context save area pointer must have been
  9316.                        initialized by a previous Set Alternate Map Register
  9317.                        Set call.  Note that the value of the context save
  9318.                        area pointer saved within EMM is zero immediately
  9319.                        after installation.
  9320.  
  9321.  
  9322.  
  9323.           EMM Functions                                                 153
  9324.  
  9325.  
  9326.  
  9327.  
  9328.  
  9329.           Function 28. Alternate Map Register Set
  9330.           Get Alternate Map Register Set subfunction
  9331.  
  9332.  
  9333.  
  9334.                    e.  The context save area must be initialized by a
  9335.                        previous Get Page Map call (Function 15).
  9336.  
  9337.                2.  If the preceding Set Alternate Map Register Set call was
  9338.                    done with the alternate map register set greater than
  9339.                    zero (BL > 0), then the number of the alternate map
  9340.                    register set which is in use at the time that this
  9341.                    function is invoked is returned.  The context save area
  9342.                    pointer is not returned in this case.
  9343.  
  9344.  
  9345.           CALLING PARAMETERS
  9346.  
  9347.                AX = 5B00h
  9348.                    Contains the Get Alternate Map Register Set subfunction.
  9349.  
  9350.  
  9351.           RESULTS
  9352.  
  9353.                These results are valid only if the status returned is zero.
  9354.  
  9355.                If BL <> 0, current active alternate map register set number
  9356.                    Contains the alternate map register set which was active
  9357.                    at the time that this function was invoked.
  9358.  
  9359.                ES:DI   Unaffected.
  9360.  
  9361.                If BL = 0
  9362.                    Indicates that a pointer to an area which contains the
  9363.                    state of all the map registers on all boards in the
  9364.                    system, and any additional information necessary to
  9365.                    restore the boards to their original state, has been
  9366.                    returned.
  9367.  
  9368.                ES:DI = pointer to a map register context save area
  9369.                    Contains a pointer to an operating system supplied
  9370.                    context save area.  The pointer is in standard seg-
  9371.                    ment:offset format.  This pointer is always returned if
  9372.                    the expanded memory hardware does not supply alternate
  9373.                    mapping register sets.
  9374.  
  9375.  
  9376.  
  9377.  
  9378.  
  9379.  
  9380.  
  9381.  
  9382.           EMM Functions                                                 154
  9383.  
  9384.  
  9385.  
  9386.  
  9387.  
  9388.           Function 28. Alternate Map Register Set
  9389.           Get Alternate Map Register Set subfunction
  9390.  
  9391.  
  9392.  
  9393.                    The operating system first passes this pointer to the
  9394.                    memory manager whenever it invokes a Set Alternate Map
  9395.                    Register Set subfunction (the description follows).  If
  9396.                    the OS/E invokes this function before invoking a Set
  9397.                    Alternate Map Register Set subfunction, this function
  9398.                    returns a pointer value of zero.  The OS/E must have
  9399.                    allocated the space for the save area.  However, the OS
  9400.                    must request that the memory manager initialize the
  9401.                    contents of this save area before it contains any useful
  9402.                    information.
  9403.  
  9404.                    The OS/E must initialize the save area it has allocated
  9405.                    by invoking Function 15 (Get Page Map subfunction). 
  9406.                    After the OS/E has done this, the save area will contain
  9407.                    the state of all the map registers on all boards in the
  9408.                    system.  The save area will also contain any additional
  9409.                    information necessary to restore the boards to their
  9410.                    original state when the operating system invokes a Set
  9411.                    Alternate Map Register Set subfunction.
  9412.  
  9413.  
  9414.           REGISTERS MODIFIED
  9415.  
  9416.                AX, BX, ES:DI
  9417.  
  9418.  
  9419.           STATUS
  9420.  
  9421.                AH = 0   SUCCESSFUL.
  9422.                    The manager got the alternate map register set.
  9423.  
  9424.                AH = 80h   NON-RECOVERABLE.
  9425.                    The manager detected a malfunction in the memory manager
  9426.                    software.
  9427.  
  9428.                AH = 81h   NON-RECOVERABLE.
  9429.                    The manager detected a malfunction in the expanded
  9430.                    memory hardware.
  9431.  
  9432.                AH = 84h   NON-RECOVERABLE.
  9433.                    The function code passed to the memory manager is not
  9434.                    defined.
  9435.  
  9436.                AH = 8Fh   NON-RECOVERABLE.
  9437.                    The subfunction parameter is invalid.
  9438.  
  9439.  
  9440.  
  9441.           EMM Functions                                                 155
  9442.  
  9443.  
  9444.  
  9445.  
  9446.  
  9447.           Function 28. Alternate Map Register Set
  9448.           Get Alternate Map Register Set subfunction
  9449.  
  9450.  
  9451.  
  9452.                AH = A4h   NON-RECOVERABLE.
  9453.                    The operating system denied access to this function. 
  9454.                    The function cannot be used at this time.
  9455.  
  9456.  
  9457.           EXAMPLE
  9458.  
  9459.           alt_map_reg_set                        DB ?
  9460.           context_save_area_ptr_seg              DW ?
  9461.           context_save_area_ptr_offset           DW ?
  9462.  
  9463.           MOV   AX,5B00h                         ; load function code
  9464.           INT   67h                              ; call the memory manager
  9465.           OR    AH,AH                            ; check EMM status
  9466.           JNZ   emm_err_handler                  ; jump to error handler
  9467.                                                  ; on error
  9468.           MOV   alt_map_reg_set,BL
  9469.           TEST  BL,BL
  9470.           JNZ   no_ptr_returned
  9471.  
  9472.           MOV   context_save_area_ptr_seg,ES     ; save pointer values
  9473.           MOV   context_save_area_ptr_offset,DI
  9474.  
  9475.           no_ptr_returned:
  9476.  
  9477.  
  9478.  
  9479.  
  9480.  
  9481.  
  9482.  
  9483.  
  9484.  
  9485.  
  9486.  
  9487.  
  9488.  
  9489.  
  9490.  
  9491.  
  9492.  
  9493.  
  9494.  
  9495.  
  9496.  
  9497.  
  9498.  
  9499.  
  9500.           EMM Functions                                                 156
  9501.  
  9502.  
  9503.  
  9504.  
  9505.  
  9506.           Function 28. Alternate Map Register Set
  9507.           Set Alternate Map Register Set subfunction
  9508.  
  9509.  
  9510.  
  9511.           Note............................................................
  9512.                This function is for use by operating systems only.  The
  9513.                operating system can disable this function at any time. 
  9514.                Refer to Function 30 for a description of how an operating
  9515.                system can enable or disable this function.
  9516.  
  9517.  
  9518.           PURPOSE
  9519.  
  9520.                The subfunction does one of two things, depending on the map
  9521.                register set specified:
  9522.  
  9523.                1.  If the alternate map register set specified is zero, map
  9524.                    register set zero is activated.  If the map register
  9525.                    context restore area pointer is not equal to zero, the
  9526.                    contents of the restore area pointed to by ES:DI are
  9527.                    copied into register set zero on each expanded memory
  9528.                    board in the system.  If the pointer is equal to zero,
  9529.                    the contents are not copied.
  9530.  
  9531.                    Regardless of its value, the map register context
  9532.                    restore area pointer is saved within the memory manager. 
  9533.                    It will be used during the Get Alternate Map Register
  9534.                    Set subfunction.
  9535.  
  9536.                    The operating system must supply the pointer to the
  9537.                    area.  This subfunction is intended to simulate setting
  9538.                    an alternate map register set.  Note that the operating
  9539.                    system must allocate the space for the context.  The
  9540.                    memory manager saves the context save area pointer
  9541.                    internally.
  9542.  
  9543.                2.  If the alternate map register set specified is not zero,
  9544.                    the alternate map register set specified is activated. 
  9545.                    The restore area, which the operating system is pointing
  9546.                    to, is not used.
  9547.  
  9548.  
  9549.           CALLING PARAMETERS
  9550.  
  9551.                AX = 5B01h
  9552.                    Contains the Set Alternate Map Register Set subfunction.
  9553.  
  9554.  
  9555.  
  9556.  
  9557.  
  9558.  
  9559.           EMM Functions                                                 157
  9560.  
  9561.  
  9562.  
  9563.  
  9564.  
  9565.           Function 28. Alternate Map Register Set
  9566.           Set Alternate Map Register Set subfunction
  9567.  
  9568.  
  9569.  
  9570.                BL = new alternate map register set number
  9571.                    Contains the number of the alternate map register set
  9572.                    which is to be activated.
  9573.  
  9574.                    If BL <> 0
  9575.                        A pointer to a map register context restore area is
  9576.                        not required and the contents of ES:DI is unaffected
  9577.                        and ignored.  The alternate map register set
  9578.                        specified in BL is activated if the board supports
  9579.                        it.
  9580.  
  9581.                    If BL = 0
  9582.                        A pointer to an area which contains the state of all
  9583.                        the map registers on all boards in the system, and
  9584.                        any additional information necessary to restore the
  9585.                        boards to their original state, has been passed in
  9586.                        ES:DI.
  9587.  
  9588.                ES:DI = pointer to a map register context restore area
  9589.                    Contains a pointer to an OS/E supplied map register
  9590.                    context restore area.  The pointer is in standard
  9591.                    segment:offset format.  This pointer must always be
  9592.                    passed if the expanded memory hardware does not supply
  9593.                    alternate mapping register sets.
  9594.  
  9595.                    The memory manager must save this pointer whenever the
  9596.                    OS/E invokes this function.  The OS/E must have allo-
  9597.                    cated the space for the restore area.  Additionally, the
  9598.                    contents of this restore area must have been initialized
  9599.                    by the memory manager before it will contain any useful
  9600.                    information.  The OS/E initializes the restore area it
  9601.                    has allocated by invoking Function 15 (Get Page Map
  9602.                    subfunction).  After the OS/E has done this, the restore
  9603.                    area will contain the state of the map registers on all
  9604.                    boards in the system, and any additional information
  9605.                    necessary to restore the boards to their original state
  9606.                    when the operating system invokes a Set Alternate Map
  9607.                    Register Set subfunction.
  9608.  
  9609.  
  9610.           REGISTERS MODIFIED
  9611.  
  9612.                AX
  9613.  
  9614.  
  9615.  
  9616.  
  9617.  
  9618.           EMM Functions                                                 158
  9619.  
  9620.  
  9621.  
  9622.  
  9623.  
  9624.           Function 28. Alternate Map Register Set
  9625.           Set Alternate Map Register Set subfunction
  9626.  
  9627.  
  9628.  
  9629.           STATUS
  9630.  
  9631.                AH = 0   SUCCESSFUL.
  9632.                    The manager set the alternate map register set.
  9633.  
  9634.                AH = 80h   NON-RECOVERABLE.
  9635.                    The manager detected a malfunction in the memory manager
  9636.                    software.
  9637.  
  9638.                AH = 81h   NON-RECOVERABLE.
  9639.                    The manager detected a malfunction in the expanded
  9640.                    memory hardware.
  9641.  
  9642.                AH = 84h   NON-RECOVERABLE.
  9643.                    The function code passed to the memory manager is not
  9644.                    defined.
  9645.  
  9646.                AH = 8Fh   NON-RECOVERABLE.
  9647.                    The subfunction parameter is invalid.
  9648.  
  9649.                AH = 9Ah   NON-RECOVERABLE.
  9650.                    Alternate map register sets are supported, but the
  9651.                    alternate map register set specified is not supported.
  9652.  
  9653.                AH = 9Ch   NON-RECOVERABLE.
  9654.                    Alternate map register sets are not supported, and the
  9655.                    alternate map register set specified is not zero.
  9656.  
  9657.                AH = 9Dh   NON-RECOVERABLE.
  9658.                    Alternate map register sets are supported, but the
  9659.                    alternate map register set specified is either not
  9660.                    defined or not allocated.
  9661.  
  9662.                AH = A3h   NON-RECOVERABLE.
  9663.                    The contents of the source array have been corrupted, or
  9664.                    the pointer passed to the subfunction is invalid.
  9665.  
  9666.                AH = A4h   NON-RECOVERABLE.
  9667.                    The operating system has denied access to this function. 
  9668.                    The function cannot be used at this time.
  9669.  
  9670.  
  9671.  
  9672.  
  9673.  
  9674.  
  9675.  
  9676.  
  9677.           EMM Functions                                                 159
  9678.  
  9679.  
  9680.  
  9681.  
  9682.  
  9683.           Function 28. Alternate Map Register Set
  9684.           Set Alternate Map Register Set subfunction
  9685.  
  9686.  
  9687.  
  9688.           EXAMPLE
  9689.  
  9690.           alt_map_reg_set                        DB ?
  9691.           context_restore_area_ptr_seg           DW ?
  9692.           context_restore_area_ptr_offset        DW ?
  9693.  
  9694.           MOV   AX,5B01h                         ; load function code
  9695.           MOV   BL,alt_map_reg_set
  9696.           TEST  BL,BL
  9697.           JZ    no_ptr_passed
  9698.  
  9699.           MOV   ES,context_restore_area_ptr_seg
  9700.           MOV   DI,context_restore_area_ptr_offset
  9701.  
  9702.           no_ptr_passed:
  9703.  
  9704.           INT   67h                              ; call the memory manger
  9705.           OR    AH,AH                            ; check EMM status
  9706.           JNZ   emm_err_handler                  ; jump to error handler
  9707.                                                  ; on error
  9708.  
  9709.  
  9710.  
  9711.  
  9712.  
  9713.  
  9714.  
  9715.  
  9716.  
  9717.  
  9718.  
  9719.  
  9720.  
  9721.  
  9722.  
  9723.  
  9724.  
  9725.  
  9726.  
  9727.  
  9728.  
  9729.  
  9730.  
  9731.  
  9732.  
  9733.  
  9734.  
  9735.  
  9736.           EMM Functions                                                 160
  9737.  
  9738.  
  9739.  
  9740.  
  9741.  
  9742.           Function 28. Alternate Map Register Set
  9743.           Get Alternate Map Save Array Size subfunction
  9744.  
  9745.  
  9746.  
  9747.           Note............................................................
  9748.                This function is for use by operating systems only.  The
  9749.                operating system can disable this function at any time. 
  9750.                Refer to Function 30 for a description of how an operating
  9751.                system can enable or disable this function.
  9752.  
  9753.  
  9754.           PURPOSE
  9755.  
  9756.                This subfunction returns the storage requirements for the
  9757.                map register context save area referenced by the other
  9758.                subfunctions.
  9759.  
  9760.  
  9761.           CALLING PARAMETERS
  9762.  
  9763.                AX = 5B02h
  9764.                    Contains the Get Alternate Map Save Array Size subfunc-
  9765.                    tion.
  9766.  
  9767.  
  9768.           RESULTS
  9769.  
  9770.                These results are valid only if the status returned is zero.
  9771.  
  9772.                DX = size_of_array
  9773.                    Contains the number of bytes that will be transferred to
  9774.                    the memory area supplied by an operating system whenever
  9775.                    an operating system requests the Get, Set, or Get and
  9776.                    Set subfunction.
  9777.  
  9778.  
  9779.           REGISTERS MODIFIED
  9780.  
  9781.                AX, DX
  9782.  
  9783.  
  9784.           STATUS
  9785.  
  9786.                AH = 0   SUCCESSFUL.
  9787.                    The manager has returned the array size.
  9788.  
  9789.                AH = 80h   NON-RECOVERABLE.
  9790.                    The manager detected a malfunction in the memory manager
  9791.                    software.
  9792.  
  9793.  
  9794.  
  9795.           EMM Functions                                                 161
  9796.  
  9797.  
  9798.  
  9799.  
  9800.  
  9801.           Function 28. Alternate Map Register Set
  9802.           Get Alternate Map Save Array Size subfunction
  9803.  
  9804.  
  9805.  
  9806.                AH = 81h   NON-RECOVERABLE.
  9807.                    The manager detected a malfunction in the expanded
  9808.                    memory hardware.
  9809.  
  9810.                AH = 84h   NON-RECOVERABLE.
  9811.                    The function code passed to the memory manager is not
  9812.                    defined.
  9813.  
  9814.                AH = 8Fh   NON-RECOVERABLE.
  9815.                    The subfunction parameter is invalid.
  9816.  
  9817.                AH = A4h   NON-RECOVERABLE.
  9818.                    The operating system has denied access to this function. 
  9819.                    The function cannot be used at this time.
  9820.  
  9821.  
  9822.           EXAMPLE
  9823.  
  9824.           size_of_array                  DW ?
  9825.  
  9826.           MOV   AX,5B02h                 ; load function code
  9827.           INT   67h                      ; call the memory manager
  9828.           OR    AH,AH                    ; check EMM status
  9829.           JNZ   emm_err_handler          ; jump to error handler on error
  9830.           MOV   size_of_array,DX         ; save size of array
  9831.  
  9832.  
  9833.  
  9834.  
  9835.  
  9836.  
  9837.  
  9838.  
  9839.  
  9840.  
  9841.  
  9842.  
  9843.  
  9844.  
  9845.  
  9846.  
  9847.  
  9848.  
  9849.  
  9850.  
  9851.  
  9852.  
  9853.  
  9854.           EMM Functions                                                 162
  9855.  
  9856.  
  9857.  
  9858.  
  9859.  
  9860.           Function 28. Alternate Map Register Set
  9861.           Allocate Alternate Map Register Set subfunction
  9862.  
  9863.  
  9864.  
  9865.           Note............................................................
  9866.                This function is for use by operating systems only.  The
  9867.                operating system can disable this function at any time. 
  9868.                Refer to Function 30 for a description of how an operating
  9869.                system can enable or disable this function.
  9870.  
  9871.  
  9872.           PURPOSE
  9873.  
  9874.                The Allocate Alternate Map Register Set subfunction gets the
  9875.                number of an alternate map register set for an operating
  9876.                system if an alternate map register set is currently
  9877.                available for use.  If the hardware does not support
  9878.                alternate map register sets, an alternate map register set
  9879.                number of zero will be returned.
  9880.  
  9881.                The alternate map register set allocated may be referred to
  9882.                by this number when using the Get or Set Alternate Map
  9883.                Register Set subfunctions.  The operating system can use
  9884.                these subfunctions to switch map contexts very rapidly on
  9885.                expanded memory boards with alternate map register sets.
  9886.  
  9887.                This subfunction copies the currently active alternate map
  9888.                register set's contents into the newly allocated alternate
  9889.                map register set's mapping registers.  This is done so that
  9890.                when the OS/E performs a Set Alternate Map Register Set
  9891.                subfunction the memory mapped before the allocation of the
  9892.                new alternate map will be available for reading and writing. 
  9893.                This function does not actually change the alternate map
  9894.                register set in use, but in addition to allocating a new
  9895.                alternate map register set, it prepares the new alternate
  9896.                map register set for a subsequent Set Alternate Map Register
  9897.                Set subfunction.
  9898.  
  9899.  
  9900.           CALLING PARAMETERS
  9901.  
  9902.                AX = 5B03h
  9903.                    Contains the Allocate Alternate Map Register Set
  9904.                    subfunction.
  9905.  
  9906.  
  9907.  
  9908.  
  9909.  
  9910.  
  9911.  
  9912.  
  9913.           EMM Functions                                                 163
  9914.  
  9915.  
  9916.  
  9917.  
  9918.  
  9919.           Function 28. Alternate Map Register Set
  9920.           Allocate Alternate Map Register Set subfunction
  9921.  
  9922.  
  9923.  
  9924.           RESULTS
  9925.  
  9926.                These results are valid only if the status returned is zero.
  9927.  
  9928.                BL = alternate map register set number
  9929.                    Contains the number of an alternate map register set. 
  9930.                    If there are no alternate map register sets supported by
  9931.                    the hardware, a zero will be returned.  In this case,
  9932.                    the Get Alternate Map function (Function 28) should be
  9933.                    invoked in order to obtain a pointer to a map register
  9934.                    context save area.  The OS/E must supply this area.  The
  9935.                    save area is necessary because the hardware doesn't
  9936.                    support alternate map register sets.
  9937.  
  9938.  
  9939.           REGISTERS MODIFIED
  9940.  
  9941.                AX, BX
  9942.  
  9943.  
  9944.           STATUS
  9945.  
  9946.                AH = 0   SUCCESSFUL.
  9947.                    The manager has returned the alternate map register set
  9948.                    number.
  9949.  
  9950.                AH = 80h   NON-RECOVERABLE.
  9951.                    The manager detected a malfunction in the memory manager
  9952.                    software.
  9953.  
  9954.                AH = 81h   NON-RECOVERABLE.
  9955.                    The manager detected a malfunction in the expanded
  9956.                    memory hardware.
  9957.  
  9958.                AH = 84h   NON-RECOVERABLE.
  9959.                    The function code passed to the memory manager is not
  9960.                    defined.
  9961.  
  9962.                AH = 8Fh   NON-RECOVERABLE.
  9963.                    The subfunction parameter is invalid.
  9964.  
  9965.                AH = 9Bh   NON-RECOVERABLE.
  9966.                    Alternate map register sets are supported.  However, all
  9967.                    alternate map register sets are currently allocated.
  9968.  
  9969.  
  9970.  
  9971.  
  9972.           EMM Functions                                                 164
  9973.  
  9974.  
  9975.  
  9976.  
  9977.  
  9978.           Function 28. Alternate Map Register Set
  9979.           Allocate Alternate Map Register Set subfunction
  9980.  
  9981.  
  9982.  
  9983.                AH = A4h   NON-RECOVERABLE.
  9984.                    The operating system has denied access to this function. 
  9985.                    The function cannot be used at this time.
  9986.  
  9987.  
  9988.           EXAMPLE
  9989.  
  9990.           alt_map_reg_num                DB ?
  9991.  
  9992.           MOV   AX,5B03h                 ; load function code
  9993.           INT   67h                      ; call the memory manager
  9994.           OR    AH,AH                    ; check EMM status
  9995.           JNZ   emm_err_handler          ; jump to error handler on error
  9996.           MOV   alt_map_reg_num,BL       ; save number of
  9997.                                          ; alternate map register set
  9998.  
  9999.  
  10000.  
  10001.  
  10002.  
  10003.  
  10004.  
  10005.  
  10006.  
  10007.  
  10008.  
  10009.  
  10010.  
  10011.  
  10012.  
  10013.  
  10014.  
  10015.  
  10016.  
  10017.  
  10018.  
  10019.  
  10020.  
  10021.  
  10022.  
  10023.  
  10024.  
  10025.  
  10026.  
  10027.  
  10028.  
  10029.  
  10030.  
  10031.           EMM Functions                                                 165
  10032.  
  10033.  
  10034.  
  10035.  
  10036.  
  10037.           Function 28. Alternate Map Register Set
  10038.           Deallocate Alternate Map Register Set subfunction
  10039.  
  10040.  
  10041.  
  10042.           Note............................................................
  10043.                This function is for use by operating systems only.  The
  10044.                operating system can disable this function at any time. 
  10045.                Refer to Function 30 for a description of how an operating
  10046.                system can enable or disable this function.
  10047.  
  10048.  
  10049.           PURPOSE
  10050.  
  10051.                The Deallocate Alternate Map Register Set subfunction
  10052.                returns the alternate map register set to the memory manager
  10053.                for future use.  The memory manager may reallocate the
  10054.                alternate map register set when needed.
  10055.  
  10056.                This subfunction also makes the mapping context of the
  10057.                alternate map register specified unavailable for reading or
  10058.                writing (unmapping).  This protects the pages previously
  10059.                mapped in an alternate map register set by making them
  10060.                inaccessible.  Note that the current alternate map register
  10061.                set cannot be deallocated.  This makes all memory which was
  10062.                currently mapped into conventional and expanded memory
  10063.                inaccessible.
  10064.  
  10065.  
  10066.           CALLING PARAMETERS
  10067.  
  10068.                AX = 5B04h
  10069.                    Contains the Deallocate Alternate Map Register Set
  10070.                    subfunction.
  10071.  
  10072.                BL = alternate register set number
  10073.                    Contains the number of the alternate map register set to
  10074.                    deallocate.  Map register set zero cannot be allocated
  10075.                    or deallocated.  However, if alternate map register set
  10076.                    zero is specified and this subfunction is invoked, no
  10077.                    error will be returned.  The function invocation is
  10078.                    ignored in this case.
  10079.  
  10080.  
  10081.           REGISTERS MODIFIED
  10082.  
  10083.                AX
  10084.  
  10085.  
  10086.  
  10087.  
  10088.  
  10089.  
  10090.           EMM Functions                                                 166
  10091.  
  10092.  
  10093.  
  10094.  
  10095.  
  10096.           Function 28. Alternate Map Register Set
  10097.           Deallocate Alternate Map Register Set subfunction
  10098.  
  10099.  
  10100.  
  10101.           STATUS
  10102.  
  10103.                AH = 0   SUCCESSFUL.
  10104.                    The manager has deallocated the alternate map register
  10105.                    set.
  10106.  
  10107.                AH = 80h   NON-RECOVERABLE.
  10108.                    The manager detected a malfunction in the memory manager
  10109.                    software.
  10110.  
  10111.                AH = 81h   NON-RECOVERABLE.
  10112.                    The manager detected a malfunction in the expanded
  10113.                    memory hardware.
  10114.  
  10115.                AH = 84h   NON-RECOVERABLE.
  10116.                    The function code passed to the memory manager is not
  10117.                    defined.
  10118.  
  10119.                AH = 8Fh   NON-RECOVERABLE.
  10120.                    The subfunction parameter is invalid.
  10121.  
  10122.                AH = 9Ch   NON-RECOVERABLE.
  10123.                    Alternate map register sets are not supported and the
  10124.                    alternate map register set specified is not zero.
  10125.  
  10126.                AH = 9Dh   NON-RECOVERABLE.
  10127.                    Alternate map register sets are supported, but the
  10128.                    alternate map register set specified is either not
  10129.                    defined or not allocated.
  10130.  
  10131.                AH = A4h   NON-RECOVERABLE.
  10132.                    The operating system has denied access to this function. 
  10133.                    The function cannot be used at this time.
  10134.  
  10135.  
  10136.           EXAMPLE
  10137.  
  10138.           alternate_map_reg_set               DB ?
  10139.  
  10140.           MOV   BL,alternate_map_reg_set      ; specify alternate map
  10141.                                               ; register set
  10142.           MOV   AX,5B04h                      ; load function code
  10143.           INT   67h                           ; call the memory manager
  10144.           OR    AH,AH                         ; check EMM status
  10145.           JNZ   emm_err_handler               ; jump to error handler
  10146.                                               ; on error
  10147.  
  10148.  
  10149.           EMM Functions                                                 167
  10150.  
  10151.  
  10152.  
  10153.  
  10154.  
  10155.           Function 28. Alternate Map Register Set
  10156.           Allocate DMA Register Set subfunction
  10157.  
  10158.  
  10159.  
  10160.           Note............................................................
  10161.                This function is for use by operating systems only.  The
  10162.                operating system can disable this function at any time. 
  10163.                Refer to Function 30 for a description of how an operating
  10164.                system can enable or disable this function.
  10165.  
  10166.  
  10167.           PURPOSE
  10168.  
  10169.                The Allocate DMA Register Set subfunction gets the number of
  10170.                a DMA register set for an OS/E, if a DMA register set is
  10171.                currently available for use.  If the hardware does not
  10172.                support DMA register sets, a DMA register set number of zero
  10173.                will be returned.
  10174.  
  10175.                In a multitasking operating system, when one task is waiting
  10176.                for DMA to complete, it is useful to be able to switch to
  10177.                another task.  However, if the DMA is being mapped through
  10178.                the current register set, the switching cannot occur.  That
  10179.                is, all DMA action must be complete before any remapping of
  10180.                pages can be done.
  10181.  
  10182.                The operating system would initiate a DMA operation on a
  10183.                specific DMA channel using a specific alternate map register
  10184.                set.  This alternate map register set would not be used
  10185.                again, by the operating system or an application, until
  10186.                after the DMA operation is complete.  The operating system
  10187.                guarantees this by not changing the contents of the alter-
  10188.                nate map register set, or allowing an application to change
  10189.                the contents of the alternate map register set, for the
  10190.                duration of the DMA operation.
  10191.  
  10192.  
  10193.           CALLING PARAMETERS
  10194.  
  10195.                AX = 5B05h
  10196.                    Contains the Allocate DMA Register Set subfunction.
  10197.  
  10198.  
  10199.           RESULTS
  10200.  
  10201.                These results are valid only if the status returned is zero.
  10202.  
  10203.                BL = DMA register set number
  10204.                    Contains the number of a DMA register set.  If there are
  10205.                    no DMA register sets supported by the hardware, a zero
  10206.                    will be returned.
  10207.  
  10208.           EMM Functions                                                 168
  10209.  
  10210.  
  10211.  
  10212.  
  10213.  
  10214.           Function 28. Alternate Map Register Set
  10215.           Allocate DMA Register Set subfunction
  10216.  
  10217.  
  10218.  
  10219.           REGISTERS MODIFIED
  10220.  
  10221.                AX, BX
  10222.  
  10223.  
  10224.           STATUS
  10225.  
  10226.                AH = 0   SUCCESSFUL.
  10227.                    The manager has allocated the DMA register set.
  10228.  
  10229.                AH = 80h   NON-RECOVERABLE.
  10230.                    The manager detected a malfunction in the memory manager
  10231.                    software.
  10232.  
  10233.                AH = 81h   NON-RECOVERABLE.
  10234.                    The manager detected a malfunction in the expanded
  10235.                    memory hardware.
  10236.  
  10237.                AH = 84h   NON-RECOVERABLE.
  10238.                    The function code passed to the memory manager is not
  10239.                    defined.
  10240.  
  10241.                AH = 8Fh   NON-RECOVERABLE.
  10242.                    The subfunction parameter is invalid.
  10243.  
  10244.                AH = 9Bh   NON-RECOVERABLE.
  10245.                    DMA register sets are supported.  However, all DMA
  10246.                    register sets are currently allocated.
  10247.  
  10248.                AH = A4h   NON-RECOVERABLE.
  10249.                    Access to this function has been denied by the operating
  10250.                    system.  The function cannot be used at this time.
  10251.  
  10252.  
  10253.           EXAMPLE
  10254.  
  10255.           DMA_reg_set_number                  DB ?
  10256.  
  10257.           MOV   AX,5B05h                      ; load function code
  10258.           INT   67h                           ; call memory manager
  10259.           OR    AH,AH                         ; check EMM status
  10260.           JNZ   emm_err_handler               ; jump to error handler
  10261.                                               ; on error
  10262.           MOV   DMA_reg_set_number,BL         ; save number of DMA
  10263.                                               ; register set
  10264.  
  10265.  
  10266.  
  10267.           EMM Functions                                                 169
  10268.  
  10269.  
  10270.  
  10271.  
  10272.  
  10273.           Function 28. Alternate Map Register Set
  10274.           Enable DMA on Alternate Map Register Set subfunction
  10275.  
  10276.  
  10277.  
  10278.           Note............................................................
  10279.                This function is for use by operating systems only.  The
  10280.                operating system can disable this function at any time. 
  10281.                Refer to Function 30 for a description of how an operating
  10282.                system can enable or disable this function.
  10283.  
  10284.  
  10285.           PURPOSE
  10286.  
  10287.                This subfunction allows DMA accesses on a specific DMA
  10288.                channel to be associated with a specific alternate map
  10289.                register set.  In a multitasking operating system, when a
  10290.                task is waiting for the completion of DMA, it is useful to
  10291.                be able to switch to another task until the DMA operation
  10292.                completes.
  10293.  
  10294.                Any DMA on the specified channel will go through the speci-
  10295.                fied DMA register set regardless of the current register
  10296.                set.  If a DMA channel is not assigned to a DMA register
  10297.                set, DMA for that channel will be mapped through the current
  10298.                register set.
  10299.  
  10300.  
  10301.           CALLING PARAMETERS
  10302.  
  10303.                AX = 5B06h
  10304.                    Contains the Enable DMA on Alternate Map Register Set
  10305.                    subfunction.
  10306.  
  10307.                BL = DMA register set number
  10308.                    Contains the number of the alternate map register set to
  10309.                    be used for DMA operations on the DMA channel specified
  10310.                    by DL.  If the alternate map register set specified is
  10311.                    zero, no special action will be taken on DMA accesses
  10312.                    for the DMA channel specified.
  10313.  
  10314.                DL = DMA channel number
  10315.                    Contains the DMA channel which is to be associated with
  10316.                    the DMA map register set specified in BL.
  10317.  
  10318.  
  10319.           REGISTERS MODIFIED
  10320.  
  10321.                AX
  10322.  
  10323.  
  10324.  
  10325.  
  10326.           EMM Functions                                                 170
  10327.  
  10328.  
  10329.  
  10330.  
  10331.  
  10332.           Function 28. Alternate Map Register Set
  10333.           Enable DMA on Alternate Map Register Set subfunction
  10334.  
  10335.  
  10336.  
  10337.           STATUS
  10338.  
  10339.                AH = 0   SUCCESSFUL.
  10340.                    The manager has enabled DMA on the DMA register set and
  10341.                    the DMA channel specified.
  10342.  
  10343.                AH = 80h   NON-RECOVERABLE.
  10344.                    The manager detected a malfunction in the memory manager
  10345.                    software.
  10346.  
  10347.                AH = 81h   NON-RECOVERABLE.
  10348.                    The manager detected a malfunction in the expanded
  10349.                    memory hardware.
  10350.  
  10351.                AH = 84h   NON-RECOVERABLE.
  10352.                    The function code passed to the memory manager is not
  10353.                    defined.
  10354.  
  10355.                AH = 8Fh   NON-RECOVERABLE.
  10356.                    The subfunction parameter is invalid.
  10357.  
  10358.                AH = 9Ah   NON-RECOVERABLE.
  10359.                    Alternate DMA register sets are supported, but the
  10360.                    alternate DMA register set specified is not supported.
  10361.  
  10362.                AH = 9Ch   NON-RECOVERABLE.
  10363.                    Alternate DMA register sets are not supported, and the
  10364.                    DMA register set specified is not zero.
  10365.  
  10366.                AH = 9Dh   NON-RECOVERABLE.
  10367.                    DMA register sets are supported, but the DMA register
  10368.                    set specified is either not defined or not allocated.
  10369.  
  10370.                AH = 9Eh   NON-RECOVERABLE.
  10371.                    Dedicated DMA channels are not supported.
  10372.  
  10373.                AH = 9Fh   NON-RECOVERABLE.
  10374.                    Dedicated DMA channels are supported, but the DMA
  10375.                    channel specified is not supported.
  10376.  
  10377.                AH = A4h   NON-RECOVERABLE.
  10378.                    The operating system has denied access to this function. 
  10379.                    The function cannot be used at this time.
  10380.  
  10381.  
  10382.  
  10383.  
  10384.  
  10385.           EMM Functions                                                 171
  10386.  
  10387.  
  10388.  
  10389.  
  10390.  
  10391.           Function 28. Alternate Map Register Set
  10392.           Enable DMA on Alternate Map Register Set subfunction
  10393.  
  10394.  
  10395.  
  10396.           EXAMPLE
  10397.  
  10398.           alt_map_reg_set                DB ?
  10399.           DMA_channel_num                DB ?
  10400.  
  10401.           MOV   BL,alt_map_reg_set
  10402.           MOV   DL,DMA_channel_num
  10403.           MOV   AX,5B06h                 ; load function code
  10404.           INT   67h                      ; call the memory manager
  10405.           OR    AH,AH                    ; check EMM status
  10406.           JNZ   emm_err_handler          ; jump to error handler on error
  10407.  
  10408.  
  10409.  
  10410.  
  10411.  
  10412.  
  10413.  
  10414.  
  10415.  
  10416.  
  10417.  
  10418.  
  10419.  
  10420.  
  10421.  
  10422.  
  10423.  
  10424.  
  10425.  
  10426.  
  10427.  
  10428.  
  10429.  
  10430.  
  10431.  
  10432.  
  10433.  
  10434.  
  10435.  
  10436.  
  10437.  
  10438.  
  10439.  
  10440.  
  10441.  
  10442.  
  10443.  
  10444.           EMM Functions                                                 172
  10445.  
  10446.  
  10447.  
  10448.  
  10449.  
  10450.           Function 28. Alternate Map Register Set
  10451.           Disable DMA on Alternate Map Register Set subfunction
  10452.  
  10453.  
  10454.  
  10455.           Note............................................................
  10456.                This function is for use by operating systems only.  The
  10457.                operating system can disable this function at any time. 
  10458.                Refer to Function 30 for a description of how an operating
  10459.                system can enable or disable this function.
  10460.  
  10461.  
  10462.           PURPOSE
  10463.  
  10464.                This subfunction disables DMA accesses for all DMA channels
  10465.                which were associated with a specific alternate map register
  10466.                set.
  10467.  
  10468.  
  10469.           CALLING PARAMETERS
  10470.  
  10471.                AX = 5B07h
  10472.                    Contains the Disable DMA on Alternate Map Register Set
  10473.                    subfunction.
  10474.  
  10475.                BL = alternate register set number
  10476.                    Contains the number of the DMA register set for which
  10477.                    all operations are to be disabled.  If the alternate map
  10478.                    register set specified is zero, no action will be taken.
  10479.  
  10480.  
  10481.           REGISTERS MODIFIED
  10482.  
  10483.                AX
  10484.  
  10485.  
  10486.           STATUS
  10487.  
  10488.                AH = 0   SUCCESSFUL.
  10489.                    The manager has disabled DMA operations on the alternate
  10490.                    DMA register set.
  10491.  
  10492.                AH = 80h   NON-RECOVERABLE.
  10493.                    The manager detected a malfunction in the memory manager
  10494.                    software.
  10495.  
  10496.                AH = 81h   NON-RECOVERABLE.
  10497.                    The manager detected a malfunction in the expanded
  10498.                    memory hardware.
  10499.  
  10500.  
  10501.  
  10502.  
  10503.           EMM Functions                                                 173
  10504.  
  10505.  
  10506.  
  10507.  
  10508.  
  10509.           Function 28. Alternate Map Register Set
  10510.           Disable DMA on Alternate Map Register Set subfunction
  10511.  
  10512.  
  10513.  
  10514.                AH = 84h   NON-RECOVERABLE.
  10515.                    The function code passed to the memory manager is not
  10516.                    defined.
  10517.  
  10518.                AH = 8Fh   NON-RECOVERABLE.
  10519.                    The subfunction parameter is invalid.
  10520.  
  10521.                AH = 9Ah   NON-RECOVERABLE.
  10522.                    Alternate DMA register sets are supported, but the
  10523.                    alternate DMA register set specified is not supported.
  10524.  
  10525.                AH = 9Ch   NON-RECOVERABLE.
  10526.                    Alternate DMA register sets are not supported, and the
  10527.                    DMA register set specified is not zero.
  10528.  
  10529.                AH = 9Dh   NON-RECOVERABLE.
  10530.                    DMA register sets are supported, but the DMA register
  10531.                    set specified is either not defined or not allocated.
  10532.  
  10533.                AH = 9Eh   NON-RECOVERABLE.
  10534.                    Dedicated DMA channels are not supported.
  10535.  
  10536.                AH = 9Fh   NON-RECOVERABLE.
  10537.                    Dedicated DMA channels are supported, but the DMA
  10538.                    channel specified is not supported.
  10539.  
  10540.                AH = A4h   NON-RECOVERABLE.
  10541.                    The operating system has denied access to this function. 
  10542.                    The function cannot be used at this time.
  10543.  
  10544.  
  10545.           EXAMPLE
  10546.  
  10547.           DMA_reg_set                    DB ?
  10548.  
  10549.           MOV   BL,DMA_reg_set
  10550.           MOV   AX,5B07h                 ; load function code
  10551.           INT   67h                      ; call the memory manager
  10552.           OR    AH,AH                    ; check EMM status
  10553.           JNZ   emm_err_handler          ; jump to error handler on error
  10554.  
  10555.  
  10556.  
  10557.  
  10558.  
  10559.  
  10560.  
  10561.  
  10562.           EMM Functions                                                 174
  10563.  
  10564.  
  10565.  
  10566.  
  10567.  
  10568.           Function 28. Alternate Map Register Set
  10569.           Deallocate DMA Register Set subfunction
  10570.  
  10571.  
  10572.  
  10573.           Note............................................................
  10574.                This function is for use by operating systems only.  The
  10575.                operating system can disable this function at any time. 
  10576.                Refer to Function 30 for a description of how an operating
  10577.                system can enable or disable this function.
  10578.  
  10579.  
  10580.           PURPOSE
  10581.  
  10582.                The Deallocate DMA Register Set subfunction deallocates the
  10583.                specified DMA register set.
  10584.  
  10585.  
  10586.           CALLING PARAMETERS
  10587.  
  10588.                AX = 5B08h
  10589.                    Contains the Deallocate DMA Register Set subfunction.
  10590.  
  10591.                BL = DMA register set number
  10592.                    Contains the number of the DMA register set which should
  10593.                    not be used for DMA operations any longer.  The DMA
  10594.                    register set would have been previously allocated and
  10595.                    enabled for DMA operations on a specific DMA channel. 
  10596.                    If the DMA register set specified is zero, no action
  10597.                    will be taken.
  10598.  
  10599.  
  10600.           REGISTERS MODIFIED
  10601.  
  10602.                AX
  10603.  
  10604.  
  10605.           STATUS
  10606.  
  10607.                AH = 0   SUCCESSFUL.
  10608.                    The manager has deallocated the DMA register set.
  10609.  
  10610.                AH = 80h   NON-RECOVERABLE.
  10611.                    The manager detected a malfunction in the memory manager
  10612.                    software.
  10613.  
  10614.                AH = 81h   NON-RECOVERABLE.
  10615.                    The manager detected a malfunction in the expanded
  10616.                    memory hardware.
  10617.  
  10618.  
  10619.  
  10620.  
  10621.           EMM Functions                                                 175
  10622.  
  10623.  
  10624.  
  10625.  
  10626.  
  10627.           Function 28. Alternate Map Register Set
  10628.           Deallocate DMA on Alternate Map Register Set subfunction
  10629.  
  10630.  
  10631.  
  10632.                AH = 84h   NON-RECOVERABLE.
  10633.                    The function code passed to the memory manager is not
  10634.                    defined.
  10635.  
  10636.                AH = 8Fh   NON-RECOVERABLE.
  10637.                    The subfunction parameter is invalid.
  10638.  
  10639.                AH = 9Ch   NON-RECOVERABLE.
  10640.                    DMA register sets are not supported, and the DMA
  10641.                    register set specified is not zero.
  10642.  
  10643.                AH = 9Dh   NON-RECOVERABLE.
  10644.                    DMA register sets are supported, but the DMA register
  10645.                    set specified is either not defined or not allocated.
  10646.  
  10647.                AH = A4h   NON-RECOVERABLE.
  10648.                    The operating system has denied access to this function. 
  10649.                    The function cannot be used at this time.
  10650.  
  10651.  
  10652.           EXAMPLE
  10653.  
  10654.           DMA_reg_set_num                DB ?
  10655.  
  10656.           MOV   BL,DMA_reg_set_num
  10657.           MOV   AX,5B08h                 ; load function code
  10658.           INT   67h                      ; call the memory manager
  10659.           OR    AH,AH                    ; check EMM status
  10660.           JNZ   emm_err_handler          ; jump to error handler on error
  10661.  
  10662.  
  10663.  
  10664.  
  10665.  
  10666.  
  10667.  
  10668.  
  10669.  
  10670.  
  10671.  
  10672.  
  10673.  
  10674.  
  10675.  
  10676.  
  10677.  
  10678.  
  10679.  
  10680.           EMM Functions                                                 176
  10681.  
  10682.  
  10683.  
  10684.  
  10685.  
  10686.           Function 29. Prepare Expanded Memory Hardware For Warm Boot
  10687.  
  10688.  
  10689.  
  10690.           PURPOSE
  10691.  
  10692.                This function prepares the expanded memory hardware for an
  10693.                impending warm boot.  This function assumes that the next
  10694.                operation that the operating system performs is a warm boot
  10695.                of the system.  In general, this function will effect the
  10696.                current mapping context, the alternate register set in use,
  10697.                and any other expanded memory hardware dependencies which
  10698.                need to be initialized at boot time.  If an application
  10699.                decides to map memory below 640K, the application must trap
  10700.                all possible conditions leading to a warm boot and invoke
  10701.                this function before performing the warm boot itself.
  10702.  
  10703.  
  10704.           CALLING PARAMETERS
  10705.  
  10706.                AH = 5Ch
  10707.                    Contains the Prepare Expanded Memory Hardware for Warm
  10708.                    Boot function.
  10709.  
  10710.  
  10711.           REGISTERS MODIFIED
  10712.  
  10713.                AX
  10714.  
  10715.  
  10716.           STATUS
  10717.  
  10718.                AH = 0   SUCCESSFUL.
  10719.                    The manager has prepared the expanded memory hardware
  10720.                    for a warm boot.
  10721.  
  10722.                AH = 80h   NON-RECOVERABLE.
  10723.                    The manager detected a malfunction in the memory manager
  10724.                    software.
  10725.  
  10726.                AH = 81h   NON-RECOVERABLE.
  10727.                    The manager detected a malfunction in the expanded
  10728.                    memory hardware.
  10729.  
  10730.                AH = 84h   NON-RECOVERABLE.
  10731.                    The function code passed to the memory manager is not
  10732.                    defined.
  10733.  
  10734.  
  10735.  
  10736.  
  10737.  
  10738.  
  10739.           EMM Functions                                                 177
  10740.  
  10741.  
  10742.  
  10743.  
  10744.  
  10745.           Function 29. Prepare Expanded Memory Hardware for Warm Boot
  10746.  
  10747.  
  10748.  
  10749.           EXAMPLE
  10750.  
  10751.           MOV   AH,5Ch                   ; load function code
  10752.           INT   67h                      ; call the memory manager
  10753.           OR    AH,AH                    ; check EMM status
  10754.           JNZ   emm_err_handler          ; jump to error handler on error
  10755.  
  10756.  
  10757.  
  10758.  
  10759.  
  10760.  
  10761.  
  10762.  
  10763.  
  10764.  
  10765.  
  10766.  
  10767.  
  10768.  
  10769.  
  10770.  
  10771.  
  10772.  
  10773.  
  10774.  
  10775.  
  10776.  
  10777.  
  10778.  
  10779.  
  10780.  
  10781.  
  10782.  
  10783.  
  10784.  
  10785.  
  10786.  
  10787.  
  10788.  
  10789.  
  10790.  
  10791.  
  10792.  
  10793.  
  10794.  
  10795.  
  10796.  
  10797.  
  10798.           EMM Functions                                                 178
  10799.  
  10800.  
  10801.  
  10802.  
  10803.  
  10804.           Function 30. Enable/Disable OS/E Function Set Functions
  10805.           Enable OS/E Function Set subfunction
  10806.  
  10807.  
  10808.  
  10809.           Note............................................................
  10810.                This function is for use by operating systems only.  The
  10811.                operating system can disable this function at any time.
  10812.  
  10813.  
  10814.           PURPOSE
  10815.  
  10816.                This subfunction provides an OS/E with the ability to enable
  10817.                all programs or device drivers to use the OS/E specific
  10818.                functions.  The capability is provided only for an OS/E
  10819.                which manages regions of mappable conventional memory and
  10820.                cannot permit programs to use any of the functions which
  10821.                affect mappable conventional memory regions, but must be
  10822.                able to use these functions itself.  When an OS/E disables
  10823.                these functions and a program attempts to use them, the
  10824.                memory manager returns a status to the program indicating
  10825.                that the OS/E has denied the program access to the function. 
  10826.                In other words, the functions will not work when disabled. 
  10827.                However, all programs may use them when enabled.
  10828.  
  10829.                The OS/E (Operating System/Environment) functions this
  10830.                subfunction enables are:
  10831.  
  10832.                Function 26.  Get Expanded Memory Hardware Information.
  10833.                Function 28.  Alternate Map Register Sets.
  10834.                Function 30.  Enable/Disable Operating System Functions.
  10835.  
  10836.                It appears contradictory that the OS/E can re-enable these
  10837.                functions when the function which re-enables them is itself
  10838.                disabled.  An overview of the process follows.
  10839.  
  10840.                The memory manager enables all the OS/E specific functions,
  10841.                including this one, when it is loaded.  The OS/E gets
  10842.                exclusive access to these functions by invoking either of
  10843.                the Enable/Disable OS/E Function Set subfunctions before any
  10844.                other software does.
  10845.  
  10846.                On the first invocation of either of these subfunctions, the
  10847.                memory manager returns an access_key which the OS/E must use
  10848.                in all future invocations of either of these subfunctions. 
  10849.                The memory manager does not require the access_key on the
  10850.                first invocation of the Enable/Disable OS/E Function Set
  10851.                subfunctions.
  10852.  
  10853.  
  10854.  
  10855.  
  10856.  
  10857.           EMM Functions                                                 179
  10858.  
  10859.  
  10860.  
  10861.  
  10862.  
  10863.           Function 30. Enable/Disable OS/E Function Set Functions
  10864.           Enable OS/E Function Set subfunction
  10865.  
  10866.  
  10867.  
  10868.                On all subsequent invocations, the access_key is required
  10869.                for either the Enable or Disable OS/E Function Set subfunc-
  10870.                tions.  Since the access_key is returned only on the first
  10871.                invocation of the Enable/Disable OS/E Function Set subfunc-
  10872.                tions, and presumably the OS/E is the first software to
  10873.                invoke this function, only the OS/E obtains a copy of this
  10874.                key.  The memory manager must return an access key with a
  10875.                random value, a fixed value key defeats the purpose of
  10876.                providing this level of security for an OS/E.
  10877.  
  10878.  
  10879.           CALLING PARAMETERS
  10880.  
  10881.                AX = 5D00h
  10882.                    Contains the Enable OS/E Function Set subfunction.
  10883.  
  10884.                BX,CX = access_key
  10885.                    Required on all function invocations after the first. 
  10886.                    The access_key value returned by the first function
  10887.                    invocation is required.
  10888.  
  10889.  
  10890.           RESULTS
  10891.  
  10892.                These results are valid only if the status returned is zero.
  10893.  
  10894.                BX,CX = access_key
  10895.                    Returned only on the first function invocation, the
  10896.                    memory manager returns a random valued key which will be
  10897.                    required thereafter for the execution of this function. 
  10898.                    On all invocations after the first, this key is not
  10899.                    returned.  Neither BX nor CX is affected after the first
  10900.                    time this function is invoked.
  10901.  
  10902.  
  10903.           REGISTERS MODIFIED
  10904.  
  10905.                AX, BX, CX
  10906.  
  10907.  
  10908.           STATUS
  10909.  
  10910.                AH = 0   SUCCESSFUL.
  10911.                    The operating system function set has been enabled.
  10912.  
  10913.  
  10914.  
  10915.  
  10916.           EMM Functions                                                 180
  10917.  
  10918.  
  10919.  
  10920.  
  10921.  
  10922.           Function 30. Enable/Disable OS/E Function Set Functions
  10923.           Enable OS/E Function Set subfunction
  10924.  
  10925.  
  10926.  
  10927.                AH = 80h   NON-RECOVERABLE.
  10928.                    The manager detected a malfunction in the memory manager
  10929.                    software.
  10930.  
  10931.                AH = 81h   NON-RECOVERABLE.
  10932.                    The manager detected a malfunction in the expanded
  10933.                    memory hardware.
  10934.  
  10935.                AH = 84h   NON-RECOVERABLE.
  10936.                    The function code passed to the memory manager is not
  10937.                    defined.
  10938.  
  10939.                AH = 8Fh   NON-RECOVERABLE.
  10940.                    The subfunction parameter is invalid.
  10941.  
  10942.                AH = A4h   NON-RECOVERABLE.
  10943.                    The operating system has denied access to this function. 
  10944.                    The function cannot be used at this time.  The value of
  10945.                    the key which was passed to this function does not
  10946.                    entitle the program to execute this function.
  10947.  
  10948.  
  10949.           EXAMPLE
  10950.  
  10951.           First invocation
  10952.  
  10953.           access_key                     DW 2 DUP (?)
  10954.  
  10955.           MOV   AX,5D00h                 ; load function code
  10956.           INT   67h                      ; call the memory manager
  10957.           OR    AH,AH                    ; check EMM status
  10958.           JNZ   emm_err_handler          ; jump to error handler on error
  10959.           MOV   access_key[0],BX
  10960.           MOV   access_key[2],CX
  10961.  
  10962.  
  10963.           All invocations after the first
  10964.  
  10965.           access_key                     DW 2 DUP (?)
  10966.  
  10967.           MOV   BX,access_key[0]
  10968.           MOV   CX,access_key[2]
  10969.           MOV   AX,5D00h                 ; load function code
  10970.           INT   67h                      ; call the memory manager
  10971.           OR    AH,AH                    ; check EMM status
  10972.           JNZ   emm_err_handler          ; jump to error handler on error
  10973.  
  10974.  
  10975.           EMM Functions                                                 181
  10976.  
  10977.  
  10978.  
  10979.  
  10980.  
  10981.           Function 30. Enable/Disable OS/E Function Set Functions
  10982.           Disable OS/E Function Set subfunction
  10983.  
  10984.  
  10985.  
  10986.           Note............................................................
  10987.                This function is for use by operating systems only.  The
  10988.                operating system can disable this function at any time.
  10989.  
  10990.  
  10991.           PURPOSE
  10992.  
  10993.                This subfunction provides an OS/E with the ability to
  10994.                disable all programs or device drivers from using the OS/E
  10995.                specific functions.  The capability is provided only for an
  10996.                OS/E which manages regions of mappable conventional memory
  10997.                and cannot permit programs to use any of the functions which
  10998.                would affect mappable conventional memory regions.  When an
  10999.                OS/E disables these functions and a program attempts to use
  11000.                them, the memory manager returns a status to the program
  11001.                indicating that the OS/E has denied the program access to
  11002.                the function.  In other words, the functions will not work
  11003.                when disabled.
  11004.  
  11005.                The OS/E (Operating System) functions which are disabled by
  11006.                this subfunction are:
  11007.  
  11008.                Function 26.  Get Expanded Memory Hardware Information.
  11009.                Function 28.  Alternate Map Register Sets.
  11010.                Function 30.  Enable/Disable Operating System Functions.
  11011.  
  11012.  
  11013.           CALLING PARAMETERS
  11014.  
  11015.                AX = 5D01h
  11016.                    Contains the Disable OS/E Function Set subfunction.
  11017.  
  11018.                BX,CX = access_key
  11019.                    Required on all function invocations after the first. 
  11020.                    The access_key value returned by the first function
  11021.                    invocation is required.
  11022.  
  11023.  
  11024.  
  11025.  
  11026.  
  11027.  
  11028.  
  11029.  
  11030.  
  11031.  
  11032.  
  11033.  
  11034.           EMM Functions                                                 182
  11035.  
  11036.  
  11037.  
  11038.  
  11039.  
  11040.           Function 30. Enable/Disable OS/E Function Set Functions
  11041.           Disable OS/E Function Set subfunction
  11042.  
  11043.  
  11044.  
  11045.           RESULTS
  11046.  
  11047.                These results are valid only if the status returned is zero.
  11048.  
  11049.                BX,CX = access_key
  11050.                    Returned only on the first function invocation, the
  11051.                    memory manager returns a random valued key which will be
  11052.                    required thereafter for the execution of this function. 
  11053.                    On all invocations after the first, this key is not
  11054.                    returned.  Neither BX nor CX is affected after the first
  11055.                    time this function is invoked.
  11056.  
  11057.  
  11058.           REGISTERS MODIFIED
  11059.  
  11060.                AX, BX, CX
  11061.  
  11062.  
  11063.           STATUS
  11064.  
  11065.                AH = 0   SUCCESSFUL.
  11066.                    The operating system function set has been disabled.
  11067.  
  11068.                AH = 80h   NON-RECOVERABLE.
  11069.                    The manager detected a malfunction in the memory manager
  11070.                    software.
  11071.  
  11072.                AH = 81h   NON-RECOVERABLE.
  11073.                    The manager detected a malfunction in the expanded
  11074.                    memory hardware.
  11075.  
  11076.                AH = 84h   NON-RECOVERABLE.
  11077.                    The function code passed to the memory manager is not
  11078.                    defined.
  11079.  
  11080.                AH = 8Fh   NON-RECOVERABLE.
  11081.                    The subfunction parameter is invalid.
  11082.  
  11083.                AH = A4h   NON-RECOVERABLE.
  11084.                    The operating system has denied access to this function. 
  11085.                    The function cannot be used at this time.  The value of
  11086.                    the key which was passed to this function does not
  11087.                    entitle the program to execute this function.
  11088.  
  11089.  
  11090.  
  11091.  
  11092.  
  11093.           EMM Functions                                                 183
  11094.  
  11095.  
  11096.  
  11097.  
  11098.  
  11099.           Function 30. Enable/Disable OS/E Function Set Functions
  11100.           Disable OS/E Function Set subfunction
  11101.  
  11102.  
  11103.  
  11104.           EXAMPLE
  11105.  
  11106.           First Function invocation
  11107.  
  11108.           access_key                     DW 2 DUP (?)
  11109.  
  11110.           MOV   AX,5D01h                 ; load function code
  11111.           INT   67h                      ; call the memory manager
  11112.           OR    AH,AH                    ; check EMM status
  11113.           JNZ   emm_err_handler          ; jump to error handler on error
  11114.           MOV   access_key[0],BX
  11115.           MOV   access_key[2],CX
  11116.  
  11117.  
  11118.           All invocations after the first
  11119.  
  11120.           access_key                     DW 2 DUP (?)
  11121.  
  11122.           MOV   BX,access_key[0]
  11123.           MOV   CX,access_key[2]
  11124.           MOV   AX,5D01h                 ; load function code
  11125.           INT   67h                      ; call the memory manager
  11126.           OR    AH,AH                    ; check EMM status
  11127.           JNZ   emm_err_handler          ; jump to error handler on error
  11128.  
  11129.  
  11130.  
  11131.  
  11132.  
  11133.  
  11134.  
  11135.  
  11136.  
  11137.  
  11138.  
  11139.  
  11140.  
  11141.  
  11142.  
  11143.  
  11144.  
  11145.  
  11146.  
  11147.  
  11148.  
  11149.  
  11150.  
  11151.  
  11152.           EMM Functions                                                 184
  11153.  
  11154.  
  11155.  
  11156.  
  11157.  
  11158.           Function 30. Enable/Disable OS/E Function Set Functions
  11159.           Return Access Key subfunction
  11160.  
  11161.  
  11162.  
  11163.           Note............................................................
  11164.                This function is for use by operating systems only.  The
  11165.                operating system can disable this function at any time.
  11166.  
  11167.  
  11168.           PURPOSE
  11169.  
  11170.                This subfunction provides an OS/E with the ability to return
  11171.                the access key to the memory manager.  Returning the access
  11172.                key to the memory manager places the memory manager in the
  11173.                state it is in at installation time (regarding the use of
  11174.                the OS/E function set and the access key).  That is, access
  11175.                to the OS/E function set is enabled.  Upon execution of the
  11176.                next enable/disable OS/E function set subfunction, the
  11177.                access key will once again be returned.
  11178.  
  11179.  
  11180.           CALLING PARAMETERS
  11181.  
  11182.                AX = 5D02h
  11183.                    Contains the Return Access Key subfunction.
  11184.  
  11185.                BX,CX = access_key
  11186.                    Required on all function invocations.  The access_key
  11187.                    value returned by the first function invocation of the
  11188.                    enable or disable subfunctions is required.
  11189.  
  11190.  
  11191.           REGISTERS MODIFIED
  11192.  
  11193.                AX
  11194.  
  11195.  
  11196.           STATUS
  11197.  
  11198.                AH = 0   SUCCESSFUL.
  11199.                    The access key has been returned to the memory manager.
  11200.  
  11201.                AH = 80h   NON-RECOVERABLE.
  11202.                    The manager detected a malfunction in the memory manager
  11203.                    software.
  11204.  
  11205.                AH = 81h   NON-RECOVERABLE.
  11206.                    The manager detected a malfunction in the expanded
  11207.                    memory hardware.
  11208.  
  11209.  
  11210.  
  11211.           EMM Functions                                                 185
  11212.  
  11213.  
  11214.  
  11215.  
  11216.  
  11217.           Function 30. Enable/Disable OS/E Function Set Functions
  11218.           Return Access Key subfunction
  11219.  
  11220.  
  11221.  
  11222.                AH = 84h   NON-RECOVERABLE.
  11223.                    The function code passed to the memory manager is not
  11224.                    defined.
  11225.  
  11226.                AH = 8Fh   NON-RECOVERABLE.
  11227.                    The subfunction parameter is invalid.
  11228.  
  11229.                AH = A4h   NON-RECOVERABLE.
  11230.                    The operating system has denied access to this function. 
  11231.                    The function cannot be used at this time.  The value of
  11232.                    the key which was passed to this function does not
  11233.                    entitle the program to execute this function.
  11234.  
  11235.  
  11236.           EXAMPLE
  11237.  
  11238.           access_key                     DW 2 DUP (?)
  11239.  
  11240.           MOV   BX,access_key[0]
  11241.           MOV   CX,access_key[2]
  11242.           MOV   AX,5D02h                 ; load function code
  11243.           INT   67h                      ; call the memory manager
  11244.           OR    AH,AH                    ; check EMM status
  11245.           JNZ   emm_err_handler          ; jump to error handler on error
  11246.  
  11247.  
  11248.  
  11249.  
  11250.  
  11251.  
  11252.  
  11253.  
  11254.  
  11255.  
  11256.  
  11257.  
  11258.  
  11259.  
  11260.  
  11261.  
  11262.  
  11263.  
  11264.  
  11265.  
  11266.  
  11267.  
  11268.  
  11269.  
  11270.           EMM Functions                                                 186
  11271.  
  11272.  
  11273.  
  11274.  
  11275.  
  11276.           Appendix A
  11277.           FUNCTION AND STATUS CODE CROSS REFERENCE TABLES
  11278.  
  11279.  
  11280.  
  11281.                This appendix contains two cross reference tables:  one
  11282.                lists the function codes and the status codes they return;
  11283.                the other lists the status codes and the functions that
  11284.                return them.
  11285.  
  11286.  
  11287.           Table A-1.  Function and Status Code Cross Reference
  11288.           ----------------------------------------------------------------
  11289.  
  11290.           Function        Status                 Description
  11291.  
  11292.           ----------------------------------------------------------------
  11293.  
  11294.              40h    00h, 80h, 81h, 84h   Get Memory Manager Status
  11295.  
  11296.              41h    00h, 80h, 81h, 84h   Get Page Frame Segment Address
  11297.  
  11298.              42h    00h, 80h, 81h, 84h   Get Unallocated Page Count
  11299.  
  11300.              43h    00h, 80h, 81h, 84h   Allocate Pages
  11301.                     85h, 87h, 88h, 89h
  11302.  
  11303.              44h    00h, 80h, 81h, 83h   Map/Unmap Handle Page
  11304.                     84h, 8Ah, 8Bh
  11305.  
  11306.              45h    00h, 80h, 81h, 83h   Deallocate Pages
  11307.                     84h, 86h
  11308.  
  11309.              46h    00h, 80h, 81h, 84h   Get EMM Version
  11310.  
  11311.              47h    00h, 80h, 81h, 83h   Save Page Map
  11312.                     84h, 8Ch, 8Dh
  11313.  
  11314.              48h    00h, 80h, 81h, 83h   Restore Page Map
  11315.                     84h, 8Eh
  11316.  
  11317.              49h                         Reserved
  11318.  
  11319.              4Ah                         Reserved
  11320.  
  11321.              4Bh    00h, 80h, 81h, 84h   Get EMM Handle Count
  11322.  
  11323.              4Ch    00h, 80h, 81h, 83h   Get EMM Handle Pages
  11324.                     84h
  11325.  
  11326.              4Dh    00h, 80h, 81h, 84h   Get All EMM Handle Pages
  11327.  
  11328.  
  11329.           Cross Reference Tables                                        187
  11330.  
  11331.  
  11332.  
  11333.  
  11334.  
  11335.           Table A-1.  Function and Status Code Cross Reference (continued)
  11336.           ----------------------------------------------------------------
  11337.  
  11338.           Function        Status                 Description
  11339.  
  11340.           ----------------------------------------------------------------
  11341.  
  11342.            4E00h    00h, 80h, 81h, 84h   Get Page Map
  11343.                     8Fh
  11344.  
  11345.            4E01h    00h, 80h, 81h, 84h   Set Page Map
  11346.                     8Fh, A3h
  11347.  
  11348.            4E02h    00h, 80h, 81h, 84h   Get & Set Page Map
  11349.                     8Fh, A3h
  11350.  
  11351.            4E03h    00h, 80h, 81h, 84h   Get Size of Page Map Save Array
  11352.                     8Fh
  11353.  
  11354.            4F00h    00h, 80h, 81h, 84h   Get Partial Page Map
  11355.                     8Bh, 8Fh, A3h
  11356.  
  11357.            4F01h    00h, 80h, 81h, 84h   Set Partial Page Map
  11358.                     8Fh, A3h
  11359.  
  11360.            4F02h    00h, 80h, 81h, 84h   Get Size of Partial Page Map Array
  11361.                     8Bh, 8Fh
  11362.  
  11363.            5000h    00h, 80h, 81h, 83h   Map/Unmap Multiple Handle Pages
  11364.                     84h, 8Ah, 8Bh, 8Fh   (physical page number mode)
  11365.  
  11366.            5001h    00h, 80h, 81h, 83h   Map/Unmap Multiple Handle Pages
  11367.                     84h, 8Ah, 8Bh, 8Fh   (segment address mode)
  11368.  
  11369.              51h    00h, 80h, 81h, 83h   Reallocate Pages
  11370.                     84h, 87h, 88h
  11371.  
  11372.            5200h    00h, 80h, 81h, 83h   Get Handle Attribute
  11373.                     84h, 8Fh, 91h
  11374.  
  11375.            5201h    00h, 80h, 81h, 83h   Set Handle Attribute
  11376.                     84h, 8Fh, 90h, 91h
  11377.  
  11378.            5202h    00h, 80h, 81h, 84h   Get Handle Attribute Capability
  11379.                     8Fh
  11380.  
  11381.            5300h    00h, 80h, 81h, 83h   Get Handle Name
  11382.                     84h, 8Fh
  11383.  
  11384.            5301h    00h, 80h, 81h, 83h   Set Handle Name
  11385.                     84h, 8Fh, A1h
  11386.  
  11387.  
  11388.           Cross Reference Tables                                        188
  11389.  
  11390.  
  11391.  
  11392.  
  11393.  
  11394.           Table A-1.  Function and Status Code Cross Reference (continued)
  11395.           ----------------------------------------------------------------
  11396.  
  11397.           Function        Status                 Description
  11398.  
  11399.           ----------------------------------------------------------------
  11400.  
  11401.            5400h    00h, 80h, 81h, 84h   Get Handle Directory
  11402.                     8Fh
  11403.  
  11404.            5401h    00h, 80h, 81h, 84h   Search for Named Handle
  11405.                     8Fh, A0h, A1h
  11406.  
  11407.            5402h    00h, 80h, 81h, 84h   Get Total Handles
  11408.                     8Fh
  11409.  
  11410.            5500h    00h, 80h, 81h, 83h   Alter Page Map & Jump (Physical   
  11411.                     84h, 8Ah, 8Bh, 8Fh   page mode)
  11412.  
  11413.            5501h    00h, 80h, 81h, 83h   Alter Page Map & Jump (Segment    
  11414.                     84h, 8Ah, 8Bh, 8Fh   address mode)
  11415.  
  11416.            5600h    00h, 80h, 81h, 83h   Alter Page Map & Call (Physical   
  11417.                     84h, 8Ah, 8Bh, 8Fh   page mode)
  11418.  
  11419.            5601h    00h, 80h, 81h, 83h   Alter Page Map & Call (Segment    
  11420.                     84h, 8Ah, 8Bh, 8Fh   address mode)
  11421.  
  11422.            5602h    00h, 80h, 81h, 84h   Get Alter Page Map & Call Stack   
  11423.                     8Fh                  Space Size
  11424.  
  11425.            5700h    00h, 80h, 81h, 83h   Move Memory Region
  11426.                     84h, 8Ah, 8Fh, 92h
  11427.                     93h, 94h, 95h, 96h
  11428.                     98h, A2h
  11429.  
  11430.            5701h    00h, 80h, 81h, 83h   Exchange Memory Region
  11431.                     84h, 8Ah, 8Fh, 93h
  11432.                     94h, 95h, 96h, 97h
  11433.                     98h, A2h
  11434.  
  11435.            5800h    00h, 80h, 81h, 84h   Get Mappable Physical Address     
  11436.                     8Fh                  Array
  11437.  
  11438.            5801h    00h, 80h, 81h, 84h   Get Mappable Physical Address     
  11439.                     8Fh                  Array Entries
  11440.  
  11441.            5900h    00h, 80h, 81h, 84h   Get Expanded Memory Hardware      
  11442.                     8Fh, A4h             Information
  11443.  
  11444.            5901h    00h, 80h, 81h, 84h   Get Unallocated Raw Page Count
  11445.                     8Fh
  11446.  
  11447.           Cross Reference Tables                                        189
  11448.  
  11449.  
  11450.  
  11451.  
  11452.  
  11453.           Table A-1.  Function and Status Code Cross Reference (continued)
  11454.           ----------------------------------------------------------------
  11455.  
  11456.           Function        Status                 Description
  11457.  
  11458.           ----------------------------------------------------------------
  11459.  
  11460.            5A00h    00h, 80h, 81h, 84h   Allocate Standard Pages
  11461.                     85h, 87h, 88h, 8Fh
  11462.  
  11463.            5A01h    00h, 80h, 81h, 84h   Allocate Raw Pages
  11464.                     85h, 87h, 88h, 8Fh
  11465.  
  11466.            5B00h    00h, 80h, 81h, 84h   Get Alternate Map Register Set
  11467.                     8Fh, A4h
  11468.  
  11469.            5B01h    00h, 80h, 81h, 84h   Set Alternate Map Register Set
  11470.                     8Fh, 9Ah, 9Ch, 9Dh
  11471.                     A3h, A4h
  11472.  
  11473.            5B02h    00h, 80h, 81h, 84h   Get Alternate Map Save Array Size
  11474.                     8Fh, A4h
  11475.  
  11476.            5B03h    00h, 80h, 81h, 84h   Allocate Alternate Map Register   
  11477.                     8Fh, 9Bh, A4h        Set
  11478.  
  11479.            5B04h    00h, 80h, 81h, 84h   Deallocate Alternate Map Register 
  11480.                     8Fh, 9Ch, 9Dh, A4h   Set
  11481.  
  11482.            5B05h    00h, 80h, 81h, 84h   Allocate DMA Register Set
  11483.                     8Fh, 9Bh, A4h
  11484.  
  11485.            5B06h    00h, 80h, 81h, 84h   Enable DMA on Alternate Map       
  11486.                     8Fh, 9Ah, 9Ch, 9Dh   Register Set
  11487.                     9Eh, 9Fh, A4h
  11488.  
  11489.            5B07h    00h, 80h, 81h, 84h   Disable DMA on Alternate Map      
  11490.                     8Fh, 9Ah, 9Ch, 9Dh   Register Set
  11491.                     9Eh, 9Fh, A4h
  11492.  
  11493.            5B08h    00h, 80h, 81h, 84h   Deallocate DMA Register Set
  11494.                     8Fh, 9Ch, 9Dh, A4h
  11495.  
  11496.              5Ch    00h, 80h, 81h, 84h   Prepare Expanded Memory Hardware
  11497.                                          for Warmboot
  11498.  
  11499.            5D00h    00h, 80h, 81h, 84h   Enable Operating System Function  
  11500.                     8Fh, A4h             Set
  11501.  
  11502.            5D01h    00h, 80h, 81h, 84h   Disable Operating System Function 
  11503.                     8Fh, A4h             Set
  11504.  
  11505.  
  11506.           Cross Reference Tables                                        190
  11507.  
  11508.  
  11509.  
  11510.  
  11511.  
  11512.           Table A-1.  Function and Status Code Cross Reference (continued)
  11513.           ----------------------------------------------------------------
  11514.  
  11515.           Function        Status                 Description
  11516.  
  11517.           ----------------------------------------------------------------
  11518.  
  11519.            5D02h    00h, 80h, 81h, 84h   Return Operating System Access Key
  11520.                     8Fh, A4h
  11521.           ----------------------------------------------------------------
  11522.  
  11523.  
  11524.  
  11525.  
  11526.  
  11527.  
  11528.  
  11529.  
  11530.  
  11531.  
  11532.  
  11533.  
  11534.  
  11535.  
  11536.  
  11537.  
  11538.  
  11539.  
  11540.  
  11541.  
  11542.  
  11543.  
  11544.  
  11545.  
  11546.  
  11547.  
  11548.  
  11549.  
  11550.  
  11551.  
  11552.  
  11553.  
  11554.  
  11555.  
  11556.  
  11557.  
  11558.  
  11559.  
  11560.  
  11561.  
  11562.  
  11563.  
  11564.  
  11565.           Cross Reference Tables                                        191
  11566.  
  11567.  
  11568.  
  11569.  
  11570.  
  11571.           Table A-2.  Status and Function Code Cross Reference
  11572.           ----------------------------------------------------------------
  11573.  
  11574.           Status      Function                   Description
  11575.  
  11576.           ----------------------------------------------------------------
  11577.  
  11578.            00h   All                  The function completed normally.
  11579.  
  11580.            80h   All                  The memory manager has detected a
  11581.                                       malfunction in the expanded memory
  11582.                                       software.  A condition has been
  11583.                                       detected which would not have
  11584.                                       occurred if the memory manager had
  11585.                                       been operating correctly.
  11586.  
  11587.            81h   All                  The memory manager has detected a
  11588.                                       malfunction in the expanded memory
  11589.                                       hardware.  A condition has been
  11590.                                       detected which would not occur if the
  11591.                                       memory hardware were working correct-
  11592.                                       ly.  Diagnostics should be run on the
  11593.                                       expanded memory system to determine
  11594.                                       the source of the problem.
  11595.  
  11596.            82h   None                 This error code is not returned in
  11597.                                       version 3.2 of the memory manager or
  11598.                                       above.  In earlier versions of the
  11599.                                       memory manager this code meant a
  11600.                                       "busy" status.  This status indicated
  11601.                                       that the memory manager was already
  11602.                                       processing an expanded memory request
  11603.                                       when the current request was made and
  11604.                                       is unable to process another request. 
  11605.                                       In versions 3.2 of the memory manager
  11606.                                       and above, the memory manager is
  11607.                                       never "busy" and can always honor
  11608.                                       requests.
  11609.  
  11610.            83h   44h, 45h, 47h, 48h   The memory manager can not find the
  11611.                  4Ch, 5000h, 5001h    handle specified.  The program has
  11612.                  51h, 5200h, 5201h    probably corrupted its specified
  11613.                  5300h, 5301h         handle.  The memory manager does not
  11614.                  5500h, 5501h         have any information pertaining to
  11615.                  5600h, 5601h         the  specified handle.  The program
  11616.                  5700h, 5701h         has probably corrupted its handle.
  11617.  
  11618.            84h   All                  The function code passed to the
  11619.                                       manager is not currently defined. 
  11620.                                       Function codes in the range 40h
  11621.                                       through 5Dh are currently defined.
  11622.  
  11623.  
  11624.           Cross Reference Tables                                        192
  11625.  
  11626.  
  11627.  
  11628.  
  11629.  
  11630.           Table A-2.  Status and Function Code Cross Reference (continued)
  11631.           ----------------------------------------------------------------
  11632.  
  11633.           Status      Function                   Description
  11634.  
  11635.           ----------------------------------------------------------------
  11636.  
  11637.            85h   43h, 5A00h, 5A01h    No handles are currently available. 
  11638.                                       All assignable handles are currently
  11639.                                       in use.  The program may re-request
  11640.                                       the assignment of a handle in the
  11641.                                       hope that another program has
  11642.                                       released a handle.  The maximum
  11643.                                       number of handles that may be
  11644.                                       supported is 255.
  11645.  
  11646.            86h   45h                  A mapping context restoration error
  11647.                                       has been detected.  This error occurs
  11648.                                       when a program attempts to return a
  11649.                                       handle and there is still a "mapping
  11650.                                       context" on the context stack for the
  11651.                                       indicated handle.  A program can
  11652.                                       recover from this error by restoring
  11653.                                       the mapping context before returning
  11654.                                       the handle.
  11655.  
  11656.            87h   43h, 51h, 5A00h,     The number of total pages that are
  11657.                  5A01h                available in the system is insuffi-
  11658.                                       cient to honor the request.  The
  11659.                                       program can recover from this
  11660.                                       condition by requesting fewer pages.
  11661.  
  11662.            88h   43h, 51h, 5A00h,     The number of unallocated pages
  11663.                  5A01h                currently available is insufficient
  11664.                                       to honor the allocation request.  The
  11665.                                       program can recover from this
  11666.                                       condition by re-posting the request
  11667.                                       or by requesting fewer pages.
  11668.  
  11669.            89h   43h                  A Function 4 (Allocate Pages) request
  11670.                                       has been made specifying zero pages. 
  11671.                                       Zero pages cannot be assigned to a
  11672.                                       handle with Function 4 (Allocate
  11673.                                       Pages).  If it is necessary to assign
  11674.                                       zero pages to a handle, Function 27
  11675.                                       (Allocate Standard Pages and Allocate
  11676.                                       Raw Pages subfunctions) may be used.
  11677.  
  11678.  
  11679.  
  11680.  
  11681.  
  11682.  
  11683.           Cross Reference Tables                                        193
  11684.  
  11685.  
  11686.  
  11687.  
  11688.  
  11689.           Table A-2.  Status and Function Code Cross Reference (continued)
  11690.           ----------------------------------------------------------------
  11691.  
  11692.           Status      Function                   Description
  11693.  
  11694.           ----------------------------------------------------------------
  11695.  
  11696.            8Ah   44h, 5000h, 5001h    The logical page to map into memory
  11697.                  5500h, 5501h         is out of the range of logical pages
  11698.                  5600h, 5601h         which are allocated to the handle. 
  11699.                  5700h, 5701h         The program can recover from this
  11700.                                       condition by attempting to map a
  11701.                                       logical page which is within the
  11702.                                       bounds for the handle.
  11703.  
  11704.            8Bh   44h, 4F00h, 4F02h    One or more of the physical pages is
  11705.                  5000h, 5001h         out of the range of allowable
  11706.                  5600h, 5601h         physical pages.  Physical page
  11707.                  5500h, 5501          numbers are numbered zero-relative. 
  11708.                                       The program can recover from this
  11709.                                       condition by mapping at a physical
  11710.                                       page which is in the range from zero
  11711.                                       to three.
  11712.  
  11713.            8Ch   47h                  The mapping register context save
  11714.                                       area is full.  The program can
  11715.                                       recover from this condition by
  11716.                                       attempting to save the mapping
  11717.                                       registers again.
  11718.  
  11719.            8Dh   47h                  The mapping register context stack
  11720.                                       already has a context associated with
  11721.                                       the handle.  The program has at-
  11722.                                       tempted to save the mapping register
  11723.                                       context when there was already a
  11724.                                       context for the handle on the stack. 
  11725.                                       The program can recover from this
  11726.                                       condition by not attempting to save
  11727.                                       the context again (this assumes the
  11728.                                       mapping register context on the stack
  11729.                                       for the handle is correct).
  11730.  
  11731.  
  11732.  
  11733.  
  11734.  
  11735.  
  11736.  
  11737.  
  11738.  
  11739.  
  11740.  
  11741.  
  11742.           Cross Reference Tables                                        194
  11743.  
  11744.  
  11745.  
  11746.  
  11747.  
  11748.           Table A-2.  Status and Function Code Cross Reference (continued)
  11749.           ----------------------------------------------------------------
  11750.  
  11751.           Status      Function                   Description
  11752.  
  11753.           ----------------------------------------------------------------
  11754.  
  11755.            8Eh   48h                  The mapping register context stack
  11756.                                       does not have a context associated
  11757.                                       with the handle.  The program has
  11758.                                       attempted to restore the mapping
  11759.                                       register context when there was no
  11760.                                       context for the handle on the stack. 
  11761.                                       The program can recover from this
  11762.                                       condition by not attempting to
  11763.                                       restore the context again (this
  11764.                                       assumes the current mapping register
  11765.                                       context is correct).
  11766.  
  11767.            8Fh   All functions        The subfunction parameter passed to
  11768.                  requiring            the function is not defined.
  11769.                  subfunction codes
  11770.  
  11771.            90h   5201h                The attribute type is undefined.
  11772.  
  11773.            91h   5200h, 5201h         The system configuration does not
  11774.                                       support non-volatility.
  11775.  
  11776.            92h   5700h                The source and destination expanded
  11777.                                       memory regions have the same handle
  11778.                                       and overlap.  This is valid for a
  11779.                                       move.  The move has been completed
  11780.                                       and the destination region has a full
  11781.                                       copy of the source region.  However,
  11782.                                       at least a portion of the source
  11783.                                       region has been overwritten by the
  11784.                                       move.  Note that the source and
  11785.                                       destination expanded memory regions
  11786.                                       with different handles will never
  11787.                                       physically overlap because the
  11788.                                       different handles specify totally
  11789.                                       different regions of expanded memory.
  11790.  
  11791.  
  11792.  
  11793.  
  11794.  
  11795.  
  11796.  
  11797.  
  11798.  
  11799.  
  11800.  
  11801.           Cross Reference Tables                                        195
  11802.  
  11803.  
  11804.  
  11805.  
  11806.  
  11807.           Table A-2.  Status and Function Code Cross Reference (continued)
  11808.           ----------------------------------------------------------------
  11809.  
  11810.           Status      Function                   Description
  11811.  
  11812.           ----------------------------------------------------------------
  11813.  
  11814.            93h   5700h, 5701h         The length of the specified source or
  11815.                                       destination expanded memory region
  11816.                                       exceeds the length of the expanded
  11817.                                       memory region allocated to the
  11818.                                       specified source or destination
  11819.                                       handle.  There are insufficient pages
  11820.                                       allocated to this handle to move/ex-
  11821.                                       change a region of the size speci-
  11822.                                       fied.  The program can recover from
  11823.                                       this condition by attempting to
  11824.                                       allocate additional pages to the
  11825.                                       destination or source handle or by
  11826.                                       reducing the specified length. 
  11827.                                       However, if the application program
  11828.                                       has allocated as much expanded memory
  11829.                                       as it thought it needed, this may be
  11830.                                       a program error and is therefore not
  11831.                                       recoverable.
  11832.  
  11833.            94h   5700h, 5701h         The conventional memory region and
  11834.                                       expanded memory region overlap.  This
  11835.                                       is invalid, the conventional memory
  11836.                                       region cannot overlap the expanded
  11837.                                       memory region.
  11838.  
  11839.            95h   5700h, 5701h         The offset within the logical page
  11840.                                       exceeds the length of the logical
  11841.                                       page.  The initial source or destina-
  11842.                                       tion offsets within an expanded
  11843.                                       memory region must be between 0 and
  11844.                                       the (length of a logical page - 1) or
  11845.                                       16383 (3FFFh).
  11846.  
  11847.            96h   5700h, 5701h         Region length exceeds 1M-byte limit.
  11848.  
  11849.  
  11850.  
  11851.  
  11852.  
  11853.  
  11854.  
  11855.  
  11856.  
  11857.  
  11858.  
  11859.  
  11860.           Cross Reference Tables                                        196
  11861.  
  11862.  
  11863.  
  11864.  
  11865.  
  11866.           Table A-2.  Status and Function Code Cross Reference (continued)
  11867.           ----------------------------------------------------------------
  11868.  
  11869.           Status      Function                   Description
  11870.  
  11871.           ----------------------------------------------------------------
  11872.  
  11873.            97h   5701h                The source and destination expanded
  11874.                                       memory regions have the SAME handle
  11875.                                       AND overlap.  This is invalid; the
  11876.                                       source and destination expanded
  11877.                                       memory regions cannot have the same
  11878.                                       handle and overlap when they are
  11879.                                       being exchanged.  Note that the
  11880.                                       source and destination expanded
  11881.                                       memory regions with different handles
  11882.                                       will never physically overlap because
  11883.                                       the different handles specify totally
  11884.                                       different regions of expanded memory.
  11885.  
  11886.            98h   5700h, 5701h         The memory source and destination
  11887.                                       types are undefined/not supported.
  11888.  
  11889.            9Ah   5B01h, 5B06h         Alternate map register sets are
  11890.                  5B07h                supported, but the alternate map
  11891.                                       register set specified is not
  11892.                                       supported.
  11893.  
  11894.            9Bh   5B03h, 5B05h         Alternate map/DMA register sets are
  11895.                                       supported.  However, all alternate
  11896.                                       map/DMA register sets are currently
  11897.                                       allocated.
  11898.  
  11899.            9Ch   5B01h, 5B04h         Alternate map/DMA register sets are
  11900.                  5B06h, 5B07h         not supported, and the alternate
  11901.                  5B08h                map/DMA register set specified is not
  11902.                                       zero.
  11903.  
  11904.            9Dh   5B01h, 5B04h         Alternate map/DMA register sets are
  11905.                  5B06h, 5B07h         supported, but the alternate map
  11906.                  5B08h                register set specified is not
  11907.                                       defined, not allocated, or is the
  11908.                                       currently allocated map register set.
  11909.  
  11910.            9Eh   5B06h, 5B07h         Dedicated DMA channels are not
  11911.                                       supported.
  11912.  
  11913.            9Fh   5B06h, 5B07h         Dedicated DMA channels are supported. 
  11914.                                       But the DMA channel specified is not
  11915.                                       supported.
  11916.  
  11917.  
  11918.  
  11919.           Cross Reference Tables                                        197
  11920.  
  11921.  
  11922.  
  11923.  
  11924.  
  11925.           Table A-2.  Status and Function Code Cross Reference (continued)
  11926.           ----------------------------------------------------------------
  11927.  
  11928.           Status      Function                   Description
  11929.  
  11930.           ----------------------------------------------------------------
  11931.  
  11932.            A0h   5401h                No corresponding handle value could
  11933.                                       be found for the handle name speci-
  11934.                                       fied.
  11935.  
  11936.            A1h   5301h, 5401h         A handle with this name already
  11937.                                       exists.  The specified handle was not
  11938.                                       assigned a name.
  11939.  
  11940.            A2h   5700h, 5701h         An attempt was made to "wrap around"
  11941.                                       the 1M-byte address space during the
  11942.                                       move/exchange.  The source starting
  11943.                                       address together with the length of
  11944.                                       the region to be moved/exchanged
  11945.                                       exceeds 1M bytes.  No data was
  11946.                                       moved/exchanged.
  11947.  
  11948.            A3h   4E01h, 4E02h         The contents of the data structure
  11949.                  4F00h, 4F01h         passed to the function have either
  11950.                  5B01h                been corrupted or are meaningless.
  11951.  
  11952.            A4h   5900h, 5B00h         The operating system has denied
  11953.                  5B01h, 5B02h         access to this function.  The 
  11954.                  5B03h, 5B04h         function cannot be used at this time.
  11955.                  5B05h, 5B06h
  11956.                  5B07h, 5B08h
  11957.                  5D00h, 5D01h
  11958.                  5D02h
  11959.  
  11960.           ----------------------------------------------------------------
  11961.  
  11962.  
  11963.  
  11964.  
  11965.  
  11966.  
  11967.  
  11968.  
  11969.  
  11970.  
  11971.  
  11972.  
  11973.  
  11974.  
  11975.  
  11976.  
  11977.  
  11978.           Cross Reference Tables                                        198
  11979.  
  11980.  
  11981.  
  11982.  
  11983.  
  11984.           Appendix B
  11985.           TESTING FOR THE PRESENCE OF THE EXPANDED MEMORY MANAGER
  11986.  
  11987.  
  11988.  
  11989.                Before an application program can use the Expanded Memory
  11990.                Manager, it must determine whether DOS has loaded the
  11991.                manager.  This appendix describes two methods your program
  11992.                can use to test for the presence of the memory manager and
  11993.                how to choose the correct one for your situation.
  11994.  
  11995.                The first method uses the DOS "open handle" technique; the
  11996.                second method uses the DOS "get interrupt vector" technique.
  11997.  
  11998.  
  11999.           Which method should your program use?
  12000.  
  12001.                The majority of application programs can use either the
  12002.                "open handle" or the "get interrupt vector" method. 
  12003.                However, if your program is a device driver or if it
  12004.                interrupts DOS during file system operations, you must use
  12005.                only the "get interrupt vector" method.
  12006.  
  12007.                Device drivers execute from within DOS and can't access the
  12008.                DOS file system; programs that interrupt DOS during file
  12009.                system operations have a similar restriction.  During their
  12010.                interrupt processing procedures, they can't access the DOS
  12011.                file system because another program may be using the system. 
  12012.                Since the "get interrupt vector" method doesn't require the
  12013.                DOS file system, you must use it for these types of pro-
  12014.                grams.
  12015.  
  12016.  
  12017.           The "open handle" technique
  12018.  
  12019.                Most application programs can use the DOS "open handle"
  12020.                technique to test for the presence of the memory manager. 
  12021.                This section describes how to use the technique and gives an
  12022.                example.
  12023.  
  12024.           Caution.........................................................
  12025.                Don't use this technique if your program is a device driver
  12026.                or if it interrupts DOS during file system operations.  Use
  12027.                the "get interrupt vector" technique described later in this
  12028.                appendix.
  12029.  
  12030.  
  12031.           Using the "open handle" technique
  12032.  
  12033.                This section describes how to use the DOS "open handle"
  12034.                technique to test for the presence of the memory manager. 
  12035.                Follow these steps in order:
  12036.  
  12037.           Testing For The Presence Of The EMM                           199
  12038.  
  12039.  
  12040.  
  12041.  
  12042.  
  12043.                1.  Issue an "open handle" command (DOS function 3Dh) in
  12044.                    "read only" access mode (register AL = 0).  This
  12045.                    function requires your program to point to an ASCII
  12046.                    string which contains the path name of the file or
  12047.                    device in which you're interested (register set DS:DX
  12048.                    contains the pointer).  In this case the file is
  12049.                    actually the name of the memory manager.
  12050.  
  12051.                    You should format the ASCII string as follows:
  12052.  
  12053.                    ASCII_device_name  DB  'EMMXXXX0', 0
  12054.  
  12055.                    The ASCII codes for the capital letters EMMXXXX0 are
  12056.                    terminated by a byte containing a value of zero.
  12057.  
  12058.                2.  If DOS returns no error status code, skip Steps 3 and 4
  12059.                    and go to Step 5.  If DOS returns a "Too many open
  12060.                    files" error status code, go to Step 3.  If DOS returns
  12061.                    a "File/Path not found" error status code, skip Step 3
  12062.                    and go to Step 4.
  12063.  
  12064.                3.  If DOS returns a "Too many open files" (not enough
  12065.                    handles) status code, your program should invoke the
  12066.                    "open file" command before it opens any other files. 
  12067.                    This will guarantee that at least one file handle will
  12068.                    be available to perform the function without causing
  12069.                    this error.
  12070.  
  12071.                    After the program performs the "open file" command, it
  12072.                    should perform the test described in Step 6 and close
  12073.                    the "file handle" (DOS function 3Eh).  Don't keep the
  12074.                    manager "open" after this status test is performed since
  12075.                    "manager" functions are not available through DOS.  Go
  12076.                    to Step 6.
  12077.  
  12078.                4.  If DOS returns a "File/Path not found," the memory
  12079.                    manager is not installed.  If your application requires
  12080.                    the memory manager, the user will have to reboot the
  12081.                    system with a disk containing the memory manager and the
  12082.                    appropriate CONFIG.SYS file before proceeding.
  12083.  
  12084.                5.  If DOS doesn't return an error status code you can
  12085.                    assume that either a device with the name EMMXXXX0 is
  12086.                    resident in the system, or a file with this name is on
  12087.                    disk in the current disk drive.  Go to Step 6.
  12088.  
  12089.                6.  Issue an "I/O Control for Devices" command (DOS function
  12090.                    44h) with a "get device information" command (register
  12091.                    AL = 0).  DOS function 44h determines whether EMMXXXX0
  12092.                    is a device or a file.
  12093.  
  12094.  
  12095.  
  12096.           Testing For The Presence Of The EMM                           200
  12097.  
  12098.  
  12099.  
  12100.  
  12101.  
  12102.                    You must use the file handle (register BX) which you
  12103.                    obtained in Step 1 to access the "EMM" device.
  12104.  
  12105.                    This function returns the "device information" in a word
  12106.                    (register DX).  Go to Step 7.
  12107.  
  12108.                7.  If DOS returns any error status code, you should assume
  12109.                    that the memory manager device driver is not installed. 
  12110.                    If your application requires the memory manager, the
  12111.                    user will have to reboot the system with a disk contain-
  12112.                    ing the memory manager and the appropriate CONFIG.SYS
  12113.                    file before proceeding.
  12114.  
  12115.                8.  If DOS didn't return an error status, test the contents
  12116.                    of bit 7 (counting from 0) of the "device information"
  12117.                    word (register DX) the function returned.  Go to Step 9.
  12118.  
  12119.                9.  If bit 7 of the "device information" word contains a
  12120.                    zero, then EMMXXXX0 is a file, and the memory manager
  12121.                    device driver is not present.  If your application
  12122.                    requires the memory manager, the user will have to
  12123.                    reboot the system with a disk containing the memory
  12124.                    manager and the appropriate CONFIG.SYS file before
  12125.                    proceeding.
  12126.  
  12127.                    If bit 7 contains a one, then EMMXXXX0 is a device.  Go
  12128.                    to Step 10.
  12129.  
  12130.                10. Issue an "I/O Control for Devices" command (DOS function
  12131.                    44h) with a "get output status" command (register AL =
  12132.                    7).
  12133.  
  12134.                    You must use the file handle you obtained in Step 1 to
  12135.                    access the "EMM" device (register BX).  Go to Step 11.
  12136.  
  12137.                11. If the expanded memory device driver is "ready," the
  12138.                    memory manager passes a status value of "FFh" in
  12139.                    register AL.  The status value is "00h" if the device
  12140.                    driver is "not ready."
  12141.  
  12142.                    If the memory manager device driver is "not ready" and
  12143.                    your application requires its presence, the user will
  12144.                    have to reboot the system with a disk containing the
  12145.                    memory manager and the appropriate CONFIG.SYS file
  12146.                    before proceeding.
  12147.  
  12148.                    If the memory manager device driver is "ready," go to
  12149.                    Step 12.
  12150.  
  12151.  
  12152.  
  12153.  
  12154.  
  12155.           Testing For The Presence Of The EMM                           201
  12156.  
  12157.  
  12158.  
  12159.  
  12160.  
  12161.                12. Issue a "Close File Handle" command (DOS function 3Eh)
  12162.                    to close the expanded memory device driver.  You must
  12163.                    use the file handle you obtained in Step 1 to close the
  12164.                    "EMM" device (register BX).
  12165.  
  12166.  
  12167.  
  12168.  
  12169.  
  12170.  
  12171.  
  12172.  
  12173.  
  12174.  
  12175.  
  12176.  
  12177.  
  12178.  
  12179.  
  12180.  
  12181.  
  12182.  
  12183.  
  12184.  
  12185.  
  12186.  
  12187.  
  12188.  
  12189.  
  12190.  
  12191.  
  12192.  
  12193.  
  12194.  
  12195.  
  12196.  
  12197.  
  12198.  
  12199.  
  12200.  
  12201.  
  12202.  
  12203.  
  12204.  
  12205.  
  12206.  
  12207.  
  12208.  
  12209.  
  12210.  
  12211.  
  12212.  
  12213.  
  12214.           Testing For The Presence Of The EMM                           202
  12215.  
  12216.  
  12217.  
  12218.  
  12219.  
  12220.           An example of the "open handle" technique
  12221.  
  12222.                The following procedure is an example of the "open handle"
  12223.                technique outlined in the previous section.
  12224.  
  12225.           ;--------------------------------------------------------------;
  12226.           ;    The following procedure tests for the presence of the     ;
  12227.           ;    EMM in the system.  It returns the CARRY FLAG SET if      ;
  12228.           ;    the EMM is present.  If the EMM is not present, this      ;
  12229.           ;    procedure returns the CARRY FLAG CLEAR.                   ;
  12230.           ;--------------------------------------------------------------;
  12231.  
  12232.           first_test_for_EMM  PROC  NEAR
  12233.           PUSH  DS
  12234.           PUSH  CS
  12235.           POP   DS
  12236.           MOV   AX,3D00h                       ; issue "device open" in
  12237.           LEA   DX,ASCII_device_name           ; "read only" mode
  12238.           INT   21h
  12239.           JC    first_test_for_EMM_error_exit  ; test for error
  12240.                                                ; during "device open"
  12241.           MOV   BX,AX                          ; get the "file
  12242.                                                ; handle" returned by DOS
  12243.           MOV   AX,4400h                       ; issue "IOCTL
  12244.           INT   21h                            ; get device info"
  12245.           JC    first_test_for_EMM_error_exit  ; test for error
  12246.                                                ; during "get device info"
  12247.           TEST  DX,0080h                       ; test to determine
  12248.           JZ    first_test_for_EMM_error_exit  ; ASCII_device_name
  12249.                                                ; is a device or a file
  12250.           MOV   AX,4407h                       ; issue "IOCTL"
  12251.           INT   21h
  12252.           JC    first_test_for_EMM_error_exit  ; test for error
  12253.                                                ; during "IOCTL"
  12254.           PUSH  AX                             ; save "IOCTL" status
  12255.           MOV   AH,3Eh                         ; issue "close
  12256.           INT   21h                            ; file handle"
  12257.           POP   AX                             ; restore "IOCTL" status
  12258.           CMP   AL,0FFh                        ; test for "device
  12259.           JNE   first_test_for_EMM_error_exit  ; ready" status
  12260.                                                ; returned by the driver
  12261.           first_test_for_EMM_exit:
  12262.           POP   DS                             ; EMM is present
  12263.           STC                                  ; in the system
  12264.           RET
  12265.  
  12266.           first_test_for_EMM_error_exit:
  12267.           POP   DS                             ; EMM is NOT present
  12268.           CLC                                  ; in the system
  12269.           RET
  12270.           ASCII_device_name   DB  'EMMXXXX0', 0
  12271.           first_test_for_EMM  ENDP
  12272.  
  12273.           Testing For The Presence Of The EMM                           203
  12274.  
  12275.  
  12276.  
  12277.  
  12278.  
  12279.           The "get interrupt vector" technique
  12280.  
  12281.                Any type of program can use the DOS "get interrupt vector"
  12282.                technique to test for the presence of the memory manager. 
  12283.                This section describes how to use the technique and gives an
  12284.                example.
  12285.  
  12286.           Caution.........................................................
  12287.                Be sure to use this technique (and not the "open handle"
  12288.                technique) if your program is a device driver or if it
  12289.                interrupts DOS during file system operations.
  12290.  
  12291.  
  12292.           Using the "get interrupt vector" technique
  12293.  
  12294.                This section describes how to use the DOS "get interrupt
  12295.                vector" technique to test for the presence of the memory
  12296.                manager.  Follow these steps in order:
  12297.  
  12298.                1.  Issue a "get vector" command (DOS function 35h) to
  12299.                    obtain the contents of interrupt vector array entry
  12300.                    number 67h (addresses 0000:019Ch thru 0000:019Fh).
  12301.  
  12302.                    The memory manager uses this interrupt vector to perform
  12303.                    all manager functions.  The offset portion of this
  12304.                    interrupt service routine address is stored in the word
  12305.                    located at address 0000:019Ch; the segment portion is
  12306.                    stored in the word located at address 0000:019Eh.
  12307.  
  12308.                2.  Compare the "device name field" with the contents of the
  12309.                    ASCII string which starts at the address specified by
  12310.                    the segment portion of the contents of interrupt vector
  12311.                    address 67h and a fixed offset of 000Ah.  If DOS loaded
  12312.                    the memory manager at boot time this name field will
  12313.                    have the name of the device in it.
  12314.  
  12315.                    Since the memory manager is implemented as a character
  12316.                    device driver, its program origin is 0000h.  Device
  12317.                    drivers are required to have a "device header" located
  12318.                    at the program origin.  Within the "device header" is an
  12319.                    8 byte "device name field."  For a character mode device
  12320.                    driver this name field is always located at offset 000Ah
  12321.                    within the device header.  The device name field
  12322.                    contains the name of the device which DOS uses when it
  12323.                    references the device.
  12324.  
  12325.                    If the result of the "string compare" in this technique
  12326.                    is positive, the memory manager is present.
  12327.  
  12328.  
  12329.  
  12330.  
  12331.  
  12332.           Testing For The Presence Of The EMM                           204
  12333.  
  12334.  
  12335.  
  12336.  
  12337.  
  12338.           An example of the "get interrupt vector" technique
  12339.  
  12340.                The following procedure is an example of the "get interrupt
  12341.                vector" technique outlined in the previous section.
  12342.  
  12343.  
  12344.           ;--------------------------------------------------------------;
  12345.           ;    The following procedure tests for the presence of the     ;
  12346.           ;    EMM in the system.  It returns the CARRY FLAG SET if      ;
  12347.           ;    the EMM is present.  If the EMM is not present, this      ;
  12348.           ;    procedure returns the CARRY FLAG CLEAR.                   ;
  12349.           ;--------------------------------------------------------------;
  12350.  
  12351.  
  12352.           second_test_for_EMM  PROC  NEAR
  12353.           PUSH  DS
  12354.           PUSH  CS
  12355.           POP   DS
  12356.           MOV   AX,3567h                       ; issue "get interrupt
  12357.                                                ; vector"
  12358.           INT   21h
  12359.           MOV   DI,000Ah                       ; use the segment in ES
  12360.                                                ; returned by DOS, place
  12361.                                                ; the "device name field"
  12362.                                                ; OFFSET in DI
  12363.           LEA   SI,ASCII_device_name           ; place the OFFSET of the
  12364.                                                ; device name string in SI,
  12365.                                                ; the SEGMENT is already
  12366.                                                ; in DS
  12367.           MOV   CX,8                           ; compare the name strings
  12368.           CLD
  12369.           REPE  CMPSB
  12370.           JNE   second_test_for_EMM_error_exit
  12371.  
  12372.           second_test_for_EMM_exit:
  12373.           POP   DS                             ; EMM is present in
  12374.           STC                                  ; the system
  12375.           RET
  12376.  
  12377.           second_test_for_EMM_error_exit:
  12378.           POP   DS                             ; EMM is NOT present
  12379.           CLC                                  ; in the system
  12380.           RET
  12381.  
  12382.           ASCII_device_name   DB  'EMMXXXX0'
  12383.           second_test_for_EMM ENDP
  12384.  
  12385.  
  12386.  
  12387.  
  12388.  
  12389.  
  12390.  
  12391.           Testing For The Presence Of The EMM                           205
  12392.  
  12393.  
  12394.  
  12395.  
  12396.  
  12397.           Appendix C
  12398.           EXPANDED MEMORY MANAGER IMPLEMENTATION GUIDELINES
  12399.  
  12400.  
  12401.  
  12402.                In addition to the functional specification, the expanded
  12403.                memory manager should provide certain resources.  The
  12404.                following guidelines are provided so required resources are
  12405.                present in expanded memory managers which comply with this
  12406.                version of the LIM specification.
  12407.  
  12408.                o   The amount of expanded memory supported:
  12409.                    Up to a maximum of 32M bytes of expanded memory should
  12410.                    be supported.
  12411.  
  12412.                o   The number of handles supported:
  12413.                    The maximum number of expanded memory handles provided
  12414.                    should be 255, the minimum should be 64.
  12415.  
  12416.                o   Handle Numbering:
  12417.                    Although a handle is a word quantity, there is a maximum
  12418.                    of 255 handles, including the operating system handle. 
  12419.                    This specification defines the handle word as follows: 
  12420.                    the low byte of the word is the actual handle value, the
  12421.                    high byte of the handle is set to 00h by the memory
  12422.                    manager.  Previous versions of this specification did
  12423.                    not specify the value of handles.
  12424.  
  12425.                o   New handle type:  Handles versus Raw Handles:
  12426.                    The difference between a raw handle and a regular handle
  12427.                    is slight.  If you use Function 27 to "Allocate raw
  12428.                    pages to a handle," what is returned in DX is termed a
  12429.                    raw handle.  The raw handle does not necessarily refer
  12430.                    to 16K-byte pages.  Instead it refers to the "raw" page
  12431.                    size, which depends on the expanded memory hardware.
  12432.  
  12433.                    An application program can use Function 26 to find the
  12434.                    raw page size, and by using the raw handle Function 27
  12435.                    returns, it can access them with the finer resolution
  12436.                    that a particular expanded memory board may allow.
  12437.  
  12438.                    On the other hand, applications which use Function 4 to
  12439.                    "allocate pages to handle" receive a handle which always
  12440.                    refers to 16K-byte pages.  On expanded memory boards
  12441.                    with smaller raw pages, the EMM driver will allocate and
  12442.                    maintain the number of raw pages it takes to create a
  12443.                    single composite 16K-byte page.  The difference between
  12444.                    the expanded memory boards' raw page size and the 16K-
  12445.                    byte LIM page size is transparent to the application
  12446.                    when it is using a handle obtained with Function 4.
  12447.  
  12448.  
  12449.  
  12450.           EMM Implementation Guidelines                                 206
  12451.  
  12452.  
  12453.  
  12454.  
  12455.  
  12456.                    The memory manager must differentiate between pages
  12457.                    allocated to handles and pages allocated to raw handles. 
  12458.                    The meaning of a call to the driver changes depending on
  12459.                    whether a handle or a raw handle is passed to the memory
  12460.                    manager.  If, for example, a handle is passed to
  12461.                    Function 18 (Reallocate), the memory manager will
  12462.                    increase or decrease the number of 16K-byte pages
  12463.                    allocated to the handle.  If Function 18 is passed a raw
  12464.                    handle, the memory manager will increase or decrease the
  12465.                    number of raw (non-16K-byte) pages allocated to the raw
  12466.                    handle.  For LIM standard boards, there is no difference
  12467.                    between pages and raw pages.
  12468.  
  12469.                o   The system Raw Handle (Raw Handle = 0000h):
  12470.                    For expanded memory boards that can remap the memory in
  12471.                    the lower 640K-byte address space, managing the pages of
  12472.                    memory which are used to fill in the lower 640K can be a
  12473.                    problem.  To solve this problem, the memory manager will
  12474.                    create a raw handle with a value of 0000h when DOS loads
  12475.                    the manager.  This raw handle is called the system
  12476.                    handle.
  12477.  
  12478.                    At power up, the memory manager will allocate all of the
  12479.                    pages that are mapped into the lower 640K bytes to the
  12480.                    system handle.  These pages should be mapped in their
  12481.                    logical order.  For example, if the system board
  12482.                    supplies 256K bytes of RAM, and the 384K bytes above it
  12483.                    is mappable, the system handle should have its logical
  12484.                    page zero mapped into the first physical page at 256K,
  12485.                    its logical page one mapped into the next physical page,
  12486.                    and so on.
  12487.  
  12488.                    The system handle should deal with raw pages.  To
  12489.                    release some of these pages so application programs can
  12490.                    use them, an operating system could decrease the number
  12491.                    of pages allocated to the system handle with the
  12492.                    "Reallocate" function.  Invoking the "Deallocate"
  12493.                    function would decrease the system handle to zero size,
  12494.                    but it must not deallocate the raw handle itself.  The
  12495.                    "Deallocate" function treats the system handle dif-
  12496.                    ferently than it treats other raw handles.  If the
  12497.                    operating system can ever be "exited" (for example, the
  12498.                    way Windows can be exited), it must increase the size of
  12499.                    the system handle back to what is needed to fill 640K
  12500.                    and map these logical pages back into physical memory
  12501.                    before returning to DOS.
  12502.  
  12503.  
  12504.  
  12505.  
  12506.  
  12507.  
  12508.  
  12509.           EMM Implementation Guidelines                                 207
  12510.  
  12511.  
  12512.  
  12513.  
  12514.  
  12515.                    There are two functional special cases for this handle:
  12516.  
  12517.                    -   The first special case deals with Function 4
  12518.                        (Allocate Pages).  This function must never return
  12519.                        zero as a handle value.  Applications must always
  12520.                        invoke Function 4 to allocate pages and obtain a
  12521.                        handle which identifies its pages.  Since Function 4
  12522.                        will never return a handle value of zero, an
  12523.                        application will never gain access to this special
  12524.                        handle.
  12525.  
  12526.                    -   The second special case deals with Function 6
  12527.                        (Deallocate Pages).  If the operating system uses
  12528.                        Function 6 to deallocate the pages which are
  12529.                        allocated to the system handle, the pages will be
  12530.                        returned to the manager for use, but the handle will
  12531.                        not be available for reassignment.  The manager
  12532.                        should treat a "deallocate pages" function request
  12533.                        for this handle the same as a "reallocate pages"
  12534.                        function request, where the number of pages to
  12535.                        reallocate to this handle is zero.
  12536.  
  12537.                o   Terminate and Stay Resident (TSR) Program Cooperation:
  12538.                    In order for TSR's to cooperate with each other and with
  12539.                    other applications, TSR's must follow this rule:  a
  12540.                    program may only remap the DOS partition it lives in. 
  12541.                    This rule applies at all times, even when no expanded
  12542.                    memory is present.
  12543.  
  12544.                o   Accelerator Cards:
  12545.                    To support generic accelerator cards, the support of
  12546.                    Function 34, as defined by AST, is encouraged.
  12547.  
  12548.  
  12549.  
  12550.  
  12551.  
  12552.  
  12553.  
  12554.  
  12555.  
  12556.  
  12557.  
  12558.  
  12559.  
  12560.  
  12561.  
  12562.  
  12563.  
  12564.  
  12565.  
  12566.  
  12567.  
  12568.           EMM Implementation Guidelines                                 208
  12569.  
  12570.  
  12571.  
  12572.  
  12573.  
  12574.           Appendix D
  12575.           OPERATING SYSTEM/ENVIRONMENT USE OF FUNCTION 28
  12576.  
  12577.  
  12578.  
  12579.                All expanded memory boards have a set of registers that
  12580.                "remember" the logical to physical page mappings.  Some
  12581.                boards have extra (or alternate) sets of these mapping
  12582.                registers.  Because no expanded memory board can supply an
  12583.                infinite number of alternate map register sets, this
  12584.                specification provides a way to simulate them using Function
  12585.                28 (Alternate Map Register Set).
  12586.  
  12587.  
  12588.           Examples
  12589.  
  12590.                For the examples in this section, assume the hardware
  12591.                supports alternate map register sets.  First Windows is
  12592.                brought up, then "Reversi" is started.  Then control is
  12593.                switched back to the MS-DOS Executive.  For this procedure,
  12594.                here are the calls to the expanded memory manager:
  12595.  
  12596.                                       Example 1
  12597.  
  12598.           Allocate alt reg set           ; Start up the MS-DOS
  12599.           (for MS-DOS Executive)         ; Executive
  12600.  
  12601.           Set alt reg set
  12602.           (for MS-DOS Executive)
  12603.  
  12604.           Allocate alt reg set           ; Start up Reversi
  12605.           (for Reversi)
  12606.  
  12607.           Set alt reg set
  12608.           (for Reversi)
  12609.  
  12610.           Map pages
  12611.           (for Reversi)
  12612.  
  12613.           Set alt ret set                ; Switch back to MS-DOS
  12614.           (for MS-DOS Executive)         ; Executive
  12615.  
  12616.  
  12617.  
  12618.  
  12619.  
  12620.  
  12621.  
  12622.  
  12623.  
  12624.  
  12625.  
  12626.  
  12627.           Operating System Use Of Function 28                           209
  12628.  
  12629.  
  12630.  
  12631.  
  12632.  
  12633.                Notice this procedure needed no "get" calls because the
  12634.                register set contained all the information needed to save a
  12635.                context.  However, using "Get" calls would have no ill
  12636.                effects.
  12637.  
  12638.                                       Example 2
  12639.  
  12640.           Allocate alt reg set           ; Start up MS-DOS
  12641.           (for MS-DOS Executive)         ; Executive
  12642.  
  12643.           Set alt reg set
  12644.           (for MS-DOS Executive)
  12645.  
  12646.           Get alt reg set
  12647.           (for MS-DOS Executive)
  12648.  
  12649.           Allocate alt reg set           ; Start up Reversi
  12650.           (for Reversi)
  12651.  
  12652.           Set alt reg set
  12653.           (for Reversi)
  12654.  
  12655.           Map pages
  12656.           (for Reversi)
  12657.  
  12658.           Get alt reg set
  12659.           (for Reversi)
  12660.  
  12661.           Set alt reg set                ; Switch back to MS-DOS
  12662.           (for MS-DOS Executive)         ; Executive
  12663.  
  12664.                The important point to follow is that a Set must always
  12665.                precede a Get.  The model of Set then Get is the inverse of
  12666.                what interrupt handlers use, which is Get then Set (Get the
  12667.                old map context and Set the new one).  Another crucial point
  12668.                is that an alternate map register set must have the current
  12669.                mapping when allocated; otherwise, the Set will create
  12670.                chaos.
  12671.  
  12672.                What happens if this is simulated in software?  The same Set
  12673.                and Get model applies.  The main difference is where the
  12674.                context is saved.
  12675.  
  12676.  
  12677.  
  12678.  
  12679.  
  12680.  
  12681.  
  12682.  
  12683.  
  12684.  
  12685.  
  12686.           Operating System Use Of Function 28                           210
  12687.  
  12688.  
  12689.  
  12690.  
  12691.  
  12692.                Since the allocate call is dynamic and there is no limit on
  12693.                the number of sets allocated, the OS/E must supply the space
  12694.                required.  Device drivers cannot allocate space dynamically,
  12695.                since the request would fail.  If the Allocate register set
  12696.                call returns a status indicating the alternate map register
  12697.                sets aren't supported, the OS/E must allocate space for the
  12698.                context.  It must also initialize the context using Function
  12699.                15.  At that point it can do the Set, passing a pointer to
  12700.                the map context space.  On the Get call, the EMM driver is
  12701.                to return a pointer to the same context space.
  12702.  
  12703.                                       Example 3
  12704.  
  12705.           Allocate alt reg set           ; Start up MS-DOS
  12706.           (for MS-DOS Executive)         ; Executive
  12707.  
  12708.           Get Page Map
  12709.           (for MS-DOS Executive)
  12710.  
  12711.           Set alt reg set
  12712.           (for MS-DOS Executive)
  12713.  
  12714.           Allocate alt reg set           ; Start up Reversi
  12715.           (for Reversi)
  12716.  
  12717.           Set alt reg set
  12718.           (for Reversi)
  12719.  
  12720.           Map pages
  12721.           (for Reversi)
  12722.  
  12723.           Get Page Map
  12724.           (for Reversi)
  12725.  
  12726.           Set alt ret set                ; Switch back to MS-DOS
  12727.           (for MS-DOS Executive)         ; Executive
  12728.  
  12729.  
  12730.  
  12731.  
  12732.  
  12733.  
  12734.  
  12735.  
  12736.  
  12737.  
  12738.  
  12739.  
  12740.  
  12741.  
  12742.  
  12743.  
  12744.  
  12745.           Operating System Use Of Function 28                           211
  12746.  
  12747.  
  12748.  
  12749.  
  12750.  
  12751.           GLOSSARY
  12752.  
  12753.  
  12754.  
  12755.                The following terms are used frequently in this specifica-
  12756.                tion:
  12757.  
  12758.  
  12759.           Allocate                 To reserve a specified amount of
  12760.                                    expanded memory pages.
  12761.  
  12762.           Application Program      An application program is the program
  12763.                                    you write and your customer uses.  Some
  12764.                                    categories of application software are
  12765.                                    word processors, database managers,
  12766.                                    spreadsheet managers, and project
  12767.                                    managers.
  12768.  
  12769.           Conventional memory      The memory between 0 and 640K bytes,
  12770.                                    address range 00000h thru 9FFFFh.
  12771.  
  12772.           Deallocate               To return previously allocated expanded
  12773.                                    memory to the memory manager.
  12774.  
  12775.           EMM                      See Expanded Memory Manager.
  12776.  
  12777.           Expanded memory          Expanded memory is memory outside DOS's
  12778.                                    640K-byte limit (usually in the range of
  12779.                                    C0000h thru EFFFFh).
  12780.  
  12781.           Expanded Memory          A device driver that controls the
  12782.             Manager (EMM)          interface between DOS application
  12783.                                    programs and expanded memory.
  12784.  
  12785.           Extended memory          The 15M-byte address range between
  12786.                                    100000h thru FFFFFFh available on an
  12787.                                    80286 processor when it is operating in
  12788.                                    protected virtual address mode.
  12789.  
  12790.           Handle                   A value that the EMM assigns and uses to
  12791.                                    identify a block of memory requested by
  12792.                                    an application program.  All allocated
  12793.                                    logical pages are associated with a
  12794.                                    particular handle.
  12795.  
  12796.           Logical Page             The EMM allocates expanded memory in
  12797.                                    units (typically 16K bytes) called
  12798.                                    logical pages.
  12799.  
  12800.           Mappable Segment         A 16K-byte region of memory which can
  12801.                                    have a logical page mapped at it.
  12802.  
  12803.  
  12804.           Glossary                                                      212
  12805.  
  12806.  
  12807.  
  12808.  
  12809.  
  12810.           Map Registers            The set of registers containing the
  12811.                                    current mapping context of the EMM
  12812.                                    hardware.
  12813.  
  12814.           Mapping                  The process of making a logical page of
  12815.                                    memory appear at a physical page.
  12816.  
  12817.           Mapping Context          The contents of the mapping registers at
  12818.                                    a specific instant.  This context
  12819.                                    represents a map state.
  12820.  
  12821.           Page Frame               A collection of 16K-byte contiguous
  12822.                                    physical pages from which an application
  12823.                                    program accesses expanded memory.
  12824.  
  12825.           Page Frame               A page frame base address is the
  12826.             Base Address           location (in segment format) of the
  12827.                                    first byte of the page frame.
  12828.  
  12829.           Physical Page            A physical page is the range of memory
  12830.                                    addresses occupied by a single 16K-byte
  12831.                                    page.
  12832.  
  12833.           Raw Page                 The smallest unit of mappable memory
  12834.                                    that an expanded memory board can
  12835.                                    supply.
  12836.  
  12837.           Resident Application     A resident application program is loaded
  12838.             Program                by DOS, executes, and remains resident
  12839.                                    in the system after it returns control
  12840.                                    to DOS.  This type of program occupies
  12841.                                    memory and is usually invoked by the
  12842.                                    operating system, an application
  12843.                                    program, or the hardware.  Some example
  12844.                                    of resident application programs are RAM
  12845.                                    disks, print spoolers, and "pop-up"
  12846.                                    desktop programs.
  12847.  
  12848.           Status code              A code that an EMM function returns
  12849.                                    which indicates something about the
  12850.                                    result of running the function.  Some
  12851.                                    status codes indicate whether the
  12852.                                    function worked correctly and others may
  12853.                                    tell you something about the expanded
  12854.                                    memory hardware or software.
  12855.  
  12856.  
  12857.  
  12858.  
  12859.  
  12860.  
  12861.  
  12862.  
  12863.           Glossary                                                      213
  12864.  
  12865.  
  12866.  
  12867.  
  12868.  
  12869.           Transient Application    A transient application program is
  12870.             Program                loaded by DOS, executes, and doesn't
  12871.                                    remain in the system after it returns
  12872.                                    control to DOS.  After a transient
  12873.                                    application program returns control to
  12874.                                    DOS, the memory it used is available for
  12875.                                    other programs.
  12876.  
  12877.           Unmap                    To make a logical page inaccessible for
  12878.                                    reading or writing.
  12879.  
  12880.  
  12881.  
  12882.  
  12883.  
  12884.  
  12885.  
  12886.  
  12887.  
  12888.  
  12889.  
  12890.  
  12891.  
  12892.  
  12893.  
  12894.  
  12895.  
  12896.  
  12897.  
  12898.  
  12899.  
  12900.  
  12901.  
  12902.  
  12903.  
  12904.  
  12905.  
  12906.  
  12907.  
  12908.  
  12909.  
  12910.  
  12911.  
  12912.  
  12913.  
  12914.  
  12915.  
  12916.  
  12917.  
  12918.  
  12919.  
  12920.  
  12921.  
  12922.           Glossary                                                      214
  12923.  
  12924.  
  12925.  
  12926.  
  12927.  
  12928.           INDEX
  12929.  
  12930.  
  12931.  
  12932.                Allocate Alternate Map Register Set  36, 163
  12933.                Allocate DMA Register Set  36, 168, 190
  12934.                Allocate Pages  5, 14, 23, 30, 34, 42, 43, 47, 49, 144,
  12935.                    147, 148, 193, 206, 208
  12936.                Allocate Raw Pages  36, 46, 80, 89, 147-149, 190, 193,
  12937.                    206
  12938.                Allocate Standard Pages  36, 42, 46, 80, 89, 144, 145,
  12939.                    147, 190, 193
  12940.                Alter Page Map & Call  7, 10, 35, 113, 118, 189
  12941.                Alter Page Map & Jump  7, 10, 35, 109, 189
  12942.                Alternate Map  10, 36, 151, 153-155, 157-159, 161, 163,
  12943.                    164, 165-168, 170, 173, 175, 179, 182, 190, 197,
  12944.                    209, 210, 211
  12945.                Alternate Map Register Set  10, 36, 151, 153-155, 157,
  12946.                    158, 159, 161, 163-168, 170, 173, 175, 190, 197,
  12947.                    209, 210
  12948.                Alternate Mapping and Unmapping Methods  81
  12949.                Alternate Register  139, 166, 173, 177
  12950.                Data Aliasing  12
  12951.                Deallocate Alternate Map Register Set  36, 166
  12952.                Deallocate DMA Register Set  36, 175, 190
  12953.                Deallocate Pages  5, 14, 25, 31, 34, 43, 49, 88, 145,
  12954.                    148, 208
  12955.                Design Considerations  91, 151
  12956.                Device Driver  1, 15, 43, 53, 55, 144, 148, 199, 201,
  12957.                    202, 204, 212
  12958.                Disable DMA on Alternate Map Register Set  173
  12959.                Disable OS/E Function Set  36, 179, 180, 182, 185
  12960.                DMA  36, 138-140, 151, 152, 168-176, 190, 197
  12961.                DMA Channels  139, 171, 173, 174, 197
  12962.                DMA Register  36, 139, 140, 151, 152, 168-171, 173-176,
  12963.                    190, 197
  12964.                DOS  1, 12, 14, 15, 19, 21, 30, 31, 49, 53, 88, 199-205,
  12965.                    207-214
  12966.                Enable DMA on Alternate Map Register Set  170
  12967.                Enable OS/E Function Set  36, 179, 180
  12968.                Enable/Disable OS/E Function Set  179, 180, 182, 185
  12969.                Exchange Memory Region  7, 10, 35, 120, 126, 127, 189
  12970.                Expanded Memory Support of DMA  151
  12971.                Expanded Memory Support of DMA Register Sets  151
  12972.                Extended Memory  91
  12973.                Function 1  37
  12974.                Function 10  57
  12975.                Function 11  58
  12976.                Function 12  59
  12977.                Function 13  61
  12978.                Function 14  7, 63
  12979.  
  12980.  
  12981.           Index                                                         215
  12982.  
  12983.  
  12984.  
  12985.  
  12986.  
  12987.                Function 15  13, 53, 55, 65, 67, 69, 71, 73, 76, 139,
  12988.                    153, 154, 155, 158, 211
  12989.                Function 16  13, 73, 76, 78
  12990.                Function 17  6, 80, 82, 85
  12991.                Function 18  6, 43, 88, 144, 148, 207
  12992.                Function 19  7, 91, 92, 94, 96
  12993.                Function 2  4, 38
  12994.                Function 20  7, 98, 100
  12995.                Function 21  7, 42, 102, 105, 107
  12996.                Function 22  109
  12997.                Function 23  113, 118
  12998.                Function 24  7, 120, 126
  12999.                Function 25  6, 8, 46, 74, 85, 132, 136
  13000.                Function 26  138, 142, 179, 182, 206
  13001.                Function 27  42, 46, 80, 89, 144, 145, 147-149, 193, 206
  13002.                Function 28  140, 151, 153, 157, 161, 163, 164, 166,
  13003.                    168, 170, 173, 175, 179, 182, 209
  13004.                Function 29  177
  13005.                Function 3  4, 40, 142
  13006.                Function 30  138, 151, 153, 157, 161, 163, 166, 168,
  13007.                    170, 173, 175, 179, 182, 185
  13008.                Function 4  4, 42, 43, 46, 47, 49, 80, 89, 144, 145,
  13009.                    147, 149, 193, 206, 208
  13010.                Function 5  4, 46, 81
  13011.                Function 6  4, 43, 49, 88, 145, 148, 208
  13012.                Function 7  5, 51
  13013.                Function 8  46, 50, 53, 55
  13014.                Function 9  46, 50, 53, 55
  13015.                Get & Set Page Map  35, 69
  13016.                Get All Handle Pages  9, 34, 63
  13017.                Get Alternate Map Register Set  36, 153, 154, 157, 190
  13018.                Get Alternate Map Save Array Size  36, 161, 190
  13019.                Get Attribute Capability  7, 96
  13020.                Get Expanded Memory Hardware Information  10, 138, 142,
  13021.                    179, 182
  13022.                Get Handle Attribute  35, 92
  13023.                Get Handle Count  9, 34, 59
  13024.                Get Handle Directory  10, 35, 102, 105, 107
  13025.                Get Handle Name  35, 98
  13026.                Get Handle Pages  7, 9, 34, 61
  13027.                Get Hardware Configuration Array  36, 138
  13028.                Get Interrupt Vector  15, 21, 30, 199, 204, 205
  13029.                Get Mappable Physical Address Array  6, 8, 10, 35, 46,
  13030.                    85, 132, 136
  13031.                Get Mappable Physical Address Array Entries  8, 136
  13032.                Get Page Frame Address  5, 34, 38
  13033.                Get Page Map  35, 65, 118, 153-155, 158, 211
  13034.                Get Page Map Stack Space Size  35, 118
  13035.                Get Partial Page Map  35, 73, 78
  13036.                Get Size of Page Map Save Array  35, 65, 67, 71, 139
  13037.                Get Size of Partial Page Map Save Array  74, 76, 78
  13038.                Get Status  5, 34, 37
  13039.  
  13040.           Index                                                         216
  13041.  
  13042.  
  13043.  
  13044.  
  13045.  
  13046.                Get Total Handles  35, 107
  13047.                Get Unallocated Page Count  5, 22, 34, 40, 142
  13048.                Get Unallocated Raw Page Count  36, 142, 189
  13049.                Get Version  5, 34, 51
  13050.                Get/Set Handle Attribute  9, 91, 92, 94, 96
  13051.                Get/Set Handle Name  10, 98, 100
  13052.                Get/Set Page Map  9, 13, 65, 67, 69, 71
  13053.                Get/Set Partial Page Map  9, 13, 73, 76, 78
  13054.                Handle Attribute  9, 35, 91-94, 96, 188
  13055.                Handle Name  6, 7, 10, 35, 98, 100, 105, 106, 188, 198
  13056.                Intel  i, ii, 1, 5, 57, 58
  13057.                Interrupt Vector  12, 15, 21, 30, 199, 204, 205
  13058.                LIM  1, 7, 13, 19, 27, 53, 55, 138, 140, 206, 207
  13059.                Logical Page  1, 5, 12, 16, 19, 23, 28, 31, 32, 46-48,
  13060.                    80-83, 85, 86, 88, 110, 111, 115, 116, 120, 122,
  13061.                    123, 125, 126, 128, 129, 131, 147, 194, 196, 207,
  13062.                    212-214
  13063.                Logical Page/Physical Page Method  82
  13064.                Logical Page/Segment Address Method  85
  13065.                Lotus  i, ii, 1, 5, 57, 58
  13066.                Map Register  10, 13, 36, 53, 55, 151, 153-155, 157-159,
  13067.                    161, 163-168, 170, 173, 175, 179, 182, 190, 197,
  13068.                    209-211
  13069.                Map/Unmap Handle Pages  46
  13070.                Map/Unmap Multiple Handle Pages  9, 35, 80, 82, 85
  13071.                Mapping and Unmapping Multiple Pages Simultaneously  80
  13072.                Mapping Multiple Pages  6, 80
  13073.                Microsoft  i, ii, 1, 5, 14, 30, 42, 57, 58, 144, 148
  13074.                Move Memory Region  35, 120, 121, 189
  13075.                Move/Exchange Memory Region  7, 10, 120, 126
  13076.                Open Handle  64, 102, 199, 200, 203, 204
  13077.                Operating System  3, 8, 10-12, 42, 43, 59, 63, 107, 138,
  13078.                    139, 141, 142, 144-151, 153-159, 161-163, 165-171,
  13079.                    173-177, 179-183, 185, 186, 190, 191, 198, 206,
  13080.                    207-209, 213
  13081.                Page Frame  1-6, 14, 17-19, 24, 28, 31, 34, 38, 39, 47,
  13082.                    53, 55, 121, 128, 133, 187, 213
  13083.                Page Map  7, 9, 10, 13, 34, 35, 50, 53, 55, 65, 67, 69,
  13084.                    71, 73-76, 78, 109, 113, 118, 139, 153-155, 158,
  13085.                    187, 188, 189, 211
  13086.                Page Mapping Register I/O Array  57
  13087.                Page Translation Array  58
  13088.                Physical Page  1, 5, 6, 8, 10, 12, 16, 23, 28, 31, 35,
  13089.                    46, 47, 48, 80-83, 85, 109-112, 114-117, 132-134,
  13090.                    136, 138, 139, 142, 147, 188, 194, 207, 209, 213
  13091.                Prepare Expanded Memory Hardware For Warm Boot  10, 177
  13092.                Raw Handle  147, 149, 150, 206, 207
  13093.                Raw Page  36, 142, 143, 147, 189, 206
  13094.                Reallocate Pages  9, 35, 43, 88, 144, 145, 148, 208
  13095.                Restore Page Map  9, 13, 34, 50, 53, 55
  13096.                Return Access Key  185
  13097.                Save Page Map  9, 13, 34, 50, 53, 55
  13098.  
  13099.           Index                                                         217
  13100.  
  13101.  
  13102.  
  13103.  
  13104.  
  13105.                Search For Named Handle  7, 35, 105
  13106.                Set Alternate Map Register Set  36, 153-155, 157, 158,
  13107.                    163, 190
  13108.                Set Handle Attribute  9, 35, 91, 92, 94, 96
  13109.                Set Handle Name  7, 10, 35, 98, 100
  13110.                Set Page Map  9, 13, 35, 65, 67, 69, 71, 188
  13111.                Set Partial Page Map  9, 13, 35, 73, 76, 78
  13112.                Standard Handle  146
  13113.                Standard Page  147
  13114.                System DMA Capabilities  151
  13115.                TSR  12, 13, 208
  13116.                Unmapping Multiple Pages  6, 80
  13117.  
  13118.  
  13119.  
  13120.  
  13121.  
  13122.  
  13123.  
  13124.  
  13125.  
  13126.  
  13127.  
  13128.  
  13129.  
  13130.  
  13131.  
  13132.  
  13133.  
  13134.  
  13135.  
  13136.  
  13137.  
  13138.  
  13139.  
  13140.  
  13141.  
  13142.  
  13143.  
  13144.  
  13145.  
  13146.  
  13147.  
  13148.  
  13149.  
  13150.  
  13151.  
  13152.  
  13153.  
  13154.  
  13155.  
  13156.  
  13157.  
  13158.           Index                                                         218
  13159.  
  13160.  M╡pALLINFO.TXT
  13161. Following are BBSes that are members of DV-NET.  DV-Net is an informal
  13162. network of BBS's that carry files that would be useful to DESQview users. 
  13163. Not all BBSes that carry the DESQview conference are members of DV-Net.
  13164.  
  13165. All address are NetMail addresses.
  13166.  
  13167.             ----------------------------------------------
  13168.                  DVNet DESQview Support File Network
  13169.             ----------------------------------------------
  13170.          DESQview is a trademark of Quarterdeck Office Systems
  13171.        -----------------------------------------------------------
  13172.          DVNet is not affiliated with Quarterdeck Office Systems
  13173.    ----------------------------------------------------------------
  13174.  
  13175.    Name, City and State             NetAddress  Telephone     Maxbaud
  13176.    -------------------------------  ---------- ------------  -------
  13177.  *65'North, Fairbanks, AK         1:17/38    907-452-1460  9600HSTV32
  13178.   Opus 386, Davis, CA             1:203/910  916-753-6321  2400
  13179.   Carl's Corner, San Jose, CA     1:10/1     408-248-9704  9600HSTV32
  13180.   Carl's Corner, San Jose, CA     1:10/2     408-248-0198  2400
  13181.   SeaHunt BBS, Burlingame, CA     1:125/20   415-344-4348  9600HST
  13182.   Stingray!, Clovis CA            1:205/12   209-298-9461  9600HST
  13183.   SF PCUG BBS, San Francisco CA   1:1/310    415-621-2609  9600HSTV32RE
  13184.   Bink of an Aye, Portland, OR    1:105/42   503-297-9043  9600PEPV32MO
  13185.   P C Support, Portland, OR       1:105/66   503-297-9078  2400
  13186.   Atarian BBS, Portland, OR       1:105/10   503-245-9730  9600HSTV32
  13187.   Busker's BoneYard, Portland,OR  1:105/14   503-771-4773  9600PEP
  13188.   Busker's Boneyard, Portland,OR  1:105/41   503-775-7926  9600HSTV32
  13189.   Pacifier BBS, Vancouver, WA     1:105/103  206-253-9770  9600HSTV32
  13190.   Puget Sound Gtwy., Puyallup, WA 1:138/3    206-566-8854  9600HST
  13191.   Rampart General,Kansas City,MO  1:280/6    816-761-4039  9600HST
  13192.   Oregon Trail XRoads, Casper WY  1:303/5    307-472-3615  9600H96
  13193.   Dawg Byte, Nashville, TN        1:116/29   615-385-4268  9600HST
  13194.   Dickson County, Dickson, TN     1:116/25   615-446-4475  2400
  13195.   Programmers' Attic, Will., MI   1:159/850  517-655-3347  2400
  13196.   Dark Side Of the Moon,Savoy IL  1:233/493  217-356-6922  9600HSTV32
  13197.   Ecclesia Place, Monroeville, PA 1:129/75   412-373-8612  9600HST
  13198.   The Other BBS, Harrisburg PA    1:270/101  717-657-2223  9600HST
  13199.   IBM Tech Fido, Pepperell, MA    1:322/1    508-433-8452  9600HSTV32
  13200.   Waystar BBS, Marlborough, MA    1:322/14   508-481-7147  9600HST
  13201.   Andromeda Galaxy, Troy NY       1:267/167  518-273-8313  9600HST
  13202.   Treasure Island, Danbury, CT    1:141/730  203-791-8532, 9600HST
  13203.   Addict's Attic,Germantown MD    1:109/423  301-428-8998  9600HST
  13204.   Maple Shade Opus,Maple Shade NJ 1:266/12   609-482-8604  9600HSTV32
  13205.   Capital City , Burlington NJ   99:9230/1   609-386-1989  9600HSTV32
  13206.   Capital City , Burlington NJ    8:950/10   609-386-1989  9600HSTV32
  13207.   Southern Cross BBS, Miami FL    1:135/69   305-220-8752  9600HST
  13208.   Software Designer, Albany, GA   1:3617/1   912-432-2440  9600HSTV32
  13209.   Software Designer, Albany, GA   8:928/1    912-432-2440  9600HSTV32
  13210.   Dragon's Lair, Galveston, TX    1:386/451  409-762-2761  9600HST
  13211.   Dragon's Lair, Galveston, TX    1:386/1451 409-762-7456  2400MNP
  13212.   Conch Opus, Houston, TX         1:106/357  713-667-7213  2400PCP
  13213.   Inns of Court, Dallas, TX       1:124/6101 214-458-2620  9600HSTV32
  13214.   Dallas Email, Dallas, TX        8:930/101  214-358-1205  9600HSTV32MO
  13215.   Spare Parts, Bedford, TX        1:130/38   817-540-3527  9600HST
  13216.   QE2, Austin TX                  1:382/58   512-328-1229  2400
  13217.   Ned's Opus HST Ottawa,ON Canada 1:163/211  613-523-8965  9600HST
  13218.   Ned's Opus, Ottawa ON Canada    1:163/210  613-731-8132  2400
  13219.   Imperial Terran, St Cath,ON     1:247/102  416-646-7105  9600HST
  13220.   Arcane BBS, Laval PQ Canada     1:167/116  514-687-9586  9600HST
  13221.   Zone 2 & Zone 3
  13222.   ------------------------------  ---------  ------------- -------
  13223.   The HEKOM Board (Netherlands)   2:286/3    31-3483-4072  2400MNP5
  13224.   BBS_D.C.V.V., Maaseik (Belgium) 2:295/26   32-11-568620