]> 4ch.mooo.com Git - 16.git/blob - 16/PCGPE10/XMS30.TXT
reverted my open watcom to 1.9 an recompiled everything~
[16.git] / 16 / PCGPE10 / XMS30.TXT
1 eXtended Memory Specification (XMS), ver 3.0\r
2 \r
3 \r
4 January 1991\r
5 \r
6 \r
7 Copyright (c) 1988, Microsoft Corporation, Lotus Development\r
8 Corporation, Intel Corporation, and AST Research, Inc.\r
9 \r
10 Microsoft Corporation                                            \r
11 Box 97017\r
12 \r
13 One Microsoft Way                                       \r
14 Redmond, WA 98073\r
15 \r
16 LOTUS (r)\r
17 INTEL (r)\r
18 MICROSOFT (r)\r
19 AST (r) Research\r
20 \r
21 This specification was jointly developed by Microsoft Corporation,\r
22 Lotus Development Corporation, Intel Corporation,and AST Research,\r
23 Inc. Although it has been released into the public domain and is not\r
24 confidential or proprietary, the specification is still the copyright\r
25 and property of Microsoft Corporation, Lotus Development Corporation,\r
26 Intel Corporation, and AST Research, Inc.\r
27 \r
28 Disclaimer of Warranty\r
29 \r
30 MICROSOFT CORPORATION, LOTUS DEVELOPMENT CORPORATION, INTEL\r
31 CORPORATION, AND AST RESEARCH, INC., EXCLUDE ANY AND ALL IMPLIED\r
32 WARRANTIES, INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
33 PARTICULAR PURPOSE. NEITHER MICROSOFT NOR LOTUS NOR INTEL NOR AST\r
34 RESEARCH MAKE ANY WARRANTY OF REPRESENTATION, EITHER EXPRESS OR\r
35 IMPLIED, WITH RESPECT TO THIS SPECIFICATION, ITS QUALITY,\r
36 PERFORMANCE, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.\r
37 NEITHER MICROSOFT NOR LOTUS NOR INTEL NOR AST RESEARCH SHALL HAVE ANY\r
38 LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING\r
39 OUT OF OR RESULTING FROM THE USE OR MODIFICATION OF THIS\r
40 SPECIFICATION.\r
41 \r
42 This specification uses the following trademarks:\r
43 \r
44 Intel is a registered trademark of Intel Corporation, Microsoft is a\r
45 registered trademark of Microsoft Corporation, Lotus is a registered\r
46 trademark of Lotus Development Corporation, and AST is a registered\r
47 trademark of AST Research, Inc.\r
48 \r
49 \r
50 \r
51 Extended Memory Specification\r
52 \r
53     The purpose of this document is to define the Extended Memory Specification (XMS) version 3.00 for MS-DOS.  XMS allows DOS programs to utilize additional memory found in Intel's 80286 and 80386 based machines in a consistent, machine independent manner.  With some restrictions, XMS adds almost 64K to the 640K which DOS programs can access directly.  Depending on available hardware, XMS may provide even more memory to DOS programs.  XMS also provides DOS programs with a standard method of storing data in extended memory.\r
54 \r
55         To be considered fully XMS 3.0 compliant, all calls except those associated with UMB support must be implemented. UMB functions 10h, 11h and 12h are optional for XMS 3.0 and may return the Function Not Implemented error code, 80h.\r
56 \r
57 DEFINITIONS:\r
58 ------------\r
59 \r
60 Extended Memory:\r
61 Memory in 80286 and 80386 based machines which is located above the 1MB address boundary.\r
62 \r
63 High Memory Area (HMA):\r
64 The first 64K of extended memory.  The High Memory Area is unique because code can be executed in it while in real mode.  The HMA officially starts at FFFF:10h and ends at FFFF:FFFFh making it 64K-16 bytes in length.\r
65                     \r
66 Upper Memory Blocks (UMBs):\r
67 Blocks of memory available on some 80x86 based machines which are located between DOS's 640K limit and the 1MB address boundary.  The number, size, and location of these blocks vary widely depending upon the types of hardware adapter cards installed in the machine.\r
68                     \r
69 Extended Memory Blocks (EMBs):\r
70 Blocks of extended memory located above the HMA which can only be used for data storage.\r
71                     \r
72 A20 Line:\r
73 The 21st address line of 80x86 CPUs.  Enabling the A20 line allows access to the HMA.\r
74 \r
75 XMM:\r
76 An Extended Memory Manager.  A DOS device driver which implements XMS.  XMMs are machine specific but allow programs to use extended memory in a machine-independent manner.\r
77     \r
78 HIMEM.SYS:\r
79 The Extended Memory Manager currently being distributed by Microsoft.\r
80 \r
81 \r
82 \r
83 Helpful Diagram:\r
84 \r
85 |               |   Top of Memory\r
86 |               |\r
87 |               |\r
88 |       /\      |\r
89 |       /||\    |\r
90 |       ||      |\r
91 |       ||      |\r
92 |               |\r
93 |               |\r
94 |               |\r
95 |       Possible Extended Memory Block  |\r
96 |               |\r
97 |               |\r
98 |               |\r
99 |       ||      |\r
100 |       ||      |\r
101 |       \||/    |\r
102 |       \/      |\r
103 |               |\r
104 |               |\r
105 |       Other EMBs could exist above 1088K (1MB+64K)    |\r
106 |               |\r
107 |               |\r
108 |               |   1088K\r
109 |               |\r
110 |               |\r
111 |       The High Memory Area    |\r
112 |               |\r
113 |               |\r
114 |               |   1024K or 1MB\r
115 |               |\r
116 |       /\      |\r
117 |       /||\    |\r
118 |       ||      |\r
119 |       ||      |\r
120 |               |\r
121 |               |\r
122 |       Possible Upper Memory Block     |\r
123 |               |\r
124 |       ||      |\r
125 |       ||      |\r
126 |       \||/    |\r
127 |       \/      |\r
128 |               |\r
129 |       Other UMBs could exist between 640K and 1MB     |\r
130 |               |\r
131 |               |   640K\r
132 \r
133 |               |\r
134 |               |\r
135 |               |\r
136 |       Conventional or DOS Memory      |\r
137 |               |\r
138 |               |\r
139 |               |\r
140 |               |\r
141 |               |\r
142 +               +   0K\r
143 \r
144 DRIVER INSTALLATION:\r
145 --------------------\r
146 \r
147     An XMS driver is installed by including a DEVICE= statement in the\r
148 machine's CONFIG.SYS file.  It must be installed prior to any other\r
149 devices or TSRs which use it.  An optional parameter after the driver's \r
150 name (suggested name "/HMAMIN=") indicates the minimum amount of space in\r
151 the HMA a program can use.  Programs which use less than the minimum will\r
152 not be placed in the HMA.  See "Prioritizing HMA Usage" below for more\r
153 information.  A second optional parameter (suggested name "/NUMHANDLES=")\r
154 allows users to specify the maximum number of extended memory blocks which\r
155 may be allocated at any time.\r
156 \r
157     NOTE: XMS requires DOS 3.00 or above.\r
158 \r
159 \r
160 THE PROGRAMMING API:\r
161 --------------------\r
162 \r
163     The XMS API Functions are accessed via the XMS driver's Control Function.\r
164 The address of the Control Function is determined via INT 2Fh.  First, a\r
165 program should determine if an XMS driver is installed.  Next, it should\r
166 retrieve the address of the driver's Control Function.  It can then use any\r
167 of the available XMS functions.  The functions are divided into several\r
168 groups:\r
169 \r
170         1. Driver Information Functions (0h)\r
171         2. HMA Management Functions (1h-2h)\r
172         3. A20 Management Functions (3h-7h)\r
173         4. Extended Memory Management Functions (8h-Fh)\r
174         5. Upper Memory Management Functions (10h-11h)\r
175 \r
176 \r
177 DETERMINING IF AN XMS DRIVER IS INSTALLED:\r
178 ------------------------------------------\r
179 \r
180     The recommended way of determining if an XMS driver is installed is to\r
181 set AH=43h and AL=00h and then execute INT 2Fh.  If an XMS driver is available,\r
182 80h will be returned in AL.\r
183 \r
184     Example:\r
185             ; Is an XMS driver installed?\r
186             mov     ax,4300h\r
187             int     2Fh         \r
188             cmp     al,80h  \r
189             jne     NoXMSDriver\r
190             \r
191 \r
192 CALLING THE API FUNCTIONS:\r
193 --------------------------\r
194 \r
195     Programs can execute INT 2Fh with AH=43h and AL=10h to obtain the address\r
196 of the driver's control function.  The address is returned in ES:BX.  This\r
197 function is called to access all of the XMS functions.  It should be called\r
198 with AH set to the number of the API function requested.  The API function\r
199 will put a success code of 0001h or 0000h in AX.  If the function succeeded\r
200 (AX=0001h), additional information may be passed back in BX and DX.  If the\r
201 function failed (AX=0000h), an error code may be returned in BL.  Valid\r
202 error codes have their high bit set.  Developers should keep in mind that\r
203 some of the XMS API functions may not be implemented by all drivers and will\r
204 return failure in all cases.\r
205 \r
206     Example:\r
207             ; Get the address of the driver's control function\r
208             mov     ax,4310h\r
209             int     2Fh\r
210             mov     word ptr [XMSControl],bx        ; XMSControl is a DWORD\r
211             mov     word ptr [XMSControl+2],es\r
212             \r
213             ; Get the XMS driver's version number\r
214             mov     ah,00h\r
215             call    [XMSControl]    ; Get XMS Version Number\r
216 \r
217     NOTE: Programs should make sure that at least 256 bytes of stack space\r
218           is available before calling XMS API functions.\r
219 \r
220 \r
221 API FUNCTION DESCRIPTIONS:\r
222 --------------------------\r
223 \r
224     The following XMS API functions are available:\r
225 \r
226        0h)  Get XMS Version Number\r
227        1h)  Request High Memory Area\r
228        2h)  Release High Memory Area\r
229        3h)  Global Enable A20\r
230        4h)  Global Disable A20\r
231        5h)  Local Enable A20\r
232        6h)  Local Disable A20\r
233        7h)  Query A20\r
234        8h)  Query Free Extended Memory\r
235        9h)  Allocate Extended Memory Block\r
236        Ah)  Free Extended Memory Block\r
237        Bh)  Move Extended Memory Block\r
238        Ch)  Lock Extended Memory Block\r
239        Dh)  Unlock Extended Memory Block\r
240        Eh)  Get Handle Information\r
241        Fh)  Reallocate Extended Memory Block\r
242       10h)  Request Upper Memory Block\r
243       11h)  Release Upper Memory Block\r
244       12h) Realloc Upper Memory Block\r
245       88h) Query any Free Extended Memory\r
246       89h) Allocate any Extended Memory Block\r
247       8Eh) Get Extended EMB Handle\r
248       8Fh) Realloc any Extended Memory\r
249 \r
250 Each is described below.\r
251 \r
252 \r
253 Get XMS Version Number (Function 00h):\r
254 --------------------------------------\r
255 \r
256     ARGS:   AH = 00h\r
257     RETS:   AX = XMS version number\r
258             BX = Driver internal revision number\r
259             DX = 0001h if the HMA exists, 0000h otherwise\r
260     ERRS:   None\r
261 \r
262     This function returns with AX equal to a 16-bit BCD number representing\r
263 the revision of the DOS Extended Memory Specification which the driver\r
264 implements (e.g. AX=0235h would mean that the driver implemented XMS version\r
265 2.35).  BX is set equal to the driver's internal revision number mainly for\r
266 debugging purposes.  DX indicates the existence of the HMA (not its\r
267 availability) and is intended mainly for installation programs.\r
268     \r
269     NOTE: This document defines version 3.00 of the specification.\r
270 \r
271 \r
272 Request High Memory Area (Function 01h):\r
273 ----------------------------------------\r
274 \r
275     ARGS:   AH = 01h\r
276             If the caller is a TSR or device driver,\r
277                 DX = Space needed in the HMA by the caller in bytes\r
278             If the caller is an application program,\r
279                 DX = FFFFh     \r
280     RETS:   AX = 0001h if the HMA is assigned to the caller, 0000h otherwise\r
281     ERRS:   BL = 80h if the function is not implemented\r
282             BL = 81h if a VDISK device is detected\r
283             BL = 90h if the HMA does not exist\r
284             BL = 91h if the HMA is already in use\r
285             BL = 92h if DX is less than the /HMAMIN= parameter\r
286 \r
287     This function attempts to reserve the 64K-16 byte high memory area for\r
288 the caller.  If the HMA is currently unused, the caller's size parameter is\r
289 compared to the /HMAMIN= parameter on the driver's command line.  If the\r
290 value passed by the caller is greater than or equal to the amount specified\r
291 by the driver's parameter, the request succeeds.  This provides the ability\r
292 to ensure that programs which use the HMA efficiently have priority over\r
293 those which do not.\r
294 \r
295     NOTE: See the sections "Prioritizing HMA Usage" and "High Memory Area\r
296           Restrictions" below for more information.\r
297 \r
298 \r
299 Release High Memory Area (Function 02h):\r
300 ----------------------------------------\r
301 \r
302     ARGS:   AH = 02h\r
303     RETS:   AX = 0001h if the HMA is successfully released, 0000h otherwise\r
304     ERRS:   BL = 80h if the function is not implemented\r
305             BL = 81h if a VDISK device is detected\r
306             BL = 90h if the HMA does not exist\r
307             BL = 93h if the HMA was not allocated\r
308 \r
309     This function releases the high memory area and allows other programs to\r
310 use it.  Programs which allocate the HMA must release it before exiting.  \r
311 When the HMA has been released, any code or data stored in it becomes invalid\r
312 and should not be accessed.\r
313 \r
314 \r
315 Global Enable A20 (Function 03h):\r
316 ---------------------------------\r
317 \r
318     ARGS:   AH = 03h\r
319     RETS:   AX = 0001h if the A20 line is enabled, 0000h otherwise\r
320     ERRS:   BL = 80h if the function is not implemented\r
321             BL = 81h if a VDISK device is detected\r
322             BL = 82h if an A20 error occurs\r
323 \r
324     This function attempts to enable the A20 line.  It should only be used\r
325 by programs which have control of the HMA.  The A20 line should be turned\r
326 off via Function 04h (Global Disable A20) before a program releases control\r
327 of the system.\r
328 \r
329     NOTE: On many machines, toggling the A20 line is a relatively slow\r
330           operation.\r
331 \r
332 \r
333 Global Disable A20 (Function 04h):\r
334 ----------------------------------\r
335 \r
336     ARGS:   AH = 04h\r
337     RETS:   AX = 0001h if the A20 line is disabled, 0000h otherwise\r
338     ERRS:   BL = 80h if the function is not implemented\r
339             BL = 81h if a VDISK device is detected\r
340             BL = 82h if an A20 error occurs\r
341             BL = 94h if the A20 line is still enabled\r
342     \r
343     This function attempts to disable the A20 line.  It should only be used\r
344 by programs which have control of the HMA.  The A20 line should be disabled\r
345 before a program releases control of the system.\r
346 \r
347     NOTE: On many machines, toggling the A20 line is a relatively slow\r
348           operation.\r
349 \r
350 \r
351 Local Enable A20 (Function 05h):\r
352 --------------------------------\r
353 \r
354     ARGS:   AH = 05h\r
355     RETS:   AX = 0001h if the A20 line is enabled, 0000h otherwise\r
356     ERRS:   BL = 80h if the function is not implemented\r
357             BL = 81h if a VDISK device is detected\r
358             BL = 82h if an A20 error occurs\r
359 \r
360     This function attempts to enable the A20 line.  It should only be used\r
361 by programs which need direct access to extended memory.  Programs which use\r
362 this function should call Function 06h (Local Disable A20) before releasing\r
363 control of the system.\r
364 \r
365     NOTE: On many machines, toggling the A20 line is a relatively slow\r
366           operation.\r
367 \r
368 \r
369 Local Disable A20 (Function 06h):\r
370 ---------------------------------\r
371 \r
372     ARGS:   AH = 06h\r
373     RETS:   AX = 0001h if the function succeeds, 0000h otherwise\r
374     ERRS:   BL = 80h if the function is not implemented\r
375             BL = 81h if a VDISK device is detected\r
376             BL = 82h if an A20 error occurs\r
377             BL = 94h if the A20 line is still enabled\r
378 \r
379     This function cancels a previous call to Function 05h (Local Enable\r
380 A20).  It should only be used by programs which need direct access to\r
381 extended memory.  Previous calls to Function 05h must be canceled before\r
382 releasing control of the system.\r
383 \r
384     NOTE: On many machines, toggling the A20 line is a relatively slow\r
385           operation.\r
386 \r
387 \r
388 Query A20 (Function 07h):\r
389 -------------------------\r
390 \r
391     ARGS:   AH = 07h\r
392     RETS:   AX = 0001h if the A20 line is physically enabled, 0000h otherwise\r
393     ERRS:   BL = 00h if the function succeeds\r
394             BL = 80h if the function is not implemented\r
395             BL = 81h if a VDISK device is detected\r
396 \r
397     This function checks to see if the A20 line is physically enabled.  It\r
398 does this in a hardware independent manner by seeing if "memory wrap" occurs.\r
399 \r
400 \r
401 Query Free Extended Memory (Function 08h):\r
402 ------------------------------------------\r
403 \r
404     ARGS:   AH = 08h\r
405     RETS:   AX = Size of the largest free extended memory block in K-bytes\r
406             DX = Total amount of free extended memory in K-bytes\r
407     ERRS:   BL = 80h if the function is not implemented\r
408             BL = 81h if a VDISK device is detected\r
409             BL = A0h if all extended memory is allocated\r
410 \r
411     This function returns the size of the largest available extended memory\r
412 block in the system.\r
413 \r
414     NOTE: The 64K HMA is not included in the returned value even if it is\r
415           not in use.\r
416 \r
417 \r
418 Allocate Extended Memory Block (Function 09h):\r
419 ----------------------------------------------\r
420 \r
421     ARGS:   AH = 09h\r
422             DX = Amount of extended memory being requested in K-bytes\r
423     RETS:   AX = 0001h if the block is allocated, 0000h otherwise\r
424             DX = 16-bit handle to the allocated block\r
425     ERRS:   BL = 80h if the function is not implemented\r
426             BL = 81h if a VDISK device is detected\r
427             BL = A0h if all available extended memory is allocated\r
428             BL = A1h if all available extended memory handles are in use\r
429             \r
430     This function attempts to allocate a block of the given size out of the\r
431 pool of free extended memory.  If a block is available, it is reserved\r
432 for the caller and a 16-bit handle to that block is returned.  The handle\r
433 should be used in all subsequent extended memory calls.  If no memory was\r
434 allocated, the returned handle is null.\r
435 \r
436     NOTE: Extended memory handles are scarce resources.  Programs should\r
437           try to allocate as few as possible at any one time.  When all\r
438           of a driver's handles are in use, any free extended memory is\r
439           unavailable.\r
440 \r
441 \r
442 \r
443 Free Extended Memory Block (Function 0Ah):\r
444 ------------------------------------------\r
445 \r
446     ARGS:   AH = 0Ah\r
447             DX = Handle to the allocated block which should be freed\r
448     RETS:   AX = 0001h if the block is successfully freed, 0000h otherwise\r
449     ERRS:   BL = 80h if the function is not implemented\r
450             BL = 81h if a VDISK device is detected\r
451             BL = A2h if the handle is invalid\r
452             BL = ABh if the handle is locked\r
453 \r
454     This function frees a block of extended memory which was previously\r
455 allocated using Function 09h (Allocate Extended Memory Block).  Programs\r
456 which allocate extended memory should free their memory blocks before\r
457 exiting.  When an extended memory buffer is freed, its handle and all data\r
458 stored in it become invalid and should not be accessed.\r
459 \r
460 \r
461 Move Extended Memory Block (Function 0Bh):\r
462 ------------------------------------------\r
463 \r
464     ARGS:   AH = 0Bh\r
465             DS:SI = Pointer to an Extended Memory Move Structure (see below)\r
466     RETS:   AX = 0001h if the move is successful, 0000h otherwise\r
467     ERRS:   BL = 80h if the function is not implemented\r
468             BL = 81h if a VDISK device is detected\r
469             BL = 82h if an A20 error occurs\r
470             BL = A3h if the SourceHandle is invalid\r
471             BL = A4h if the SourceOffset is invalid\r
472             BL = A5h if the DestHandle is invalid\r
473             BL = A6h if the DestOffset is invalid\r
474             BL = A7h if the Length is invalid\r
475             BL = A8h if the move has an invalid overlap\r
476             BL = A9h if a parity error occurs\r
477 \r
478     Extended Memory Move Structure Definition:\r
479 \r
480         ExtMemMoveStruct    struc\r
481             Length              dd  ?   ; 32-bit number of bytes to transfer\r
482             SourceHandle        dw  ?   ; Handle of source block\r
483             SourceOffset        dd  ?   ; 32-bit offset into source \r
484             DestHandle          dw  ?   ; Handle of destination block\r
485             DestOffset          dd  ?   ; 32-bit offset into destination block\r
486         ExtMemMoveStruct    ends\r
487             \r
488     This function attempts to transfer a block of data from one location to\r
489 another.  It is primarily intended for moving blocks of data between\r
490 conventional memory and extended memory, however it can be used for moving\r
491 blocks within conventional memory and within extended memory.\r
492 \r
493     NOTE: If SourceHandle is set to 0000h, the SourceOffset is interpreted\r
494           as a standard segment:offset pair which refers to memory that is\r
495           directly accessible by the processor.  The segment:offset pair\r
496           is stored in Intel DWORD notation.  The same is true for DestHandle\r
497           and DestOffset.\r
498           \r
499           SourceHandle and DestHandle do not have to refer to locked memory\r
500           blocks.\r
501           \r
502           Length must be even.  Although not required, WORD-aligned moves\r
503           can be significantly faster on most machines.  DWORD aligned move\r
504           can be even faster on 80386 machines.\r
505           \r
506           If the source and destination blocks overlap, only forward moves\r
507           (i.e. where the source base is less than the destination base) are\r
508           guaranteed to work properly.\r
509           \r
510           Programs should not enable the A20 line before calling this\r
511           function.  The state of the A20 line is preserved.\r
512 \r
513           This function is guaranteed to provide a reasonable number of\r
514           interrupt windows during long transfers.\r
515           \r
516           \r
517 Lock Extended Memory Block (Function 0Ch):\r
518 ------------------------------------------\r
519 \r
520     ARGS:   AH = 0Ch\r
521             DX = Extended memory block handle to lock\r
522     RETS:   AX = 0001h if the block is locked, 0000h otherwise\r
523             DX:BX = 32-bit physical address of the locked block\r
524     ERRS:   BL = 80h if the function is not implemented\r
525             BL = 81h if a VDISK device is detected\r
526             BL = A2h if the handle is invalid\r
527             BL = ACh if the block's lock count overflows\r
528             BL = ADh if the lock fails\r
529             \r
530     This function locks an extended memory block and returns its base \r
531 address as a 32-bit physical address.  Locked memory blocks are guaranteed not\r
532 to move.  The 32-bit pointer is only valid while the block is locked.\r
533 Locked blocks should be unlocked as soon as possible.\r
534 \r
535     NOTE: A block does not have to be locked before using Function 0Bh (Move\r
536           Extended Memory Block).\r
537           \r
538           "Lock counts" are maintained for EMBs.\r
539 \r
540 \r
541 \r
542 Unlock Extended Memory Block (Function 0Dh):\r
543 --------------------------------------------\r
544 \r
545     ARGS:   AH = 0Dh\r
546             DX = Extended memory block handle to unlock\r
547     RETS:   AX = 0001h if the block is unlocked, 0000h otherwise\r
548     ERRS:   BL = 80h if the function is not implemented\r
549             BL = 81h if a VDISK device is detected\r
550             BL = A2h if the handle is invalid\r
551             BL = AAh if the block is not locked\r
552     \r
553     This function unlocks a locked extended memory block.  Any 32-bit\r
554 pointers into the block become invalid and should no longer be used.\r
555 \r
556 \r
557 Get EMB Handle Information (Function 0Eh):\r
558 ------------------------------------------\r
559 \r
560     ARGS:   AH = 0Eh\r
561             DX = Extended memory block handle\r
562     RETS:   AX = 0001h if the block's information is found, 0000h otherwise\r
563             BH = The block's lock count\r
564             BL = Number of free EMB handles in the system\r
565             DX = The block's length in K-bytes\r
566     ERRS:   BL = 80h if the function is not implemented\r
567             BL = 81h if a VDISK device is detected\r
568             BL = A2h if the handle is invalid\r
569 \r
570     This function returns additional information about an extended memory\r
571 block to the caller.\r
572 \r
573     NOTE: To get the block's base address, use Function 0Ch (Lock Extended\r
574           Memory Block).\r
575           \r
576           \r
577 Reallocate Extended Memory Block (Function 0Fh):\r
578 ------------------------------------------------\r
579 \r
580     ARGS:   AH = 0Fh\r
581             BX = New size for the extended memory block in K-bytes\r
582             DX = Unlocked extended memory block handle to reallocate\r
583     RETS:   AX = 0001h if the block is reallocated, 0000h otherwise\r
584     ERRS:   BL = 80h if the function is not implemented\r
585             BL = 81h if a VDISK device is detected\r
586             BL = A0h if all available extended memory is allocated\r
587             BL = A1h if all available extended memory handles are in use\r
588             BL = A2h if the handle is invalid\r
589             BL = ABh if the block is locked\r
590 \r
591     This function attempts to reallocate an unlocked extended memory block\r
592 so that it becomes the newly specified size.  If the new size is smaller\r
593 than the old block's size, all data at the upper end of the old block is\r
594 lost.\r
595 \r
596 \r
597 Request Upper Memory Block (Function 10h):\r
598 ------------------------------------------\r
599 \r
600     ARGS:   AH = 10h\r
601             DX = Size of requested memory block in paragraphs\r
602     RETS:   AX = 0001h if the request is granted, 0000h otherwise\r
603             BX = Segment number of the upper memory block\r
604             If the request is granted,\r
605                 DX = Actual size of the allocated block in paragraphs\r
606             otherwise,\r
607                 DX = Size of the largest available UMB in paragraphs\r
608     ERRS:   BL = 80h if the function is not implemented\r
609             BL = B0h if a smaller UMB is available\r
610             BL = B1h if no UMBs are available\r
611 \r
612     This function attempts to allocate an upper memory block to the caller.\r
613 If the function fails, the size of the largest free UMB is returned in DX.\r
614 \r
615     NOTE: By definition UMBs are located below the 1MB address boundary.\r
616           The A20 Line does not need to be enabled before accessing an\r
617           allocated UMB.\r
618 \r
619           UMBs are paragraph aligned.\r
620 \r
621           To determine the size of the largest available UMB, attempt to\r
622           allocate one with a size of FFFFh.\r
623 \r
624           UMBs are unaffected by EMS calls.\r
625 \r
626 \r
627 Release Upper Memory Block (Function 11h):\r
628 ------------------------------------------\r
629 \r
630     ARGS:   AH = 11h\r
631             DX = Segment number of the upper memory block\r
632     RETS:   AX = 0001h if the block was released, 0000h otherwise\r
633     ERRS:   BL = 80h if the function is not implemented\r
634             BL = B2h if the UMB segment number is invalid\r
635 \r
636     This function frees a previously allocated upper memory block.  When an\r
637 UMB has been released, any code or data stored in it becomes invalid and\r
638 should not be accessed.\r
639 \r
640 \r
641 \r
642 \r
643 Reallocate Upper Memory Block (Function 12h)\r
644 \r
645         ARGS:\r
646                 AH = 12h\r
647                 BX = New size for UMB in paragraphs\r
648                 DX = Segment number of the UMB to reallocate\r
649         RETS:\r
650                 AX = 1 if the block was reallocated, 0 otherwise\r
651         ERRS:\r
652                 BL = 80h if the function is not implemented\r
653                 BL = B0h if no UMB large enough to satisfy the request is available.\r
654                         In this event, DX is returned with the size of the largest UMB that is                  available.\r
655                 BL = B2h if the UMB segment number is invalid\r
656 \r
657 This function attempts to reallocate an Upper Memory Block to a newly specified size.  If the new size is smaller than the old block's size, all data at the upper end of the block is lost.\r
658 \r
659 \r
660 \r
661 Super Extended Memory Support\r
662 \r
663 These changes are intended to provide support for extended memory pools up to 4 Gb in size.  The current XMS API, since it uses 16-bit values to specify block sizes in Kb, is limited to 64 Mb maximum block size.  Future machines are expected to support memory above 64 MB.\r
664 \r
665 This support is implemented in the form of extensions to existing functions, rather than entirely new entry points, to allow for more efficient implementations.\r
666 \r
667 Programs should generally use the existing functions, instead of these extended ones, unless they have an explicit need to deal with memory above 64 Mb.  \r
668 \r
669 \r
670 Query Any Free Extended Memory (Function 88h)\r
671 \r
672         Entry:\r
673                 AH = 88h                        \r
674         Exit:\r
675                 EAX = Size of largest free extended memory block in Kb.\r
676                 BL = 0 if no error occurs, otherwise it takes an error code.\r
677                 ECX = Highest ending address of any memory block.\r
678                 EDX = Total amount of free memory in Kb.\r
679         Errors:\r
680                 BL = 80h if the function is not implemented.\r
681                 BL = 81h if a VDISK device is detected.\r
682                 BL = A0h if all extended memory is allocated.\r
683 \r
684 This function uses 32-bit values to return the size of available memory, thus allowing returns up to 4GByte.  Additionally, it returns the highest known physical memory address, that is, the physical address of the last byte of memory.  There may be discontinuities in the memory map below this address.\r
685 \r
686 The memory pool reported on is the same as that reported on by the existing Query Free Extended Memory function.  If the highest memory address is not more than 64 Mb, then these two functions will return the same results.\r
687 \r
688 Because of its reliance on 32-bit registers, this function is only available on 80386 and higher processors.  XMS drivers on 80286 machines should return error code 80h if this function is called.\r
689 \r
690 If error code 81h is returned, the value in ECX will still be valid.  If error code A0h is returned, EAX and EDX will be 0, and ECX will still be valid.\r
691 \r
692 \r
693 Allocate Any Extended Memory (Function 89h)\r
694 \r
695         Entry:\r
696                 AH = 89h\r
697                 EDX = Amount of extended memory requested, in Kb.\r
698         Exit:\r
699                 AX = 1 if the block is allocated, 0 if not\r
700                 DX = Handle to allocated block.\r
701         Errors:\r
702                 BL = 80h if the function is not implemented.\r
703                 BL = 81h if a VDISK device is detected.\r
704                 BL = A0h if all available extended memory is allocated.\r
705                 BL = A1h if all available extended memory handles are in use.\r
706 \r
707 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.\r
708 \r
709 \r
710 Get Extended EMB Handle Information (Function 8Eh)\r
711 \r
712         Entry:\r
713                 AH = 8Eh\r
714                 DX = Extended memory block handle.\r
715         Exit:\r
716                 AX = 1 if the block's information is found, 0 if not\r
717                 BH = Block lock count\r
718                 CX = Number of free EMB handles in the system\r
719                 EDX = Block's length in Kb.\r
720         Errors:\r
721                 BL = 80h if the function is not implemented.\r
722                 BL = 81h if a VDISK device is detected.\r
723                 BL = A2h if the handle is invalid.\r
724 \r
725 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.\r
726 \r
727 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.\r
728 \r
729 \r
730 Reallocate Any Extended Memory (Function 8Fh)\r
731 \r
732         Entry:\r
733                 AH = 8Fh\r
734                 EBX = New size for extended memory block, in Kb.\r
735                 DX = Unlocked handle for memory block to be resized.\r
736         Exit:\r
737                 AX = 1 if the block is reallocated, 0 if not\r
738         Errors:\r
739                 BL = 80h if the function is not implemented.\r
740                 BL = 81h if a VDISK device is detected.\r
741                 BL = A0h if all available extended memory is allocated.\r
742                 BL = A1h if all available extended memory handles are in use.\r
743                 BL = A2h if the handle is invalid.\r
744                 BL = ABh if the block is locked.\r
745 \r
746 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.\r
747 \r
748 \r
749 \r
750 \r
751 PRIORITIZING HMA USAGE:\r
752 -----------------------\r
753 \r
754     For DOS users to receive the maximum benefit from the High Memory Area,\r
755 programs which use the HMA must store as much of their resident code in it as\r
756 is possible.  It is very important that developers realize that the HMA is\r
757 allocated as a single unit. \r
758 \r
759     For example, a TSR program which grabs the HMA and puts 10K of code into\r
760 it may prevent a later TSR from putting 62K into the HMA.  Obviously, regular\r
761 DOS programs would have more memory available to them below the 640K line if\r
762 the 62K TSR was moved into the HMA instead of the 10K one.\r
763 \r
764     The first method for dealing with conflicts such as this is to require \r
765 programs which use the HMA to provide a command line option for disabling\r
766 this feature.  It is crucial that TSRs which do not make full use of the HMA\r
767 provide such a switch on their own command line (suggested name "/NOHMA").\r
768 \r
769     The second method for optimizing HMA usage is through the /HMAMIN=\r
770 parameter on the XMS device driver line.  The number after the parameter\r
771 is defined to be the minimum amount of HMA space (in K-bytes) used by any\r
772 driver or TSR.  For example, if "DEVICE=HIMEM.SYS /HMAMIN=48" is in a\r
773 user's CONFIG.SYS file, only programs which request at least 48K would be\r
774 allowed to allocate the HMA.  This number can be adjusted either by\r
775 installation programs or by the user himself.  If this parameter is not\r
776 specified, the default value of 0 is used causing the HMA to be allocated\r
777 on a first come, first served basis.\r
778 \r
779     Note that this problem does not impact application programs.  If the HMA\r
780 is available when an application program starts, the application is free to\r
781 use as much or as little of the HMA as it wants.  For this reason,\r
782 applications should pass FFFFh in DX when calling Function 01h.\r
783 \r
784 \r
785 \r
786 HIGH MEMORY AREA RESTRICTIONS:\r
787 ------------------------------\r
788 \r
789 -   Far pointers to data located in the HMA cannot be passed to DOS.  DOS\r
790     normalizes any pointer which is passed into it.  This will cause data\r
791     addresses in the HMA to be invalidated.\r
792 \r
793 -   Disk I/O directly into the HMA (via DOS, INT 13h, or otherwise) is not\r
794     recommended.\r
795        \r
796 -   Programs, especially drivers and TSRs, which use the HMA *MUST* use\r
797     as much of it as possible.  If a driver or TSR is unable to use at\r
798     least 90% of the available HMA (typically ~58K), they must provide\r
799     a command line switch for overriding HMA usage.  This will allow\r
800     the user to configure his machine for optimum use of the HMA.\r
801        \r
802 -   Device drivers and TSRs cannot leave the A20 line permanently turned\r
803     on.  Several applications rely on 1MB memory wrap and will overwrite the\r
804     HMA if the A20 line is left enabled potentially causing a system crash.\r
805         \r
806 -   Interrupt vectors must not point into the HMA.  This is a result of\r
807     the previous restriction.  Note that interrupt vectors can point into\r
808     any allocated upper memory blocks however.\r
809 \r
810 ERROR CODE INDEX:\r
811 -----------------\r
812 \r
813 If AX=0000h when a function returns and the high bit of BL is set,\r
814 \r
815     BL=80h if the function is not implemented\r
816        81h if a VDISK device is detected\r
817        82h if an A20 error occurs\r
818        8Eh if a general driver error occurs\r
819        8Fh if an unrecoverable driver error occurs\r
820        90h if the HMA does not exist\r
821        91h if the HMA is already in use\r
822        92h if DX is less than the /HMAMIN= parameter\r
823        93h if the HMA is not allocated\r
824        94h if the A20 line is still enabled\r
825        A0h if all extended memory is allocated\r
826        A1h if all available extended memory handles are in use\r
827        A2h if the handle is invalid\r
828        A3h if the SourceHandle is invalid\r
829        A4h if the SourceOffset is invalid\r
830        A5h if the DestHandle is invalid\r
831        A6h if the DestOffset is invalid\r
832        A7h if the Length is invalid\r
833        A8h if the move has an invalid overlap\r
834        A9h if a parity error occurs\r
835        AAh if the block is not locked\r
836        ABh if the block is locked\r
837        ACh if the block's lock count overflows\r
838        ADh if the lock fails\r
839        B0h if a smaller UMB is available\r
840        B1h if no UMBs are available\r
841        B2h if the UMB segment number is invalid\r
842 \r
843 \r
844 IMPLEMENTATION NOTES FOR DOS XMS DRIVERS:\r
845 -----------------------------------------\r
846 \r
847 -   A DOS XMS driver's control function must begin with code similar to the\r
848     following:\r
849 \r
850 XMMControl  proc    far\r
851 \r
852             jmp     short XCControlEntry    ; For "hookability"\r
853             nop                     ; NOTE: The jump must be a short\r
854             nop                     ;  jump to indicate the end of\r
855             nop                     ;  any hook chainThe nop's\r
856                                             ;  allow a far jump to be\r
857                                             ;  patched in.\r
858 XCControlEntry:\r
859 \r
860 \r
861 -   XMS drivers must preserve all registers except those containing\r
862     returned values across any function call.\r
863 \r
864 -   XMS drivers are required to hook INT 15h and watch for calls to\r
865     functions 87h (Block Move) and 88h (Extended Memory Available).  The\r
866     INT 15h Block Move function must be hooked so that the state of the A20\r
867     line is preserved across the call.  The INT 15h Extended Memory\r
868     Available function must be hooked to return 0h to protect the HMA.\r
869 \r
870 -   In order to maintain compatibility with existing device drivers, DOS XMS\r
871     drivers must not hook INT 15h until the first non-Version Number call\r
872     to the control function is made.\r
873 \r
874 -   XMS drivers are required to check for the presence of drivers which\r
875     use the IBM VDISK allocation scheme.  Note that it is not sufficient to\r
876     check for VDISK users at installation time but at the time when the HMA\r
877     is first allocated.  If a VDISK user is detected, the HMA must not be\r
878     allocated.  Microsoft will publish a standard method for detecting\r
879     drivers which use the VDISK allocation scheme.\r
880 \r
881 -   XMS drivers which have a fixed number of extended memory handles (most\r
882     do) should implement a command line parameter for adjusting that number\r
883     (suggested name "/NUMHANDLES=")\r
884 \r
885 -   XMS drivers should make sure that the major DOS version number is\r
886     greater than or equal to 3 before installing themselves.\r
887 \r
888 -   UMBs cannot occupy memory addresses that can be banked by EMS 4.0.\r
889     EMS 4.0 takes precedence over UMBs for physically addressable memory.\r
890 \r
891 -   All driver functions must be re-entrant.  Care should be taken to not\r
892     leave interrupts disabled for long periods of time.\r
893 \r
894 -   Allocation of a zero length extended memory buffer is allowed.  Programs\r
895     which hook XMS drivers may need to reserve a handle for private use via\r
896     this method.  Programs which hook an XMS driver should pass all requests\r
897     for zero length EMBs to the next driver in the chain.\r
898 \r
899 -   Drivers should control the A20 line via an "enable count."  Local En-\r
900     able only enables the A20 line if the count is zero.  It then increments\r
901     the count.  Local Disable only disables A20 if the count is one.  It\r
902     then decrements the count.  Global Enable/Disable keeps a flag which\r
903     indicates the state of A20.  They use Local Enable/Disable to actually\r
904     change the state.\r
905 \r
906 -  Drivers should always check the physical A20 state in the local Enable-Disable calls, to see\r
907     that the physical state matches the internal count.  If the physical state does not match, it should\r
908     be modified so that it matches the internal count.  This avoids problems with applications that \r
909     modify A20 directly.\r
910 \r
911 \r
912 IMPLEMENTATION OF CODE FOR HOOKING THE XMS DRIVER:\r
913 \r
914   In order to support the hooking of the XMS driver by multiple\r
915   pieces of code, the following code sample should be followed.\r
916   Use of other methods for hooking the XMS driver will not work\r
917   in many cases. This method is the official supported one.\r
918 \r
919   The basic strategy is:\r
920 \r
921     Find the XMS driver header which has the "near jump" dispatch.\r
922 \r
923     Patch the near jump to a FAR jump which jumps to my HOOK XMS\r
924         driver header.\r
925 \r
926   NOTES:\r
927 \r
928     o This architecture allows the most recent HOOKer to undo his\r
929         XMS driver hook at any time without having to worry about\r
930         damaging a "hook chain".\r
931 \r
932     o This architecture allows the complete XMS hook chain to be\r
933         enumerated at any time. There are no "hidden hooks".\r
934 \r
935     o This architecture allows the HOOKer to not have to worry\r
936         about installing an "INT 2F hook" to hook the AH=43h\r
937         INT 2Fs handled by the XMS driver. The base XMS driver\r
938         continues to be the only one installed on INT 2Fh AH=43h.\r
939 \r
940         This avoids all of the problems of undoing a software\r
941         interrupt hook.\r
942 \r
943   ;\r
944   ; When I wish to CHAIN to the previous XMS driver, I execute a FAR JMP\r
945   ;     to the address stored in this DWORD.\r
946   ;\r
947   PrevXMSControlAddr    dd      ?\r
948 \r
949   ;\r
950   ; The next two data items are needed ONLY if I desire to be able to undo\r
951   ;     my XMS hook.\r
952   ; PrevXMSControlJmpVal stores the previos XMS dispatch near jump offset\r
953   ;     value that is used to unhook my XMS hook\r
954   ; PrevXMSControlBase stores the address of the XMS header that I hooked\r
955   ;\r
956   PrevXMSControlBase    dd      ?\r
957   PrevXMSControlJmpVal  db      ?\r
958 \r
959   ;\r
960   ; This is MY XMS control header.\r
961   ;\r
962   MyXMSControlFunc proc FAR\r
963         jmp     short XMSControlEntry\r
964         nop\r
965         nop\r
966         nop\r
967   XMSControlEntry:\r
968 \r
969   ......\r
970 \r
971   Chain:\r
972         jmp     cs:[PrevXMSControlAddr]\r
973 \r
974   MyXMSControlFunc endp\r
975 \r
976 \r
977   .......\r
978   ;\r
979   ; This is the code which installs my hook into the XMS driver.\r
980   ;\r
981     ;\r
982     ; See if there is an XMS driver to hook\r
983     ;\r
984         mov     ax,4300h\r
985         int     2Fh\r
986         cmp     al,80h\r
987         jne     NoXMSDrvrToHookError\r
988     ;\r
989     ; Get the current XMS driver Control address\r
990     ;\r
991         mov     ax,4310h\r
992         int     2Fh\r
993   NextXMSHeader:\r
994         mov     word ptr [PrevXMSControlAddr+2],es\r
995         mov     word ptr [PrevXMSControlBase+2],es\r
996         mov     word ptr [PrevXMSControlBase],bx\r
997         mov     cx,word ptr es:[bx]\r
998         cmp     cl,0EBh                         ; Near JUMP\r
999         je      ComputeNearJmp\r
1000         cmp     cl,0EAh                         ; Far JUMP\r
1001         jne     XMSDrvrChainMessedUpError\r
1002   ComputeFarJmp:\r
1003         mov     si,word ptr es:[bx+1]           ; Offset of jump\r
1004         mov     es,word ptr es:[bx+1+2]         ; Seg of jump\r
1005         mov     bx,si\r
1006         jmp     short NextXMSHeader\r
1007 \r
1008   ComputeNearJmp:\r
1009         cmp     word ptr es:[bx+2],9090h        ; Two NOPs?\r
1010         jne     XMSDrvrChainMessedUpError       ; No\r
1011         cmp     byte ptr es:[bx+4],90h          ; Total of 3 NOPs?\r
1012         jne     XMSDrvrChainMessedUpError       ; No\r
1013         mov     di,bx                           ; Save pointer to header\r
1014         xor     ax,ax\r
1015         mov     al,ch                           ; jmp addr of near jump\r
1016         mov     [PrevXMSControlJmpVal],al\r
1017         add     ax,2                            ; NEAR JMP is 2 byte instruction\r
1018         add     bx,ax                           ; Target of jump\r
1019         mov     word ptr [PrevXMSControlAddr],bx\r
1020     ;\r
1021     ; Now INSTALL my XMS HOOK\r
1022     ;\r
1023         cli                             ; Disable INTs in case someone calls\r
1024                                         ;       XMS at interrupt time\r
1025         mov     byte ptr es:[di],0EAh   ; Far Immed. JUMP instruction\r
1026         mov     word ptr es:[di+1],offset MyXMSControlFunc\r
1027         mov     word ptr es:[di+3],cs\r
1028         sti\r
1029     .....\r
1030 \r
1031     ;\r
1032     ; Deinstall my XMS hook. This can be done IF AND ONLY IF my XMS header\r
1033     ;   still contains the near jump dispatch\r
1034     ;\r
1035         cmp     byte ptr [MyXMSControlFunc],0EBh\r
1036         jne     CantDeinstallError\r
1037         mov     al,0EBh\r
1038         mov     ah,[PrevXMSControlJmpVal]\r
1039         les     bx,[PrevXMSControlBase]\r
1040         cli                             ; Disable INTs in case someone calls\r
1041                                         ;       XMS at interrupt time\r
1042         mov     word ptr es:[bx],ax\r
1043         mov     word ptr es:[bx+2],9090h\r
1044         mov     byte ptr es:[bx+4],90h\r
1045         sti\r
1046     ....\r
1047 \r
1048 IMPLEMENTATION NOTES FOR HIMEM.SYS:\r
1049 -----------------------------------\r
1050 \r
1051 -   HIMEM.SYS currently supports true AT-compatibles, 386 AT machines, IBM\r
1052     PS/2s, AT&T 6300 Plus systems and Hewlett Packard Vectras.\r
1053 \r
1054 -   If HIMEM finds that it cannot properly control the A20 line or if there\r
1055     is no extended memory available when HIMEM.SYS is invoked, the driver\r
1056     does not install itself.  HIMEM.SYS displays the message "High Memory\r
1057     Area Unavailable" when this situation occurs.\r
1058 \r
1059 -   If HIMEM finds that the A20 line is already enabled when it is invoked,\r
1060     it will NOT change the A20 line's state.  The assumption is that whoever\r
1061     enabled it knew what they were doing.  HIMEM.SYS displays the message "A20\r
1062     Line Permanently Enabled" when this situation occurs.\r
1063 \r
1064 -   HIMEM.SYS is incompatible with IBM's VDISK.SYS driver and other drivers\r
1065     which use the VDISK scheme for allocating extended memory.  However, \r
1066     HIMEM does attempt to detect these drivers and will not allocate the\r
1067     HMA if one is found.\r
1068 \r
1069 -   HIMEM.SYS supports the optional "/HMAMIN=" parameter.  The valid values\r
1070     are decimal numbers between 0 and 63.\r
1071 \r
1072 -   By default, HIMEM.SYS has 32 extended memory handles available for use.\r
1073     This number may be adjusted with the "/NUMHANDLES=" parameter.  The\r
1074     maximum value for this parameter is 128 and the minimum is 0.  Each\r
1075     handle currently requires 6 bytes of resident space.\r
1076 \r
1077 \r
1078 Copyright (c) 1988, Microsoft Corporation\r
1079 \r