A Grail Millennium Project

White Paper

History | Preface | TOC

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.

Preface | TOC


OCI/Spec | DOS16/32 L E G A C Y

DESIGNER

Lewis A. Sellers (aka Minimalist) lsellers@usit.net

CRITIQUED BY

DRAFTS

INSPIRATIONAL MUSIC for this Document:

TOC


(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 NoticesWho gets sued and why
HistoryChanges and who made them
PrefaceAbout the FS and the people that make it

OverviewAn Overview of the DOS Legacy


TOC

DOS16/32 Legacy

"The count of lawyers in a society is good indication of how immoral it is."
--min 6-2-96 445a

Um, 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.

TOC


THE CODE BRIDGE:

INTERFACING WITH LEGACY SOFTWARE

BY | Lewis Sellers lsellers@usit.net

System Timer 08h

COM2 COM4

COM1 COM3

The Virtual Memory Map

TOC


The Program Itself

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\".

TOC


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.BAT

COPY 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

NameColumnsLinesCharsBitwidthBackForeTypeAtrrib
3h80258161616Fixed
6080508161616
8060
13225
13243
13260

Graphics

NameWidthHeightDepthBitdeapthRGBTypeFormat
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.


TOC

DPMI 0.9, EMS, XMS

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 invalid

PREPARING TO USE XMS:

To Call:
	AH=43h
	INT 2Fh
Return:
	ES:BX driver function control address

Under 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:
	None

This 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


TOC

VESA 1.2 VBE 2.0

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 = 02h

BH = 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 = 03h

BH = 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 Call

AH = 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 = 07h

AL = 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 = 08h

BH = 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 = 09h

AL = 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 = 0Ah

AL = 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 = 0Bh

BH = 00h

BL = background/border color (border only in text modes)

SET PALETTE

AH = 0BH

BH = 01h

BL = palette ID

00h background, green, red, and brown/yellow

01h background, cyan, magenta, and white

WRITE GRAPHICS PIXEL

AH = 0Ch

BH = 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 = 0Dh

BH = 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 = 0Eh

AL = 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 = 0Fh

Return: 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 = 1000h

BL = 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 = 1009h

ES:DX -> 17-byte buffer (see AX=1002h)

SET INDIVIDUAL DAC REGISTER

AX = 1010h

BX = 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 = 1012h

BX = 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 = 1013h

BL = 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 = 1015h

BL = palette register number

Return: DH = red value

CH = green value

CL = blue value

READ BLOCK OF DAC REGISTERS

AX = 1017h

BX = 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 = 1018h

BL = new PEL value

READ PEL MASK (VGA/MCGA)

AX = 1019h

Return: 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 = 101Bh

BX = starting palette register

CX = number of registers to convert

TEXT-MODE CHARACTER GENERATOR FUNCTIONS

AH = 11h

The 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 = 11h

AL = 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 = 1130h

BH = 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 = 12h

BL = 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 = 12h

BL = 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 = 12h

BL = 30h

AL = vertical resolution

00h 200 scan lines

01h 350 scan lines

02h 400 scan lines

ALTERNATE FUNCTION SELECT (VGA, MCGA) - PALETTE LOADING

AH = 12h

BL = 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 = 12h

BL = 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 = 12h

BL = 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 = 12h

BL = 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 = 12h

BL = 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 = 12h

BL = 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 = 1Bh

BX = 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

TOC


Joystick

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

TOC


Keyboard

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)

TOC


Mouse

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 bit is 1 when the button is pressed. The bit is 0 when the button is released.

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.

Read Button Release State of Mouse

To Call:

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.

Define Horizontal (X) Range of Cursor Location

To Call:

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.

Define Vertical (Y) Range of Cursor Location

To Call:

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.

Define Graphics Mode Cursor Style

To Call: AX = 9

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.)

Read Mouse Motion Number

To Call:

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.

Define Event Handler Entry Location

To Call:

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.)

Enable Light Pen Emulation Function

To Call:

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).

Disable Light Pen Emulation Function

To Call:

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.

Define Sensitivity (Mouse Motion/Pixel) of Mouse

To Call:

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

Disable Cursor Display in Special Range

To Call:

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

Define Double-Speed Threshold

To Call:

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.

Swap Event Handler Entry Location

To Call:

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.

Get Mouse Driver State Storage Size

To Call:

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.

Save Mouse Driver state

To Call:

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.

Restore Mouse Driver State

To Call:

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.

Set CRT Page Number

To Call:

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.

Read CRT Page Number

To Call:

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:

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
Note: x = B or D depending on the base I/O address;

determined by Miscellaneous Output Register bit 1.

Retrieve Single Data

To Call:

AH = F0H

BX = Index number

DX = Port number

Return:

BL = Retrieved data from EGA register

This function retrieves data from a single register.

Save Single Data

To Call:

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.

Retrieve Registers on a Specified Port

To Call:

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.

Save Registers on a Specified Port

To Call:

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.

Retrieve Several Registers Data At The Same Time

To Call: AH = F4H

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.

Save Several Registers Data At The Same Time

To Call:

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.

Reset All Registers as Initial Values

To Call:

AH = F6H

Return:

None

This function resets all values to default values for the specific registers. Function 7 sets the default values.

Set Initial Values

This function sets the initial default values. Upon finishing a call to this function, the BX and DX values are altered.

To Call:

AH = F7H

DX = Port number

ES:BX = Table of output data

Get Version Number of Mouse Driver

This function will give the Mouse driver version number.

To Call:

AH = FAH

BX = 00H

Return:

ES:BX = Pointer to Mouse driver version number.


TOC

File BIOS/DOS Services

BY | Lewis Sellers lsellers@usit.net

Under Legacy FCB functions are mostly dummy operations. They provide only enough functionality to emulate getting or setting the "volume label".

"TRUENAME" - CANONICALIZE FILENAME OR PATH

To Call:

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

Far East DOS 3.2+ - GET DOUBLE BYTE CHARACTER SET LEAD-BYTE TABLE

To Call:

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

DOS 2.25, Far East DOS 3.2+ - GET KOREAN (HANGEUL) INPUT MODE

AX = 6302h

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

EXTENDED OPEN/CREATE

AX = 6C00h

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

MS-DOS 7 - LONG FILENAME FUNCTIONS

To Call:

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

Windows95 - LONG FILENAME - "TRUENAME" - CANONICALIZE FILENAME OR PATH

AX = 7160h

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)

Windows95 - LONG FILENAME - GET VOLUME INFORMATION

AX = 71A0h

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

Windows95 - LONG FILENAME - "FindClose" - TERMINATE DIRECTORY SEARCH

AX = 71A1h

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

MS-DOS 7 (Windows95) - DRIVE LOCKING ???

AH = 73h

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

European MS-DOS 4.0 - "PBLOCK" - BLOCK A PROCESS

AH = 99h

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

European MS-DOS 4.0 - "PRUN" - UNBLOCK A PROCESS

AH = 9Ah

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

WRITE CHARACTER TO PRINTER

AH = 05h

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

DIRECT CONSOLE OUTPUT

AH = 06h

DL = character (except FFh)

INT 21h

Return:

AL = character output

Writes to standard output, which is usally the screen.

DIRECT CONSOLE INPUT

AH = 06h

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

DIRECT CHARACTER INPUT, WITHOUT ECHO

AH = 07h

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

CHARACTER INPUT WITHOUT ECHO

AH = 08h

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

WRITE STRING TO STANDARD OUTPUT

AH = 09h

DS:DX -> '$'-terminated string

INT 21h

Return:

AL = 24h

BUFFERED INPUT

AH = 0Ah

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

GET STDIN STATUS

AH = 0Bh

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

FLUSH BUFFER AND READ STANDARD INPUT

AH = 0Ch

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

DISK RESET

AH = 0Dh

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)

SELECT DEFAULT DRIVE

AH = 0Eh

DL = new default drive (00h = A:, 01h = B:, etc)

INT 21h

Return:

AL = number of potentially valid drive letters

GET CURRENT DEFAULT DRIVE

AH = 19h

INT 21h

Return: AL = drive (00h = A:, 01h = B:, etc)

SET DISK TRANSFER AREA ADDRESS

AH = 1Ah

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.

GET ALLOCATION INFORMATION FOR DEFAULT DRIVE

AH = 1Bh

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")

GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE

AH = 1Ch

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)

GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE

AH = 1Fh

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

SET VERIFY FLAG

To Call:

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.

GET DISK TRANSFER AREA ADDRESS

AH = 2Fh

INT 21h

Return: ES:BX -> current DTA

GET DOS VERSION

AH = 30h

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)

GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE

AH = 32h

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

EXTENDED BREAK CHECKING

AH = 33h

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

GET BOOT DRIVE

AX = 3305h

INT 21h

Return:

DL = boot drive (1=A:,...)

GET TRUE VERSION NUMBER

To Call:

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.

GET ADDRESS OF INDOS FLAG

To Call:

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.

GET INTERRUPT VECTOR

To Call:

AH = 35h

AL = interrupt number

INT 21h

Return:

ES:BX -> current interrupt handler

GET FREE DISK SPACE

AH = 36h

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

"MKDIR" - CREATE SUBDIRECTORY

To Call:

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.

"RMDIR" - REMOVE SUBDIRECTORY

AH = 3Ah

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 '..'.

"CHDIR" - SET CURRENT DIRECTORY

AH = 3Bh

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

"CREAT" - CREATE OR TRUNCATE FILE

AH = 3Ch

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

"OPEN" - OPEN EXISTING FILE

AH = 3Dh

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

"CLOSE" - CLOSE FILE

AH = 3Eh

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

"READ" - READ FROM FILE OR DEVICE

AH = 3Fh

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

"WRITE" - WRITE TO FILE OR DEVICE

AH = 40h

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

"UNLINK" - DELETE FILE

AH = 41h

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.

"LSEEK" - SET CURRENT FILE POSITION

AH = 42h

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)

GET FILE ATTRIBUTES

To Call:

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)

"CHMOD" - SET FILE ATTRIBUTES

To Call:

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

DOS 7 GET VOLUME INFORMATION

AX = 4302h

INT 21h

READ RANDOM RECORD FROM FCB FILE

AH = 21h

DS:DX -> opened FCB (see #0574)

INT 21h

This function does not work and always returns AL=0FFh.

WRITE RANDOM RECORD TO FCB FILE

AH = 22h

DS:DX -> opened FCB (see #0574)

[DTA] = record to write

INT 21h

This function does not work and always returns AL=0FFh.

GET FILE SIZE FOR FCB

AH = 23h

DS:DX -> unopened FCB (see #0574), wildcards not allowed

This function does not work and always returns AL=0FFh.

SET RANDOM RECORD NUMBER FOR FCB

AH = 24h

DS:DX -> opened FCB (see #0574)

INT 21h

This function does not work and always returns AL=0FFh.

RANDOM BLOCK READ FROM FCB FILE

AH = 27h

CX = number of records to read

DS:DX -> opened FCB (see #0574)

INT 21h

This function does not work and always returns AL=0FFh.

RANDOM BLOCK WRITE TO FCB FILE

AH = 28h

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.

PARSE FILENAME INTO FCB

AH = 29h

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.

OPEN FILE USING FCB

AH = 0Fh

DS:DX -> unopened File Control Block (see #0574)

INT 21h

This function does not work and always returns AL=0FFh.

CLOSE FILE USING FCB

To Call:

AH = 10h

DS:DX -> File Control Block

INT 21h

This function does not work and always returns AL=FFh.

FIND FIRST MATCHING FILE USING FCB

AH = 11h

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

FIND NEXT MATCHING FILE USING FCB

AH = 12h

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

DELETE FILE USING FCB

AH = 13h

DS:DX -> unopened FCB

INT 21h

This function does not work and always returns AL=0FFh.

SEQUENTIAL READ FROM FCB FILE

AH = 14h

DS:DX -> opened FCB

INT 21h

This function does not work and always returns AL=0FFh.

SEQUENTIAL WRITE TO FCB FILE

AH = 15h

DS:DX -> opened FCB (see #0574)

[DTA] = record to write

INT 21h

This function does not work and always returns AL=0FFh.

CREATE OR TRUNCATE FILE USING FCB

AH = 16h

DS:DX -> unopened FCB (see #0574), wildcards not allowed

INT 21h

This function does not work and always returns AL=0FFh.

RENAME FILE USING FCB

AH = 17h

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.


TOC

Other Misc BIOS/DOS Services

BY | Lewis Sellers lsellers@usit.net

INT 1F - SYSTEM DATA - 8x8 GRAPHICS FONT

this vector points at 1024 bytes of graphics data, 8 bytes for each character 80h-FFh

GET EXTENDED COUNTRY INFORMATION

AH = 65h

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

GET CURRENT PSP ADDRESS

To Call:

AH = 62h

INT 21h

Return:

BX = segment of PSP for current process

"SWITCHAR" - GET SWITCH CHARACTER

To Call:

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 "-".

"SWITCHAR" - SET SWITCH CHARACTER

To Call:

AX = 3701h

DL = new switch character

INT 21h

Return:

AL = status

00h successful

FFh unsupported subfunction

GET COUNTRY-SPECIFIC INFORMATION

To Call:

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

SET INTERRUPT VECTOR

To Call:

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

GET SYSTEM DATE

To Call:

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

GET SYSTEM TIME

To Call:

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

SET SYSTEM TIME

To Call:

AH = 01h

CX:DX = number of clock ticks since midnight

INT 1Ah

GET REAL-TIME CLOCK TIME

To Call:

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)

SET REAL-TIME CLOCK TIME

To Call:

AH = 03h

CH = hour (BCD)

CL = minutes (BCD)

DH = seconds (BCD)

DL = daylight savings flag (00h standard time, 01h daylight time)

INT 1Ah

GET REAL-TIME CLOCK DATE

To Call:

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

SET REAL-TIME CLOCK DATE

To Call:

AH = 05h

CH = century (BCD)

CL = year (BCD)

DH = month (BCD)

DL = day (BCD)

INT 1Ah

SET ALARM

To Call:

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.

CANCEL ALARM

To Call:

AH = 07h

INT 1Ah

Return:

alarm disabled

does not disable the real-time clock's IRQ

SET RTC ACTIVATED POWER ON MODE

To Call:

AH = 08h

CH = hours in BCD

CL = minutes in BCD

DH = seconds in BCD

INT 1Ah

READ RTC ALARM TIME AND STATUS

To Call:

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

READ SYSTEM-TIMER DAY COUNTER

To Call:

AH = 0Ah

INT 1Ah

Return: CF set on error

CF clear if successful

CX = count of days since Jan 1,1980

SET SYSTEM-TIMER DAY COUNTER

To Call:

AH = 0Bh

CX = count of days since Jan 1,1980

INT 1Ah

Return: CF set on error

CF clear if successful

INT 1B C - KEYBOARD - CONTROL-BREAK HANDLER

this interrupt is automatically called when INT 09 determines that

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.

INT 1C - TIME - SYSTEM TIMER TICK

this interrupt is automatically called on each clock tick by the INT 08 handler

INT 1D - SYSTEM DATA - VIDEO PARAMETER TABLES

Note: the default parameter table (see #0571) is located at F000h:F0A4h for

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

INT 1Eh SYSTEM DATA - DISKETTE PARAMETERS

When LEGACY is initialized, a diskette parameter table which is pointed to by the vector at INT 1Eh is filled with values. These values are never again updated, unless the diskette is changed. LEGACY never makes use of them.

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

INT 1F - SYSTEM DATA - 8x8 GRAPHICS FONT

This vector points to 1024 bytes of graphics data, 8 bytes for each character 80h-FFh.

TERMINATE PROGRAM

To Call:

AH = 00h

CS = PSP segment

INT 21h

TERMINATE PROGRAM

To Call:

CS = PSP segment

INT 20h

Multiplex - NOTES

To Call:

AH = identifier of program which is to handle the interrupt

INT 2Fh

CREATE NEW PROGRAM SEGMENT PREFIX

To Call:

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


TOC

Interrupts

BY | Lewis Sellers lsellers@usit.net

Legacy only adds one new set of interrupts to its DOS emulation. They are at INT 0FFh an are mostly informational.

LEGACY CHECK

To 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:


TOC

Patches and Fixes

BY | Lewis Sellers lsellers@usit.net

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.

TRADEMARKS

The Pentium and Pentium Pro are trademarks of the Intel Corporation.
TASM is a trademark of Borland International.

Grail Millennium Project