home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-08-20 | 79.7 KB | 2,278 lines |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- XLIB PROGRAMMER'S MANUAL
- VERSION 1.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 $45.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 3
- 3. Mode Switching 5
- 4. Interrupt Management 7
- 5. Memory Management 10
- 6. XLIB Initialization 11
- 7. XLIB Termination 12
- 8. Using XLIB in High-Level Language Libraries 13
-
-
- TABLES
- Page
- 1. XLIB Segments and Selectors by Public Symbol 3
- 2. CALLPM/ENTERPM Register Storage Locations by Public Symbol 6
- 3. CALLRM Register Storage Locations by Public Symbol 6
-
-
- EXAMPLES
- Page
- 1. Simple Mode Switching Under XLIB 2
- 2. Calling Protected-Mode Libraries From BASIC 13
-
-
- APPENDICES
- Page
- A. Summary of XLIB Public Data 17
- B. Summary of XLIB Public Procedures 19
- C. XLIB Error Codes 27
- D. Calling Protected-Mode Libraries From C 28
- E. Reporting Problems With XLIB 30
- F. DPMI 1.0 Error Codes 31
- G. XMS Error Codes 32
- H. The SWITCHPM and SWITCHRM Procedures 33
-
-
-
-
-
-
- 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. Assembly language programmers can be writing
- protected-mode code in a matter of minutes with XLIB. Implementation of such
- code will often require no more than placing the code in the proper segment
- and making two calls to XLIB procedures.
- 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 procedures handle important tasks such as mode switching between
- real and protected modes, memory management under protected mode, and
- interrupt management under protected mode. 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 these interfaces
- 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.
- 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.
- The memory model supported by XLIB approximates the flat model of IBM
- OS/2 and Microsoft Windows NT. Therefore, code written for XLIB will require
- little modification when being transported to these systems. Indeed, many
- procedures will require no modification whatsoever. Moreover, XLIB includes
- flat-model descriptors which may be used to execute genuine flat-model code;
- however, it does not include routines to load and relocate such code.
- The following program illustrates the simplicity with which protected-
- mode execution may be initiated and terminated with XLIB. The program 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.
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 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
- -----------------------------------------------------------------------------
-
-
- 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, and Quarterdeck QDPMI version 1.01.
- Assembly language programs should use the CPARM:1 parameter because XLIB
- will generally attempt to allocate DOS memory. The NOPACKC option for LINK
- was found to be problematic for 32-bit segments and should therefore be
- avoided.
-
-
-
- 2
-
-
-
-
-
-
- 2. XLIB Conventions and Structure
-
-
- A summary of most XLIB public data is included in Appendix A. A summary
- of all XLIB public procedures is included in Appendix B. This section sets
- forth rules which will be generally applicable to XLIB data and procedures.
- Exceptions to these rules are covered in Appendix H.
- 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 XLIB real-mode procedures are located in a 16-bit segment
- called CSEG. The user may also place code in CSEG but is never required to do
- so. All public XLIB real-mode routines have far returns.
- All public XLIB protected-mode procedures are located in a 32-bit segment
- called TSEG. The user must also place all protected-mode code in TSEG. All
- XLIB protected-mode procedures have near returns. Likewise, all protected-
- mode procedures called by XLIB routines must have near returns.
- All XLIB procedures may be called with interrupts enabled and will return
- with interrupts enabled provided that they were enabled upon call.
- All XLIB data is contained in a segment called DSEG. The user may also
- place data in DSEG but is never 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 may possibly encounter error conditions will always
- return error codes in AX (see Appendix C). In many cases, DX or the high word
- of EAX will be returned with specific information about the error, such as
- XMS, DPMI, or DOS error codes.
- 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 selector
- FLATDSEL . Flat-model data selector
- DGROUPSEL DGROUP DGROUP data group
- SCRNSEL . Screen data (color or monochrome)
- -----------------------------------------------------------------------------
-
-
- 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. 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.
-
-
-
- 3
-
-
-
-
-
-
- Descriptor privilege levels and requested privilege levels are set to zero
- unless DPMI is installed. Privilege levels under DPMI will be dictated by the
- DPMI host, but will generally be set to three.
- The values contained in the above selectors will be different under DPMI
- than other environments. Moreover, DPMI selectors values can differ under
- different DPMI environments depending upon the DPMI host and the presence of
- other DPMI clients. The user should therefore always read selector values
- from these locations.
- Since selectors are contained 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 segment 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 segment
- override. For example from TSEG code you can always load DS with DSEGSEL
- using MOV DS,CS:CSDSEGSEL.
- TSEG may be larger than 64K provided that certain rules are observed.
- 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. If you need to make modifications to TSEG, then do them from a TSEG
- protected-mode procedure. Finally, never encode segment constants in TSEG.
- For example, the symbols CSEG, TSEG, DSEG, and DGROUP should never be found in
- TSEG. DOS will not be able to perform relocation fixups 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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4
-
-
-
-
-
-
- 3. Mode Switching
-
-
- As illustrated in Example 1, CALLPM may be used to transfer control to
- protected mode. When execution is returned to real mode after CALLPM, only
- segment registers and ESP are restored to their original values. Real mode
- receives other registers (except EFLAGS) at values as of the protected-mode
- RET instruction. Control may be returned from protected mode to real mode
- either by RET or by a near jump to RETPM (return from protected mode). RETPM
- is an XLIB procedure which successfully returns control to real mode
- regardless of stack state.
- Execution may also be transferred to protected mode 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
- preserve register state. ENTERPM restores register state as required by
- Microsoft high-level languages. In particular, ENTERPM restores all 16-bit
- and 32-bit registers (including system and control flags in EFLAGS) except EAX
- and EDX. EAX and EDX are not restored since 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; however, upon
- return to real mode, CALLPM restores only segment registers and ESP while
- ENTERPM restores all registers except EAX and EDX. 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.
- FPU state is restored with the FRSTOR instruction executed in real mode.
- Control may be returned to real mode after ENTERPM either with the RET
- instruction or by a near jump to EXITPM. EXITPM will return control to real
- mode regardless of stack state.
- 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. EXITPM restores all registers
- except EAX and EDX. RETPM restores only segment registers and ESP.
- CALLPM and ENTERPM save registers to public locations in DSEG. The
- following table specifies the symbols under which the registers are stored.
- The calling stack is always saved after the real-mode return address and the
- protected-mode target address have been popped from it.
-
-
-
-
-
-
-
-
-
-
-
-
- 5
-
-
-
-
-
-
- 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]
- -----------------------------------------------------------------------------
-
-
- The protected-mode targets of CALLPM and ENTERPM receive the XLIB
- protected mode stack (SS = TSEGSEL) with 1000H bytes of free space. The
- target also receives DS = FLATDSEL (flat-model data selector), ES = TSEGDSEL
- (TSEG data selector), FS = DSEGSEL (DSEG selector), and GS = DGROUPSEL (DGROUP
- selector). The target procedure may switch stacks if desired.
- Once within protected mode, far procedures in real mode can be called
- using CALLRM (call real mode), which is a near procedure in TSEG. CALLRM
- should be called with the real-mode target address on the stack (push segment
- first) CALLRM saves and restores only segments registers and ESP. The target
- address receives the XLIB real-mode stack (SS = DSEG) with 200H free bytes, DS
- = DGROUP, and ES = DSEG. Code called by this routine cannot perform XLIB
- shifts back to protected mode. This excludes usage of the XLIB memory
- management procedures and XLIB interrupt-vector management procedures since
- these require protected-mode execution.
- CALLRM saves segment registers and ESP at public locations in DSEG. The
- following table specifies the symbols under which the registers are stored.
- The calling stack is saved after popping the protected-mode near return and
- the real-mode target address.
-
-
- 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
- -----------------------------------------------------------------------------
-
-
-
-
-
-
-
-
- 6
-
-
-
-
-
-
- 4. Interrupt Management
-
-
- XLIB handles nearly all interrupts occurring in protected mode by
- shifting to real mode and calling the inherited real-mode interrupt handlers.
- All interrupts are handled this way except the keyboard interrupt (IRQ 1) and
- the FPU interrupt (IRQ 13). XLIB has its own handlers for these routines.
- These handlers are activated as of protected-mode entry through CALLPM or
- ENTERPM. They remain active during calls back to real mode through CALLRM.
- They are disabled upon return to CALLPM/ENTERPM. The user may replace or
- disable these handlers if desired.
- It is generally desirable for the user to be able to terminate a program
- or subroutine with a certain keypress combination. Unfortunately, it is
- difficult to safely abort protected-mode execution from an interrupt handler.
- This is particularly the case under DPMI. The DPMI host traps all interrupts
- before transferring control to the interrupt handler. If control is not
- returned back to the host with an IRET instruction, the host will be left in
- an irregular and potentially unstable state. Similar problems could occur
- under a VCPI multitasking control program. Consequently, a keyboard interrupt
- handler cannot be safely used to immediately abort execution upon a keypress.
- The XLIB keyboard interrupt handler provides the best alternative. The
- handler examines keyboard input to determine if a user definable hot key has
- been pressed. If a pressed key is not the hot key, the interrupt handler
- cascades the interrupt to the inherited real-mode handler. If the hot key is
- pressed, then a flag is placed in a DWORD condition code whose linear address
- is stored in CCODEPTR (condition code pointer). CCODEPRR is a public DWORD in
- DSEG. The condition code may then be polled by code in the main thread of
- execution where termination can be safely accomplished. The hot key is not
- cascaded.
- 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 022EH (CTRL C). The condition code flag for
- the hot key is included among XLIB error codes in Appendix C.
- By default CCODEPTR 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 XLIB interrupt handler for the FPU performs three 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 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
-
-
-
- 7
-
-
-
-
-
-
- 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
- code has been terminated from within an interrupt handler. This is also the
- case for the FPU interrupt handler. If an FPU exception occurs under DPMI or
- under a VCPI-based multitasker, then the machine may need rebooting. Most
- DPMI hosts appear to be restored to normal state by execution of INT 21
- function 4CH (DOS termination). However, this approach is not recommended in
- the DPMI specifications, and should be particularly suspect under a
- multitasker. It is generally safe to continue execution after an FPU
- exception when running in a single-task environment under VCPI or when running
- in the absence of both DPMI and VCPI. The user may therefore wish to debug
- FPU code in these sorts of environments.
- Bit 0 of OFLAGS is used by XLIB to simultaneously enable or disable all
- of its own 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 cascaded to the inherited real-mode handlers when the bit
- is clear.
- The keyboard interrupt handler may be permanently disabled by setting
- HOTKEY to zero. This follows since no key has a zero scan code. With HOTKEY
- = 0, all keyboard interrupts are cascaded to the inherited real-mode handler.
- 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 before returning to protected mode.
- The user may install real-mode interrupt handlers in usual fashion. Such
- handlers will also receive interrupts occurring in protected mode provided
- that the protected-mode handlers cascade the interrupt. Protected-mode
- interrupts will be deflected to real mode either by XLIB or by the DPMI host.
- If XLIB deflects the interrupt, then the handler will receive SS = DSEG with
- ESP set to 200H free bytes. Stack sizes under DPMI will depend upon the host.
- 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).
- Call PMGETRMIV with the interrupt number in AL. The handler address is
- returned in CX:DX. Call PMSETRMIV with the interrupt number in AL and the new
- handler address in CX:DX.
- The user may install a protected-mode interrupt handler from real mode by
- calling SETPMIV (set protected-mode interrupt vector). Call with the
- interrupt number in AL and the address of the new handler in CX:EDX (CX is a
- selector). This routine returns an error code in EAX (EAX returned as zero if
- successful). The current protected-mode interrupt vector may be obtained by
- calling GETPMIV. Call with AL equal to the interrupt number. The current
- handler address is returned in CX:EDX. This routine is always successful.
- These routines should not be used to manage vectors for CPU exceptions when
- DPMI is active. Direct calls to DPMI functions should be executed for these
- purposes.
-
-
-
- 8
-
-
-
-
-
-
- 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 tha absence of
- DPMI. That is, real-mode interrupts are never deflected to protected mode 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. 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 service the interrupts with the inherited real-
- mode handlers.
- Under DPMI, all 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. This is not a concern if the interrupts are cascaded.
- 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 may be remapped
- under either VCPI or DPMI. 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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 9
-
-
-
-
-
-
- 5. Memory Management
-
-
- XLIB supplies memory management procedures for both real mode and
- protected mode. 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. Call PMGETDOSMEM with the
- requested number of bytes in EAX. If successful (EAX returned as zero), then
- the linear address of the allocated block is returned in EDX; the allocated
- block size is returned in ECX and will be at least as large as the requested
- size. A block handle is returned in EBX. Call PMFREEDOSMEM to release a
- previously allocated block. The block handle should be in EAX upon call.
- Call PMGETDOSMEM with EAX = 0 to get the largest available DOS memory
- block. The call is successful if EAX is returned as zero, in which event the
- size of the largest available block will be in ECX (EBX and EDX are
- preserved).
- The real-mode extended memory management procedures are GETMEM, FREEMEM,
- and RESETMEM. Allocate memory by calling GETMEM with the number of bytes
- requested in EAX. With successful execution (EAX returned as zero), GETMEM
- will return with the linear address of the allocated extended memory block in
- EDX. The size of the allocated block will be returned in ECX and will be at
- least as large as the requested size. The memory block handle will be
- returned in EBX. Release the block by calling FREEMEM with the block handle
- in EAX. Release all previously allocated extended memory at once by calling
- RESETMEM.
- 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.
- GETMEM and PMGETMEM can also be used to obtain the size of the largest
- available extended memory block (not total free memory). Call with EAX = 0
- for this purpose. If this call is successful (EAX returned as zero), then the
- size of the largest free block will be returned in ECX (EBX and EDX are
- preserved).
- 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).
-
-
-
-
-
-
-
-
-
-
-
-
-
- 10
-
-
-
-
-
-
- 6. XLIB Initialization
-
-
- Most XLIB procedures should be called only after XLIB has been
- initialized by calling INITXLIB. This procedure will examine the operating
- environment for the presence of DPMI, VCPI, and XMS. It will then perform
- extensive code modifications upon itself 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 by default, 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 assembly
- language 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 in DX:AX (measured in bytes), and then
- release at least this much memory. This process is illustrated for Microsoft
- BASIC in the next example. 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 by obtained in DX:AX by calling
- DPMIMEMREQ. VCPI conventional memory requirements may be obtained in DX:AX by
- calling VCPIMEMREQ.
- The XLIB routine XLIBCONFIG (XLIB configuration) returns the results of
- INITXLIB. The initialized protected-mode configuration is returned in AX.
- The value of the lower nibble specifies the configured protected-mode
- interface. The value will be 1 for DPMI, 2 for VCPI, and 3 for XLIB. Bit 4
- of AX will be set if XMS is configured. XLIBCONFIG is a real-mode routine.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 11
-
-
-
-
-
-
- 7. XLIB Termination
-
-
- XLIB is terminated simply by executing INT 21 function 4CH (DOS
- termination) from real mode. This function must not be called from protected
- mode. Upon termination, XLIB releases all previously allocated memory and
- resets all interrupt vectors to their original values.
- Termination of DPMI requires that INT 21 function 4CH be executed from
- protected mode. XLIB intercepts INT 21 calls and determines if the function
- number is 4CH. If so, and if DPMI is active, then XLIB shifts to protected
- mode and issues the call.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 12
-
-
-
-
-
-
- 8. 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 methodolgy 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 BASIC.
- 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 D.
-
-
- Example 2: 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
-
- CSEG SEGMENT PARA PUBLIC USE16 'CODE'
- ASSUME CS:CSEG, DS:DSEG
-
-
-
-
-
- 13
-
-
-
-
-
-
- ;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
-
- TSEG SEGMENT PARA PUBLIC USE32 'CODE'
- ASSUME CS:TSEG, SS:TSEG, DS:TSEG, ES:TSEG, FS:DSEG, GS:DGROUP
-
-
-
-
-
-
-
-
-
-
- 14
-
-
-
-
-
-
- ;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)
-
-
-
-
-
-
-
- 15
-
-
-
-
-
-
- '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
- -----------------------------------------------------------------------------
-
-
-
-
-
-
-
- 16
-
-
-
-
-
-
- Appendix A: Summary 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.
-
-
- 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 fixups. Read these locations to
- get segment values. User segments should be handled the same way.
-
- 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. CCODEPTR initially contains the
- linear address of CCODE. CCODEPTR may be changed by the user, but must point
- to a DWORD in conventional memory.
-
- 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.
-
- Symbol: HOTKEY (Hot Key)
- Symbol Type: WORD
- Default Setting: 022EH
- 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. The default hot key is CTRL C. Bypass
- hot key detection by setting HOTKEY = 0.
-
- 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.
-
-
-
-
-
-
- 17
-
-
-
-
-
-
- Symbols: IRQ0INTNO/IRQ8INTNO (IRQ X Interrupt Number)
- Symbol Types: BYTE/BYTE
- Default Settings: 08H/70H
- 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.
-
- Symbol: OFLAGS (Operation Flags)
- Symbol Type: WORD
- Default Setting: 0
- Description: OFLAGS controls post-initialization operation of XLIB.
- Setting bit 0 disables XLIB interrupt handlers. XLIB sets this bit only at
- calls to CALLPM and ENTERPM and then clears the bit upon return.
- Setting bit 1 causes all FPU interrupts to be cascaded to the inherited
- real-mode interrupt handler. This bit is automatically set if no FPU is
- present.
- Setting bit 2 enables FPU save/restore in CALLPM and ENTERPM. Setting this
- bit also causes load of FPUCW to the FPU control word.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 18
-
-
-
-
-
-
- Appendix B: Summary of XLIB Public Procedures
-
-
- The following is a summary of all XLIB public procedures. All procedures
- entered from real mode are in CSEG and have far returns. All protected-mode
- procedures are in TSEG and have 32-bit near returns. All procedures conform
- to the Pascal naming and calling convention. All XLIB procedures may be
- called with interrupts enabled and will return with interrupts enabled
- provided that they were enabled upon call.
-
-
- Initialization Routines
-
-
- 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 returned
- in DX:AX. DX:AX is upward adjusted to an integer multiple of 16.
- Sign bit of DX set if unsuccessful. Error code returned in AX (always DOS
- error code).
- Details:
- This routine will return DX:AX = 0 if XLIB contains free internal memory in
- sufficient quantity to meet conventional memory demands.
- 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.
-
- DPMIMEMREQ (DPMI Memory Requirements)
- Purpose: Find DPMI conventional memory requirements.
- CPU Mode: Real
- Registers at Call: None
- Return Registers: DX:AX = conventional memory requirements adjusted upward to
- integer multiple of 16.
- Details:
- This routine will return DX:AX = 0 if XLIB contains free internal memory in
- sufficient quantity to meet the conventional memory demands of DPMI.
- This routine does not assume the presence of DPMI. It will return DX:AX =
- 0 if DPMI is absent.
-
- VCPIMEMREQ (VCPI Memory Requirements)
- Purpose: Find VCPI conventional memory requirements.
- CPU Mode: Real
- Registers at Call: None
- Return Registers: DX:AX = conventional memory requirements adjusted upward to
- integer multiple of 16.
- Details: This routine simply loads DX:AX with a constant.
-
-
-
-
-
-
-
- 19
-
-
-
-
-
-
- INITXLIB (Initialize XLIB)
- Purpose: Check for presence of XMS, DPMI, and VCPI. Configure XLIB
- accordingly.
- CPU Mode: Real
- Registers at Call: None
- Return Registers:
- AX = 0 if successful, in which event DX and EAX are zero as well.
- AX <> 0 if unsuccessful. XLIB error code returned in AX. Specific error
- code returned in DX and in high word of EAX (EAH). If AX = operating
- environment identification error or DOS memory allocation error, then DX and
- EAH = DOS error code. If AX = DPMI error, then DX and EAH = 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; consequently, some
- DOS memory must be free. The amount of DOS memory XLIB will attempt to
- allocate can be obtained by calling XLIBMEMREQ, VCPIMEMREQ, or DPMIMEMREQ.
- This routine should be called only once within a program. Subsequent calls
- are returned with no action. XLIB is terminated by INT 21 function 4C (DOS
- termination) issued from real mode.
-
- XLIBCONFIG (XLIB Configuration)
- Purpose: Get XLIB configuration.
- CPU Mode: Real
- Registers at Call: None
- Return Registers:
- AX = 0 if protected-mode structures not initialized.
- AX = XLIB configuration if protected-mode structures initialized. Value of
- lower nibble identifies protected-mode host/server. If 1 then DPMI. If 2
- then VCPI. If 3 then XLIB. Bit 4 is set if XMS is initialized.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 20
-
-
-
-
-
-
- Mode Switch Routines
-
-
- Mode switch routines require initialization of XLIB by INITXLIB.
-
-
- CALLPM (Call Protected Mode)
- Purpose: Call protected-mode procedure in TSEG with near return.
- Mode: Real
- Registers at Call: SS:ESP = far real-mode return address (four bytes), near
- protected-mode target offset (four bytes).
- Return Registers: Returns through RETPM. See RETPM for details.
- Details:
- All CPU registers except EAX and EDX are saved. The calling SS:ESP is
- saved at ORGSS:ORGESP after the return address and argument have been popped.
- XLIB interrupt handlers are enabled. Entry point receives SS = TSEGDSEL with
- 1000H free bytes on the stack. The return address on the stack is a near
- return to RETPM. Entry point receives segments DS = FLATDSEL, ES = TSEGDSEL,
- FS = DSEGSEL, and GS = DGROUPSEL.
- 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.
- If bit 1 of OFLAGS is set, then the XLIB interrupt handler for the FPU will
- not be enabled.
-
- 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 and ESP
- to values as of call to either CALLPM or ENTERPM. XLIB interrupt handlers are
- disabled. 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 protected mode procedure in TSEG with near return.
- Mode: Real
- Registers at Call: SS:ESP = far real-mode return address (four bytes), near
- protected mode target offset (four bytes).
- 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.
-
- 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 and
- EDX to values as of call to either CALLPM or ENTERPM. The system and control
-
-
-
- 21
-
-
-
-
-
-
- flags in EFLAGS are also restored. XLIB interrupt handlers are disabled.
- 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 registers.
- EXITPM will successfully execute regardless of stack state.
- The XLIB FPU interrupt handler performs a jump to EXITPM upon occurrence of
- any unmasked FPU exception.
-
- CALLRM (Call a Real-Mode Procedure)
- Purpose: From protected mode, call a real-mode procedure with far return.
- CPU Mode: Protected
- Registers at Call: SS:ESP = near protected-mode return address (four bytes),
- far real-mode target address (four bytes).
- Return Registers: All segment registers and ESP are restored.
- Details:
- The calling SS:ESP is saved at CALLSS:CALLESP after popping the return
- address and arguments. The called routine receives the XLIB real-mode stack
- (SS = DSEG) with 200H free bytes. Data segment settings are DS = DGROUP and
- ES = DSEG.
- Code called by this routine cannot perform XLIB shifts back to protected
- mode, including calls to XLIB memory management procedures or procedures
- managing interrupt vectors.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 22
-
-
-
-
-
-
- Memory Management Routines
-
-
- Memory management routines require initialization of XLIB by INITXLIB.
-
-
- 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. Block handle returned in EBX. Number of allocated
- bytes returned in ECX. Linear address of allocated block returned in EDX.
- EAX = error code if unsuccessful. AX = XLIB error code. High word of EAX
- (EAH) will be set to DOS error code. If DPMI is active, then EAH will be DPMI
- error code (codes supplied by DPMI .9 and up).
- Details:
- The returned block size will always be 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.
-
- 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. High word of EAX (EAH) will be DOS error code. If DPMI is
- active, then EAH will equal DPMI error code (codes 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. Block handle returned in EBX. Number of allocated
- bytes returned in ECX. Logical address of allocated block returned in EDX.
- EAX = error code if unsuccessful. AX = XLIB error code. If DPMI is
- active, then high word of EAX (EAH) will be DPMI 1.0 error code (if provided
- by host). If XMS is active, then EAH = XMS error code.
- Details:
- The returned block size will always be an integer multiple of eight. Under
- XMS the returned block size will be a 1K multiple. Under VCPI and most DPMI
- hosts, block sizes will be 4K multiples.
- 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.
-
-
-
- 23
-
-
-
-
-
-
- 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 preserved). This call can also return with
- 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
- 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
- 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.
- RESETMEM is always called upon execution of INT 21 function 4C (DOS
- termination)
-
- 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
-
-
-
-
-
-
- Interrupt Management Routines
-
-
- Interrupt management routines require initialization of XLIB by INITXLIB.
-
-
- PMGETRMIV (Protected Mode - Get Real-Mode Interrupt Vector)
- Purpose: Retrieve address of real-mode interrupt handler.
- 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.
- 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 except the handler for IRQ1 (keyboard interrupt) and IRQ13 (FPU
- interrupt). The keyboard interrupt handler cascades all interrupts except
- those caused by pressing the hot key. The FPU interrupt handler cascades
- interrupts only if bit 1 of OFLAGS is set.
- 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 DPMI 1.0 error code (if provided by host).
- Details:
- 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 receives
-
-
-
- 25
-
-
-
-
-
-
- control of the interrupt first. It may cascade the interrupt if so desired.
- If no protected-mode handler has been installed, then DPMI services these
- interrupts with the inherited real-mode handlers.
- XLIB never disables handlers installed by this procedure.
- Do not use this routine to install CPU exception handlers under DPMI. Use
- DPMI functions directly 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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 26
-
-
-
-
-
-
- Appendix C: 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 Unable to enable A20
- 15H Insufficient logical address space
- 16H Insufficient number of extended memory block handles
- 17H Bad extended memory block handle
-
- Errors Occurring Under DPMI (See Appendix F for codes returned by DPMI)
- 20H Protected mode initialization failure
- 21H Descriptor allocation error
- 22H Descriptor placement 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
-
- Errors Occurring Under XMS (See Appendix G 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
-
- 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
-
-
-
-
- 27
-
-
-
-
-
-
- Appendix D: Calling Protected-Mode Libraries From C
-
-
- This appendix contains a C version of the BASIC program presented in
- Example 2. 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
- 2. 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 2. 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;
-
-
-
-
- 28
-
-
-
-
-
-
- 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);
- }
- -----------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 29
-
-
-
-
-
-
- Appendix E: 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, and QDPMI. 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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 30
-
-
-
-
-
-
- Appendix F: 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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 31
-
-
-
-
-
-
- Appendix G: 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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 32
-
-
-
-
-
-
- Appendix H: The SWITCHPM and SWITCHRM Procedures
-
-
- SWITCHPM and SWITCHRM are procedures in CSEG which are used internally by
- XLIB. They perform untransferred switches to protected mode and real mode.
- They are made public for users who need to perform mode switching without the
- overhead of CALLPM and ENTERPM. These procedures perform mode switching in
- minimum CPU time. However, they do not conform to all of the general
- conventions followed by other XLIB public procedures.
- SWITCHPM is a near procedure in CSEG which switches the CPU to 16-bit
- protected mode. It returns to the caller. It must be called with SS = DSEG;
- therefore, a stack must be set up in this segment. SWITCHPM returns with CS =
- CSEGSEL and with SS, DS, ES, FS, and GS all being set to DSEGSEL. Other
- registers are preserved. Note that the caller is responsible for preserving
- real-mode segment registers.
- SWITCHRM is a near procedure in CSEG which switches the CPU to real mode.
- It returns to the caller. It must be called with SS = DSEGSEL. SWITCHRM
- returns with CS = CSEG and with SS, DS, ES, FS, and GS all being set to DSEG.
- Other registers are preserved. Note that the caller is responsible for
- preserving protected-mode segment registers.
- These routines offer a great deal of potential for inline assembly in 16-
- bit C. However, usage of 32-bit registers and 32-bit offsets in such code
- will necessitate the insertion of operand-size and address-size prefixes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 33
-