First steps towards system programming under MS-DOS 7/Appendix

Appendices

A.01 PC's main data structures
Both BIOS and DOS store their important data in especially devoted areas of computer's memory. Data placement inside these areas is not fixed for ever and may depend on version of BIOS and DOS. Therefore data in system structures should not be addressed directly, but rather should be accessed via special functions, described in chapter 8 of this book. One more reason is that data can't be updated properly unless the corresponding service function is called for.

Nevertheless direct access to system data structures may be necessary. It enables to get more information than you are allowed to know via service functions. For debugging purposes you may need to see data "as they were", without being updated. You may need to intervene, to change certain settings in order to provoke desirable consequences. Of course, each such action is done exclusively at your own risk, but it may give you a chance, which otherwise would be lost.

A.01-1. BIOS data area
Just when computer is switched on its BIOS system begins to gather data and arrange its data area. In AT-compatible computers the BIOS data area occupies 100h bytes at 0040:0000h–0040:00FFh. The table below gives general disposition of selected data items with references to separate data tables for floppy drives (A.08-1), video system (A.10-6), keyboard (A.02-3) and other hardware (A.11-1).

 ^ a b After a reboot, initiated by a jump far to F000:FFF0h address,&#91;Note 4 to A.12-1&#93; POST test performance depends on contents, preserved in 0040:0072h memory cell :
 * Notes
 * 0000h – "cold" boot (full POST with memory test)
 * 1234h – "warm" boot (bypass memory test)

Since data disposition in BIOS data area may depend on BIOS version, it is for you to decide, whether the data item at any particular offset is indeed the one you expect to find there. 

A.01-2 Selected entries in DOS' list-of-lists
List-of-lists is the basic data structure, created by IO.SYS loader at start of DOS loading procedure. A pointer to first byte of DOS's list-of-lists is returned by INT 21\AH=52h function (8.02-59). Fig.10 (in appendix A.03-3) illustrates process of access to list-of-lists. Selected information about data items in DOS's list-of-lists is given in the following table.

 ^ DPB blocks (Drive Parameter Blocks, A.03-1) are arranged in a chain, so that a pointer to the next DPB is at offset 19h in the previous DPB. ^ NUL device driver header at offset 22h is the first in a chain of driver headers. First dword in each header is a pointer to the next header. Another way to obtain a pointer to the second driver header is via INT 2F\AX=122Ch. Last header in the chain begins with word FFFFh. 
 * Notes

A.01-3. Selected items in DOS's swappable data area
Current address and size of DOS's swappable data area (SDA) are returned by INT 21\AX=5D06h function (8.02-70). SDA stores continuously updated data, including main DOS's system stacks. These data reflect ever changing DOS's status at each current moment. Total size of swappable area may be as large as several kilobytes, it depends on size of the stacks.

The SDA area is named "swappable", because its swapping is the main mechanism of obtaining DOS's re-enterability, i.e. opportunity to call DOS's functions by TSRs and handlers, which themselves may be called while execution of previous DOS's function hasn't been finished. If interrupt handler reveals that either critical error flag (at offset 00h in SDA) or InDOS flag (at offset 01h in SDA) have a non-zero value, hence a call for this handler has interrupted execution of a DOS's function, and then the next call for any DOS's function can change data in SDA area so that a return back to proper resumption of the interrupted program will become impossible. Though sometimes resumption of interrupted program is possible (8.02-28, 8.02-87), nevertheless the most radical solution is to save contents of SDA before any DOS's function is called, and to restore SDA state afterwards on basis of the saved data. It also should be taken into account that INT 21\AX=5D06h function itself (8.02-70) is non-reentrant; therefore a call for SDA's address should be performed beforehand, during handler's initialization, so that at the moment of interrupt the handler may read a prepared SDA address without a new call for INT 21\AX=5D06h.

The table below shows selected data items inside swappable data area

A.01-4 System File Table structure
Associations between access handles and the corresponding "opened" objects are stored by DOS in a chain-like queue of tables, named SFT (System File Tables). This name is not quite correct, because "opened" objects may be not files only, but also allotted XMS areas, driver's access channels and other objects, known as "character devices".

A pointer to the first SFT is at offset 04h in the list-of-lists (A.01-2). Each SFT begins at offset 00h with a dword pointer to the next SFT, except the last one, which is marked with word FFFFh at offset 00h. Such structure can easily be traced through from the first SFT to the last. A word at offset 04h in each SFT declares number of entries in this particular SFT. Each entry corresponds to one "opened" object. Total number of SFT entries is limited by FILES specification in CONFIG.SYS file (4.12).

Numbers of SFT entries, which are "opened" to a given program, are stored in JFT at offset 18h inside PSP (A.07-1), belonging to this program. The corresponding "opened" objects are addressed to with handles (INT 21\AH=3Dh, 8.02-33), which identify SFT entries according to disposition order of their numbers in JFT. The number of SFT entry, corresponding to a given handle, can be found also with INT 2F\AX=1220h (8.03-11). Then INT 2F\AX=1216h function (8.03-09), being given the SFT entry number, returns a pointer to this entry. Some information about active SFT entries and corresponding objects can be obtained via INT 21\AX=4400h function (8.02-40).

The first three SFT entry numbers have fixed default associations: 00h – AUX channel (COM1 port), 01h – the CON device (console), 02h – the PRN device (LPT1 port). These 3 SFT entry numbers are automatically written into JFT table of each program. Order of their disposition in JFT (01h, 01h, 01h, 00h, 02h) defines associated handles: 0000h – for STDIN channel, 0001h – for STDOUT channel, 0002h – for STDERR channel, 0003h – for COM1 port, 0004h – for LPT1 port. SFT entries for handles 0005h and on are created on requests by INT 21\AH=3Dh (8.02-33) and by INT 21\AX=6C00h (8.02-78) functions.

The first entry in each SFT table starts at offset 06h. As far as each entry has fixed length 3Bh, start points of the following entries can be easily calculated. The table below specifies selected data items inside each entry with offsets counted from start point of that entry. The first column "CDE" of the table corresponds to "character device" entries, the second column "OFE" – to entries, associated with ordinary files.

 ^ Flags byte at 03h includes all BH register settings, specified for INT 21\AX=6C00h function (8.02-78). Besides this, set state of bit 7 in flags byte marks files opened by means of FCB. </ol>
 * Notes

A.02-1 Key codes
User's control over PC via keyboard must be enabled always, even when operating system isn't loaded yet. Therefore motherboard's hardware and BIOS system are responsible for compatibility with different types of keyboards. Just when PC is switched on, its BIOS system loads INT 09 and INT 16 handlers, providing various keyboard functions.

Keyboard signals are received and transformed by keyboard controller. It responds to each change of key's state (press or release) with preparing code for port 60h and sending a request via IRQ 01 interrupt request line. Request invokes the INT 09 handler. Some keys induce keyboard controller to send a succession of codes, so that INT 09 handler is invoked several times. The code, read by INT 09 handler from port 60h, is most often the scan code of some key, but it may be a service code. Codes from E0h to FFh, and also 00h and AAh are interpreted as service codes. Service codes, charged with a special keystroke identification mission, are known as prefixes :
 * E0h – prefix for discrimination between those keys, which for the sake of compatibility with obsolete 84-key keyboards have been given identical scan codes.
 * E1h – prefix for keys having a two byte scan code. In ordinary keyboards there is only one such key: Pause/Break.<sup id="note-A.02-1-6-ref1">&#91;Note 6&#93;

Reading of a prefix from port 60h makes INT 09 handler prepared to a specific interpretation of that scan code, which will be received by the next call for INT 09. In the second column (INT 09) of the table below hexadecimal scan codes of keystrokes are shown, read by INT 09 handler from port 60h. Key release codes are not shown in the table, because release codes can be easily derived from keystroke codes by making its 7th bit set. For example, key "A" sends keystroke (press) code 1Eh, hence its release code is 9Eh. But those scan codes, which are sent preceded by a prefix either E0h or E1h, are shown in the second table's column together with this prefix. Naturally, release codes of the same keys are preceded by the same prefix.

"Raw" scan code, read from port 60h, is translated by INT 09 and INT 16 handlers into a new pair — a unified scan code and ASCII value, corresponding to the pressed (or released) key. Just this data pair will be presented to program, sending a request for keyboard input via INT 16. Unified scan-code most often is equal to press scan code, but may be altered, if at the same time a "functional" key is kept pressed: SHIFT, CTRL, or ALT. Each "functional" key has its own scan code (in second column of the table below). Scan codes of "functional" keys are taken into account by INT 09 handler, but are not stored in keyboard buffer. States of "functional" keys are expressed otherwise: via a status word, returned by INT 16\AH=12 function (8.01-85).The following table represents keys of the most widely used 104-key "enhanced" keyboard. The word "num" before a key name in the first table's column denotes keys of a numeric keypad at the right side of keyboard. The shown codes for such keys correspond to turned OFF state of NUMLOCK switch.<sup id="note-A.02-1-6-ref2">&#91;Note 6&#93; Data order is defined by key's scan codes values in the second table's column.

Hexadecimal numbers in columns 3–6 of the table below represent the data, returned in AX register by INT 16\AH=10h function (8.01-83). Left two digits in each number define unified scan-code, returned in AH register, and the right two digits — ASCII code of corresponding character, returned in AL register. Data in the 3rd column (AX) correspond to keystrokes, not accompanied by keeping pressed any "functional" key. Data in the 4th column (SHIFT) correspond to the case when SHIFT key is kept pressed, data in the 5th column (CTRL) — to the case of keeping pressed the CTRL key, data in the 6th column (ALT) — to the case of keeping pressed the ALT key. Blank space in place of any particular value means that corresponding key or key combination is sensed by BIOS, but isn't reported via INT 16 handler.

<ol> <li id="note-A.02-1-1">^ The INT16\AH=00h function doesn't respond to this keystroke when "functional" key ALT is kept pressed.</li> <li id="note-A.02-1-2">^ The INT16\AH=00h function doesn't respond to this keystroke when "functional" key CTRL is kept pressed.</li> <li id="note-A.02-1-3">^ The INT16\AH=00h function returns 00h instead of ASCII code E0h, except for two keystrokes : after "num /" it returns ASCII code 35h, after "num Enter" keystroke it returns ASCII code 1Ch.</li> <li id="note-A.02-1-4">^ Code of this key is not written into keyboard buffer, but it does affect translation of other key's codes by INT 09 handler.</li> <li id="note-A.02-1-5">^ Keyboard controller responds to SysRq keystroke with "E0 2A E0 37" codes succession, and to SysRq key release — with inverse succession "E0 B7 E0 AA". Some INT 16 handlers may return other response to CTRL-SysRq key combination.</li> <li id="note-A.02-1-6">^ a b c d Release of Pause/Break key is not registered separately. After each Pause/Break keystroke its press code is immediately followed by release code, forming a succession "E1 1D 45 E1 9D C5". Having received such succession of codes, the INT 09 handler resets keyboard buffer and calls for INT 1B (8.01-95).</li> <li id="note-A.02-1-7">^ The shown codes for this key correspond to turned OFF state of Numlock switch. When NumLock switch is turned ON, codes shown in 3rd and in 4th columns of the table get exchanged.</li> <li id="note-A.02-1-8">^ The INT 16\AH=00h function gives no response to these keys.</li> <li id="note-A.02-1-9">Several models of keyboards have three auxiliary keys for power control : "Power", "Sleep" and "Wake Up". Corresponding scan codes for these keys are E0 5E, E0 5F, E0 63.</li> </ol>
 * Notes

A.02-2 Keyboard layouts and national codepages
The following table comprises data for MS-DOS 7 national adaptation by those means, which are supplied in Microsoft's Windows 95/98 release. These means include data file COUNTRY.SYS, three files with keyboard layouts (KEYBOARD.SYS, KEYBRD2.SYS and KEYBRD3.SYS), and four files with fonts for different codepages (EGA.CPI, EGA2.CPI, EGA3.CPI and ISO.CPI).

The first column (Abbr) in this table contains literal country codes, the third column (ID) – keyboard layout identifiers. Both these items are needed for KEYB.COM driver's (5.02-04) command line composition. Layout identifier is necessary for those countries only, where more than one keyboard's layout is used, for other countries it may be omitted.

The 4th column (Keyb) of the table specifies which file with keyboard layout should be loaded : digit 1 corresponds to KEYBOARD.SYS, digit 2 – to KEYBRD2.SYS, digit 3 – to KEYBRD3.SYS, word "Any" – to either of these three files.

The 5th column (Code) of the table shows numeric country code, used for loading COUNTRY.SYS data file (5.02-01) with COUNTRY command (4.05).

Last 7th column of the table shows codepages used in various countries. Number of a codepage is needed for MORE.COM utility (6.18), which has to select one font from a group of fonts in each *.CPI file (example in 9.01-02). The ISO.CPI file supplies fonts, recommended by International Standards Organization. Proprietary Microsoft's fonts are in EGA*.CPI files, about 5 fonts in each. Therefore 6th table's column (Ega*) specifies which one of EGA*.CPI files should be loaded: digit 1 corresponds to file EGA.SYS, digit 2 – to EGA2.CPI, digit 3 – to EGA3.CPI, word "Any" – to either of these files.

Note 1: KEYBOARD.SYS is the only file, which supports typewriter mode of keyboard layout.

Note 2: Microsoft's files for national adaptation are not compatible with KEYRUS.COM driver (5.02-05). The latter uses internal code tables and keyboard layouts.

Note 3: fonts for some other countries (China, Israel, Japan, etc.) are supplied exclusively with special national versions of Microsoft's operating systems.

A.02-3 Keyboard data fields in BIOS data area
The following table shows disposition of keyboard data in BIOS data area. All offsets are given relative to segment address 0040h, where BIOS data area starts.

Note 1: presented data disposition may depend on BIOS version (A.01-1).

A.02-4 National adaptation parameters block
Data block with currently active national adaptation parameters is returned by INT 21\AX=6501h function (8.02-74). Data block of the same structure is accepted by INT 21\AX=7002h function (note 3 to 8.02-74), defining national adaptation for MS-DOS 7.

<ol> <li id="note-A.02-4-1">^ When data block is sent to INT 21\AX=7002h function, then this item is ignored.</li> <li id="note-A.02-4-2">^ Case map routine translates national characters (with ASCII codes larger than 80h) into upper case and back. The case map routine should be called for with CALL FAR command (7.03-08). AL register is used for both sending ASCII code of the character to be translated and for returning the result back.</li> </ol>
 * Notes

A.02-5 Country-dependent restrictions for filenames
A pointer to this table is returned by INT 21\AX=6505h function (note 1 to 8.02-74).

A.02-6 Information about available code pages
The following table shows structure of DISPLAY.SYS (5.02-02) driver's data block ; a pointer to this block is returned by INT 2F\AX=AD03h function (8.03-27).

A.02-7 Definition of "hot" keys in AMIS specification
Common practice for TSR programs is assignment of functions to predetermined "hot" keys irrespective to which keys have been charged yet with other missions by previously loaded TSR programs. The least harmful outcome of this practice is a loss of opportunities to invoke functions of previously loaded TSR programs and drivers. A real chance to prevent interception of "hot" key functions is suggested by AMIS specification (A.07-6). According to AMIS specification, resident modules must respond to calls for multiplex interrupt INT 2D with operation code AL = 05h, returning in DX:BX registers a pointer to a list of their active "hot" keys. Any program, which intends to arrange its own "hot" keys, should be given access to data about previous "hot" key assignments.

The first byte, at offset 00h from the start of "hot" keys list, informs about "hot" calls interception method.<sup id="note-A.02-7-1-ref">&#91;Note 1&#93; The second byte at offset 01h is a number of "hot" keys, kept active by responding resident module. This number also defines total length of the returned list, because after the second byte, starting at offset 02h, a group of "hot" key descriptors follows, each 6 bytes long. Structure of these descriptors is shown in table below. Offsets in the table are counted from start of each descriptor.

<ol> <li id="note-A.02-7-1">^ Byte at offset 00h in "hot" keys list informs about "hot" calls interception method. Bit 7 in this byte must be cleared; other bits have the following meaning :
 * Notes
 * bit 0 set : interception before INT 09 handler
 * bit 1 set : interception after INT 09 handler
 * bit 2 set : interception before INT 15\AH=4Fh
 * bit 3 set : interception after INT 15\AH=4Fh
 * bit 4 set : interception of INT 16\AH=00h,01h,02h calls
 * bit 5 set : interception of INT 16\AH=10h,11h,12h calls
 * bit 6 set : interception of INT 16\AH=20h,21h,22h calls.</li>

<li id="note-A.02-7-2">^ If the most significant bit of scan-code is clear, hence actuation is registered when the key is pressed; if the most significant bit of scan code is set, hence actuation is registered when the key is released. If actuation is caused exclusively by a specific states combination of "functional" keys, then 00h or 80h values should be specified instead of scan code.</li> <li id="note-A.02-7-3">^ A word of required shift states is almost identical to the word of keyboard flags, returned by INT 16\AH=12h function (8.01-85). The only difference is the meaning of bit 7: in a word of required shift states it corresponds to keeping pressed either (left or right) SHIFT key. Set state of any bit in a word of required shift states specifies a necessary condition for "hot" key actuation.</li> <li id="note-A.02-7-4">^ Bits in a word of disallowed shift states have the same meaning, as in a word of required shift states,&#91;Note 3&#93; but their set state expresses the opposite condition : prevention of "hot" key actuation. Combination of required and disallowed conditions helps to decrease probability of false actuations.</li> <li id="note-A.02-7-5">^ The last byte in each "hot" key descriptor is a byte of auxiliary flags. Bits 6 and 7 in this byte must be cleared; states of other bits have the following meaning :
 * bit 0 set: – actuation before module's execution
 * bit 1 set: – actuation after module's execution
 * bit 2 set: – monitoring interception is allowed
 * bit 3 set: – actuation is blocked by other keys
 * bit 4 set: – role of this "hot" key is redefined
 * bit 5 set: – actuation depends on execution conditions.</li>

</ol>

A.02-8. ASCII service marks and commands
Positions 0–31 in American Standard Code for Information Interchange (ASCII) are devoted to service marks and commands. All DOS's codepages have inherited these 32 service codes. Under MS-DOS 7 most part of these service codes is ignored, but some are executed as commands.

Some service codes can be entered by key combinations, described in article 1.05. Another way to input service codes is by their decimal ASCII number (0–31) with keys in numeric keypad while the ALT key is kept pressed.

First response to entered service code may be got from input module of the CON (console) device driver. Further response may be given by command interpreter. When a service code is sent to output, BIOS system enables to execute it as a command (8.01-21, 8.01-33) or to avoid its execution (8.01-17) as well. By default the output module of the CON (console) device driver doesn't attempt to avoid execution of some service codes. Such behavior may be altered by sending a parameters string (8.02-41) to the CON device driver, but there is no reason to do this because DOS programs are allowed to output data directly via desirable BIOS function(s).

Sometimes ASCII service codes may be useful, but it must be known beforehand, where and how each particular service code will be interpreted. Therefore the following table shows a list of those service codes, which are active under MS-DOS 7, with description of actions, associated with these codes.

<ol> <li id="note-A.02-8-1">^ Service codes 0Dh 0Ah together are used as end-of-line marker in all textual files typed under DOS.</li> <li id="note-A.02-8-2">There is a non-zero probability to encounter resident modules, responding to some service codes, which are not shown here and normally are ignored under DOS.</li> </ol>
 * Notes

A.03-1. Structure of Drive Parameters Blocks (DPB)
DOS stores disk access parameters in DPB blocks – one per each available logical disk of any kind, and in one more copy of such block for default (current) drive. The INT 21\AX=7302h function (8.02-79) enables to copy any DPB block into a prepared buffer. Pointers to DPB blocks are returned by INT 21\AH=1Fh and by INT 21\AH=32h functions (8.02-24), documented in previous versions of DOS. In fig.8 below the whole access path to disk's C: DPB block is shown, including a call for INT 21\AH=32h function, reading block's address 00C9:13C0h from DS:BX registers and display of DPB block's dump. In the displayed dump at offset 19h there is address 00C9:13FDh of the next DPB block, related to next logical disk D:. A dump of DPB block for disk D: is also shown in fig.8.

The mentioned legal functions of access to DPB blocks automatically attempt to read the requested disk in order to update data in DPB block. This makes program's execution slower and sometimes can't be applied to removable media, which may be absent in the drive at that moment. Alternative is to read DPB block's address from a cell at offset 45h in CDS entry (A.03-3) of the same disk.

All DPB blocks have the same structure as that shown below. Bytes up to offset 20h are the same as in previous DOS versions, but bytes beyond offset 20h are specific for extended DPB blocks in MS-DOS 7.

<ol> <li id="note-A.03-1-1">Data in DPB block are translated from BPB block (A.03-4) of the same disk by means of INT 21\AH=53h function.</li> <li id="note-A.03-1-2">^ a b A word FFFFh at offset 25h means that there is no FAT information sector on a requested disk. If FAT information sector is present, it contains at offset 00h a fixed double-word signature 61417272h, the second double word at offset 04h is number of free clusters (or FFFFFFFFh if unknown), the third double word at offset 08h is a number of the most recently allocated cluster.</li> </ol>
 * Notes

A.03-2 Disk data tables (DDT)
DDT tables represent a special database for block device drivers, integrated into DOS's core. DDT tables correspond to local disks, which are properly detected and supported by BIOS, including those emulated by BIOS from disk's images on bootable CD/DVD-ROMs. There are no DDT tables for IFS drives, dummy disks, RAM-disks and all other disks, opened for access by drivers, specified in configuration files.

DDT tables are arranged as a chain-like queue of tables, each 96h bytes long. A pointer to the first table is returned by INT 2F\AX=0803h function (8.03-04). This is enough to trace the whole queue, since the first double word in each table is a pointer to DDT table for the next logical disk. The table having the first word FFFFh is the last one in the chain. Fig.9 illustrates access to DDT tables for disks,   and  , including a call for INT 2F\AX=0803h function, reading the returned address (0B52:0000h) of the first DDT table from DS:DI registers, display of a partial dump of DDT table for disk A:, reading from the first 4 bytes of that dump the address (0B52:0096h) of DDT table for the next disk B:, display of a partial dump of DDT table for disk B:, and repetition of the last two operations relative to DDT table for disk C:.

The table below shows data structure in one DDT table. The same data structure is accepted by INT 2F\AX=0801 function (8.03-02), appending a chain of DDT tables with a one more table for a new logical disk.

<ol> <li id="note-A.03-2-1">^ a b c d LUN (Logical Unit Number) is used for discrimination between devices, sharing the same number on a bus. In particular, this is necessary for optical DVD-RAM drives, which present themselves with different LUN numbers either as removable HDD or as CD/DVD-ROM disk. Flash card adapters also represent flash cards in different slots as disks with different LUN numbers.</li> <li id="note-A.03-2-2">^ If disk's parameters were changed, data in DDT table must be reset by INT 21\AX=440Dh\CX=4840h function (8.02-46).</li> <li id="note-A.03-2-3">^ Access ban flag disables both reads and writes. It is applied to HDDs only, in particular, to other primary partitions beyond the first primary partition. Inverse state of access ban flag is reported by INT 21\AX=440Dh\CX=4867h function and may be set anew by INT 21\AX=440Dh\CX=4847h function (8.02-46).</li> <li id="note-A.03-2-4">^ The BPB data block (A.03-4) at offset 43h corresponds not to the current media, but to default type of removable media for this drive. Normally default media is the highest capacity media.</li> </ol>
 * Notes

A.03-3 Current Directory Structure (CDS)
CDS table is an array of data blocks (entries). Each CDS entry corresponds to one logical disk and specifies several parameters of that disk, including a path to the current (default) directory.

A pointer to the first CDS entry is stored at offset 16h in DOS's list of lists (A.01-2). Just there a byte at offset 21h stores total number of entries in CDS table, defined by LASTDRIVE specification in CONFIG.SYS file (4.17). Each CDS entry is 58h bytes long.

Access to CDS table is illustrated by fig.10. The first step is a call for INT 21\AH=52h function (8.02-59), returning address of DOS's list-of-lists (00C9:0026h) in registers ES:BX. The next step is display of memory contents dump, starting at returned address. Length of the displayed dump is chosen so that the last 4 bytes at offsets 16h–19h show the address of CDS table (D203:0000h). Memory contents dump, starting at that address, presents CDS entry for disk A:. 58h bytes behind each previous CDS entry a next CDS entry follows, representing data for the next logical disk.

Among CDS table entries there are dummy entries, having no corresponding logical disks. Dummy entries reserve letter-names for those logical disks, which may be created or become accessible later: RAM-disks, IFS disks, network disks, etc. CDS table is created by IO.SYS loader during commands interpretation in CONFIG.SYS file. Later CDS table can't be appended with new entries. Therefore a sufficient number of dummy entries must be ordered beforehand by means of LASTDRIVE command (4.17).

Data structure of one CDS entry is shown in the table below.

<ol> <li id="note-A.03-3-1">^ For local disks a path to the current directory includes disk's letter-name, colon, backslash, and the rest part of path. End of path must be marked with byte 00h.</li> <li id="note-A.03-3-2">^ If either bit 12 or bit 13 in attribute word is set, then the path at offset 00h isn't a real path.</li> <li id="note-A.03-3-3">^ A zero value of both attribute bits 14 and 15 means that this entry is a dummy or is disabled. Such disks are kept hidden.</li> <li id="note-A.03-3-4">^ If both bits 14 and 15 in attribute word are set, hence this disk represents an IFS file system.</li> <li id="note-A.03-3-5">^ This cluster number is counted from the start of logical disk. Therefore for the root directory cluster number is 0000h. If disk hasn't been accessed yet, cluster field is filled with FFFFh.</li> <li id="note-A.03-3-6">^ DOS may report only the final part of the path to current directory, if a word at offset 4Fh defines a non-zero number of characters, which are to be hidden.</li> <li id="note-A.03-3-7">In early DOS versions CDS entry was 51h byte long; bytes 51h–57h have been added since MS-DOS 4 for IFS and network drivers.</li> </ol>
 * Notes

A.03-4 BIOS Parameter Block (BPB) for a disk
BPB is a part of boot sector on disk media. When DOS starts, BPB data are used to fill internal DOS's tables: DPB (A.03-1) and DDT (A.03-2). This procedure is repeated each time a media change is detected, so that data are always kept updated.

In disk's partitions with FAT-16 file system the BPB is 39h bytes long; its structure is shown in the first column ("F16") of the table below. BPB data inside DDT table have a slightly different "standard" structure, shown in third column ("STD"). Standard BPB blocks are accepted by INT 21\AX=440Dh\CX=0840h function and are returned by INT 21\AX=440Dh\CX=0060h function (8.02-46). Both these functions can be applied to disks with FAT-12 or FAT-16 file systems only.

In disk's partitions with FAT-32 file system the BPB is 5Ah bytes long; its structure is shown in the second column ("F32") of the table below. The same data inside DDT table are arranged according to new "extended" structure, shown in the fourth column ("EXT") of the table. For these data structures MS-DOS 7 provides other functions (8.02-46), which were not available in previous DOS versions: INT 21\AX=440Dh\CX=4840h to refresh BPB data in DDT and INT 21\AX=440Dh\CX=4860h to read BPB data in DDT. Both these new functions should be applied to disks formatted with FAT-32 file system.

<ol> <li id="note-A.03-4-1">^ For partitions smaller than 32 Mb a double word at offset 15h must be zero, the number of sectors in such partitions must be specified in a word at offset 08h.</li> <li id="note-A.03-4-2">^ Media ID byte corresponds to specification of INT 21\AH=1Ch function (8.02-17). If type of removable media is not identified, then the 00h value is assigned to media ID byte.</li> <li id="note-A.03-4-3">^ In "extended" BPB blocks a cell at offset 0Bh has 0000h value, and number of sectors, occupied by FAT table, is expressed by a double word value in a cell at offset 19h.</li> <li id="note-A.03-4-4">^ In BPBs of HDD's partitions the starting sector number is the same as that specified in corresponding partition's descriptor (A.13-5) at offset 08h.</li> <li id="note-A.03-4-5">^ A word at 1Fh and following bytes 21h, 22h of the standard BPB block are not included in extended BPB block and in BPB blocks inside DDT table (A.03-2).</li> </ol>
 * Notes

A.04-1 Data block for IOCTL serial number functions
This data block is returned by functions INT 21\AX=440Dh\CX=4866h (8.02-46) and INT 21\AX=6900h (8.02-77), reading serial number from storage media. Data block of the same structure is accepted by functions INT 21\AX=440Dh\CX=4846h (8.02-46) and INT 21\AX=6901h (8.02-77) in order to assign new serial number to a disk.

<ol> <li id="note-A.04-1-1">^ Name " " corresponds to High-Sierra CD-ROM file system, name " " corresponds to ISO 9660 CD-ROM file system.</li> </ol>
 * Notes

A.04-2 File handle's information word
Handle's information word, read at offset 05h in SFT entry (A.01-4), is returned by INT 21\AX=4400h function (8.02-40). If specified handle refers to SFT entry, related to a non-file object, then returned information word should be interpreted according to table A.05-2. If specified handle refers to SFT entry, related to an opened file, then returned information word should be interpreted according to the table below. Distinctive feature of file handle's information word is clear state of its 7th bit.

A.04-3 Data block for disk parameters specification
A pointer to this data block should be prepared in DS:DX registers before subfunction INT 21\AX=440Dh\CX=4840h (8.02-46) is called for in order to update BPB data in tables DPB (A.03-1) and DDT (A.03-2). Data block of the same structure is returned by INT 21\AX=440Dh\CX=4860h subfunction (8.02-46). Buffer's address for the returned data block should be prepared in advance in DS:DX registers. A byte of flags at offset 00h is not returned, it defines request conditions and should be specified before the call.

<ol> <li id="note-A.04-3-1">^ If bit 0 in flag's byte is set, then updating or copying of BPB block (A.03-4) causes an attempt of access to physical storage media. But when bit 0 in flag's byte is clear, then access to physical storage media wouldn't be attempted: subject of operation will be a copy of BPB block inside DDT table (A.03-2) at offset 43h, which specifies the default type of storage media for this particular device.</li> <li id="note-A.04-3-2">^ Bits 1 and 2 in flag's byte specify interpretation of optional sub-table, defining sector allocation in a track. This sub-table up to 256 bytes long may start at offset 26h for subfunction CX=0840h and at offset 5Ch for subfunction CX=4840h. Media with non-equal sector sizes are not considered in this book, though. For subfunction CX=4860h bit 1 in flag's byte must be clear.</li> <li id="note-A.04-3-3">^ For subfunction CX=0840h the BPB table at offset 07h must have standard BPB structure (A.03-4). Final 6 bytes of BPB block are accepted by subfunction CX=0840h if flag's byte at offset 00h has its bit 0 set, otherwise bytes after offset 1Eh are ignored. For subfunction CX=4840h the BPB table at offset 07h must be 53 bytes long according to extended BPB structure (A.03-4).</li> </ol>
 * Notes

A.04-4 Structure of data block for read/write functions
A pointer to this data block is accepted by INT 21\AX=440Dh\CX=4861h reading function and by INT 21\AX=440Dh\CX=4841h writing function (8.02-46). These functions can't be executed inside "DOS box" under WINDOWS OS unless the addressed logical disk is locked in advance (8.01-58).

A.04-5 Structure of data block for format/verify functions
A pointer to this data block is accepted by INT 21\AX=440Dh\CX=4842h function for formatting and by INT 21\AX=440Dh\CX=4862h verifying function (8.02-46). These functions can't be executed inside "DOS box" under Windows OS unless the addressed logical disk is locked in advance (8.01-58).

Note 1: for format function a word at 05h is ignored, if byte at offset 00h has its bit 1 clear: only one track would be formatted in this case.

Note 2: for verification function a number of tracks in word 05h should correspond to no more than 255 sectors, bit 0 set in byte at offset 00h specifies verification of multiple tracks, bit 1 must be zero.

Note 3: on return the byte at offset 00h is replaced with status code :
 * 00h – this function is supported by BIOS,
 * 01h – this function is not supported by BIOS,
 * 02h – given specifications don't suit for this logical disk,
 * 03h – there is no media in the drive.

Returned status code 00h doesn't confirm successful outcome : success should be confirmed by returned clear state of CF flag.

A.05-1 Driver's header structure
The table below shows data offsets for 3 types of DOS driver's headers :
 * column "B" – for "block" devices, i.e. disk and tape storage drives ;
 * column "C" – for 'character" devices, i.e. communication channels ;
 * column "D" – for CD-ROM drivers, cooperating with MSCDEX.EXE.

A pointer to disk driver header is given in a double word at offset 13h in Drive Parameter Block for the corresponding disk (A.03-1). "Character" device drivers may be identified by a signature at offset 0Ah in their header while tracing a chain of header's addresses. Tracing start address may be got at offset 22h in DOS's List-of-Lists (A.01-2), or else may be obtained by means of INT 2F\AX=122Ch function (8.03-12).

<ol> <li id="note-A.05-1-1">^ The next driver's address field must be initialized as FFFF:FFFFh; later DOS will fill this field with address of the next driver. If no next driver would be loaded, then remaining FFFFh value at start of current driver's header will signify the end of driver's addresses reference chain.</li> <li id="note-A.05-1-2">^ Byte at offset 14h must be initialized with 00h value. Later MSCDEX.EXE program (5.08-03) or SHSUCDX.EXE program (5.08-04) will replace initial zero value with number (note 1 to 8.02-17) of the first disk, controlled by this driver.</li> </ol>
 * Notes

A.05-2 Driver's attributes
Driver's attribute word is at offset 04h in driver's header (A.05-1). But meaning of most bits in attribute word is different for "character" device drivers (in second column of the table below) and for "block" devices drivers (in the third column). CD/DVD-ROM device drivers, cooperating with programs MSCDEX.EXE (5.08-03) or SHSUCDX.EXE (5.08-04), and also drivers of virtual disks, created by SUBST.EXE program (6.23), formally belong to "character" device drivers, as far as bit 15 in their attribute word is set.

Character device driver's attribute word is used as a basis of channel handle's information word, which is stored at offset 05h in corresponding SFT entry (A.01-4) and is returned by INT 21\AX=4400h function (8.02-40) in response to channel handle requests (about file's handle requests in A.04-2). Differences between "character" device driver's attribute word and channel's handle information word evince themselves in bits 4–7 in the second column of the table below: these bits in "character" device driver's attribute word normally are clear. In channel handle's information words bit 7 is set: it is their main distinctive feature from file handle's information words.

<ol> <li id="note-A.05-2-1">^ Among attribute bits 0–3 for character device drivers one bit only may be set (or none).</li> <li id="note-A.05-2-2">^ Raw (binary) output means that neither of output characters is interpreted by driver as a command (as it is shown in A.02-8).</li> <li id="note-A.05-2-3">^ Set state of bit 6 signifies support for functions INT 21\AX=440Ch, 440Dh, 440Eh, 440Fh.</li> <li id="note-A.05-2-4">^ Set state of bit 7 signifies support for functions INT 21\AX=4410h, 4411h.</li> <li id="note-A.05-2-5">^ Set state of bit 9 means that disks, controlled by this driver, are inaccessible to functions of BIOS's INT 13 handler. Set state of bit 9 is typical for drivers, providing access to remote disks, to IFS disks and to disks with parameters, substituted by DRIVPARM command (4.09).</li> <li id="note-A.05-2-6">^ Set state of bit 11 means that driver is able to transfer slot lid lock signals for removable disk drives.</li> <li id="note-A.05-2-7">^ a bSet state of bit 14 means that driver is able to cope with control parameters, sent via INT 21\AX=4403h and INT 21\AX=4405h functions (8.02-41).</li> <li id="note-A.05-2-8">Driver's attribute bits, not mentioned in this table, are considered reserved and normally must be clear.</li> </ol>
 * Notes

A.05-3 Selected requests to device drivers
Interaction between DOS and any device driver is performed by sending an address of request data block in ES:BX registers with a CALL FAR command to driver's strategy routine. The driver receives code of operation and initiates its execution. After some time DOS sends another call for driver's interrupt routine, which fills the same request data block with requested results of performed operation. DOS accepts the result, if successful termination of operation is confirmed by status byte in returned data block (A.05-4).

The same forms of request data blocks are accepted by INT 2F\AX=0802h function (8.03-03), which implicitly sends requests to block device drivers, integrated into DOS's core. These drivers control logical disks, having parameters registered in corresponding DDT tables (A.03-2). Only these logical disks can be addressed by INT 2F\AX=0802h function.

The first column of the table below specifies size of request data block, the second column – code of the requested operation, the fourth column shows which driver type this operation can be applied to. The fifth column shows whether the operation can be requested via INT 2F\AX=0802h function.

<ol> <li id="note-A.05-3-1">^ Requests for sending or receiving IOCTL string can be addressed to those drives only (of either type), which have bit 14 set in their attribute word (A.05-2).</li> <li id="note-A.05-3-2">^ Command 01h (media check) accepts media identifier at offset 0Dh in request data block and returns in the same data block a status byte at offset 0Eh. Value of status byte should be interpreted as follows :
 * Notes
 * FFh – media has not been changed;
 * 01h – media has been changed;
 * 00h – media change state can't be determined.</li>

<li id="note-A.05-3-3">^ Command 05h (nondestructive read) returns one data byte at offset 0Dh in request data block, if BUSY bit in status byte at offset 04h (A.05-4) isn't set on return.</li> </ol>

A.05-4 Format of a request header
Presented header format is used in request data blocks, sent to drivers either with CALL FAR command (A.05-3) or via a call for INT 2F\AX=0802h function (8.03-03). In both cases a pointer to request data block must be in ES:BX registers. The header occupies bytes at offsets 00h–0Ch in request data block. For a number of operations (06h, 07h, 0Ah, 0Bh, 0Dh, 0Eh, 0Fh, 17h) the request data block is nothing else but a header. Structure of a header, common for all requests to drivers, is shown in the table below.

<ol> <li id="note-A.05-4-1">If operation 0Fh (detect removable drive) returns status 02h (busy), this means the addressed drive is a fixed drive.</li> <li id="note-A.05-4-2">^ Here a logical disk is defined by its number in a list of disks, controlled by the addressed driver. When a request is sent via INT 2F\AX=0802h function (8.03-03), then these logical disk numbers are identical to absolute logical disk numbers: 00h = A:, 02h = C:, and so on, but for those logical disks only, which have their parameters specified in DDT tables (A.03-2).</li> <li id="note-A.05-4-3">^ Error code is returned only when status byte at offset 04h has the 80h value, i.e. confirms erroneous outcome. Then error code should be interpreted according to records for INT 2F in table A.06-1.</li> <li id="note-A.05-4-4">^ In case of success the 17h operation (Get disk number) returns absolute number of the requested logical disk at offset 03h. If requested number is beyond the list of logical disks, controlled by the addressed driver, then the 00h value is returned. In any case disk's type and media presence are not checked.</li> </ol>
 * Notes

A.05-5 Initialization request data block
Only once, just when driver is installed by IO.SYS loader, DOS sends to this driver a request for initialization procedure. Request is sent by CALL FAR command with a pointer to request data block in registers ES:BX. Code 00h of initialization procedure is specified in a header of request data block (A.05-03). Having accepted initialization request, the driver explores the available hardware it is responsible for. Some initial data as well as data, returned by the driver, are transferred in the rest part of request data block, beyond its header. Data disposition in this part of request data block (offsets 0Dh–18h) is shown in the table below.

<ol> <li id="note-A.05-5-1">"character" device drivers must return zero in a double word at offset 12h.</li> <li id="note-A.05-5-2">^ Error message flag value 0000h at offset 17h doesn't cause error message display. But if driver returns error message flag value 0001h, then DOS displays message: "There is an error in your CONFIG.SYS file in line..."</li> </ol>
 * Notes

A.05-6 Structure of I/O request data block
I/O request data block is used for driver's data transfer operations called either directly with CALL FAR command (A.05-3) or via INT 2F\AX=0802h function (8.03-03). Address of request data block is presented in ES:BX registers, and header of this request data block specifies code of the requested operation: 04h, 08h or 09h. Data reading operation (code 04h) transfers data from a media into a prepared buffer in memory. Data writing operations (codes 08h and 09h) send data from buffer to disk or to output channel. All mentioned data transfer operations use request data block of the same structure, including a header (A.05-4) and the rest part with access parameters. Disposition of these parameters beyond the header is shown in the table below.

<ol> <li id="note-A.05-6-1">^ Length of data packet for channel drivers is counted in bytes. Length of data packet for disks ("block" device) drivers is expressed in number of sectors.</li> <li id="note-A.05-6-2">^ Some other DOS versions use another data format with a 4-byte starting sector number at offset 14h; a distinctive feature of this data format is length 18h of request data block, specified in the first byte of header (A.05-4). MS-DOS 7 sends a 4-byte starting sector number to those drivers only, which declare their support for 32-bit addressing by setting bit 1 in driver's attribute word (A.05-2). Starting sector number for these drivers is specified at offset 1Ah, and then a cell at offset 14h is filled with FFFFh.</li> <li id="note-A.05-6-3">^ A pointer to volume identifier is returned by driver when error 0Fh occurs (improper change of media).</li> </ol>
 * Notes

A.05-7 Request data block for string operations
This data block is used for driver's byte string transfer operations called by CALL FAR command (A.05-3). Address of data block is specified in ES:BX registers, and header (A.05-4) of that data block specifies code of the requested operation: 03h, 0Ch or 10h. Operation with code 10h sends data string to a channel. Requests with operation codes 03h, 0Ch can be addressed to those drivers only, which declare IOCTL support by having bit 14 set in their attribute word.<sup id="note-A.05-2-7-ref2">&#91;Note 7 to A.05-2&#93; Request with operation code 03h suggests to take into account new values of control parameters, sent via INT 21\AX=4403h or INT 21\AX=4405h function (8.02-41). Operation 0Ch is an offer to the driver to report its actual control parameters, requested either via INT 21\AX=4402h or via INT 21\AX=4404h function (8.02-41).

Request data block for the mentioned operations must have the same structure, including a header (A.05-4) and the rest part; data disposition in this rest part of request data block is shown in the table below.

A.06-1 Summary table of error codes
After any fault both BIOS and DOS functions return error code. Functions of MS-DOS 7 usually leave error code in AL. After BIOS's operations error code may be returned in AH. Interpretation of many error codes depends on which handler has left this error code. For convenience reasons the presented summary table comprises almost all error code interpretations, which may be encountered under MS-DOS 7. Being given the whole variety of alternatives, you'll easily choose the appropriate one according to the handler, which has returned the error code.

<ol> <li id="note-A.06-1-1">If error code is returned in AX register, its most significant byte (in AH register) is zero.</li> <li id="note-A.06-1-2">^ Together with error code 22h, a pointer to media identifier is returned in ES:DI registers. This media identifier includes :
 * Notes
 * at offset 00h – 12 bytes : disk's volume label, ending with 00h ;
 * at offset 0Ch – 1 double word : disk's serial number (in binary form).</li>

<li id="note-A.06-1-3">The HIMEM.SYS driver (5.04-01) returns error codes in BL register.</li> <li id="note-A.06-1-4">Error code, returned by the latest executed DOS's function, is stored in DOS's swappable data area SDA (A.01-3) at offset 04h. BIOS' functions write their error code into BIOS data area (A.01-1), most probably in cell 0040:0074h.</li> </ol>

A.06-2 Error class codes
Error class code, returned in BH register by INT 21\AH=59h function (8.02-65), is stored at offset 07h in DOS's swappable area SDA (A.01-3). Interpretation of error class codes is shown in the table below.

A.06-3 Codes of suggested action
Code of suggested action is returned in BL register by INT 21\AH=59h function (8.02-5) and is stored at offset 06h in DOS's swappable area SDA (A.01-3).

A.06-4 Error locus codes
Error locus code is returned in CH register by INT 21\AH=59h function (8.02-65) and is stored at offset 03h in DOS's swappable area SDA (A.01-3).

A.06-5 I/O error status codes
Error status code is returned in AH register by INT 25 and INT 26 handlers (8.02-85).

A.07-1 Program Segment Prefix
When a program is loaded for execution into an allotted memory segment, executable code of the program is placed at offset 100h and on. Preceding part of the segment (offsets 00h–FFh) is known as PSP, i.e. Program Segment Prefix. It is filled with important service data, which are used by DOS functions and may be used by the program itself.

By means of DEBUG.EXE that PSP can be peeped most easily, which is formed by COMMAND.COM interpreter for DEBUG.EXE itself. A procedure of displaying a part of that PSP is shown in fig.11. The rest part of that PSP is filled with zeros.

The program under test in fig.11 is file CJPEG.EXE. Parameters "-baseline" and "VC01.BMP" are transferred to program under test in order to present an example of filling the first and the second FCB blocks, starting at offsets 5Ch and 6Ch correspondingly. Contents of these and some other PSP data fields are explained in the table below.

<ol> <li id="note-A.07-1-1">^ If segment address of the parent's PSP at offset 16h points at current PSP, then program is regarded as having no parent or, in other terms, as being its own parent. This is a distinctive feature of permanently loaded program, for example, of command interpreter. Permanently loaded programs can't be terminated by a call for INT 20 or for INT 21\AH=4Ch function.</li> <li id="note-A.07-1-2">^ In protected mode some PSP fields, including the "parent" segment field at offset 16h, may be overwritten. Therefore tracing a chain of PSP references may get confused, unless each candidate "parent" PSP segment confirms presence of typical signatures, for example, code CD20h (INT 20) at offset 00h or code CD21h at offset 50h.</li> <li id="note-A.07-1-3">^ a b c When current program starts, its JFT (Job File Table, offset 18h) contains SFT (A.01-4) entry numbers — one byte each — for "opened" objects, which are inherited from the parent process. Free spaces in JFT are filled with FFh byte. Values 80h–FEh in JFT correspond to remote files, opened by network redirectors. Default size of JFT — 20 bytes — imposes a restriction on number of opened objects. The INT 21\AH=67h function (8.02-76) enables to overcome this restriction: it arranges a larger JFT outside PSP, replaces a pointer to JFT in PSP at offset 34h and a count of JFT entries at offset 32h. However, child processes in any case can't inherit from their parent process more than 20 "opened" objects.</li> <li id="note-A.07-1-4">^ a b Areas at offsets 5Ch and 6Ch are filled as unopened FCBs (A.09-5) with parsed data from first and second command line parameters. Parameters are parsed with INT 21\AX=2901h function (8.02-19). Count of parameters includes those that can't be parsed.</li> <li id="note-A.07-1-5">^ a b The "command tail" area 81h–FFh is filled with a copy of command line with all parameters, which follow command name. The filled part of command tail area is terminated by byte 0Dh. Length of the filled part is written at offset 80h. If the length is set to 7Fh, and byte at offset FFh is 0Dh, hence real length of command tail exceeds 126 bytes, and its non-truncated version should be found in value of CMDLINE environmental variable.</li> <li id="note-A.07-1-6">^ "command tail" area 80h–FFh is used as default DTA (data transfer area) by "find file" functions INT 21\AH=11h,12h,4Eh,4Fh. You may prevent overwriting of "command tail" by changing DTA address with INT 21\AH=1Ah function (8.02-16).</li> </ol>
 * Notes

A.07-2 Data block for loading a program
The table below shows structure of a data block, used by INT 21\AX=4B00h and INT 21\AX=4B01h functions (8.02-53) in order to load a program into memory for its further execution.

<ol> <li id="note-A.07-2-1">^ Whole environment of the parent process will be copied into this segment. If child process should be given access not to a copy, but to parent's environment itself, then the 0000h value should be assigned to a word at offset 00h in this data block.</li> <li id="note-A.07-2-2">^ Command line must include all what is to be written into PSP of the child process starting at offset 80h.<sup id="note-A.07-1-5-ref2">&#91;Note 5 to A.07-1&#93; Command line string must begin with a byte, specifying its length, and must end with byte 0Dh.</li> <li id="note-A.07-2-3">^ This data string will be copied into corresponding FCB block<sup id="note-A.07-1-4-ref2">&#91;Note 4 to A.07-1&#93; inside PSP for the child process. Required structure of this data string is shown in the "N" column of table A.09-5. First 12 bytes should be filled, then 4 bytes 00h must follow. If FCB should be left empty, then its first byte must be 00h, and then 11 bytes 20h must follow.</li> <li id="note-A.07-2-4">^ Double words at offsets 0Eh and 12h are returned by INT 21\AX=4B01h function only. This function loads a program, but doesn't initiate its execution. Returned stack top and entrance point enable to start execution of the loaded program later.</li> </ol>
 * Notes

A.07-3 Execution state descriptor
The table below shows data structure in execution state descriptor, used by INT 21\AX=4B05h function (8.02-54).

A.07-4 Data block for server function
As far as server function INT 21\AX=5D00h (8.02-68) enables to execute any INT 21 function as a separate process, this data block defines the states of all registers as required for execution of the selected function. Before this selected function is called for, all specified states will be copied from data block into registers automatically.

<ol> <li id="note-A.07-4-1">^ If selected function is to be executed under current MS-DOS 7, then the 0000h value should be specified as virtual machine identifier.</li> <li id="note-A.07-4-2">^ When this data block is used in order to close a process by means of INT 21\AX=5D01h function (8.02-69), then words at offsets 12h and 14h only are taken into account, all other words are ignored.</li> </ol>
 * Notes

A.07-5 Interrupt sharing protocol
Many drivers and TSR programs load their interrupt handlers and have to write address of this handler into a certain cell of interrupt table. However, this certain cell may be occupied yet by an address of another handler, which has been loaded beforehand. If new handler has to replace the former one, then a problem arises how to release memory, occupied by the former handler. If new handler complements functions of the former one, then a problem arises how to arrange their interaction. In both cases a solution is that each resident module must provide data, necessary for other resident modules, which may be loaded later.

The first step in arranging resident modules interaction was IBM's Interrupt Sharing Protocol (ISP), stipulating presence of 16-byte data block with fixed placement relative to call address for corresponding resident module. The ISP protocol enables to form a traceable chain of references to all the modules, sharing a common interrupt number. ISP protocol gives an opportunity to alter the order of references in the chain and to remove certain references from the chain. The latter is a necessary condition for unloading resident modules.

According to ISP protocol the call address, written into interrupt table, must point at a command of a short jump 16 bytes ahead, where executable code of resident module starts. The jumped over 16 bytes is just a place for data block. Structure of this data block is shown in the table below. All offsets in the table are counted from resident module's call address.

Note 1: many resident modules don't conform to ISP protocol. It may be intentionally ignored in order to prevent references chain tracing or resident module unloading.

A.07-6 Alternative Multiplex Interrupt Specification (AMIS)
Multiplex interrupt INT 2F, described in part 8.03, has a serious drawback: coincident identifiers sometimes are appointed to different TSR modules due to inconsistent decisions of their developers. In order to avoid such conflicts an idea has been suggested to assign identifiers not beforehand by the will of module's developers, but automatically just in course of module's loading. Authorship of this idea is known to belong to Ralf Brown. Idea has been institutionalized by Alternative Multiplex Interrupt Specification (AMIS) and has been implemented by multiplex interrupt INT 2D. Contents of this article are based on version 3.6 of AMIS specification. Besides that, each resident module using multiplex interrupt INT 2D must conform to IBM's Interrupt sharing protocol ISP (A.07-5).

According to AMIS specification an identifier for resident module should be searched in a cycle of calls for multiplex interrupt INT 2D with operation code AL = 00h and with successive incrementation of candidate identifiers in AH register, starting from AH = 00h. If anyone of loaded resident modules considers a particular candidate identifier in AH register as its own, it must set AL = FFh, must return in CH:CL registers its version number and must return in DX:DI registers a pointer to a signature up to 80 bytes long, ending with byte 00h. Search cycle should terminate on condition of returned zero value in AL register: it means that neither loaded resident module has appropriated the last specified candidate identifier. Hence, the latter is free, and current resident module can assign this identifier to itself.

A similar cycle, but with other termination condition, should be arranged in order to find out whether a particular resident module is loaded or not. For this purpose the main role belongs to signature, pointed at by address returned in DX:DI registers. 16 bytes of this signature must be sufficient for identification of resident module. First 8 bytes must specify company or developer's name, the following 8 bytes — a name of program or a driver, which has loaded the responding resident module. Abridged names are allowed. If a name is shorter than 8 bytes, it should be appended with spaces (bytes 20h). The rest part of signature beyond 16 bytes is optional, but it may specify version and other useful data. Signature check enables to prevent repetitive loading of the same resident modules. Search cycle for a signature check also reveals identifier, assigned to the requested resident module. When the identifier is known, then other functions of this resident module can be called for.

As far as calls for multiplex interrupt imply a search through a chain of references and are performed slowly, hence repetitive calls for module's specific functions via INT 2D are not expedient (though are allowed with operation codes above 10h). Direct addressing to module's functions with a CALL FAR command (7.03-08) is preferable. In order to obtain direct address, the INT 2D interrupt should be called once with operation code AL = 01h and with particular module's identifier in AH register. Address for direct calls, returned in DX:BX registers, should be saved, and then later more calls for multiplex interrupt wouldn't be needed.

Beside the mentioned operations with operation codes AL = 00h and AL = 01h, AMIS specification stipulates several other operations, listed in the table below. Unified codes of these operations, shown in the first column of the table, enable to apply identical services for all resident modules. Some operations are optional. If addressed resident module returns in AL register the status code value 00h, hence it doesn't support the requested operation. On the contrary, returned status code value FFh confirms that the requested operation is supported and is done successfully. Several operations may return other status code values, informing about specific features of resident module. These and some other peculiarities of AMIS operation execution are explained in notes after the following table.

<ol> <li id="note-A.07-6-1">^ Returned status value AL = 00h means that requested resident module can't be addressed with CALL FAR command. Validity of the address returned in DX:BX registers must be confirmed by returned status code value AL = FFh.</li> <li id="note-A.07-6-2">^ A request to uninstall resident module must supply in DX:BX registers an address for return after completion of uninstall operation, though resident module may ignore this address. Returned in AL register status code values (except 00h and FFh) have the following meaning :
 * 01 – uninstall attempt failure ;
 * 02 – uninstall operation will be completed later ;
 * 03 – module has no uninstaller and stays active ;
 * 04 – the same, as 03, but module is deactivated ;
 * 05 – uninstall attempt should be repeated later ;
 * 06 – module is deactivated, but can't be uninstalled ;
 * 07 – the same, as 03, plus driver unloading required.

Return of status code values 03, 04 or 07 means a necessity to launch a special uninstaller program. For this program the addressed resident module must return in BX register that segment address, where its executable code is loaded.</li> <li id="note-A.07-6-3">^ Returned in AL register status code values (except 00h and FFh) have the following meaning :
 * 01 – activation attempt should be repeated later ;
 * 02 – program will be activated later ;
 * 03 – program is active yet ;
 * 04 – activation attempt has failed.

After successful activation, confirmed by status code FFh, some programs may report extra information in BX register. After a failure, confirmed by status code 04h, extra information may be returned in BX and CX registers. If the cause of failure remains unknown, BX and CX registers should return zeros.</li> <li id="note-A.07-6-4">^ Requests for operation 04h must specify in BL register a number of that interrupt (except INT 2D), which is to be checked. Returned in AL register status code values (except 00h) have the following meaning :
 * 01 – check result can't be determined ;
 * 02 – specified interrupt has been intercepted ;
 * 03 – the same as 02 plus handler's address – in DX:BX ;
 * 04 – in DX:BX – pointer to a list of interceptions ;
 * FF – specified interrupt is not intercepted.

Status code value 04 means that interrupt number, specified in BL register, is ignored. Returned list is composed of 3-byte groups per each interrupt: the first byte, the interrupt number ; the following 2 bytes, the offset (inside DX segment) of that interrupt handler's entrance address. End of list is marked with code 2Dh in a place for interrupt number.</li> <li id="note-A.07-6-5">^ After successful outcome, confirmed by status code FFh, in DX:BX registers a pointer to a list of "hot" keys is returned. Structure of this list is described in appendix A.02-7.</li> <li id="note-A.07-6-6">^ Operation 06h returns in AL register number of drivers, installed by addressed resident module, and in DX:BX registers – a pointer to header of the first of these installed drivers (A.05-1). In AH register a byte of flags is returned; bits 3–7 in this byte are reserved and must be clear. Set state of the rest flags should be interpreted as follows:
 * bit 0 – drivers can't be unloaded from memory;
 * bit 1 – drivers are not included in DOS's drivers chain;
 * bit 2 – installed drivers are not reenterable.

If addressed TSR program didn't install drivers, it has to return AL = 00h value. On return the contents of AH, BX and DX registers may be arbitrary altered.</li> </ol>

A.08-1 Floppy drive's data in BIOS data area
The table presents that information in BIOS data area, which relates to floppy drive(s). All offsets are counted from segment address 0040h, i.e. from the start of BIOS data area.

<ol> <li id="note-A.08-1-1">Data placement in BIOS data area may depend on BIOS version (A.01-1).</li> <li id="note-A.08-1-2">^ Particular values of last error byte at offset 41h should be interpreted as it is shown in table A.06-1 for INT 13.</li> </ol>
 * Notes

A.08-2 Access and formatting parameters
Computer's BIOS system stores access and formatting parameters for each floppy disk drive in separate 11-byte tables. A pointer to such table for any particular floppy drive can be obtained with INT 13\AH=00h function (8.01-49). Besides that, one more similar 11-byte table is created for the default ("current") floppy drive; a pointer to the latter table is stored in a cell 0000:0078h (also known as INT 1E) inside interrupt table.

Access and formatting parameters can be changed by INT 13\AH=18h function (8.01-54), but the changes wouldn't come into effect until floppy controller is reset by a call for INT 13\AH=00h (8.01-44).

A.08-3 Floppy drive types registered by BIOS
BIOS Setup program stores data about registered floppy drives in a cell 10h of CMOS memory. In order to read these data the cell address 10h has to be sent with OUT command (7.03-66) into port 70h, and after that the required data byte can be read by IN command (7.03-26) from port 71h (more about that in note 1 to A.14-1 ). The required data byte occurs in AL register; bits 4–7 in that byte specify features of the first floppy drive, bits 0–3 specify features of the second floppy drive, if it exists. Hexadecimal values, expressed by each of these 4-bit groups, should be interpreted independently according to the table below.

A.09-1 Directory records and file's data
Data concerning files, volume labels and subdirectories are stored in corresponding directory records. Data structure in ordinary 32-byte directory record for an object with a "short" name is shown in the first column "D" of the table below. DOS's "find file" functions INT 21\AH=4E00h (8.02-57) and INT 21\AH=4Fh (8.02-58) read directory records and return the found data in DTA area (8.02-16); format of data, returned by these functions, is shown in second column "F4E" of the table below. Other "find file" functions INT 21\AH=11h (8.02-11) and INT 21\AH=12h (8.02-12) also return found data in DTA area, but in other formats. Third column "F1N" of the table below shows format of data, returned after a search request with normal FCB block (column "N" in appendix A.09-5). But when search request is presented in a form of extended FCB block (column "E" in appendix A.09-5), then the same functions return other data structure, which is shown in the fourth column "F1E" of the table below.

<ol> <li id="note-A.09-1-1">^ Search functions INT 21\AX=4E00h (8.02-57) and INT 21\AH=4Fh (8.02-58) return this byte with its 7th bit set, if disk is accessed via a network.</li> <li id="note-A.09-1-2">^ If object is created under DOS, then this data field is not filled. Copying procedures under DOS don't copy those data, which may be present in this field.</li> <li id="note-A.09-1-3">^ This data field is used by operating systems Windows-2000/XP, but the author has no information about role of these data.</li> <li id="note-A.09-1-4">^ Object's starting cluster number in FAT-16 volumes is a word at offset 1Ah; field at offset 14h is not used. But cluster number in FAT-32 volumes is a double word. The most significant two bytes of this double word are stored at offset 14h.</li> <li id="note-A.09-1-5">^ Search functions INT 21\AX=4E00h (8.02-57) and INT 21\AH=4Fh (8.02-58) don't overwrite name search template at offset 01h; actual name of the found object, ending with 00h byte, is returned at offset 1Eh.</li> </ol>
 * Notes

A.09-2 Structure of attribute byte
Attribute byte at offset 0Bh in a directory record (A.09-1) defines class of the object, associated with this record. Bitfields of attribute byte are explained in the table below.

Note 1: the 0Fh value of attribute byte is regarded as a signature of LFN directory records, associated with files having "long" names (A.09-3). Such records are formed by Windows-95/98/ME operating systems.

Note 2: states of bits 3 and 4 in attribute byte can't be changed by INT 21\AX=4301h function (8.02-39) or by ATTRIB.EXE utility (6.01).

Note 3: file search functions INT 21\AX=4E00h (8.02-57) and INT 21\AH=4Fh (8.02-58) ignore states of bits 0 and 5 in attribute byte.

Note 4: extended "file open" function INT 21\AX=6C00h (8.02-78) accepts in CX register an attribute word with clear bits 4 and 6-15. Role of other bits corresponds to that shown in table A.09-2.

A.09-3 Format of LFN directory records
Each "long" filename, accepted by Windows-95/98/ME operating systems, occupies at least several directory records of standard 32-byte size. Truncated version of "long" filename is stored in the last of these records; its structure corresponds to that shown in table A.09-1. But the rest records, associated with the same file, store unicode characters of "long" filename. These rest LFN records have other structure, shown in the table below.

<ol> <li id="note-A.09-3-1">^ The last LFN record, associated with the same "long" filename, is marked by set state of bit 6 in the first byte.</li> <li id="note-A.09-3-2">^ The short filename checksum byte is calculated by adding up the eleven bytes of the short filename, with rotating the intermediate sum right one bit before adding each next character byte.</li> </ol>
 * Notes

A.09-4 Bitfields of access and sharing byte
While preparing an object for access, the INT 21\AH=3Dh (8.02-33) and INT 21\AX=6C00h (8.02-78) functions accept a byte of access conditions. This byte is written into a cell at offset 02h in corresponding SFT entry (A.01-4). Role of bitfields in access and sharing conditions byte is shown in the table below.

Note 1: sharing conditions are ignored unless SHARE.EXE utility is loaded.

Note 2: previous versions of MS-DOS require clear state of bit 2.

A.09-5 Unopened file control blocks
File control block (FCB) is an obsolete form of object's properties specification. It gives no access to objects beyond current directory and to disks with FAT-32 file system. Nevertheless some functions employ partially filled (unopened) FCBs just as a template of specification for object's search, renaming and deletion. Unlike operations with completely filled (opened) FCB blocks, operations with unopened FCBs (INT 21\AH=11h, 12h, 13h, 17h) are still used and can be applied to objects in the current directory on disks with FAT-32 file system. Unopened FCB's data structure is shown in the table below.

In MS-DOS 7 two forms of FCB blocks are allowed: normal FCB blocks up to 36 bytes long and extended FCBs up to 43 bytes long. A distinctive feature of extended FCB is FFh value of its first byte. Normal FCB blocks define files only, except those having "Hidden" and "System" attributes. Extended FSBs include search attributes specification and therefore may be applied to different objects: files, volume labels and subdirectories. Both normal and extended FCBs may be completely filled (opened) and partially filled (unopened). Column "N" of the table below shows data structure in unopened normal FCB blocks, column "E" shows the same for unopened extended FCB blocks. Those FCB bytes, which are not shown in the table below, must have the 00h value.

<ol> <li id="note-A.09-5-1">^ In FCBs all characters of name and suffix must be in upper case. Name is appended with spaces (20h) to its nominal length 8 bytes, suffix is appended with spaces to its nominal length 3 bytes. If empty, both name and suffix fields must be filled with spaces. The mentioned and some other requirements to filling FCB fields can be met by means of INT 21\AH=29h function (8.02-19).</li> <li id="note-A.09-5-2">Being called for the first time, functions INT 21\AH=11h (8.02-11) and INT 21\AH=13h (8.02-13) require 00h values in all fields after offset 0Ch in normal FCB and after offset 13h in extended FCB. On return these fields contain data, which must be preserved intact from each previous search call to each next search call. In the same FCB fields the INT 21\AH=17h function (8.02-14) accepts new name for the renamed file, requiring buffer 28 bytes long for normal FCB and 35 bytes long for extended FCB.</li> <li id="note-A.09-5-3">Unopened FCB blocks are not subjected to restriction, imposed by FCBS command specification (4.10) in CONFIG.SYS file.</li> </ol>
 * Notes

A.09-6 Canonical structure of a CD directory record
High Sierra and ISO 9660 file systems implement slightly different data structures in CD directory records. Both these data structures can be translated by INT 2F\AX=150Fh function (8.03-19) to a common canonical form, which is shown below.

A.10-1 Selected videomodes
Videomodes define screen appearance. Both BIOS and DOS use textual videomodes : color videomode 03h or monochrome videomode 07h. Each program is allowed to set the most appropriate video mode, either textual or graphic.

Available videomodes depend on PC's hardware. During hardware evolution some videomodes have become common for the sake of compatibility. Later a subset of videomodes has acquired the status of a standard. The table below lists only those videomodes, which are almost certainly supported by any modern video card. Video cards with insufficient internal memory probably will not be able to support graphic videomodes with high resolution. Obsolete PC's produced before 1991 don't support SVGA videomodes at all.

EGA and VGA videomodes are defined by one-byte code, specified in the first column of the table below. These videomodes may be set by INT 10\AH=00h function (8.01-10).

SVGA video modes are defined by 2-byte hexadecimal code, which should be specified in BX register for INT 10\AX=4F02h function (8.01-37). The table below doesn't specify the most significant half-byte of SVGA videomode code, because this half-byte (bits 15–12) is charged with another mission. Its 12th and 13th bits must be cleared, the 14th bit enables linear frame buffer access, and the 15th bit forces to retain video memory contents. For example, you may specify BX=0102h, when you want video memory to be cleared, or BX=8102h if you want video memory contents to be preserved: in both cases you'll get the same videomode, which is specified as 102h in the first column of the table below. Codes of other SVGA videomodes are shown in the same way — without specification of the most significant half-byte. Codes of non-SVGA video modes may be specified for INT 10\AX=4F02h function in the least significant byte of BX register while its bits 15 and 14 are charged with the described missions, and bits 13–8 are made clear.

Monochrome videomodes, both textual and graphic, are marked in the second column of the table as "b/w" (instead of colors number).

Textual video modes are characterized in column 3 of the table below by number of characters in a row and by number of rows per screen height. For example, definition 80x25 means that you may address rows 0–24 and character cells 0–79 in each row. All listed textual modes accept 8x16 fonts.

Graphic modes are characterized by their resolution in pixels, shown in the 4th column. For example, resolution 640x480 means that you are allowed to address screen lines 0–479 and pixels 0–639 in each line.

The 5th column in the table shows video buffer starting address for those videomodes, which use fixed video buffer in UMB address space.

Note 1: position and size of video memory access "windows" in address space for SVGA videomodes may depend on PC's hardware. Video memory access parameters should be determined by call for INT 10\AX=4F01h function (8.01-36, A.10-7).

Note 2: when SVGA standard hasn't been adopted yet, then equivalent to SVGA's 102h videomode was 6Ah videomode (800x600x16). The 6Ah videomode still can be set by INT 10\AH=00h function (8.01-10).

Note 3: SVGA standard reserves BX=81FFh code for special video mode, enabling unlimited direct access to video memory.

A.10-2 Information about video adapter status
The table below shows structure of 64-byte data block, returned by INT 10\AH=1Bh function (8.01-34). This block presents information about current status of video adapter.

<ol> <li id="note-A.10-2-1">^ Number of active scan lines is defined by set state of one bit in a byte at offset 2Ah. Set state of bit 0, 1, 2, 3, 4, 5, 6 corresponds to numbers of lines 200, 350, 400, 480, 512, 600, 768.</li> <li id="note-A.10-2-2">^ Bits in flag's byte at offset 2Dh have the following meaning :
 * Notes
 * bit 0 – no restrictions on videomode choice
 * bit 1 – gray scale summing is on
 * bit 2 – monochrome display attached
 * bit 3 – default palette loading disabled
 * bit 4 – cursor emulation enabled
 * bit 5 – role of 7th bit in color byte (A.10-5)
 * bit 6 – 9-dot wide fonts are not supported

If 5th bit in flag's byte is cleared, then 7th bit in color byte defines brightness of background, otherwise it defines blinking.</li> </ol>

A.10-3 Format of static functionality table
Static functionality table informs about variety of capabilities, potentially supported by PC's video adapter. A pointer to static functionality table is returned by INT 10\AH=1Bh function (8.01-34) in current video adapter status table (A.10-2) at offset 00h.

A.10-4 BIOS information about SVGA extensions
The table below shows selected data from a data block 512 bytes long returned by INT 10\AX=4F00 function (8.01-35). These data characterize software supplied in fixed storage chip(s) of video adapter.

A.10-5 16-color codes
Though AT-compatible computer's hardware suggests a large variety of videomodes, the default videomode for both BIOS and MS-DOS 7 is a 16-color 80x25 textual videomode 03h. For this videomode and for all other 16-color videomodes (A.10-1) colors are defined by a 4-bit code, shown in the table below.

Color codes are used to compose color bytes, also known as display attribute bytes. Video memory in textual videomodes is filled with alternating color bytes and character bytes. In each color byte bits 3–0 define foreground (character's) color, and bits 6–4 define background color. By default the 7th bit defines character's blinking instead of background's brightness, but role of the 7th bit may be reprogrammed by INT 10\AX=1003h function (8.01-23), and then the most significant bits in both 4-bit groups will have the same mission. By default the 3rd bit defines foreground brightness, but this role also may be reprogrammed by INT 10\AX=1103h function (8.01-28), and then bit 3 will redirect character generator to another font block, thus enabling to display characters from two fonts at the same time.

A.10-6 Video data fields in BIOS data area
The table below shows those selected items in BIOS data area, which have relation to computer's video subsystem. All offsets in the table are counted from the start of BIOS data area (A.01-1) at segment address 0040h.

Note 1: presented data placement may depend on BIOS version (A.01-1).

A.10-7 Features of requested SVGA videomode
This table presents selected data from a 256-byte data block, returned by INT 10\AX=4F01 function (8.01-36) in response to a request about any SVGA videomode, supported by computer's hardware.

A.11-1 Hardware configuration word
Hardware configuration word is returned by INT 11 handler (8.01-42); it reads this word in BIOS data area (A.01-1) at address 0040:0010h (exact address may depend on BIOS version). Bifields in hardware configuration word should be interpreted according to the following table.

A.11-2 PC model identifiers for HIMEM.SYS driver
In order to enable access to computer's extended memory, HIMEM.SYS driver (5.04-01) has to determine CPU model. However, in some computers HIMEM.SYS can't determine CPU model properly, and then computer's identifier or its numeric code should be specified explicitly in driver's command line.

The table below presents identifiers and corresponding numeric codes for computers, which don't ensure CPU determination for at least some versions of HIMEM.SYS driver. The first place in this table (code 1) is an exception: IBM AT is a determinable model, it represents the default choice. Latest versions of HIMEM.SYS driver are able to detect properly most part of PC types, specified in this table, except Acer 1100, Wyse, and IBM 7552.

A.11-3 Keyboard controller
Keyboard controller is a chip on computer's motherboard. Though types of keyboard controllers may be different, their mission and their interface in all AT-compatible computers are unified. Main interaction between CPU and keyboard controller occurs via ports 60h and 64h.

Port 64h is always opened for reading keyboard controller's current status by IN command (7.03-26). Set state of bits in status byte, read from port 64h, should be interpreted as follows:
 * bit 7 – an error has occurred in data sent from keyboard
 * bit 6 – keyboard doesn't respond to controller
 * bit 4 – keyboard is blocked with ADh command
 * bit 2 – keyboard's self-test has been successful
 * bit 1 – previous operation isn't completed yet
 * bit 0 – a key code is prepared for reading in port 60h

At each keystroke and at each key release keyboard controller exhibits transformed key code in port 60h and just after that announces its readiness for reading via bit 0 in port 64h and via bit 4 of controller's output line.<sup id="note-A.11-3-1-ref1">&#91;Note 1&#93; The latter signal invokes INT 09 handler (8.01-09), which reads the prepared byte from port 60h. Each reading access to port 60h clears bit 0 in port 64h.

Besides that, port 64h receives operation codes, sent to keyboard controller with OUT command (7.03-66). As far as keyboard controller is much slower, than CPU, before sending an operation code the CPU must wait until bit 1 will be cleared in status byte, read from the same port 64h: it will signify that the keyboard controller has finished its previous operation and is ready to receive the next operation code for execution. Codes of some important operations, which may be sent to keyboard controller's port 64h, are shown in the table below.

<ol> <li id="note-A.11-3-1">^ a b Having received operation code D1h via port 64h, keyboard controller begins to wait for reception of data byte via port 60h and then transfers the received data byte to its output bus. Bits of data byte are distributed among output bus lines in the following way:
 * Notes
 * bit 7 – command output to keyboard via data line;
 * bit 6 – clock output to keyboard via clock line;
 * bit 4 – a call for INT 09 (8.01-09) via line IRQ 1;
 * bit 1 – to gate of CPU's address line A20;
 * bit 0 – to CPU's reset pin.

Active state of controller's output lines corresponds to cleared states of bits in data byte; hence, sending a data byte with clear bit 0 is not allowed – CPU will get blocked. Because of the same reason for opening A20 line gate a data byte FFh should be sent to port 60h, and for closing access to HMA – data byte FDh.</li> <li id="note-A.11-3-2">^ Having received operation code EDh via port 64h, keyboard controller begins to wait for reception of data byte via port 60h and then transfers bit states of the received data byte to control lines of keyboard's LED indicators, in particular :
 * bit 2 – to Caps Lock indicator;
 * bit 1 – to Num Lock indicator;
 * bit 0 – to Scroll Lock indicator.

Indicator will be lit, if corresponding bit in data byte is set. Not mentioned bits in this data byte must be cleared.</li> <li id="note-A.11-3-3">^ Having received operation codes F0h–FFh via port 64h, keyboard controller sends four least significant bits of this operation code to lines 3–0 of its output bus. Unlike to response on reception of operation code D1h, after reception of operation codes F0h–FFh the imposed states of output lines are not fixed for ever, but are kept for about 6 milliseconds as a solitary pulse. In particular, operation code FEh causes a pulse sent to CPU's reset pin, just as after a press on RESET button on a face panel of computer's system block. Some ways to affect further events after CPU's reset are described in &#91;Note 4 to A.12-1&#93; .</li> </ol>

A.11-4. CPU's flags register
Former 16-bit flags register in modern processors, starting from model 80386, has been expanded to 32 bits; besides that, control registers CR0, CR2 and CR3 have been introduced. Later, starting from Pentium CPU, one more control register CR4 has been added. Flags are present in all of the mentioned control registers, except CR2: it stores linear address of that last command, which requested access to a forbidden memory page. Missions of flags in flags register, and also of some flags in control registers are shown in the table below.

<ol> <li id="note-A.11-4-1">^ Mission and states of this flag are described in article 6.05-15.</li> <li id="note-A.11-4-2">^ Bits 0Ch and 0Dh in flags register express required privilege level for performing I/O operations. By default under DOS both bits 0Ch and 0Dh are set: hence, direct I/O operations are allowed for all processes. But only processes with the highest (zero) privilege level are allowed to alter states of 0Ch and 0Dh bits with POPF command (7.03-68). The latter feature enables to determine whether the current process indeed is performed at the highest privilege level.</li> <li id="note-A.11-4-3">^ Flags register enables to perform a coarse identification of CPU type. Inability to clear the 0Fh flag is a distinctive feature of obsolete 8086 CPU. Inability to set the 0Eh flag is specific for 16-bit processors. If CPU is able to set the 0Eh flag, hence it is a 32-bit CPU and is equipped with extended EFLAGS register. In the latter case bit 15 in EFLAGS register will show, whether this CPU is able to respond properly to CPU identification command (CPUID, machine code 0Fh A2h)</li> <li id="note-A.11-4-4">^ a b c EFLAGS is a 32-bit extension of 16-bit flags register. In real mode access to EFLAGS's bits 31–16 can be provided by PUSHF and POPF commands, preceded by prefix 66h, as it is described in article 7.02-06.</li> <li id="note-A.11-4-5">^ An opportunity to set V86 mode with POPF command is blocked by hardware. Nevertheless V86 mode can be set from stack with IRET command, if CPU is in protected mode and if at the same time the 06 bit in segment descriptor allows 32-bit addressing (A.12-2).</li> <li id="note-A.11-4-6">^ Here alignment implies that address of each operand in memory must be a multiple of this operand's size (in bytes). Alignment check can be performed at the lowest (the third) privilege level only, when CPU is in protected mode (note 1 to 8.01-42). Alignment mask bit in CR0 enables alignment exceptions even if these are not enabled by AC flag in EFLAGS register.</li> <li id="note-A.11-4-7">^ Control registers can be accessed with MOV command (note 1 to 7.03-58). Besides that, contents of CR0 register can be read by INT 67\AX=DE07h function (8.03-72).</li> <li id="note-A.11-4-8">^ Bit 10h is used in order to protect application programs segments from being accessed for writing to operating system or to other processes, which may have higher privilege level.</li> <li id="note-A.11-4-9">^ 20 most significant bits of CR3 register store base address of page directory. This base address must be a multiple of page size (normally 4 kb). Each writing operation to CR3 register causes updating of TLB buffer contents; this should be done after every change in page address translation table(s).</li> </ol>
 * Notes

A.11-5 CPU's debugging registers
Debugging registers enable to call for INT 01 handler (8.01-02) each time a particular target is addressed: a port or a prescribed memory region, including non-writable regions of address space, where breakpoints can't be stored. All modern processors of x86 platform, starting from model 80386, are equipped with debugging registers DR0–DR7. Access to debugging registers is provided by INT 67\AX=DE08h-DE09h functions (8.03-73), and also by MOV command (note 1 to 7.03-58).

Registers DR0–DR3 store four 32-bit absolute linear addresses of prescribed target points. The DR7 register defines conditions of access event enrolment. The DR6 register stores some circumstances of happened access event (programmable and external interrupts don't affect DR6 contents). Missions of selected bitfields in DR6 and DR7 registers are shown in the following table.

<ol> <li id="note-A.11-5-1">^ Access event is fixed in bits 01h–03h of DR6 register even when exception generation is not permitted by bit 0Dh in DR7 register or by bit 10h in EFLAGS register (A.11-4). Bit 0Eh in DR6 register fixes state of TF flag at the moment of access event ; bit 0Fh, the state of task switch. Set state of bit 0Dh in DR6 register reminds that exception hasn't been generated yet, though access event has happened (bit 0Dh is cleared by exception).</li> <li id="note-A.11-5-2">^ Permission field defines either local or global permission to enroll access events. The first of bits in permission field acts locally within current task only and is turned off at each task change. The second bit in permission field is imparted with global property and enables to enroll access events beyond the current task.</li> <li id="note-A.11-5-3">^ Bit 0Dh in DR7 register doesn't affect access event enrolment, but rather allows exception generation, caused by access event. State of 0Dh bit in DR7 can't be changed unless the process either has the highest privilege level or is executed in real mode.</li> <li id="note-A.11-5-4">^ The first pair of bits in each control field defines purpose of those access events, which should be intercepted :
 * Notes
 * 00 – attempt to execute machine code
 * 01 – attempt of writing into memory
 * 10 – I/O address to a port (for CPUs Pentium+)
 * 11 – both reading and writing attempts.

The second pair of bits in each control field defines size of the monitored address space: a byte, a word or a double word. Attempt of access to either byte within monitored address space is equally enrolled as access event.</li> </ol>

A.12-1 General memory map
This table shows general allocation of memory space below 1 Mb, typical for AT-compatible computers, controlled by DOS operating system. However, memory allocation depends on BIOS version, on BIOS Setup settings, on particular computer's configuration. Therefore some features of memory allocation in your computer may differ from those shown below.

<ol> <li id="note-A.12-1-1">^ The 640 kb boundary of conventional memory is hardware defined by dynamic memory controller chip in motherboard's chipset. Above this boundary the next 384 kb of address space are reserved for video memory and for BIOS ROM chips. Free space in this area normally is made accessible in protected mode due to address translation mechanism in CPU.</li> <li id="note-A.12-1-2">^ a b Address space area A000:0000–B000:FFFF provides access to video memory. Particular usage of this area depends on videomode (A.10-1). SVGA BIOS of modern video adapters arranges in this area one or two "sliding" windows, providing "sliding" access to selected part(s) of large video memory (details in section 8.01-39).</li> <li id="note-A.12-1-3">^ a b Access via the same areas of address space may be arranged either directly to BIOS and video BIOS codes in ROM chips or to copies of these codes in a more fast RAM. A choice of a particular alternative depends on "shadowing" parameters settings for corresponding memory areas, set by BIOS Setup program.</li> <li id="note-A.12-1-4">^ a b c d e Reset program's entrance point address F000:FFF0h is hardware defined by CPU : at power-on the initial state of its address bus is just FFFF0h. Further booting process depends on value written in byte 0Fh in BIOS's CMOS RAM<sup id="note-A.14-1-1-ref3">&#91;Note 1 to A.14-1&#93; :
 * Notes
 * 00h – ordinary booting with POST test
 * 04h – reboot with a call for INT 19 (8.01-90)
 * 05h – reset and jump to address in 0040:0067 cell (A.01-1)
 * 0Ah – jump to address prepared in 0040:0067 cell (A.01-1)

Unlike booting after power-on, POST test after reboot depends on a word at address 0040:0072h.<sup id="note-A.01-1-1-ref2">&#91;Note 1 to A.01-1&#93; Alternatives 05h and 0Ah are used after reboot only and differ in that whether interrupt controller will be reset or not.</li> <li id="note-A.12-1-5">^ High memory area is accessed, when segment address summation with offset produces a carry bit, directed into A20 line of address bus. High memory area is accessible in real mode, but needs HIMEM.SYS driver (5.04-01) to be installed, which provides control over A20 line gate.</li> <li id="note-A.12-1-6">^ The 0050:0040–0050:00FB area stores copies of selected interrupt handler's addresses (INT 00 – INT 1F, INT 40 – INT 43, INT 46, INT 70 – INT 77), prepared by BIOS for subsequent loading of operating system. In main interrupt table these addresses may be overwritten by addresses of other handlers, installed later either by MS-DOS 7 itself, or by TSR programs, or by drivers.</li> </ol>

A.12-2 Segment descriptors
Segment boundaries and access rights in protected mode are defined by segment descriptors. A number of most important segment descriptors constitute global descriptor table (GDT). CPU transition to protected mode implies presence of a GDT, at least partially prepared beforehand, while CPU is in real mode. Order and selection of descriptors in the prepared GDT depend on requirements of that procedure, which should control CPU transition to protected mode.

Examples of GDT tables for different procedures are shown in articles 8.01-76, 8.01-78 and 9.10-01. In all GDT tables the first descriptor must be filled with zeros: it is a template for non-requested segments and memory pages. All descriptors have the same internal structure, shown in the following table. Least

<ol> <li id="note-A.12-2-1">^ Bytes 06h and 07h of segment descriptor are taken into account by CPU models 80386 and higher. If program is expected to be executed by CPU 80286, then bytes 06h and 07h must be cleared. Zero values of bytes 06h and 07h are a distinctive feature of protected mode 16-bit programs, enabling their proper execution by 32-bit CPU models.</li> <li id="note-A.12-2-2">^ Interpretation of bits 0–3 in access rights byte depends on bit 4. The shown interpretation of bits 0–3 relates to application programs, including their data segments and executable code segments. In system descriptors bits 0–3 define 16 types of different descriptor's subtypes.</li> <li id="note-A.12-2-3">^ Interpretation of bit 2 in access rights byte depends on bit 3. In code segments cleared state of bit 2 means that code can be executed by programs of the same privilege level (otherwise code also can be executed by programs having higher privilege level). For data segments cleared state of bit 2 means normal expansion direction upwards, whereas set state of bit 2 means reverse expansion direction — downwards, as used in stack segments.</li> <li id="note-A.12-2-4">^ Bit 4 in byte 06h is available to programmer's regulation. In memory page descriptors this bit is used as a redefinition ban mark, for example, for mapping I/O address space into memory.</li> <li id="note-A.12-2-5">^ a b c d Size bit 6 in byte 06h of code segment descriptors defines sizes of both addresses and operands. In system segments, bits 4–6 of byte 06h must be cleared.</li> </ol>
 * Notes

A.12-3 Selected subfunctions of XMS-driver
XMS subfunctions are performed by extended memory driver HIMEM.SYS (5.04-01). Before these subfunctions can be used, two preliminary operations have to be done. First is to check with INT 2F\AX=4300h function (8.03-22) whether HIMEM.SYS driver is installed. The second operation is to find out with INT 2F\AX=4310h function (8.03-23) an address of XMS driver's entrance point. Returned double-word address should be specified for a CALL FAR command (7.03-08). On call the subfunction to be executed is defined by value in AX register, shown in the first column of the table below. DX register's mission is shown in second column, returned AX contents – in the fourth column. If AX returns status, AX=0001h means success, AX=0000h means failure. In case of failure, almost all subfunctions (except AH=00h) return error code (A.06-1) in BL register. Query subfunctions AH=08h and AH=88h return error code in BL register in any case.

<ol> <li id="note-A.12-3-1">^ This subfunction returns status of HMA area in DX register: DX=0001h signifies that HMA area is in use, DX=0000h – that HMA area is not used.</li> <li id="note-A.12-3-2">^ On call subfunction 08h needs BL=00h. On return size of free XMS memory (in kilobytes) is reported in DX register, and size of the largest available XMSmemory block is reported in AX register. The 88h subfunction does the same, but returns similar results in 32-bit registers EDX and EAX. Besides that, subfunction 88h in ECX register returns maximum physical address, corresponding to furthermost available byte of XMS-memory.</li> <li id="note-A.12-3-3">^ Both 09h and 89h subfunctions accept requested size of XMS-memory block in kilobytes, but 09h subfunction accepts requested size from DX register, whereas 89h subfunction accepts requested size from 32-bit EDX register. Both 09h and 89h subfunctions return a handle for allotted XMS-memory block in DX register.</li> <li id="note-A.12-3-4">^ In case of success registers DX:BX return 32-bit physical address of that memory block, which has been locked.</li> <li id="note-A.12-3-5">^ The 0Eh subfunction returns in BH register a number of lock counts for the requested XMS block, in BL register – number of free handles, in DX register – size in kilobytes of XMS block, opened for access by the specified handle. The 8Eh subfunction does the same, but returns number of free handles in CX register, and size of XMS block – in EDX register.</li> <li id="note-A.12-3-6">^ a b Resizing subfunction 0Fh accepts new size (in kilobytes) for the requested memory block from BX register. The 8Fh subfunction does the same, but accepts new size from EBX register. Requested memory block must not be locked.</li> <li id="note-A.12-3-7">^ For CPU models 80386 and higher the 10h–12h subfunctions usually are implemented by means of address translation in CPU's TLB buffer. Therefore execution of these subfunctions is relegated to EMM386.EXE driver (5.04-02), which arranges address translation and intercepts address of direct calls for HIMEM.SYS driver. However, subfunctions 10h–12h don't necessarily require switching CPU to protected mode and can be implemented in real mode by UMBPCI.SYS driver (5.04-04).</li> <li id="note-A.12-3-8">^ Both 10h and 12h subfunctions operate with UMB block size specifications in 16-byte units (paragraphs). Resizing subfunction 12h accepts requested new size from BX register. Allocation subfunction 10h in case of successful termination returns segment address of UMB block in BX register, and actual size of UMB block &mdash; in DX register. In case of a failure, marked by AX=0000h value, both 10h and 12h subfunctions return size of the largest available UMB block in DX register.</li> <li id="note-A.12-3-9">^ Unlike 0xh subfunctions, the 8xh subfunctions can't be implemented by obsolete 16-bit processors and require HIMEM.SYS driver's version not less than 3.07.</li> </ol>
 * Notes

A.12-4 Format of XMS copy request
A pointer to this request data block is accepted from DS:SI registers by subfunction AH = 0Bh (A.12-3) of XMS driver HIMEM.SYS (5.04-01). Subfunction AH = 0Bh copies a group of bytes from one XMS block, addressed via source handle, to another XMS block, addressed via destination handle.

Note 1: if source and destination overlap, only forward copying (source base less than destination base) is guaranteed to work properly.

Note 2: if either handle in the request is 0000h, then the corresponding offset double-word is interpreted as ordinary address (segment: offset) inside directly addressable conventional memory.

A.12-5 Format of EMS copy descriptor
EMS copy descriptor specifies source and destination for copying and exchange functions INT 67\AX=5700h-5701h (8.03-69), performed by EMM386.EXE driver (5.04-02). Both source and destination may belong either to EMS memory page(s) or to conventional memory. In the latter case 0000h value should be written instead of corresponding handle number, and location should be specified by segment address in place of EMS logical page number.

Note 1: for move operation the source and destination may overlap, but then only one direction of copying provides proper result.

A.12-6 Data block for jumps inside EMS memory
The shown data block specifies parameters of a call for subroutine inside EMS memory, performed by INT 67\AH=56h function (8.03-68) of EMM386.EXE driver (5.04-02). A far jump operation inside EMS memory, performed by INT 67\AH=55h function (8.03-68), uses a part of the shown data block up to offset 09h.

Note 1: internal structure of page mapping lists is described in note 3 to article 8.03-66. Data about current page mapping list, which is to be replaced, are needed for return to current program execution when subroutine's execution terminates.

A.12-7 Memory control descriptors
Computer's memory allocation is a prerogative of operating system. Each memory block, allotted by DOS, is preceded by a 16 bytes long memory control descriptor. These descriptors are also known as MCB (Memory Control Blocks). MCBs are easy to find: segment address of MCB descriptor is always a unity less, than segment address of allotted memory block, associated with this MCB descriptor.

DOS traces the whole available memory via a chain of MCB descriptors.<sup id="note-A.12-7-3-ref1">&#91;Note 3&#93; Free memory space beyond the allocated memory areas is considered by DOS as a separate memory block: it also must be preceded by MCB descriptor. A distinctive feature of MCB descriptor(s), associated with free memory space(s), is code 0000h instead of segment address of the owner program. All data about available free memory and about disposition of particular free memory areas DOS acquires from a traceable chain of MCB descriptors.

Data structure inside a MCB descriptor is shown in the following table.

<ol> <li id="note-A.12-7-1">^ Memory block with main DOS's system data is divided into subblocks, each having its own MCB descriptor, but with other identifiers in a byte at offset 00h :
 * Notes
 * 42h (= B) – subblock with buffers (4.03)
 * 44h (= D) – subblock for DOS's drivers
 * 45h (= E) – data subblock for DOS's drivers
 * 46h (= F) – subbblock with SFT table (4.12)
 * 49h (= I) – subblock for IFS data
 * 4Ch (= L) – subblock with CDS table (4.17)
 * 53h (= S) – subblock for DOS's stacks (4.27)
 * 54h (= T) – subblock for transition code(s)
 * 58h (= X) – subblock for FCBS (4.10)</li>

<li id="note-A.12-7-2">^ If associated memory space is free, then in MCB descriptor a word at offset 01h is filled with zeros. If associated memory block is allocated by DOS to itself, then code 0008h is written in a word at offset 01h instead of segment address of the owner program.</li> <li id="note-A.12-7-3">a b Size of associated memory block is specified in 16-byte units (paragraphs). Segment address of each next MCB descriptor is a unity greater than a sum of a number, specified at offset 03h in current MCB descriptor, with segment address of current MCB descriptor. On basis of this formula DOS traces a chain of MCB descriptors. Tracing starts from the first MCB descriptor; segment address of this first MCB descriptor is stored in a word just preceding DOS's List-of-Lists. This word is marked in table A.01-2 as having offset &minus;02h.</li> <li id="note-A.12-7-4">^ Name of program's file is specified in those MCB descriptors, which are associated with PSP memory blocks, with driver's subblocks and with IFS subblocks. At offset 08h in several other MCB descriptors there are signatures with the following meaning :
 * SC – associated block contains DOS's executable code;
 * SD – associated block contains DOS's data;
 * SM – associated block is the last in UMB area;
 * UMB – associated block is the first in UMB area.

Bytes 08h–0Fh in MCB descriptors, associated with other memory blocks, are not used and may contain "garbage".</li> <li id="note-A.12-7-5">^ Program files with *.COM suffix have no headers, which specify the required memory space for other types of executable files. This is why for programs with *.COM suffix DOS allocates the whole free memory space, following previously allocated memory areas. When DOS has no more free memory space, then computer may get hanged at each next request for memory space, which may come from unexpectedly activated resident program of from a handler, invoked by external interrupt. In order to avoid a threat of hanging the programs with *.COM suffix must call for INT 21\AH=4Ah function (8.02-52), forming a separate MCB descriptor for unused part of memory and thus announcing it free. Examples of such calls are shown in the first 6 lines of assembler texts in articles 9.06, 9.10-01 and 9.10-02.</li> </ol>

A.13-1 BIOS tables of physical HDD parameters
BIOS systems in obsolete computers, produced before 1996, addressed HDDs with parameters CHS (Cylinder-Head-Sector). HDD's storage space, available for CHS addressing, is limited to 528 Mb. BIOS system stored CHS parameters of first and second physical HDDs in data tables; addresses of these tables were written in memory cells 0000:0104h and 0000:0118h correspondingly. Both these cells are inside interrupt table (A.12-1) and sometimes are referred to as INT 41 and INT 46. If computer was equipped with more than two HDDs, then the only way to obtain CHS parameters of the rest HDDs was a call for INT 13\AH=08h function (8.01-49).

In 1995 capacities of HDDs have reached 1 Gb. The 528 Mb limit, inherent to CHS addressing, had to be overcame. For newer BIOS systems LBA addressing<sup id="note-A.13-6-4-ref2">&#91;Note 4 to A.13-6&#93; and extended INT 13 functions (8.01-55 – 8.01-60) have been developed. But compatibility with former programs had to be preserved. Therefore in newer BIOS systems the INT 13\AH=08h function (8.01-49) has been "taught" to yield not the real, but transformed CHS parameters. When programs call for "old" INT 13 functions (8.01-46 – 8.01-54) and specify transformed CHS parameters, then BIOS system automatically performs reverse transformation so that HDD's storage space, available for CHS addressing, is expanded to 8.4 Gb (some detail in note 2 to A.13-6 ).

Data blocks, addressed by pointers stored in cells 0000:0104h and 0000:0118h, may have different data structures: it depends on whether there are real or transformed CHS parameters. Both kinds of data structures are shown in the table below. Real data offsets are shown in the first column (Std). Offsets in the second column (Trs) correspond to transformed CHS data, conforming to Phoenix-1995 specification for HDDs with more than 1024 cylinders. Though described data blocks are supported by modern BIOS systems, nevertheless for programs being developed now usage of parameters from these data blocks is not recommended.

<ol> <li id="note-A.13-1-1">^ CHS parameters in these positions are for "old" functions of INT 13 handler (8.01-46 – 8.01-54). Nevertheless there are some BIOS versions, which specify in these positions a number of cylinders exceeding 1024, inadmissible for "old" functions.</li> <li id="note-A.13-1-2">^ These positions are filled with real HDD's parameters for programs, appealing not to INT 13 handler, but directly to HDD controller's port. These positions are not filled in those data blocks, which supply real parameters for "old" functions of INT 13 handler.</li> <li id="note-A.13-1-3">^ Modern disk drives perform landing and write precompensation independently. Attempts to affect these operations are ignored.</li> <li id="note-A.13-1-4">^ The track number, where surface defect map is written, is usually a unit greater than the number of cylinders, specified at offset 00h in BIOS tables of physical HDD's parameters.</li> </ol>
 * Notes

A.13-2 Extended table of HDD's parameters
Extended table of HDD's parameters is written into a prepared buffer by INT 13\AH=48h function (8.01-60).

<ol> <li id="note-A.13-2-1">^ Valid numbers of tracks, cylinders and heads are counted from zero, therefore the last valid number is a unity less than the value specified in this field. A value in this field is a real value. Therefore this value shouldn't be specified in calls for "old" INT 13 functions: these functions require transformed parameters, returned by INT 13\AH=08h function (8.01-49).</li> <li id="note-A.13-2-2">^ BIOS INT 13 extensions below version 2.x don't return DPTE table, and fill DPTE pointer field with FFFFh:FFFFh value. Structure of DPTE table is shown in appendix A.13-3. DPTE table is presented in a temporary buffer; its contents are not preserved after next calls for BIOS functions.</li> <li id="note-A.13-2-3">^ Interface type field may be filled with the following words: 1394, ATA, ATAPI, SCSI, USB. Words are appended with spaces up to nominal field length 8 bytes.</li> <li id="note-A.13-2-4">^ For ISA bus the path field contains a 2-byte base I/O port address, bytes at offsets 32h–37h are zeros. For PCI bus a byte at offset 30h presents bus number ; byte at offset 31h, slot number ; byte at offset 32h, function number ; byte at offset 33h, controller number ; bytes at offsets 34h–37h are zeros.</li> <li id="note-A.13-2-5">^ For 1394 (Firewire) interface a 8-byte extended unique identifier (EUI-64) is specified at offset 38h. For ATA (IDE) interface the 00h value at offset 38h signifies master device, the 01h value at offset 38h signifies slave device. Byte at offset 38h has the same meaning for ATAPI interface, but byte at offset 39h represents logical unit number (LUN). For SCSI interface a 2-byte device identifier (SCSI ID) is specified starting at offset 38h, and a 8-byte logical unit number (LUN) is specified starting at offset 3Ah. For USB interface a 8-byte serial number is written starting at offset 38h. Not mentioned bytes at offsets 3Ah–48h are reserved and must be cleared.</li> </ol>
 * Notes

A.13-3 Auxiliary device parameters table DPTE
BIOS INT 13 version 2.0 and higher supplement extended HDD's parameters table (A.13-2) with auxiliary device parameters table DPTE. A pointer to DPTE table is returned by INT 13\AH=48h function (8.01-60) at offset 1Ah inside extended HDD's parameters table (A.13-2). DPTE address points at a temporary buffer, which doesn't preserve its contents after following BIOS functions calls. Data in DPTE table are consigned for those programs, which intend to appeal directly to ports of HDD controller. DPTE data structure is shown in the table below.

A.13-4 Disk address packet
This form of data packet is used by extended reading function INT 13\AH=42h (8.01-56) and by extended writing function INT 13\AH=43h (8.01-57). Before applying these functions a check for their BIOS support should be made with a call for INT 13\AH=41h (8.01-55).

<ol> <li id="note-A.13-4-1">^ If extended disk address packet is supported, then size is 20h, otherwise size is 10h. Set state of bit 3 in CX register, returned by INT 13\AH=41h function (8.01-55), signifies that extended disk address packet is supported.</li> <li id="note-A.13-4-2">^ If extended disk address packet is supported, and if the FFh value is written into a byte at offset 02h, then number of blocks to transfer will be read from a quad word at offset 18h. On return this number at offset 18h is replaced with number of blocks, which actually have been transferred.</li> <li id="note-A.13-4-3">^ If extended disk address packet is supported, and if FFFF:FFFFh value is written into a double word at offset 04h, then pointer to data buffer will be read from a quad word at offset 10h.</li> <li id="note-A.13-4-4">^ For disk drives, not supporting LBA addressing,<sup id="note-A.13-6-4-ref3">&#91;Note 4 to A.13-6&#93; absolute number of starting block is calculated according to formula
 * Notes
 * (C&times;N + H)&times;T + S &minus; 1

where: C – number of the selected cylinder, N – number of heads (by 1 greater than maximum head number), H – number of the selected head, T – number of sectors per track, S – number of the selected sector on a track.</li> </ol>

A.13-5 HDD's partition descriptors
In sector 01h of bootable physical HDD's head 00 cylinder 00 is the master boot record (MBR), containing up to 446 bytes of executable code, 4-byte identifier (at offsets 1B8h–1BBh) and partition table. Identifier is written by operating systems Windows-NT/2000/XP only and may be absent. In order to view MBR sector it should be copied into a file, as it is explained in article 9.02-02. Non-textual file can be opened by a viewer of Volkov Commander file manager (6.25) or else by debugger DEBUG.EXE (6.05). Fig.12 shows fragments of MBR sector, copied from a real physical disk.

The first fragment presents starting part of executable code (proprietary OnTrack's MBR version). The second fragment presents final part of that executable code with a prepared error message. The third fragment presents partition table, defining division of HDD's writable surface into partitions in a particular computer.

Partition table consists of 4 partition descriptors, each 16 bytes long. If offsets are counted from start of MBR sector, then partition descriptor's offsets are 1BEh, 1CEh, 1DEh, 1EEh correspondingly. However, MBR sector's copy, shown in fig.12, is loaded from offset 100h and on; therefore in fig.12 partition descriptor's offsets are 2BEh, 2CEh, 2DEh, 2EEh. The last word in MBR sector is a signature AA55h, marking the end of bootable disk's MBR.

Four partition descriptors enable to create up to four primary partitions in any physical HDD drive. If there is less than 4 partitions, the rest descriptors are filled with zeros. In fig.12 the first descriptor in partition table is filled with zeros. Hence, this particular HDD is divided into three valid primary partitions.

On a bootable HDD one primary partition must be marked as active (potentially bootable) with a 80h mark in the first descriptor's byte. In fig.12 the 80h mark is present at offset 02CEh, which is the first byte of the second partition descriptor. Hence, active partition in this particular HDD is the second partition.

Missions of the mentioned and of other bytes in partition descriptors are shown in the table below. Offsets in the first column of the table are counted from the start of each partition descriptor.

<ol> <li id="note-A.13-5-1">^ In a byte at offset 02h bits 5–0 express number of partition's first sector on a track, but bits 6 and 7 represent most significant bits of partition's 10-bit first track number. 8 least significant bits of partition's 10-bit first track number are stored in a byte at offset 03h.</li> <li id="note-A.13-5-2">^ In a byte at offset 06h bits 5–0 express number of partition's last sector on a track, but bits 6 and 7 represent most significant bits of partition's 10-bit last track number. 8 least significant bits of partition's 10-bit last track number are stored in a byte at offset 07h.</li> <li id="note-A.13-5-3">Descriptors to partitions with LBA addressing<sup id="note-A.13-6-4-ref4">&#91;Note 4 to A.13-6&#93; may contain invalid CHS parameters (numbers of tracks, heads and sectors). Nevertheless data in bytes at offsets 08h–0Fh must be valid.</li> </ol>
 * Notes

A.13-6 Selected file system identifiers
In each partition descriptor (A.13-5) a byte at offset 04h is file system identifier. Operating system reads file system identifier and "decides" whether it can ensure access to this partition. If file system identifier is not "known" to operating system, then access to this partition will not be attempted. Most probably such partition even wouldn't be shown to user. Some file system identifiers denote hidden partitions, which can be accessed for system purposes, but stay hidden for the user. The table below presents interpretation of selected file system identifiers.

<ol> <li id="note-A.13-6-1">^ Extended partition is a formal specification of disk's space for placement of several non-primary partitions (logical disks). Descriptors of non-primary partitions are written not in MBR, but in separate dedicated sectors, traced via a chain of references. MS-DOS doesn't allow this chain to be closed in a loop, otherwise MS-DOS hangs in infinite cycle of finding the end of this loop.</li> <li id="note-A.13-6-2">a b As far as parameters CHS (Cylinder-Head-Sector) occupy 3 bytes in partition descriptors (A.13-5), hence CHS parameters enable to address not more than 2^24 sectors 512 bytes each, equivalent to 2^23 kilobytes, or else 8 Gb. Therefore partitions with CHS addressing can't be arranged beyond first 8 Gb, counted from the start of disk's space (LBA addressing should be applied further). In table A.13-6 those only identifiers are marked with CHS, which are used as distinctive features of CHS addressing.</li> <li id="note-A.13-6-3">^ The 07h file system identifier is interpreted by Microsoft as belonging to installable file systems (IFS), file systems with transformed presentation to the user. But in fact, besides NTFS, only one rarely used IBM's HPFS file system is marked with 07h identifier.</li> <li id="note-A.13-6-4">^ a b c d e f Linear Block Addressing (LBA) is based on sectors count from start of disk's space according to data in bytes 08h–0Fh in partition descriptors (A.13-5). LBA enables to overcome the 8 Gb boundary, inherent to CHS addressing. LBA requires support for extended functions of INT 13 handler (8.01-55) from both disk drive and BIOS system. All modern computers provide such support.</li> <li id="note-A.13-6-5">^ Data about partitions GPT (= GUID Partition Table) constitute extended MBR, occupying not a single sector, but a considerable part of disk's first track. Only 64-bit versions of operating systems Windows server 2003, Windows XP and Windows Vista provide support for GPT partitions.</li> <li id="note-A.13-6-6">As far as it is known, partition identifiers 21, 23, 26, 31, 33, 34, 36, 71, 73, 74, 76, 86, A1, A3, A4, A6, B1, B3, B4, B6, E5, E6, F3, F6 are reserved and are not used yet.</li> </ol>
 * Notes

A.13-7 Disk's free space table
This table with data about logical disk's free space is returned by INT 21\AX=7303h function (8.02-80), which may be applied to logical disks, formatted with FAT-12, FAT-16 and FAT-32 file systems.

A.14-1 Selected port addresses
Ports represent computer's hardware and therefore should be addressed either via BIOS functions, which are adapted to a particular computer's motherboard, or via device drivers for expansion boards. Direct access to ports can't be recommended for application programs, though there are some exceptions. But knowledge of port addresses is beneficial, at least in order to avoid address conflicts with expansion boards.

The table below shows relatively steady features of general port addresses allocation in AT-compatible computers. Of course, port addresses allocation in your particular computer may somewhat differ from the one shown below.

<ol> <li id="note-A.14-1-1">^ a b c d Some data in CMOS RAM are accessible via BIOS Setup program (1.01). Besides that, some hardware data and memory data are read by INT 11 (8.01-42) and by INT 12 (8.01-43) handlers. Direct appeals to CMOS RAM may be necessary for masking NMI (note 1 to 8.01-03), for obtaining data about floppy drives (offset 10h in A.08-03) and for defining CPU's actions after reset, dependent on a byte at offset 0Fh in CMOS RAM.<sup id="note-A.12-1-4-ref5">&#91;Note 4 to A.12-1&#93; For access to data in CMOS RAM the requested byte's offset (up to 7Fh) should be sent by OUT command (7.03-66) to port 70h; then via port 71h the requested byte's value can be read by IN command (7.03-26) or altered with OUT command.</li> <li id="note-A.14-1-2">^ As far as drawing graphics with INT 10\AH=0Ch function (8.01-19) is slow, operating systems appeal directly to video memory and to ports of EGAcompatible video adapters. Therefore EGA port addresses are preserved as a standard, though EGA adapter itself has come out of use long ago.</li> <li id="note-A.14-1-3">^ Port 03C5h transfers a byte, sent by OUT command (7.03-66), to that internal register in video adapter, which is defined beforehand via port 03C4h. If a byte AL = 02h is sent in advance to port 03C4h, then the next byte, sent to port 03C5h, will be accepted as color mask (its normal value is 0Fh).</li> <li id="note-A.14-1-4">^ Port 03CFh transfers a byte, sent by OUT command (7.03-66), to that internal register in video adapter, which is defined beforehand via port 03CEh. If a byte AL = 08h is sent in advance to port 03CEh, then the next byte, sent to port 03CFh, will be accepted as a bit-mask for 8 consecutive pixels. If a byte AL = 05h is sent in advance to port 03CEh, then the next byte, sent to port 03CFh, will specify mode (00h–02h) of writing into video memory (note 3 to 8.01-39).</li> <li id="note-A.14-1-5">^ Port 03DAh is intended for data reading only. Bit 3 in a byte, read from port 03DAh, is kept set during field retrace intervals and is kept cleared outside these intervals. Therefore field retrace intervals can be registered by IN command (7.03-26) in order to avoid image disruptions, which are noticeable, if changes of the displayed image occur outside retrace intervals.</li> </ol>
 * Notes

A.14-2 Status of serial port
This table presents interpretation of bitfields in status byte, returned in AH register by INT 14\AH=00h – INT 14\AH=03h functions (8.01-65 – 8.01-68).

A.14-3 Status of printer, connected to parallel port
This table presents interpretation of bitfields in status byte, returned in AH register by INT 17\AH=00h – INT 17\AH=02h functions (8.01-86 – 8.01-88).

Note 1: returned set state of CF flag with status byte AH = 03h means that EPP BIOS is present, but it doesn't support the requested port.

Note 2: status byte AH = 00h means that EPP data are returned in registers (A.14-4).

A.14-4 Selected functions of EPP BIOS
EPP is a BIOS supplement, enabling enhanced modes of data transfer through LPT ports according to IEEE 1284 specification. Presence of EPP BIOS in your computer should be proved by INT 17\AX=0200h function (8.01-88), which also reports LPT port base address, EPP BIOS version, and address of its entrance point. The latter is used as a target address for CALL FAR command (7.03-08); being called in this way, EPP BIOS performs the operation, specified by a value in AH register at that moment. For the latest revision 7 of EPP BIOS the choice of a particular LPT port is defined by its base address in DX register; earlier EPP BIOS versions define LPT port by its number 00h–03h in DL register. Besides this, some EPP BIOS functions need other data, shown in the second column of the table below or in notes, marked by note number in fifth column. Unless specified otherwise, almost all EPP BIOS functions return status byte (A.14-7) in AH register, mark failure with set state of CF flag and don't preserve contents of BX register.

<ol> <li id="note-A.14-4-1">^ On call a pointer to data block must be specified in DS:SI registers, length of data block (in bytes) — in CX register. Earlier versions of EPP BIOS, preceding the 7th revision, accept a pointer to data block from ES:DI registers. Function returns in CX register a number of bytes not sent yet.</li> <li id="note-A.14-4-2">^ On call a pointer to buffer for data must be specified in ES:DI registers, length of this buffer — in CX register. After successful termination function returns buffer filled, and in CX register — a number of bytes left not filled in the buffer.</li> <li id="note-A.14-4-3">^ On call the data byte to be sent must be specified in CL register. Earlier versions of EPP BIOS, preceding the 7th revision, accept data byte from DH register.</li> <li id="note-A.14-4-4">^ If external devices are connected via multiplexer, then multiplexer port number (01h–08h) should be specified in bits 3–0 of a byte in AL register. If external devices are connected as a daisy chain, then daisy chain port number (10h–80h) should be specified in bits 7–4 of a byte in AL register.</li> <li id="note-A.14-4-5">^ Multiplexer port number (01h–08h) should be specified in AL register. If multiplexer is not used, then AL register must be cleared. For interrupt enable function (CH = 01h) a pointer to interrupt event handler should be specified in ES:DI registers.</li> <li id="note-A.14-4-6">^ This function is not implemented in earlier versions, preceding EPP BIOS revision 7. This function shouldn't be applied, if external devices are not connected to a certain LPT port via multiplexer or as a daisy chain. The requested LPT port will be identified not by its number, but by its I/O base address, which should be specified in DX register.</li> <li id="note-A.14-4-7">^ The number of currently active multiplexer port is returned by this function in AL register, and a flags byte is returned in CH register. Set state of bit 0 in flags byte signifies locked state of multiplexer port, set state of bit 1 in flags byte signifies that there is an interrupt pending from this multiplexer port.</li> <li id="note-A.14-4-8">^ This function returns in CH register a byte of flags. Set state of bits in this flags byte have the following meaning :
 * Notes
 * bit 0 – this port is selected (active)
 * bit 1 – port is locked
 * bit 2 – interrupts from this port are enabled
 * bit 3 – interrupt is pending from this port.</li>

<li id="note-A.14-4-9">^ This function returns in BH register the EPP BIOS version, in BL register — number of currently active daisy chain device, in CH register — a flags byte (as described in note 7), in CL register — number of devices constituting the daisy chain (or 00h, if there is no daisy chain), in ES:DI registers — a pointer to driver's vendor identification string.</li> </ol>

A.14-5 EPP BIOS configuration byte
The "Report configuration" function, defined on call by 00h value in AH register (A.14-4), returns in AL register a LPT port's IRQ line number, in BH register — the EPP BIOS version, in ES:DI registers — a pointer to driver's information, in CX register — LPT port's I/O base address (for versions 1.0 – 3.0 of EPP BIOS only), and in BL register returns EPP BIOS configuration byte. Interpretation of configuration byte's bitfields is given in the table below.

A.14-6 Code of EPP BIOS data transfer mode
The "Report transfer mode" function, defined on call by 02h value in AH register (A.14-4), returns code of current transfer mode in AL register. The "Set transfer mode" function, defined on call by 01h value in AH register (A.14-4), enables to change LPT data transfer mode according to mode's code, specified in AL register. Interpretation of bitfields in this mode's code is given in the table below.

<ol> <li id="note-A.14-6-1">^ Modes defined by set state of bits 3–5 in mode's code cannot be implemented by earlier versions of EPP BIOS, preceding its latest 7th revision.</li> <li id="note-A.14-6-2">^ As far as device interrupts are enabled by AH = 11h function (A.11-4), set state of bit 7 is not accepted by "Set transfer mode" function (AH = 01h), but nevertheless may be reported by "Report transfer mode" EPP BIOS function (AH = 02h).</li> </ol>
 * Notes

A.14-7 Status code of EPP BIOS functions
Almost all EPP BIOS functions, except 01h and 02h (A.14-4), return in AH register a status byte. Interpretation of EPP BIOS status byte codes is given in the following table.

A.15-1 Bootable CD/DVD specification packet
BIOS functions INT 13\AH=4A00h and INT 13\AX=4C00h (8.01-61) emulate a logical disk on basis of its copy, read from an optical CD/DVD disc. Emulation control parameters must be prepared in a form of bootable CD/DVD specification packet. Internal data structure of this packet is shown in the following table.

A.15-2 Format of command packet
This command packet specifies parameters for INT 13\AH=4Dh function (8.01-63), which reads sectors from optical CD/DVD discs. During boot procedure this command packet specifies reading of boot catalog from CD/DVD disc.

A.15-3 Boot catalog of optical CD/DVD discs
Optical discs potentially are able to implement several computer booting scenarios. Initial data, defining each booting scenario, must be present on bootable optical disc(s) in form of a hidden directory, also known as boot catalog. This directory can be read by INT 13\AH=4Dh function (8.01-63). As in ordinary directory, records in boot catalog have standard length 20h bytes. Minimal contents of boot catalog are composed of two required records: the first record is known as validation entry, the second record is a descriptor of default bootable disk's copy. The table below presents structures of both mentioned required records. Offsets 00h–1Fh correspond to validation entry record ; offsets 20h–3Fh, to descriptor of default bootable disk's copy.

<ol> <li id="note-A.15-3-1">Besides two required records, presented in table A.15-3, CD boot catalog may contain other 32-byte records, grouped in several sections. Each section represents a separate booting option and consists of not less than two records: a header record and a bootable disk's copy descriptor for that booting option. Header record begins with signature byte 90h, except header record in the last section, which begins with signature byte 91h. In every header record a word at offset 02h announces number of 32-byte records in this section. In each section descriptor of booting option may be followed by auxiliary records. Data structure in each descriptor of booting option is the same as that of default bootable disk's descriptor, shown in table A.13-3 at offsets 20h–3Fh.</li> <li id="note-A.15-3-2">^ Descriptors of non-bootable disks are allowed too, their distinctive feature is starting signature 00h.</li> </ol>
 * Notes

A.15-4 Commands, performed by CD/DVD drivers
In order to send a command to a driver, you have to obtain a handle, associated with this driver. The first step is to find a pointer to CD/DVD driver header by means of INT 2F\AX=1501h function (8.03-14), performed by TSR program either MSCDEX.EXE (5.08-03) or SHSUCDX.COM (5.08-04). Second step is to read a 8-byte name (signature) of driver's access channel inside driver's header at offset 0Ah. Driver access channel usually is named after the identifier, which follows the /D: parameter in command line, loading the driver (for example, the /D:MSCD001 identifier for CD/DVD drivers, shown in articles 5.10-01 – 5.10-03). The next third step is to use the name for obtaining a handle with INT 21\AH=3Dh function (8.02-33). The name must be uppercased and appended to 8 bytes with spaces (20h), if it is shorter. Returned handle should be placed in BX register before the desired command will be sent to the driver by INT 21\AX=4403h or by INT 21\AX=4402h function (8.02-41). Besides that, these functions need a request data block to be prepared. A pointer to request data block must be specified in DS:DX registers, and length of request data block — in CX register. Length of request data block for different commands is shown in the second column of the table below. The third column shows codes of CD/DVD driver's commands, which are to be specified at offset 00h in request data block. If command implies return of some data, driver will write these data into cells of the same request data block.

<ol> <li id="note-A.15-4-1">^ After any request to CD/DVD driver sent by INT 21\AX=4402h function and before the driver is activated for any other purpose it must be reset by sending command 02h via INT 21\AX=4403h function.</li> <li id="note-A.15-4-2">^ After execution of operations 00h and 08h the requested result is written into request data block starting at offset 01h. This result is either a 4-byte number or a 4-byte address according to the requested operation.</li> <li id="note-A.15-4-3">^ After a request for drive's head location a returned byte at offset 01h in request data block represents CD/DVD addressing format :
 * 00h – HSG format
 * 01h – Red Book format (frames/seconds/minutes).

Besides that, a double word at offset 02h in request data block is drive's head location in units according to addressing format.</li> <li id="note-A.15-4-4">^ After a request for read mode it is returned in request data block at offset 01h :
 * 00h – reading with error correction (cooked)
 * 01h – reading with ECC code, but without error correction (raw).

Besides that, returned word at offset 02h presents sector's size.</li> <li id="note-A.15-4-5">^ After a request for disc change status driver returns status byte at offset 01h in request data block :
 * 00h – change status isn't determined,
 * 01h – disc has not been changed,
 * FFh – disc has been changed.</li>

<li id="note-A.15-4-6">^ After a request for number of tracks driver returns number of the first track in a byte at offset 01h, number of the last track — in a byte at offset 02h, and start address of the first track (in Red Book format) is returned as a double word at offset 04h.</li> <li id="note-A.15-4-7">^ On call for start of a track the number of requested track must be specified in byte at offset 01h in request data block. In response to this call driver writes into request data block at offset 02h a double word address of requested track's starting point (in Red Book format). Besides that, in a word at offset 06h driver returns flags, where set state of bits means the following :
 * bit 12 – audio track, written with preemphasis,
 * bit 13 – digital copying is permitted,
 * bit 14 – this track contains data (not audio),
 * bit 15 – this is a 4-channel audio track.</li>

</ol>

A.15-5 CD/DVD audio control
If in CD/DVD drive status word (A.15-6) bit 8 is set, then this CD/DVD drive doesn't need audio card in order to control audio playback: this CD/DVD drive itself is able to control audio playback.

For sending a request to CD/DVD drive via INT 21\AX=4403h function (A.15-4), a pointer to data block with requested parameters must be specified in DS:DX registers. The table below presents structure of a data block with audio control parameters, which should be prepared for audio control operation 03h in order to alter audio playback. Data block of the same structure is written into a prepared buffer by INT 21\AX=4402h function in response to a request for audio control status operation (A.15-4). On call for INT 21\AX=4402h function a byte at offset 00h in prepared buffer must be filled yet : it must specify code 04h of audio control status operation.

Note 1: output channels 0 and 1 correspond to left and right; output channels 2 and 3 correspond to rear left and rear right. Each channel may be switched off by sending its volume value 00h.

Note 2: by default each input channel is connected to output channel with the same number, and volume is set to maximum value FFh.

A.15-6 Bitfields in optical disc drive status word
This table shows meaning of bitfields in status word, returned by INT 21\AX=4402h function inside data block at offset 01h in response to CD/DVD drive status request 06h (A.15-4).

<ol> <li id="note-A.15-6-1">^ "raw" reading mode implies that ECC code together with data is read and sent to output, but error correction is not performed. Normal "cooked" reading mode implies that ECC code is used for error correction, but is not sent to output together with corrected data.</li> <li id="note-A.15-6-2">^ Interleaving here is related to video files, composed of alternating groups of image frames and audio frames.</li> <li id="note-A.15-6-3">^ Prefetch requests cause reading into drive's memory buffer, so that later the requested data can be obtained without waiting for access to the requested track.</li> </ol>