

























                        DOS PROTECTED MODE INTERFACE (DPMI)

                                    SPECIFICATION



                  Protected Mode API For DOS Extended Applications

                                    Version 0.9

                               Printed July 26, 1990



































                                 TABLE OF CONTENTS


            1. Introduction............................................1

            2. General Notes for Protected Mode Programs...............4
                2.1 Virtual DOS Environments...........................5
                    2.1.1 No Virtualization............................5
                    2.1.2 Partial Virtualization.......................5
                    2.1.3 Complete Virtualization......................5
                2.2 Descriptor Management..............................6
                2.3 Interrupt Flag Management..........................7
                2.4 Interrupts.........................................8
                    2.4.1 Hardware Interrupts..........................8
                    2.4.2 Software Interrupts..........................9
                2.5 Virtual Memory and Page Locking...................10

            3. Mode and Stack Switching...............................11
                3.1 Stacks and Stack Switching........................12
                    3.1.1 Protected Mode Stack........................12
                    3.1.2 Locked Protected Mode Stack.................12
                    3.1.3 Real Mode Stack.............................12
                    3.1.4 DPMI Host Ring 0 Stack......................12
                3.2 Default Interrupt Reflection......................13
                3.3 Mode Switching....................................14
                3.4 State Saving......................................15

            4. Error Handling.........................................16

            5. Loading DPMI Clients and Extended Applications.........17
                5.1 Obtaining the Real to Protected Mode Switch Entry
                Point.................................................18
                5.2 Calling the Real to Protected Mode Switch Entry
                Point.................................................19

            6. Terminating A Protected Mode Program...................22

            7. Mode Detection.........................................23

            8. LDT Descriptor Management Services.....................24
                8.1 Allocate LDT Descriptors..........................25
                8.2 Free LDT Descriptor...............................26
                8.3 Segment to Descriptor.............................27
                8.4 Get Next Selector Increment Value.................28
                8.5 Reserved Subfunctions.............................29
                8.6 Get Segment Base Address..........................30
                8.7 Set Segment Base Address..........................31
                8.8 Set Segment Limit.................................32
                8.9 Set Descriptor Access Rights......................33
                8.10 Create Code Segment Alias Descriptor.............35
                8.11 Get Descriptor...................................36
                8.12 Set Descriptor...................................37
                8.13 Allocate Specific LDT Descriptor.................38













            9. DOS Memory Management Services.........................39
                9.1 Allocate DOS Memory Block.........................40
                9.2 Free DOS Memory Block.............................41
                9.3 Resize DOS Memory Block...........................42






























































            10. Interrupt Services....................................43
                10.1 Get Real Mode Interrupt Vector...................44
                10.2 Set Real Mode Interrupt Vector...................45
                10.3 Get Processor Exception Handler Vector...........46
                10.4 Set Processor Exception Handler Vector...........47
                10.5 Get Protected Mode Interrupt Vector..............50
                10.6 Set Protected Mode Interrupt Vector..............51

            11. Translation Services..................................52
                11.1 Simulate Real Mode Interrupt.....................55
                11.2 Call Real Mode Procedure With Far Return Frame...56
                11.3 Call Real Mode Procedure With Iret Frame.........57
                11.4 Allocate Real Mode Call-Back Address.............58
                11.5 Free Real Mode Call-Back Address.................62
                11.6 Get State Save/Restore Addresses.................63
                11.7 Get Raw Mode Switch Addresses....................65

            12. Get Version...........................................66

            13. Memory Management Services............................67
                13.1 Get Free Memory Information......................68
                13.2 Allocate Memory Block............................70
                13.3 Free Memory Block................................71
                13.4 Resize Memory Block..............................72

            14. Page Locking Services.................................73
                14.1 Lock Linear Region...............................74
                14.2 Unlock Linear Region.............................75
                14.3 Mark Real Mode Region as Pageable................76
                14.4 Relock Real Mode Region..........................77
                14.5 Get Page Size....................................78

            15. Demand Paging Performance Tuning Services.............79
                15.1 Reserved Subfunctions............................80
                15.2 Mark Page as Demand Paging Candidate.............81
                15.3 Discard Page Contents............................82

            16. Physical Address Mapping..............................83

            17. Virtual interrupt State Functions.....................84
                17.1 Get and Disable Virtual Interrupt State..........85
                17.2 Get and Enable Virtual Interrupt State...........86
                17.3 Get Virtual Interrupt State......................87

            18. Get Vendor Specific API Entry Point...................88

            19. Debug Register Support................................89
                19.1 Set Debug Watchpoint.............................90
                19.2 Clear Debug Watchpoint...........................91
                19.3 Get State of Debug Watchpoint....................92
                19.4 Reset Debug Watchpoint...........................93

            20. Other APIs............................................94













            21. Notes For DOS Extenders...............................95
                21.1 Initialization of  Extenders.....................96
                21.2 Installing API Extensions........................96
                21.3 Loading the Application Program..................96
                21.4 Providing API Extensions.........................97






























































                                  1. INTRODUCTION


            The DOS Protected Mode Interface (DPMI) was defined to allow
            DOS  programs   to  access   the  extended   memory  of   PC
            architecture computers  while maintaining system protection.
            DPMI defines  a specific  subset of  DOS and BIOS calls that
            can be made by protected mode DOS programs.  It also defines
            a new  interface via  software interrupt  31h that protected
            mode programs  use to  allocate memory,  modify descriptors,
            call real  mode software,  etc.   Any operating  system that
            currently supports virtual DOS sessions should be capable of
            supporting DPMI without affecting system security.

            Some DPMI  implementations can  execute  multiple  protected
            mode programs  in independent  virtual machines.  Thus, DPMI
            applications can  behave exactly like any other standard DOS
            program and  can, for example, run in the background or in a
            window  (if   the  environment   supports  these  features).
            Programs that  run in  protected  mode  also  gain  all  the
            benefits of  virtual memory and can run in 32-bit flat model
            if desired.

            Throughout this  document, the  term "real mode" software is
            used to  refer to  code that  runs in  the  low  1  megabyte
            address space  and uses  segment:offset addressing.    Under
            many implementations  of DPMI,  so called real mode software
            is actually  executed in  virtual 8086 mode.  However, since
            virtual 8086  mode is  a very  close approximation  of  real
            mode, we will refer to it as real mode in this document.

            DPMI services are only available to protected mode programs.
            Programs running  in real  mode can  not use these services.
            Protected mode  programs must  use the  service described on
            page 20  to enter  protected mode  before  calling  Int  31h
            services.

            All Int 31h functions will modify flags and the AX register.
            All other  registers  will  be  preserved  unless  they  are
            specified as  return values.   Unsupported calls will return
            with the  carry flag set.  Since Int 31h is set up as a trap
            gate, the interrupt flag will not be modified by any Int 31h
            calls  except  for  memory  management  and  interrupt  flag
            management calls.   All  memory management  calls may enable
            interrupts.  Interrupt flag management calls will modify the
            interrupt flag  as specified  by the  call.    All  Int  31h
            services are reentrant.

            Some implementations  of DPMI  can run 32-bit 80386 specific
            programs.   DPMI functions  that take pointers as parameters
            will use  the extended  32-bit registers  for  offsets  (for
            example, ES:EDI  instead of  ES:DI) when running 32-bit mode




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 1








            programs.   The high  word of  the 32-bit  registers will be
            ignored when running 16-bit protected mode programs.

            DPMI services  are provided  by what  will be referred to as
            the DPMI  host  program.    The  program(s)  that  use  DPMI
            services are  called DPMI  clients.  Generally, DPMI clients
            are two categories:

                 o    Extended Applications
                 o    Applications that use DPMI directly

            It is  believed that most DPMI applications will be extended
            applications.   Extended  applications  are  bound  with  an
            extender that  is the actual DPMI client and the application
            calls extender  services that  then are  translated  by  the
            client into  DPMI calls.    The  advantage  of  an  extended
            application over  one that  calls DPMI  services directly is
            that generally an extender will support more than just DPMI.
            In fact  it is recommended that extenders look for extension
            services in the following order:

                 o    DPMI
                 o    VCPI/EMS
                 o    XMS
                 o    Top-down (Int 15h)

            An extender  can provide  a single set of APIs to the actual
            application and then translate them to the services that are
            provided.   Where the  host extension services are "lacking"
            in a  particular function  the extender  must  provide  that
            function for the application.

            Figure 1  on page  3 shows a picture of how this works.  The
            application code  sits on  top of  a set  of  base  extender
            functions and  APIs.  The extender then has separate modules
            for each  type of extension service and code to "fill in the
            slack" where  services are lacking.  An example of a typical
            extender service  is protected  mode program  loading.   The
            actual shipped  application is the application code bound in
            with the extender and all of its styles of client support.

            The host  support is  generally an  extension of the base OS
            functions or  a device  driver used  to extend  the base  OS
            functions.

            This document  is intended  to provide  a definition  of the
            DPMI  services  that  a  DPMI  host  would  be  required  to
            implement and that a DPMI client would use.









     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 2










            Figure 1.  Application/Extender/Client/Host/OS structure


            +----------------------------------------------------------+
            |                                                          |
            |  +----------------------------------------------------+  |
            |  |                                                    |  |
            |  |                  Application Code                  |  |
            |  |                                                    |  |
            |  +----------------------------------------------------+  |
            |                                                          |
            |  +----------------------------------------------------+  |
            |  |           Extender Base (including APIs)           |  |
            |  | -------------------------------------------------- |  |
            |  |    DPMI                                            |  |
            |  |   client                                           |  |
            |  +------------+                                       |  |
            |               |    VCPI                               |  |
            |               |   client                              |  |
            |               +------------+                          |  |
            |                            |    XMS                   |  |
            |                            |   client                 |  |
            |                            +------------+             |  |
            |                                         |  Top-down   |  |
            |                                         |   client    |  |
            |                                         +-------------+  |
            |                                                          |
            +----------------------------------------------------------+

               +------------+
               |            |
               |            |
               |            |------------+
               |            |            |
               |    DPMI    |            |
               |    host    |    VCPI    |------------+
               |            |            |            |
               |            |            |            |
               |            |------------|    XMS     |-------------+
               |            |    EMS     |            |  Top-down   |
               |            |            |            |  (Int 15h)  |
               +----------------------------------------------------+

               +----------------------------------------------------+
               |                                                    |
               |             Operating System (e.g. DOS)            |
               |                                                    |
               +----------------------------------------------------+







     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 3









                    2. GENERAL NOTES FOR PROTECTED MODE PROGRAMS


            There are  a few  basic differences  between real  mode  and
            protected mode  that need  to be addressed to convert a real
            mode program to run in protected mode.

            Programs run  at a  protection level that prevents them from
            executing privileged  instructions such  as lgdt, lidt, etc.
            The DPMI  interface is  the only method application programs
            have for modifying system structures such as descriptors.

            While DPMI  defines a specific set of functions that will be
            supported  by   all  implementations,  there  may  be  minor
            differences  in  individual  implementations.    Programmers
            should refer  to the notes for their DPMI implementation for
            documentation on  detecting  the  presence  of  and  calling
            vendor specific  extensions.   However, any application that
            is written to adhere only to standard DPMI calls should work
            correctly under all implementations of DPMI.




































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 4









             2.1 Virtual DOS Environments


            Many  DPMI   implementations  are  simulated  "virtual  DOS"
            sessions.  In other words, the DOS interface and environment
            presented  to  the  program  are  not  actually  the  native
            interface of  the operating  system.   Hardware  interrupts,
            I/O, and  processor exceptions  will be  virtualized by  the
            operating system.   This  means, for  example, that  a  DPMI
            program may  receive a simulated keyboard interrupt and read
            simulated I/O from the keyboard controller ports.

            In these  environments, actual  hardware interrupts  will be
            handled by  the operating  system.   The physical interrupts
            will be  invisible to  the DPMI application program.  If the
            operating system  so  chooses,  it  may  reflect  a  virtual
            interrupt to  the DPMI  program.   The DPMI program does not
            need to know, nor should it care, if this is the case.  From
            the program's  point of  view, the  interrupt looks  exactly
            like a  "real" interrupt.   The  operating system  will also
            virtualize I/O  to the  interrupt controller  ports and  any
            other simulated devices.

            There are basically three levels of virtualization that DPMI
            implementations can provide:

            2.1.1 No Virtualization

            In general,  stand-alone single tasking DPMI implementations
            will not  virtualize  any  hardware  devices.    These  hose
            extension programs  will execute  as standard  DOS real mode
            drivers or  programs.   Extenders  which  use  the  services
            provided by these DPMI host drivers will translate protected
            mode DOS  calls to  real mode  DOS calls.    Normally  these
            extenders will  invoke DPMI services to return the processor
            to real  mode (instead  of virtual  8086 mode)  when calling
            DOS.

            2.1.2 Partial Virtualization

            Some environments  that execute  under DOS  will  virtualize
            hardware devices,  provide virtual  memory, or provide other
            services  that   require  virtualization  of  some  hardware
            devices.   Under these  environments, DPMI applications will
            always run  at a non-privileged ring (usually ring 3).  Some
            or all  hardware interrupts will be virtualized, some or all
            I/O  will   be  virtualized,   and  virtual  memory  may  be
            supported.     Under  these  implementations,  page  locking
            services  usually   must  be  used  to  lock  interrupt  and
            exception handling code.






     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 5








            2.1.3 Complete Virtualization

            These  environments   provide  a  completely  simulated  DOS
            environment.  The native operating system is something other
            than MS-DOS.   Under  these  implementations  of  DPMI,  all
            devices will  be virtualized to some extent.  Normally, page
            locking services  will be  ignored by  these implementations
            since all physical device interrupt and I/O handling will be
            performed by the operating system.  Programs will always run
            at a non-privileged ring.















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 6









             2.2 Descriptor Management


            Protected mode  code segments  can not  be modified.    This
            requires programs  to allocate  an alias  data descriptor if
            they need to store data in a code segment.

            Segment arithmetic  that works in real mode does not work in
            protected mode.

            Some calls will return a range of descriptors.  For example,
            if a  16-bit mode program allocates a block of memory larger
            than  64K,   the  call  will  allocate  several,  contiguous
            descriptors.   Each descriptor  will have a 64K limit except
            for the  final descriptor  which  will  have  a  limit  that
            contains the  remainder of  the block.  The call will return
            the first  selector in  the array.    To  get  to  the  next
            selector, your  program must  add the  value returned by Int
            31h call 0003h (see page 32).





































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 7









             2.3 Interrupt Flag Management


            The popf  and iret  instructions may not modify the state of
            the interrupt  flag since most DPMI implementations will run
            programs with  IOPL < DPL.  Programs must execute cli or sti
            to modify the interrupt flag state.

            This means  that the  following  code  sequence  will  leave
            interrupts disabled:

                 ;
                 ; (Assume interrupts are enabled at this point)
                 ;
                         pushf
                         cli
                         .
                         .
                         popf            ; Interrupts are still OFF!

            Note that since some implementations of DPMI will maintain a
            virtual interrupt state for protected mode DOS programs, the
            current value  of the  interrupt flag  may not  reflect  the
            current virtual  interrupt state.   Protected  mode programs
            should use the virtual interrupt state services to determine
            the current interrupt flag state (see page 99).

            Since cli  and sti  are privileged  instructions, they  will
            cause a  protection violation  and the  DPMI  provider  will
            simulate the  instruction.  Because of the overhead involved
            in processing  the exception,  cli and sti should be used as
            little as possible.  In general, you should expect either of
            these instructions to require at least 300 clocks.























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 8









             2.4 Interrupts


            Protected mode  programs can hook both hardware and software
            interrupts  using  the  DPMI  get  and  set  protected  mode
            interrupt vector  functions (see  page 56).   All interrupts
            from  hardware   devices  such  as  the  timer  or  keyboard
            controller will  always be  reflected to  the protected mode
            interrupt handler  first.   If the  protected  mode  handler
            jumps to  or calls  the previous  interrupt handler then the
            interrupt will be reflected to real mode.

            As in real mode, interrupt procedures can either service the
            interrupt and  iret or they can chain to the next handler in
            the interrupt chain by executing pushf/call or by jumping to
            the next  handler.  The final handler for all protected mode
            interrupts will reflect the interrupt to real mode.

            When an  interrupt is  reflected to real mode, the EAX, EBX,
            ECX, EDX,  ESI, EDI,  EBP registers,  and flags  will all be
            passed from  protected to  real mode unaltered.  The segment
            registers  will  contain  undefined  values  unless  an  API
            translator (such  as a  DOS or  BIOS translator)  explicitly
            sets a  real mode segment register.  DPMI will automatically
            provide a  real mode stack for interrupts that are reflected
            to real mode.


            2.4.1 Hardware Interrupts

            The interrupt controllers are mapped to the system's default
            interrupts.   On an  IBM AT-compatible  system, for example,
            the master  interrupt controller  is programmed  with a base
            interrupt of  8 and  the slave controller has a base of 70h.
            The virtualized  interrupt controllers  can be reprogrammed;
            the base  setting may be examined in protected mode with Int
            31h function 0400h.

            Hardware interrupt  procedures and  all of  their data  must
            reside in  locked memory.   All  memory that  is touched  by
            hardware interrupt  hooks must  be locked.  The handler will
            always be  called on  a locked  stack.  See page 12 for more
            details.

            As in real mode, hardware interrupt handlers are called with
            interrupts disabled.    Since  iret  will  not  restore  the
            interrupt flag, hardware interrupt hooks must execute an sti
            before  executing   iret  or  else  interrupts  will  remain
            disabled.

            Protected mode  hardware interrupt  handlers will  always be
            called even  for interrupts  that occur  in real  mode.  The




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9         Page 9








            last hook on the protected mode interrupt chain will reflect
            the interrupt to real mode.

            Protected mode hardware interrupt handlers that need to call
            software running  in real  mode must either be sure that the
            real mode  software that  they are  calling will  not modify
            segment registers  or they  must use  the state save service
            (see page  74) to  save and  restore the  real mode  segment
            registers.   However, any  interrupt handler  that  executes
            completely in  protected mode,  or uses translation services
            0300h, 0301h,  or 0302h  does not need to save the real mode
            register state.   Therefore,  this is  not an issue for most
            interrupt handlers.












































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 10








            For compatibility  with older  systems, computers  with  two
            interrupt controllers  have the  BIOS redirect  one  of  the
            interrupts from  the slave  controller into the range of the
            master controller.   For example, devices jumpered for IRQ 2
            on IBM  AT-compatible computers  actually interrupt on IRQ 9
            (interrupt 71h).   In  real mode,  the BIOS on these systems
            will convert  interrupt 71h  to Int  0Ah and  EOI the  slave
            controller.   A protected  mode program that needs access to
            the redirected  interrupt may  use variations  on either  of
            these techniques:

                 1.   Hook the  target interrupt  in real  mode.    This
                      takes advantage of the built in redirection.  This
                      is robust  on systems  where  other  software  has
                      reprogrammed the  interrupt controllers,  or where
                      the slave interrupt controller may be absent.

                 2.   Hook  the   actual  interrupt  in  both  real  and
                      protected mode.   In  this case,  the program must
                      EOI  both   the   slave   and   master   interrupt
                      controllers since  the BIOS  will not get control.
                      This is  more efficient  in that there will not be
                      any unnecessary switches to real mode.

            2.4.2 Software Interrupts

            Most software  interrupts executed  in real mode will not be
            reflected to  the protected  mode interrupt hooks.  However,
            some software  interrupts are  also reflected  to  protected
            mode programs when they are called in real mode.  These are:


                       INT            DESCRIPTION

                       1Ch    BIOS timer tick interrupt
                       23h    DOS Ctrl+C interrupt
                       24h    DOS critical error interrupt


            Programs should  not terminate  during interrupts  that were
            reflected from  real mode.   Terminating the program at this
            point may prevent the DPMI host from cleaning up properly.

            Of all software interrupts, only Ints 00h-07h will be called
            with virtual interrupts disabled.  For these interrupts, the
            handler should  return with  interrupts enabled.   All other
            interrupts will not modify the interrupt flag state.

            Since most  software interrupts  that are  executed in  real
            mode are  not reflected  to protected  mode interrupt hooks,
            programs would  be required to install a real mode interrupt
            hook to monitor these interrupts.





     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 11









             2.5 Virtual Memory and Page Locking


            Many implementations  of DPMI  support virtual  memory.   In
            these environments,  it will be necessary to lock any memory
            that can  be touched while executing inside of DOS.  This is
            necessary because  it may  not be possible for the operating
            system to demand load a page if DOS is busy.

            Some DPMI implementations will not call DOS to read or write
            virtual memory  to disk  and under these implementations the
            page locking services may be ignored.  Since the entire DPMI
            session is  virtualized, a  page fault can be handled at any
            point while  executing the  program.    However,  under  all
            implementations, DPMI  applications  should  lock  interrupt
            code and  data.   The lock  calls will always return success
            under implementations that ignore these calls.







































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 12









                            3. MODE AND STACK SWITCHING


            This section  contains an  overview of how DPMI hosts switch
            between protected  and real mode and handle stack switching.
            It is  important to  understand the host maintains the state
            of the client to prevent overwriting stack data or modifying
            segment registers.
















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 13









             3.1 Stacks and Stack Switching


            Every  DPMI   task  runs  on  four  different  stacks:    An
            application ring  protected mode  stack, a  locked protected
            mode stack, a real mode stack, and a DPMI host ring 0 stack.

            The protected  mode stack  is the  one the  DPMI client  was
            running on  when it  switched into protected mode by calling
            the protected  mode entry  point (although  the  client  can
            switch to  another protected  mode stack  if desired).   The
            locked protected  mode stack  is provided by the DPMI server
            and  is   used  for   simulating  hardware   interrupts  and
            processing real mode call-backs.  The DPMI host provides the
            real mode  stack, which  is usually located in the data area
            provided by the client.  The ring 0 stack is only accessible
            by the  DPMI host.   However,  this stack  may contain state
            information about the currently running program.


            3.1.1 Protected Mode Stack

            This is  the stack that the client uses for normal execution
            in protected  mode.   The protected  mode stack  of  a  DPMI
            client can  be unlocked  if desired.    Software  interrupts
            executed in protected mode will be reflected on this stack.

            3.1.2 Locked Protected Mode Stack

            During hardware  interrupts, Int  1Ch,  Int  23h,  Int  24h,
            exceptions, and  real mode  call-back handling  in protected
            mode, the  DPMI will  host automatically  switch to a locked
            protected mode  stack.   When the interrupt or call returns,
            the host  will return  to the original protected mode stack.
            Note that  there is  only one,  4K, locked stack provided by
            the host.  The stack will be switched onto the first time an
            interrupt or  call is  reflected to protected mode, and will
            be switched  away from  when the client returns.  Subsequent
            nested interrupts  or calls  will not  cause a stack switch.
            Software interrupts do not automatically switch stacks.

            3.1.3 Real Mode Stack

            The DPMI host will provide the client with a real mode stack
            that is  at least  200h bytes  in size  and will  always  be
            locked.   Interrupts that  are reflected  into real mode, as
            well as  calls made  using the translation services, will be
            reflected on  this stack.  DPMI hosts will not automatically
            switch stacks for hardware interrupt processing in real mode
            since DOS performs this function automatically.






     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 14








            3.1.4 DPMI Host Ring 0 Stack

            DPMI hosts  will normally  have a stack associated with each
            DPMI task.   The DPMI client will not be able to access this
            stack in  any way -- it is used by the host for execution at
            ring 0 to handle interrupts and exceptions.  This stack will
            sometimes be used to store state information while switching
            modes.   For example,  the original  SS:ESP of the protected
            mode program  could be  saved on  the ring 0 stack while the
            DPMI host switches onto the locked protected mode stack.















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 15









             3.2 Default Interrupt Reflection


            DPMI hosts  provide interrupt  vectors  for  all  100h  (256
            decimal) interrupts  for protected  mode clients.   When the
            DPMI client initializes, all interrupt vectors will point to
            code that  will automatically  reflect the interrupt to real
            mode (except  for Int  31h and  Int 21h,  AH=4Ch).   When  a
            default interrupt  reflection handler  is executed  it  will
            switch to real mode, preserving the EAX, EBX, ECX, EDX, ESI,
            EDI, and  EBP registers and flags, and reflect the interrupt
            in real  mode.   When the  real mode  interrupt returns, the
            default  interrupt  reflection  code  will  switch  back  to
            protected mode  and return  with the modified values of EAX,
            EBX, ECX,  EDX, ESI, EDI, EBP, and flags.  Segment registers
            and the  stack pointer  will not  be passed  between  modes.
            Therefore, any  API that  passes pointers  or information in
            segment registers  will need  to  be  translated  by  a  DOS
            extender.





































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 16









             3.3 Mode Switching


            There are  three different  ways a  client can  force a mode
            switch between protected and real mode:

                 o    Execute the default interrupt reflection handler
                 o    Use the  translation services  to call  real  mode
            code
                 o    Use a  real mode  call-back to switch from real to
            protected mode
                 o    Use the raw mode switch functions

            All mode switches except for the raw mode switches will save
            some information  on the  DPMI host's  ring 0  stack.   This
            means that  programs should  not terminate  while in  nested
            mode switches  unless they  are using the raw mode switching
            services.  However, even programs that use raw mode switches
            should not attempt to terminate from a hardware interrupt or
            exception handler  since the  DPMI host  performs  automatic
            mode and stack switching to provide these services.



































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 17









             3.4 State Saving


            Because DPMI  hosts switch  stacks automatically across mode
            switches,  it  is  sometimes  necessary  to  use  the  state
            save/restore functions  while  using  the  raw  mode  switch
            services.  The host will maintain information on the "other"
            mode's current  state.   This information  will include  the
            CS:(E)IP, SS:(E)SP,  and segment register values.  Since the
            DPMI client  has no  way to directly access these values, it
            will need to call the state saving functions when performing
            nested mode switches.

            For example,  during hardware interrupts, the DPMI host will
            preserve the  real mode's  segment  registers,  CS:EIP,  and
            SS:ESP on the ring 0 stack.  However, they are not pushed on
            any stack  in the  VM --  They are  only visible  at ring 0.
            When the  raw mode  switch functions  are called  they  will
            overwrite the information saved by the host.  At this point,
            the program  would return  to the  wrong  address  when  the
            interrupt returned.   For  more information on state saving,
            refer to the documentation on page 74.


































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 18









                                 4. ERROR HANDLING


            Most Int  31h calls  can fail.   The  DPMI 0.9 specification
            does not  specify error return codes for most calls.  When a
            call fails  it will  set the  carry flag and return with the
            value in AX unmodified unless otherwise specified.  However,
            future DPMI  implementations will  return error codes in the
            AX register.   All  specific error  codes will have the high
            bit (bit  15) set.  If a function returns with carry set and
            the high  bit of AX clear, it should be treated as a general
            failure.   Specific error  codes will allow programs running
            under  future   DPMI  implementations  to  take  appropriate
            corrective action in some cases.










































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 19









                 5. LOADING DPMI CLIENTS AND EXTENDED APPLICATIONS


            All DPMI  applications begin  execution in  real mode.    An
            application must  run first  as a  standard  real  mode  DOS
            program but it can switch to protected execution by making a
            few simple calls.

            DPMI does not define an executable file format for protected
            mode programs.   Instead,  programs must  provide their  own
            mechanism for loading and fixing up protected mode code.













































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 20









             5.1 Obtaining the Real to Protected Mode Switch Entry
             Point


                 This function  can be called in real mode to detect the
                 presence of DPMI services and to obtain an address that
                 can be used to begin execution in protected mode.

            To Call

                 AX = 1687h
                 Execute an Int 2Fh (not an Int 31h)

            Returns

                 If function was successful:
                 AX = 0
                 BX = Flags
                      Bit 0 = 1 if 32-bit programs are supported
                 CL = Processor type
                      02h = 80286
                      03h = 80386
                      04h = 80486
                 DH = DPMI major version number
                 DL = DPMI minor version number
                 SI =  Number  of  paragraphs  required  for  DPMI  host
                      private data (may be 0)
                 ES:DI = Address of procedure to call to enter protected
                      mode

                 If function was not successful:
                 AX != 0

            Programmer's Notes

                 o    This  function   does  not   perform  the   actual
                      transition into  protected mode.  You need to call
                      the address  returned in  ES:DI, after  allocating
                      the private  data  area  for  the  DPMI  host,  to
                      perform the actual real to protected mode switch.
















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 21









             5.2 Calling the Real to Protected Mode Switch Entry Point


                 After using  Int 2Fh  function  1687h,  to  obtain  the
                 protected mode  entry point,  the DPMI client must call
                 the entry point address as described in this section.

            To Call

                 AX = Flags
                      Bit 0 = 1 if program is a 32-bit application
                 ES =  Real mode  segment of  DPMI host data area.  This
                      must be  the size  of the data area returned in SI
                      from the previous function.  ES will be ignored if
                      the required data size is zero.
                 Call the  address returned  in ES:DI  by  the  previous
                      function

            Returns

                 If function was successful:
                 Carry flag is clear.
                 Program is now executing in protected mode.
                 CS =  16-bit selector  with base  of real mode CS and a
                      64K limit
                 SS = Selector with base of real mode SS and a 64K limit
                 DS = Selector with base of real mode DS and a 64K limit
                 ES = Selector to program's PSP with a 100h byte limit
                 FS and GS = 0 (if running on an 80386 or 80486)
                 If the program is a 32-bit application the high word of
                      ESP will be 0
                 All other registers are preserved

                 If function was not successful:
                 Carry flag is set.
                 Program is executing in real mode

            Programmer's Notes

                 o    Once in protected mode, all Int 31h calls that are
                      supported by DPMI can be called.
                 o    To terminate  the program, execute an Int 21h with
                      AH=4Ch and  AL=Error code.   This  is the standard
                      DOS exit  function.   Do not  use  any  other  DOS
                      termination call -- Only AH=4Ch is supported under
                      DPMI.
                 o    Under  different   implementations  of   DPMI  the
                      privilege ring of a program will change.  Programs
                      should make no assumptions about the ring at which
                      they  will   run.     When  creating  descriptors,
                      programs should  set the  DPL of the descriptor to
                      the same  ring as their initial code segment.  Use
                      the lar  instruction to  determine the  protection



     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 22








                      ring  of   your  program's   code  segment.    All
                      descriptors created  by your program should be set
                      to the same protection level.
                 o    Programs  that   specify  that   they  are  32-bit
                      applications will initially run with a 16-bit code
                      segment.   Stack and  data  selectors  for  32-bit
                      programs will be 32-bit (the Big bit will be set).
                      However, all  Int 31h  calls will  require  48-bit
                      pointers even  though the  program is running in a
                      16-bit code segment.
                 o    Unless you have explicitly enabled the A20 address
                      line through the XMS interface, do not assume that
                      memory from  1Mb to  1Mb+64K-16 (the  High  Memory
                      Area) is  addressable once your program is running
                      in protected  mode.   If you  want to  be able  to
                      access the  HMA  then  you  must  enable  the  A20
                      through XMS  before entering  protected mode.  XMS
                      calls are  not supported  in protected mode.  Note
                      that  this   restriction  is  only  important  for
                      software that wishes to access the HMA.  Under all
                      implementations of  DPMI the  physical A20 address
                      line  will   always  be  enabled  while  executing
                      protected mode code.  However, some 80386 specific
                      DPMI implementations simulate 1Mb address wrap for
                      compatibility   reasons.      Under   these   DPMI
                      implementations, the  HMA will  not be  accessible
                      unless  the   A20  is   enabled  through  the  XMS
                      interface.
                 o    The environment  pointer in  the current program's
                      PSP  will   automatically  be   converted   to   a
                      descriptor.   If you  want to  free the  program's
                      environment memory, you must do so before entering
                      protected mode.   In  this case,  the  environment
                      pointer  descriptor  will  point  to  garbage  and
                      should not  be used.   The  DPMI client may change
                      the environment  pointer in the PSP after entering
                      protected mode  but it  must  restore  it  to  the
                      selector  created   by  the   DPMI   host   before
                      terminating.
                 o    The caller  is allowed  to modify  or free the DS,
                      SS, and  CS descriptors  allocated by  this  call.
                      You  may   not  modify   the  PSP   descriptor  or
                      environment pointer  descriptor in  the PSP.   See
                      page 30 for information on freeing descriptors.
                 o    Note that if DS=SS on entry to this call then only
                      one descriptor  will be  allocated for both DS and
                      SS.  In this case, for example, if you changed the
                      base of  the DS  descriptor you  would also change
                      the base of the stack segment.
                 o    For some hosts it may be a good idea for protected
                      mode programs  to use some or all of the real mode
                      memory allocated  to the  real mode program by DOS
                      for protected  mode code  or data.  Protected mode
                      programs that  use memory  in the first 1Mb should



     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 23








                      mark the  memory as  pageable using Int 31h 0602h.
                      See page 90 for details.























































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 24








            Example Code

                 ;
                 ; Get the entry point address and save it
                 ;
                         mov     ax, 1687h
                         int     2Fh
                         test    ax, ax
                         jnz     Cant_Enter_PMode
                         mov     [PMode_Entry_Seg], es
                         mov     [PMode_Entry_Off], di

                 ;
                 ; Allocate memory for use by DOS extender if necessary
                 ; NOTE:  This code assumes that the program has already
                 ;        shrunk its memory block so that the DOS
                 ;        memory allocation call will work
                 ;
                         test    si, si
                         jz      Enter_PMode_Now
                         mov     bx, si
                         mov     ah, 48h
                         int     21h
                         jc      Cant_Enter_PMode
                         mov     es, ax

                 ;
                 ; Enter protected mode as a 16-bit program
                 ;
                 Enter_PMode_Now:
                         xor     ax, ax
                         call    DWORD PTR [PMode_Entry_Off]
                         jc      Cant_Enter_PMode

                 ;
                 ; The program is running in protected mode now!
                 ; Protected mode initialization code would go here.
                 ; Mark program's real mode memory as pageable, etc.
                 ;
                         .
                         .
                         .

                 ;
                 ; Quit the program and return to real mode DOS
                 ;
                         mov     ax, 4C00h
                         int     21h









     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 25









                      6. TERMINATING A PROTECTED MODE PROGRAM


            To terminate  a protected  mode program  execute an  Int 21h
            with AH=4Ch in protected mode.  You can return an error code
            in the  AL register.  This is the standard DOS terminate API
            but it  must be executed in protected mode to allow the DPMI
            host to  clean up  any data  structures associated  with the
            protected mode program.

            Programs should not be terminated from a hardware interrupt,
            exception handler,  or real mode call-back.  Programs should
            only be  terminated from  their main  thread of execution to
            allow the  DPMI host  to clean  up properly.   However,  DOS
            extenders that use the raw mode switch services for all mode
            transitions can  execute the  terminate call after switching
            from real to protected mode.







































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 26









                                 7. MODE DETECTION


            It is possible to write a program or library that can run in
            either real or protected mode.  This function is supplied so
            that bimodal  code can  detect at  run time  whether  it  is
            running under  protected mode.    Code  that  only  runs  in
            protected mode does not need to perform this test.

            To Call

                 AX = 1686h
                 Execute an Int 2Fh (not an Int 31h)

            Returns

                 If executing in protected mode under DPMI:
                 AX = 0

                 If executing in real mode or not under DPMI then:
                 AX != 0

            Programmer's Notes

                 o    This call  will return  AX = 0  when the caller is
                      running in protected mode.  It will return AX non-
                      zero even  when running  under  environments  that
                      support DPMI  if the  caller is  in real  (virtual
                      8086) mode.    See  page  20  for  information  on
                      entering protected mode.


























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 27









                       8. LDT DESCRIPTOR MANAGEMENT SERVICES


            The LDT  descriptor management  services provide  interfaces
            for allocating,  freeing, creating,  locking  and  unlocking
            protected mode  descriptors  in  the  current  task's  Local
            Descriptor Table (LDT).

















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 28









             8.1 Allocate LDT Descriptors


                 This  function   is  used   to  allocate  one  or  more
                 descriptors from  the  task's  Local  Descriptor  Table
                 (LDT).  The descriptor(s) allocated must be initialized
                 by the application.

            To Call

                 AX = 0000h
                 CX = Number of descriptors to allocate

            Returns

                 If function was successful:
                 Carry flag is clear.
                 AX = Base selector

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    If more than one descriptor was requested, AX will
                      contain  the   first  of  a  contiguous  array  of
                      descriptors.  You should add the value returned by
                      function 0003h  (see page  32) to  get to the next
                      selector in the array.
                 o    The descriptor  will be  set to present data type,
                      with a base and limit of zero.
                 o    It is up to the caller to fill in the descriptors.
                 o    The privilege  level of descriptors will match the
                      application's code  segment privilege level.  When
                      modifying descriptors,  always set  the DPL to the
                      same  privilege   ring  as   your  program's  code
                      segment.  Use the lar instruction to determine the
                      privilege of a descriptor.


















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 29









             8.2 Free LDT Descriptor


                 This function  is used  to free  descriptors that  were
                 allocated  through   the   Allocate   LDT   Descriptors
                 function.

            To Call

                 AX = 0001h
                 BX = Selector to free

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    Arrays of  descriptors are  freed by  calling this
                      function for each of the individual descriptors.
                 o    It is  valid to free the descriptors allocated for
                      the program's  initial CS,  DS,  and  SS.    Other
                      descriptors that  were not  allocated by  function
                      0000h should  never  be  freed  by  this  function
                      unless otherwise specified.



























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 30









             8.3 Segment to Descriptor


                 This function  is used  to convert  real mode  segments
                 into descriptors that are addressable by protected mode
                 programs.

            To Call

                 AX = 0002h
                 BX = Real mode segment address

            Returns


                 If function was successful:
                 Carry flag is clear.
                 AX = Selector mapped to real mode segment

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    Multiple calls  to this  function  with  the  same
                      segment will return the same selector.
                 o    Descriptors created  by this function should never
                      be modified or freed.  For this reason, you should
                      use this  function sparingly.    If  your  program
                      needs to examine various real mode addresses using
                      the same selector you should allocate a descriptor
                      and change  the base  using the  Set Segment  Base
                      Address function instead of using this function.
                 o    The descriptor's limit will be set to 64K.
                 o    The intent  of this  function is to allow programs
                      easy access  to commonly  used real  mode segments
                      such as 40h and A000h.  Do not use this service to
                      obtain descriptors to private data areas.


















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 31









             8.4 Get Next Selector Increment Value


                 Some functions  such as  allocate LDT  descriptors  and
                 allocate  DOS   memory  can   return  more   than   one
                 descriptor.   You must  call this function to determine
                 the value  that must  be added  to a selector to access
                 the next descriptor in the array.

            To Call

                 AX = 0003h

            Returns

                 Carry flag clear (this function always succeeds)
                 AX = Value to add to get to next selector

            Programmer's Notes

                 o    Do not  make any  assumptions about the value this
                      function will return.
                 o    The increment  value returned  will be  a power of
                      two.
































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 32









             8.5 Reserved Subfunctions


            Functions 0004h  and 0005h  are reserved  and should  not be
            called.



















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 33









             8.6 Get Segment Base Address


                 This function returns the 32-bit linear base address of
                 the specified segment.

            To Call

                 AX = 0006h
                 BX = Selector

            Returns

                 If function was successful:
                 Carry flag is clear.
                 CX:DX = 32-bit linear base address of segment

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX is invalid
































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 34









             8.7 Set Segment Base Address


                 This function changes the 32-bit linear base address of
                 the specified selector.

            To Call

                 AX = 0007h
                 BX = Selector
                 CX:DX = 32-bit linear base address for segment

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX is invalid.
                 o    Your program  should only  modify descriptors that
                      were   allocated    through   the   Allocate   LDT
                      Descriptors function.
                 o    The high  8 bits of the base address (contained in
                      CH) will  be ignored  by 16-bit implementations of
                      DPMI.   This is  true even  when running  on 80386
                      machines.

























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 35









             8.8 Set Segment Limit


                 This function sets the limit for the specified segment.

            To Call

                 AX = 0008h
                 BX = Selector
                 CX:DX = 32-bit segment limit

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.


            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX  is invalid or the specified limit could not
                      be set.   16-bit  DPMI implementations can not set
                      segment limits  greater than  0FFFFh (64K)  so  CX
                      must be  zero when  calling  this  function  under
                      these implementations of DPMI.
                 o    Segment limits  greater than  1 meg  must be  page
                      aligned.     That  is,  limits  greater  than  one
                      megabyte must have the low 12 bits set.
                 o    Your program  should only  modify descriptors that
                      were   allocated    through   the   Allocate   LDT
                      Descriptors function.
                 o    To get  the limit  of a segment you should use the
                      instruction lsl  (load  segment  limit)  which  is
                      supported on  80286 and 80386 machines.  Note that
                      on 80386  machines you will need to use the 32-bit
                      form of  lsl   if the  segment has a limit greater
                      than 64K.
















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 36









             8.9 Set Descriptor Access Rights


                 This function allows a protected mode program to modify
                 the access rights and type fields of a descriptor.

            To Call

                 AX = 0009h
                 BX = Selector
                 CL = Access rights/type byte
                 CH =  80386 extended  access rights/type  byte  (32-bit
                      DPMI implementations only)

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX is invalid.
                 o    Your program  should only  modify descriptors that
                      were   allocated    through   the   Allocate   LDT
                      Descriptors function.
                 o    To examine  the access  rights of a descriptor you
                      should  use   the  instruction  lar  (load  access
                      rights) which  is supported  on  80286  and  80386
                      machines.
                 o    The access  rights/type byte  passed in CL has the
                      following format:





















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 37









                      +-------------------------------+
                      | P |  DPL  | 1 |C/D|E/C|W/R| A |
                      +-------+-----------------------+
                        |     |     |   |   |   |   +- 0=>Not Accessed
                        |     |     |   |   |   |            1=>Accessed
                         |       |        |   |   |   +-- Data: 0=>Read,
                      1=>R/W
                         |      |     |   |   |               Code: Must
                      be 1 (readable)
                        |     |     |   |   +-- Data: 0=>Exp-up, 1=>Exp-
                      dn
                         |      |     |   |              Code: Must be 0
                      (non-conform)
                        |     |     |   +-- 0=>Data, 1=>Code
                        |     |     |
                        |     |     +-- Must be 1
                        |     |
                        |     +-- Must equal caller's CPL
                        |
                        +- 0=>Absent, 1=>Present

                      A  parameter   which  does   not  meet  the  above
                      requirements is  invalid, and  causes the function
                      to return with the carry flag set.

                 o    16-bit  DPMI   implementations  will   ignore  the
                      extended access rights/type byte passed in CH even
                      if it  is running on an 80386 system.  32-bit DPMI
                      implementations  interpret  the  CH  parameter  as
                      follows:

                      +-------------------------------+
                      | G |B/D| 0 |Avl|    Reserved   |
                      +-----------------------+-------+
                        |   |   |   |         +-- Ignored
                        |   |   |   +-- Can be 0 or 1
                        |   |   +-- Must be 0
                        |   +-- 0=>Default 16-bit, 1=>Default 32-bit
                        +- 0=>Byte Granular, 1=>Page Granular
                      
                      A  parameter   which  does   not  meet  the  above
                      requirements is  invalid, and  causes the function
                      to return with the carry flag set.













     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 38









             8.10 Create Code Segment Alias Descriptor


                 This function  will create  a data  descriptor that has
                 the same  base and  limit as the specified code segment
                 descriptor.

            To Call

                 AX = 000Ah
                 BX = Code segment selector

            Returns

                 If function was successful:
                 Carry flag is clear.
                 AX = New data selector

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX is not a code segment or is invalid.
                 o    Use the Free LDT Descriptor function to deallocate
                      the alias descriptor.
                 o    The code  segment alias  descriptor will not track
                      changes to  the code  descriptor.  In other words,
                      if an  alias descriptor  is created,  and then the
                      base or  limit of the code segment is changed, the
                      alias descriptor's base or limit would not change.
























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 39









             8.11 Get Descriptor


                 This function  copies the  descriptor table entry for a
                 specified descriptor into an eight byte buffer.

            To Call

                 AX = 000Bh
                 BX = Selector
                 ES:(E)DI =  Pointer to an 8 byte buffer to receive copy
                      of descriptor

            Returns

                 If function was successful:
                 Carry flag is clear.
                 ES:(E)DI = Pointer to buffer that contains descriptor

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX is invalid or unallocated.
                 o    32-bit programs  must use  ES:EDI to  point to the
                      buffer.  16-bit programs should use ES:DI.




























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 40









             8.12 Set Descriptor


                 This function  copies an eight byte buffer into the LDT
                 entry for a specified descriptor.

            To Call

                 AX = 000Ch
                 BX = Selector
                 ES:(E)DI =  Pointer to  an 8 byte  buffer that contains
                      descriptor

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX is invalid.
                 o    Your program  should only  modify descriptors that
                      were   allocated    through   the   Allocate   LDT
                      Descriptors function.
                 o    32-bit programs  must use  ES:EDI to  point to the
                      buffer.  16-bit programs should use ES:DI.
                 o    The type byte (byte 5) follows the same format and
                      restrictions as  the access  rights/type parameter
                      (in CL)  to Set  Descriptor Access  Rights.    The
                      extended type  byte  (byte  6)  follows  the  same
                      format and  restrictions as  the  extended  access
                      rights/type parameter  (in CH)  to Set  Descriptor
                      Access Rights, except the limit field may have any
                      value,  except   the  low  order  4  bits  (marked
                      "reserved") are  used to  set the  upper 4 bits of
                      the descriptor's limit.
















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 41









             8.13 Allocate Specific LDT Descriptor




                 This function attempts to allocate a specific LDT
            descriptor.To Call

                 AX = 000Dh
                 BX = Selector

            Returns

                 If function was successful:
                 Carry flag is clear.
                 Descriptor has been allocated

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  will fail if the selector specified
                      in BX is in use or is not an LDT selector.
                 o    Use function 0001h to free the descriptor.
                 o    The first  10h (16  decimal) descriptors  must  be
                      reserved for  this function and may not be used by
                      the host.
                 o    If another  application has  already  loaded  then
                      some of these descriptors may be in use.


























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 42









                         9. DOS MEMORY MANAGEMENT SERVICES


            Some applications  require the ability to allocate memory in
            the real mode addressable 1 megabyte region.  These services
            allow protected  mode  applications  to  allocate  and  free
            memory that  is directly  addressable by  real mode software
            such as networks and DOS device drivers.  Often, this memory
            is used  in conjunction with the API translation services to
            call real  mode software  that is  not directly supported by
            DPMI.













































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 43









             9.1 Allocate DOS Memory Block


                 This function  will allocate a block of memory from the
                 DOS free  memory pool.   It  returns both the real mode
                 segment and one or more descriptors that can be used by
                 protected mode applications to access the block.

            To Call

                 AX = 0100h
                 BX = Number of paragraphs (16 byte blocks) desired

            Returns

                 If function was successful:
                 Carry flag is clear.
                 AX = Initial real mode segment of allocated block
                 DX = Selector for allocated block

                 If function was not successful:
                 Carry flag is set.
                 AX = DOS error code:
                      07h  memory control blocks damaged
                      08h  insufficient memory  available to allocate as
                      requested
                 BX = Size of largest available block in paragraphs

            Programmer's Notes

                 o    If the size of the block requested is greater than
                      64K bytes (BX > 1000h) then contiguous descriptors
                      will be  allocated.  To access the next descriptor
                      for the  memory block  add  the  value  return  by
                      function 0003h (see page 32) to the base selector.
                      If more than one descriptor is allocated under 32-
                      bit DPMI  implementations, the  limit of the first
                      descriptor will  be set  to the size of the entire
                      block.   All subsequent  descriptors will  have  a
                      limit of 64K except for the final descriptor which
                      will have  a limit  of Block size MOD 64K.  16-bit
                      DPMI implementations  will always set the limit of
                      the first  descriptor to  64K even when running on
                      an 80386.
                 o    Your program should never modify or deallocate any
                      descriptors allocated  by this function.  The Free
                      DOS Memory  Block  function  will  deallocate  the
                      descriptors automatically








     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 44









             9.2 Free DOS Memory Block


                 This function  frees memory  that was allocated through
                 the Allocate DOS Memory Block function.

            To Call

                 AX = 0101h
                 DX = Selector of block to free

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.
                 AX = DOS error code:
                      07h  memory control blocks damaged
                      09h  incorrect memory segment specified

            Programmer's Notes

                 o    All descriptors allocated for the memory block are
                      automatically freed  and therefore  should not  be
                      accessed once the block is freed by this function.





























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 45









             9.3 Resize DOS Memory Block


                 This function  is used to grow or shrink a memory block
                 that was  allocated through  the  Allocate  DOS  Memory
                 Block function.

            To Call

                 AX = 0102h
                 BX = New block size in paragraphs
                 DX = Selector of block to modify

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.
                 AX = DOS error code:
                      07h  memory control blocks damaged
                      08h  insufficient memory  available to allocate as
                      requested
                      09h  incorrect memory segment specified
                 BX = Maximum block size possible in paragraphs

            Programmer's Notes

                 o    Growing a  memory block  is often  likely to  fail
                      since other  DOS block  allocations  will  prevent
                      increasing the  size of  the block.   Also, if the
                      size of a block grows past a 64K boundary then the
                      allocation will fail if the next descriptor in the
                      LDT is  not free.   Therefore,  this  function  is
                      usually only used to shrink a block.
                 o    Shrinking a  block may cause some descriptors that
                      were previously  allocated  to  the  block  to  be
                      freed.  For example shrinking a block from 140K to
                      120K would cause the third allocated descriptor to
                      be freed since it is no longer valid.  The initial
                      selector  will   remain  unchanged,  however,  the
                      limits  of  the  remaining  two  descriptors  will
                      change:  the first to 120K and the second to 56k.












     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 46









                               10. INTERRUPT SERVICES


            These  services   allow  protected   mode  applications   to
            intercept  real  and  protected  mode  interrupts  and  hook
            processor exceptions.


















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 47









             10.1 Get Real Mode Interrupt Vector


                 This function  returns the  value of the current task's
                 real mode interrupt vector for the specified interrupt.

            To Call

                 AX = 0200h
                 BL = Interrupt number

            Returns

                 Carry flag is clear.
                 CX:DX = Segment:Offset of real mode interrupt handler

            Programmer's Notes

                 o    The address  returned in  CX is  a segment,  not a
                      selector.   Therefore you  should not  attempt  to
                      place the  value returned  in CX  into  a  segment
                      register in protected mode or a general protection
                      fault may occur.
                 o    Note all 100h (256 decimal) interrupt vectors must
                      be supported by the DPMI host.































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 48









             10.2 Set Real Mode Interrupt Vector


                 This function sets the value of the current task's real
                 mode interrupt vector for the specified interrupt.

            To Call

                 AX = 0201h
                 BL = Interrupt number
                 CX:DX = Segment:Offset of real mode interrupt handler

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    The address  passed in  CX must  be  a  real  mode
                      segment, not a selector.
                 o    If  the  interrupt  being  hooked  is  a  hardware
                      interrupt then  you must lock the segment that the
                      interrupt handler  runs in  as well  as any memory
                      the handler may touch at interrupt time.
                 o    The address contained in CX:DX must be a real mode
                      segment:offset, not a selector:offset.  This means
                      that the  code  for  the  interrupt  handler  must
                      either reside  in DOS  addressable memory  or  you
                      must use  a real mode call-back address.  Refer to
                      the section  on DOS  memory management services on
                      page 43 for information on allocating memory below
                      1 megabyte.   Information  on real  mode call back
                      addresses can be found on page 68.



















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 49









             10.3 Get Processor Exception Handler Vector


                 This function  returns  the  CS:(E)IP  of  the  current
                 protected mode  exception  handler  for  the  specified
                 exception number.

            To Call

                 AX = 0202h
                 BL = Exception/fault number (00h-1Fh)

            Returns

                 If function was successful:
                 Carry flag is clear.
                 CX:(E)DX = Selector:Offset of exception handler

                 If function was not successful:
                 Carry flag is set.
                 The value passed in BL was invalid.

            Programmer's Notes

                 o    The value returned in CX is a valid protected mode
                      selector, not a real mode segment.
                 o    32-bit mode  programs will  be returned  a  32-bit
                      offset in the EDX register.




























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 50









             10.4 Set Processor Exception Handler Vector


                 This function  allows protected  mode  applications  to
                 intercept processor  exceptions that are not handled by
                 the DPMI  environment.   Programs may  wish  to  handle
                 exceptions such  as not  present segment  faults  which
                 would otherwise generate a fatal error.

                 Every exception is first examined by the protected mode
                 operating system.   If  it can not handle the exception
                 it  then   reflects  it   through  the  protected  mode
                 exception handler  chain.   The final  handler  in  the
                 chain may  either reflect the exception as an interrupt
                 (as would  happen in real mode) or it may terminate the
                 current program.


            To Call

                 AX = 0203h
                 BL = Exception/fault number (00h-1Fh)
                 CX:(E)DX = Selector:Offset of exception handler

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.
                 The value passed in BL was invalid.

            Programmer's Notes

                 o    The value  passed in  CX must be a valid protected
                      mode code selector, not a real mode segment.
                 o    32-bit mode  programs must  supply a 32-bit offset
                      in the  EDX register.   If  your handler chains to
                      the next  exception handler  it must do so using a
                      32-bit interrupt stack frame.
                 o    The handler  should  return  using  a  far  return
                      instruction.   The original SS:(E)SP, CS:(E)IP and
                      flags on  the stack, including the interrupt flag,
                      will be restored.
                 o    All  fault   stack  frames  have  an  error  code.
                      However,  the   error  code   is  only  valid  for
                      exceptions 08h, 0Ah, 0Bh, 0Ch, 0Dh, and 0Eh.
                 o    The  handler   must  preserve   and  restore   all
                      registers.
                 o    The exception  handler will  be called on a locked
                      stack with  interrupts disabled.  The original SS,




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 51








                      (E)SP,  CS,  and  (E)IP  will  be  pushed  on  the
                      exception handler stack frame.
                 o    The handler  must either  return from  the call by
                      executing a far return or jump to the next handler
                      in the  chain (which  will execute a far return or
                      chain to the next handler).



















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 52








                 o    The procedure  can modify any of the values on the
                      stack   pertaining   to   the   exception   before
                      returning.  This can be used, for example, to jump
                      to a  procedure by  modifying  the  CS:IP  on  the
                      stack.   Note that  the procedure  must not modify
                      the far  return address  on the  stack --  it must
                      return to  the original  caller.   The caller will
                      then restore the flags, CS:(E)IP and SS:(E)SP from
                      the stack frame.
                 o    If the  DPMI client  does not handle an exception,
                      or jumps  to the  default exception  handler,  the
                      host will  reflect the  exception as  an interrupt
                      for  exceptions   0,  1,   2,  3,  4,  5,  and  7.
                      Exceptions 6,  and 8-1Fh  will be treated as fatal
                      errors and the client will be terminated.
                 o    Exception  handlers   will  only   be  called  for
                      exceptions that occur in protected mode.








































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 53








            Call-Back Stack Frames

                 Stack frame for 16-bit programs:

                      15       0


                          SS

                          SP

                        Flags

                          CS

                          IP

                       Err Code


                        Return
                          CS

                        Return
                          IP

                                 <-- SS:SP

                 Stack frame for 32-bit programs:

                 31            0


                           SS


                       ESP

                     EFlags

                           CS



                       EIP


                   Error Code

                         Ret CS







     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 54









                   Return EIP


                                 <-- SS:ESP

                 Shaded fields should not be modified.  Other fields can
                 be  modified   before  returning   from  the  exception
                 handler.
















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 55









             10.5 Get Protected Mode Interrupt Vector


                 This function  returns  the  CS:(E)IP  of  the  current
                 protected mode  interrupt  handler  for  the  specified
                 interrupt number.

            To Call

                 AX = 0204h
                 BL = Interrupt number

            Returns

                 Carry flag is clear.
                 CX:(E)DX = Selector:Offset of exception handler

            Programmer's Notes

                 o    The value returned in CX is a valid protected mode
                      selector, not a real mode segment.
                 o    32-bit mode  programs will  be returned  a  32-bit
                      offset in the EDX register.
                 o    All 100h  (256 decimal)  interrupt vectors must be
                      supported by the DPMI host.































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 56









             10.6 Set Protected Mode Interrupt Vector


                 This  function   sets  the  address  of  the  specified
                 protected mode interrupt vector.

            To Call

                 AX = 0205h
                 BL = Interrupt number
                 CX:(E)DX = Selector:Offset of exception handler

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    The value  passed in  CX must be a valid protected
                      mode code selector, not a real mode segment.
                 o    32-bit mode  programs must  supply a 32-bit offset
                      in the  EDX register.   If  your handler chains to
                      the next  exception handler  it must do so using a
                      32-bit interrupt stack frame.
                 o    Note all 100h (256 decimal) interrupt vectors must
                      be supported by the DPMI host.


























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 57









                              11. TRANSLATION SERVICES


            These services  are provided so that protected mode programs
            can call  real mode  software that  DPMI  does  not  support
            directly.   The  protected  mode  program  sets  up  a  data
            structure that  contains the values for every register.  The
            data structure is defined as:
















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 58









                              Offset      Register

                                00h         EDI

                                04h         ESI

                                08h         EBP

                                0Ch  Reserved by system

                                10h         EBX

                                14h         EDX

                                18h         ECX

                                1Ch         EAX


                                20h    Flags


                                22h      ES


                                24h      DS


                                26h      FS


                                28h      GS


                                2Ah      IP


                                2Ch      CS


                                2Eh      SP


                                30h      SS



            You will notice that all of the fields are dwords so that 32
            bit registers  can be  passed to  real mode.  Most real mode
            software  will   ignore  the   high  word  of  the  extended
            registers.   However, you  can write  a real  mode procedure
            that uses  32-bit registers if you desire.  Note that 16-bit
            DPMI implementations  may not  pass the  high word of 32-bit



     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 59








            registers or  the FS  and GS  segment registers to real mode
            even when running on an 80386 machine.

            Any interrupt  handler or  procedure called must return with
            the stack  in the  same state  as when  it was called.  This
            means that  the real mode code may switch stacks while it is
            running but  it must  return on  the same  stack that it was
            called on  and it  must pop  off the  entire far return/iret
            structure.

            After the  call or  interrupt is  complete,  all  real  mode
            registers and flags except SS, SP, CS, and IP will be copied
            back to  the real mode call structure so that the caller can
            examine the real mode return values.

            Remember that  the values in the segment registers should be
            real mode segments, not protected mode selectors.

            The translation  services will  provide a real mode stack if
            the SS:SP  fields are  zero.  However, the stack provided is
            relatively small.   If  the  real  mode  procedure/interrupt
            routine uses  more than  30 words  of stack  space then  you
            should provide your own real mode stack.

            It is  possible to  pass parameters to real mode software on
            the stack.   The  following  code  will  call  a  real  mode
            procedure with 3 word parameters:


                 Protected_Mode_Code:
                         push    Param1
                         push    Param2
                         push    Param3
                         (Set ES:DI to point to call structure)
                         mov     cx, 3           ; Copy 3 words
                         mov     ax, 0301h       ; Call real mode proc
                         int     31h             ; Call the procedure
                         add     sp, 6           ; Clean up stack

            The real  mode procedure  would be called with the following
            data on the real mode stack:
















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 60









                                       Param1

                                       Param2

                                       Param3

                                       Return
                                         CS


                                       Return
                                         IP

                                                 <-- Real mode SS:SP










































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 61








            If your program needs to perform a series of calls to a real
            mode  API  it  is  sometimes  more  convenient  to  use  the
            translation services  to call  a real mode procedure in your
            own program.  That procedure can then issue the API calls in
            real mode  and then  return to  protected mode.   This  also
            avoids the overhead of a mode switch for each API call.

            There is  also a  mechanism for  protected mode  software to
            gain control  from real  mode  via  a  real  mode  call-back
            address.  Real mode call-backs can be used to hook real mode
            interrupts or  to be called in protected mode by a real mode
            driver.   For  example,  many  mouse  drivers  will  call  a
            specified address whenever the mouse is moved.  This service
            allows the  call-back to  be handled  by software running in
            protected mode.










































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 62









             11.1 Simulate Real Mode Interrupt


                 This function  simulates an interrupt in real mode.  It
                 will invoke  the  CS:IP  specified  by  the  real  mode
                 interrupt  vector   and  the  handler  must  return  by
                 executing an iret.

            To Call

                 AX = 0300h
                 BL = Interrupt number
                 BH = Flags
                      Bit 0  = 1 resets the interrupt controller and A20
                      line
                      Other flags reserved and must be 0
                 CX =  Number of  words to  copy from  protected mode to
                      real mode stack
                 ES:(E)DI = Selector:Offset of real mode call structure

            Returns

                 If function was successful:
                 Carry flag is clear.
                 ES:(E)DI =  Selector:Offset of  modified real mode call
                      structure

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    The CS:IP  in the  real  mode  call  structure  is
                      ignored  by   this  service.     The   appropriate
                      interrupt handler  will be  called  based  on  the
                      value passed in BL.
                 o    If the  SS:SP fields  are zero  then a  real  mode
                      stack  will   be  provided   by  the   DPMI  host.
                      Otherwise, the  real mode SS:SP will be set to the
                      specified values  before the  interrupt handler is
                      called.
                 o    The  flags   specified  in   the  real  mode  call
                      structure will  be pushed  on the  real mode stack
                      iret frame.   The interrupt handler will be called
                      with the interrupt and trace flags clear.
                 o    When the  Int 31h  returns,  the  real  mode  call
                      register structure  will contain  the values  that
                      were returned by the real mode interrupt handler.
                 o    It is  up to  the caller  to remove any parameters
                      that were pushed on the protected mode stack.
                 o    32-bit programs  must use  ES:EDI to  point to the
                      real mode  call structure.  16-bit programs should
                      use ES:DI.



     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 63








                 o    The flag to reset the interrupt controller and A20
                      line is  ignored by  DPMI implementations that run
                      in  Virtual   8086   mode.      It   causes   DPMI
                      implementations that  return to  real mode  to set
                      the interrupt  controller  and  A20  address  line
                      hardware to its normal real mode state.



















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 64









             11.2 Call Real Mode Procedure With Far Return Frame


                 This function  calls a real mode procedure.  The called
                 procedure must execute a far return when it completes.

            To Call

                 AX = 0301h
                 BH = Flags
                      Bit 0  = 1 resets the interrupt controller and A20
                      line
                      Other flags reserved and must be 0
                 CX =  Number of  words to  copy from  protected mode to
                      real mode stack
                 ES:(E)DI = Selector:Offset of real mode call structure

            Returns

                 If function was successful:
                 Carry flag is clear.
                 ES:(E)DI =  Selector:Offset of  modified real mode call
                      structure

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    The  CS:IP   in  the   real  mode  call  structure
                      specifies the  address of  the real mode procedure
                      to call.
                 o    The real  mode procedure must execute a far return
                      when it has completed.
                 o    If the  SS:SP fields  are zero  then a  real  mode
                      stack  will   be  provided   by  the   DPMI  host.
                      Otherwise, the  real mode SS:SP will be set to the
                      specified values before the procedure is called.
                 o    When the  Int 31h  returns,  the  real  mode  call
                      structure  will   contain  the  values  that  were
                      returned by the real mode procedure.
                 o    It is  up to  the caller  to remove any parameters
                      that were pushed on the protected mode stack.
                 o    32-bit programs  must use  ES:EDI to  point to the
                      real mode  call structure.  16-bit programs should
                      use ES:DI.
                 o    The flag to reset the interrupt controller and A20
                      line is  ignored by  DPMI implementations that run
                      in  Virtual   8086   mode.      It   causes   DPMI
                      implementations that  return to  real mode  to set
                      the interrupt  controller  and  A20  address  line
                      hardware to its normal real mode state.




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 65









             11.3 Call Real Mode Procedure With Iret Frame


                 This function  calls a real mode procedure.  The called
                 procedure must execute an iret when it completes.

            To Call

                 AX = 0302h
                 BH = Flags
                      Bit 0  = 1 resets the interrupt controller and A20
                      line
                      Other flags reserved and must be 0
                 CX =  Number of  words to  copy from  protected mode to
                      real mode stack
                 ES:(E)DI = Selector:Offset of real mode call structure

            Returns

                 If function was successful:
                 Carry flag is clear.
                 ES:(E)DI =  Selector:Offset of  modified real mode call
                      structure

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    The  CS:IP   in  the   real  mode  call  structure
                      specifies the  address of  the real mode procedure
                      to call.
                 o    The real  mode procedure must execute an iret when
                      it has completed.
                 o    If the  SS:SP fields  are zero  then a  real  mode
                      stack  will   be  provided   by  the   DPMI  host.
                      Otherwise, the  real mode SS:SP will be set to the
                      specified values before the procedure is called.
                 o    When the  Int 31h  returns,  the  real  mode  call
                      structure  will   contain  the  values  that  were
                      returned by the real mode procedure.
                 o    The  flags   specified  in   the  real  mode  call
                      structure will  be pushed the real mode stack iret
                      frame.   The procedure  will be  called  with  the
                      interrupt and trace flags clear.
                 o    It is  up to  the caller  to remove any parameters
                      that were pushed on the protected mode stack.
                 o    32-bit programs  must use  ES:EDI to  point to the
                      real mode  call structure.  16-bit programs should
                      use ES:DI.
                 o    The flag to reset the interrupt controller and A20
                      line is  ignored by  DPMI implementations that run
                      in  Virtual   8086   mode.      It   causes   DPMI



     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 66








                      implementations that  return to  real mode  to set
                      the interrupt  controller  and  A20  address  line
                      hardware to its normal real mode state.






















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 67









             11.4 Allocate Real Mode Call-Back Address


                 This service  is used  to obtain  a  unique  real  mode
                 SEG:OFFSET that will transfer control from real mode to
                 a protected mode procedure.

                 At times  it is necessary to hook a real mode interrupt
                 or device  call-back in  a protected  mode driver.  For
                 example, many  mouse drivers  call an  address whenever
                 the mouse is moved.  Software running in protected mode
                 can use  a real  mode call-back  to intercept the mouse
                 driver calls.

            To Call

                 AX = 0303h
                 DS:(E)SI = Selector:Offset of procedure to call
                 ES:(E)DI = Selector:Offset of real mode call structure

            Returns

                 If function was successful:
                 Carry flag is clear.
                 CX:DX = Segment:Offset of real mode call address

                 If function was not successful:
                 Carry flag is set.

            Call-Back Procedure Parameters

                 Interrupts disabled
                 DS:(E)SI = Selector:Offset of real mode SS:SP
                 ES:(E)DI = Selector:Offset of real mode call structure
                 SS:(E)SP = Locked protected mode API stack
                 All other registers undefined

            Return from Call-Back Procedure

                 Execute an IRET to return
                 ES:(E)DI =  Selector:Offset of real mode call structure
                      to restore (see note)














     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 68








            Programmer's Notes

                 o    Since the  real mode call structure is static, you
                      must be  careful when  writing code  that  may  be
                      reentered.     The  simplest  method  of  avoiding
                      reentrancy  is   to  leave   interrupts   disabled
                      throughout the  entire  call.    However,  if  the
                      amount of  code executed by the call-back is large
                      then you  will need  to copy  the real  mode  call
                      structure into  another  buffer.    You  can  then
                      return with  ES:(E)DI pointing  to the  buffer you
                      copied the data to -- it does not have to point to
                      the original real mode call structure.
                 o    The called  procedure is responsible for modifying
                      the real mode CS:IP before returning.  If the real
                      mode CS:IP  is left  unchanged then  the real mode
                      call-back will  be executed  immediately and  your
                      procedure will be called again.  Normally you will
                      want to  pop a return address off of the real mode
                      stack and  place it  in the  real mode CS:IP.  The
                      example code  in  the  next  section  demonstrates
                      chaining  to   another   interrupt   handler   and
                      simulating a real mode iret.
                 o    To return  values to the real mode caller you must
                      modify the real mode call structure.
                 o    Remember that  all segment values in the real mode
                      call structure  will contain  real mode  segments,
                      not selectors.    If  you  need  to  examine  data
                      pointed to  by a  real mode seg:offset pointer you
                      should not  use the segment to selector service to
                      create  a  new  selector.    Instead,  allocate  a
                      descriptor during  initialization and  change  the
                      descriptor's  base  to  16  times  the  real  mode
                      segment's  value.     This   is  important   since
                      selectors allocated though the segment to selector
                      service can never be freed.
                 o    DPMI hosts  should provide  a minimum  of 16 call-
                      back addresses per task.



















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 69








            Example Code

                 The following code is a sample of a real mode interrupt
                 hook.   It hooks  the DOS  Int 21h and returns an error
                 for the delete file function (AH=41h).  Other calls are
                 passed through  to DOS.  This example is somewhat silly
                 but it  demonstrates the techniques used to hook a real
                 mode  interrupt.     Note  that  since  DOS  calls  are
                 reflected  from   protected  mode  to  real  mode,  the
                 following code  will intercept  all DOS calls from both
                 real mode and protected mode.

                 ;******************************************************
                 ; This procedure gets the current Int 21h real mode
                 ; Seg:Offset, allocates a real mode call-back address,
                 ; and sets the real mode Int 21h vector to the call-
                 ; back address.
                 ;******************************************************
                 Initialization_Code:
                 ;
                 ; Create a code segment alias to save data in
                 ;
                         mov     ax, 000Ah
                         mov     bx, cs
                         int     31h
                         jc      ERROR
                         mov     ds, ax
                         ASSUMES DS,_TEXT
                 ;
                 ; Get current Int 21h real mode SEG:OFFSET
                 ;
                         mov     ax, 0200h
                         mov     bl, 21h
                         int     31h
                         jc      ERROR
                         mov     [Orig_Real_Seg], cx
                         mov     [Orig_Real_Offset], dx
                 ;
                 ; Allocate a real mode call-back
                 ;
                         mov     ax, 0303h
                         push    ds
                         mov     bx, cs
                         mov     ds, bx
                         mov     si, OFFSET My_Int_21_Hook
                         pop     es
                         mov     di, OFFSET My_Real_Mode_Call_Struc
                         int     31h
                         jc      ERROR
                 ;
                 ; Hook real mode int 21h with the call-back address
                 ;
                         mov     ax, 0201h
                         mov     bl, 21h



     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 70








                         int     31h
                         jc      ERROR























































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 71








                 ;******************************************************
                 ;
                 ; This is the actual Int 21h hook code.  It will return
                 ; an "access denied" error for all calls made in real
                 ; mode to delete a file.  Other calls will be passed
                 ; through to DOS.
                 ;
                 ; ENTRY:
                 ;    DS:SI -> Real mode SS:SP
                 ;    ES:DI -> Real mode call structure
                 ;    Interrupts disabled
                 ;
                 ; EXIT:
                 ;    ES:DI -> Real mode call structure
                 ;
                 ;******************************************************

                 My_Int_21_Hook:
                         cmp     es:[di.RealMode_AH], 41h
                         jne     Chain_To_DOS
                 ;
                 ; This is a delete file call (AH=41h).  Simulate an
                 ; iret on the real mode stack, set the real mode
                 ; carry flag, and set the real mode AX to 5 to indicate
                 ; an access denied error.
                 ;
                         cld
                         lodsw                   ; Get real mode ret IP
                         mov     es:[di.RealMode_IP], ax
                         lodsw                   ; Get real mode ret CS
                         mov     es:[di.RealMode_CS], ax
                         lodsw                   ; Get real mode flags
                         or      ax, 1           ; Set carry flag
                         mov     es:[di.RealMode_Flags], ax
                         add     es:[di.RealMode_SP], 6
                         mov     es:[di.RealMode_AX], 5
                         jmp     My_Hook_Exit
                 ;
                 ; Chain to original Int 21h vector by replacing the
                 ; real mode CS:IP with the original Seg:Offset.
                 ;
                 Chain_To_DOS:
                         mov     ax, cs:[Orig_Real_Seg]
                         mov     es:[di.RealMode_CS], ax
                         mov     ax, cs:[Orig_Real_Offset]
                         mov     es:[di.RealMode_IP], ax

                 My_Hook_Exit:
                         iret








     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 72









             11.5 Free Real Mode Call-Back Address



                 This function  frees a real mode call-back address that
                 was allocated  through the allocate real mode call-back
                 address service.

            To Call

                 AX = 0304h
                 CX:DX = Real mode call-back address to free

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    Real mode call-backs are a limited resource.  Your
                      code should  free any  break point  that it  is no
                      longer using.






























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 73









             11.6 Get State Save/Restore Addresses


                 When a  program uses  the raw mode switch services (see
                 page 77)  or issues DOS calls from a hardware interrupt
                 handler, it  will need to save the state of the current
                 task before  changing modes.   This service returns the
                 addresses of  two procedures  used to save the state of
                 the current  task's registers.   For  example, the real
                 mode address is used to save the state of the protected
                 mode registers.   The protected mode address is used to
                 save the state of the real mode registers.  This can be
                 used  to   save  the  state  of  the  alternate  mode's
                 registers before  they are  modified by the mode switch
                 call.   The current  mode's registers  can be  saved by
                 simply pushing them on the stack.

                 Note:   It is  not necessary  to call  this service  if
                 using the  translation services  0300h, 0301h or 0302h.
                 It is  provided for  programs that  use  the  raw  mode
                 switch service.

            To Call

                 AX = 0305h

            Returns

                 If function was successful:
                 Carry flag is clear
                 AX = Size of buffer in bytes required to save state
                 BX:CX = Real mode address used to save/restore state
                 SI:(E)DI =  Protected mode address used to save/restore
                      state

                 If function was not successful:
                 Carry flag is set

            Parameters To State-Save Procedures

                 Execute a  far call to the appropriate address (real or
                      pmode) with:
                 ES:(E)DI = Pointer to state-save buffer
                 AL = 0 to save state
                 AL = 1 to restore state

            Programmer's Notes

                 o    Some implementations  of DPMI will not require the
                      state to  be saved.  In this case, the buffer size
                      returned will be zero.  However, it is still valid
                      to call the addresses returned, although they will




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 74








                      just  return   without   performing   any   useful
                      function.
                 o    The save/restore  functions will  not  modify  any
                      registers.
                 o    The address  returned in BX:CX must only be called
                      in real  mode.   The address  returned in SI:(E)DI
                      must only be called in protected mode.
                 o    16-bit programs  should call  the address returned
                      in SI:DI  to save  the real  mode state.    32-bit
                      programs  should  call  the  address  returned  in
                      SI:EDI.














































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 75








            Example Code

                 The following  code is  a sample  protected mode  timer
                 interrupt handler that saves the state of the real mode
                 registers, issues  DOS calls,  and restores  the state.
                 This code  assumes that  the Int 31h function 0305h has
                 been executed and that the call address and buffer size
                 have been saved in local variables.

                 Sample_Timer_Code:
                         pushf
                         call    FAR PTR cs:[Next_Timer_Handler]
                         sti
                 ;
                 ; Save protected mode registers
                 ;
                         push    ds
                         push    es
                         pusha
                 ;
                 ; Save real mode registers
                 ;
                         mov     ds, cs:[My_Local_DS]
                         mov     ax, ss
                         mov     es, ax
                         sub     sp, [State_Save_Size]
                         mov     di, sp
                         xor     al, al
                         call    [PM_Save_Restore_State]

                 ;
                 ; Raw mode switch here
                 ;
                         .
                         .
                         .
                 ;
                 ; Restore real mode registers
                 ;
                         mov     ax, ss
                         mov     es, ax
                         mov     di, sp
                         mov     al, 1
                         call    [PM_Save_Restore_State]
                         add     sp, [State_Save_Size]
                 ;
                 ; Restore protected mode registers and return
                 ;
                         popa
                         pop     es
                         pop     ds

                         iret




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 76









             11.7 Get Raw Mode Switch Addresses




                 This function returns addresses that can be jumped to
            for low-level mode switching.To Call

                 AX = 0306h

            Returns

                 If function was successful:
                 Carry flag is clear
                 BX:CX = Real -> Protected mode switch address
                 SI:(E)DI = Protected -> Real mode switch address

                 If function was not successful:
                 Carry flag is set

            Parameters To State-Save Procedures

                 Execute a  far jump to the appropriate address (real or
                      pmode) with:
                 AX   = New DS
                 CX   = New ES
                 DX   = New SS
                 (E)BX     = New (E)SP
                 SI   = New CS
                 (E)DI     = New (E)IP

                 The processor  will be placed in the desired mode.  The
                 DS, ES,  SS, (E)SP,  CS, and  (E)IP  will  contain  the
                 values specified.  The (E)BP register will be preserved
                 across the  call and  so can be used as a pointer.  The
                 values in  (E)AX, (E)BX, (E)CX, (E)DX, (E)SI, and (E)DI
                 will be  undefined.  On an 80386 or 80486 the FS and GS
                 segment registers  will contain  zero  after  the  mode
                 switch.

            Programmer's Notes

                 o    The address  returned in BX:CX must only be called
                      in real  mode to  switch into protected mode.  The
                      address returned  in SI:(E)DI  must only be called
                      in protected mode to switch into real mode.
                 o    16-bit programs  should call  the address returned
                      in SI:DI  to switch  from protected  to real mode.
                      32-bit programs  should call  the address returned
                      in SI:EDI.
                 o    It is  up to  the caller  to save  and restore the
                      state of  the task  when using  this  function  to




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 77








                      switch modes.   This  usually requires  using  the
                      state save function (see page 74).
                 o    The  parameters   must  contain   segment   values
                      appropriate for  the mode  that is  being switched
                      to.   If  invalid  selectors  are  specified  when
                      switching into  protected mode,  an exception will
                      occur.
                 o    Applications  may  find  functions  0300h,  0301h,
                      0302h, and 0304h more convenient to use than using
                      this type of mode switching.















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 78









                                  12. GET VERSION


            Function  0400h   returns  the   version  of  DPMI  services
            supported.  Note that this is not necessarily the version of
            any operating  system that supports DPMI.  It should be used
            by programs to determine what calls are legal in the current
            environment.

            To Call

                 AX = 0400h

            Returns

                 AH = Major version
                 AL = Minor version
                 BX = Flags
                      Bit  0   =  1  if  running  under  an  80386  DPMI
                      implementation
                      Bit 1  = 1  if  processor is returned to real mode
                      for reflected  interrupts (as  opposed to  Virtual
                      8086 mode).
                      Bit 2 = 1 if virtual memory is supported
                      Bit 3 is reserved and undefined
                      All other bits are zero and reserved for later use
                 CL = Processor type
                      02 = 80286
                      03 = 80386
                      04 = 80486
                 DH = Current value of virtual master PIC base interrupt
                 DL = Current value of virtual slave PIC base interrupt
                 Carry flag clear (call can not fail)

            Programmer's Notes

                 None



















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 79









                           13. MEMORY MANAGEMENT SERVICES


            These functions  are provided  to  allocate  linear  address
            space.



















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 80









             13.1 Get Free Memory Information


                 This  function  is  provided  so  that  protected  mode
                 applications  can   determine  how   much   memory   is
                 available.   Under DPMI  implementations  that  support
                 virtual memory, it is important to consider issues such
                 as the amount of available physical memory.

                 Note that  since DPMI  applications will  often run  in
                 multi-tasking  environments,   this  function  must  be
                 considered only advisory.

            To Call

                 AX = 0500h
                 ES:(E)DI = Selector:Offset of 30h byte buffer

            Returns

                 If function was successful:
                 Carry flag is clear.
                 ES:(E)DI = Selector:Offset of buffer with the following
                      structure:
































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 81









                       Offset           Description

                        00h   Largest available free block in
                       bytes

                        04h   Maximum unlocked page allocation

                        08h    Maximum locked page allocation

                        0Ch   Linear addr space size in pages

                        10h    Total number of unlocked pages

                        14h         Number of free pages

                        18h    Total number of physical pages

                        1Ch  Free linear address space in pages

                        20h   Size of paging file/partition in
                       pages




                       24h-2Fh            Reserved





                 If function was not successful:
                 Carry flag is set.























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 82








            Programmer's Notes

                 o    32-bit programs  must use  ES:EDI to  point to the
                      buffer.  16-bit programs should use ES:DI.
                 o    DPMI implementations  that do  not support virtual
                      memory (returned  in flags  from Get Version call)
                      will only  fill in  the first  field.   This value
                      specifies that  largest allocation  that could  be
                      made using  function 0501h.   Other fields will be
                      set to -1.
                 o    Only  the   first  field   of  this  structure  is
                      guaranteed to  contain a  valid value.  All fields
                      that are  not returned  by the DPMI implementation
                      will be  set to  -1 (0FFFFFFFFh)  to indicate that
                      the information is not available.
                 o    The field  at offset  00h  specifies  the  largest
                      block of  contiguous linear  memory in  bytes that
                      could be  allocated  if  the  memory  were  to  be
                      allocated and left unlocked.
                 o    The field  at offset  04h specifies  the number of
                      pages that  could be allocated.  This is the value
                      returned by field 00h / page size.
                 o    The field  at offset  08h  specifies  the  largest
                      block of  memory in  pages that could be allocated
                      and then locked.
                 o    The field  at offset 0Ch specifies the size of the
                      total  linear   address  space  in  pages.    This
                      includes all linear address space that has already
                      been allocated.
                 o    The field at offset 10h specifies the total number
                      of pages  that are currently unlocked and could be
                      paged out.   This  value also  contains  any  free
                      pages.
                 o    The field  at offset  14h specifies  the number of
                      physical pages that currently are not in use.
                 o    The field at offset 18h specifies the total number
                      of physical  pages that  the  DPMI  host  manages.
                      This value includes all free, locked, and unlocked
                      physical pages.
                 o    The field  at offset 20h specifies the size of the
                      DPMI host's paging partition or file in pages.
                 o    To determine  the size  of pages for the DPMI host
                      call the Get Page Size service (see page 93).














     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 83









             13.2 Allocate Memory Block


                 This function allocates and commits linear memory.

            To Call

                 AX = 0501h
                 BX:CX = Size of memory block to allocate in bytes

            Returns

                 If function was successful:
                 Carry flag is clear
                 BX:CX = Linear address of allocated memory block
                 SI:DI = Memory block handle (used to resize and free)

                 If function was unsuccessful:
                 Carry flag is set

            Programmer's Notes

                 o    This function  does not allocate any selectors for
                      the memory block.  It is the responsibility of the
                      caller to  allocate and  initialize any  selectors
                      needed to access the memory.
                 o    Under DPMI  implementations that  support  virtual
                      memory  the   memory  block   will  be   allocated
                      unlocked.   If some or all of the memory should be
                      locked you  will  need  to  use  either  the  lock
                      selector  function   or  the  lock  linear  region
                      function.
                 o    Under many  implementations of  DPMI,  allocations
                      will  be  page  granular.    This  means  that  an
                      allocation  of  1001h  bytes  will  result  in  an
                      allocation of  2000h bytes.   Therefore it is best
                      to always allocate memory in multiples of 4K.



















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 84









             13.3 Free Memory Block


                 This function  frees a  memory block  that was allocate
                 through the allocate memory block function.

            To Call

                 AX = 0502h
                 SI:DI = Handle of memory block to free

            Returns

                 If function was successful:
                 Carry flag is clear

                 If function was unsuccessful:
                 Carry flag is set

            Programmer's Notes

                 o    Your program  must also free any selectors that it
                      allocated to point to the memory block.

































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 85









             13.4 Resize Memory Block


                 This function  changes the  size of a memory block that
                 was  allocated   through  the   allocate  memory  block
                 function.

            To Call

                 AX = 0503h
                 BX:CX = New size of memory block to allocate in bytes
                 SI:DI = Handle of memory block to resize

            Returns

                 If function was successful:
                 Carry flag is clear
                 BX:CX = New linear address of memory block
                 SI:DI = New handle of memory block

                 If function was unsuccessful:
                 Carry flag is set

            Programmer's Notes

                 o    This function may change the linear address of the
                      memory block  and the  memory handle.   Therefore,
                      you will  need to  update any selectors that point
                      to the  block after resizing it.  You must use the
                      new handle instead of the old one.
                 o    This function  will generate  an error if a memory
                      block is resized to 0 bytes.
























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 86









                             14. PAGE LOCKING SERVICES


            These services  are only  useful under  DPMI implementations
            that support virtual memory.  They will be ignored by 16-bit
            DPMI implementations  (although they will always return with
            carry clear to indicate success).

            Some  implementations   of  DPMI  may  ignore  these  calls.
            However, if the calls are ignored then the DPMI host will be
            able to  handle page  faults at  arbitrary points during the
            application's execution  including interrupt  and  exception
            handler code.

            Although memory  ranges are  specified in  bytes, the actual
            unit of  memory that  will be  locked will  be one  or  more
            pages.   Page locks  are maintained  as a  count.   When the
            count is  decremented to  zero, the page is unlocked and can
            be swapped  to disk.   This means that if a region of memory
            is locked  three times  then it must be unlocked three times
            before the pages will be unlocked.



































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 87









             14.1 Lock Linear Region


                 This function locks a specified linear address range.

            To Call

                 AX = 0600h
                 BX:CX = Starting linear address of memory to lock
                 SI:DI = Size of region to lock in bytes

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    If this  function fails  then none  of the  memory
                      will be locked.
                 o    If the specified region overlaps part of a page at
                      the beginning  or end  of the  region, the page(s)
                      will be locked.






























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 88









             14.2 Unlock Linear Region


                 This function  unlocks a specified linear address range
                 that was previously locked using the Lock Linear Region
                 function.

            To Call

                 AX = 0601h
                 BX:CX = Starting linear address of memory to unlock
                 SI:DI = Size of region to unlock in bytes

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    If this  function fails  then none  of the  memory
                      will be unlocked.
                 o    An error  will be  returned if  the memory was not
                      previously locked  or if  the specified  region is
                      invalid.
                 o    If the specified region overlaps part of a page at
                      the beginning  or end  of the  region, the page(s)
                      will be unlocked.
                 o    Even if  the function  succeeds, the  memory  will
                      remain locked if the lock count is not decremented
                      to zero.






















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 89









             14.3 Mark Real Mode Region as Pageable


                 Under some  implementations  of  DPMI,  all  memory  in
                 virtual 8086 mode is locked by default.  If a protected
                 mode program  is using  memory in the first megabyte of
                 address space,  it is  a good idea to use this function
                 to turn  off automatic  page  locking  for  regions  of
                 memory that will not be touched at interrupt time.

                 Do not  mark memory as pageable in regions that are not
                 owned by your application.  For example, you should not
                 mark all free DOS memory as pageable since it may cause
                 a page  fault to  occur while  inside of DOS (causing a
                 crash).   Also, do  not mark the DPMI host data area as
                 pageable.

                 It is  very important  to relock  any real  mode memory
                 using function  0603h  before  terminating  a  program.
                 Memory  that  remains  unlocked  after  a  program  has
                 terminated could result in fatal page faults when other
                 software is executed in that address space.

                 Note that  address space  marked as  pageable  by  this
                 function can  be locked  using function  0600h.    This
                 function is  just an  advisory service  to allow memory
                 that does  not need to be locked to be paged out.  This
                 function just  disables any  automatic locking  of real
                 mode memory performed by the DPMI host.

            To Call

                 AX = 0602h
                 BX:CX =  Starting linear  address of  memory to mark as
                      pageable
                 SI:DI = Size of region to page in bytes

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    If this  function fails  then none  of the  memory
                      will be unlocked.
                 o    If the specified region overlaps part of a page at
                      the beginning  or end  of the  region, the page(s)
                      will be not be marked as pageable.




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 90








                 o    When  your   program  terminates  it  should  call
                      function 0603h to relock the memory region.
                 o    Unlike the  lock and unlock calls, the pageability
                      of the  real mode region is maintained as a binary
                      state, not  a count.   Therefore, do not call this
                      function multiple times for a given linear region.



















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 91









             14.4 Relock Real Mode Region


                 This function  is used  to relock  memory regions  that
                 were marked as pageable by the previous function.

            To Call

                 AX = 0603h
                 BX:CX = Starting linear address of memory to relock
                 SI:DI = Size of region to page in bytes

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    If this  function fails  then none  of the  memory
                      will be relocked.
                 o    If the specified region overlaps part of a page at
                      the beginning  or end  of the  region, the page(s)
                      will be not be relocked.





























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 92









             14.5 Get Page Size


                 This function  returns the size of a single memory page
                 in bytes.

            To Call

                 AX = 0604h

            Returns

                 If function was successful:
                 Carry flag is clear
                 BX:CX = Page size in bytes

                 If function was not successful:
                 Carry flag is set

            Programmers Notes

                 None


































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 93









                   15. DEMAND PAGING PERFORMANCE TUNING SERVICES


            Some applications  will discard  memory objects  or will not
            access objects for long periods of time.  These services can
            be used to improve the performance of demand paging.

            Although  these   functions  are   only  relevant  for  DPMI
            implementations   that   support   virtual   memory,   other
            implementations will  ignore these functions (it will always
            return carry  clear).   Therefore your  code can always call
            these functions  regardless of the environment it is running
            under.

            Since both of these functions are simply advisory functions,
            the operating  system may  choose to  ignore them.   In  any
            case,  your  code  should  function  properly  even  if  the
            functions fail.






































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 94









             15.1 Reserved Subfunctions


                 Functions 0700h  and 0701h  are reserved and should not
                 be called.



















































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 95









             15.2 Mark Page as Demand Paging Candidate


                 This function  is used  to inform  the operating system
                 that a  range of  pages should be placed at the head of
                 the page  out candidate  list.   This will  force these
                 pages to  be swapped  to disk ahead of other pages even
                 if the memory has been accessed recently.  However, all
                 memory contents will be preserved.

                 This is  useful, for example, if a program knows that a
                 given piece  of data  will not  be accessed  for a long
                 period of  time.   That data  is ideal  for swapping to
                 disk since  the physical  memory it now occupies can be
                 used for other purposes.

            To Call

                 AX = 0702h
                 BX:CX = Starting linear address of pages to mark
                 SI:DI = Number of bytes to mark as paging candidates

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    This function  does not  force  the  pages  to  be
                      swapped to disk immediately.
                 o    Partial pages will not be discarded.





















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 96









             15.3 Discard Page Contents


                 This function  discards the  entire contents of a given
                 linear memory  range.  It is used after a memory object
                 that  occupied   a  given  piece  of  memory  has  been
                 discarded.

                 The contents  of the  region will be undefined the next
                 time the  memory is  accessed.   All values  previously
                 stored in this memory will be lost.

            To Call

                 AX = 0703h
                 BX:CX = Starting linear address of pages to discard
                 SI:DI = Number of bytes to discard

            Returns

                 If function was successful:
                 Carry flag is clear.

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    Partial pages will not be discarded.



























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 97









                            16. PHYSICAL ADDRESS MAPPING


            Memory mapped  devices such as network adapters and displays
            sometimes have  memory mapped at physical addresses that lie
            outside of  the normal  1Mb of memory that is addressable in
            real  mode.     Under  many  implementations  of  DPMI,  all
            addresses are  linear addresses  since they  use the  paging
            mechanism of  the 80386.  This service can be used by device
            drivers to convert a physical address into a linear address.
            The linear  address can  then be  used to  access the device
            memory.

            Some implementations  of DPMI  may  not  support  this  call
            because it  could be  used to  circumvent system protection.
            This call  should only  be used  by programs that absolutely
            require direct access to a memory mapped device.

            To Call

                 AX = 0800h
                 BX:CX = Physical address of memory
                 SI:DI = Size of region to map in bytes

            Returns

                 If function was successful:
                 Carry flag is clear.
                 BX:CX =  Linear address  that can be used to access the
                      physical memory

                 If function was not successful:
                 Carry flag is set.

            Programmer's Notes

                 o    Under DPMI  implementations that  do not  use  the
                      80386 paging  mechanism, the  function will always
                      succeed and  the address returned will be equal to
                      the physical  address parameter  passed into  this
                      function.
                 o    It is  up to  the caller  to build  an appropriate
                      selector to access the memory.
                 o    Do not  use this  service to access memory that is
                      mapped in the first megabyte of address space (the
                      real mode addressable region).










     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 98









                       17. VIRTUAL INTERRUPT STATE FUNCTIONS


            Under many  implementations of  DPMI, the  interrupt flag in
            protected mode  will always  be  set  (interrupts  enabled).
            This is  because the  program is  running under  a protected
            operating system  that can  not allow  programs  to  disable
            physical hardware interrupts.  However, the operating system
            will maintain a "virtual" interrupt state for protected mode
            programs.   When the program executes a cli instruction, the
            program's virtual  interrupt state will be disabled, and the
            program will  not receive  any hardware  interrupts until it
            executes an  sti to  reenable interrupts  (or calls  service
            0901h).

            When a  protected mode program executes a pushf instruction,
            the real  processor flags  will be  pushed onto  the  stack.
            Thus, examining  the  flags  pushed  on  the  stack  is  not
            sufficient to  determine the  state of the program's virtual
            interrupt flag.   These  services enable programs to get and
            modify the state of their virtual interrupt flag.

            The following  sample  code  enters  an  interrupt  critical
            section and  then restores  the virtual  interrupt state  to
            it's previous state.

                 ;
                 ; Disable interrupts and get previous interrupt state
                 ;
                         mov     ax, 0900h
                         int     31h
                 ;
                 ; At this point AX = 0900h or 0901h
                 ;
                         .
                         .
                         .
                 ;
                 ; Restore previous state (assumes AX unchanged)
                 ;
                         int     31h















     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9        Page 99









             17.1 Get and Disable Virtual Interrupt State


                 This function  will disable  the virtual interrupt flag
                 and return  the previous state of the virtual interrupt
                 flag.

            To Call

                 AX = 0900h

            Returns

                 Carry flag clear (this function always succeeds)
                 Virtual interrupts are disabled
                 AL = 0 if virtual interrupts were previously disabled
                 AL = 1 if virtual interrupts were previously enabled

            Programmer's Notes

                 o    AH  will   not  be   changed  by  this  procedure.
                      Therefore, to  restore the  previous state, simply
                      execute an Int 31h.

































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 100









             17.2 Get and Enable Virtual Interrupt State


                 This function  will enable  the virtual  interrupt flag
                 and return  the previous state of the virtual interrupt
                 flag.

            To Call

                 AX = 0901h

            Returns

                 Carry flag clear (this function always succeeds)
                 Virtual interrupts are enabled
                 AL = 0 if virtual interrupts were previously disabled
                 AL = 1 if virtual interrupts were previously enabled

            Programmer's Notes

                 o    AH  will   not  be   changed  by  this  procedure.
                      Therefore, to  restore the  previous state, simply
                      execute an Int 31h.

































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 101









             17.3 Get Virtual Interrupt State


                 This function  will return  the current  state  of  the
                 virtual interrupt flag.

            To Call

                 AX = 0902h

            Returns

                 Carry flag clear (this function always succeeds)
                 AL = 0 if virtual interrupts are disabled
                 AL = 1 if virtual interrupts are enabled

            Programmer's Notes

                 None





































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 102









                      18. GET VENDOR SPECIFIC API ENTRY POINT


            Some DOS extenders provide extensions to the standard set of
            DPMI calls.   This  call is  used to obtain an address which
            must be  called to  use the  extensions.   The caller points
            DS:(E)SI to  a null  terminated string  that  specifies  the
            vendor name  or some  other unique  identifier to obtain the
            specific extension entry point.

            To Call

                 AX = 0A00h
                 DS:(E)SI = Pointer to null terminated string

            Returns

                 If function was successful:
                 Carry flag is clear
                 ES:(E)DI = Extended API entry point
                 DS, FS,  GS, EAX,  EBX, ECX,  EDX, ESI,  and EBP may be
            modified

                 If function was not successful:
                 Carry flag is set

            Programmer's Notes

                 o    Execute a far call to call the API entry point.
                 o    All extended  API parameters  are specified by the
                      vendor.
                 o    The string comparison used to return the API entry
                      point is case sensitive.























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 103









                             19. DEBUG REGISTER SUPPORT


            The 80386 processor supports special registers that are used
            for debugging.   Since  the  instructions  to  modify  these
            registers can only be executed by code running at privileged
            level  zero,   protected  mode  debuggers  running  in  DPMI
            environments can  not modify  the registers directly.  These
            services provide  mechanisms for  setting and clearing debug
            watchpoints and  detecting when  a watchpoint  has caused  a
            fault.













































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 104









             19.1 Set Debug Watchpoint


                 This  function   will  set  a  debug  watchpoint  at  a
                 specified linear address.

            To Call

                 AX = 0B00h
                 BX:CX = Linear address of watchpoint
                 DL = Size of watchpoint (1, 2, or 4)
                 DH = Type of watchpoint
                      0 = Execute
                      1 = Write
                      2 = Read/Write

            Returns

                 If function was successful:
                 Carry flag is clear
                 BX = Debug watchpoint handle

                 If function was not successful:
                 Carry flag is set

            Programmer's Notes

                 None




























     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 105









             19.2 Clear Debug Watchpoint


                 This function  will clear  a debug  watchpoint that was
                 set using the Set Debug Watchpoint function.

            To Call

                 AX = 0B01h
                 BX = Debug watchpoint handle

            Returns

                 If function was successful:
                 Carry flag is clear

                 If function was not successful:
                 Carry flag is set

            Programmer's Notes

                 o    This call frees the debug watchpoint handle


































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 106









             19.3 Get State of Debug Watchpoint


                 This function  returns the  state of a debug watchpoint
                 that was set using the Set Debug Watchpoint function.

            To Call

                 AX = 0B02h
                 BX = Debug Watchpoint Handle

            Returns

                 If function was successful:
                 Carry flag is clear
                 AX = Status flags
                      Bit 0 = 1 if watch point has been executed

                 If function was not successful:
                 Carry flag is set

            Programmer's Notes

                 o    To clear  the watchpoint state the caller must use
                      function 0B03h.































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 107









             19.4 Reset Debug Watchpoint


                 This function  resets the state of a previously defined
                 debug watchpoint.

            To Call

                 AX = 0B03h
                 BX = Debug Watchpoint Handle

            Returns

                 If function was successful:
                 Carry flag is clear

                 If function was not successful:
                 Carry flag is set

            Programmer's Notes

                 None


































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 108









                                   20. OTHER APIS


            In general,  any software  interrupt interface  that  passes
            parameters in  the EAX,  EBX, ECX,  EDX, ESI,  EDI, and  EBP
            registers will  work  as  long  as  none  of  the  registers
            contains a  segment value.   In  other words,  if a software
            interrupt interface is completely register based without any
            pointers, segment  register, or  stack parameters,  that API
            could work under any DPMI implementation.

            More complex  APIs require the caller to use the translation
            services described on page 58.











































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 109









                            21. NOTES FOR DOS EXTENDERS


            Many programs  that use  DPMI will be bound to DOS extenders
            so that  they will be able to run under any DOS environment.
            Existing DOS extenders support APIs that differ from the Int
            31h interface.   Usually,  DOS  extenders  use  an  Int  21h
            multiplex for their extended APIs.

            Extenders  that   support  DPMI   will  need  to  initialize
            differently when they are run under DPMI environments.  They
            will need  to enter  protected mode  using the  DPMI real to
            protected mode  entry point, install their own API handlers,
            and then load the DOS extended application program.










































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 110









             21.1 Initialization of  Extenders


            DOS extenders  should check  for the presence of DPMI before
            attempting to  allocate memory or enter protected mode using
            any other  API.   DOS extenders should check for APIs in the
            following order:

                 DOS Protected Mode Interface
                 Virtual Control Program Interface
                 eXtended Memory Specification
                 Int 15h memory allocation

            When DPMI  services are  detected,  extenders  that  provide
            interfaces that  extend or are different from the basic DPMI
            interface will switch into protected mode and initialize any
            internal data  structures.   DPMI compatible  extenders that
            provide  no   API  extensions   should  simply  execute  the
            protected mode application in real mode.




             21.2 Installing API Extensions


            DOS  extenders  typically  use  Int  21h  to  implement  API
            extensions.  Under DPMI, a DOS extender will need to install
            an API  translation library  by hooking Int 21h via then get
            and set  protected mode interrupt vector functions (see page
            56).   The DOS  extender library  then gets to see every DOS
            call executed  by the  application program.  If the API does
            not have any pointers then the interrupt can be reflected to
            the original  interrupt handler.   The  default handler will
            pass the  interrupt  to  real  mode.    Other  APIs  can  be
            explicitly mapped by the DOS extender.

            WARNING:   The translation  library code should be in locked
            memory to  prevent page  faults while  DOS is  in a critical
            section.   This could  happen, for  instance, if  a  program
            called DOS reentrantly from an Int 24h (critical error).




             21.3 Loading the Application Program


            Once the  API translation  library has been initialized, the
            DOS extender can load the application program using standard
            DOS calls.  Memory should be allocated using the DPMI memory
            allocation services.




     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 111









             21.4 Providing API Extensions


            DPMI call  0A00h provides a standard mechanism for providing
            vendor specific extensions to the standard APIs.  To support
            extensions under a DPMI environment, the translation library
            should hook  the Int 31h chain (using the DOS get/set vector
            calls) and  watch for  call 0A00h.  When this call is issued
            with the  proper string  parameter, the  Int 31h  hook  code
            should modify  ES:(E)DI, clear  the carry flag on the stack,
            and iret  without passing  the call  down the Int 31h chain.
            If  the  string  passed  in  ES:(E)DI  does  not  match  the
            extensions supported  by the library then the call should be
            passed down the Int 31h chain.










































     July 26, 1990 DOS PROTECTED MODE INTERFACE SPECIFICATION 0.9       Page 112


