📄 xms-specification.txt
字号:
Allocate Any Extended Memory (Function 89h)
Entry:
AH = 89h
EDX = Amount of extended memory requested, in Kb.
Exit:
AX = 1 if the block is allocated, 0 if not
DX = Handle to allocated block.
Errors:
BL = 80h if the function is not implemented.
BL = 81h if a VDISK device is detected.
BL = A0h if all available extended memory is allocated.
BL = A1h if all available extended memory handles are in use.
This function is similar to the existing Allocate Extended Memory, except that it uses a 32-bit instead of a 16-bit value to specify the amount of memory requested. It allocates from the same memory and handle pool as the current function. Since it requires a 32-bit register, this function can be supported only on 80386 and higher processors, and XMS drivers on 80286 machines should return error code 80h.
Get Extended EMB Handle Information (Function 8Eh)
Entry:
AH = 8Eh
DX = Extended memory block handle.
Exit:
AX = 1 if the block's information is found, 0 if not
BH = Block lock count
CX = Number of free EMB handles in the system
EDX = Block's length in Kb.
Errors:
BL = 80h if the function is not implemented.
BL = 81h if a VDISK device is detected.
BL = A2h if the handle is invalid.
This function is similar to the Get EMB Handle Information function. Since it uses a 32-bit register to report the block size, it can be used to get information on blocks larger than 64 Mb. It also uses a 16-bit instead of 8-bit register to report the number of free handles, allowing the handle pool to be extended beyond 256 entries.
Because of its reliance on a 32-bit register, this function is available on 80386 and higher processors. XMS drivers on 80286 machines should return error code 80h if this function is called.
Reallocate Any Extended Memory (Function 8Fh)
Entry:
AH = 8Fh
EBX = New size for extended memory block, in Kb.
DX = Unlocked handle for memory block to be resized.
Exit:
AX = 1 if the block is reallocated, 0 if not
Errors:
BL = 80h if the function is not implemented.
BL = 81h if a VDISK device is detected.
BL = A0h if all available extended memory is allocated.
BL = A1h if all available extended memory handles are in use.
BL = A2h if the handle is invalid.
BL = ABh if the block is locked.
This function is similar to the existing Reallocate Extended Memory, except that it uses a 32-bit instead of a 16-bit value to specify the amount of memory requested. It allocates from the same memory and handle pool as the current function. Since it requires a 32-bit register, this function can be supported only on 80386 and higher processors, and XMS drivers on 80286 machines should return error code 80h.
PRIORITIZING HMA USAGE
For DOS users to receive the maximum benefit from the High Memory Area, programs which use the HMA must store as much of their resident code in it as is possible. It is very important that developers realize that the HMA is allocated as a single unit.
For example, a TSR program which grabs the HMA and puts 10K of code into it may prevent a later TSR from putting 62K into the HMA. Obviously, regular DOS programs would have more memory available to them below the 640K line if the 62K TSR was moved into the HMA instead of the 10K one.
The first method for dealing with conflicts such as this is to require programs which use the HMA to provide a command line option for disabling this feature. It is crucial that TSRs which do not make full use of the HMA provide such a switch on their own command line (suggested name "/NOHMA").
The second method for optimizing HMA usage is through the /HMAMIN= parameter on the XMS device driver line. The number after the parameter is defined to be the minimum amount of HMA space (in K-bytes) used by any driver or TSR. For example, if "DEVICE=HIMEM.SYS /HMAMIN=48" is in a user's CONFIG.SYS file, only programs which request at least 48K would be allowed to allocate the HMA. This number can be adjusted either by installation programs or by the user himself. If this parameter is not specified, the default value of 0 is used causing the HMA to be allocated on a first come, first served basis.
Note that this problem does not impact application programs. If the HMA is available when an application program starts, the application is free to use as much or as little of the HMA as it wants. For this reason, applications should pass FFFFh in DX when calling Function 01h.
HIGH MEMORY AREA RESTRICTIONS
Far pointers to data located in the HMA cannot be passed to DOS. DOS normalizes any pointer which is passed into it. This will cause data addresses in the HMA to be invalidated.
Disk I/O directly into the HMA (via DOS, INT 13h, or otherwise) is not recommended.
Programs, especially drivers and TSRs, which use the HMA *MUST* use as much of it as possible. If a driver or TSR is unable to use at least 90% of the available HMA (typically ~58K), they must provide a command line switch for overriding HMA usage. This will allow the user to configure his machine for optimum use of the HMA.
Device drivers and TSRs cannot leave the A20 line permanently turned on. Several applications rely on 1MB memory wrap and will overwrite the HMA if the A20 line is left enabled potentially causing a system crash.
Interrupt vectors must not point into the HMA. This is a result of the previous restriction. Note that interrupt vectors can point into any allocated upper memory blocks however.
ERROR CODE INDEX
If AX=0000h when a function returns and the high bit of BL is set, BL=
80h if the function is not implemented
81h if a VDISK device is detected
82h if an A20 error occurs
8Eh if a general driver error occurs
8Fh if an unrecoverable driver error occurs
90h if the HMA does not exist
91h if the HMA is already in use
92h if DX is less than the /HMAMIN= parameter
93h if the HMA is not allocated
94h if the A20 line is still enabled
A0h if all extended memory is allocated
A1h if all available extended memory handles are in use
A2h if the handle is invalid
A3h if the SourceHandle is invalid
A4h if the SourceOffset is invalid
A5h if the DestHandle is invalid
A6h if the DestOffset is invalid
A7h if the Length is invalid
A8h if the move has an invalid overlap
A9h if a parity error occurs
AAh if the block is not locked
ABh if the block is locked
ACh if the block's lock count overflows
ADh if the lock fails
B0h if a smaller UMB is available
B1h if no UMBs are available
B2h if the UMB segment number is invalid
IMPLEMENTATION NOTES FOR DOS XMS DRIVERS
A DOS XMS driver's control function must begin with code similar to the following:
XMMControl proc far
jmp short XCControlEntry ; For "hookability"
nop ; NOTE: The jump must be a short
nop ; jump to indicate the end of
nop ; any hook chainThe nop's
; allow a far jump to be
; patched in.
XCControlEntry:
XMS drivers must preserve all registers except those containing returned values across any function call.
XMS drivers are required to hook INT 15h and watch for calls to functions 87h (Block Move) and 88h (Extended Memory Available). The INT 15h Block Move function must be hooked so that the state of the A20 line is preserved across the call. The INT 15h Extended Memory Available function must be hooked to return 0h to protect the HMA.
In order to maintain compatibility with existing device drivers, DOS XMS drivers must not hook INT 15h until the first non-Version Number call to the control function is made.
XMS drivers are required to check for the presence of drivers which use the IBM VDISK allocation scheme. Note that it is not sufficient to check for VDISK users at installation time but at the time when the HMA is first allocated. If a VDISK user is detected, the HMA must not be allocated. Microsoft will publish a standard method for detecting drivers which use the VDISK allocation scheme.
XMS drivers which have a fixed number of extended memory handles (most do) should implement a command line parameter for adjusting that number (suggested name "/NUMHANDLES=")
XMS drivers should make sure that the major DOS version number is greater than or equal to 3 before installing themselves.
UMBs cannot occupy memory addresses that can be banked by EMS 4.0. EMS 4.0 takes precedence over UMBs for physically addressable memory.
All driver functions must be re-entrant. Care should be taken to not leave interrupts disabled for long periods of time.
Allocation of a zero length extended memory buffer is allowed. Programs which hook XMS drivers may need to reserve a handle for private use via this method. Programs which hook an XMS driver should pass all requests for zero length EMBs to the next driver in the chain.
Drivers should control the A20 line via an "enable count." Local En- able only enables the A20 line if the count is zero. It then increments the count. Local Disable only disables A20 if the count is one. It then decrements the count. Global Enable/Disable keeps a flag which indicates the state of A20. They use Local Enable/Disable to actually change the state.
Drivers should always check the physical A20 state in the local Enable-Disable calls, to see that the physical state matches the internal count. If the physical state does not match, it should be modified so that it matches the internal count. This avoids problems with applications that modify A20 directly.
IMPLEMENTATION OF CODE FOR HOOKING THE XMS DRIVER
In order to support the hooking of the XMS driver by multiple pieces of code, the following code sample should be followed. Use of other methods for hooking the XMS driver will not work in many cases. This method is the official supported one.
The basic strategy is:
Find the XMS driver header which has the "near jump" dispatch.
Patch the near jump to a FAR jump which jumps to my HOOK XMS driver header.
NOTES:
This architecture allows the most recent HOOKer to undo his XMS driver hook at any time without having to worry about damaging a "hook chain".
This architecture allows the complete XMS hook chain to be enumerated at any time. There are no "hidden hooks".
This architecture allows the HOOKer to not have to worry about installing an "INT 2F hook" to hook the AH=43h INT 2Fs handled by the XMS driver. The base XMS driver continues to be the only one installed on INT 2Fh AH=43h.
This avoids all of the problems of undoing a software interrupt hook.
;
; When I wish to CHAIN to the previous XMS driver, I execute a FAR JMP
; to the address stored in this DWORD.
;
PrevXMSControlAddr dd ?
;
; The next two data items are needed ONLY if I desire to be able to undo
; my XMS hook.
; PrevXMSControlJmpVal stores the previos XMS dispatch near jump offset
; value that is used to unhook my XMS hook
; PrevXMSControlBase stores the address of the XMS header that I hooked
;
PrevXMSControlBase dd ?
PrevXMSControlJmpVal db ?
;
; This is MY XMS control header.
;
MyXMSControlFunc proc FAR
jmp short XMSControlEntry
nop
nop
nop
XMSControlEntry:
......
Chain:
jmp cs:[PrevXMSControlAddr]
MyXMSControlFunc endp
.......
;
; This is the code which installs my hook into the XMS driver.
;
;
; See if there is an XMS driver to hook
;
mov ax,4300h
int 2Fh
cmp al,80h
jne NoXMSDrvrToHookError
;
; Get the current XMS driver Control address
;
mov ax,4310h
int 2Fh
NextXMSHeader:
mov word ptr [PrevXMSControlAddr+2],es
mov word ptr [PrevXMSControlBase+2],es
mov word ptr [PrevXMSControlBase],bx
mov cx,word ptr es:[bx]
cmp cl,0EBh ; Near JUMP
je ComputeNearJmp
cmp cl,0EAh ; Far JUMP
jne XMSDrvrChainMessedUpError
ComputeFarJmp:
mov si,word ptr es:[bx+1] ; Offset of jump
mov es,word ptr es:[bx+1+2] ; Seg of jump
mov bx,si
jmp short NextXMSHeader
ComputeNearJmp:
cmp word ptr es:[bx+2],9090h ; Two NOPs?
jne XMSDrvrChainMessedUpError ; No
cmp byte ptr es:[bx+4],90h ; Total of 3 NOPs?
jne XMSDrvrChainMessedUpError ; No
mov di,bx ; Save pointer to header
xor ax,ax
mov al,ch ; jmp addr of near jump
mov [PrevXMSControlJmpVal],al
add ax,2 ; NEAR JMP is 2 byte instruction
add bx,ax ; Target of jump
mov word ptr [PrevXMSControlAddr],bx
;
; Now INSTALL my XMS HOOK
;
cli ; Disable INTs in case someone calls
; XMS at interrupt time
mov byte ptr es:[di],0EAh ; Far Immed. JUMP instruction
mov word ptr es:[di+1],offset MyXMSControlFunc
mov word ptr es:[di+3],cs
sti
.....
;
; Deinstall my XMS hook. This can be done IF AND ONLY IF my XMS header
; still contains the near jump dispatch
;
cmp byte ptr [MyXMSControlFunc],0EBh
jne CantDeinstallError
mov al,0EBh
mov ah,[PrevXMSControlJmpVal]
les bx,[PrevXMSControlBase]
cli ; Disable INTs in case someone calls
; XMS at interrupt time
mov word ptr es:[bx],ax
mov word ptr es:[bx+2],9090h
mov byte ptr es:[bx+4],90h
sti
....
IMPLEMENTATION NOTES FOR HIMEM.SYS
HIMEM.SYS currently supports true AT-compatibles, 386 AT machines, IBM PS/2s, AT&T 6300 Plus systems and Hewlett Packard Vectras.
If HIMEM finds that it cannot properly control the A20 line or if there is no extended memory available when HIMEM.SYS is invoked, the driver does not install itself. HIMEM.SYS displays the message "High Memory Area Unavailable" when this situation occurs.
If HIMEM finds that the A20 line is already enabled when it is invoked, it will NOT change the A20 line's state. The assumption is that whoever enabled it knew what they were doing. HIMEM.SYS displays the message "A20 Line Permanently Enabled" when this situation occurs.
HIMEM.SYS is incompatible with IBM's VDISK.SYS driver and other drivers which use the VDISK scheme for allocating extended memory. However, HIMEM does attempt to detect these drivers and will not allocate the HMA if one is found.
HIMEM.SYS supports the optional "/HMAMIN=" parameter. The valid values are decimal numbers between 0 and 63.
By default, HIMEM.SYS has 32 extended memory handles available for use. This number may be adjusted with the "/NUMHANDLES=" parameter. The maximum value for this parameter is 128 and the minimum is 0. Each handle currently requires 6 bytes of resident space.
--------------------------------------------------------------------------------
Microsoft Corporation
Box 97017
One Microsoft Way
Redmond, WA 98073
LOTUS ?
INTEL ?
MICROSOFT ?
AST ? Research
This specification was jointly developed by Microsoft Corporation, Lotus Development Corporation, Intel Corporation,and AST Research, Inc. Although it has been released into the public domain and is not confidential or proprietary, the specification is still the copyright and property of Microsoft Corporation, Lotus Development Corporation, Intel Corporation, and AST Research, Inc.
Disclaimer of Warranty
MICROSOFT CORPORATION, LOTUS DEVELOPMENT CORPORATION, INTEL CORPORATION, AND AST RESEARCH, INC., EXCLUDE ANY AND ALL IMPLIED WARRANTIES, INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. NEITHER MICROSOFT NOR LOTUS NOR INTEL NOR AST RESEARCH MAKE ANY WARRANTY OF REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS SPECIFICATION, ITS QUALITY, PERFORMANCE, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. NEITHER MICROSOFT NOR LOTUS NOR INTEL NOR AST RESEARCH SHALL HAVE ANY LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RESULTING FROM THE USE OR MODIFICATION OF THIS SPECIFICATION.
This specification uses the following trademarks:
Intel is a registered trademark of Intel Corporation, Microsoft is a registered trademark of Microsoft Corporation, Lotus is a registered trademark of Lotus Development Corporation, and AST is a registered trademark of AST Research, Inc.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -