home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-11 | 114.7 KB | 2,984 lines |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- XLIB PROGRAMMER'S MANUAL
- VERSION 2.0
-
- (DOS Extender Library)
-
- TechniLib Company
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright 1993, by TechniLib (TM) Company
- All Rights Reserved
-
-
-
-
-
-
- TERMS OF USE AND DISTRIBUTION
-
-
- XLIB is a shareware product; therefore, unregistered copies of XLIB are
- made available free of charge so that potential purchasers will have the
- opportunity to examine and test the software before committing payment.
- Distribution of unregistered copies of XLIB to other potential users is also
- permitted and appreciated. However, usage and distribution of XLIB must
- conform to the following conditions. In the following statement, the term
- "commercial distribution," includes shareware distribution.
-
- 1) XLIB and accompanying software must be distributed together in copies of
- the original archive provided by TechniLib. Neither the archive nor
- individual files therein may be modified.
-
- 2) The XLIB archive may be distributed in combination with other shareware
- products; however, the XLIB archive may not be distributed with other
- commercially distributed software without written consent of TechniLib.
-
- 3) Copies of XLIB which have been used to develop software for commercial
- distribution must be registered before such software is marketed. Copies of
- XLIB which have been used to develop noncommercial software must be registered
- if such software is to be regularly used either by the developer or others.
-
- 4) Commercially distributed software must embed XLIB procedures in the
- software code. Files contained in the XLIB archive may not be placed in the
- distribution media.
-
- 5) XLIB is designed to offer a set of services to other executable code. XLIB
- may not be used to develop software for commercial distribution which will
- essentially offer any of these same services to other executable code.
- Exceptions to this condition require written consent of TechniLib.
-
- 6) Rights afforded by registering a single copy of XLIB pertain only to a
- single computer.
-
- 7) XLIB may be registered for a fee of $35.00 per copy. Accompany payment
- with the registration form included in the XLIB archive. Registrants will be
- entitled to the most recent version of the XLIB archive.
-
-
- DISCLAIMER OF WARRANTY
-
-
- XLIB AND ALL ACCOMPANYING SOFTWARE AND LITERATURE ARE DISTRIBUTED WITH
- THE EXCLUSION OF ANY AND ALL IMPLIED WARRANTIES, AND WITH THE EXCLUSION OF
- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. TechniLib
- SHALL HAVE NO LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- RESULTING FROM THE USE OF XLIB OR ACCOMPANYING MATERIALS. The user assumes
- the entire risk of using this software.
-
-
- Copyright 1993, by TechniLib (TM) Company
- All Rights Reserved
-
-
-
-
-
-
- TABLE OF CONTENTS
-
-
- CHAPTERS
- Page
- 1. Introduction 1
- 2. XLIB Conventions and Structure 4
- 3. XLIB Initialization and Termination 6
- 4. Mode Switching 9
- 5. Inline Mode Switching 13
- 6. Interrupt Management 16
- 7. Memory Management 22
- 8. File Management 25
- 9. Descriptor Management 29
- 10. Using XLIB in High-Level Language Libraries 30
-
-
- TABLES
- Page
- 1. XLIB Segments and Selectors by Public Symbol 5
- 2. CALLPM/ENTERPM Register Storage Locations by Public Symbol 11
- 3. CALLRM Register Storage Locations by Public Symbol 12
- 4. XLIB File Control Block Structure 25
-
-
- EXAMPLES
- Page
- 1. Simple Mode Switching Under XLIB 3
- 2. Using INLINEPM/INLINERM in C 13
- 3. Calling Protected-Mode Libraries From BASIC 30
-
-
- APPENDICES
- Page
- A. Description of XLIB Public Data 34
- B. XLIB Error Codes 37
- C. DPMI 1.0 Error Codes 39
- D. XMS Error Codes 40
- E. Calling Protected-Mode Libraries From C 41
- F. Reporting Problems With XLIB 43
- G. The SWITCHPM and SWITCHRM Procedures 44
-
-
-
-
-
-
- 1. Introduction
-
-
- XLIB is an assembly language library which may be used with assembly
- language programs to greatly simplify protected-mode programming under the
- Microsoft DOS operating system. Implementation of protected-mode procedures
- will often require no more than placing code in the proper segment and making
- two calls to XLIB procedures. XLIB also simplifies protected-mode programming
- in C using inline assembly.
- XLIB is designed for the Intel 386, 486, and Pentium processors. XLIB
- fully utilizes the 32-bit processing powers of these chips and makes these
- powers available to the user. The compactness of XLIB follows largely from
- the fact that much of it is written in 32-bit code.
- XLIB is used to produce extended DOS applications. DOS is unfortunately
- limited by the fact that it is a real-mode operating system intended to manage
- only real-mode programs. Real-mode programs cannot use memory addresses
- requiring more than 20 bits, or use memory offsets requiring more than 16
- bits. Such programs are further limited by the fact that 32-bit instructions
- execute awkwardly in real-mode. When the processor is in real-mode, it will
- expect all 32-bit instructions to be preceded by at least one prefix. Each of
- these prefixes consumes one byte of memory and requires at least one clock to
- execute. Such limitations do not exist in 32-bit protected mode. Extended
- DOS applications overcome the limitations of DOS with their ability to execute
- in both real and protected modes. DOS services can be utilized from real mode
- while the 32-bit processing power of the CPU can be utilized from protected
- mode.
- There are presently several 32-bit operating systems available on the
- market. Such systems include IBM OS/2, Microsoft Windows NT, and UNIX. These
- systems can manage programs which operate exclusively in protected mode. Such
- programs are generally easier to develop than extended DOS applications.
- However, extended DOS applications have an advantage in that they can execute
- under all of these operating systems because all of these systems can emulate
- DOS.
- Of course DOS will eventually become obsolete. Future programs will
- likely operate exclusively in protected mode using the flat memory model. The
- memory models supported by XLIB approximate the flat model; therefore, code
- written for XLIB will require little modification when being transported to
- flat-model operating environments. Indeed, many procedures will require no
- modification whatsoever. Moreover, XLIB includes flat-model descriptors which
- may be used to execute genuine flat-model code. XLIB does not load and
- relocate such code; however, it does provide all the necessary tools to
- develop such procedures.
- XLIB procedures handle important tasks such as mode switching between
- real and protected modes, memory management under protected mode, protected-
- mode interrupt management, and protected-mode file management. XLIB includes
- routines to perform these tasks in the absence of a protected-mode interface,
- or in the presence of the Virtual Control Program Interface (VCPI), or the DOS
- Protected Mode Interface (DPMI, version .9 or higher). XLIB can also manage
- extended memory through the Extended Memory Specification (XMS).
- Upon initialization, XLIB will examine the operating environment for the
- presence of DPMI, VCPI, and XMS, and then configure itself accordingly. The
- client program may therefore perform calls to XLIB procedures with few
- concerns as to the environment in which it is executing.
-
-
-
-
- 1
-
-
-
-
-
-
- XLIB relieves the programmer of descriptor table management by supplying
- a set of predefined segments along with their associated descriptors and
- selectors. Many protected-mode procedures will require no modification for
- XLIB other than being placed in the proper segment. XLIB provides a single
- 32-bit segment for protected-mode routines. This segment may be larger than
- 64K, but must reside in conventional memory so that DOS can load it. However,
- code within this segment may access data throughout the address space. XLIB
- does allow user-defined descriptors; however, these should be needful only in
- very rare cases.
- The following program illustrates the simplicity with which protected-
- mode execution may be initiated and terminated with XLIB. The program was
- written with the Microsoft Assembler (MASM). It first initializes XLIB by
- calling a procedure called INITXLIB. After confirming that initialization is
- successful, the program then transfers control to a 32-bit protected-mode
- procedure which prints a message to the screen. Control is transferred by
- placing the protected-mode target address on the stack and then calling an
- XLIB procedure named CALLPM (call protected mode). CALLPM will expect the
- target procedure to be contained in a segment called TSEG. The protected-mode
- procedure in TSEG returns control to real or virtual 8086 (V86) mode simply by
- executing the RET instruction.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
- Example 1: Simple Mode Switching Under XLIB
- -----------------------------------------------------------------------------
- .MODEL LARGE,PASCAL
- .386P
-
- INCLUDE XLIB.INC ;Include XLIB public symbols
- INCLUDELIB XLIB.LIB ;Link with XLIB.LIB
-
- .STACK 1024
- .CODE
- .STARTUP
- CALL INITXLIB ;Initialize XLIB
- OR EAX,EAX ;EAX = 0 if successful
- JZ INITDONE
- .EXIT 0 ;Initialization failed
- INITDONE: PUSHD OFFSET DEMOPROC
- CALL CALLPM ;Execute DEMOPROC in protected
- .EXIT 0
-
- ;Protected-mode routines must be placed in following segment:
- TSEG SEGMENT PARA PUBLIC USE32 'CODE'
- ASSUME CS:TSEG, SS:TSEG, DS:TSEG, ES:TSEG, FS:DSEG, GS:DGROUP
-
- ;Protected-mode routine to print message to the screen using DOS function.
- DEMOPROC PROC NEAR
- MOV EBX,OFFSET PMMSG
- MOV AH,02H
- MSGLOOP: MOV DL,CS:[EBX] ;32-bit offset!!!!!
- OR DL,DL
- JZ EXIT
- INT 21H ;Print character with DOS
- INC EBX
- JMP MSGLOOP
- EXIT: RET ;Go back to real or V86 mode
- PMMSG DB "In 32-bit protected mode!!! "
- DB "Returning to real mode.",10,13,0
- DEMOPROC ENDP
-
- TSEG ENDS
- END
- -----------------------------------------------------------------------------
-
-
- The framework presented in the above program is extremely simple;
- nonetheless, it will meet the demands of many protected-mode programs. Most
- protected-mode programs will require no further modifications other than a few
- calls to XLIB extended memory management procedures.
- XLIB was developed and tested under Microsoft DOS version 6.0 using
- Microsoft Assembler (MASM) version 6.1a, Microsoft LINK version 5.31.009, and
- Microsoft LIB version 3.20.01. MASM parameters were set to c, W2, and WX.
- LINK parameters were set to BATCH, CPARM:1, FAR, NOPACKF, and PACKC. XLIB has
- also been tested under Microsoft Windows 3.1, Qualitas 386MAX version 6.02,
- Quarterdeck QEMM version 6.02, Quarterdeck QDPMI version 1.01, Quarterdeck
- DESQview version 2.42, and IBM OS/2 version 2.1.
-
-
-
- 3
-
-
-
-
-
-
- 2. XLIB Conventions and Structure
-
-
- XLIB public procedures and public data are explained in the following
- chapters. A detailed explanation of most XLIB public data is also included in
- Appendix A. This chapter sets forth rules which will be generally applicable
- to all XLIB data and procedures.
- Though it is sometimes necessary for XLIB to distinguish between real
- mode and virtual 8086 mode; this document uses the term "real mode" to include
- virtual 8086 mode.
- All public real-mode procedures and 16-bit protected-mode procedures in
- XLIB are located in a segment called CSEG. The user may also place code in
- CSEG but is rarely required to do so. All public XLIB procedures in CSEG have
- far returns.
- All public 32-bit protected-mode procedures in XLIB are located in a 32-
- bit segment called TSEG and have near returns. XLIB will also expect the user
- to place all 32-bit procedures in TSEG and will expect these procedures to
- have near returns. This policy is adopted to achieve approximation to the
- flat model.
- Nearly all XLIB protected-mode procedures are 32-bit routines. The only
- exceptions to this rule are the inline mode-switch procedures discussed in
- Chapter 5. This policy is implemented to approximate the flat model. There
- are very few circumstances in which 16-bit protected mode is preferable to 32-
- bit protected mode. One can generally increase program speed and reduce
- program size by writing the code for 32-bit segments.
- TSEG may be larger than 64K provided that certain rules are observed.
- XLIB adheres to all of the necessary rules. First, only 32-bit protected-mode
- code should be placed in TSEG. The processor will not generally be able to
- execute real-mode code in this segment because the offsets will be 32-bit
- values. Second, real-mode code should never write to or read from TSEG. Such
- instructions will also require 32-bit offsets. Modifications to TSEG should
- be done from a TSEG protected-mode procedure. Finally, segment constants
- should never be encoded in TSEG. For example, the symbols CSEG, TSEG, DSEG,
- and DGROUP should not be found in TSEG. DOS will not be able to perform
- relocation edits on these constants if they are in a segment larger than 64K.
- To read these values from TSEG, initialize memory locations in a 16-bit
- segment to the values and then read the memory locations. Memory locations in
- DSEG have already been initialized for XLIB segments (see Appendix A).
- Microsoft LINK will issue a warning for code segments exceeding 64K; however,
- this warning may be safely ignored provided that the above rules are observed.
- All XLIB procedures may be called with interrupts enabled and will return
- with interrupts enabled provided that they were enabled upon call.
- All XLIB public data is contained in a 16-bit segment called DSEG. The
- user may also place data in DSEG but is rarely required to do so.
- XLIB uses the PASCAL calling and naming convention. The PASCAL
- convention is equivalent to the BASIC/FORTRAN convention. C programmers must
- adapt XLIB procedures and symbols with declarations which specify the PASCAL
- convention. The header file XLIB.H contains such declarations.
- XLIB routines which can encounter error conditions will always return
- XLIB error codes in AX. A list of such error codes is presented in Appendix
- B. In most cases, DX or the high word of EAX will be returned with specific
- information about the error, such as DPMI, XMS, or DOS error codes. DPMI
- error codes are presented in Appendix C. XMS error codes are in Appendix D.
-
-
-
-
- 4
-
-
-
-
-
-
- Selectors for all XLIB segments are placed in public WORD locations in
- segment DSEG. The following table gives the name of each predefined selector
- along with its associated segment name and description:
-
-
- Table 1: XLIB Segments and Selectors by Public Symbol
- -----------------------------------------------------------------------------
- Selector Name Segment Name Description
- ------------- ------------ -----------
- CSEGSEL CSEG XLIB 16-bit code segment
- CSEGDSEL CSEG Data selector to CSEG
- TSEGSEL TSEG 32-bit code segment
- TSEGDSEL TSEG Data selector to TSEG
- DSEGSEL DSEG XLIB data segment
- FLATSEL . Flat-model code
- FLATDSEL . Flat-model data
- DGROUPSEL DGROUP DGROUP data group
- SCRNSEL . Screen data
- MAINCSSEL . CS selector for main caller
- MAINSSSEL . SS selector for main caller
- MAINDSSEL . DS selector for main caller
- MAINESSEL . ES selector for main caller
- ILCSSEL . Inline CS selector
- ILSSSEL . Inline SS selector
- ILDSSEL . Inline DS selector
- -----------------------------------------------------------------------------
-
-
- The flat-model and TSEG descriptors have limit FFFFFFFFH. All other
- descriptors have limit FFFFH. The screen descriptor has base set to B8000H
- for color monitors and B0000H for monochrome monitors. MAINCSSEL, MAINSSEL,
- MAINDSSEL, and MAINESSEL are selectors to descriptors which have base
- addresses matching the contents of CS, SS, DS, and ES as of the call to
- INITXLIB. ILCSSEL, ILSSSEL, and ILDSSEL are selectors used by the inline
- mode-switch procedures (see Chapter 5). The base addresses of the
- corresponding descriptors are adjusted dynamically.
- All data segments are writable. The data descriptors have their big bits
- set; consequently, implicit stack instructions will use ESP rather then SP.
- All code segments are readable and nonconforming. Descriptor privilege levels
- and requested privilege levels are set to zero unless DPMI is installed.
- Privilege levels under DPMI will generally be set to three.
- The values contained in the above selectors will be different under DPMI
- than other environments. Moreover, DPMI selector values can differ in
- different environments and under different hosts. The user should therefore
- always read selector values from these locations.
- Since selectors are stored in DSEG, the user must never lose track of the
- DSEG selector. This could prove a problem in interrupt handlers where no
- assumptions can be made as to register contents. Consequently, XLIB places a
- copy of the DSEG selector in TSEG where it can always be found. It is stored
- under WORD symbol CSDSEGSEL and may be read with CS override. For example
- from TSEG code you can always load DS with DSEGSEL using MOV DS,CS:CSDSEGSEL.
- XLIB never uses selectors past DGROUPSEL in Table 1. The user may
- therefore redefine the associated descriptors if desired. Selector values
- however should not be changed.
-
-
-
- 5
-
-
-
-
-
-
- 3. XLIB Initialization and Termination
-
-
- XLIB procedures apart from those presented in this chapter should be
- called only after XLIB has been initialized by calling INITXLIB. This routine
- will examine the operating environment for the presence of DPMI, VCPI, and
- XMS. It will then perform extensive code modifications upon XLIB to
- accommodate the resident software. INITXLIB is to be called only once within
- a program. Subsequent calls have no effect.
- If XLIB finds that neither DPMI nor VCPI are present, then XLIB will
- completely handle all mode switching and interrupt management. If XLIB finds
- that XMS is absent also, then XLIB will handle all extended memory management.
- If XLIB finds that both DPMI and VCPI are present, then it will configure
- itself for DPMI by default. However, the default may be changed by setting
- bit 0 of IFLAGS (initialization flags) before calling INITXLIB. If this bit
- is set, then VCPI is given priority over DPMI. IFLAGS is a public WORD
- location in DSEG.
- INITXLIB will probably attempt to allocate some conventional memory
- through DOS. Since high-level language modules and assembly language modules
- often claim all available DOS memory, INITXLIB may fail for lack of available
- DOS memory. This problem can be averted with assembly language modules by
- linking with the CPARM:1 parameter. This forces the module to claim no more
- DOS memory than is necessary. High-level language modules should call
- XLIBMEMREQ (XLIB memory requirements) to obtain conventional memory
- requirements and then release at least this much memory. This process is
- illustrated for Microsoft BASIC in Chapter 10. C does not allocate all DOS
- memory and therefore does not require such special action.
- If both VCPI and DPMI are present, then conventional memory requirements
- will depend upon which of these interfaces is to be chosen by INITXLIB. In
- such cases, XLIBMEMREQ will return DPMI memory requirements if bit 0 of IFLAGS
- is clear, and will return VCPI requirements otherwise. Therefore, this bit
- should be set to the appropriate value by the user before calling XLIBMEMREQ.
- DPMI conventional memory requirements may be obtained by calling DPMIMEMREQ.
- These will vary from host to host. VCPI conventional memory requirements may
- be obtained by calling VCPIMEMREQ. VCPI requirements are the same for all
- servers.
- One of the principle function of XLIB is of course to make protected-mode
- interfaces and memory management interfaces transparent to the client program.
- However, there are special cases where a program should be informed as to
- which interfaces are implemented. In such cases, the procedure XLIBCONFIG
- (XLIB configuration) may be called to determine the how XLIB has been
- configured by INITXLIB.
- XLIB is terminated with INT 21H function 4C (DOS termination) issued
- either from real or protected mode.
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6
-
-
-
-
-
-
- Detailed Specifications
-
-
- INITXLIB (Initialize XLIB)
- Purpose: Check for presence of XMS, DPMI, and VCPI, then configure XLIB to
- operate with the installed interfaces.
- CPU Mode: Real
- Registers at Call: None
- Return Registers:
- AX = 0 if successful, in which event DX and EAX are zero as well. The
- configured interfaces may be identified by calling XLIBCONFIG (see below).
- AX <> 0 if unsuccessful. An XLIB error code is returned in AX. A specific
- error code is returned in DX and in the high word of EAX (EAH). If AX = 11H
- or 12H, then DX and EAH will equal a DOS error code. If AX = DPMI error, then
- DX and EAH will equal a DPMI 1.0 error code (if provided by host). If AX =
- VCPI error, then DX and EAH are returned as zero.
- Details:
- If both DPMI and VCPI are present, then XLIB will be configured for DPMI if
- the zero bit of IFLAGS is clear. If this bit is set, then XLIB will be
- configured for VCPI. The bit is clear by default.
- This routine will likely attempt to allocate DOS memory. The amount of DOS
- memory XLIB will attempt to allocate can be obtained by calling XLIBMEMREQ
- (see below).
- Descriptors are created for the segments loaded in CS, SS, DS, and ES as of
- call to this routine. The selectors for these descriptors are MAINCSSEL,
- MAINSSSEL, MAINDSSEL, and MAINESSEL. These descriptors are never used by
- other XLIB procedures. They are provided to augment development of protected-
- mode libraries. Protected-mode library routines may access the stack and data
- of the main program through these descriptors.
- INITXLIB should be called only once within a program. Subsequent calls are
- returned with no action. XLIB is terminated by INT 21H function 4C (DOS
- termination) issued from either real or protected mode.
-
- XLIBMEMREQ (XLIB Memory Requirements)
- Purpose: Find XLIB conventional memory requirements.
- CPU Mode: Real
- Registers at Call: None
- Return Registers:
- Sign bit of DX clear if successful. Memory requirements in bytes are
- returned in DX:AX.
- Sign bit of DX set if unsuccessful. An error code is returned in AX
- (always a DOS error code).
- Details:
- DX:AX is adjusted upward to an integer multiple of 16.
- If both DPMI and VCPI are present, then XLIBMEMREQ will assume that DPMI
- will be used if bit 0 of IFLAGS is clear (the default); otherwise, VCPI is
- assumed. No additional conventional memory is needed if both DPMI and VCPI
- are absent.
- This routine will return DX:AX = 0 if XLIB contains free internal memory in
- sufficient quantity to meet conventional memory demands.
- This routine obtains DPMI requirements by calling DPMIMEMREQ (see below)
- and VCPI requirements by calling VCPIMEMREQ.
-
-
-
-
-
- 7
-
-
-
-
-
-
- DPMIMEMREQ (DPMI Memory Requirements)
- Purpose: Find DPMI conventional memory requirements.
- CPU Mode: Real
- Registers at Call: None
- Return Registers: DX:AX = conventional memory requirements.
- Details:
- DX:AX is adjusted upward to an integer multiple of 16.
- This routine does not assume the presence of DPMI. It will return DX:AX =
- 0 if DPMI is absent.
- This routine will return DX:AX = 0 if XLIB contains free internal memory in
- sufficient quantity to meet the conventional memory demands of DPMI.
-
- VCPIMEMREQ (VCPI Memory Requirements)
- Purpose: Find VCPI conventional memory requirements.
- CPU Mode: Real
- Registers at Call: None
- Return Registers: DX:AX = conventional memory requirements.
- Details:
- DX:AX is adjusted upward to an integer multiple of 16.
- This routine simply loads DX:AX with a constant.
-
- XLIBCONFIG (XLIB Configuration)
- Purpose: Get XLIB configuration.
- CPU Mode: Real
- Registers at Call: None
- Return Registers: AX = 0 if protected-mode structures are not initialized;
- otherwise, AX = XLIB configuration. The value of lower nibble identifies the
- protected-mode host/server. If 1 then DPMI is installed. If 2 then VCPI is
- installed. If 3 then XLIB handles mode switches. Bit 4 is set if XMS is
- installed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 8
-
-
-
-
-
-
- 4. Mode Switching
-
-
- As illustrated in Example 1, CALLPM may be used to transfer control to
- 32-bit protected mode in segment TSEG. When execution is returned to real
- mode, segment registers, ESP, system flags, and control flags are restored to
- their original values.
- Execution may also be transferred to protected mode in TSEG with the
- ENTERPM (enter protected mode) procedure. This procedure is specially
- designed to accommodate mixed-language programming with high-level languages
- operating in real mode. High-level language modules may be linked with
- libraries containing protected-mode procedures. These procedures may then be
- called from high-level code. However, such procedures must generally be
- careful to restore register state. ENTERPM restores register state as
- required by Microsoft high-level languages. In particular, ENTERPM restores
- all registers except EAX, EDX, and the status flags. EAX and EDX are not
- restored because these are typically used by high-level languages for return
- values. ENTERPM otherwise functions exactly as CALLPM.
- Both CALLPM and ENTERPM save register state as of call. CALLPM and
- ENTERPM will also save and restore the state of the floating point unit (FPU)
- if requested. FPU save/restore can be enabled by setting bit 2 of OFLAGS
- (operation flags). The bit is clear by default. OFLAGS is a public WORD in
- DSEG.
- FPU state is saved with the FSAVE instruction executed from real mode.
- This instruction resets the FPU; consequently, the FPU control word must be
- redefined. XLIB will therefore load FPUCW (FPU control word) to the FPU
- control word after performing FSAVE. FPUCW is a public WORD location in DSEG.
- After entering protected mode through CALLPM or ENTERPM, control would
- typically be returned to real mode with the RET instruction. However, control
- may also be returned to real mode by jumping to either RETPM or EXITPM. These
- are both procedures in TSEG. They will successfully return control to real
- mode regardless of the stack state.
- RETPM returns control to the real-mode caller of CALLPM/ENTERPM after
- restoring segment registers, ESP, system flags, and control flags. EXITPM
- returns control to the real mode caller after restoring all registers except
- EAX, EDX, and the status flags.
- The return address placed on the stack by CALLPM is actually a near
- return to RETPM. Likewise, ENTERPM places a near return to EXITPM. CALLPM
- and ENTERPM are otherwise identical procedures.
- Once within protected mode, far procedures in real mode can be called
- using CALLRM. CALLRM may be called only by protected-mode procedures in TSEG.
- XLIB contains two hardware interrupt handlers that are typically
- activated upon entry to protected mode. These handlers are fully explained in
- Chapter 6. The first handler is hooked to the keyboard interrupt. This
- handler manages hot key detection. The second handler is hooked to the FPU
- interrupt and is designed to handle FPU exceptions.
-
-
-
-
-
-
-
-
-
-
-
- 9
-
-
-
-
-
-
- Detailed Specifications
-
-
- CALLPM (Call Protected Mode)
- Purpose: Call a protected-mode procedure in TSEG with near return.
- CPU Mode: Real
- Registers at Call: SS:ESP = 32-bit protected-mode target offset.
- Return Registers: Returns through RETPM. See RETPM for details.
- Details:
- All CPU registers except EAX and EDX are saved at locations presented in
- Table 2. The stack is saved after the return address and argument have been
- popped.
- The target receives SS = TSEGDSEL with 1000H free bytes on the stack. The
- return address on the stack is a near return to RETPM. The target receives by
- default: DS = FLATDSEL, ES = TSEGDSEL, FS = DSEGSEL, and GS = DGROUPSEL.
- Other registers, including the status flags, are received at values as of
- call.
- If bit 2 of OFLAGS is set, then the FPU state is also saved; the FPU is
- initialized, and FPUCW is loaded to the control word.
- XLIB hardware interrupt handlers are enabled (see Chapter 6). However, if
- bit 1 of OFLAGS is set, then the XLIB interrupt handler for the FPU will not
- be enabled.
- If an FPU exception occurs after CALLPM, and if the FPU exception handler
- is enabled, then protected mode will be exited through EXITPM rather than
- RETPM. If FPU save/restore is not enabled, then real-mode will receive an
- initialized FPU with control word set to the value existing as of the
- exception.
- The user may change the stack after the mode switch.
- DS, ES, FS, and GS are actually loaded from: PMDS, PMES, PMFS, and PMGS.
- These are public WORD locations in DSEG and are initialized to the default
- selectors by INITXLIB. The user however may change these selectors to any
- legal values after initialization.
-
- RETPM (Return From Protected Mode)
- Purpose: Return control to real mode with partial register restoration.
- CPU Mode: Protected
- Registers at Call: None
- Return Registers: No return
- Details:
- RETPM switches to real mode and then restores all segment registers, ESP,
- system flags, and control flags to values as of call to either CALLPM or
- ENTERPM. XLIB hardware interrupt handlers are disabled (see Chapter 6).
- Control is then transferred to the real-mode return address as of call to
- CALLPM/ENTERPM.
- If bit 2 of OFLAGS is set, then RETPM also restores FPU state.
- RETPM will successfully execute regardless of stack state.
-
- ENTERPM (Enter Protected Mode)
- Purpose: Call a protected mode procedure in TSEG with near return.
- CPU Mode: Real
- Registers at Call: SS:ESP = 32-bit protected-mode target offset.
- Return Registers: Returns through EXITPM. See EXITPM for details.
- Details: This routine executes exactly as CALLPM except that a near return to
- EXITPM is placed on the stack rather than to RETPM.
-
-
-
- 10
-
-
-
-
-
-
-
- EXITPM (Exit Protected Mode)
- Purpose: Return control to real mode with general register restoration.
- CPU Mode: Protected
- Registers at Call: None
- Return Registers: No return
- Details:
- EXITPM switches to real mode and then restores all registers except EAX,
- EDX, and status flags to values as of call to either CALLPM or ENTERPM. XLIB
- hardware interrupt handlers are disabled (see Chapter 6). Control is then
- transferred to the real-mode return address as of call to CALLPM/ENTERPM.
- If bit 2 of OFLAGS is set, then EXITPM also restores FPU state.
- EXITPM will successfully execute regardless of stack state.
- The FPU exception handler performs a jump to EXITPM upon occurrence of any
- unmasked FPU exception.
-
-
- Table 2: CALLPM/ENTERPM Register Storage Locations by Public Symbol
- -----------------------------------------------------------------------------
- Register Symbol Symbol Type
- -------- ------ -----------
- EBX ORGEBX DWORD
- ECX ORGECX DWORD
- ESI ORGESI DWORD
- EDI ORGEDI DWORD
- EBP ORGEBP DWORD
- ESP ORGESP DWORD
- EFLAGS ORGEFLAGS DWORD
- SS ORGSS WORD
- DS ORGDS WORD
- ES ORGES WORD
- FS ORGFS WORD
- GS ORGGS WORD
- FPU State ORGFPU BYTE[94]
- -----------------------------------------------------------------------------
-
-
- CALLRM (Call a Real-Mode Procedure)
- Purpose: Call a real-mode routine with far return from protected mode.
- CPU Mode: Protected
- Registers at Call: SS:ESP = far real-mode target address (four bytes).
- Return Registers: All segment registers and ESP are restored. Other
- registers, including status flags, are received with values as of the real-
- mode RET instruction.
- Details:
- This is a near procedure in TSEG. It must therefore be called from TSEG.
- Segment registers and ESP are saved at locations presented in Table 3. The
- stack is saved after popping the return address and argument.
- The target receives the XLIB real-mode stack (SS = DSEG) with 200H free
- bytes. By default, the target receives DS = DGROUP, ES = DSEG, FS = DSEG, and
- GS = DSEG. Other registers, including status flags, are received at values as
- of call.
- Code called by this routine should not perform calls to XLIB procedures
- other than SWITCHPM and SWITCHRM (see Appendix G).
-
-
-
- 11
-
-
-
-
-
-
- DS and ES are actually loaded from RMDS and RMES. These are public WORD
- locations in DSEG and are initialized to the default values. However, the
- user may change these values if desired.
- This procedure does not change values in OFLAGS; consequently, XLIB
- hardware interrupt handlers remain enabled in real mode if they were enabled
- as of call (see Chapter 6).
- FPU exceptions in real mode are handled the same as in protected mode;
- however, system software is less apt to be left in regular state after real-
- mode exceptions. FPU instructions should therefore be executed in protected
- mode where possible.
-
-
- Table 3: CALLRM Register Storage Locations by Public Symbol
- -----------------------------------------------------------------------------
- Register Symbol Symbol Type
- -------- ------ -----------
- ESP CALLESP DWORD
- SS CALLSS WORD
- DS CALLDS WORD
- ES CALLES WORD
- FS CALLFS WORD
- GS CALLGS WORD
- -----------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 12
-
-
-
-
-
-
- 5. Inline Mode Switching
-
-
- XLIB includes two routines to perform mode switching in C programs using
- inline assembly. These procedures are very versatile and simple. A third
- routine is included to facilitate calls from 16-bit segments to 32-bit near
- procedures in TSEG.
- Call INLINEPM to switch to protected mode. Descriptors are automatically
- created for CS, SS, and DS. These registers are returned containing selectors
- to the respective descriptors. ES is returned containing DSEGSEL. ES may be
- used to load other XLIB selectors to segment registers.
- Call INLINERM to return to real-mode. This function should be called
- from the same segment as the previous call to INLINEPM and should be using the
- same stack segment. INLINERM restores segment registers to values which
- existed as of the call to INLINEPM.
- The following Microsoft C 7.0 program illustrates the usage of these
- procedures. The program contains a C subroutine called "getextmem" which uses
- INLINEPM and INLINERM to retrieve a DWORD from extended memory.
- Observe that since the inline assembly code is in a 16-bit segment,
- prefixes must be used with 32-bit instructions. Also observe that INLINERM is
- called indirect through a supplied pointer in DSEG called INLINERMPTR. This
- is done to ensure that the intersegment call loads CS with the protected-mode
- selector for CSEG (CSEGSEL) rather than with the segment constant.
- This program may fail if an attempt is made to access logical addresses
- which are either protected or undefined in the page tables.
-
-
- Example 2: Using INLINEPM/INLINERM in C
- -----------------------------------------------------------------------------
- #include <stdio.h>
- #include <xlib.h>
- #define som _emit 0x66 /* switch operand mode */
- #define sam _emit 0x67 /* switch address mode */
- long __far getextmem(long address);
-
- int goterr = 0; /* error flag */
-
- main()
- {
- long l;
- l = INITXLIB(); /* initialize XLIB */
- if(l != 0)
- {
- printf("Library initialization error: %lX\n",l);
- return 0;
- }
- l = getextmem(0x100000); /* read first address in 2ond meg */
- if(goterr != 0)
- {
- printf("Inline mode-switch error: %lX\n",l);
- return 0;
- }
- printf("%lX\n",l);
- }
-
-
-
- 13
-
-
-
-
-
-
-
- long __far getextmem(long address)
- {
- __asm
- {
- som ;mov eax,[bp+6]
- mov ax,[bp+6] ; ""
- call INLINEPM
- jc error ;Error code in ax
- mov ds,es:FLATDSEL
- sam ;push dword ptr [eax]
- som ; ""
- _emit 0ffh ; ""
- _emit 030h ; ""
- pop ax
- pop dx
- call es:INLINERMPTR
- jmp done
- error:
- xor dx,dx ;Return error code in dx:ax
- inc goterr
- done:
- }
- }
- -----------------------------------------------------------------------------
-
-
- Detailed Specifications
-
-
- INLINEPM (Inline Protected-Mode)
- Purpose: Return to real-mode caller in 16-bit protected mode.
- CPU Mode: Real
- Registers at Call: None
- Return Registers:
- CF clear if successful. Descriptors are created for CS, SS, and DS. These
- descriptors have base addresses matching the calling contents of the
- respective segment registers. The segment registers are returned containing
- selectors to these descriptors. These selectors are also stored in DSEG at
- the public WORD locations ILCSSEL, ILSSSEL, and ILDSSEL. See Chapter 2 for
- further details as to descriptor specifications. ES, FS, and GS are returned
- containing DSEGSEL. Protected mode receives other registers, except the
- status flags, at values as of call.
- CF set if unsuccessful. The processor will still be in real mode.
- Unsuccessful execution can occur only under DPMI. EAX is returned with an
- error code. AX = XLIB error code. The high word of EAX will equal a DPMI 1.0
- error code (if provided by host). Other registers, except the status flags,
- are unchanged.
- Details:
- INLINEPM stores segment registers at the same locations used by CALLPM and
- ENTERPM (Table 1). INLINERM (see below) then restores these registers. C
- will require that other registers be preserved also; however, the user is
- responsible for managing these.
-
-
-
-
- 14
-
-
-
-
-
-
- XLIB hardware interrupt handlers are not activated by this procedure (see
- Chapter 6). The keyboard handler may be enabled by the user if hot key
- detection is needful; however, the FPU exception handler should never be
- enabled. Therefore, hot key detection should be enabled by setting both bits
- 0 and 1 in OFLAGS.
- SP is preserved through the mode switch; however, the high word of ESP is
- set to zero. The high word must be cleared since SS is set to a descriptor
- having FFFFH limit and having its big bit set.
- If multiple calls are made to INLINEPM with the same values in CS, SS, and
- DS, then descriptors are created only on the first call. Subsequent calls
- will therefore execute more quickly.
-
- INLINERM (Inline Real-Mode)
- Purpose: Return to 16-bit protected-mode caller in real mode.
- CPU Mode: 16-bit protected mode
- Registers at Call: CS and SS must equal values as of return from INLINEPM.
- Return Registers: Segment registers are restored to values existing as of
- former call to INLINEPM. Real mode receives other registers, except status
- flags, at values as of call.
- Details:
- Since INLINERM will be called intersegment, caution must be taken that CS
- is loaded with CSEGSEL and not CSEG. XLIB provides a far pointer to this
- procedure called INLINERMPTR which may be used to execute the call.
- INLINERM and CALL32 are the only 16-bit protected-mode procedures in XLIB.
- They are also the only protected-mode procedures having far returns.
-
- CALL32 (Call 32-bit Protected-Mode)
- Purpose: Call a 32-bit protected-mode near procedure in segment TSEG from 16-
- bit protected-mode.
- CPU Mode: 16-bit protected mode
- Registers at Call: SS:ESP = 32-bit protected-mode target offset.
- Return Registers: All registers, including status flags, are returned with
- values existing as of the 32-bit RET instruction.
- Details:
- CALL32 is a far procedure; therefore, caution must be taken that calls to
- CALL32 load CS with CSEGSEL instead of CSEG. XLIB provides a far pointer to
- this procedure in DSEG called CALL32PTR which may be used to execute the call.
- CALL32 and INLINERM are the only 16-bit protected-mode procedures in XLIB.
- They are also the only protected-mode procedures having far returns.
- This procedure does not alter the state of OFLAGS.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 15
-
-
-
-
-
-
- 6. Interrupt Management
-
-
- Interrupt management is the most complicated task performed by XLIB.
- Accordingly, this chapter is the most difficult section of the user's manual.
- In general, this chapter may be ignored for programs which do not install
- interrupt handlers, do not require hot key detection, and do not use floating
- point operations.
-
-
- XLIB Interrupt Handlers
-
-
- XLIB handles nearly all interrupts occurring in protected mode by
- shifting to real mode and calling the currently installed real-mode interrupt
- handlers. In all but three cases, XLIB uses inherited real-mode handlers.
- XLIB installs its own handlers only for the DOS interrupt (INT 21H), the
- keyboard interrupt (INT 9), and the FPU interrupt (INT 75H).
- The DOS interrupt handler (INT 21H) intercepts all DOS calls and
- determines if termination is requested (AH = 4CH). If not, then the interrupt
- is immediately cascaded to DOS. If so, then XLIB performs housecleaning
- before relaying the request to DOS. Under DPMI, XLIB will restore all
- interrupt vectors and release all allocated descriptors. The DPMI host
- automatically releases all allocated memory. Under other configurations, XLIB
- will reset all real-mode interrupt vectors and release all allocated extended
- memory.
- INT 21H function 4CH may be executed in either real mode or protected
- mode. DPMI hosts will expect this function to be executed from protected
- mode; consequently, XLIB will switch to protected mode before relaying the
- request to DPMI. XLIB also installs a protected-mode handler for INT 21H
- under DPMI. This is to ensure that XLIB will see the termination request
- before the DPMI host.
- The keyboard interrupt handler is intended to facilitate termination of
- protected-mode procedures with a keypress. When a user-defined hot key is
- pressed, the keyboard interrupt handler will modify a flag variable. This
- flag variable may then be polled periodically in the main thread of execution.
- The keyboard interrupt handler is a real-mode routine.
- The inconvenience of having to poll the flag variable is unfortunately
- necessary. It is not generally safe to terminate within a hardware interrupt
- handler, particularly in protected-mode environments. A hardware interrupt
- generated by a keypress may have interrupted system software in the middle of
- a system maintenance operation. Termination in such cases would likely leave
- the system in an irregular and potentially unstable state.
- Matters are further complicated in most protected-mode environments. For
- example, a DPMI host will trap all hardware interrupts before cascading them
- to interrupt handlers. If control is not returned to the host with the IRET
- instruction, then the host will be left in an irregular state. Moreover, the
- trapping procedure will likely switch stacks before relaying the interrupt to
- the handler; consequently, the handler cannot determine the final return
- address and therefore cannot change this address to a termination procedure.
- These complications will nearly always occur when hardware interrupts are
- virtualized. Virtual 8086 mode interrupts will almost certainly be
- virtualized in either VCPI-based or DPMI-based environments.
-
-
-
-
- 16
-
-
-
-
-
-
- When a key is pressed, the keyboard interrupt handler will examine the
- key to determine if it is the hot key. If not, then the interrupt is cascaded
- to the inherited real-mode handler. If so, then a hot key flag is recorded to
- a DWORD whose linear address is recorded at CCODEPTR (condition code pointer).
- The hot key is not cascaded. CCODEPTR is a public DWORD in DSEG. The hot key
- flag is listed among XLIB error codes in Appendix B.
- CCODEPTR initially contains the linear address to public DWORD location
- CCODE which is in DSEG. Therefore, the hot key flag would be written to CCODE
- by default. CCODEPTR may be changed by the user; however, it must point to an
- address in conventional memory.
- The hot key specification is stored in DSEG at a public WORD location
- called HOTKEY. The lower byte of HOTKEY contains the scan code of the hot key
- while the upper byte specifies the state of the shift keys. Bit 8 specifies
- the state of SHIFT; bit 9 specifies CTRL, and bit 10 specifies ALT. All other
- bits are ignored. Set bits require that the designated shift key be pressed.
- The default setting for HOTKEY is zero. This setting disables hot key
- detection since no key has a zero scan code.
- The XLIB interrupt handler for FPU exceptions performs three major
- functions upon the occurrence of any FPU exception that is unmasked in the FPU
- control word. First, an error code is loaded to EAX and is also recorded at
- the linear address in CCODEPTR. Next, the FPU is initialized with FNINIT (the
- FPU control word is preserved). Third, control is transferred to EXITPM to
- return to real mode. The high word stored in EAX and the condition code will
- be the FPU status word. This word may be examined to determine the nature of
- the exception. The FPU interrupt handler is a real-mode routine.
- The response of the FPU to exception conditions is largely determined by
- the settings in the FPU control word. If FPU save/restore is enabled, then
- the FPU control word will be set to FPUCW upon execution of CALLPM/ENTERPM.
- The default value for FPUCW is 0332H. This sets rounding control to nearest,
- precision control to 64 bits, and unmasks exceptions for overflow, zero
- divide, and invalid operations. Exceptions for underflow, precision, and
- denormalized operations are masked, and are therefore handled internally by
- the FPU. FPUCW may be modified by the user.
- As explained above, the machine may be left in an unstable state after a
- program has been terminated from within a hardware interrupt handler. This
- can also be the case for the FPU interrupt handler. However, it will be safe
- to continue execution after FPU exceptions under clean configurations. This
- follows because interrupts are not virtualized and because the exception will
- never be generated in the operating system (DOS does not use the FPU). Nor
- should there be any problem with continuing execution after an exception in
- protected-mode under VCPI. This follows since protected-mode interrupts
- cannot be virtualized under VCPI. Exceptions occurring in Virtual 8086 mode
- or under DPMI protected mode may however leave the machine in an irregular
- state. Reboot may be necessary in these cases.
- All tested DPMI hosts appear to be restored to normal state by execution
- of INT 21H function 4CH (DOS termination). However, the DPMI specifications
- offer no guarantees to this approach. FPU exceptions in virtual 8086 mode are
- generally no problem in single-task environments; however, they will
- frequently prove problematic under a multitasker such as DESQview.
- Bit 0 of OFLAGS is used by XLIB to simultaneously enable or disable all
- of its own hardware interrupt handlers. Setting the bit enables the handlers.
- XLIB sets this bit upon calls to CALLPM/ENTERPM and clears the bit upon
- return. All interrupts are immediately cascaded to the inherited real-mode
- handlers when the bit is clear. Therefore, FPU exceptions are handled by XLIB
-
-
-
- 17
-
-
-
-
-
-
- only after calls to CALLPM/ENTERPM. Accordingly, hot key detection is enabled
- only after calls to CALLPM/ENTERPM. The user may set the bit under other
- circumstances; however, XLIB will not be able to properly handle FPU
- exceptions in these cases. The bit should be set by the user only when hot
- key detection is desired and when it is certain that the FPU exception handler
- will not be invoked.
- The FPU exception handler may be permanently disabled by setting bit 1 in
- OFLAGS. If this bit is set, then the FPU interrupt handler simply cascades
- the interrupt to the inherited real-mode handler. XLIB will set the bit
- during initialization if an FPU is not present; it is otherwise cleared.
- Real-mode software interrupts which receive or return values in segment
- registers cannot be used within protected mode because the deflection routine
- will restore selectors to segment registers upon completion of the interrupt.
- To use such software interrupts, one must switch to real mode through CALLRM;
- issue the interrupt, and then transfer the segment registers to other
- registers or to memory before returning to protected mode.
- Certain software interrupts use status flags for return flags, typically
- to signal error conditions. This is particularly the case for DOS interrupts.
- The deflection routine will pass these alterations to the code which issued
- the interrupt.
-
-
- Installation of Interrupt Handlers
-
-
- The user may install real-mode interrupt handlers in usual fashion. Such
- handlers will also receive interrupts occurring in protected mode because
- either XLIB or the DPMI host will deflect all protected-mode interrupts. If
- XLIB deflects the interrupt, then the handler will receive SS = DSEG with ESP
- set to 100H free bytes. Stack sizes under DPMI will depend upon the host, but
- must contain a minimum of 200H free bytes to meet DPMI specifications.
- The DOS routines to get and set interrupt vectors (INT 21H functions 35H
- and 25H) receive and return values through segment registers; consequently,
- they cannot be used in protected mode. Instead, use the XLIB procedures
- PMGETRMIV and PMSETRMIV (protected mode - get/set real-mode interrupt vector).
- The user may install a protected-mode interrupt handler from real mode by
- calling SETPMIV (set protected-mode interrupt vector). The current protected-
- mode interrupt vector may be obtained by calling GETPMIV.
- From protected mode, interrupt vectors can be managed with PMSETPMIV and
- PMGETPMIV. These procedures have the same specifications as SETPMIV and
- GETPMIV.
- Interrupt handlers installed with SETPMIV/PMSETPMIV are never disabled by
- XLIB and will therefore always be active under protected-mode execution.
- These handlers will not be active under real-mode execution in the absence of
- DPMI. That is, real-mode interrupts are never deflected to protected-mode
- handlers in such environments. However if DPMI is active, then all hardware
- interrupts (IRQs 0-15) and the software interrupts: 1CH (BIOS timer tick),
- 23H (DOS CTRL C), and 24H (DOS critical error) are deflected from real mode to
- the installed protected-mode handler. Therefore the protected-mode handler
- always receives the interrupt first. If the handler cascades the interrupt,
- then the real-mode handler will receive it next. If the user has not
- installed protected-mode handlers for these interrupts, then they are serviced
- by default handlers in the DPMI host. The default handlers typically deflect
- the interrupts to the real-mode handlers.
-
-
-
- 18
-
-
-
-
-
-
- If the programmer wishes to install a protected-mode interrupt handler
- for a hardware interrupt or for INT 1CH, INT 23H, or INT 24H, then
- consideration must be given to the fact that treatment of these interrupts
- will differ under different protected-mode configurations. As noted above,
- the DPMI host will always send these interrupts to the protected-mode handler
- regardless of the CPU mode in which the interrupt occurred. If DPMI is not
- installed, then protected-mode handlers receive control only under protected-
- mode interrupts. Therefore, if the protected-mode handler is to receive real-
- mode interrupts under such configurations, the programmer must install a real-
- mode handler to perform the deflection.
- XLIB includes a procedure called DEFLECTPM which can be used within a
- real-mode interrupt handler to deflect control to a protected-mode handler.
- DEFLECTPM functions only under VCPI and XLIB mode switching. If DPMI is
- installed, then the procedure returns with no action. The intent of this
- procedure is to enable simulation of DPMI treatment of hardware interrupts,
- INT 1CH, INT 23H, and INT 24H.
- Observe that if the real-mode handler deflects to the protected-mode
- handler, then the latter should not cascade the interrupt since an infinite
- loop would result. This follows because the initial protected-mode handler
- deflects to the real-mode handler.
- Were one to use DEFLECTPM in a real-mode handler for the interrupts named
- above, then the protected-mode handler will receive all interrupts regardless
- of the protected-mode configuration. This occurs naturally under DPMI.
- DEFLECTPM ensures that it will occur under other configurations. Observe that
- under DPMI, the real-mode handler will never be executed.
- It is sometimes important that interrupt handlers execute in shortest
- possible CPU time. This would typically be the case for handlers of the
- communication ports. Since mode switching is time consuming, such handlers
- should be installed for the CPU mode which is expected to receive the most
- interrupts.
- If DPMI is installed, then it is possible for multiple clients to operate
- in a single virtual machine. In such cases, DPMI will always send hardware
- interrupts to the primary client (the most recently installed client in the
- virtual machine).
- Under DPMI, all protected-mode handlers for hardware interrupts and
- software interrupts 0-7 will receive control with interrupts disabled. Since
- DPMI virtualizes the interrupt flag, the IRET instruction may not reenable
- interrupts. Consequently, all handlers for these interrupts should execute
- STI before executing IRET. Other protected-mode interrupts do not affect the
- interrupt flag.
- All real-mode interrupt handlers will receive control with interrupts
- disabled regardless of the protected-mode configuration. All protected-mode
- handlers will receive control with interrupts disabled under VCPI or XLIB mode
- switching. However, if DPMI is installed, then protected-mode software
- interrupts apart from 0-7 will receive the virtual interrupt flag at its value
- as of the INT instruction. That is, DPMI does not alter the interrupt flag in
- these cases.
- Hardware interrupts IRQ 0 through IRQ 7 are typically assigned to
- interrupt numbers 08H through 0FH, while IRQs 8 through 15 are typically
- assigned interrupt numbers 70H through 77H. However, IRQs are remapped in
- some operating environments, typically to facilitate exception handling. The
- current mappings may be loaded from IRQ0INTNO (IRQ 0 interrupt number) and
- IRQ8INTNO. These are public BYTE locations in DSEG. They should be read only
- after the call to INITXLIB.
-
-
-
- 19
-
-
-
-
-
-
- DESQview does remap hardware interrupts; however, its interrupt handlers
- for the new locations generally transfer control to the addresses at the
- conventional vectors. DESQview must be started with a command-line switch if
- it is to accommodate certain hardware interrupts. In particular, the FPU
- interrupt will not function properly under DESQview unless DESQview is started
- with DV /HW:75:C.
-
-
- Detailed Specifications
-
-
- PMGETRMIV (Protected Mode - Get Real-Mode Interrupt Vector)
- Purpose: Retrieve address of real-mode interrupt handler from protected mode.
- CPU Mode: Protected
- Registers at Call: AL = interrupt number.
- Return Registers: Handler address returned in CX:DX.
- Details: The DOS routine for this purpose (INT 21H function 35H) is not
- useful because it returns a value in ES.
-
- PMSETRMIV (Protected Mode - Set Real-Mode Interrupt Vector)
- Purpose: Set address of real-mode interrupt handler from protected mode.
- CPU Mode: Protected
- Registers at Call: AL = interrupt number, CX:DX = address of handler.
- Return Registers: None
- Details:
- The DOS routine for this purpose (INT 21H function 25H) is not useful
- because it requires an argument in DS.
- Real-mode interrupt handlers will also be called when interrupts occur in
- protected mode provided that the protected-mode interrupt handler cascades the
- interrupt. The default protected-mode handlers do in fact cascade all
- interrupts.
- XLIB never disables handlers installed by this procedure.
-
- GETPMIV (Get Protected-Mode Interrupt Vector)
- Purpose: Retrieve address of protected-mode interrupt handler from interrupt
- descriptor table.
- CPU Mode: Real
- Registers at Call: AL = interrupt number.
- Return Registers: Handler address returned in CX:EDX (CX is a selector).
- Details: This routine does not return addresses of CPU exception handlers
- under DPMI. Use DPMI functions directly for this purpose.
-
- SETPMIV (Set Protected-Mode Interrupt Vector)
- Purpose: Set address of protected-mode interrupt handler in interrupt
- descriptor table.
- CPU Mode: Real
- Registers at Call: AL = interrupt number. Handler address in CX:EDX (CX is a
- selector).
- Return Registers: EAX = 0 if successful. EAX = error code if unsuccessful.
- AX = XLIB error code. If DPMI is installed then the high word of EAX will
- contain a DPMI 1.0 error code (if provided by host).
- Details:
- XLIB never disables handlers installed by this procedure.
-
-
-
-
- 20
-
-
-
-
-
-
- Protected-mode interrupt handlers never receive interrupts occurring in
- real mode unless DPMI is active. Under DPMI all hardware interrupts (IRQs 0-
- 15) and software interrupts 1CH, 23H, and 24H are deflected from real mode to
- the installed protected-mode handler. The protected-mode handler therefore
- receives control of the interrupt first. It may cascade the interrupt if so
- desired, in which event, the real-mode handler receives the interrupt next. If
- no protected-mode handler has been installed, then DPMI generally deflects the
- interrupt to the real-mode handler.
- All protected-mode handlers will receive control with interrupts disabled
- unless DPMI is installed. Under DPMI, protected-mode software interrupts
- apart from 0-7 do not alter the state of the virtual interrupt flag.
- Protected-mode handlers under DPMI for hardware interrupts and software
- interrupts 0-7 should execute STI before IRET to ensure that the virtual
- interrupt flag is enabled.
- If multiple DPMI clients are running in the same virtual machine, then the
- primary client (most recently installed client) always receives hardware
- interrupts.
- If DPMI is installed, then protected-mode interrupt vectors should be reset
- to original values before termination.
- This routine should not be used to install CPU exception handlers under
- DPMI. DPMI functions should be used for this purpose.
-
- PMGETPMIV (Protected Mode - Get Protected-Mode Interrupt Vector)
- Purpose: Retrieve address of protected-mode interrupt handler from interrupt
- descriptor table.
- CPU Mode: Protected
- Details: This routine is the protected-mode version of GETPMIV. See GETPMIV
- for specifications.
-
- PMSETPMIV (Protected Mode - Set Protected-Mode Interrupt Vector)
- Purpose: Set address of protected-mode interrupt handler in interrupt
- descriptor table.
- CPU Mode: Protected
- Details: This routine is the protected-mode version of SETPMIV. See SETPMIV
- for specifications.
-
- DEFLECTPM (Deflect to Protected-Mode)
- Purpose: Call a protected-mode interrupt handler.
- CPU Mode: Real
- Registers at Call: SS:ESP = interrupt number (2 bytes)
- Return Registers: All registers except segment registers and ESP are returned
- at values as of the protected-mode IRET instruction.
- Details:
- This procedure can be used only under VCPI and XLIB mode switching. It
- returns with no action under DPMI. The routine is intended to simulate DPMI
- treatment of hardware interrupts, INT 1CH, INT 23H, and INT24H. The routine
- may be called from a real-mode interrupt handler to deflect the interrupt to
- the protected-mode handler.
- The protected-mode handler should not cascade the interrupt; otherwise, an
- infinite loop will result.
-
-
-
-
-
-
-
- 21
-
-
-
-
-
-
- 7. Memory Management
-
-
- XLIB supplies memory management procedures for both real and protected
- modes. These procedures are configured at initialization to work with the
- currently resident memory management interfaces.
- Conventional memory may be allocated and released in real mode through
- DOS in usual fashion (INT 21H functions 48H and 49H). However, DOS functions
- may not work properly in protected mode. Therefore, use the XLIB routines
- PMGETDOSMEM and PMFREEDOSMEM for such requests. PMFREEDOSMEM can also be used
- to find the amount of available DOS memory.
- The real-mode extended memory management procedures are GETMEM, FREEMEM,
- and RESETMEM. GETMEM is used to allocate a block of extended memory. FREEMEM
- may then be used to release the block. RESETMEM releases all previously
- allocated blocks at once. GETMEM may also be used to find the amount of
- available extended memory.
- The protected-mode memory management procedures are PMGETMEM, PMFREEMEM,
- and PMRESETMEM. These procedures function exactly as the corresponding real-
- mode procedures: GETMEM, FREEMEM, and RESETMEM.
- XLIB will seek extended memory through XMS only if it is present and if
- both DPMI and VCPI are absent. If either protected-mode interface is present,
- then all extended memory will be allocated through the configured interface.
- XLIB will not use XMS to allocate memory from the high memory area (HMA)
- or from upper memory blocks (UMBs). XLIB will however allocate from the HMA
- when it has full responsibility for extended memory management (DPMI, VCPI,
- and XMS are all absent). XLIB never issues calls under the Expanded Memory
- Specification (EMS).
-
-
- Detailed Specifications
-
-
- PMGETDOSMEM (Protected Mode - Get DOS Memory)
- Purpose: Allocate DOS memory block.
- CPU Mode: Protected
- Registers at Call: EAX = desired size of block in bytes.
- Return Registers:
- EAX = 0 if successful. A block handle is returned in EBX. The number of
- allocated bytes is returned in ECX. The linear address of allocated block is
- returned in EDX.
- EAX = error code if unsuccessful. AX = XLIB error code. The high word of
- EAX (EAH) will be set to a DOS error code. If DPMI is active, then EAH will
- be a DPMI error code (codes are supplied by DPMI .9 and up).
- Details:
- The block will always be paragraph aligned and will have size equal to an
- integer multiple of 16.
- Call with EAX = 0 to get largest available DOS memory block (not total free
- memory) in ECX (EAX, EBX, and EDX are preserved).
- If DPMI is active, then the handle is actually a selector with base address
- set to the linear address of the block. If DPMI is not active, then the
- handle will be the segment of the block.
- In real mode, DOS memory may be allocated directly from DOS (INT 21H
- function 48H); however, this call will likely fail under DPMI protected mode.
-
-
-
-
- 22
-
-
-
-
-
-
- PMFREEDOSMEM (Protected Mode - Free DOS Memory)
- Purpose: Release previously allocated DOS memory block.
- CPU Mode: Protected
- Registers at Call: EAX = block handle.
- Return Registers: EAX = 0 if successful; otherwise, EAX = error code. AX =
- XLIB error. The high word of EAX (EAH) will be a DOS error code. If DPMI is
- active, then EAH will equal a DPMI error code (codes are supplied by DPMI .9
- and up).
- Details: In real mode, DOS memory may be released directly by DOS (INT 21H
- function 49H); however, this call will likely fail under DPMI protected mode.
-
- GETMEM (Get Memory)
- Purpose: Allocate extended memory block.
- CPU Mode: Real
- Registers at Call: EAX = desired size of block in bytes.
- Return Registers:
- EAX = 0 if successful. A block handle is returned in EBX. The number of
- allocated bytes is returned in ECX. The logical address of allocated block is
- returned in EDX.
- EAX = error code if unsuccessful. AX = XLIB error code. If DPMI is
- active, then the high word of EAX (EAH) will be a DPMI 1.0 error code (if
- provided by host). If XMS is active, then EAH = XMS error code.
- Details:
- The page size for extended memory allocations is contained in PAGESIZE.
- PAGESIZE is a DWORD in DSEG and should be read after initialization. The
- blocks will have addresses that are PAGESIZE aligned and will have sizes equal
- to an integer multiple of PAGESIZE. PAGESIZE will equal: 1024 for XMS, 4096
- for VCPI, 4096 for most DPMI hosts, and 16 in the absence of a memory manager.
- If XMS is present in conjunction with either DPMI or VCPI, no extended
- memory will be requested through XMS. All extended memory will be requested
- through the active protected-mode interface.
- XMS is never used to allocate from the HMA or from UMBs. XLIB will however
- allocate from the HMA in the absence of a memory management interface.
- Call with EAX = 0 to get largest available extended memory block (not total
- free memory) in ECX (EBX and EDX are preserved). This call can also return
- with an error condition in EAX.
-
- FREEMEM (Free Memory)
- Purpose: Release previously allocated extended memory block.
- CPU Mode: Real
- Registers at Call: EAX = block handle.
- Return Registers: EAX = 0 if successful; otherwise, EAX = error code. AX =
- XLIB error code. If DPMI is active, then the high word of EAX (EAH) will be a
- DPMI 1.0 error code (if provided by host). If XMS is active, then EAH = XMS
- error code.
- Details: FREEMEM does not release page tables allocated under VCPI. Call
- RESETMEM for this purpose.
-
- RESETMEM (Reset Memory)
- Purpose: Release all previously allocated extended memory.
- CPU Mode: Real
- Registers at Call: None
- Return Registers: EAX = 0 if successful; otherwise, EAX = error code. AX =
- XLIB error code. If DPMI is active, then the high word of EAX (EAH) will be a
-
-
-
- 23
-
-
-
-
-
-
- DPMI 1.0 error code (if provided by host). If XMS is active, then EAH = XMS
- error code.
- Details:
- GETMEM will automatically allocate page tables as needed under VCPI.
- RESETMEM will release such tables.
- If DPMI is not installed, then RESETMEM will be called upon execution of
- INT 21H function 4C (DOS termination). DPMI hosts reset extended memory
- automatically.
-
- PMGETMEM (Protected Mode - Get Memory)
- Purpose: Allocate extended memory block while in protected mode.
- CPU Mode: Protected
- Details: This routine is the protected-mode version of GETMEM. See GETMEM
- for specifications.
-
- PMFREEMEM (Protected Mode - Free Memory)
- Purpose: Free previously allocated extended memory block while in protected
- mode.
- CPU Mode: Protected
- Details: This routine is the protected-mode version of FREEMEM. See FREEMEM
- for specifications.
-
- PMRESETMEM (Protected Mode - Reset Memory)
- Purpose: Free all previously allocated extended memory while in protected
- mode.
- CPU Mode: Protected
- Details: This routine is the protected-mode version of RESETMEM. See
- RESETMEM for specifications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 24
-
-
-
-
-
-
- 8. File Management
-
-
- XLIB file management procedures are low-level routines with powerful
- capabilities. These routines can load files to extended memory or save
- extended memory to files. They can read and write files either sequentially
- or randomly.
- All XLIB file management routines will receive and return values in a
- contiguous block of memory called a "file control block" (not to be confused
- with DOS file control blocks). The file control block must be located in
- conventional memory and must have the form presented in Table 4.
-
-
- Table 4: XLIB File Control Block Structure
- ------------------------------------------------------------------------------
- Field Name Field Type Field Description
- ---------- ---------- -----------------
- CONDCODE DWORD Condition code from file operation
- FNAME BYTE[68] File path and name (zero terminated string)
- FHANDLE WORD File handle assigned by DOS
- FPTRMODE WORD File pointer mode
- FPTR DWORD File pointer
- BLKADR DWORD Memory source/destination address
- BLKSIZE DWORD Size of transfer block in bytes
- BUFADR DWORD Buffer address (conventional memory address)
- BUFSIZE WORD Buffer size in bytes
- CONTROL WORD Control word
- ------------------------------------------------------------------------------
-
- CONDCODE is used to return error codes. CONDCODE should be situated at
- the starting address of the control block.
- FNAME is a zero-terminated ASCII string defining the file path and name.
- There cannot be more than 67 characters in this string, excluding the
- termination character.
- BLKADR and BLKSIZE define the source/destination memory block for the
- transfer. This block may be in either conventional or extended memory.
- BLKADR is a linear address.
- XLIB uses DOS to access the disk. DOS cannot read or write to extended
- memory; consequently, a conventional memory buffer must be set up for the DOS
- transfers. File management routines shift to protected mode to perform
- transfers between the buffer and the source/destination memory. BUFADR and
- BUFSIZE define the conventional memory buffer. BUFADR is a linear address.
- For fastest transfers, the memory block and the buffer should be DWORD
- aligned and should have sizes equal to an integer multiple of 16.
- FPTR and FPTRMODE specify the file pointer setting to be used before
- transfers to or from the disk. FPTRMODE specifies how FPTR is to be
- interpreted. The following values are valid for FPTRMODE:
-
-
- FPTRMODE FPTR Interpretation
- 0 Unsigned offset from the beginning of the file
- 1 Signed offset from the current file pointer
- 2 Signed offset from the end of the file
- 3 FPTR is ignored. Use current file pointer (sequential mode)
-
-
-
- 25
-
-
-
-
-
-
-
-
- CONTROL is not used in the present version of XLIB. Set all bits in
- CONTROL to zero.
- In assembly language or C, the file control block would typically be
- defined by a structure. In BASIC, the file control block can be defined with
- a user defined type.
- Values are transferred to and from all file routines in EAX and in the
- file control block. All routines should be called with the linear address of
- the file control block in EAX. All routines return with two copies of the
- error code; one in EAX and one in the condition code of the file control
- block. A zero error code indicates successful execution.
- Since these routines perform disk operations, special precautions should
- be taken to ensure that parameters in the file control block are properly
- defined before performing calls. In particular, one should always make sure
- that the source/destination memory block and the conventional memory buffer
- are properly defined. A safe rule is to simply set the buffer size to zero
- because this forces XLIB to supply a buffer when opening or creating the file.
-
-
- Detailed Specifications
-
-
- XCREATE (Create File)
- Purpose: Create and open a new file of specified name in specified directory.
- CPU Mode: Real
- Registers at Call: EAX = linear address of file control block.
- Control Block at Call: FNAME = file path and name.
- Return Registers: EAX = error code. AX = XLIB error code. If a DOS error
- occurred, then the high word of EAX will be set to the DOS error code.
- Control Block at Return: CONDCODE = error code. If CONDCODE = 0, then
- FHANDLE = file handle assigned by DOS. If the procedure is called with
- BUFSIZE = 0, then XLIB will set BUFADR and BUFSIZE to its own internal buffer.
- Details:
- If the file already exists, then it will be truncated to zero length.
- The size and location of the internal buffer will depend upon how XLIB was
- initialized. If DPMI is active, then the buffer will be slightly larger than
- 2K; otherwise, the buffer will be slightly larger than 1K. The linear address
- and size of the buffer may be obtained from FILEBUFADR (DWORD), and
- FILEBUFSIZE (WORD) in DSEG.
- Files created by this routine will be given both read and write access.
- This routine uses INT 21H function 3CH to create the file.
-
- XOPEN (Open File)
- Purpose: Open existing file of specified name in specified directory.
- CPU Mode: Real
- Registers at Call: EAX = linear address of file control block.
- Control Block at Call: FNAME = file path and name.
- Return Registers: EAX = error code. AX = XLIB error code. If a DOS error
- occurred, then the high word of EAX will be set to the DOS error code.
- Control Block at Return: CONDCODE = error code. If CONDCODE = 0, then
- FHANDLE = file handle assigned by DOS. If the procedure is called with
- BUFSIZE = 0, then XLIB will set BUFADR and BUFSIZE to its own internal buffer.
- Details:
-
-
-
- 26
-
-
-
-
-
-
- The file is opened for both read and write access.
- The size and location of the internal buffer will depend upon how XLIB was
- initialized. If DPMI is active, then the buffer will be slightly larger than
- 2K; otherwise, the buffer will be slightly larger than 1K. The linear address
- and size of the buffer may be obtained from FILEBUFADR (DWORD), and
- FILEBUFSIZE (WORD) in DSEG.
- This routine uses INT 21H function 3DH to open the file.
-
- XCLOSE (Close File)
- Purpose: Close previously opened file.
- CPU Mode: Real
- Registers at Call: EAX = linear address of file control block.
- Control Block at Call: FHANDLE = file handle.
- Return Registers: EAX = error code. AX = XLIB error code. If a DOS error
- occurred, then the high word of EAX will be set to the DOS error code.
- Control Block at Return: CONDCODE = error code.
- Details: This routine uses INT 21H function 3EH to close the file.
-
- XSAVE (Save File)
- Purpose: Create file with contents equal to specified memory block.
- CPU Mode: Real
- Registers at Call: EAX = linear address of file control block.
- Control Block at Call: FNAME = file path and name. BLKADR/BLKSIZE = address
- and size of memory block to provide file contents. BUFADR/BUFSIZE = address
- and size of conventional memory buffer.
- Return Registers: EAX = error code. AX = XLIB error code. If a DOS error
- occurred, then the high word of EAX will be set to the DOS error code.
- Control Block at Return: CONDCODE = error code.
- Details:
- The file cannot already be open. The file is both created and closed by
- this routine.
- This routine will replace any previously existing file named FNAME.
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- This routine transfers the source memory to the file through the buffer.
- Transfers from buffer to disk are accomplished with INT 21H function 40H.
-
- XLOAD (Load File)
- Purpose: Load file contents to specified memory block.
- CPU Mode: Real
- Registers at Call: EAX = linear address of file control block.
- Control Block at Call: FNAME = file path and name. BLKADR/BLKSIZE = address
- and size of memory block to receive file contents. BUFADR/BUFSIZE = address
- and size of conventional memory buffer.
- Return Registers: EAX = error code. AX = XLIB error code. If a DOS error
- occurred, then the high word of EAX will be set to the DOS error code.
- Control Block at Return: CONDCODE = error code. If CONDCODE = 0, then
- BLKSIZE = actual number of bytes transferred.
- Details:
- The file cannot already be open. The file is both opened and closed by
- this routine.
- The value of BLKSIZE as of call is interpreted as an upper limit on the
- number of bytes to transfer. The entire file is loaded provided that it does
- not contain more than BLKSIZE bytes.
-
-
-
- 27
-
-
-
-
-
-
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- This routine uses INT 21H function 3FH to transfer the disk contents to the
- buffer. It then transfers the buffer contents to the destination memory.
-
- XWRITE (Write to File)
- Purpose: Write specified memory block to specified location in open file.
- CPU Mode: Real
- Registers at Call: EAX = linear address of file control block.
- Control Block at Call: FHANDLE = file handle. FPTR/FPTRMODE = file pointer
- setting for beginning of transfer. BLKADR/BLKSIZE = address and size of
- memory block to provide file contents. BUFADR/BUFSIZE = address and size of
- conventional memory buffer.
- Return Registers: EAX = error code. AX = XLIB error code. If a DOS error
- occurred, then the high word of EAX will be set to the DOS error code.
- Control Block at Return: CONDCODE = error code.
- Details:
- The file must be opened with XOPEN or XCREATE before using this routine.
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- This routine uses INT 21H function 42H to set the file pointer. The source
- memory is then transferred through the buffer to disk. Transfers from buffer
- to disk are accomplished with INT 21H function 40H.
- Sequential transfers should set FPTRMODE = 3 for fastest execution.
-
- XREAD (Read From File)
- Purpose: Write to specified memory block from specified location in open
- file.
- CPU Mode: Real
- Registers at Call: EAX = linear address of file control block.
- Control Block at Call: FHANDLE = file handle. FPTR/FPTRMODE = file pointer
- setting for beginning of transfer. BLKADR/BLKSIZE = address and size of
- memory block to receive file contents. BUFADR/BUFSIZE = address and size of
- conventional memory buffer.
- Return Registers: EAX = error code. AX = XLIB error code. If a DOS error
- occurred, then the high word of EAX will be set to the DOS error code.
- Control Block at Return: CONDCODE = error code.
- Details:
- The file must be opened with XOPEN or XCREATE before using this routine.
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- This routine uses INT 21H function 42H to set the file pointer. The file
- contents are then transferred to the destination memory through the buffer.
- The file contents are transferred to the buffer using INT 21H function 3FH.
- Sequential transfers should set FPTRMODE = 3 for fastest execution.
-
-
-
-
-
-
-
-
-
-
-
-
- 28
-
-
-
-
-
-
- 9. Descriptor Management
-
-
- All selectors in Table 1 up to DGROUPSEL are used by XLIB procedures;
- consequently, the corresponding descriptors should never be changed. However,
- descriptors for the other selectors may be modified. XLIB includes a
- procedure called SETDESC (set descriptor) to facilitate such modifications. A
- second routine called PMSETDESC is the protected-mode version of SETDESC.
- Descriptors corresponding to the inline selectors should not be changed
- in programs which also use the inline mode-switch procedures.
-
-
- Detailed Specifications
-
-
- SETDESC (Set Descriptor)
- Purpose: Change a descriptor in the local descriptor table.
- CPU Mode: Real
- Registers at Call: BX = selector. EDX:EAX = the new descriptor.
- Return Registers: EAX = error code. AX = XLIB error code. If DPMI is
- installed, then the high word of EAX will equal a DPMI 1.0 error code (if
- provided by host). EDX may be returned with some modifications to the access
- rights bits.
- Details:
- The access rights bits in EDX will be edited before installation of the
- descriptor. In particular: The application bit will be set to indicate an
- application segment (rather than a system segment). Reserved bits will be
- given proper settings. The descriptor privilege level will be set to the
- appropriate value. If the descriptor corresponds to a code segment, then the
- descriptor will also be marked as readable and nonconforming.
- Segment registers which are loaded with the current value of the descriptor
- will not necessarily be reloaded when the descriptor is changed.
-
- PMSETDESC (Protected Mode - Set Descriptor)
- Purpose: Change a descriptor in the local descriptor table.
- CPU Mode: Protected
- Details: This routine is the protected-mode version of SETDESC. See SETDESC
- for details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 29
-
-
-
-
-
-
- 10. Using XLIB in High-Level Language Libraries
-
-
- The following program illustrates the usage of XLIB in libraries called
- from Microsoft BASIC 7.0. The library contains a protected-mode procedure
- which sums the elements in a single precision array created within BASIC. The
- general methodology here is recommended for developing assembly language
- libraries.
- Since BASIC cannot call a 32-bit segment, a real-mode interface procedure
- must be placed in a 16-bit segment to receive the BASIC call and then transfer
- execution to 32-bit protected mode. The interface procedure is call SUMARRAY
- while the 32-bit protected-mode procedure which actually sums the array
- elements is called SUMARRAY32.
- BASIC must pass certain arguments to the library procedures. These
- include the array address and the number of elements to be summed. These
- arguments could be passed on the stack; however, such approach proves awkward
- since the stack must be changed when entering protected mode. Consequently,
- BASIC places all arguments in a contiguous block of memory called a "control
- block," and then passes only the address of the control block to the library.
- BASIC constructs the control block with a user-defined type.
- The first four bytes of the control block are reserved for placement of
- error codes by the library procedures. Also, the address of the control block
- is placed in CCODEPTR so that any FPU exceptions will be signalled in the
- error code location as well. Were an FPU exception to occur, the FPU
- interrupt handler will immediately transfer control to EXITPM which will shift
- to real-mode, restore registers, and return control to the BASIC caller.
- The library also contains a real-mode function called LINADR which may be
- called by BASIC to convert segment addresses to linear addresses.
- An example of this same program for Microsoft C 7.0 is included in
- Appendix E.
-
-
- Example 3: Calling Protected-Mode Libraries From BASIC
- -----------------------------------------------------------------------------
- +++++++++++++++++++++++++
- + ASSEMBLY CODE LIBRARY +
- +++++++++++++++++++++++++
-
-
- ;The following library should be combined with XLIB.LIB using the Microsoft
- ;LINK and LIB utilities. If BASIC is to be executed from the QBX
- ;environment, then a quick library must be loaded with the environment. See
- ;BASIC documentation for instructions.
-
-
- .MODEL LARGE,PASCAL
- .386P
-
- INCLUDE XLIB.INC
-
-
-
-
-
-
-
-
- 30
-
-
-
-
-
-
- CSEG SEGMENT PARA PUBLIC USE16 'CODE'
- ASSUME CS:CSEG, DS:DSEG
-
- ;Function to calculate linear address from segment address on stack.
- ;Returns linear address in DX:AX.
- LINADR PROC FAR PUBLIC,
- SEGADR:DWORD ;Segment address of variable
- XOR EAX,EAX ;Clear high words
- XOR EDX,EDX
- MOV AX,WORD PTR SEGADR[0]
- MOV DX,WORD PTR SEGADR[2]
- SHL EDX,4 ;Calculate linear address
- ADD EDX,EAX
- MOV AX,DX
- SHR EDX,16 ;Return linear address in DX:AX
- RET
- LINADR ENDP
-
- ;Structure defining control block for SUMARRAY.
- ARRAYDATA STRUCT
- CONDCODE DWORD 0 ;Condition code
- N DWORD 0 ;Number of elements to sum
- ADDRESS DWORD 0 ;Address of first element
- SUM DWORD 0 ;Sum of array elements
- ARRAYDATA ENDS
-
- ;Real-mode interface to SUMARRAY32. Segment address of control block having
- ;structure ARRAYDATA should be on the stack.
- SUMARRAY PROC FAR PUBLIC,
- CBSEGADR:DWORD ;Control block segment address
- PUSH DS
- PUSHW DSEG
- POP DS
- XOR EAX,EAX ;Clear high words
- XOR EDX,EDX
- MOV AX,WORD PTR CBSEGADR[2]
- MOV DX,WORD PTR CBSEGADR[0]
- SHL EAX,4 ;Calculate linear address
- ADD EAX,EDX
- MOV CCODEPTR,EAX ;Reset condition code address
- POP DS ;Pop calling DS
- PUSHD OFFSET SUMARRAY32
- CALL ENTERPM ;Execute SUMARRAY32 in protected
- RET
- SUMARRAY ENDP
-
- CSEG ENDS
-
-
-
-
-
-
-
-
-
-
- 31
-
-
-
-
-
-
- TSEG SEGMENT PARA PUBLIC USE32 'CODE'
- ASSUME CS:TSEG, SS:TSEG, DS:TSEG, ES:TSEG, FS:DSEG, GS:DGROUP
-
- ;Sum the elements of a single precision array. Array parameters are stored
- ;in a control block having structure of ARRAYDATA. The linear address of the
- ;control block is stored at CCODEPTR. An error code of -1 is returned in the
- ;condition code of the control block if the number of array elements is zero.
- ;XLIB places an error code in the control block if an FPU exception occurs
- ;while calculating the sum. This error code will have the FPU status word in
- ;the high word and the XLIB FPU error code in the low word. Observe that this
- ;routine will be called with DS = FLATDSEL (flat-model data descriptor) and
- ;FS = DSEGSEL (DSEG data descriptor).
- SUMARRAY32 PROC NEAR
- MOV EBX,FS:CCODEPTR ;Get control block
- MOV EDX,ARRAYDATA.ADDRESS[EBX] ;Get array address
- MOV ESI,ARRAYDATA.N[EBX] ;Get N
- SUB ESI,1
- JB NODATA ;Error: N = 0
- FLDZ ;Initialize sum
- SUMLOOP: FADD DWORD PTR [EDX+4*ESI]
- SUB ESI,1
- JAE SUMLOOP
- FSTP ARRAYDATA.SUM[EBX] ;Save sum
- RET
- NODATA: MOV ARRAYDATA.CONDCODE[EBX],-1 ;Record error code
- RET
- SUMARRAY32 ENDP
-
- TSEG ENDS
- END
-
-
- +++++++++++++++++++++
- + BASIC MAIN MODULE +
- +++++++++++++++++++++
-
-
- 'The following Microsoft BASIC 7.0 program should be linked with the above
- 'library. The BASIC program first initializes XLIB. Next, it creates a
- 'single precision array. A control block for SUMARRAY is then constructed
- 'and the call to SUMARRAY is executed. Finally, the condition code in the
- 'control block is inspected and results are printed.
-
- DEFINT A-Z
-
- 'Declare XLIB procedures
- DECLARE FUNCTION XLIBMEMREQ& ()
- DECLARE FUNCTION INITXLIB& ()
- DECLARE FUNCTION XLIBCONFIG% ()
-
- 'Declare procedures in the library linked with XLIB
- DECLARE FUNCTION LINADR& (SEG VARIABLE AS ANY)
- DECLARE SUB SUMARRAY (SEG VARIABLE AS ANY)
-
-
-
-
- 32
-
-
-
-
-
-
- 'Structure for the control block
- TYPE ARRAYDATA
- CONDCODE AS LONG 'Location to receive any error codes
- N AS LONG 'Number of elements to be summed
- ADDRESS AS LONG 'Linear address of the array
- SUM AS SINGLE 'Location for array sum
- END TYPE
-
- 'Check XLIBCONFIG to see if XLIB has already been initialized. If not then
- 'call XLIBMEMREQ to find amount of conventional memory needed by XLIB and
- 'release at least this amount with the BASIC SETMEM function. XLIBMEMREQ
- 'returns with sign bit of DX set if an error occurred. The error is then
- 'identified by AX. XLIB will not be terminated upon completion of this
- 'program in the Microsoft QBX environment; therefore, initialization is
- 'required only once within the environment.
- IF XLIBCONFIG = 0 THEN
- TEMP& = XLIBMEMREQ
- IF TEMP& >= 0& THEN
- IF TEMP& > 0 THEN TEMP& = SETMEM(-TEMP& - 16&)
- TEMP& = INITXLIB 'INITXLIB error code returned in TEMP&
- ELSE
- TEMP& = TEMP& AND &H7FFFFFFF 'Mask sign bit to leave error code only
- END IF
- IF TEMP& THEN
- PRINT "Library initialization error: "; HEX$(TEMP&)
- END
- END IF
- END IF
-
- DIM A(100) AS SINGLE
- DIM AD AS ARRAYDATA
-
- FOR I = 0 TO 100 'Assign numbers to array
- A(I) = I
- NEXT I
-
- AD.CONDCODE = 0& 'Clear the error code
- AD.N = 50& 'Sum first 50 elements
- AD.ADDRESS = LINADR(A(0)) 'Calculate and record linear address of A(0)
-
- CALL SUMARRAY(AD)
-
- IF AD.CONDCODE THEN
- PRINT "Error: ";HEX$(AD.CONDCODE)
- ELSE
- PRINT "Sum: ";AD.SUM 'Should equal 1225
- ENDIF
-
- END
- -----------------------------------------------------------------------------
-
-
-
-
-
-
-
- 33
-
-
-
-
-
-
- Appendix A: Description of XLIB Public Data
-
-
- The following is a summary of most public symbols located in the XLIB
- data segment DSEG. This summary excludes the symbols presented in tables one
- through three. All XLIB symbols conform to the PASCAL naming convention.
-
- Symbol: CALL32PTR (CALL32 Pointer)
- Symbol Type: DWORD
- Default Setting: Far 16-bit protected-mode address of CALL32 procedure
- Description: This location is a pointer to the CALL32 procedure and is
- included to facilitate intersegment calls. The contents of the location
- should not be changed.
-
- Symbols: CCODEPTR/CCODE (Condition Code Pointer/Condition Code)
- Symbol Types: DWORD/DWORD
- Default Settings: CCODEPTR = linear address of CCODE. CCODE = 0.
- Descriptions: XLIB interrupt handlers will place flags in the condition code
- to signal the occurrence of the interrupt. Flags are placed for FPU
- exceptions and hot key presses. CCODEPTR initially contains the linear
- address of CCODE. CCODEPTR may be changed by the user, but must point to a
- DWORD in conventional memory. The user is responsible for initializing the
- condition code.
-
- Symbols: CSEGVAL, TSEGVAL, DSEGVAL, DGROUPVAL (Segment Values)
- Symbol Types: WORD
- Default Settings: CSEG, TSEG, DSEG, DGROUP
- Descriptions: These are memory locations initialized to the respective
- segment values. Code in TSEG should not contain segment constants since DOS
- may not be able to handle them in relocation edits. Read these locations to
- get segment values. User segments should be handled the same way. These
- locations should not be changed.
-
- Symbols: FILEBUFADR/FILEBUFSIZE (File Buffer Specifications)
- Symbol Types: DWORD/WORD
- Default Settings: Varies with operating environment
- Descriptions: FILEBUFADR contains the linear address of the internal file
- buffer in XLIB. FILEBUFSIZE contains the size of the buffer in bytes. This
- buffer is used only by the file management routines. The size and location of
- the buffer will depend upon the operating environment. If DPMI is active,
- then the buffer will be slightly larger than 2K; it is otherwise slightly
- larger than 1K. These location should be read only after initialization.
-
- Symbol: FPUCW (Floating Point Unit Control Word)
- Symbol Type: WORD
- Default Setting: 0332H
- Description: FPUCW is optionally loaded to the FPU control word by CALLPM and
- ENTERPM. The default sets rounding control to nearest, precision control to
- 64 bits, and unmasks exceptions for overflow, zero divide, and invalid
- operations. Exceptions for underflow, precision, and denormalized operations
- are masked, and are therefore handled internally by the FPU. Set bit 2 of
- OFLAGS to enable FPU save/restore and load of FPUCW.
-
-
-
-
-
- 34
-
-
-
-
-
-
- Symbol: HOTKEY (Hot Key)
- Symbol Type: WORD
- Default Setting: 0H
- Description: HOTKEY specifies the hot key for the keyboard interrupt handler.
- The low byte of HOTKEY specifies the scan code for the key. The upper byte
- specifies the state of the shift keys. Bit 8 specifies SHIFT; bit 9 specifies
- CTLR, and bit 10 specifies ALT. Set bits mean that the designated key must be
- pressed. All other bits are ignored. When the hot key is pressed, the XLIB
- keyboard interrupt handler will record the hot key flag at the DWORD whose
- linear address is stored at CCODEPTR. The default setting for HOTKEY is 0.
- This setting effectively disables hot key detection since no key has a zero
- scan code.
-
- Symbol: IFLAGS (Initialization Flags)
- Symbol Type: WORD
- Default Setting: 0
- Description: IFLAGS is used by INITXLIB to control the initialization
- process. Bit 0 of IFLAGS determines DPMI/VCPI priority in the event that both
- interfaces are present. If this bit is clear then DPMI will be installed in
- such cases. The other bits are reserved.
-
- Symbol: INLINERMPTR (INLINERM Pointer)
- Symbol Type: DWORD
- Default Setting: Far 16-bit protected-mode address of INLINERM procedure
- Description: This location is a pointer to the INLINERM procedure and is
- included to facilitate intersegment calls. The contents of the location
- should not be changed.
-
- Symbols: IRQ0INTNO/IRQ8INTNO (IRQ X Interrupt Number)
- Symbol Types: BYTE/BYTE
- Default Settings: Varies with operating environment
- Descriptions: Specifies the interrupt number assigned to IRQ X. IRQs 0
- through 7 and IRQs 8 through 15 are assigned to contiguous interrupt numbers.
- These locations are valid only after call to INITXLIB. Typically, IRQ 0 is
- assigned to interrupt 8, and IRQ 8 is assigned to interrupt 70H; however,
- these assignments may have been changed by system software.
-
- Symbol: OFLAGS (Operation Flags)
- Symbol Type: WORD
- Default Setting: Varies with operating environment
- Description: OFLAGS controls post-initialization operation of XLIB.
- Setting bit 0 enables XLIB hardware interrupt handlers. These handlers
- will continue to receive interrupts but will always cascade them when the bit
- is clear. XLIB sets this bit only at calls to CALLPM and ENTERPM and then
- clears the bit upon return. When the bit is clear, hot key detection is
- disabled, and the XLIB FPU interrupt handler is disabled.
- Setting bit 1 causes all FPU interrupts to be cascaded to the inherited
- real-mode interrupt handler. This bit is initialized by INITXLIB. It is set
- if no FPU is present; it is otherwise cleared.
- Setting bit 2 enables FPU save/restore in CALLPM and ENTERPM. Setting this
- bit also causes load of FPUCW to the FPU control word. The bit is clear by
- default.
-
-
-
-
-
- 35
-
-
-
-
-
-
- Symbol: PAGESIZE (Page Size)
- Symbol Type: DWORD
- Default Setting: Varies with operating environment
- Description: This memory location contains the minimum unit (in bytes) for
- extended memory allocation. PAGESIZE is initialized by INITXLIB. It will
- contain 4096 for VCPI, 1024 for XMS, and 16 for clean configurations. Values
- can vary under DPMI but will typically equal 4096. Extended memory requests
- are rounded up to the nearest integer multiple of PAGESIZE. Extended memory
- blocks will be PAGESIZE aligned.
-
- Symbols: PMDS, PMES, PMFS, PMGS (Protected-Mode Segments)
- Symbol Types: WORD
- Default Settings: FLATDSEL, TSEGDSEL, DSEGSEL, DGROUPSEL
- Descriptions: These memory locations are loaded to data segment registers by
- CALLPM and ENTERPM before transferring control to the protected-mode target.
- These locations are respectively loaded to DS, ES, FS, and GS. The contents
- of these locations may be changed to any legal selectors after the call to
- INITXLIB.
-
- Symbols: RMDS, RMES (Real-Mode Segments)
- Symbol Types: WORD
- Default Settings: DGROUP, DSEG
- Descriptions: These memory locations are loaded to data segment registers by
- CALLRM before transferring control to the real-mode target. These locations
- are respectively loaded to DS and ES. The contents of these locations may be
- changed if desired.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 36
-
-
-
-
-
-
- Appendix B: XLIB Error Codes
-
-
- XLIB error codes are always returned in AX. In many cases, the high word
- of EAX will be returned with specific information about the error, such as
- XMS, DPMI, or DOS error codes.
- Although error codes are not provided in the DPMI .9 specification, many
- DPMI .9 hosts do return DPMI 1.0 error codes. DPMI 1.0 error codes may in
- fact be DOS error codes returned to the DPMI host by DOS. If the sign bit
- (bit 15) of the error code is clear, then the error code was issued by DOS.
-
-
- Condition Code Flags
- 01H FPU exception
- 02H Hot key pressed
-
- General Errors
- 10H Interface not available
- 11H Unable to identify operating environment
- 12H DOS memory allocation failure
- 13H DOS memory release error
- 14H Failed to enable A20
- 15H Insufficient logical address space
- 16H Insufficient number of extended memory block handles
- 17H Bad extended memory block handle
- 18H Bad selector
- 19H Unable to create file
- 1AH Unable to open file
- 1BH Unable to read file
- 1CH Unable to write file
- 1DH Unable to set file pointer
- 1EH Unable to close file
- 1FH Disk full
-
- Errors Occurring Under DPMI (See Appendix C for codes returned by DPMI)
- 20H Protected mode initialization failure
- 21H Descriptor allocation error
- 22H Descriptor installation error
- 23H Unable to switch protected mode interrupt vector
- 24H Insufficient extended memory error
- 25H Extended memory allocation error
- 26H Extended memory release error
- 27H DPMI DOS memory allocation error
- 28H DPMI DOS memory release error
- 29H Unable to set descriptor base address
-
- Errors Occurring Under XMS (See Appendix D for codes returned by XMS)
- 30H Unable to measure available extended memory
- 31H Insufficient extended memory error
- 32H Extended memory allocation error
- 33H Unable to lock extended memory
- 34H Unable to unlock extended memory
- 35H Extended memory release error
-
-
-
-
- 37
-
-
-
-
-
-
- Errors Occurring Under VCPI
- 40H Error in determining protected mode entry point
- 41H Unable to determine physical address of DOS memory page
- 42H Unable to determine hardware interrupt mappings
- 43H Insufficient extended memory error
- 44H Unable to determine number of free extended memory pages
- 45H Extended memory allocation error
- 46H Extended memory release error
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 38
-
-
-
-
-
-
- Appendix C: DPMI 1.0 Error Codes
-
-
- DPMI 1.0 error codes may in fact be DOS error codes returned to the DPMI
- host by DOS. If the sign bit (bit 15) of the error code is clear, then the
- error code was issued by DOS.
-
-
- Number Explanation
- 8001H Unsupported function
- 8002H Invalid state for requested operation
- 8003H System integrity would be endangered
- 8004H Deadlock situation detected by host
- 8005H Serialization request cancelled
- 8010H Resource unavailable
- 8011H Host unable to allocate descriptor
- 8012H Linear memory unavailable
- 8013H Physical memory unavailable
- 8014H Backing store unavailable
- 8015H Callback specifications cannot be allocated
- 8016H Cannot allocate handle
- 8017H Lock count limits exceeded
- 8018H Resource owned exclusively by another client
- 8019H Resource already shared by another client
- 8021H Invalid value
- 8022H Invalid selector
- 8023H Invalid handle
- 8024H Invalid callback
- 8025H Invalid linear address
- 8026H Request not supported by hardware
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 39
-
-
-
-
-
-
- Appendix D: XMS Error Codes
-
-
- Number Explanation
- 80H Function not implemented
- 81H VDISK was detected
- 82H An A20 error occurred
- 8EH General driver error
- 8FH Unrecoverable driver error
- 90H HMA does not exist
- 91H HMA is already in use
- 92H Attempt to allocate less than HMAMIN of HMA
- 93H HMA is not allocated
- 94H A20 is still enabled
- A0H All extended memory is allocated
- A1H All available handles are allocated
- A2H Invalid handle
- A3H Source handle is invalid
- A4H Source offset is invalid
- A5H Destination handle is invalid
- A6H Destination offset is invalid
- A7H Length is invalid
- A8H Move has an invalid overlap
- A9H Parity error
- AAH Block is not locked
- ABH Block is locked
- ACH Block lock count overflow
- ADH Lock failed
- B0H Only a smaller upper memory block (UMB) is available
- B1H No UMB's are available
- B2H UMB segment number is invalid
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 40
-
-
-
-
-
-
- Appendix E: Calling Protected-Mode Libraries From C
-
-
- This appendix contains a C version of the BASIC program presented in
- Example 3. Microsoft C version 7.0 is used to create a float array. C then
- calls a protected-mode assembly language procedure in a library to sum the
- elements of the array. The assembly language library is presented in Example
- 3. C calls a 16-bit procedure called SUMARRAY This procedure then transfers
- control to a 32-bit protected-mode procedure called SUMARRAY32. The latter
- procedure performs the actual calculations. Parameters defining the array are
- placed in a contiguous block of memory defined by a C structure. C passes the
- address of this structure to the library. The first four bytes in the
- structure are reserved for error codes. The linear address of the structure
- is placed in CCODEPTR so that any FPU exceptions will be recorded by the FPU
- interrupt handler in the error code location. The SUMARRAY32 procedure will
- also record an error if the parameter defining the number of elements to be
- summed is zero.
- The C code is somewhat simpler than the corresponding BASIC code because
- DOS memory does not have to be released prior to calling INITXLIB. This
- follows because C does not claim all DOS memory as does BASIC.
- C is more powerful than BASIC in that it can access data under external
- symbols whereas BASIC cannot. Access to XLIB public data is made possible in
- C by including the header file called XLIB.H. This file makes all XLIB public
- data and public real-mode procedures visible to C. It also contains
- declarations which adapt the PASCAL conventions of XLIB.
-
-
- -----------------------------------------------------------------------------
- +++++++++++++++++++++
- + C MAIN MODULE +
- +++++++++++++++++++++
-
-
- /* The following Microsoft C 7.0 program should be linked with the assembly
- language library in Example 3. Combine the library with XLIB.LIB using the
- Microsoft LIB utility. The C program first initializes XLIB. Next, it
- creates a float array. A control block for SUMARRAY is then constructed
- and the call to SUMARRAY is executed. Finally, the condition code in the
- control block is inspected and results are printed. */
-
- #include <stdio.h>
- #include <xlib.h>
-
- extern long __far __pascal LINADR(void __far *ptr);
- extern void __far __pascal SUMARRAY(void __far *ptr);
-
- struct arraydata
- {
- long condcode;
- long n;
- long address;
- float sum;
- } ad;
-
-
-
-
- 41
-
-
-
-
-
-
- float a[101];
-
- main()
- {
- int i;
- long temp;
-
- temp = INITXLIB();
- if (temp != 0)
- {
- printf("Initialization Error: %lX\n",temp);
- return 0;
- }
-
- for(i = 0; i <= 100; i++)
- a[i] = i;
-
- ad.condcode = 0;
- ad.n = 50;
- ad.address = LINADR(a);
-
- SUMARRAY(&ad);
- if (ad.condcode != 0)
- {
- printf("Error: %lX\n",ad.condcode);
- return 0;
- }
- printf("Sum: %f\n",ad.sum);
- }
- -----------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 42
-
-
-
-
-
-
- Appendix F: Reporting Problems With XLIB
-
-
- All efforts to isolate and report problems with XLIB will be appreciated.
- The following steps will greatly facilitate bug-tracking:
-
- 1) Ensure that your own program always checks the error codes returned by XLIB
- procedures. These codes will likely resolve the problem. If not, then make
- note of the code.
-
- 2) Attempt to execute your program under DPMI, VCPI, and in the absence of
- both. If the problem relates to memory management, then also attempt to
- execute your program in the presence of XMS but in the absence of DPMI and
- VCPI, then attempt to execute in the absence of all three interfaces. It will
- generally be found that the problem occurs only under a specific interface.
- If so, then note the interface under which the problem occurs.
-
- 3) If the problem occurs only under one interface, then attempt to execute
- your program under different implementations of the interface. For example, a
- DPMI host is contained in Windows 3.1, 386MAX, QDPMI, and OS/2 2.x. Try
- executing your program under each host and make note of the results. Problems
- occurring only under one host are generally indicative of bugs in the host
- rather than XLIB.
-
- 4) Try different options on your compiler, assembler, and linker. It is
- sometimes the case that code is not processed properly under some options.
-
- 5) Report problems to:
-
- Dr. David Pyles
- TechniLib Company
- P.O. Box 6818
- Jackson, Ms. 39282
- (601) 372-7433
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 43
-
-
-
-
-
-
- Appendix G: The SWITCHPM and SWITCHRM Procedures
-
-
- SWITCHPM and SWITCHRM are the primitive mode-switch routines used by
- nearly all XLIB procedures requiring execution in both real and protected
- modes. They are made public for users who need to perform mode switching
- tasks not provided by XLIB. These routines do not conform to the general
- conventions followed by other XLIB procedures; consequently, they are
- presented in an appendix.
- There are special situations in which CALLPM and ENTERPM may not be
- suitable for performing mode switches. For example, suppose one has a
- protected-mode hardware interrupt handler that is intended to service
- interrupts occurring in both real and protected modes. Unless DPMI is
- installed, the user will have to write a second handler to deflect real-mode
- interrupts to the protected-mode handler. CALLPM and ENTERPM could not be
- used in the event that the interrupt occurred in a procedure called from
- protected mode will CALLRM. This follows because CALLPM and ENTERPM are not
- reentrant. Instead, the user must perform the mode switches either with
- DEFLECTPM or with SWITCHPM and SWITCHRM. A second example could occur where
- the user needs to perform mode switches without the overhead of CALLPM and
- ENTERPM. SWITCHPM and SWITCHRM perform mode switches in minimum CPU time.
- Both SWITCHPM and SWITCHRM are near procedures in CSEG; therefore, they
- must be called from this segment. SWITCHPM returns to the caller in 16-bit
- protected mode. SWITCHRM returns to the caller in real mode. Both procedures
- must be called with a stack in DSEG. Do not use XLIB stacks for this purpose.
- SWITCHPM returns with CS = CSEGSEL and with all other segments equal to
- DSEGSEL. All other registers, except the status flags, are preserved.
- SWITCHRM returns with CS = CSEG and with SS, DS, and ES set to DSEG. FS
- and GS are undefined. All other registers, except the status flags, are
- preserved.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 44
-