📄 xlib.doc
字号:
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -