The bit is 1 when the button is pressed. The bit is 0 when the button is released.
A Grail Millennium Project
White Paper
This document is maintained by the author, Lewis A. Sellers, somewhere in the mountains of East Tennessee, the United States of America. It is an informal technical document for a works in progress project called Grail Millennium, or fully, The Minimal Operating System of Object Class Interfaces Holy Grail for the Millennium. In other words, for a new, easy to use, long-lived operating system.
Copyright Notice
This document and all material therein, unless otherwise stated, is Copyright © 1995,1996, Lewis A. Sellers. All Rights Reserved. Permission to distribute this document, in part or full, via electronic means (emailed, posted or archived) or printed copy are granted providing that no charges are involved, reasonable attempt is made to use the most current version, and all credits and copyright notices are retained.
Distribution Rights
All requests for other distribution rights, including incorporation in commercial products, such as books, magazine articles, CD-ROMs, and or computer programs should be made to the primary author Lewis Sellers.
Warranty and disclaimer
This document is provided as is without any express or implied warranties. This is a work-in-progress, and as such will contain outdated or as yet uncorrected or substanstiated assumptions. The author, maintainer and/or contributors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.
WWW Home Sites
You can currently find home sites to this project at If you can not reach them, or they seem to be down, do a key word search on AltaVista, Lycos, or the Web Crawler search engines.
Contact Email
The primary author of Grail Millennium should be reachable at lsellers@usit.net.
OCI/Spec | DOS16/32 L E G A C Y
DESIGNER
Lewis A. Sellers (aka Minimalist) lsellers@usit.net
CRITIQUED BY
- Akintunde Omitowoju tunde@housing.east-tenn-st.edu
DRAFTS
- 5/29/96 rough revision 0.00 (the first new document for Grail resurgence 3)
INSPIRATIONAL MUSIC for this Document:
- Pinion -- PN-WATER.S3M
- Pinion -- PN-FORCE.S3M
- Pinion -- PN-WINTR.S3M
- Pinion -- PN-AZURE.S3M
- THE CURE - Burn
(a0.01)
Preface
This group has been around in one form or another, under one name or another throughout most of the project's history. The original idea of saving and salvaging the past came about simply because important software that I'd wrote long ago on other platforms had since degraded beyond recovering. I miss it.
While researching computer history for "On the Evolution of Machine, Mind and Man" I ran across a page on the web concerning the late Stephen Cabriney, and his attempts to save all (and I mean all) computer software and hardware that had been. Thus it seemed more than fitting the code-name of this group should carry his name on.
Table of Contents
Legal Notices Who gets sued and why History Changes and who made them Preface About the FS and the people that make it
Overview An Overview of the DOS Legacy
DOS16/32 Legacy
"The count of lawyers in a society is good indication of how immoral it is."
--min 6-2-96 445aUm, what is the DOS32 "Legacy" BRIDGE METAPHOR?
We all remember DOS of course. Most of the best and fastest IBM PC games were written for it and probably will be so for years to come. DOS32 is a "bridge metaphor" that allows most 32-bit DOS programs using DPMI and VESA to run under Grail without change.
When a 32-bit DOS program is ran directly, or via a link the DOS32 BRIDGE METAPHOR object is brought into memory, all other programs are gracefully suspended, an interrupt translation code bridge is created, and the program given exclusive run status. That is, to be safe, all other programs are shut down and only 32-bit DOS programs may be run until........
DOS32 can run 32-bit binary application .EXE files and the script .BAT file. It can NOT run the old 16-bit 64kb-limited .COM files.
The COMMAND-LINE Metaphor
DOS32, if invoked without the name of a DOS program or link with environment definitions will go into it's default internal COMMAND-LINE mode. As you might guess, this means that you get the message:
GRAIL Operating System -- DOS32 Bridge Metaphor v0.00 build 11395 Copyright (c) 1996 by The Minimalist Group. All Rights Reserved. 20,971,520 bytes total memory. 13,373,200 bytes available for DPMI/VCPI Emulation. 1 MB reserved for conventional thunking.When a program started in the command-line mode ends, you return to the command-line. Otherwise DOS32 removes itself from memory and Grail operations immediately return to normal.
Can we run ancient 16-bit DOS programs too?
Yes. But such programs will run in a highly protected virtual machine emulation similar to the DOS32 structure. The noticeable differences will be that only XMS or EMS memory calls will be available. The entire 1MB "conventional" memory area will be available excepting the emulated text and video areas at 0A000h to 0BFFFFh, the first 4kb, and the memory area just below 1MB used by the bridge emulation ROM/DOS code. In short, you should never have a problem with "insufficient conventional memory" errors. You will always have 651,264 bytes of "conventional" memory to work with, and perhaps a couple hundred more kbs of "UMB".
Can I run DOS32 on processors other than the X86 line?
Um, probably not anytime soon. It's not beyond reason to expect a DOS16 emulation at some point however. We'll see.
Of Historical Note
It seems a little ironic that as I near the end the detailed planning of Grail that we have arrived at the DOS32 Metaphor. For those few of you who remember, Grail, back before it was called such, was to be simply a video/audio setup program which would create a set of text files any DOS application could read and know what your video/audio preferences were without asking you over and over again.
And here we are again. Full circle.
THE CODE BRIDGE:
INTERFACING WITH LEGACY SOFTWARE
BY | Lewis Sellers lsellers@usit.net
System Timer 08hCOM2 COM4
COM1 COM3
The Virtual Memory Map
BY | Lewis Sellers lsellers@usit.net
DOS32 "Legacy" resides in its own folder as do all other metaphors. The "path" from DOS is automatic under DOS32. When a program is ran, it is first looked for in the current directory, then the DOS32 root "Root\", then the DOS32 utility "Utility\".
The Command-line Interface
BY | Lewis Sellers lsellers@usit.net
DOS32 provides an integrated command-line interface similiar, though not equivilent to various incarnations of PC-DOS, DR-DOS and/or MS-DOS. Part of DOS32 resides in a virtual 1MB near what would be the top of the BIOS area, and the rest lies in normal flat Grail space.
CHANGE FILE ATTRIBUTES
ATTRIB filename
/?
/help
CHANGE CURRENT DIRECTORY
CD
/?
/help
..
\
CD by itself shows the current directory (which is rather redundant, since DOS32 ALWAYS shows you this at the prompt anyway).
SHOW FILES IN DIRECTORY
DIR
/?
/help
/p page
/w wide
/l long
/formatted=
/exe, program files .COM, .BAT, .EXE
/dir, directories
Date Time Flags Type Size Name 28-04-1996 15:00.00 -------- - 128kb This is a file 25-04-1996 17:12.13 -------- - 1.34mb A real big file 01-05-1996 1:59.05 -------O - 438kb TEST.DOC 07-11-1993 13:15:44 -------O EXE32 235kb DOOM.EXE 20-09-1986 3:34:11 -------O EXE16 127kb Opais.exe 20-09-1986 3:37:17 --------0 BATCH 577b RUNME.BATCOPY FILES
COPY filename filename
/?
/help
/all
/skip
MOVE FILES
MOVE filename filename
/?
/help
/all
/skip
MASS FILE COPY
XCOPY
/?
/help
/all
/skip
MASS FILE MOVE
XMOVE
/?
/help
/all
/skip
FILE DELETE
DEL filename
/?
/help
INCLUSIVE SUBDIRECTORY FILE DELETE
DELTREE folder
/?
/help
/all
COMPRESS FILES AND DIRECTORY OF FILES
ZIP zipfile files
/?
/help
/s subdirectory
/a absolute path
/c0 no-compression
/cn normal compression
/ce extra compression
UNCOMPRESS FILES
UNZIP zipfile
/?
/help
/a absolute path
VIDEO CAPABILITIES
VIDEO
/?
/help
/graphics
/mpeg
/vrheadset
/all
/formatted=
/acceleration
/raw
/situation=default, text, silent_movie, movie, virtual_reality, photo, magazine, cad, console
This serves two purposes. The first is to let you see what video modes are available under your sytem. Entering VIDEO with no parameters will give you something like the following:
Text
Name Columns Lines Chars Bitwidth Back Fore Type Atrrib 3h 80 25 8 16 16 16 Fixed 60 80 50 8 16 16 16 80 60 132 25 132 43 132 60 Graphics
Name Width Height Depth Bitdeapth RGB Type Format 13h 320 200 8 8 666 CLUT 101h 640 480 8 8 666 CLUT 110h 640 480 24 24 888 DIRECT RGB 110ha 640 480 24 32 888 DIRECT RGBa You can also limit the information to a selected subtype such as MPEG or VR-HEADSET compatible modes.
The second purpose is to SELECT your preferred default modes for a few situations. This defaults are saved in the file VIDEO.INF which resides at DOS32's virtual root directory. The /situation switches here deserve a little explaination. Simply put, for each of the following you can define a specific video mode that you like:
default
text, for text-only displays, such as for reading books on computer.
movie, for watching full-motion movies with a sound-track
silent_movie, for watching movies that are silent, or get their audio for an external source
virtual_reality, for virtual reality or first-person graphics (ie, DOOM)
action_virtual_reality, same as virtual_reality, but when speed is more important than quality of the rendering
photo, for looking at detailed images such as photos, maps and fine-art
cad, for detailed design work such as CAD or editing Doom/Quake levels :)
magazine, for reading electronic versions of magazines or Adobe PDFs, etc
console, normal a text mode screen such as 80x50
/Situation has two arguments. The first is the mode type, and the second determines the scaling factor if any. 0 is no scaling. -1 is to scale close to full screen using integer scaling factors (best). -2 is scale to full screen. All others imply a times scaling factor such as 2, 3 or 4 if needed. This may or may not mean anything to an application.
AUDIO CAPABILITIES
AUDIO
/?
/help
/digital
/midi
/fm
/all
/formatted=
Digital
Bits Khz Cmprs Buffer Port IRQ DMA
24 44 None 512k 220 5,10 1,5
GMIDI
?
CONTROLLER CAPABILITIES
CONTROL
/?
/help
/formatted=
/keyboard
/joystick
/mouse
/vrglove
/lightpen
/tablet
/situation=default, text, movie, first-person, map, magazine
Keyboard
104 keys
Mouse
3-button Serial, Serial 1
Joystick
4-button Gravis
You can select which devices you wish active in any of the defined situations (modes), as well as thier order of important to you.
COMMUNICATIONS CAPABILITIES
COM
/?
/help
/formatted=
Modem
Name bs Comprs Buffer Type
#1 14,000 yes 32 16550A
Serial Null-Modem
Name bs Comprs Buffer Type
#1
#2
IPX
Name bs
#1
EMULATION PERFORMANCE SETTINGS (BIOS/ROM/DOS)
EMULATE filename, switches...
/?
/help
/all
/joystick
/mouse
/keyboard
/floppy
/hd
/cd-rom
/printer
/svga
/vga
/ega
/cga
/mono
/speaker
/digitalaudio
/gmidi
/xms
/ems
/dpmi
/vcpi
/audio
/video
/memory=n, free, real/virtual, min/max
/ports=free, unrestrict x... , restrict x...
/save=filename
/application=filename
You can turn emulation on or off by using the keyboards "on" or "off" after each switch.
DOS32 METAPHOR HELP
HELP topic
/?
/help
TEXT EDITOR
EDIT filename
/?
/help
A simple single file text editor, using ASCII, UNICODE and ANSI.
TEXT VIEWER
VIEW filename
/?
/help
A simple text file viewer using ESC, and arrow/paging keys. You can use plain ASCII, UNICODE and ANSI codes.
BY | Lewis Sellers lsellers@usit.net
Under DOS32 memory is of two flavours: DPMI extended and conventional. Conventional memory resides as a 1MB space. The high-memory area is NEVER available in this implementation.
XMS Extended Memory Support
Legacy supports XMS while in 16-bit mode, though not while in the 32-bit compatability mode. There are a few very important things you must know about XMS emulation. First off, the emulated version is 3.00, and the Super Extended Memory Support functions are also available, which is fairly standard. A major difference is that High Memory Area (HMA) and A20-Line functions are completely ignored. If you try to use them, you will recieve back messages to the effect that yes, A20 is enabled (permanently), but HMA does not exist. This normal under Legacy emulation, and will not change.
All XMS functions are re-entrant.
The allocation of a zero length extended memory buffer is permissible so as to allow reserving a handle for private use.
When Legacy comes up, the message "High Memory Area Unavailable" appears for reasons that are obvious to the experienced XMS user.
The HIMEM.SYS emulator has 256 extended memory handles available for use. Each handle requires 6 bytes of DOS emulation memory. This far exceeds the original DOS design specifications of XMS.
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 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 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 invalidPREPARING TO USE XMS:
To Call: AH=43h INT 2Fh Return: ES:BX driver function control addressUnder Legacy, XMS will always be available while in 16-bit mode, but of course older programs will not be aware of this. They will determine if an XMS driver is installed by setting AH=43h and AL=00h and then executing INT 2Fh. 80h will always be returned in AL.
This function is called to access all of the XMS functions. It should be called with AH set to the number of the API function requested. The API function will put a success code of 0001h or 0000h in AX. If the function succeeded (AX=0001h), additional information may be passed back in BX and DX. If the function failed (AX=0000h), an error code may be returned in BL. Valid error codes have their high bit set. Developers should keep in mind that some of the XMS API functions may not be implemented by all drivers and will return failure in all cases.
Programs should make sure that at least 256 bytes of stack space is available before calling XMS API functions.Get XMS Version Number
To Call: AH = 00h Returns: AX = XMS version number BX = Driver internal revision number DX = 0000h, meaning HMA does not exist ERRS: NoneThis function returns a 16-bit BCD number in register AX representing the version of the DOS Extended Memory Specification which is emulated. This is currently set at 3.00, e.g. AX=0300h.
Request High Memory Area
To Call: AH = 01h RETURNS: AX = 0001h if the HMA is assigned to the caller, 0000h otherwise BL = 90h if the HMA does not exist This function always returns BL=90h.Release High Memory Area
To Call:AH = 02h
RETURNS:
AX =0000h otherwise
BL = 90h if the HMA does not exist
Global Enable A20
To Call:AH = 03h
RETURNS:
AX = 0001h if the A20 line is enabled
BL = 82h if an A20 error occurs
Global Disable A20
To Call:AH = 04h
RETURNS:
AX = 0000h if a20 enabled
BL = 94h if the A20 line is still enabled
This function attempts to disable the A20 line, but will always fail.
Local Enable A20
To Call:AH = 05h
RETURNS:
AX = 0001h if the A20 line is enabled
BL = 82h if an A20 error occurs
Local Disable A20
To Call:
AH = 06h
RETURNS:
AX = 0000h otherwise
BL = 94h if the A20 line is still enabled
Query A20
To Call:
AH = 07h
RETURNS:
AX = 0001h if the A20 line is physically enabled
BL = 00h if the function succeeds
This function is supposed to check to see if the A20 line is physically enabled. Since under Grail this is ALWAYS so, the function will always succeed and return AX=01h.
Query Free Extended Memory
To Call:
AH = 08h
RETURNS:
AX = Size of the largest free extended memory block in K-bytes
DX = Total amount of free extended memory in K-bytes
BL = A0h if all extended memory is allocated
This function returns the size of the largest available extended memory block allocated to the DOS emulator.
Allocate Extended Memory Block
To Call:
AH = 09h
DX = Amount of extended memory being requested in K-bytes
RETURNS:
AX = 0001h if the block is allocated, 0000h otherwise
DX = 16-bit handle to the allocated block
BL = A0h if all available extended memory is allocated
A1h if all available extended memory handles are in use
This function attempts to allocate a block of the given size out of the pool of free extended memory. If a block is available, it is reserved for the caller and a 16-bit handle to that block is returned. The handle should be used in all subsequent extended memory calls. If no memory was allocated, the returned handle is null.
Extended memory handles are, as per the original design, a limited resources. There is a total maximum availablity of 256 such handles. When all of the emulators handles are in use, any free extended memory is unavailable.
Free Extended Memory Block
To Call:
AH = 0Ah
DX = Handle to the allocated block which should be freed
RETURNS:
AX = 0001h if the block is successfully freed, 0000h otherwise
BL = 80h if the function is not implemented
A2h if the handle is invalid
ABh if the handle is locked
This function frees a block of extended memory which was previously allocated using Function 09h (Allocate Extended Memory Block). Programs which allocate extended memory should free their memory blocks before
exiting. When an extended memory buffer is freed, its handle and all data
stored in it become invalid and should not be accessed.
Move Extended Memory Block
To Call:
AH = 0Bh
DS:SI = Pointer to an Extended Memory Move Structure (see below)
RETURNS:
AX = 0001h if the move is successful, 0000h otherwise
BL = 80h if the function is not implemented
82h if an A20 error occurs
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
Extended Memory Move Structure Definition:
ExtMemMoveStruct struc
Length dd ? ; 32-bit number of bytes to transfer
SourceHandle dw ? ; Handle of source block
SourceOffset dd ? ; 32-bit offset into source
DestHandle dw ? ; Handle of destination block
DestOffset dd ? ; 32-bit offset into destination block
ExtMemMoveStruct ends
This function attempts to transfer a block of data from one location to
another. It is primarily intended for moving blocks of data between
conventional memory and extended memory, however it can be used for moving
blocks within conventional memory and within extended memory.
If SourceHandle is set to 0000h, the SourceOffset is interpreted
as a standard segment:offset pair which refers to memory that is
directly accessible by the processor. The segment:offset pair
is stored in Intel DWORD notation. The same is true for DestHandle
and DestOffset.
SourceHandle and DestHandle do not have to refer to locked memory
blocks.
Length must be even. Although not required, WORD-aligned moves
can be significantly faster on most machines. DWORD aligned move
can be even faster on 80386 machines.
If the source and destination blocks overlap, only forward moves
(i.e. where the source base is less than the destination base) are
guaranteed to work properly.
This function is guaranteed to provide a reasonable number of
interrupt windows during long transfers.
Lock Extended Memory Block
To Call:
AH = 0Ch
DX = Extended memory block handle to lock
RETURNS:
AX = 0001h if the block is locked, 0000h otherwise
DX:BX = 32-bit physical address of the locked block
ERRS: BL = 80h if the function is not implemented
BL = A2h if the handle is invalid
BL = ACh if the block's lock count overflows
BL = ADh if the lock fails
This function locks an extended memory block and returns its base
address as a 32-bit physical address. Locked memory blocks are guaranteed not
to move. The 32-bit pointer is only valid while the block is locked.
Locked blocks should be unlocked as soon as possible.
NOTE: A block does not have to be locked before using Function 0Bh (Move Extended Memory Block).
"Lock counts" are maintained for EMBs.
Unlock Extended Memory Block
To Call: AH = 0Dh
DX = Extended memory block handle to unlock
RETURNS: AX = 0001h if the block is unlocked, 0000h otherwise
ERRS: BL = 80h if the function is not implemented
BL = 81h if a VDISK device is detected
BL = A2h if the handle is invalid
BL = AAh if the block is not locked
This function unlocks a locked extended memory block. Any 32-bit
pointers into the block become invalid and should no longer be used.
Get EMB Handle Information
To Call: AH = 0Eh
DX = Extended memory block handle
RETURNS: AX = 0001h if the block's information is found, 0000h otherwise
BH = The block's lock count
BL = Number of free EMB handles in the system
DX = The block's length in K-bytes
ERRS: BL = 80h if the function is not implemented
BL = A2h if the handle is invalid
This function returns additional information about an extended memory block to the caller.
Reallocate Extended Memory Block
To Call: AH = 0Fh
BX = New size for the extended memory block in K-bytes
DX = Unlocked extended memory block handle to reallocate
RETURNS: AX = 0001h if the block is reallocated, 0000h otherwise
ERRS: BL = 80h if the function is not implemented
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 attempts to reallocate an unlocked extended memory block so that it becomes the newly specified size. If the new size is smaller than the old block's size, all data at the upper end of the old block is lost.
Request Upper Memory Block
To Call: AH = 10h
DX = Size of requested memory block in paragraphs
RETURNS: AX = 0001h if the request is granted, 0000h otherwise
BX = Segment number of the upper memory block
If the request is granted,
DX = Actual size of the allocated block in paragraphs otherwise,
DX = Size of the largest available UMB in paragraphs
ERRS: BL = 80h if the function is not implemented
BL = B0h if a smaller UMB is available
BL = B1h if no UMBs are available
This function attempts to allocate an upper memory block to the caller. If the function fails, the size of the largest free UMB is returned in DX.
By definition UMBs are located below the 1MB address boundary.
UMBs are paragraph aligned.
To determine the size of the largest available UMB, attempt to allocate one with a size of FFFFh.
UMBs are unaffected by EMS calls.
Release Upper Memory Block
To Call: AH = 11h
DX = Segment number of the upper memory block
RETURNS: AX = 0001h if the block was released, 0000h otherwise
ERRS: BL = B2h if the UMB segment number is invalid
This function frees a previously allocated upper memory block. When an
UMB has been released, any code or data stored in it becomes invalid and
should not be accessed.
Reallocate Upper Memory Block
To Call:
AH = 12h
BX = New size for UMB in paragraphs
DX = Segment number of the UMB to reallocate
RETURNS:
AX = 1 if the block was reallocated, 0 otherwise
ERRS:
BL = 80h if the function is not implemented
BL = B0h if no UMB large enough to satisfy the request is available.
In this event, DX is returned with the size of the largest UMB that is available.
BL = B2h if the UMB segment number is invalid
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.
Query Any Free Extended Memory
Entry:
AH = 88h
Exit:
EAX = Size of largest free extended memory block in Kb.
BL = 0 if no error occurs, otherwise it takes an error code.
ECX = Highest ending address of any memory block.
EDX = Total amount of free memory in Kb.
Errors:
BL = A0h if all extended memory is allocated.
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.
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.
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.
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.
Allocate Any Extended Memory
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 = 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 = 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 = 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.
Obtaining the Real to Protected Mode Switch Entry Point
This function can be called in real mode to detect the
presence of DPMI services and to obtain an address that
can be used to begin execution in protected mode.
To Call
AX = 1687h
Execute an Int 2Fh (not an Int 31h)
Returns
If function was successful:
AX = 0
BX = Flags
Bit 0 = 1 if 32-bit programs are supported
CL = Processor type
03h = 80386
04h = 80486
05h = Pentium
06h = Pentium Pro
DH = DPMI major compliance number = 9
DL = DPMI minor version number = 0
SI = Number of paragraphs required for DPMI host private data (may be 0)
ES:DI = Address of procedure to call to enter protected mode
If function was not successful:
AX != 0
Calling the Real to Protected Mode Switch Entry Point
After using Int 2Fh function 1687h, to obtain the
protected mode entry point, the DPMI client must call
the entry point address as described in this section.
To Call
AX = Flags
Bit 0 = always 1 if program is a 32-bit application
ES = Real mode segment of DPMI host data area. This
must be the size of the data area returned in SI
from the previous function. ES will be ignored if
the required data size is zero.
Call the address returned in ES:DI by the previous
function
Returns
If function was successful:
Carry flag is clear.
Program is now executing in protected mode.
CS = 16-bit selector with base of real mode CS and a
64K limit
SS = Selector with base of real mode SS and a 64K limit
DS = Selector with base of real mode DS and a 64K limit
ES = Selector to program's PSP with a 100h byte limit
FS and GS = 0
If the program is a 32-bit application the high word of
ESP will be 0
All other registers are preserved
If function was not successful:
Carry flag is set.
Program is executing in real mode
TERMINATE PROTECTED MODE PROGRAM
To Call:
AH=4Ch
AL= error code
INT 21h
Return:
MODE DETECTION
To Call:
AX = 1686h
INT 2Fh
Returns:
AX=0, if executing in protected mode under DPMI
AX!=0, if executing in 16-bit virtual real-mode
Segment to Descriptor
This function is used to convert real mode segments
into descriptors that are addressable by protected mode
programs.
To Call
AX = 0002h
BX = Real mode segment address
Returns
If function was successful:
Carry flag is clear.
AX = Selector mapped to real mode segment
If function was not successful:
Carry flag is set.
6 Get Segment Base Address
This function returns the 32-bit linear base address of
the specified segment.
To Call
AX = 0006h
BX = Selector
Returns
If function was successful:
Carry flag is clear.
CX:DX = 32-bit linear base address of segment
If function was not successful:
Carry flag is set.
7 Create Code Segment Alias Descriptor
This function will create a data descriptor that has
the same base and limit as the specified code segment
descriptor.
To Call
AX = 000Ah
BX = Code segment selector
Returns
If function was successful:
Carry flag is clear.
AX = New data selector
If function was not successful:
Carry flag is set.
Allocate DOS Memory Block
To Call:
AX = 0100h
BX = Number of paragraphs (16 byte blocks) desired
Returns:
If function was successful:
Carry flag is clear.
AX = Initial real mode segment of allocated block
DX = Selector for allocated block
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as requested
BX = Size of largest available block in paragraphs
will allocate a block of memory from the DOS free memory pool. It returns both the real mode
segment and one or more descriptors that can be used by
protected mode applications to access the block.
Free DOS Memory Block
To Call:
AX = 0101h
DX = Selector of block to free
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
09h incorrect memory segment specified
This function frees memory that was allocated through
the Allocate DOS Memory Block function.
o All descriptors allocated for the memory block are
automatically freed and therefore should not be
accessed once the block is freed by this function.
Resize DOS Memory Block
To Call:
AX = 0102h
BX = New block size in paragraphs
DX = Selector of block to modify
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
AX = DOS error code:
07h memory control blocks damaged
08h insufficient memory available to allocate as requested
09h incorrect memory segment specified
BX = Maximum block size possible in paragraphs
This function is used to grow or shrink a memory block
was allocated through the Allocate DOS Memory Block function.
o Growing a memory block is often likely to fail
since other DOS block allocations will prevent
increasing the size of the block. Also, if the
size of a block grows past a 64K boundary then the
allocation will fail if the next descriptor in the
LDT is not free. Therefore, this function is
usually only used to shrink a block.
o Shrinking a block may cause some descriptors that
were previously allocated to the block to be
freed. For example shrinking a block from 140K to
120K would cause the third allocated descriptor to
be freed since it is no longer valid. The initial
selector will remain unchanged, however, the
limits of the remaining two descriptors will
change: the first to 120K and the second to 56k.
Get Real Mode Interrupt Vector
To Call:
AX = 0200h
BL = Interrupt number
Returns:
Carry flag is clear.
CX:DX = Segment:Offset of real mode interrupt handler
This function returns the value of the current task's
real mode interrupt vector for the specified interrupt.
o The address returned in CX is a segment, not a
selector. Therefore you should not attempt to
place the value returned in CX into a segment
register in protected mode or a general protection
fault may occur.
o Note all 100h (256 decimal) interrupt vectors must
be supported by the DPMI host.
10.2 Set Real Mode Interrupt Vector
To Call:
AX = 0201h
BL = Interrupt number
CX:DX = Segment:Offset of real mode interrupt handler
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
This function sets the value of the current task's real
mode interrupt vector for the specified interrupt.
o The address passed in CX must be a real mode
segment, not a selector.
o If the interrupt being hooked is a hardware
interrupt then you must lock the segment that the
interrupt handler runs in as well as any memory
the handler may touch at interrupt time.
o The address contained in CX:DX must be a real mode
segment:offset, not a selector:offset. This means
that the code for the interrupt handler must
either reside in DOS addressable memory or you
must use a real mode call-back address. Refer to
the section on DOS memory management services on
page 43 for information on allocating memory below
1 megabyte. Information on real mode call back
addresses can be found on page 68.
10.3 Get Processor Exception Handler Vector
To Call:
AX = 0202h
BL = Exception/fault number (00h-1Fh)
Returns:
If function was successful:
Carry flag is clear.
CX:(E)DX = Selector:Offset of exception handler
If function was not successful:
Carry flag is set.
The value passed in BL was invalid.
This function returns the CS:(E)IP of the current
protected mode exception handler for the specified
exception number.
o The value returned in CX is a valid protected mode
selector, not a real mode segment.
o 32-bit mode programs will be returned a 32-bit
offset in the EDX register.
10.4 Set Processor Exception Handler Vector
To Call:
AX = 0203h
BL = Exception/fault number (00h-1Fh)
CX:(E)DX = Selector:Offset of exception handler
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
The value passed in BL was invalid.
This function allows protected mode applications to
intercept processor exceptions that are not handled by
the DPMI environment. Programs may wish to handle
exceptions such as not present segment faults which
would otherwise generate a fatal error.
Every exception is first examined by the protected mode
operating system. If it can not handle the exception
it then reflects it through the protected mode
exception handler chain. The final handler in the
chain may either reflect the exception as an interrupt
(as would happen in real mode) or it may terminate the
current program.
Get Protected Mode Interrupt Vector
To Call:AX = 0204h
BL = Interrupt number
Returns:
Carry flag is clear.
CX:(E)DX = Selector:Offset of exception handler
This function returns the CS:(E)IP of the current protected mode interrupt handler for the specified interrupt number.
o The value returned in CX is a valid protected mode
selector, not a real mode segment.
o 32-bit mode programs will be returned a 32-bit
offset in the EDX register.
o All 100h (256 decimal) interrupt vectors must be
supported by the DPMI host.
Set Protected Mode Interrupt Vector
To Call:AX = 0205h
BL = Interrupt number
CX:(E)DX = Selector:Offset of exception handler
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
This function sets the address of the specified
protected mode interrupt vector.
o The value passed in CX must be a valid protected
mode code selector, not a real mode segment.
o 32-bit mode programs must supply a 32-bit offset
in the EDX register. If your handler chains to
the next exception handler it must do so using a
32-bit interrupt stack frame.
o Note all 100h (256 decimal) interrupt vectors must
be supported by the DPMI host.
11. TRANSLATION SERVICES
These services are provided so that protected mode programs
can call real mode software that DPMI does not support
directly. The protected mode program sets up a data
structure that contains the values for every register. The
data structure is defined as:
Offset Register
00h EDI
04h ESI
08h EBP
0Ch Reserved by system
10h EBX
14h EDX
18h ECX
1Ch EAX
20h Flags
22h ES
24h DS
26h FS
28h GS
2Ah IP
2Ch CS
2Eh SP
30h SS
You will notice that all of the fields are dwords so that 32
bit registers can be passed to real mode. Most real mode
software will ignore the high word of the extended
registers. However, you can write a real mode procedure
that uses 32-bit registers if you desire. Note that 16-bit
DPMI implementations may not pass the high word of 32-bit
registers or the FS and GS segment registers to real mode
even when running on an 80386 machine.
Any interrupt handler or procedure called must return with
the stack in the same state as when it was called. This
means that the real mode code may switch stacks while it is
running but it must return on the same stack that it was
called on and it must pop off the entire far return/iret
structure.
After the call or interrupt is complete, all real mode
registers and flags except SS, SP, CS, and IP will be copied
back to the real mode call structure so that the caller can
examine the real mode return values.
Remember that the values in the segment registers should be
real mode segments, not protected mode selectors.
The translation services will provide a real mode stack if
the SS:SP fields are zero. However, the stack provided is
relatively small. If the real mode procedure/interrupt
routine uses more than 30 words of stack space then you
should provide your own real mode stack.
It is possible to pass parameters to real mode software on
the stack. The following code will call a real mode
procedure with 3 word parameters:
Protected_Mode_Code:
push Param1
push Param2
push Param3
(Set ES:DI to point to call structure)
mov cx, 3 ; Copy 3 words
mov ax, 0301h ; Call real mode proc
int 31h ; Call the procedure
add sp, 6 ; Clean up stack
The real mode procedure would be called with the following
data on the real mode stack:
Param1
Param2
Param3
Return
CS
Return
IP
<-- Real mode SS:SP
11.1 Simulate Real Mode Interrupt
This function simulates an interrupt in real mode. It
will invoke the CS:IP specified by the real mode
interrupt vector and the handler must return by
executing an iret.
To Call
AX = 0300h
BL = Interrupt number
BH = Flags
Bit 0 = 1 resets the interrupt controller and A20
line
Other flags reserved and must be 0
CX = Number of words to copy from protected mode to
real mode stack
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of modified real mode call
structure
If function was not successful:
Carry flag is set.
11.2 Call Real Mode Procedure With Far Return Frame
This function calls a real mode procedure. The called
procedure must execute a far return when it completes.
To Call
AX = 0301h
BH = Flags
Bit 0 = 1 resets the interrupt controller and A20
line
Other flags reserved and must be 0
CX = Number of words to copy from protected mode to
real mode stack
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of modified real mode call
structure
If function was not successful:
Carry flag is set.
11.3 Call Real Mode Procedure With Iret Frame
This function calls a real mode procedure. The called
procedure must execute an iret when it completes.
To Call
AX = 0302h
BH = Flags
Bit 0 = 1 resets the interrupt controller and A20
line
Other flags reserved and must be 0
CX = Number of words to copy from protected mode to
real mode stack
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of modified real mode call
structure
If function was not successful:
Carry flag is set.
Allocate Real Mode Call-Back Address
This service is used to obtain a unique real mode
SEG:OFFSET that will transfer control from real mode to
a protected mode procedure.
At times it is necessary to hook a real mode interrupt
or device call-back in a protected mode driver. For
example, many mouse drivers call an address whenever
the mouse is moved. Software running in protected mode
can use a real mode call-back to intercept the mouse
driver calls.
To Call
AX = 0303h
DS:(E)SI = Selector:Offset of procedure to call
ES:(E)DI = Selector:Offset of real mode call structure
Returns
If function was successful:
Carry flag is clear.
CX:DX = Segment:Offset of real mode call address
If function was not successful:
Carry flag is set.
Call-Back Procedure Parameters
Interrupts disabled
DS:(E)SI = Selector:Offset of real mode SS:SP
ES:(E)DI = Selector:Offset of real mode call structure
SS:(E)SP = Locked protected mode API stack
All other registers undefined
Return from Call-Back Procedure
Execute an IRET to return
ES:(E)DI = Selector:Offset of real mode call structure
to restore (see note)
o Since the real mode call structure is static, you
must be careful when writing code that may be
reentered. The simplest method of avoiding
reentrancy is to leave interrupts disabled
throughout the entire call. However, if the
amount of code executed by the call-back is large
then you will need to copy the real mode call
structure into another buffer. You can then
return with ES:(E)DI pointing to the buffer you
copied the data to -- it does not have to point to
the original real mode call structure.
o The called procedure is responsible for modifying
the real mode CS:IP before returning. If the real
mode CS:IP is left unchanged then the real mode
call-back will be executed immediately and your
procedure will be called again. Normally you will
want to pop a return address off of the real mode
stack and place it in the real mode CS:IP. The
example code in the next section demonstrates
chaining to another interrupt handler and
simulating a real mode iret.
o To return values to the real mode caller you must
modify the real mode call structure.
o Remember that all segment values in the real mode
call structure will contain real mode segments,
not selectors. If you need to examine data
pointed to by a real mode seg:offset pointer you
should not use the segment to selector service to
create a new selector. Instead, allocate a
descriptor during initialization and change the
descriptor's base to 16 times the real mode
segment's value. This is important since
selectors allocated though the segment to selector
service can never be freed.
o DPMI hosts should provide a minimum of 16 call-
back addresses per task.
11.5 Free Real Mode Call-Back Address
This function frees a real mode call-back address that
was allocated through the allocate real mode call-back
address service.
To Call
AX = 0304h
CX:DX = Real mode call-back address to free
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
11.6 Get State Save/Restore Addresses
When a program uses the raw mode switch services (see
page 77) or issues DOS calls from a hardware interrupt
handler, it will need to save the state of the current
task before changing modes. This service returns the
addresses of two procedures used to save the state of
the current task's registers. For example, the real
mode address is used to save the state of the protected
mode registers. The protected mode address is used to
save the state of the real mode registers. This can be
used to save the state of the alternate mode's
registers before they are modified by the mode switch
call. The current mode's registers can be saved by
simply pushing them on the stack.
Note: It is not necessary to call this service if
using the translation services 0300h, 0301h or 0302h.
It is provided for programs that use the raw mode
switch service.
To Call
AX = 0305h
Returns
If function was successful:
Carry flag is clear
AX = Size of buffer in bytes required to save state
BX:CX = Real mode address used to save/restore state
SI:(E)DI = Protected mode address used to save/restore
state
If function was not successful:
Carry flag is set
Parameters To State-Save Procedures
Execute a far call to the appropriate address (real or
pmode) with:
ES:(E)DI = Pointer to state-save buffer
AL = 0 to save state
AL = 1 to restore state
11.7 Get Raw Mode Switch Addresses
This function returns addresses that can be jumped to
for low-level mode switching.
To Call
AX = 0306h
Returns
If function was successful:
Carry flag is clear
BX:CX = Real -> Protected mode switch address
SI:(E)DI = Protected -> Real mode switch address
If function was not successful:
Carry flag is set
Parameters To State-Save Procedures
Execute a far jump to the appropriate address (real or
pmode) with:
AX = New DS
CX = New ES
DX = New SS
(E)BX = New (E)SP
SI = New CS
(E)DI = New (E)IP
The processor will be placed in the desired mode. The
DS, ES, SS, (E)SP, CS, and (E)IP will contain the
values specified. The (E)BP register will be preserved
across the call and so can be used as a pointer. The
values in (E)AX, (E)BX, (E)CX, (E)DX, (E)SI, and (E)DI
will be undefined. On an 80386 or 80486 the FS and GS
segment registers will contain zero after the mode
switch.
GET VERSION
To Call:
AX = 0400h
Returns:
AH = Major version, ALWAYS 0
AL = Minor version, ALWAYS 9
BX = Flags
Bit 0 = 1 if running under an 80386 DPMI implementation: ALWAYS 1
Bit 1 = 1 if processor is returned to real mode for reflected interrupts (as opposed to Virtual 8086 mode).
Bit 2 = 1 if virtual memory is supported, ALWAYS 1
Bit 3 is reserved and undefined
All other bits are zero and reserved for later use
CL = Processor type
03 = 80386
04 = 80486
05=Pentium
06=Pentium Pro
DH = Current value of virtual master PIC base interrupt
DL = Current value of virtual slave PIC base interrupt
Carry flag clear (call can not fail)
This function returns the compatability version of the DPMI services supported. This will be locked in as 0.9 unless otherwise mentioned.
Get Free Memory Information
To Call:AX = 0500h
ES:(E)DI = Selector:Offset of 30h byte buffer
Returns:
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of buffer with the following structure:
Offset Description
00h Largest available free block in bytes
04h Maximum unlocked page allocation
08h Maximum locked page allocation
0Ch Linear addr space size in pages
10h Total number of unlocked pages
14h Number of free pages
18h Total number of physical pages
1Ch Free linear address space in pages
20h Size of paging file/partition in pages
24h-2Fh Reserved
If function was not successful:
Carry flag is set.
This function is provided so that protected mode applications can determine how much memory is available. Under DPMI implementations that support
virtual memory, it is important to consider issues such
as the amount of available physical memory.
Note that since DPMI applications will often run in
multi-tasking environments, this function must be
considered only advisory.
Allocate Memory Block
To Call
AX = 0501h
BX:CX = Size of memory block to allocate in bytes
Returns
If function was successful:
Carry flag is clear
BX:CX = Linear address of allocated memory block
SI:DI = Memory block handle (used to resize and free)
If function was unsuccessful:
Carry flag is set
This function allocates and commits linear memory.
o This function does not allocate any selectors for
the memory block. It is the responsibility of the
caller to allocate and initialize any selectors
needed to access the memory.
o Under DPMI implementations that support virtual
memory the memory block will be allocated
unlocked. If some or all of the memory should be
locked you will need to use either the lock
selector function or the lock linear region
function.
Free Memory Block
This function frees a memory block that was allocate
through the allocate memory block function.
To Call
AX = 0502h
SI:DI = Handle of memory block to free
Returns
If function was successful:
Carry flag is clear
If function was unsuccessful:
Carry flag is set
Resize Memory Block
This function changes the size of a memory block that
was allocated through the allocate memory block
function.
To Call
AX = 0503h
BX:CX = New size of memory block to allocate in bytes
SI:DI = Handle of memory block to resize
Returns
If function was successful:
Carry flag is clear
BX:CX = New linear address of memory block
SI:DI = New handle of memory block
If function was unsuccessful:
Carry flag is set
Lock Linear Region
To Call:AX = 0600h
BX:CX = Starting linear address of memory to lock
SI:DI = Size of region to lock in bytes
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
This function locks a specified linear address range.
o If this function fails then none of the memory
will be locked.
o If the specified region overlaps part of a page at
the beginning or end of the region, the page(s)
will be locked.
Unlock Linear Region
To Call:
AX = 0601h
BX:CX = Starting linear address of memory to unlock
SI:DI = Size of region to unlock in bytes
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
function unlocks a specified linear address range
that was previously locked using the Lock Linear Region
function.
o If this function fails then none of the memory
will be unlocked.
o An error will be returned if the memory was not
previously locked or if the specified region is
invalid.
o If the specified region overlaps part of a page at
the beginning or end of the region, the page(s)
will be unlocked.
o Even if the function succeeds, the memory will
remain locked if the lock count is not decremented to zero.
14.3 Mark Real Mode Region as Pageable
To Call:
AX = 0602h
BX:CX = Starting linear address of memory to mark as pageable
SI:DI = Size of region to page in bytes
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
Relock Real Mode Region
To Call:
AX = 0603h
BX:CX = Starting linear address of memory to relock
SI:DI = Size of region to page in bytes
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
This function is used to relock memory regions that
were marked as pageable by the previous function.
o If this function fails then none of the memory
will be relocked.
o If the specified region overlaps part of a page at
the beginning or end of the region, the page(s)
will be not be relocked.
Get Page Size
To Call:
AX = 0604h
Returns:
If function was successful:
Carry flag is clear
BX:CX = Page size in bytes
If function was not successful:
Carry flag is set
This function returns the size of a single memory page in bytes.
Mark Page as Demand Paging Candidate
To Call:
AX = 0702h
BX:CX = Starting linear address of pages to mark
SI:DI = Number of bytes to mark as paging candidates
Returns:
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
This function is used to inform the operating system
that a range of pages should be placed at the head of
the page out candidate list. This will force these
pages to be swapped to disk ahead of other pages even
if the memory has been accessed recently. However, all
memory contents will be preserved.
This is useful, for example, if a program knows that a
given piece of data will not be accessed for a long
period of time. That data is ideal for swapping to
disk since the physical memory it now occupies can be
used for other purposes.
o This function does not force the pages to be
swapped to disk immediately.
o Partial pages will not be discarded.
15.3 Discard Page Contents
This function discards the entire contents of a given
linear memory range. It is used after a memory object
that occupied a given piece of memory has been
discarded.
The contents of the region will be undefined the next
time the memory is accessed. All values previously
stored in this memory will be lost.
To Call
AX = 0703h
BX:CX = Starting linear address of pages to discard
SI:DI = Number of bytes to discard
Returns
If function was successful:
Carry flag is clear.
If function was not successful:
Carry flag is set.
16. PHYSICAL ADDRESS MAPPING
Memory mapped devices such as network adapters and displays
sometimes have memory mapped at physical addresses that lie
outside of the normal 1Mb of memory that is addressable in
real mode. Under many implementations of DPMI, all
addresses are linear addresses since they use the paging
mechanism of the 80386. This service can be used by device
drivers to convert a physical address into a linear address.
The linear address can then be used to access the device
memory.
Some implementations of DPMI may not support this call
because it could be used to circumvent system protection.
This call should only be used by programs that absolutely
require direct access to a memory mapped device.
To Call
AX = 0800h
BX:CX = Physical address of memory
SI:DI = Size of region to map in bytes
Returns
If function was successful:
Carry flag is clear.
BX:CX = Linear address that can be used to access the
physical memory
If function was not successful:
Carry flag is set.
17. VIRTUAL INTERRUPT STATE FUNCTIONS
Under many implementations of DPMI, the interrupt flag in
protected mode will always be set (interrupts enabled).
This is because the program is running under a protected
operating system that can not allow programs to disable
physical hardware interrupts. However, the operating system
will maintain a "virtual" interrupt state for protected mode
programs. When the program executes a cli instruction, the
program's virtual interrupt state will be disabled, and the
program will not receive any hardware interrupts until it
executes an sti to reenable interrupts (or calls service
0901h).
When a protected mode program executes a pushf instruction,
the real processor flags will be pushed onto the stack.
Thus, examining the flags pushed on the stack is not
sufficient to determine the state of the program's virtual
interrupt flag. These services enable programs to get and
modify the state of their virtual interrupt flag.
The following sample code enters an interrupt critical
section and then restores the virtual interrupt state to
it's previous state.
17.1 Get and Disable Virtual Interrupt State
This function will disable the virtual interrupt flag
and return the previous state of the virtual interrupt flag.
To Call
AX = 0900h
Returns
Carry flag clear (this function always succeeds)
Virtual interrupts are disabled
AL = 0 if virtual interrupts were previously disabled
AL = 1 if virtual interrupts were previously enabled
17.2 Get and Enable Virtual Interrupt State
This function will enable the virtual interrupt flag
and return the previous state of the virtual interrupt flag.
To Call
AX = 0901h
Returns
Carry flag clear (this function always succeeds)
Virtual interrupts are enabled
AL = 0 if virtual interrupts were previously disabled
AL = 1 if virtual interrupts were previously enabled
17.3 Get Virtual Interrupt State
This function will return the current state of the
virtual interrupt flag.
To Call
AX = 0902h
Returns
Carry flag clear (this function always succeeds)
AL = 0 if virtual interrupts are disabled
AL = 1 if virtual interrupts are enabled
19. DEBUG REGISTER SUPPORT
The 80386 processor supports special registers that are used
for debugging. Since the instructions to modify these
registers can only be executed by code running at privileged
level zero, protected mode debuggers running in DPMI
environments can not modify the registers directly. These
services provide mechanisms for setting and clearing debug
watchpoints and detecting when a watchpoint has caused a
fault.
19.1 Set Debug Watchpoint
This function will set a debug watchpoint at a
specified linear address.
To Call
AX = 0B00h
BX:CX = Linear address of watchpoint
DL = Size of watchpoint (1, 2, or 4)
DH = Type of watchpoint
0 = Execute
1 = Write
2 = Read/Write
Returns
If function was successful:
Carry flag is clear
BX = Debug watchpoint handle
If function was not successful:
Carry flag is set
19.2 Clear Debug Watchpoint
This function will clear a debug watchpoint that was set using the Set Debug Watchpoint function.
To Call
AX = 0B01h
BX = Debug watchpoint handle
Returns
If function was successful:
Carry flag is clear
If function was not successful:
Carry flag is set
Get State of Debug Watchpoint
This function returns the state of a debug watchpoint that was set using the Set Debug Watchpoint function.
To Call
AX = 0B02h
BX = Debug Watchpoint Handle
Returns
If function was successful:
Carry flag is clear
AX = Status flags
Bit 0 = 1 if watch point has been executed
If function was not successful:
Carry flag is set
Reset Debug Watchpoint
This function resets the state of a previously defined
debug watchpoint.
To Call
AX = 0B03h
BX = Debug Watchpoint Handle
Returns
If function was successful:
Carry flag is clear
If function was not successful:
Carry flag is set
BY | Lewis Sellers lsellers@usit.net
SET VIDEO MODE
To Call:AH = 00h
AL = mode (see below)
INT 10h
Return:
AL = video mode flag
20h mode > 7
30h modes <= 7 except mode 6
3Fh mode 6
AL = CRT controller mode byte
IBM standard modes do not clear the screen if the high bit of AL is set
Values for video mode:text/ text pixel pixel colors display scrn system grph resol box resoltn pages addr 00h = T 40x25 8x14 16gray 8 B800 = T 40x25 8x16 16 8 B800 = T 40x25 9x16 16 8 B800 01h = T 40x25 8x14 16 8 B800 = T 40x25 8x16 16 8 B800 = T 40x25 9x16 16 8 B800 02h = T 80x25 8x14 16gray 4 B800 = T 80x25 8x16 16 4 B800 = T 80x25 9x16 16 4 B800 03h = T 80x25 8x14 16 4 B800 = T 80x25 8x16 16 4 B800 = T 80x25 9x16 16 4 B800 04h = G 40x25 8x8 320x200 4 B800 05h = G 40x25 8x8 320x200 4gray B800 = G 40x25 8x8 320x200 4 B800 06h = G 80x25 8x8 640x200 2 B800 07h = T 80x25 9x14 mono var B000 = T 80x25 9x16 mono B000 0Dh = G 40x25 8x8 320x200 16 8 A000 0Eh = G 80x25 8x8 640x200 16 4 A000 0Fh = G 80x25 8x14 640x350 mono 2 A000 10h = G 80x25 8x14 640x350 4 2 A000 = G 640x350 16 A000 11h = G 80x30 8x16 640x480 mono A000 12h = G 80x30 8x16 640x480 16/256k A000 = G 80x30 8x16 640x480 16/64 A000 13h = G 40x25 8x8 320x200 256/256k A000
SET TEXT-MODE CURSOR SHAPE
To Call:AH = 01h
CH = bit 7 should be zero
bits 6,5 cursor blink
(00=normal, 01=invisible, 10=erratic, 11=slow)
(00=normal, other=invisible on EGA/VGA)
bits 4-0 top scan line containing cursor
CL = bottom scan line containing cursor (bits 0-4)
SET CURSOR POSITION
AH = 02hBH = page number
0-3 in modes 2&3
0-7 in modes 0&1
0 in graphics modes
DH = row (00h is top)
DL = column (00h is left)
GET CURSOR POSITION AND SIZE
AH = 03hBH = page number
0-3 in modes 2&3
0-7 in modes 0&1
0 in graphics modes
Return:
AX = 0000h (Phoenix BIOS)
CH = start scan line
CL = end scan line
DH = row (00h is top)
DL = column (00h is left)
a separate cursor is maintained for each of up to 8 display pages many ROM BIOSes incorrectly return the default size for a color display (start 06h, end 07h) when a monochrome display is attached
READ LIGHT PEN POSITION
To CallAH = 04h
INT 10h
Return:
AH = light pen trigger flag
00h not down/triggered
01h down/triggered
DH,DL = row,column of character light pen is on
CH = pixel row (graphics modes 04h-06h)
CX = pixel row (graphics modes with >200 rows)
BX = pixel column
on a CGA, returned column numbers are always multiples of 2 (320-column modes) or 4 (640-column modes)
SELECT ACTIVE DISPLAY PAGE
To Call:AH = 05h
AL = new page number (00h to number of pages - 1) (see AH=00h)
INT 10h
SCROLL UP WINDOW
To Call:AH = 06h
AL = number of lines by which to scroll up (00h = clear entire window)
BH = attribute used to write blank lines at bottom of window
CH,CL = row,column of window's upper left corner
DH,DL = row,column of window's lower right corner
INT 10h
SCROLL DOWN WINDOW
AH = 07hAL = number of lines by which to scroll down (00h=clear entire window)
BH = attribute used to write blank lines at top of window
CH,CL = row,column of window's upper left corner
DH,DL = row,column of window's lower right corner
READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION
AH = 08hBH = page number (00h to number of pages - 1) (see AH=00h)
Return:
AH = attribute
bit 7: blink
bits 6-4: background color
000 black
001 blue
010 green
011 cyan
100 red
101 magenta
110 brown
111 white
bits 3-0: foreground color
0000 black 1000 dark gray
0001 blue 1001 light blue
0010 green 1010 light green
0011 cyan 1011 light cyan
0100 red 1100 light red
0101 magenta 1101 light magenta
0110 brown 1110 yellow
0111 light gray 1111 white
AL = character
for monochrome displays, a foreground of 1 with background 0 is underlined the blink bit may be reprogrammed to enable intense background colors using AX=1003h or by programming the CRT controller
WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION
AH = 09hAL = character to display
BH = page number (00h to number of pages - 1) (see AH=00h)
BL = attribute (text mode) or color (graphics mode)
if bit 7 set in graphics mode, character is xor'ed onto screen
CX = number of times to write character
all characters are displayed, including CR, LF, and BS replication count in CX may produce an unpredictable result in graphics modes if it is greater than the number of positions remaining in the current row
WRITE CHARACTER ONLY AT CURSOR POSITION
AH = 0AhAL = character to display
BH = page number (00h to number of pages - 1) (see AH=00h)
BL = attribute (PCjr only) or color (graphics mode)
if bit 7 set in graphics mode, character is xor'ed onto screen
CX = number of times to write character
all characters are displayed, including CR, LF, and BS replication count in CX may produce an unpredictable result in graphics modes if it is greater than the number of positions remaining in the current row
SET BACKGROUND/BORDER COLOR
AH = 0BhBH = 00h
BL = background/border color (border only in text modes)
SET PALETTE
AH = 0BHBH = 01h
BL = palette ID
00h background, green, red, and brown/yellow
01h background, cyan, magenta, and white
WRITE GRAPHICS PIXEL
AH = 0ChBH = page number
AL = pixel color (if bit 7 set, value is xor'ed onto screen)
CX = column
DX = row
Notes: valid only in graphics modes. BH is ignored if the current video mode supports only one page
READ GRAPHICS PIXEL
AH = 0DhBH = page number
CX = column
DX = row
Return: AL = pixel color
valid only in graphics modes. BH is ignored if the current video mode supports only one page
TELETYPE OUTPUT
AH = 0EhAL = character to write
BH = page number
BL = foreground color (graphics modes only)
characters 07h (BEL), 08h (BS), 0Ah (LF), and 0Dh (CR) are interpreted and do the expected things IBM PC ROMs dated 4/24/81 and 10/19/81 require that BH be the same as the current active page
GET CURRENT VIDEO MODE
AH = 0FhReturn: AH = number of character columns
AL = display mode (see AH=00h)
BH = active page (see AH=05h)
Notes: if mode was set with bit 7 set ("no blanking"), the returned mode will also have bit 7 set EGA, VGA, and UltraVision return either AL=03h (color) or AL=07h (monochrome) in all extended-row text modes
SET SINGLE PALETTE REGISTER
AX = 1000hBL = palette register number (00h-0Fh)
= attribute register number (undocumented)
10h attribute mode control register (should let BIOS control this)
11h overscan color register (see also AX=1001h)
12h color plane enable register (bits 3-0 enable corresponding
text attribute bit)
13h horizontal PEL panning register
14h color select register
BH = color or attribute register value
SET BORDER (OVERSCAN) COLOR
To Call:AX = 1001h
BH = border color (00h-3Fh)
INT 10h
SET ALL PALETTE REGISTERS
To Call:AX = 1002h
ES:DX -> palette register list
Format of palette register list:
Offset Size Description
00h 16 BYTEs colors for palette registers 00h through 0Fh
10h BYTE border color
TOGGLE INTENSITY/BLINKING BIT
To Call:AX = 1003h
BL = new state
00h background intensity enabled
01h blink enabled
although there is no function to get the current status, bit 5 of 0040h:0065h indicates the state
GET INDIVIDUAL PALETTE REGISTER
To Call:AX = 1007h
BL = palette or attribute register number
Return:
BH = palette or attribute register value
READ OVERSCAN (BORDER COLOR) REGISTER
To Call:AX = 1008h
Return:
BH = border color (00h-3Fh)
READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER
AX = 1009hES:DX -> 17-byte buffer (see AX=1002h)
SET INDIVIDUAL DAC REGISTER
AX = 1010hBX = register number
CH = new value for green (0-63)
CL = new value for blue (0-63)
DH = new value for red (0-63)
SET BLOCK OF DAC REGISTERS
AX = 1012hBX = starting color register
CX = number of registers to set
ES:DX -> table of 3*CX bytes where each 3 byte group represents one
byte each of red, green and blue (0-63)
SELECT VIDEO DAC COLOR PAGE
AX = 1013hBL = subfunction
00h select paging mode
BH = 00h select 4 blocks of 64
BH = 01h select 16 blocks of 16
01h select page
BH = page number (00h to 03h) or (00h to 0Fh)
Note: not valid in mode 13h
READ INDIVIDUAL DAC REGISTER
AX = 1015hBL = palette register number
Return: DH = red value
CH = green value
CL = blue value
READ BLOCK OF DAC REGISTERS
AX = 1017hBX = starting palette register
CX = number of palette registers to read
ES:DX -> buffer (3 * CX bytes in size) (see also AX=1012h)
Return: buffer filled with CX red, green and blue triples
SET PEL MASK (VGA/MCGA)
AX = 1018hBL = new PEL value
READ PEL MASK (VGA/MCGA)
AX = 1019hReturn: BL = value read
GET VIDEO DAC COLOR-PAGE STATE (VGA)
To Call:AX = 101Ah
Return:
BL = paging mode
00h four pages of 64
01h sixteen pages of 16
BH = current page
PERFORM GRAY-SCALE SUMMING (VGA/MCGA)
AX = 101BhBX = starting palette register
CX = number of registers to convert
TEXT-MODE CHARACTER GENERATOR FUNCTIONS
AH = 11hThe following functions will cause a mode set, completely resetting
the video environment, but without clearing the video buffer
AL = 00h, 10h: load user-specified patterns
ES:BP -> user table
CX = count of patterns to store
DX = character offset into map 2 block
BL = block to load in map 2
BH = number of bytes per character pattern
AL = 01h, 11h: load ROM monochrome patterns (8 by 14)
BL = block to load
AL = 02h, 12h: load ROM 8 by 8 double-dot patterns
BL = block to load
AL = 03h: set block specifier
BL = block specifier
bits 0,1 = block selected by chars with attribute bit 3=0
bits 2,3 = block selected by chars with attribute bit 3=1
bits 0,1,4 = block selected by attribute bit 3 = 0
bits 2,3,5 = block selected by attribute bit 3 = 1
AL = 04h, 14h: load ROM 8x16 character set (VGA)
BL = block to load
The routines called with AL=1xh are designed to be called only
immediately after a mode set and are similar to the routines called
with AL=0xh, except that:
Page 0 must be active.
Bytes/character is recalculated.
Max character rows is recalculated.
CRT buffer length is recalculated.
CRTC registers are reprogrammed as follows:
R09 = bytes/char-1 ; max scan line (mode 7 only)
R0A = bytes/char-2 ; cursor start
R0B = 0 ; cursor end
R12 = ((rows+1)*(bytes/char))-1 ; vertical display end
R14 = bytes/char ; underline loc
(*** BUG: should be 1 less ***)
GRAPHICS-MODE CHARACTER GENERATOR FUNCTIONS
AH = 11hAL = 20h: set user 8 by 8 graphics characters (INT 1F)
ES:BP -> user table
AL = 21h: set user graphics characters
ES:BP -> user table
CX = bytes per character
BL = row specifier
00h user set
DL = number of rows
01h 14 rows
02h 25 rows
03h 43 rows
AL = 22h: ROM 8 by 14 set
BL = row specifier (see above)
AL = 23h: ROM 8 by 8 double dot
BL = row specifier (see above)
AL = 24h: load 8x16 graphics characters (VGA/MCGA)
BL = row specifier (see above)
AL = 29h: load 8x16 graphics characters (Compaq Systempro)
BL = row specifier (see above)
GET FONT INFORMATION (EGA, MCGA, VGA)
AX = 1130hBH = pointer specifier
00h INT 1Fh pointer
01h INT 43h pointer
02h ROM 8x14 character font pointer
03h ROM 8x8 double dot font pointer
04h ROM 8x8 double dot font (high 128 characters)
05h ROM alpha alternate (9 by 14) pointer (EGA,VGA)
06h ROM 8x16 font (MCGA, VGA)
07h ROM alternate 9x16 font (VGA only)
11h (UltraVision v2+) 8x20 font (VGA) or 8x19 font (autosync EGA)
12h (UltraVision v2+) 8x10 font (VGA) or 8x11 font (autosync EGA)
Return: ES:BP = specified pointer
CX = bytes/character
DL = character rows on screen - 1
ALTERNATE FUNCTION SELECT
AH = 12hBL = 10h
Return: BH = 00h color mode in effect (I/O port 3Dxh)
01h mono mode in effect (I/O port 3Bxh)
BL = 00h 64k bytes memory installed
01h 128k bytes memory installed
02h 192k bytes memory installed
03h 256k bytes memory installed
CH = feature bits
CL = switch settings
ALTERNATE FUNCTION SELECT
AH = 12hBL = 20h select alternate print screen routine
installs a PrtSc routine from the video card's BIOS to replace the default PrtSc handler from the ROM BIOS, which usually does not understand screen heights other than 25 lines some adapters disable print-screen instead of enhancing it
ALTERNATE FUNCTION SELECT (VGA) - SELECT VERTICAL RESOLUTION
AH = 12hBL = 30h
AL = vertical resolution
00h 200 scan lines
01h 350 scan lines
02h 400 scan lines
ALTERNATE FUNCTION SELECT (VGA, MCGA) - PALETTE LOADING
AH = 12hBL = 31h
AL = 00h enable default palette loading
01h disable default palette loading
Return: AL = 12h if function supported
ALTERNATE FUNCTION SELECT (VGA, MCGA) - VIDEO ADDRESSING
AH = 12hBL = 32h
AL = 00h enable video addressing
01h disable video addressing
Return: AL = 12h if function supported
ALTERNATE FUNCTION SELECT (VGA, MCGA) - GRAY-SCALE SUMMING
AH = 12hBL = 33h
AL = 00h enable gray scale summing
01h disable gray scale summing
Return: AL = 12h if function supported
ALTERNATE FUNCTION SELECT (VGA) - CURSOR EMULATION
AH = 12hBL = 34h
AL = 00h enable alphanumeric cursor emulation
01h disable alphanumeric cursor emulation
Return: AL = 12h if function supported
ALTERNATE FUNCTION SELECT (PS) - DISPLAY-SWITCH INTERFACE
AH = 12hBL = 35h
AL = 00h initial adapter video off
01h initial planar video on
02h switch active video off
03h switch inactive video on
80h *UNDOCUMENTED* set system board video active flag
ES:DX -> buffer (128 byte save area if AL = 0, 2 or 3)
Return: AL = 12h if function supported
ALTERNATE FUNCTION SELECT (PS, VGA) - VIDEO REFRESH CONTROL
AH = 12hBL = 36h
AL = 00h enable refresh
01h disable refresh
Return: AL = 12h if function supported
WRITE STRING
To Call:AH = 13h
AL = write mode
bit 0: update cursor after writing
1: string contains alternating characters and attributes
BH = page number
BL = attribute if string contains only characters
CX = number of characters in string
DH,DL = row,column at which to start writing
ES:BP -> string to write
recognizes CR, LF, BS, and bell
DISPLAY COMBINATION
To Call:AH = 1Ah
AL = 00h read display combination code
Return:
BL = active display code (see below)
BH = alternate display code
01h set display combination code
BL = active display code (see below)
BH = alternate display code
Return:
AL = 1Ah if function was supported
Values for display combination code:
00h no display
01h monochrome adapter w/ monochrome display
02h CGA w/ color display
03h reserved
04h EGA w/ color display
05h EGA w/ monochrome display
06h PGA w/ color display
07h VGA w/ monochrome analog display
08h VGA w/ color analog display
09h reserved
0Ah MCGA w/ digital color display
0Bh MCGA w/ monochrome analog display
0Ch MCGA w/ color analog display
FFh unknown display type
FUNCTIONALITY/STATE INFORMATION
AH = 1BhBX = implementation type
0000h return functionality/state information
ES:DI -> 64 byte buffer for state information (see below)
Return: AL = 1Bh if function supported
ES:DI buffer filled with state information
Format of state information:
Offset Size Description
00h DWORD address of static functionality table (see below)
04h BYTE video mode in effect
05h WORD number of columns
07h WORD length of regen buffer in bytes
09h WORD starting address of regen buffer
0Bh WORD cursor position for page 0
0Dh WORD cursor position for page 1
0Fh WORD cursor position for page 2
11h WORD cursor position for page 3
13h WORD cursor position for page 4
15h WORD cursor position for page 5
17h WORD cursor position for page 6
19h WORD cursor position for page 7
1Bh WORD cursor type
1Dh BYTE active display page
1Eh WORD CRTC port address
20h BYTE current setting of register (3?8)
21h BYTE current setting of register (3?9)
22h BYTE number of rows
23h WORD bytes/character
25h BYTE display combination code of active display
26h BYTE DCC of alternate display
27h WORD number of colors supported in current mode
29h BYTE number of pages supported in current mode
2Ah BYTE number of scan lines active
(0,1,2,3) = (200,350,400,480)
2Bh BYTE primary character block
2Ch BYTE secondary character block
2Dh BYTE miscellaneous flags
bit 0 all modes on all displays on
1 gray summing on
2 monochrome display attached
3 default palette loading disabled
4 cursor emulation enabled
5 0 = intensity; 1 = blinking
6 PS/2 P70 plasma display (without 9-dot wide font) active
7 reserved
2Eh 3 BYTEs reserved (00h)
31h BYTE video memory available
00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K
32h BYTE save pointer state flags
bit 0 512 character set active
1 dynamic save area present
2 alpha font override active
3 graphics font override active
4 palette override active
5 DCC override active
6 reserved
7 reserved
33h 13 BYTEs reserved (00h)
Format of Static Functionality Table:
Offset Size Description
00h BYTE modes supported #1
bit 0 to bit 7 = 1 modes 0,1,2,3,4,5,6 supported
01h BYTE modes supported #2
bit 0 to bit 7 = 1 modes 8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh supported
02h BYTE modes supported #3
bit 0 to bit 3 = 1 modes 10h,11h,12h,13h supported
bit 4 to bit 7 reserved
03h 4 BYTEs reserved
07h BYTE scan lines supported
bit 0 to bit 2 = 1 if scan lines 200,350,400 supported
08h BYTE total number of character blocks available in text modes
09h BYTE maximum number of active character blocks in text modes
0Ah BYTE miscellaneous function flags #1
bit 0 all modes on all displays function supported
1 gray summing function supported
2 character font loading function supported
3 default palette loading enable/disable supported
4 cursor emulation function supported
5 EGA palette present
6 color palette present
7 color paging function supported
0Bh BYTE miscellaneous function flags #2
bit 0 light pen supported
1 save/restore state function 1Ch supported
2 intensity blinking function supported
3 Display Combination Code supported
4-7 reserved
0Ch WORD reserved
0Eh BYTE save pointer function flags
bit 0 512 character set supported
1 dynamic save area supported
2 alpha font override supported
3 graphics font override supported
4 palette override supported
5 DCC extension supported
6 reserved
7 reserved
0Fh BYTE reserved
SAVE/RESTORE VIDEO STATE
To Call:AH = 1Ch
AL = 00h return state buffer size
INT 10h
Return:
BX = number of 64-byte blocks needed
01h save video state
ES:BX -> buffer
02h restore video state
ES:BX -> buffer containing previously saved state
CX = requested states
bit 0 video hardware
1 BIOS data areas
2 color registers and DAC state
3-15 reserved
Return:
AL = 1Ch if function supported
BY | Lewis Sellers lsellers@usit.net
Many BIOSes do not fully support the joystick for some reason, leaving software forced to directly use port 21h. Legacy DOES fully support the joystick BIOS routines.
Read Joystick Buttons
To Call:AH = 84h
DX = 00h Read switch settings
INT 15h
Returns:
AL = Switch settings (bits 4 - 7)
Carry flag set on error
Read Joystick Position
To Call:AH = 84h
DX = 01h Read joystick position
INT 15h
Returns:
AX = A(X) value
BX = A(Y) value
CX = B(X) value
DX = B(Y) value
BY | Lewis Sellers lsellers@usit.net
The operation of the keyboard is really quite simple. Every time a key is pressed or released an interrupt 9 is generated, and reading the value from port 60h tells you what happened.
Decoding the Keyboard Byte
Well..each key on the keyboard has an associated scan code which is contained in the lower 7 bits of the byte. The most significant bit (ie bit 7) tells you what was actually done, 0 = key was just pressed, 1 = key was just released. If someone had just pressed the ESC key for instance, the port will show a value of 1 (1 is the ESC key's scan code). If they hold their finger on the button the keyboard will keep generating interrupt 9's and each time the port will still show a value of 1. When the person releases the key
a final interrupt will be generated and the port will return 129 (1 + 128, since the high bit will be set indicating the person has released the key).
Some keys are "extended" keys. When an
extended key is pressed an interrupt is generated and the keyboard port
will return a value of 224 (E0h). This means that an extended key was pressed
and it's *extended* scan code will be available during the *next* interrupt.
Note that the left control key has a scan code of 29, while the *right*
control key has an *extended* scan code of 29. The same applies to the alt
keys and the arrow keys (keypad arrows vs the other ones).
It would be nice if all keys were created equal and we could just throw away
the 224 extended bytes and handle all the other bytes normally. Unfortunately
there are two buttons which on my machine at least (and others I have tested)
do some really weird stuff:
Scan Codes
The following is a list of all the regular key scan codes in numerical order:
Scan Scan
Code Key Code Key
1 ESC 44 Z
2 1 45 X
3 2 46 C
4 3 47 V
5 4 48 B
6 5 49 N
7 6 50 M
8 7 51 , <
9 8 52 . >
10 9 53 / ?
11 0 54 RIGHT SHIFT
12 - _ 55 * (KEYPAD)
13 = + 56 LEFT ALT
14 BACKSPACE 57 SPACEBAR
15 TAB 58 CAPSLOCK
16 Q 59 F1
17 W 60 F2
18 E 61 F3
19 R 62 F4
20 T 63 F5
21 Y 64 F6
22 U 65 F7
23 I 66 F8
24 O 67 F9
25 P 68 F10
26 [ { 69 NUMLOCK (KEYPAD)
27 ] } 70 SCROLL LOCK
28 ENTER (RETURN) 71 7 HOME (KEYPAD)
29 LEFT CONTROL 72 8 UP (KEYPAD)
30 A 73 9 PGUP (KEYPAD)
31 S 74 - (KEYPAD)
32 D 75 4 LEFT (KEYPAD)
33 F 76 5 (KEYPAD)
34 G 77 6 RIGHT (KEYPAD)
35 H 78 + (KEYPAD)
36 J 79 1 END (KEYPAD)
37 K 80 2 DOWN (KEYPAD)
38 L 81 3 PGDN (KEYPAD)
39 ; : 82 0 INSERT (KEYPAD)
40 ' " 83 . DEL (KEYPAD)
41 ' ~ 87 F11
42 LEFT SHIFT 88 F12
The following is a list of all the extended key scan codes in numerical order:
Scan Scan
Code Key Code Key
28 ENTER (KEYPAD) 75 LEFT (NOT KEYPAD)
29 RIGHT CONTROL 77 RIGHT (NOT KEYPAD)
42 PRINT SCREEN (SEE TEXT) 79 END (NOT KEYPAD)
53 / (KEYPAD) 80 DOWN (NOT KEYPAD)
55 PRINT SCREEN (SEE TEXT) 81 PAGE DOWN (NOT KEYPAD)
56 RIGHT ALT 82 INSERT (NOT KEYPAD)
71 HOME (NOT KEYPAD) 83 DELETE (NOT KEYPAD)
72 UP (NOT KEYPAD) 111 MACRO
73 PAGE UP (NOT KEYPAD)
BY | Lewis Sellers lsellers@usit.net
Reset Mouse
To Call:AX = 0
Return:
AX = mouse state (-1: installed, 0: not installed)
BX = number of buttons (2 button mode, 3 button mode)
gives the current status of the mouse hardware plus the current status of the mouse software. The calling program is able to determine the presence of a mouse driver and/or a serial port.
This function resets the mouse driver to the following default status as indicated:
Variable Value
----------------------------------------------------------------------------
internal cursor flag -1 (cursor concealed)
graphics cursor shape horizontal oval
text cursor reverse video
user-defined call mask all zeroes
light pen emulation mode enabled
vertical mouse motion/pixel ratio 16 to 8
horizontal mouse motion/pixel ratio 8 to 8
vertical min/max cursor coordinates 0/current display mode y values minus 1
horizontal min/max cursor coordinates 0/current display mode x values minus 1
Enable Cursor Display
To Call:
AX = 1
INT 31h
Return:
none
Makes the cursor visible if it was not already.
Disable Cursor Display
To Call:
AX = 2
Return:
none
This function disables the cursor (removes it from the screen). Though not visible, all motion by the mouse is still tracked.
Read Cursor Location & Button State of Mouse
To Call:AX = 3
INT 31h
Return:
BX = button status
CX = horizontal cursor coordinate
DX = vertical cursor coordinate
gives the status of mouse buttons, plus cursor location.
Button status consists of a single integer value:
Bit 0 = left button (2 button mode, 3 button mode)
Bit 1 = right button (2 button mode, 3 button mode)
Bit 2 = middle button (3 button mode)
The bit is 1 when the button is pressed. The bit is 0 when the button is released.
Set Cursor Location of Mouse
To Call:AX = 4
CX = new horizontal cursor coordinate
DX = new vertical cursor coordinate
Return:
none
sets the current cursor location. Values must be within the coordinate ranges for the virtual screen and, if necessary, are rounded to the nearest values allowed for the current screen mode.
Read Button Press State of Mouse
To Call:AX = 5
BX = button status (left = 0, right = 1, middle = 2)
Return:
AX = button status
BX = number of button presses
CX = horizontal cursor coordinate at last press
DX = vertical cursor coordinate at last press
provides status on the specified button, gives the number of button presses since the last call, and produces the location of the cursor at last button press.
Button status consists of a single integer value. Again, as in function 3:
Bit 0 = left button (2 button mode, 3 button mode)Bit 1 = right button (2 button mode, 3 button mode)
Bit 2 = middle button (3 button mode)
The number of button presses will always fall in the range of 0 to 32767. There is no indicator for overflow. Following this function call, the count is reset to zero.
AX = 6
BX = button status (left = 0, right = 1, middle = 2)
Return:
AX = button status
BX = number of button releases
CX = horizontal cursor coordinate at last release
DX = vertical cursor coordinate at last release
provides status on the specified button, gives the number of button releases since the last call, and provides the location of the cursor at the last button release.
Button status consists of a single integer value. Again, as in function 3:
Bit 0 = left button (2 button mode, 3 button mode)
Bit 1 = right button (2 button mode, 3 button mode)
Bit 2 = middle button (3 button mode)
The bit is 1 when the button is pressed. The bit is 0 when the button is released.
The number of button releases will always fall in the range of 0 to 32767.
There is no indicator for overflow. Following this function call, the count is
reset to zero.
AX = 7
CX = minimum horizontal cursor coordinate
DX = maximum horizontal cursor coordinate
Return: none
defines the horizontal range of the cursor on-screen. As a result, cursor movement is limited to this specified area. If a cursor happens to be
outside of this area when a call is made, the cursor is moved to just inside the
area.
AX = 8
CX = minimum vertical cursor coordinate
DX = maximum vertical cursor coordinate
Return: none
defines the vertical range of the cursor on-screen. As a result, cursor movement is limited to this specified area. If a cursor happens to be outside of this area when a call is made, the cursor is moved to just inside the area.
BX = horizontal cursor hot spot
CX = vertical cursor hot spot
DX = pointer to screen and cursor mask
Return: none
defines the style of the cursor in terms of color, shape, and center
for the graphics. As mentioned before, this cursor is a 16-by-16 pixel block
and is defined by two 16-bit arrays (the screen mask bit and the cursor mask bit).
Cursor coordinates for the hot spot must be in the range of -16 to +16.
Define Text Mode Cursor Style
To Call:
AX = 10
BX = select cursor (0: software text, 1: hardware text)
CX = screen mask value/scan line start
DX = cursor mask value/scan line stop
Return:
none
chooses the hardware or the software text cursor.
For example, if BX (G2%) is 1, the hardware cursor is selected and the hardware
is set up with the first and last scan lines which define the cursor.
(Values for CX (G3%) and DX (G4%) range from 0 to 7 for the color display and 0
to 11 for the monochrome display.)
If BX (G2%) is 0, the software cursor is selected; and CX (G3%) and DX (G4%)
must specify the screen and cursor masks. (These masks give the attributes and
character code of the cursor, and their values are dependent on the type of display in use.)
AX = 11
Return:
CX = horizontal number
DX = vertical number
gives the mouse motion number since the last call. A positive horizontal number indicates rightward movement (negative shows leftward movement). A positive vertical number indicates downward movement (negative shows upward movement).
The number is always in the range of -32768 to 32767. Overflow is disregarded. Once the call is completed, the number is set to 0.
AX = 12
CX = call mask
ES:DX = pointer to event handler routine
Return:
none
defines the address entry location of an event handler routine which is called when a certain event (defined by the call mask) occurs. The program is temporarily interrupted by the mouse driver. At the end of the event handler routine the program continues at the point it was interrupted.
The call mask is a single integer value defining the conditions which will cause an interrupt.
A specific condition corresponds to a bit in the call mask:
Mask Bit Condition
--------------------------------------------------
0 cursor location changed
1 left button pressed
2 left button released
3 right button pressed
4 right button released
5 middle button pressed
6 middle button released
7 - 15 not used
In order to call the event handler routine, set the mask bit to 1 and put the mask in at CX (G3%). To disable, set the mask bit to 0 and put the mask in at CX (G3%). Always be sure to set the call mask to 0 before the program finishes. (Leave the system in the same state upon exit as if was upon entrance.)
AX = 13
Return:
none
permits the mouse to act like a light pen. When in this mode, calls to the pen function will give the cursor coordinates at the last pen down location.
Note that the status of "pen down" and "pen off-screen" is controlled by the mouse buttons: all buttons up, pen off-screen; one button pressed, pen down.
Light pen emulation is ON after each call to function 0 (Reset Mouse Driver).
AX = 14
Return:
none
turns off the light pen emulation mode. When disabled, any call to the pen function will give information only about a real light pen.
AX = 15
CX = horizontal mouse motion counts to pixel ratio
DX = vertical mouse motion counts to pixel ratio
Return:
none
defines mouse sensitivity as determined by the mouse motion/pixel ratio. This is a way of setting the amount of cursor motion wanted for mouse movement. These ratios specify mouse motion per 8 pixels. These values must be in the range of 1 to 32767. With a larger ratio, the cursor movement is shortened for each mouse movement.
Default values: horizontal ratio - 8 mouse motions to 8 pixels
vertical ratio - 16 mouse motions to 8 pixels
Note: 1 mouse motion = 1/200 of an inch increment
AX = 16
ES:DX = pointer to special range
Return:
none
sets up a special range on-screen. If the cursor moves to this area or is in this area, it will be disabled. After a call is made to this function, it is necessary to call function 1 to enable the cursor again.
Define the special range with screen location values using four components:
Components Values
--------------------------------------------------------
1 Left horizontal screen location
2 Upper vertical screen location
3 Right horizontal screen location
4 Lower vertical screen location
AX = 19
DX = threshold speed in mouse motions/second
Return:
none
defines the threshold value (mouse motion per second) for doubling the cursor's motion. Should the mouse move faster than the DX (G4%) value, the cursor motion doubles. The default value is 64 mouse motions per second.
If you should want to disable double-speed, just set the threshold to 32767 (7FFFH) mouse motions/second.
AX = 20
CX = new call mask
ES:DX = new pointer to event handler routine
Return:
CX = old call mask
ES:DX = old pointer to event handler routine
sets new values for the call mask and event handler routine address for mouse hardware interrupts and return the values that were previously specified.
For detail information to reference Function 12 description.
AX = 21
Return:
BX = buffer size required for mouse driver state
returns the size of the buffer required to store the current state of the mouse driver. It is used with functions 22 and 23 when you want to temporarily interrupt a program that is using the mouse and execute another that also uses the mouse.
AX = 22
ES:DX = pointer to the buffer
Return:
None
saves the current mouse driver state in a buffer allocated by your program. It is used with functions 21 and 23 when you want to temporarily interrupt a program that is using the mouse and execute another program that also uses the mouse.
Before your program calls function 22, the program should call function 21 to determine the buffer size required for saving the mouse driver state, then allocate the appropriate amount of memory.
AX = 23
ES:DX = pointer to the buffer
Return:
None
restores the last mouse driver state saved by function 22. It is used with functions 21 and 22 when you want to temporarily interrupt a program that is using the mouse and execute another program that also uses the mouse. To restore the mouse driver state saved by function 22, call function 23 at the end of the interrupt program.
AX = 29
BX = CRT page for mouse cursor display
Return:
none
specifies the CRT page on which the mouse cursor will be displayed.
For information on the number of CRT pages available in each display mode your adapter supports, see the documentation that came with the graphics adapter.
AX = 30
Return:
BX = CRT page number of current cursor display
returns the number of the CRT page on which the mouse cursor is displayed.
The cursor in use is defined as a monochrome cursor with one bit per pixel. The bit masks are determined by function 9 and apply to all active planes.
In order to make an EGA function call from an Assembly-Language program, first load the AX, BX, CX, DX, and ES registers with the values indicated for the parameters. Note that five values must be given for a high level language program. Next, execute software interrupt 16 (10h). The values that are returned are intalled in the registers by EGA functions.
Upon start with DOS, PC BIOS will verify if the EGA BIOS exists. When this is verified, the PC will execute the EGA BIOS, booting up the program to write the INT 10h entry vector to the address of the INT 42h vector. Now, EGA BIOS address will be written to INT 10h. Following this, you are able to call EGA BIOS (by using INT 10h) and PC video BIOS (by using INT 42h).
The following indicates nine EGA functions and the corresponding function number:
Function Number (HEX)
-----------------------------------------------------------------
Retrieve Single Data F0
Save Single Data F1
Retrieve Registers on a Specified Port F2
Save Registers on a Specified Port F3
Retrieve Several Registers Data F4
Save Several Registers Data F5
Reset All Registers as Initial Values F6
Set Initial Values F7
Get Version Number of Mouse Driver FA
In the above functions, the EGA I/O port number and address are as follows:
Note: x = B or D depending on the base I/O address;Port No. Register Name No. of Registers Index No. Address Select Register
00H CRT Controller 25 0 - 24 3x4H 08H Sequencer 5 0 - 4 3C4H 10H Graphics Controller 9 0 - 8 3CEH 18H Attribute Controlle 20 0 - 19 3C0H Singular Registers 20H Miscellaneous Output 1 ignored 3C2H 28H Feature Control 1 ignored 3xAH 30H Graphics 1 Position 1 ignored 3CCH 38H Graphics 2 Position 1 ignored 3CAH
determined by Miscellaneous Output Register bit 1.
AH = F0H
BX = Index number
DX = Port number
Return:
BL = Retrieved data from EGA register
This function retrieves data from a single register.
AH = F1H
BL = Index number (Non-single register only)
= Data (Single register only)
BH = Data (Non-single register only)
= Disregard (Single register only)
DX = Port number
Return:
None
This function saves data to an EGA register. Upon finishing a call to this function, the BH and DX values are altered.
AH = F3H
CH = Starting index number
CL = Number of registers
DX = Port number
ES:BX = Destination of returned data
Return:
Returned data to destination address
This function retrieves data from registers on a specifiã port. Upon finishing a call to this function, the CX value is altered.
AH = F3H
CH = Starting index number
CL = Number of register
DX = Port number
ES:BX = Address source of incoming data
Return:
None
This function saves data from registers on a specifiã port. Upon finishing a call to this function, the BX, CX, and DX values are altered.
CX = Number of registers (more than 1)
ES:BX = Address of register packet (each consists of 4 bytes;
port address, byte 1-2; index number, byte 3;
returned data, byte 4)
Return: Returned data is saved into byte 4
This function retrieves data from several registers at the same time. Upon finishing a call to this function, the CX value is altered.
AH = F5H
CX = Number of registers (more than 1)
ES:BX = Address of register packet (each consists of 4 bytes;
port number, byte 1-2; index number, byte 3; output data, byte 4)
Return:
None
This function saves data from several registers at the same time. Upon finishing a call to this function, the CX value is altered.
AH = F6H
Return:
None
This function resets all values to default values for the specific registers. Function 7 sets the default values.
To Call:
AH = F7H
DX = Port number
ES:BX = Table of output data
To Call:
AH = FAH
BX = 00H
Return:
ES:BX = Pointer to Mouse driver version number.
Under Legacy FCB functions are mostly dummy operations. They provide only enough functionality to emulate getting or setting the "volume label".
AH = 60h
DS:SI -> ASCIZ filename or path
ES:DI -> 128-byte buffer for canonicalized name
INT 21h
Return:
CF set on error
AX = error code
02h invalid component in directory path or drive letter only
03h malformed path or invalid drive letter
ES:DI buffer unchanged
CF clear if successful
AH = 00h
AL = destroyed (00h or 5Ch or last char of current dir on drive)
determine the canonical name of the specified filename or path, corresponding to the undocumented TRUENAME command in COMMAND.COM
Notes: the input path need not actually exist
letters are uppercased, forward slashes converted to backslashes,
asterisks converted to appropriate number of question marks, and
file and directory names are truncated to 8.3 if necessary. (DR-DOS
3.41 and 5.0 do not expand asterisks)
'.' and '..' in the path are resolved
filespecs on local drives always start with "d:", those on network
drives always start with "\\"
if path string is on a JOINed drive, the returned name is the one that
would be needed if the drive were not JOINed; similarly for a
SUBSTed, ASSIGNed, or network drive letter. Because of this, it is
possible to get a qualified name that is not legal under the current
combination of SUBSTs, ASSIGNs, JOINs, and network redirections
under DOS 3.3 through 6.00, a device name is translated differently if
the device name does not have an explicit directory or the directory
is \DEV (relative directory DEV from the root directory works
correctly). In these cases, the returned string consists of the
unchanged device name and extension appended to the string X:/
(forward slash instead of backward slash as in all other cases) where
X is the default or explicit drive letter.
functions which take pathnames require canonical paths if invoked via
INT 21/AX=5D00h
supported by OS/2 v1.1 compatibility box
AX = 6300h
INT 21h
Return:
AL = error code
00h successful
DS:SI -> DBCS table (see #0952)
all other registers except CS:IP and SS:SP destroyed
FFh not supported
the US version of MS-DOS 3.30 treats this as an unused function, setting AL=00h and returning immediately the US version of DOS 4.0+ accepts this function, but returns an empty list
Format of DBCS table:
Offset Size Description (Table 0952)
00h 2 BYTEs low/high ends of a range of leading byte of double-byte chars
02h 2 BYTEs low/high ends of a range of leading byte of double-byte chars
...
N 2 BYTEs 00h,00h end flag
INT 21 - DOS 2.25, Far East DOS 3.2+ - SET KOREAN (HANGEUL) INPUT MODE
AX = 6301h
DL = new mode
00h return only full characters on DOS keyboard input functions
01h return partially-formed (interim) characters also
Return: AL = status
00h successful
FFh invalid mode
INT 21h
Return: AL = status
00h successful
DL = current input mode
00h return only full characters (clears interim flag)
01h return partial characters (sets interim flag)
FFh not supported
INT 21 - DOS 3.3+ - SET HANDLE COUNT
AH = 67h
BX = size of new file handle table for process
Return: CF clear if successful
CF set on error
AX = error code (see #0885 at AH=59h)
Desc: adjust the size of the per-process open file table, thus raising or
lowering the limit on the number of files the caller can open
simultaneously
Notes: if BX <= 20, no action is taken if the handle limit has not yet been
increased, and the table is copied back into the PSP if the limit
is currently > 20 handles
for file handle tables of > 20 handles, DOS 3.30 never reuses the
same memory block, even if the limit is being reduced; this can lead
to memory fragmentation as a new block is allocated and the existing
one freed
only the first 20 handles are copied to child processes in DOS 3.3-6.0
increasing the file handles here will not, in general, increase the
number of files that can be opened using the runtime library of a
high-level language such as C
Novell DOS 7 reportedly terminates the calling program if the JFT is
being reduced in size and there are any open file handles beyond
the portion of the JFT being retained
BUGS: the original release of DOS 3.30 allocates a full 64K for the handle
table on requests for an even number of handles
DR-DOS 3.41 and 5.0 will lose track of any open file handles beyond
the portion of the JFT retained after the call; MS-DOS will indicate
error 04h if any of the JFT entries to be removed are open
INT 21 - DOS 3.3+ - "FFLUSH" - COMMIT FILE
AH = 68h
BX = file handle
Return: CF clear if successful
all data still in DOS disk buffers is written to disk immediately,
and the file's directory entry is updated
CF set on error
AX = error code (see #0885 at AH=59h)
INT 21 U - DOS 4.0+ - COMMIT FILE
AH = 6Ah
BX = file handle
Return: CF clear if successful
AH = 68h
CF set on error
AX = error code (06h) (see #0885 at AH=59h)
identical to AH=68h in DOS 5.0-6.0; not known whether this is the case in DOS 4.x
BL = open mode as in AL for normal open (see also AH=3Dh)
bit 7: inheritance
bits 4-6: sharing mode
bit 3 reserved
bits 0-2: access mode
BH = flags
bit 6 = auto commit on every write (see also AH=68h)
bit 5 = return error rather than doing INT 24h
CX = create attribute (see #0965)
DL = action if file exists/does not exist (see #0966)
DH = 00h (reserved)
DS:SI -> ASCIZ file name
INT 21h
Return: CF set on error
AX = error code (see #0885 at AH=59h)
CF clear if successful
AX = file handle
CX = status (see #0964)
(Table 0964)
Values for extended open function status:
01h file opened
02h file created
03h file replaced
Bitfields for file create attribute:
Bit(s) Description (Table 0965)
6-15 reserved
5 archive
4 reserved
3 volume label
2 system
1 hidden
0 readonly
Bitfields for action:
Bit(s) Description (Table 0966)
7-4 action if file does not exist
0000 fail
0001 create
3-0 action if file exists
0000 fail
0001 open
0010 replace/open
INT 21 - MS-DOS 7 (Windows95) - ??? (country-specific?)
AH = 70h
AL = subfunction
00h get ??? info
CX = buffer size (3Ah bytes needed)
ES:DI -> buffer
01h set above info
02h set ??? info
CX = buffer size >= 26h;
first three bytes are skipped, the rest is copied to somewhere
in the DOS data segment
Return: CF clear if successful
ES:DI buffer filled (func 00h)
returned was (among others) "ENU USA GR"..."AM PM M/d/yy"...
"dddd,MMMMdd,yyyy" in the German Preview version, and "US"
instead of "GR" in the US build 450 version (with German
country setting)
CF set on error
AX = error code
7000h if function not supported
AH = 71h
AL = function
39h create directory
3Ah remove directory
3Bh set current directory
41h delete file
43h get file attributes (BL=00h), set file attributes (BL=01h)
47h get current directory
4Eh find first file
4Fh find next file
56h move (rename) file
6Ch create/open file
INT 21h
Return:
CF set on error
AX = error code
7100h if function not supported
CF clear if successful
other registers as for corresponding "old" DOS function
if error 7100h is returned, the old-style function should be called AX=714Eh returns a "search handle" which must be passed to AX=714Fh; when the search is complete, AX=71A1h must be called to terminate the search
INT 21 - Windows95 - LONG FILENAME - FIND FIRST MATCHING FILE
AX = 714Eh
SI = 0000h
DS:DX -> ASCIZ filespec
ES:DI -> FindData record (see #2695)
Return: CF clear if successful
AX = filefind handle (needed to continue search)
CF set on error
AX = error code
7100h if function not supported
Format of Windows95 long filename FindData record:
Offset Size Description (Table 2695)
00h DWORD file attributes
bits 0-6 standard DOS attributes (see #0643 at INT 21/AX=4301h)
bit 8: temporary file
04h QWORD file creation time (number of 100ns intervals since 1/1/1601)
0Ch QWORD last access time
14h QWORD last modification time
1Ch DWORD file size (high 32 bits)
20h DWORD file size (low 32 bits)
24h 8 BYTEs reserved
2Ch 260 BYTEs ASCIZ full filename
130h 14 BYTEs ASCIZ short filename (for backward compatibility)
INT 21 - Windows95 - LONG FILENAME - FIND NEXT MATCHING FILE
AX = 714Fh
SI = 0000h
BX = filefind handle (from AX=714Eh)
ES:DI -> FindData record (see #2695)
Return: CF clear if successful
CF set on error
AX = error code
7100h if function not supported
CX = ??? (apparently must be 0002h)
DS:SI -> ASCIZ filename or path
ES:DI -> 128-byte buffer for canonicalized name
INT 21h
Return: CF set on error
AX = error code
02h invalid component in directory path or drive letter only
03h malformed path or invalid drive letter
ES:DI buffer unchanged
CF clear if successful
AH = 00h
AL = destroyed (00h or 5Ch or last char of current dir on drive)
DS:SI -> ASCIZ root name (e.g. "C:\")
ES:DI -> buffer for file system name
CX = size of ES:DI buffer
INT 21h
Return: CF clear if successful
BX = flags (see below)
CX = maximum length of file name [usually 255]
DX = maximum length of path [usually 260]
ES:DI buffer filled (ASCIZ, e.g. "FAT","NTFS","CDFS")
CF set on error
AX = error code
7100h if function not supported
for the file system name buffer, 32 bytes should be sufficient;
Bitfields for flags:
Bit(s) Description
0 searches are case sensitive
1 preserves case in directory entries
2 uses Unicode characters in file and directory names
3-13 reserved (0)
14 supports DOS long filename functions
15 volume is compressed
BX = filefind handle (from AX=714Eh)
INT 21h
Return: CF clear if successful
CF set on error
AX = error code
7100h if function not supported
this function must be called after starting a search with AX=714Eh, to indicate that the search handle returned by that function will no longer be used
AL = subfunction
00h get ???: CL =
00h: drive flag???
01h: ??? flag
01h set ???: CL =
00h: drive flag???
set to 06h if CH bit 1 =1, else to 00h
01h: ??? flag
set flag bit 3 to bit 3 of CH
DL = drive (0=current, 1=A:, etc.)
INT 21h
Return: CF clear if successful
for AL=00h:
AL = value of CL on entry
for CL=00h: AH = flag and 06h (i.e. bits 1 and 2 used)
for CL=01h: AH = flag and 08h (i.e. bit 3 used)
(flag being taken from a table of bytes)
CF set on error
AX = error code
7300h if function not supported
INT 21 - European MS-DOS 4.0 - "AEXEC" - EXECUTE PROGRAM IN BACKGROUND
AH = 80h
CX = mode
0000h place child in zombie mode on exit to preserve exit code
0001h discard child process and exit code on termination
DS:DX -> ASCIZ full program name
ES:BX -> parameter block (as for AX=4B00h)
Return: CF clear if successful
AX = Command Subgroup ID (CSID)
CF set on error
AX = error code (see #0885 at AH=59h)
European MS-DOS 4.0 was written for Siemens in Germany and then used by several other European OEMs; its release falls between mainstream versions 3.2 and 3.3 asynchronously execute a program, creating a new process for it
Notes: this function is called by the DETACH command
there is a system-wide limit of 32 processes
the CSID is used to identify all processes that have been spawned by
a given process, whether directly or indirectly
programs to be run in the background must use the new executable format
(see #0809 at AH=4Bh)
background processes may only perform asynchronous (background) EXECs,
either this function or AX=4B04h
background processes may execute INT 11, INT 12, INT 21, INT 2A, and
INT 2F at any time; they may execute INT 10 and INT 16 only while
they have opened a popup screen via INT 2F/AX=1401h; no other
interrupts may be executed from the background
background processes may not use drive B: or overlay their code
segments
see AX=8700h for an installation check
the "NE" new executable format made its first appearance in European
MS-DOS 4.0
INT 21 - European MS-DOS 4.0 - "FREEZE" - STOP A PROCESS
AH = 81h
BX = flag (00h freeze command subtree, 01h only specified process)
CX = Process ID of head of command subtree
Return: CF clear if successful
CF set on error
AX = error code (no such process)
Desc: temporarily suspend a process or a process and all of its children
Note: if BX=0001h, this call will not return until the process is actually
frozen, which may not be until after it unblocks from an I/O
operation
INT 21 - European MS-DOS 4.0 - "RESUME" - RESTART A PROCESS
AH = 82h
BX = flag (00h resume command subtree, 01h only specified process)
CX = Process ID of head of command subtree
Return: CF clear if successful
CF set on error
AX = error code (no such process)
restart a previously-suspended process or a process and all of its children
INT 21 - European MS-DOS 4.0 - "PARTITION" - GET/SET FOREGROUND PARTITION SIZE
AH = 83h
AL = function
00h get size
01h set new size
BX = new size in paragraphs
Return: CF clear if successful
BX = current size (function 00h) or old size (function 01h)
CF set on error
AX = error code (01h,07h,0Dh)(see #0885 at AH=59h)
Desc: specify or determine how much memory may be allocated by the foreground
process
Note: if the partition size is set to 0000h, no partition management is done
and all memory allocation is compatible with DOS 3.2.
the partition size can be changed regardless of what use is being made
of the changed memory; subsequent allocations will follow the
partition rules (foreground processes may allocate only foreground
memory; background processes allocate background memory first, then
foreground memory)
INT 21 - European MS-DOS 4.0 - "CREATMEM" - CREATE A SHARED MEMORY AREA
AX = 8400h
BX = size in bytes (0000h = 65536)
CX = flags
bit 6: zero-initialize segment
DS:DX -> ASCIZ name (must begin with "\SHAREMEM\")
Return: CF clear if successful
AX = segment address of shared memory global object
CF set on error
AX = error code (06h,08h) (see #0885 at AH=59h)
Desc: create an area of memory which may be accessed by multiple processes
Notes: shared memory objects are created as special files (thus the restriction on the name) on successful creation, the reference count is set to 1
INT 21 - European MS-DOS 4.0 - "GETMEM" - OBTAIN ACCESS TO SHARED MEMORY AREA
AX = 8401h
CX = flags
bit 7: writable segment (ignored by MS-DOS 4.0)
DS:DX -> ASCIZ name (must begin with "\SHAREMEM\")
Return: CF clear if successful
AX = segment address of shared memory global object
CX = size in bytes
CF set on error
AX = error code (invalid name)
get address of a previously-created area of memory which may be accessed by multiple processes
Note: this call increments the reference count for the shared memory area
INT 21 - European MS-DOS 4.0 - "RELEASEMEM" - FREE SHARED MEMORY AREA
AX = 8402h
BX = handle (segment address of shared memory object)
Return: CF clear if successful
CF set on error
AX = error code (no such name)
Desc: indicate that the specified area of shared memory will no longer be
used by the caller
Note: the reference count is decremented and the shared memory area is
deallocated if the new reference count is zero
SeeAlso: AX=8400h,AX=8401h,INT 15/AX=DE19h
INT 21 - European MS-DOS 4.0 - "SETFILETABLE" - INSTALL NEW FILE HANDLE TABLE
AH = 86h
BX = total number of file handles in new table
Return: CF clear if successful
CF set on error
AX = error code (06h,08h) (see #0885 at AH=59h)
Desc: adjust the size of the per-process open file table, thus raising or
lowering the limit on the number of files the caller can open
simultaneously
Notes: any currently-open files are copied to the new table
if the table is increased beyond the default 20 handles, only the
first 20 will be inherited by child processes
error 06h is returned if the requested number of handles exceeds
system limits or would require closing currently-open files
INT 21 - European MS-DOS 4.0 - "GETPID" - GET PROCESS IDENTIFIER
AH = 87h
Return: AX = PID
BX = parent process's PID
CX = Command Subgroup ID (CSID)
Program: European MS-DOS 4.0 was written for Siemens in Germany and then used
by several other European OEMs; its release falls between mainstream
versions 3.2 and 3.3
Desc: determine an identifier by which to access the calling process
Notes: called by MS C v5.1 getpid() function
this function apparently must return AX=0001h for INT 21/AH=80h to
succeed
one possible check for European MS-DOS 4.0 is to issue this call with
AL=00h and check whether AL is nonzero on return
INT 21 - European MS-DOS 4.0 - SLEEP
AH = 89h
CX = time in milliseconds or 0000h to give up time slice
Return: CF clear if successful
CX = 0000h
CF set on error
AX = error code (interrupted system call)
CX = sleep time remaining
Desc: suspend the calling process for the specified duration
Notes: the sleep interval is rounded up to the next higher increment of the
scheduler clock, and may be extended further if other processes are
running
this call may be interrupted by signals (see AH=8Dh)
reportedly called by Microsoft C 4.0 startup code
background processes have higher priority than the foreground process,
and should thus periodically yield the CPU
INT 21 - European MS-DOS 4.0 - "CWAIT" - WAIT FOR CHILD TO TERMINATE
AH = 8Ah
BL = range (00h command subtree, 01h any child)
BH = suspend flag
00h suspend if children exist but none are dead
01h return if no dead children
CX = Process ID of head of command subtree
Return: CF clear if successful
AH = termination type (see #0970)
AL = return code from child or aborting signal
BX = PID of child (0000h if no dead children)
CF set on error
AX = error code (no child,interrupted system call)
Desc: get return code from an asynchronously-executed child program,
optionally waiting if no return code is available
(Table 0970)
Values for termination type:
00h normal termination
01h aborted by Control-C
02h aborted by I/O error
03h terminate and stay resident
04h aborted by signal
05h aborted by program error
INT 21 - European MS-DOS 4.0 - SET SIGNAL HANDLER
AH = 8Ch
AL = signal number (see #0971)
BL = action (see #0972)
DS:DX -> signal handler (see #0973)
Return: CF clear if successful
AL = previous action
ES:BX -> previous signal handler
CF set on error
AX = error code (01h,invalid SigNumber or Action)
(see #0885 at AH=59h)
Desc: set the routine which will be invoked on a number of exceptional
conditions
Note: all signals will be sent to the most recently installed handler
(Table 0971)
Values for European MS-DOS 4.0 signal number:
01h SIGINTR Control-C or user defined interrupt key
08h SIGTERM program termination
09h SIGPIPE broken pipe
0Dh SIGUSER1 reserved for user definition
0Eh SIGUSER2 reserved for user definition
(Table 0972)
Values for signal action:
00h SIG_DFL terminate process on receipt
01h SIG_IGN ignore signal
02h SIG_GET signal is accepted
03h SIG_ERR sender gets error
04h SIG_ACK acknowledge received signal and clear it, but don't
change current setting
(Table 0973)
Values signal handler is called with:
AL = signal number (see #0971)
AH = signal argument
Return: RETF, CF set: terminate process
RETF, CF clear, ZF set: abort any interrupted system call with an error
RETF, CF clear, ZF clear: restart any interrupted system call
IRET: restart any interrupted system call
Note: the signal handler may also perform a nonlocal GOTO by resetting the
stack pointer and jumping; before doing so, it should dismiss the
signal by calling this function with BL=04h
INT 21 - European MS-DOS 4.0 - SEND SIGNAL
AH = 8Dh
AL = signal number (see #0971)
BH = signal argument
BL = action
00h send to entire command subtree
01h send only to specified process
DX = Process ID
Return: CF clear if successful
CF set on error
AX = error code (01h,06h)(see #0885 at AH=59h)
Desc: invoke the exceptional-condition handler for the specified process
Note: error 06h may be returned if one or more of the affected processes
have an error handler for the signal
INT 21 - European MS-DOS 4.0 - "SETPRI" - GET/SET PROCESS PRIORITY
AX = 8E00h
BH = 00h
BL = action
00h set priority for command subtree
01h set priority for specified process only
CX = Process ID
DH = 00h
DL = change in priority (00h to get priority)
Return: CF clear if successful
DL = process priority
DH destroyed
CF set on error
AX = error code (01h,no such process)(see #0885 at AH=59h)
Desc: specify or determine the execution priority of the specified process
or the process and all of its children
INT 21 - European MS-DOS 4.0 - "PIPE" - CREATE A NEW PIPE
AH = 93h
CX = size in bytes
Return: CF clear if successful
AX = read handle
BX = write handle
CF set on error
AX = error code (08h) (see #0885 at AH=59h)
create a communications channel which may be used for interprocess data and command exchanges
INT 21 - European MS-DOS 4.0 - HARD ERROR PROCESSING
AH = 95h
AL = new state
00h enabled
01h disabled, automatically fail hard errors
Return: AX = previous setting
specify whether hard (critical) errors should automatically fail the system call or invoke an INT 24
DS:BX -> memory location to block on
CX = timeout in milliseconds
DH = nonzero if interruptable
INT 21h
Return: CF clear if awakened by event
AX = 0000h
CF set if unusual wakeup
ZF set if timeout, clear if interrupted by signal
AX = nonzero
suspend calling process until another process sends a "restart" signal or a timeout occurs
DS:BX -> memory location processes may have blocked on
INT 21h
Return: AX = number of processes awakened
ZF set if no processes awakened
European MS-DOS 4.0 was written for Siemens in Germany and then used by
several other European OEMs; its release falls between mainstream versions 3.2
and 3.3 restart all processes waiting for the specified "restart"
signal
INT 21 - DOS 1+ - READ CHARACTER FROM STANDARD INPUT, WITH ECHO
AH = 01h
Return: AL = character read
Notes: ^C/^Break are checked, and INT 23 executed if read
character is echoed to standard output
standard input is always the keyboard and standard output the screen
under DOS 1.x, but they may be redirected under DOS 2+
INT 21 - DOS 1+ - WRITE CHARACTER TO STANDARD OUTPUT
AH = 02h
DL = character to write
Return: AL = last character output (despite the official docs which state
nothing is returned) (at least DOS 3.3-5.0)
Notes: ^C/^Break are checked, and INT 23 executed if pressed
standard output is always the screen under DOS 1.x, but may be
redirected under DOS 2+
the last character output will be the character in DL unless DL=09h
on entry, in which case AL=20h as tabs are expanded to blanks
INT 21 - DOS 1+ - READ CHARACTER FROM STDAUX
AH = 03h
Return: AL = character read
Notes: keyboard checked for ^C/^Break, and INT 23 executed if detected
STDAUX is usually the first serial port
INT 21 - DOS 1+ - WRITE CHARACTER TO STDAUX
AH = 04h
DL = character to write
Notes: keyboard checked for ^C/^Break, and INT 23 executed if detected
STDAUX is usually the first serial port
if STDAUX is busy, this function will wait until it becomes free
DL = character to print
INT 21h
Notes: keyboard checked for ^C/^Break, and INT 23 executed if detected
STDPRN is usually the first parallel port, but may be redirected under DOS 2+ if the printer is busy, this function will wait
DL = character (except FFh)
INT 21h
Return:
AL = character output
Writes to standard output, which is usally the screen.
DL = FFh
INT 21h
Return: ZF set if no character available
AL = 00h
ZF clear if character available
AL = character read
Notes: ^C/^Break are NOT checked if the returned character is 00h, the user pressed a key with an
extended keycode, which will be returned by the next call of this
function
this function reads from standard input, which is always the keyboard
under DOS 1.x, but may be redirected under DOS 2+
although the return of AL=00h when no characters are available is not
documented, some programs rely on this behavior
INT 21h
Return:
AL = character read from standard input
Notes: does not check ^C/^Break
standard input is always the keyboard under DOS 1.x, but may be
redirected under DOS 2+
if the interim console flag is set (see AX=6301h), partially-formed
double-byte characters may be returned
INT 21h
Return: AL = character read from standard input
Notes: ^C/^Break are checked, and INT 23 executed if detected
standard input is always the keyboard under DOS 1.x, but may be
redirected under DOS 2+
if the interim console flag is set (see AX=6301h), partially-formed
double-byte characters may be returned
DS:DX -> '$'-terminated string
INT 21h
Return:
AL = 24h
DS:DX -> buffer (see #0573)
INT 21h
Return:
buffer filled with user input
Notes: ^C/^Break are checked, and INT 23 is called if either detected
reads from standard input, which may be redirected under DOS 2+
if the maximum buffer size (see #0573) is set to 00h, this call returns immediately without reading any input
Format of DOS input buffer:
Offset Size Description (Table 0573)
00h BYTE maximum characters buffer can hold
01h BYTE (call) number of chars from last input which may be recalled
(ret) number of characters actually read, excluding CR
02h N BYTEs actual characters read, including the final carriage return
INT 21h
Return:
AL = status
00h if no character available
FFh if character is available
Notes: ^C/^Break are checked, and INT 23 is called if either pressed
standard input is always the keyboard under DOS 1.x, but may be
redirected under DOS 2+
if the interim console flag is set (see AX=6301h), this function
returns AL=FFh if a partially-formed double-byte character is
available
AL = STDIN input function to execute after flushing buffer
other registers as appropriate for the input function
INT 21h
Return:
as appropriate for the specified input function
if AL is not one of 01h,06h,07h,08h, or 0Ah, the buffer is flushed but no input is attempted
INT 21h
Return:
This function writes all modified disk buffers to disk, but does not
update the directory information (that is only done when files are
closed or a SYNC call is issued)
DL = new default drive (00h = A:, 01h = B:, etc)
INT 21h
Return:
AL = number of potentially valid drive letters
INT 21h
Return: AL = drive (00h = A:, 01h = B:, etc)
DS:DX -> Disk Transfer Area (DTA)
INT 21h
The DTA is set to PSP:0080h when a program is started. Note that the DTA is DOS hack. The 128 byte area is emulated for DOS purposes.
INT 21h
Return:
AL = sectors per cluster (allocation unit)
CX = bytes per sector
DX = total number of clusters
DS:BX -> media ID byte (see #0581)
under DOS 1.x, DS:BX points at an actual copy of the FAT; later versions return a pointer to a copy of the FAT's ID byte
(Table 0581)
Values for media ID byte:
FFh floppy, double-sided, 8 sectors per track (320K)
FEh floppy, single-sided, 8 sectors per track (160K)
FDh floppy, double-sided, 9 sectors per track (360K)
FCh floppy, single-sided, 9 sectors per track (180K)
FAh HP 200LX D: ROM disk, 16 sectors per track (995K)
HP 200LX E: (Stacker host drive ???)
F9h floppy, double-sided, 15 sectors per track (1.2M)
floppy, double-sided, 9 sectors per track (720K,3.5")
F8h hard disk
F0h other media
(e.g. floppy, double-sized, 18 sectors per track -- 1.44M,3.5")
DL = drive (00h = default, 01h = A:, etc)
INT 21h
Return:
AL = sectors per cluster (allocation unit), or FFh if invalid drive
CX = bytes per sector
DX = total number of clusters
DS:BX -> media ID byte (see #0581)
INT 21h
Return: AL = status
00h successful
DS:BX -> Drive Parameter Block (DPB) AH=32h for DOS 2+)
FFh invalid drive
this call was undocumented prior to the release of DOS 5.0; however,
only the DOS 4.0+ version of the DPB has been documented
AH = 2Eh
DL = 00h (DOS 1.x/2.x only)
AL = new state of verify flag
00h off
01h on
INT 21h
When enabled, read-after-write verification is used.
INT 21h
Return: ES:BX -> current DTA
AL = what to return in BH
00h OEM number
01h version flag
INT 21h
Return:
AL = major version number
AH = minor version number
BL:CX = 24-bit user serial number (most versions do not use this)
if AL=00h
BH = MS-DOS OEM number
if AL=01h
BH = version flag
bit 3: DOS is in ROM
The version is returned as 7.0. Use INT FFh SET VERSION if needed. For the OEM number, Grail Millenium returns 6Dh, which is the ASCII char for 'm', which is the number 1000.
Values for DOS OEM number:
00h IBM
01h Compaq
02h MS Packaged Product
04h AT&T
05h ZDS (Zenith Electronics)
06h Hewlett-Packard
07h ZDS (Groupe Bull)
0Dh Packard-Bell
16h DEC
23h Olivetti
28h Texas Instruments
29h Toshiba
33h Novell (Windows/386 device IDs only)
34h MS Multimedia Systems (Windows/386 device IDs only)
35h MS Multimedia Systems (Windows/386 device IDs only)
4Dh Hewlett-Packard
5Eh RxDOS
66h PhysTechSoft (PTS-DOS)
6Dh Grail Millenium
99h General Software's Embedded DOS
EEh DR-DOS
EFh Novell DOS
FFh Microsoft, Phoenix
INT 21 - DOS 2+ - TERMINATE AND STAY RESIDENT
AH = 31h
AL = return code
DX = number of paragraphs to keep resident
Return: never
Notes: the value in DX only affects the memory block containing the PSP;
additional memory allocated via AH=48h is not affected
the minimum number of paragraphs which will remain resident is 11h
for DOS 2.x and 06h for DOS 3.0+
most TSRs can save some memory by releasing their environment block
before terminating (see #0603 at AH=26h,AH=49h)
DL = drive number (00h = default, 01h = A:, etc)
INT 21h
Return:
AL = status
00h successful
DS:BX -> Drive Parameter Block (DPB) for specified drive
FFh invalid or network drive
The values here are synthesised for consumption by DOS.
Format of DOS Drive Parameter Block:
Offset Size Description (Table 0620)
00h BYTE drive number (00h = A:, 01h = B:, etc)
01h BYTE unit number within device driver
02h WORD bytes per sector (usually 512)
04h BYTE highest sector number within a cluster
05h BYTE shift count to convert clusters into sectors
06h WORD number of reserved sectors at beginning of drive
08h BYTE number of FATs (1)
09h WORD number of root directory entries
0Bh WORD number of first sector containing user data
0Dh WORD highest cluster number (number of data clusters + 1)
16-bit FAT if greater than 0FF6h, else 12-bit FAT
0Fh WORD number of sectors per FAT
11h WORD sector number of first directory sector
13h DWORD NULL
17h BYTE media ID byte (see #0581)
18h BYTE 00h if disk accessed, FFh if not
19h DWORD pointer to next DPB
1Dh WORD cluster at which to start search for free space when writing,
usually the last cluster allocated
1Fh WORD number of free clusters on drive, FFFFh = unknown
AL = subfunction
00h get current extended break state
INT 21h
Return: DL = current state, 00h = off, 01h = on
01h set state of extended ^C/^Break checking
DL = new state
00h off, check only on character I/O functions
01h on, check on all DOS functions
INT 21h
Return:
DL = boot drive (1=A:,...)
AX = 3306h
INT 21h
Return:
BL = major version
BH = minor version
DL = revision (bits 2-0, all others 0)
DH = version flags
bit 3: DOS is in ROM
bit 4: DOS is in HMA
AL = FFh if true DOS version < 5.0
This will return a version number of 7.0 under Legacy, since that is the general compatibility level that is targeted. Registers DL, DH, and AL will be set to 0.
AH = 34h
INT 21h
Return:
ES:BX -> one-byte InDOS flag
All LEGACY DOS functions are emulated, as well any necessary structures. Excepting for the bridges, all code is 32-bit and reinterrant. The INDOS flag will always be 0 under LEGACY.
AH = 35h
AL = interrupt number
INT 21h
Return:
ES:BX -> current interrupt handler
DL = drive number (00h = default, 01h = A:, etc)
INT 21h
Return: AX = FFFFh if invalid drive
else
AX = sectors per cluster
BX = number of free clusters
CX = bytes per sector
DX = total clusters on drive
free space on drive in bytes is AX * BX * CX
total space on drive in bytes is AX * CX * DX
"lost clusters" are considered to be in use
AH = 39h
DS:DX -> ASCIZ pathname
INT 21h
Return:
CF clear if successful
AX destroyed
CF set on error
AX = error code (03h,05h) (see #0885 at AH=59h)
This creates all the specified directories in order.
DS:DX -> ASCIZ pathname of directory to be removed
INT 21h
Return:
CF clear if successful
AX destroyed
CF set on error
AX = error code (03h,05h,06h,10h) (see #0885 at AH=59h)
The directory must be empty except for '.' and '..'.
DS:DX -> ASCIZ pathname to become current directory (max 64 bytes)
INT 21h
Return: CF clear if successful
AX destroyed
CF set on error
AX = error code (03h) (see #0885 at AH=59h)
Notes: if new directory name includes a drive letter, the default drive is
not changed, only the current directory on that drive
changing the current directory also changes the directory in which
FCB file calls operate
under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
CX = file attributes
DS:DX -> ASCIZ filename
INT 21h
Return:
CF clear if successful
AX = file handle
CF set on error
AX = error code (03h,04h,05h) (see #0885 at AH=59h)
if a file with the given name exists, it is truncated to zero length
Bitfields for file attributes:
Bit(s) Description (Table 0626)
0 read-only
1 hidden
2 system
3 volume label (ignored)
4 reserved, must be zero (directory)
5 archive bit
7 if set, file is shareable under Novell NetWare
AL = access and sharing modes (see #0627)
DS:DX -> ASCIZ filename
CL = attribute mask of files to look for (server call only)
INT 21h
Return:
CF clear if successful
AX = file handle
CF set on error
AX = error code (01h,02h,03h,04h,05h,0Ch,56h) (see #0885 at AH=59h)
file pointer is set to start of file file handles which are inherited from a parent also inherit sharing and access restrictions
files may be opened even if given the hidden or system attributes
under the FlashTek X-32 DOS extender, the pointer is in DS:EDX
DR-DOS checks the system password or explicitly supplied password at
the end of the filename against the reserved field in the directory
entry before allowing access
sharing modes are only effective on local drives if SHARE is loaded
Bitfields for access and sharing modes:
Bit(s) Description (Table 0627)
2-0 access mode
000 read only
001 write only
010 read/write
011 (DOS 5+ internal) passed to redirector on EXEC to allow
case-sensitive filenames
3 reserved (0)
6-4 sharing mode (DOS 3.0+) (see #0628)
000 compatibility mode
001 "DENYALL" prohiboth read and write access by others
010 "DENYWRITE" prohiwrite access by others
011 "DENYREAD" prohiread access by others
100 "DENYNONE" allow full access by others
111 network FCB (only available during server call)
7 inheritance
if set, file is private to current process and will not be inherited
by child processes
(Table 0628)
Values of DOS file sharing behavior:
| Second and subsequent Opens
First |Compat Deny Deny Deny Deny
Open | All Write Read None
|R W RW R W RW R W RW R W RW R W RW
- - - - -| - - - - - - - - - - - - - - - - -
Compat R |Y Y Y N N N 1 N N N N N 1 N N
W |Y Y Y N N N N N N N N N N N N
RW|Y Y Y N N N N N N N N N N N N
- - - - -|
Deny R |C C C N N N N N N N N N N N N
All W |C C C N N N N N N N N N N N N
RW|C C C N N N N N N N N N N N N
- - - - -|
Deny R |2 C C N N N Y N N N N N Y N N
Write W |C C C N N N N N N Y N N Y N N
RW|C C C N N N N N N N N N Y N N
- - - - -|
Deny R |C C C N N N N Y N N N N N Y N
Read W |C C C N N N N N N N Y N N Y N
RW|C C C N N N N N N N N N N Y N
- - - - -|
Deny R |2 C C N N N Y Y Y N N N Y Y Y
None W |C C C N N N N N N Y Y Y Y Y Y
RW|C C C N N N N N N N N N Y Y Y
Legend: Y = open succeeds, N = open fails with error code 05h
C = open fails, INT 24 generated
1 = open succeeds if file read-only, else fails with error code
2 = open succeeds if file read-only, else fails with INT 24
BX = file handle
INT 21h
Return:
CF clear if successful
AX destroyed
CF set on error
AX = error code (06h) (see #0885 at AH=59h)
if the file was written to, any pending disk writes are performed, the time and date stamps are set to the current time, and the directory entry is updated
BX = file handle
CX = number of bytes to read
DS:DX -> buffer for data
INT 21h
Return:
CF clear if successful
AX = number of bytes actually read (0 if at EOF before call)
CF set on error
AX = error code (05h,06h) (see #0885 at AH=59h)
data is read beginning at current file position, and the file position is updated after a successful read the returned AX may be smaller than the request in CX if a partial read occurred
if reading from CON, read stops at first CR
BX = file handle
CX = number of bytes to write
DS:DX -> data to write
INT 21h
Return: CF clear if successful
AX = number of bytes actually written
CF set on error
AX = error code (05h,06h) (see #0885 at AH=59h)
Notes: if CX is zero, no data is written, and the file is truncated or
extended to the current position
data is written beginning at the current file position, and the file
position is updated after a successful write
the usual cause for AX < CX on return is a full disk
DS:DX -> ASCIZ filename (no wildcards, but see notes)
CL = attribute mask for deletion (server call only, see notes)
INT 21h
Return:
cfclear if successful
AX destroyed (DOS 3.3) AL seems to be drive of deleted file
CF set on error
AX = error code (02h,03h,05h) (see #0885 at AH=59h)
wildcards are allowed if invoked via AX=5D00h, in which case
the filespec must be canonical (as returned by AH=60h), and only
files matching the attribute mask in CL are deleted
DOS does not erase the file's data; it merely becomes inaccessible because the FAT chain for the file is cleared deleting a file which is crrently open may lead to filesystem corruption. Unless SHARE is loaded, DOS does not close the handles referencing the deleted file, thus allowing writes to a nonexistant file.
AL = origin of move
00h start of file
01h current file position
02h end of file
BX = file handle
CX:DX = offset from origin of new file position
INT 21h
Return: CF clear if successful
DX:AX = new file position in bytes from start of file
CF set on error
AX = error code (01h,06h) (see #0885 at AH=59h)
Notes: for origins 01h and 02h, the pointer may be positioned before the
start of the file; no error is returned in that case, but subsequent
attempts at I/O will produce errors
if the new position is beyond the current end of file, the file will
be extended by the next write (see AH=40h)
AX = 4300h
DS:DX -> ASCIZ filename
INT 21h
Return:
CF clear if successful
CX = file attributes (see #0643)
CF set on error
AX = error code (01h,02h,03h,05h)
AX = 4301h
CX = new file attributes (see #0643)
DS:DX -> ASCIZ filename
INT 21h
Return:
CF clear if successful
AX destroyed
CF set on error
AX = error code (01h,02h,03h,05h) (see #0885 at AH=59h)
SHARE will close the file if it is currently open in sharing-
compatibility mode, otherwise a sharing violation critical error is
generated if the file is currently open
Bitfields for file attributes:
Bit(s) Description (Table 0643)
7 shareable (Novell NetWare)
6 unused
5 archive
4 directory
3 volume label
2 system
1 hidden
0 read-only
INT 21h
DS:DX -> opened FCB (see #0574)
INT 21h
This function does not work and always returns AL=0FFh.
DS:DX -> opened FCB (see #0574)
[DTA] = record to write
INT 21h
This function does not work and always returns AL=0FFh.
DS:DX -> unopened FCB (see #0574), wildcards not allowed
This function does not work and always returns AL=0FFh.
DS:DX -> opened FCB (see #0574)
INT 21h
This function does not work and always returns AL=0FFh.
CX = number of records to read
DS:DX -> opened FCB (see #0574)
INT 21h
This function does not work and always returns AL=0FFh.
CX = number of records to write
DS:DX -> opened FCB (see #0574)
[DTA] = records to write
INT 21h
This function does not work and always returns AL=0FFh.
AL = parsing options (see #0605)
DS:SI -> filename string (both '*' and '?' wildcards OK)
ES:DI -> buffer for unopened FCB
INT 21h
This function does not work and always returns AL=0FFh.
DS:DX -> unopened File Control Block (see #0574)
INT 21h
This function does not work and always returns AL=0FFh.
AH = 10h
DS:DX -> File Control Block
INT 21h
This function does not work and always returns AL=FFh.
DS:DX -> unopened FCB (see #0574), may contain '?' wildcards
INT 21h
Return: AL = status
00h successful
[DTA] unopened FCB for first matching file
FFh no matching filename, or bad FCB
the type of the returned FCB depends on whether the input FCB was a
normal or an extended FCB
the data returned in the DTA is actually the drive number (or extended
FCB header and drive number) followed by the file's directory entry
(see #0580); this format happens to be compatible with an unopened
FCB
for extended FCBs with search attribute 08h, the volume label (if any)
will be returned even if the current directory is not the root dir.
DOS 3.0+ also allows the '*' wildcard
the search FCB must not be modified if AH=12h will be used to continue
searching; DOS 3.3 has set the following parts of the FCB:
0Ch BYTE ???
0Dh WORD directory entry number of matching file
0Fh WORD cluster number of current directory
11h 4 BYTEs ???
15h BYTE drive number (1=A:)
this function is used by many copy protection schemes to obtain the
starting cluster of a file
Format of DOS directory entry:
Offset Size Description (Table 0580)
00h 8 BYTEs blank-padded filename
08h 3 BYTEs blank-padded file extension
0Bh BYTE attributes
0Ch 10 BYTEs reserved
used by DR-DOS to store file password
16h WORD time of creation or last update (see #0876 at AX=5700h)
18h WORD date of creation or last update (see #0877 at AX=5700h)
1Ah WORD starting cluster number
1Ch DWORD file size
DS:DX -> unopened FCB (see #0574)
INT 21h
Return: AL = status
00h successful
[DTA] = unopened FCB
FFh no more matching filenames
Note: (see AH=11h)
assumes that successful FindFirst executed on search FCB before call
DS:DX -> unopened FCB
INT 21h
This function does not work and always returns AL=0FFh.
DS:DX -> opened FCB
INT 21h
This function does not work and always returns AL=0FFh.
DS:DX -> opened FCB (see #0574)
[DTA] = record to write
INT 21h
This function does not work and always returns AL=0FFh.
DS:DX -> unopened FCB (see #0574), wildcards not allowed
INT 21h
This function does not work and always returns AL=0FFh.
DS:DX -> modified FCB (see also #0574)
the old filename ('?' wildcards OK) is in the standard location
while the new filename ('?' wildcards OK, no drive) is stored
in the 11 bytes beginning at offset 11h
INT 21h
Return:
AL = status
00h successfully renamed
FFh no matching files,file is read-only, or new name already exists
Under Legacy the only approved purpose of this function is to rename volume Labels.
INT 1F - SYSTEM DATA - 8x8 GRAPHICS FONT
this vector points at 1024 bytes of graphics data, 8 bytes for each character 80h-FFh
AL = info ID
01h get general internationalization info
02h get pointer to uppercase table
04h get pointer to filename uppercase table
05h get pointer to filename terminator table
06h get pointer to collating sequence table
07h (DOS 4.0+) get pointer to Double-Byte Character Set table
BX = code page (FFFFh=global code page)
DX = country ID (FFFFh=current country)
ES:DI -> country information buffer (see #0956)
CX = size of buffer (>= 5)
INT 21h
Return:
CF set on error
AX = error code (see #0885 at AH=59h)
CF clear if successful
CX = size of country information returned
ES:DI -> country information
AL=05h appears to return same info for all countries and codepages; it has been documented for DOS 5+, but was undocumented in ealier versions NLSFUNC must be installed to get info for countries other than the default subfunctions 02h and 04h are identical under OS/2
Format of country information:
Offset Size Description (Table 0956)
00h BYTE info ID
---if info ID = 01h---
01h WORD size
03h WORD country ID
05h WORD code page
07h 34 BYTEs country-dependent info (see AH=38h)
---if info ID = 02h---
01h DWORD pointer to uppercase table (see #0957)
---if info ID = 04h---
01h DWORD pointer to filename uppercase table (see #0958)
---if info ID = 05h---
01h DWORD pointer to filename character table (see #0959)
---if info ID = 06h---
01h DWORD pointer to collating table (see #0960)
---if info ID = 07h (DOS 4.0+)---
01h DWORD pointer to DBCS lead byte table (see #0961)
Format of uppercase table:
Offset Size Description (Table 0957)
00h WORD table size
02h 128 BYTEs uppercase equivalents (if any) of chars 80h to FFh
Format of filename uppercase table:
Offset Size Description (Table 0958)
00h WORD table size
02h 128 BYTEs uppercase equivalents (if any) of chars 80h to FFh
Format of filename terminator table:
Offset Size Description (Table 0959)
00h WORD table size (not counting this word)
02h BYTE ??? (01h for MS-DOS 3.30-6.00)
03h BYTE lowest permissible character value for filename
04h BYTE highest permissible character value for filename
05h BYTE ??? (00h for MS-DOS 3.30-6.00)
06h BYTE first excluded character in range \ all characters in this
07h BYTE last excluded character in range / range are illegal
08h BYTE ??? (02h for MS-DOS 3.30-6.00)
09h BYTE number of illegal (terminator) characters
0Ah N BYTEs characters which terminate a filename: ."/\[]:|<>+=;,
Note: partially documented for DOS 5+, but undocumented for earlier versions
Format of collating table:
Offset Size Description (Table 0960)
00h WORD table size
02h 256 BYTEs values used to sort characters 00h to FFh
Format of DBCS lead byte table:
Offset Size Description (Table 0961)
00h WORD length
02h 2N BYTEs start/end for N lead byte ranges
WORD 0000h (end of table)
COUNTRY-DEPENDENT CHARACTER CAPITALIZATION
AH = 65h
AL = function
20h capitalize character
DL = character to capitalize
Return: DL = capitalized character
21h capitalize string
DS:DX -> string to capitalize
CX = length of string
22h capitalize ASCIZ string
DS:DX -> ASCIZ string to capitalize
INT 21h
Return:
CF set on error
AX = error code (see #0885 at AH=59h)
CF clear if successful
GET GLOBAL CODE PAGE TABLE
AX = 6601h
INT 21h
Return:
CF set on error
AX = error code (see #0885 at AH=59h)
CF clear if successful
BX = active code page (see #0962)
DX = system code page (see #0962)
SET GLOBAL CODE PAGE TABLE
AX = 6602h
BX = active code page (see #0962)
DX = system code page (active page at boot time)
INT 21h
Return: CF set on error
AX = error code (see #0885 at AH=59h)
CF clear if successful
AX = EB41h (Novell NWDOS v7.0 when NLSFUNC not installed and
request was for previously-active code page)
(Table 0962)
Values for code page:
437 US
850 Multilingual
852 Slavic/Latin II (DOS 5+)
857 Turkish
860 Portugal
861 Iceland
863 Canada (French)
865 Norway/Denmark
CREATE NEW PROGRAM SEGMENT PREFIX
To Call:
AH = 26h
DX = segment at which to create PSP
INT 21h
new PSP is updated with memory size information; INTs 22h, 23h, 24h taken from interrupt vector table; the parent PSP field is set to 0 DOS assumes that the caller's CS is the segment of the PSP to copy
Format of Program Segment Prefix (PSP):
Offset Size Description (Table 0498)
00h 2 BYTEs INT 20 instruction for CP/M CALL 0 program termination
the CDh 20h here is often used as a signature for a valid PSP
...
2Ch WORD DOS 2+ segment of environment for process (see #0499)
...
Format of environment block:
Offset Size Description (Table 0499)
00h N BYTEs first environment variable, ASCIZ string of form "var=value"
N BYTEs second environment variable, ASCIZ string
...
N BYTEs last environment variable, ASCIZ string of form "var=value"
BYTE 00h
---DOS 3+---
WORD number of strings following environment (normally 1)
N BYTEs ASCIZ full pathname of program owning this environment other strings may follow
GET COUNTRY-SPECIFIC INFORMATION
AH = 38h
AL = 00h get current-country info
DS:DX -> buffer for returned info (see #0517,#0518)
INT 21h
Format of DOS 2.11+ country info:
Offset Size Description (Table 0518)
00h WORD date format (see #0517)
02h 5 BYTEs ASCIZ currency symbol string
07h 2 BYTEs ASCIZ thousands separator
...
(Table 0519)
Values for country code:
001h United States
002h Canadian-French
003h Latin America
01Fh Netherlands
SET COUNTRY CODE
AH = 38h
DX = FFFFh
AL = 01h thru FEh for specific country with code <255
AL = FFh for specific country with code >= 255
BX = 16-bit country code (see #0519)
INT 21h
Return: CF set on error
AX = error code (see #0770 at AH=59h)
CF clear if successful
"EXEC" - LOAD AND/OR EXECUTE PROGRAM
To Call:
AH = 4Bh
ES:BX -> parameter block (see #0687)
INT 21h
Format of EXEC parameter block for AL=00h,01h,04h:
Offset Size Description
00h WORD segment of environment to copy for child process (copy caller's environment if 0000h)
Format of EXEC parameter block for AL=03h:
Offset Size Description
00h WORD segment at which to load overlay
02h WORD relocation factor to apply to overlay if in .EXE format
Format of EXEC parameter block for FlashTek X-32:
Offset Size Description (Table 0689)
00h PWORD 48-bit far pointer to environment string
06h PWORD 48-bit far pointer to command tail string
(Table 0690)
Values for the executable types understood by various environments:
MZ old-style DOS executable
...
Format of .EXE file header:
Offset Size Description (Table 0691)
00h 2 BYTEs .EXE signature, either "MZ" or "ZM" (5A4Dh or 4D5Ah)
02h WORD number of bytes in last 512-byte page of executable
...
Format of ROM Module Header:
Offset Size Description (Table 0692)
00h 2 BYTEs ROM signature 55h, AAh
02h BYTE size of ROM in 512-byte blocks
...
Format of new executable header:
Offset Size Description (Table 0693)
00h 2 BYTEs "NE" (4Eh 45h) signature
02h 2 BYTEs linker version (major, then minor)
...
0Ch BYTE program flags (see #0694)
0Dh BYTE application flags (see #0695)
...
Bitfields for new executable program flags:
Bit(s) Description (Table 0694)
0-1 DGROUP type
0 = none
1 = single shared
2 = multiple (unshared)
3 = (null)
...
Bitfields for new executable application flags:
Bit(s) Description (Table 0695)
0-2 application type
001 full screen (not aware of Windows/P.M. API)
010 compatible with Windows/P.M. API
011 uses Windows/P.M. API
...
Bitfields for other new .EXE flags:
Bit(s) Description (Table 0696)
0 supports long filenames
1 2.X protected mode
2 2.X proportional font
3 gangload area
Format of Codeview trailer (at end of executable):
Offset Size Description (Table 0697)
00h WORD signature 4E42h ('NB')
02h WORD Microsoft debug info version number
04h DWORD Codeview header offset
Format of new executable segment table record:
Offset Size Description (Table 0698)
00h WORD offset in file (shift left by alignment shift to get byte offs)
02h WORD length of image in file (0000h = 64K)
04h WORD segment attributes (see #0699)
06h WORD number of bytes to allocate for segment (0000h = 64K)
Note: the first segment table entry is entry number 1
Bitfields for segment attributes:
Bit(s) Description (Table 0699)
0 data segment rather than code segment
...
Format of new executable entry table item (list):
Offset Size Description (Table 0700)
00h BYTE number of entry points (00h if end of entry table list)
...
Format of new executable relocation data (immediately follows segment image):
Offset Size Description (Table 0701)
00h WORD number of relocation items
...
Format of new executable resource data:
Offset Size Description (Table 0702)
00h WORD alignment shift count for resource data
...
08h N Resources (see #0703)
Note: resource type and name strings are stored immediately following the
resource table, and are not null-terminated
Format of new executable resource entry:
Offset Size Description (Table 0703)
00h WORD offset in alignment units from start of file to contents of
the resource data
...
Format of new executable module reference table [one bundle of entries]:
Offset Size Description (Table 0704)
00h BYTE number of records in this bundle (00h if end of table)
...
Format of new executable resident/nonresident name table entry:
Offset Size Description (Table 0705)
00h BYTE length of string (00h if end of table)
...
Format of Linear Executable (enhanced mode executable) header:
Offset Size Description (Table 0706)
00h 2 BYTEs "LE" (4Ch 45h) signature (Windows)
"LX" (4Ch 58h) signature (OS/2)
...
10h DWORD module type (see #0707)
...
40h DWORD offset of object table (see #0708)
...
Bitfields for Linear Executable module type:
Bit(s) Description (Table 0707)
2 initialization (only for DLLs) 0 = global, 1 = per-process
4 no internal fixups in executable image
...
Format of object table entry:
Offset Size Description (Table 0708)
00h DWORD virtual size in bytes
04h DWORD relocation base address
08h DWORD object flags (see #0709)
0Ch DWORD page map index
10h DWORD page map entries
14h 4 BYTEs reserved??? (apparently always zeros)
Bitfields for object flags:
Bit(s) Description (Table 0709)
0 readable
1 writable
...
Format of object page map table entry:
Offset Size Description (Table 0710)
00h BYTE ??? (usually 00h)
01h WORD (big-endian) index to fixup table
0000h if no relocation info
03h BYTE type (00h hard copy in file, 03h some relocation needed)
Format of resident names table entry:
Offset Size Description (Table 0711)
00h BYTE length of name
01h N BYTEs name
N+1 3 BYTEs ???
Format of LE linear executable entry table:
Offset Size Description (Table 0712)
00h BYTE number of entries in table
01h 10 BYTEs per entry
...
Format of LX linear executable entry table [array]:
Offset Size Description (Table 0713)
00h BYTE number of bundles following (00h = end of entry table)
01h BYTE bundle type
...
Bitfields for linear executable fixup type:
Bit(s) Description (Table 0714)
7 ordinal is BYTE rather than WORD
6 16-rather than 8-object number/module ordinal
...
Format of linear executable fixup record:
Offset Size Description (Table 0715)
00h BYTE type
bits 7-4: modifier (0001 single, 0011 multiple)
...
01h BYTE linear executable fixup type (see #0714)
...
Format of old Phar Lap .EXP file header:
Offset Size Description (Table 0716)
00h 2 BYTEs "MP" (4Dh 50h) signature
02h WORD remainder of image size / page size (page size = 512h)
...
Format of new Phar Lap .EXP file header:
Offset Size Description (Table 0717)
00h 2 BYTEs signature ("P2" for 286 .EXP executable, "P3" for 386 .EXP)
02h WORD level (01h flat-model file, 02h multisegmented file)
...
Format of Phar Lap segment information table entry:
Offset Size Description (Table 0718)
00h WORD selector number
...
Format of 386|DOS-Extender run-time parameters:
Offset Size Description (Table 0719)
00h 2 BYTEs signature "DX" (44h 58h)
...
Format of Phar Lap repeat block header:
Offset Size Description (Table 0720)
00h WORD byte count
02h BYTE repeat string length
Format of Borland debugging information header (following load image):
Offset Size Description (Table 0721)
00h WORD signature 52FBh
02h WORD version ID
GET EXTENDED ERROR INFORMATION
To Call:
AH = 59h
BX = 0000h
INT 21h
Return:
AX = extended error code (see #0770)
BH = error class (see #0772)
BL = recommended action (see #0773)
CH = error locus (see #0774)
ES:DI may be pointer (see #0771, error code list below)
CL, DX, SI, BP, and DS destroyed
(Table 0770)
Values for DOS extended error code:
00h (0) no error
01h (1) function number invalid
02h (2) file not found
...
Format of media ID structure:
Offset Size Description (Table 0771)
00h 12 BYTEs ASCIZ volume label of required disk
0Ch DWORD serial number (DOS 4+)
(Table 0772)
Values for DOS Error Class:
01h out of resource (storage space or I/O channels)
02h temporary situation (file or record lock)
...
(Table 0773)
Values for DOS Suggested Action:
01h retry
...
(Table 0774)
Values for DOS Error Locus:
01h unknown or not appropriate
European GET HARD ERROR INFORMATION
To Call:
AH = 59h
BX = 0001h
INT 21h
Return:
ES:DI -> hard error information packet (see #0775) for most recent hard (critical) error
Format of European MS-DOS 4.0 hard error information packet:
Offset Size Description (Table 0775)
00h WORD contents of AX at system entry
GET EXTENDED COUNTRY INFORMATION
AH = 65h
ES:DI -> country information buffer (see #0840)
CX = size of buffer (>= 5)
INT 21h
Return:
CF set on error
AX = error code (see #0770 at AH=59h)
Format of country information:
Offset Size Description (Table 0840)
00h BYTE info ID
...
01h DWORD pointer to uppercase table (see #0841)
---if info ID = 04h---
01h DWORD pointer to filename uppercase table (see #0842)
---if info ID = 05h---
01h DWORD pointer to filename character table (see #0843)
---if info ID = 06h---
01h DWORD pointer to collating table (see #0844)
---if info ID = 07h (DOS 4+)---
01h DWORD pointer to DBCS lead byte table (see #0845)
Format of uppercase table:
Offset Size Description (Table 0841)
00h WORD table size
02h 128 BYTEs uppercase equivalents (if any) of chars 80h to FFh
Format of filename uppercase table:
Offset Size Description (Table 0842)
00h WORD table size
02h 128 BYTEs uppercase equivalents (if any) of chars 80h to FFh
Format of filename terminator table:
Offset Size Description (Table 0843)
00h WORD table size (not counting this word)
...
Format of collating table:
Offset Size Description (Table 0844)
00h WORD table size
02h 256 BYTEs values used to sort characters 00h to FFh
Format of DBCS lead byte table:
Offset Size Description (Table 0845)
00h WORD length
02h 2N BYTEs start/end for N lead byte ranges
WORD 0000h (end of table)
COUNTRY-DEPENDENT CHARACTER CAPITALIZATION
To Call:
AH = 65h
INT 21h
Return:
GET GLOBAL CODE PAGE TABLE
To Call:
AX = 6601h
INT 21h
Return:
CF set on error
AX = error code (see #0770 at AH=59h)
CF clear if successful
BX = active code page (see #0846)
DX = system code page (see #0846)
SET GLOBAL CODE PAGE TABLE
To Call:
AX = 6602h
BX = active code page (see #0846)
DX = system code page (active page at boot time)
INT 21h
Return:
CF set on error
AX = error code (see #0770 at AH=59h)
CF clear if successful
(Table 0846)
Values for code page:
437 US
850 Multilingual
AH = 62h
INT 21h
Return:
BX = segment of PSP for current process
AX = 3700h
INT 21h
Return:
AL = status
00h successful
DL = current switch character
FFh unsupported subfunction
Returns the character which is used to introduce command switches. By default this is "/", but is sometimes changed to "-".
AX = 3701h
DL = new switch character
INT 21h
Return:
AL = status
00h successful
FFh unsupported subfunction
AH = 38h
AL = 00h for current country
AL = 01h thru 0FEh for specific country with code <255 (see #0625)
AL = 0FFh for specific country with code >= 255
BX = 16-bit country code (see #0625)
DS:DX -> buffer for returned info (see #0624)
INT 21h
Return:
CF set on error
AX = error code (02h)
CF clear if successful
AX = country code (Novell NWDOS v7.0)
BX = country code
DS:DX buffer filled
this function is not supported by the Borland DPMI host, but no error
is returned; as a workaround, one should allocate a buffer in
conventional memory with INT 31/AX=0100h and simulate an INT 21 with
INT 31/AX=0300h
Format of DOS 2.00-2.10 country info:
Offset Size Description (Table 0623)
00h WORD date format 0 = USA mm dd yy
1 = Europe dd mm yy
2 = Japan yy mm dd
02h BYTE currency symbol
03h BYTE 00h
04h BYTE thousands separator char
05h BYTE 00h
06h BYTE decimal separator char
07h BYTE 00h
08h 24 BYTEs reserved
Format of DOS 2.11+ country info:
Offset Size Description (Table 0624)
00h WORD date format (see #0623)
02h 5 BYTEs ASCIZ currency symbol string
07h 2 BYTEs ASCIZ thousands separator
09h 2 BYTEs ASCIZ decimal separator
0Bh 2 BYTEs ASCIZ date separator
0Dh 2 BYTEs ASCIZ time separator
0Fh BYTE currency format
bit 2 = set if currency symbol replaces decimal point
bit 1 = number of spaces between value and currency symbol
bit 0 = 0 if currency symbol precedes value
1 if currency symbol follows value
10h BYTE number of digits after decimal in currency
11h BYTE time format
bit 0 = 0 if 12-hour clock
1 if 24-hour clock
12h DWORD address of case map routine
(FAR CALL, AL = character to map to upper case [>= 80h])
16h 2 BYTEs ASCIZ data-list separator
18h 10 BYTEs reserved
(Table 0625)
Values for country code:
001h United States
002h Canadian-French
003h Latin America
01Fh Netherlands
020h Belgium
021h France
022h Spain
024h Hungary (not supported by DR-DOS 5.0)
026h Yugoslavia (not supported by DR-DOS 5.0)
027h Italy
029h Switzerland
02Ah Czechoslovakia/Tjekia (not supported by DR-DOS 5.0)
02Bh Austria (DR-DOS 5.0)
02Ch United Kingdom
02Dh Denmark
02Eh Sweden
02Fh Norway
030h Poland (not supported by DR-DOS 5.0)
031h Germany
037h Brazil (not supported by DR-DOS 5.0)
03Dh International English [Australia in DR-DOS 5.0]
051h Japan (DR-DOS 5.0, MS-DOS 5.0+)
052h Korea (DR-DOS 5.0)
056h China (MS-DOS 5.0+)
058h Taiwan (MS-DOS 5.0+)
05Ah Turkey (MS-DOS 5.0+)
15Fh Portugal
162h Iceland
166h Finland
311h Middle East/Saudi Arabia (DR-DOS 5.0,MS-DOS 5.0+)
3CCh Israel (DR-DOS 5.0,MS-DOS 5.0+)
INT 21 - DOS 3.0+ - SET COUNTRY CODE
AH = 38h
DX = FFFFh
AL = 01h thru FEh for specific country with code <255
AL = FFh for specific country with code >= 255
BX = 16-bit country code (see #0625)
Return: CF set on error
AX = error code (see #0885 at AH=59h)
CF clear if successful
AH = 25h
AL = interrupt number
DS:DX -> new interrupt handler
INT 21h
this function is preferred over direct modification of the interrupt vector table
some DOS extenders place an API on this function, as it is not
directly meaningful in protected mode
AH = 2Ah
INT 21h
Return:
CX = year (1980-2099)
DH = month
DL = day
AL = day of week (00h=Sunday)
INT 21 - DOS 1+ - SET SYSTEM DATE
AH = 2Bh
CX = year (1980-2099)
DH = month
DL = day
Return: AL = status
00h successful
FFh invalid date, system date unchanged
Note: DOS 3.3+ also sets CMOS clock
INT 21 - DOS 1+ - SET SYSTEM TIME
AH = 2Dh
CH = hour
CL = minute
DH = second
DL = 1/100 seconds
Return: AL = result
00h successful
FFh invalid time, system time unchanged
Note: DOS 3.3+ also sets CMOS clock
AH = 00h
INT 1Ah
Return:
CX:DX = number of clock ticks since midnight
AL = midnight flag, nonzero if midnight passed since time last read
There are approximately 18.2 clock ticks per second, 1800B0h per 24 hrs IBM and many clone BIOSes set the flag for AL rather than incrementing
it, leading to loss of a day if two consecutive midnights pass
without a request for the time (e.g. if the system is on but idle)
since the midnight flag is cleared, if an application calls this
function after midnight before DOS does, DOS will not receive the
midnight flag and will fail to advance the date
AH = 01h
CX:DX = number of clock ticks since midnight
INT 1Ah
AH = 02h
INT 1Ah
Return: CF clear if successful
CH = hour (BCD)
CL = minutes (BCD)
DH = seconds (BCD)
DL = daylight savings flag (00h standard time, 01h daylight time)
CF set on error (i.e. clock not running or in middle of update)
AH = 03h
CH = hour (BCD)
CL = minutes (BCD)
DH = seconds (BCD)
DL = daylight savings flag (00h standard time, 01h daylight time)
INT 1Ah
AH = 04h
INT 1Ah
Return:
CF clear if successful
CH = century (BCD)
CL = year (BCD)
DH = month (BCD)
DL = day (BCD)
CF set on error
AH = 05h
CH = century (BCD)
CL = year (BCD)
DH = month (BCD)
DL = day (BCD)
INT 1Ah
AH = 06h
CH = hour (BCD)
CL = minutes (BCD)
DH = seconds (BCD)
INT 1Ah
Return:
CF set on error (alarm already set or clock stopped for update)
CF clear if successful
the alarm occurs every 24 hours until turned off, invoking INT 4A each time the BIOS does not check for invalid values for the time, so the CMOS clock chip's "don't care" setting (any values between C0h and FFh)
may be used for any or all three part. For example, to create an
alarm once a minute, every minute, call with CH=C0h, CL=C0h, and
DH=00h.
AH = 07h
INT 1Ah
Return:
alarm disabled
does not disable the real-time clock's IRQ
AH = 08h
CH = hours in BCD
CL = minutes in BCD
DH = seconds in BCD
INT 1Ah
AH = 09h
INT 1Ah
Return:
CH = hours in BCD
CL = minutes in BCD
DH = seconds in BCD
DL = alarm status
00h alarm not enabled
01h alarm enabled but will not power up system
02h alarm will power up system
AH = 0Ah
INT 1Ah
Return: CF set on error
CF clear if successful
CX = count of days since Jan 1,1980
AH = 0Bh
CX = count of days since Jan 1,1980
INT 1Ah
Return: CF set on error
CF clear if successful
Control-Break has been pressed
Note: normally points to a short routine in DOS which sets the Ctrl-C flag,
thus invoking INT 23h the next time DOS checks for Ctrl-C.
100% compatible BIOSes
Format of video parameters:
Offset Size Description (Table 0571)
00h 16 BYTEs 6845 register values for modes 00h and 01h
10h 16 BYTEs 6845 register values for modes 02h and 03h
20h 16 BYTEs 6845 register values for modes 04h and 05h
30h 16 BYTEs 6845 register values for modes 06h and 07h
40h WORD bytes in video buffer for modes 00h and 01h (0800h)
42h WORD bytes in video buffer for modes 02h and 03h (1000h)
44h WORD bytes in video buffer for modes 04h and 05h (4000h)
46h WORD bytes in video buffer for mode 06h (4000h)
48h 8 BYTEs columns on screen for each of modes 00h through 07h
50h 8 BYTEs CRT controller mode bytes for each of modes 00h through 07h
Format of diskette parameter table:
Offset Size Description
00h BYTE first specify byte
bits 7-4: step rate
bits 3-0: head unload time (0Fh = 240 ms)
01h BYTE second specify byte
bits 7-1: head load time (01h = 4 ms)
bit 0: non-DMA mode (always 0)
02h BYTE delay until motor turned off (in clock ticks)
03h BYTE bytes per sector (00h = 128, 01h = 256, 02h = 512, 03h = 1024)
04h BYTE sectors per track
05h BYTE length of gap between sectors (2Ah for 5.25", 1Bh for 3.5")
06h BYTE data length (ignored if bytes-per-sector field nonzero)
07h BYTE gap length when formatting (50h for 5.25", 6Ch for 3.5")
08h BYTE format filler byte (default F6h)
09h BYTE head settle time in milliseconds
0Ah BYTE motor start time in 1/8 seconds
To Call:TERMINATE PROGRAMAH = 00h
CS = PSP segment
INT 21h
To Call:
CS = PSP segment
INT 20h
Multiplex - NOTES
To Call:
AH = identifier of program which is to handle the interrupt
INT 2Fh
AH = 26h
DX = segment at which to create PSP (see #0603)
INT 21h
new PSP is updated with memory size information; INTs 22h, 23h, 24h
taken from interrupt vector table; the parent PSP field is set to 0
(DOS 2+) DOS assumes that the caller's CS is the segment of the PSP to
copy
Format of Program Segment Prefix (PSP):
Offset Size Description (Table 0603)
00h 2 BYTEs INT 20 instruction for CP/M CALL 0 program termination
the CDh 20h here is often used as a signature for a valid PSP
02h WORD segment of first byte beyond memory allocated to program
04h BYTE (DOS) unused filler
(OS/2) count of fake DOS version returns
05h BYTE CP/M CALL 5 service request (FAR CALL to absolute 000C0h)
BUG: (DOS 2+ DEBUG) PSPs created by DEBUG point at 000BEh
06h WORD CP/M compatibility--size of first segment for .COM files
08h 2 BYTEs remainder of FAR JMP at 05h
0Ah DWORD stored INT 22 termination address
0Eh DWORD stored INT 23 control-Break handler address
12h DWORD DOS 1.1+ stored INT 24 critical error handler address
16h WORD segment of parent PSP
18h 20 BYTEs DOS 2+ Job File Table, one byte per file handle, FFh = closed
2Ch WORD DOS 2+ segment of environment for process (see #0604)
2Eh DWORD DOS 2+ process's SS:SP on entry to last INT 21 call
32h WORD DOS 3+ number of entries in JFT (default 20)
34h DWORD DOS 3+ pointer to JFT (default PSP:0018h)
38h DWORD DOS 3+ pointer to previous PSP (default FFFFFFFFh in 3.x)
used by SHARE in DOS 3.3
3Ch BYTE DOS 4+ (DBCS) interim console flag (see AX=6301h)
3Dh BYTE (APPEND) TrueName flag (see INT 2F/AX=B711h)
3Eh BYTE (Novell NetWare) flag: next byte initialized if CEh
(OS/2) capabilities flag
3Fh BYTE (Novell NetWare) Novell task number if previous byte is CEh
40h 2 BYTEs DOS 5+ version to return on INT 21/AH=30h
42h WORD (MSWindows3) selector of next PSP (PDB) in linked list
Windows keeps a linked list of Windows programs only
44h WORD (MSWindows3) "PDB_Partition"
46h WORD (MSWindows3) "PDB_NextPDB"
48h BYTE (MSWindows3) bit 0 set if non-Windows application (WINOLDAP)
49h BYTE unused by DOS versions <= 6.00
4Ch WORD (MSWindows3) "PDB_EntryStack"
4Eh 2 BYTEs unused by DOS versions <= 6.00
50h 3 BYTEs DOS 2+ service request (INT 21/RETF instructions)
53h 2 BYTEs unused in DOS versions <= 6.00
55h 7 BYTEs unused in DOS versions <= 6.00; can be used to make first FCB
into an extended FCB
5Ch 16 BYTEs first default FCB, filled in from first commandline argument
overwrites second FCB if opened
6Ch 16 BYTEs second default FCB, filled in from second commandline argument
overwrites beginning of commandline if opened
7Ch 4 BYTEs unused
80h 128 BYTEs commandline / default DTA
command tail is BYTE for length of tail, N BYTEs for the tail,
followed by a BYTE containing 0Dh
in DOS v3+, the limit on simultaneously open files may be increased by
allocating memory for a new open file table, filling it with FFh,
copying the first 20 bytes from the default table, and adjusting the
pointer and count at 34h and 32h. However, DOS will only copy the
first 20 file handles into a child PSP (including the one created on
EXEC).
network redirectors based on the original MS-Net implementation use
values of 80h-FEh in the open file table to indicate remote files;
Novell NetWare also uses values from FEh down to 80h or one more than
FILES= (whichever is greater) to indicate remote files
some DOS extenders place protected-mode values in various PSP fields
such as the "parent" field, which can confuse PSP walkers. Always
check either for the CDh 20h signature or that the suspected PSP is
at the beginning of a memory block which owns itself (the preceding
paragraph should be a valid MCB with "owner" the same as the
suspected PSP).
Novell NetWare updates the fields at offsets 3Eh and 3Fh without
checking that a legal PSP segment is current; see AH=50h for further
discussion
Format of environment block:
Offset Size Description (Table 0604)
00h N BYTEs first environment variable, ASCIZ string of form "var=value"
N BYTEs second environment variable, ASCIZ string
...
N BYTEs last environment variable, ASCIZ string of form "var=value"
BYTE 00h
---DOS 3.0+ ---
WORD number of strings following environment (normally 1)
N BYTEs ASCIZ full pathname of program owning this environment
other strings may follow
Legacy only adds one new set of interrupts to its DOS emulation. They are at INT 0FFh an are mostly informational.
LEGACY CHECKTo Call:
AX = 0000h
CX = n
INT FFh
Returns:
AX = 1
CX = NOT CX
This does a simple check to determine if Legacy is active. Test to see if the value returned in CX is the NOT of what you sent. Try it as many times as you think you need to.
LEGACY GENERAL CONFIGURATION VERSION AND LENGTH
To Call:
AX = 0002h
INT FFh
Return:
AX = information version, should be 0
ECX = length of area needed for configuration info
LEGACY GENERAL CONFIGURATION
To Call:
AX = 0003h
ES:(E)DI =
INT FFh
Return:
This functions copies a wealth of information about the current Legacy emulation to the pointer you supply using ES:(E)DI.
Format of configuration buffer:
Size Description
DWORD Legacy major version
DWORD Legacy minor version
DWORD Legacy build
DWORD beta flag (00h normal release, 01h beta release)
DWORD DPMI major version ;DOS Protected Mode Interface
DWORD PMI minor version
DWORD VCPI major version
DWORD VCPI minor version
DWORD EMS major version ;Extended Memory Support
DWORD EMS minor version
DWORD XMS major version ;Expanded Memory Support
DWORD XMS minor version
DWORD VESA major version
DWORD VESA minor version
DWORD processor (3 = 386, 4 = 486, 5= Pentium)
DWORD coprocessor (4 = none, 6 = 287, 7 = 387/486)
DWORD machine type (0 = IBM PC compatible)
DWORD machine bus type (0=ISA, 1=MCA, 2=XT, 3=EISA, 4=PCI)
DWORD physical memory in system
DWORD virtual memory in system
DWORD DMA capable memory given to emulation
DWORD actual memory given to 1MB area
DWORD extended" memory given to emulation
DWORD total memory given to emulation
DWORD virtual swaps since startup
DWORD support
bit 0: 16-bit
bit 1: 32-bit
bit 2: ?-bit
bit 3: keyboard support
bit 4: mouse support
bit 5: joystick
bit 6: xms (HIMEM.SYS)
bit 7: ems (EMM386.SYS)
bit 8: vcpi
bit 9: dpmi
bit 10: vga
bit 11: vesa 1.2
bit 12: vbe 2.0
bit 13: vbe ?
bit 14: SHARE.EXE
bit 15:
DWORD status
bit 0: command line mode?
0=no,
1=yes, returns to command-line at termination
bit 1: mode, 0=16, 1=32
bit 2: ports, 0=free, 1=selective permission bitmap
bit 3: sessions, 0=single DOS, 1=multiple DOS
LEGACY VIDEO CONFIGURATION VERSION AND LENGTH
To Call:
AX = 0010h
INT FFh
Return:
AX = version, should be 0
ECX = length of area needed for configuration info
LEGACY VIDEO CONFIGURATION
To Call:
AX = 0011h
ES:(E)DI =
INT FFh
Return:
LEGACY AUDIO CONFIGURATION VERSION AND LENGTH
To Call:
AX = 0010h
INT FFh
Return:
AX = version, should be 0
ECX = length of area needed for configuration info
LEGACY AUDIO CONFIGURATION
To Call:
AX = 0011h
ES:(E)DI =
INT FFh
Return:
LEGACY CONTROLLER CONFIGURATION VERSION AND LENGTH
To Call:
AX = 0010h
INT FFh
Return:
AX = version, should be 0
ECX = length of area needed for configuration info
LEGACY CONTROLLER CONFIGURATION
To Call:
AX = 0011h
ES:(E)DI =
INT FFh
Return:
LEGACY COMMUNICATIONS CONFIGURATION VERSION AND LENGTH
To Call:
AX = 0010h
INT FFh
Return:
AX = version, should be 0
ECX = length of area needed for configuration info
LEGACY COMMUNICATIONS CONFIGURATION
To Call:
AX = 0011h
ES:(E)DI =
INT FFh
Return:
LEGACY EMULATION CONFIGURATION VERSION AND LENGTH
To Call:
AX = 0010h
INT FFh
Return:
AX = version, should be 0
ECX = length of area needed for configuration info
LEGACY EMULATION CONFIGURATION
To Call:
AX = 0011h
ES:(E)DI =
INT FFh
Return:
LEGACY EMULATION SETUP
To Call:
AX = 0091h
ES:(E)DI =
INT FFh
Return:
Unfortunately, even after the DOS32 Legacy Metaphor has aged a while, there will still be a few programs that will not run at all, or may require a small front helper or patch program. This is to be expected. One of the responsibilties of The Legacy Group, aside from working on DOS32 and possibly DOS16/32 is to act as a clearinghouse for these patches and fixes.
Probably one of the most common problem will be the curious usage of .COM and .BAT files to set up 32-bit DOS programs.
This document should be fully HTML 3.2 compliant
(excepting Javascript timedate stamping).
If you encounter problem while browsing,
then email Lewis Sellers.
Copyright © 1995,1996, Lewis Sellers. All Rights Reserved.
The Pentium and Pentium Pro are trademarks of the Intel Corporation. TASM is a trademark of Borland International.