First steps towards system programming under MS-DOS 7/Examples of executable files composition

Chapter 9 Examples of executable files' composition

All examples of interpretable, executable and configuration files, presented here in the 9th chapter, have been successfully tested on several different computers with processors from 486SL (dated 1992) to Pentium-D (dated 2006). However, one can't foresee everything in advance. In any case the presented examples should be regarded as advisable schemes, where anyone is allowed to select personally relevant solutions. Their applicability is left for you to decide and to implement.

Though personal problems may various, some elementary operational habits are common for all who dare to descend deeper into low-level programming. First of all, how a program's text, printed in a book, can be transferred into an executable file. For this purpose you have to launch an editor program, capable to save non-formatted text files. Most widely known WORD and WORDPAD programs wouldn't fit, but NOTEPAD and EDIT.COM are quite suitable. However, in MS-DOS any national (non-American) language commentaries can be inserted by EDIT.COM editor only (6.09), and only if national adaptation drivers are loaded beforehand (examples in articles 9.01 and 9.04).

When editor program is launched yet, then item NEW in menu FILE enables to open a new empty window, where you may write any desired text. Texts of executable files, presented in this book, normally should be typed line-by-line starting close to the left border of each line. Then text should be saved in a file by SAVE AS command in menu FILE. The SAVE AS command suggests to specify a name and a suffix for new file. Each file should be given just that suffix (2.01-02), which reflects file's status: BAT – for batchfiles, SCR – for command files, executed by DEBUG.EXE, SYS, MNU or EXT suffixes – for various configuration files.

Long files may be saved several times: first time by SAVE AS command, and later by SAVE command. If text is to be corrected on-the-fly, then parts of an unfinished file may be tested separately, as it is shown in article 9.07-02. Editor program fulfills its mission, when a textual file with specified name is completely typed, checked and saved.

If not specified otherwise, successful execution or interpretation of all program examples, presented in this chapter, implies that the following normal conditions are met : Note that the status of the %TEMP% directory implies that any file in this directory may be deleted or overwritten. Current values of environment variables may be checked with SET command (3.26). Original values of environment variables as well as other execution conditions should be defined in configuration files. Various examples of such definitions are shown in articles 9.04, 9.09. But it's expedient to start from the simplest configuration files, presented in the next article 9.01.
 * name of current command interpreter (COMMAND.COM or some other) with preceding full path must be defined by a value of environmental variable %COMSPEC%;
 * attributes H (hidden) and S (system) shouldn't be assigned to those files or utilities, which are to be called for or referred to by the program under test (note 1 to 9.11-02);
 * paths to all those files or utilities, which are to be called for or referred to by the program under test, must be specified in a value of environmental variable PATH (2.02-02);
 * synonymous utilities, unsuitable under MS-DOS 7, must not be present in the current directory and along all the paths, specified in a value of environmental variable PATH (2.02-02);
 * value of the TEMP environmental variable must specify a path to an existing directory, dedicated for temporary files, on a writable media, having enough free space for this purpose.

9.01 Simple configuration files
MS-DOS 7 loading process is configurable and may lead to different results. The IO.SYS loader accepts loading parameters from MSDOS.SYS file (5.01-01) and takes into account presence of main DOS files in the root directory of boot disk. Complete list of DOS files, which should be present in root directory, is described in article 9.11-02. Among these files are two optional, but very important files : CONFIG.SYS and AUTOEXEC.BAT. Just these two files define main features of final DOS configuration. Though MS-DOS 7 is able to load itself without these two files, but implicit default configuration is too poor and cannot be considered sufficient.

MS-DOS 7 can be made effective, convenient and friendly, but the user has to bother about that. In modern computers even simple configurations must include drivers for extended memory, for "mouse" pointing device and for CD-ROM drive. DOS can't be convenient without adequate file manager. Examples of configuration files, presented in this book, also load codepages, enabling to use both American and some national (non-American) language.

Simple versions of configuration files may be used for loading MS-DOS 7 from removable media, but are most suitable for MS-DOS 7 installation on HDDs: either for temporarily installation after formatting or for permanent installation as a possible choice among several alternative operating systems (example in 9.11-02).

9.01-01 Simple version of CONFIG.SYS file
CONFIG.SYS file is an interpretable command file: each its line is a command. Term "interpretable" implies that commands are executed not directly by CPU, but via a mediator – a command interpreter program. Mission of CONFIG.SYS commands interpretation is incumbent on IO.SYS loader.

The presented example of CONFIG.SYS file shows explicitly all the drivers, which should be loaded, and preferable order of their loading. Drivers are expected to be found in \DOS\DRV directory. If you intend to use other directory structure, path specifications must be corrected accordingly. Note that the paths are shown without disk's letter-name. Such specifications will suit for loading from any bootable disk. A help concerning all specified commands and drivers can be found in chapters 4 ("Configuration commands") and 5 ("Selected drivers"). Most drivers can be taken from \WINDOWS and \WINDOWS\COMMAND directories of WINDOWS-95/98 operating system, except MOUSE.COM (5.03-02) from MS-DOS6.22 release and OAKCDROM.SYS (5.09-01), which is copied from WINDOWS-95/98 rescue diskette. There is a lot of other mouse and CD-ROM drivers (GMOUSE.COM, VIDE-CDD.SYS, ECSCDIDE.SYS, etc.), which can work with a variety of device models and can be used here instead of MOUSE.COM and OAKCDROM.SYS.

The order of lines in CONFIG.SYS file must conform to the following general rule: the drivers providing some support must be loaded before a need arises for this support. Upper memory drivers (HIMEM.SYS and then EMM386.EXE) must be loaded with DEVICE commands before upper memory access will be required for DEVICEHIGH and INSTALLHIGH commands. INSTALL and INSTALLHIGH commands, used to load executable drivers, must be placed after all DEVICE and DEVICEHIGH commands, but before the SHELL command. SETVER.EXE driver must be loaded before any other driver, which needs to be deceived about DOS version number. Though there are no such drivers in the shown example of CONFIG.SYS file, loading of SETVER.EXE gives an opportunity to execute later version-specific utilities from earlier versions of DOS (PRINT.EXE, QBASIC.EXE, TREE.COM, etc.).

Special attention should be paid to the NOAUTO parameter of the DOS command in the 3rd line: it cancels default loading of some drivers (DBLBUFF.SYS, DRVSPACE.BIN, HIMEM.SYS, IFSHLP.SYS) as well as a search for these drivers along default paths. In fact the NOAUTO parameter enables to use MS-DOS 7 as a standalone operating system.

Note that a path to COMMAND.COM file in the last line of CONFIG.SYS file is reduced to a single backslash " \ ". This is enough for finding COMMAND.COM file in the root directory, but is not enough for proper definition of path to COMMAND.COM file in the value of COMSPEC environmental variable. Of course, a particular disk's lettername may be specified inside CONFIG.SYS file. Such examples are shown in articles 4.26 and 6.04. However, in practice it's not convenient to exchange disk's letter-name in several places each time you have to boot your PC from some other disk. Therefore, here definition of a particular disk's letter-name is postponed until execution of the last configuration file AUTOEXEC.BAT (9.01-02). Postponed disk's letter-name assignment enables to correct letter-name in a single place and provides opportunity for automatic disk's letter-name determination (examples in 9.01-03 and 9.09-02).

9.01-02 Simple version of AUTOEXEC.BAT file
As far as functional capabilities of  loader are limited, some configuration operations can't be expressed as commands in   file. Such operations constitute another configuration file –. It is also an interpretable command file, but its mission is to employ capabilities of a more powerful command interpreter –  – for performing a number of final configuration operations.

Presented version of  file implies presence of directory structure on the bootable disk: directory   for temporary files and directory   with subdirectories ,  ,  ,. This structure can suit for both diskettes and fixed disks, but if you intend to use any other structure, all paths and references must be changed accordingly. The file is devised for booting from disk. If it is to be used for loading from any other disk, reference to disk  in the second line must be replaced with reference to that disk, which actually will be used. Note that it is a single reference, which must be corrected; all other references to actual disk will be exchanged automatically.

Here is the proposed simple version of  : Command in the first line of the shown file turns echo flag off, just as it is done in ordinary batch files. The second line specifies letter-name of the current disk and assigns it as a value to environmental variable DSK. Note that there must be no spare spaces at the end of second line. Multiple references to DSK variable in the following lines insert lettername of the current disk into all relevant paths. This enables to specify disk's letter-name only once. The third line assigns correct value to COMSPEC environmental variable, which hasn't got proper value during interpretation of  file. Since this moment MS-DOS 7 is ready to a change of the current disk.

Lines 4 and 5 deal with directory TEMP for temporary files. First, existence of this directory is checked. If it doesn't exist, an attempt is made to create TEMP directory. Then its existence is checked once more, and in case of success a path to TEMP directory is assigned as a value to environmental variable TEMP. This procedure guarantees a valid path for temporary files on any writable disk. On the other hand, absence of TEMP variable after this procedure certainly indicates that current disk is non-writable.

The following group of operations assigns values for other variables: DIRCMD, PROMPT, PATH. The shown values should be regarded as examples, which need to be corrected according to actual directory structure on your disk. It is implied that value of the PATH variable (2.02-02) contains actual paths to all utilities, specified in the following lines : MODE.COM, KEYB.COM and VC.EXE, as well as other paths which you may want to supplement.

Execution of  and of   activates desirable national codepage for display and corresponding keyboard's layout. If Russian codepage 866 is not the one you need, you may change it, but beforehand it should be checked in table A.02-2 whether the associated data tables ( and  ) contain the data you need. If not, these data tables must be changed too. Of course, the choice of 437th (American) codepage makes you free to omit all lines with  and , because this codepage is activated by default.

The last two lines in  file serve to launch   – the Volkov Commander file manager (6.25). Other file managers, for example, Norton Commander and Dos Navigator  may be launched in a similar way. If you don't intend to use file manager, then the shown two last lines are not needed.

9.01-03 Automatic determination of disk's letter-name
It were convenient to have a set of self-adaptive configuration files, which can load MS-DOS 7 properly from any disk without manual correction of disk's letter-name. This opportunity can be easily implemented, if you have assembled yet the REASSIGN.COM utility, proposed in part 9.06, or have got any other functionally equivalent utility. All you need is to replace fixed assignment ("set dsk=C:") in the 2nd line of AUTOEXEC.BAT file (9.01-02) with the following two lines, performing automatic determination of disk's letter-name : Of course, the path example ("\DOS\OTH\") must be changed, if necessary, according to the directory, where the utility actually can be found. After execution of these commands the letter-name of current disk becomes a value of DSK variable, and then all other relevant specifications are corrected automatically, as it is shown in article 9.01-02. Automatic disk's letter-name determination doesn't necessarily need a special utility; it may be achieved exclusively by standard MS-DOS's means. But implementation of this idea is not so simple and, besides that, requiring access to a writable disk. Therefore, presented here version of AUTOEXEC.BAT file wouldn't suit for loading MS-DOS 7 from a CD-ROM, but it can be used and actually has been used for MS-DOS 7 single-fold relocation onto a hard disk after formatting. Lines from 8 to 18 in this version of AUTOEXEC.BAT file perform ordinary functions, described in part 9.01-02. But lines 2–6 and labels are specific for this version. In order to make lines search easier the digits in label names represent ordinal numbers of corresponding lines.

The 2nd line presents a check whether a parent directory exists for the current one. If it exists, the current directory can't be disk's root directory, and then we exit via L19 label. Hence, this file will do nothing, while it is stored anywhere inside directory structure. It becomes functional after it is moved into the root directory of a disk: then the parent directory doesn't exist, and the check in line 2 lets to proceed to the next line.

In the following line 3 the PROMPT command (3.22) sets a new prompt, which is issued only once while launching the command interpreter in the 4th line. There command interpreter formally executes an empty file $.BAT, created just before by DOS while preparing redirection in the same line. The result is written into the same $.BAT file. As far as it was initially empty, it will be filled with nothing but new prompt. Let's assume that current disk is D: ; then contents of $.BAT file will look as follows : Note that letter-name D: in the second line of $.BAT hasn't been preset beforehand, it is the actual current disk's letter-name, returned by DOS as an element of command prompt.

The TYPE command in the following line 5 reads AUTOEXEC.BAT file and sends its copy via output redirection so that it is appended to the shown three original lines in $.BAT file.

Cycle FOR in the 6th line of AUTOEXEC.BAT performs three operations by sequential substitutions of three different values for dummy parameter %%Z. First substitution gives  and AUTOEXEC.BAT file ceases to exist. Then the second substitution produces command  and former $.BAT file becomes renamed into AUTOEXEC.BAT. The third substitution gives, that is, the command to execute the new file AUTOEXEC.BAT beginning from its first line.

Since the name of this new file isn't preceded by the CALL command (3.02), there will be no return to the executed former batch file, which currently doesn't exist yet. Note that replacement of currently executed file can't be performed unless all replacement operations are written in one line.

The new AUTOEXEC.BAT file begins with those three lines of former $.BAT file, which have been shown above. In course of their execution the letter-name of current disk is assigned as a value to DSK environmental variable and an unconditional jump is performed to label L7. Thus a group of lines, containing operations of self-modification, is bypassed for ever more. Starting from label L7 ordinary operations of AUTOEXEC.BAT file will be performed. During their execution the found letter-name of current disk will be automatically inserted into all paths, where it must be specified.

9.02-01 Boot sector saving and restoration
In every logical disk the first sector is boot sector. It contains parameter block BPB (A.03-4), an executable code part and specifications of those files, which should be given control for loading operating system. Boot sector is written by FORMAT.COM utility (6.15) each time the disk is formatted, and may be rewritten by SYS.COM utility (6.24), when disk is made bootable. Several special programs, such as DDO (Dynamic Drive Overlay), use non-standard boot sector configurations, which can't be restored by utilities, supplied with MS-DOS 7. You may need to save boot sector into a file in order to restore it later after occasional data distortion, or virus infection, or overwriting in course of operating system installation (examples in article 9.11-02). Though main command interpreter – COMMAND.COM – doesn't provide access to boot sector, for debugger utility DEBUG.EXE the boot sector saving is an easy task, solved exclusively with debugger's internal commands. Here is an example of command file, which induces DEBUG.EXE to do copy boot sector from disk C: into a file: The first line is a command to read boot sector from disk C: and to write its copy into memory starting from address CS:100 and on. Lines 2–5 specify length of data area (00000200h), which should be copied into a file. Line 6 specifies a name for the file to be created. Line 7 causes data copying from memory into a file. The last command ("Q") terminates debugger's session.

The text of the shown command file should be typed in editor program's window (NOTEPAD or EDIT.COM) and saved in current directory as a file with any suitable name (let it be named SAVEBOOT.SCR). Then this file should be sent to debugger by a command

The result of execution is a 512-byte file BOOTSECT.DAT, appearing in current directory. This file is an exact image of boot sector on disk C:. You may read boot sector from any other valid logical disk in a similar way (6.05-10). In order to access disk A:, for example, you have to replace the first line in SAVEBOOT.SCR with the following one :

Of course, you can't address to a drive for removable media unless it has a valid removable media inside.

The reverse operation of writing a boot sector back to disk is performed by an even simpler command file : Here the first line announces a name of file, containing boot sector image; this file must be present in current directory. The second line reads sector data from this file into memory, and the third line writes the sector data from memory back onto its original disk (disk C: in this example). Text of the shown command file should be typed in editor program's window and then saved into a file with any suitable name, for example, RESTBOOT.SCR. As far as interpretation of RESTBOOT.SCR implies direct access to a disk, this must be done under DOS, but not inside the "DOS box" under WINDOWS OS. Restoration of boot sector will happen, when command file RESTBOOT.SCR will be sent to its interpreter via input redirection:

With described command files the boot sector restoration becomes an easy operation. Nevertheless, this operation shouldn't be used for boot sector transplantation. Even transplantation between diskettes of the same format raises a number of problems with uniqueness of their serial number and volume label, since the latter is duplicated in the root directory. Generally each boot sector is unique and can be suitable for no other disk except its original disk.

9.02-02 Copying Master Boot Record into a file
Each time you switch your computer on, it loads an installed operating system from its HDD (hard disk drive). This ordinary procedure includes several stages, and one important stage is execution of Master Boot Record (MBR), which specifies HDD's structure and directs loading process further. As any other record on a disk MBR is subjected to natural degradation, it may be damaged by an occasional fault or by virus. In any such case you will have to boot your computer from a recovery disc or from emergency diskette in order to restore MBR.

For Windows-95/98/ME operating systems you may try to restore MBR with FDISK.EXE utility (6.13), but it can't restore partition table, which is written in the same sector together with MBR (A.13-5). Specific forms of MBR, used by some other operating systems, by DDO (Dynamic Drive Overlay) and by boot managers, also can't be restored by FDISK.EXE.

Meanwhile, there is a simple and universal solution: to store a copy of MBR together with partition table in a file on a removable media (compact disk or diskette). Then you will be able to restore MBR and partition table whenever you need from this file.

MS-DOS 7 doesn't provide special means to copy MBR, but supplies debugger DEBUG.EXE, which enables you to write any succession of machine commands and can execute it at once. This article presents a command file with a succession of commands, inducing DEBUG.EXE to copy MBR into a file. Text of this command file looks as follows : Proposed commands should be typed in a window of editor program, as recommended in introduction article to chapter 9. Comments to the right of semicolons are not executed by DEBUG.EXE and hence may be omitted. Notice the empty line between "" and "" commands: it is important (7.01-04) and must be present. Then text should be saved in a file, which may be named, for example, READ_MBR.SCR.

If your computer is configured to boot not from logical disk C:, but from any other logical disk (D:, E: or other), you have to check actual number of bootable physical HDD, for example, by command

From displayed table you will be able to determine the number of bootable physical HDD; if it is not number 1, then HDD's code 80h in second line of READ_MBR.SCR file must be corrected. If bootable drive is HDD number 2, then 81h HDD's code should be specified, if bootable drive is HDD number 3 — the 82h HDD's code, and so on.

Now it's time to explain how READ_MBR.SCR works. Its first line " " switches DEBUG.EXE in assembler mode of operation for writing codes of machine commands into memory starting at address CS:0100h. While DEBUG.EXE stays in assembler mode, it allows to insert comments after semicolon sign, so the role of commands in lines 2–12 is evident from these comments. More detailed information about each command can be found in chapter 7. Two successions of machine codes are prepared: one starts from memory cell 100h, and the other, announced by ORG command in line 9, starts from memory cell 130h. Translation of commands into machine codes continues until empty line 13 is encountered : it forces DEBUG.EXE to leave assembler mode of operation. Commands in following lines are not added to prepared successions of machine codes, but rather are executed at once.

Command "G" in line 14 initiates execution of the first prepared machine codes succession from address CS:0100h. In the course of execution the MBR together with partition table are read from HDD and are written into memory from cell 0200h and on. Exit code of reading operation is temporary stored in arbitrary chosen free memory cell 01F6h. Execution of the first prepared machine codes succession is finished by RET command (7.03-73) in line 8, which returns control back to debugger DEBUG.EXE.

DEBUG.EXE continues its job from command " " (6.05-12) in line 15. It prepares name (MBR.DAT) for the file, which is to be created. You may specify other name or add a preceding path, if file is to be created elsewhere beyond the current directory. Commands in lines 16–19 specify the length (00000200h) of the file to be created. The command " " (6.05-19) in line 20 reads data from memory, starting at address CS:0200h, and writes these data into a file, which has its length and name (MBR.DAT) specified beforehand. Command "D" (6.05-04) in 21st line displays reading operation exit code, stored in memory cell 01F6h.

The last command " " in line 22 initiates execution of the second prepared succession of machine codes. Exit code of reading operation is copied from memory cell 01F6h into AL register, and then DOS's INT 21\AH=4Ch function (8.02-55) terminates debugger's session. Simultaneously the exit code from AL register becomes the errorlevel value, left behind by terminated debugger's session, so that later it may be checked with conditional "if errorlevel" command (3.15-03).

Before command file READ_MBR.SCR will be interpreted, you have to assure yourself that it exists in the current directory on a writable media. As far as MBR will be saved in a file named MBR.DAT, any synonymous file should be removed from current directory, otherwise it will be overwritten without prompt. Having finished preparatory checks, you may send READ_MBR.SCR to debugger for interpretation :

During interpretation a message "Program terminated normally" appears, but it means nothing more than DEBUG.EXE has successfully got control back after execution of the first succession of machine codes. Outcome of MBR reading attempt is represented by exit code – a hexadecimal number, displayed in penultimate row on the screen. Non-zero exit code informs about failure of MBR reading attempt. In this case a MBR.DAT file will be created containing nothing but garbage. On condition "if errorlevel 1" (3.15-03) it should be automatically deleted. Interpretation of non-zero exit codes according to table A.06-1 may help to reveal the cause of failure.

Exit code value 00h signifies success of MBR reading attempt. In this case file MBR.DAT contains a copy of MBR together with disk's partition table. An example of MBR.DAT file dump is shown in fig. 12 (in article A.13-5).

9.02-03 Restoration of Master Boot Record (MBR).
MBR failure is a relatively rare event, but no one has a guarantee to avoid it. Once something similar may happen to you. Then you have to test and exclude other suppositions: wrong BIOS settings, CMOS memory failure, disk's surface damage, boot sector overwriting, etc. Most convincing experiment is to save an image of current MBR into a file, as it is shown in preceding article 9.02-02, and to compare it with original MBR image, which you have saved beforehand in another file. Comparison may be performed by FC.EXE utility (6.12). If files differ, MBR must be rewritten or restored.

MS-DOS 7 doesn't provide special means for writing MBR image from a file onto a hard disk, but you may prepare a command file, which will force DEBUG.EXE to do this job. Let's assume that the command file is named WriteMBR.SCR, that the copy of the original MBR image is named MBR.DAT, and that both files exist in current directory. The contents of WriteMBR.SCR may look like this : The "" command in first line of this command file switches DEBUG.EXE into assembler mode, so that commands in following lines 2–8 are not executed at once, but rather are translated into machine codes written into memory cells from CS:0100h and on. While DEBUG.EXE stays in assembler mode, it allows to supply each line with commentaries. Therefore, mission of commands in lines 2–8 is clear from command file itself. Empty line 9 forces DEBUG.EXE to exit assembler mode. Then "N" command (6.05-12) in line 10 specifies name of the file to be loaded, and "L" command (6.05-10) in line 11 loads MBR image from MBR.DAT file into memory starting at address CS:0200h.

The "G" command (6.05-07) in line 12 initiates execution of prepared machine codes from address CS:0100h. Execution proceeds until in line 8 the RET command (7.03-73) is encountered, which returns control back to DEBUG.EXE. Execution of commands in WriteMBR.SCR file is then continued from line 13 with " " command, which displays exit code, left after execution of INT13\AH=03h writing function. The last line 14 with "Q" command terminates debugger's session.

Naturally, if your bootable disk is not the first physical HDD, you must change code of physical disk in the 2nd line of WriteMBR.SCR file just as it is described in preceding article 9.02-02. When you are sure that the code of physical disk is specified properly, that the MBR does need to be restored, that all the necessary files are ready and in the current directory, then you may send WriteMBR.SCR file for execution with command

After execution a hexadecimal exit code will be displayed on the screen. Interpretation of any exit code can be found in table A.06-1. Exit code 00h signifies that the MBR has been restored successfully.

Note 1: experiments with WriteMBR.SCR in order to ensure yourself shouldn't be performed upon HDDs which are currently in use! This may lead to unrepairable data loss! You may subject to experiments only those HDDs (both new and not new), which contain nothing worth saving.

Note 2: WriteMBR.SCR file needs direct access to disk. Therefore, MBR restoration shouldn't be performed inside "DOS box" under WINDOWS OS, it should be performed under genuine MS-DOS 7.

9.03 Examples of batch files
COMMAND.COM interpreter accepts ordinary command files via redirection, just as DEBUG.EXE does (9.02). But batch files represent a special class of command files, recognized and accepted by COMMAND.COM just from command line, without redirection. Moreover, in batch files COMMAND.COM can execute several important commands (3.02, 3.14, 3.21, 3.27), which can't be executed in ordinary command files or from command line. Because of these reasons a variety of command files for COMMAND.COM interpreter eventually is confined to class of batch files.

The simplest batch file in this book is AUTOEXEC.BAT file, presented in article 9.01-02. The articles below present somewhat less simple examples of batch files. These examples demonstrate techniques of batch programming, which may be useful far beyond the purposes of the shown batch files.

9.03-01 Batch file ARC.BAT for archiving
Term archiving according to computer terminology implies compression of several files into a combined file-archive. This meaning survived from those times long ago, when computers were not reliable, and personnel had to save multiple files as a combined data stream written onto magnetic tape media. Since then most everything has evolved, but interest in archiving hasn't vanished. Archiving decreases loss of free disk's space in clusters, makes faster both copying and defragmentation. File's size compression is essential because of limited transmission speed in communication networks. Packing of multiple files into one archive is convenient and is widely used for delivering large program products.

Known archiving algorithms are numerous, but only two of them — ZIP and RAR — have got widespread practical appreciation. ZIP algorithm, developed by Phil Katz in early 1990s, doesn't provide utmost compression, but has two other advantages: speed and compatibility. Archives, packed by original ZIP algorithm, can be unpacked by a lot of other archiving programs. Programs for packing and unpacking ZIP archives can be downloaded, for example, from site http://comp.site3k.net/?/comp/pkzip.html.

The RAR algorithm, developed by Eugene Roshal in middle 1990s, provides better compression and is able to emend partially damaged archives having internal recovery record. But new versions of WINRAR program (for WINDOWS OS) create archives, which can't be unpacked by earlier versions of RAR archivers. This incompatibility may let you down against your addressees. Therefore, for forming RAR archives a non-newest, but sufficiently good free version 2.50 of RAR.EXE program (dated 1999) should be preferred. This version of RAR archiver can be downloaded from internet, for example, from site http://dosprogram.narod.ru/arc/index.html.

In order to make archive usage convenient, Volkov Commander file manager enables to enter inside archives with a mouse button click and to treat their contents almost as contents of ordinary directories (details in article 6.25-04). Archive creation from file manager's menu is also much more convenient, than from command line. But file manager can't prevent user's mistakes in data preparation for archiving; moreover, finding a cause of a failure sometimes becomes even more difficult. Therefore, an idea has emerged to write a command file, which will check the data transferred from Volkov Commander file manager to archiver program. This idea was implemented in a batch file, i.e. a command file for COMMAND.COM interpreter. Batch file ARC.BAT prevented archiver's failures, and error messages, sent by ARC.BAT to display, helped to elicit the cause of each error.

As years passed, number of checks in ARC.BAT file has grown up to seven. When a time has come to decide, which batch file should be presented as a useful and relatively simple example, then the ARC.BAT file was considered the most suitable.

Principle of ARC.BAT file is based on presumption that in file manager's active panel the user chooses with right mouse's button a group of files, which are to be included into a new archive, and then with the left mouse's button highlights a filename, which will be assigned to the new archive. An example of such selection of files is shown in fig.5 (in article 6.25-01). After that a mouse button's click on corresponding menu item is enough, and new archive is created yet. If only one file manager's panel is opened at that moment, then archive will be created in current directory. If both file manager's panels are opened, then destination directory will be that shown in opposite (inactive) panel.

In the course of described procedure the states of both panels and names of selected files are sent via the file manager's macrocommands, invoked by certain character combinations shown in article 6.25-02. These character combinations should be specified in a line of menu file VC.MNU (6.25-02) so that each data item, returned by macrocommand, becomes a value of a separate dummy parameter for ARC.BAT file. In particular, for creation of RAR archives the menu line invoking ARC.BAT may look like
 * @Arc.bat RAR !: !~\ !~ !~@ %: %~\

When this line in menu file is interpreted by Volkov Commander file manager, then each character combination, invoking a macrocommand, will be replaced by data item, returned by that macrocommand. Then command line with all performed replacements will be sent to command interpreter COMMAND.COM. The latter sets ordinal correspondence between data items in command line and dummy parameters of batch file ARC.BAT. Inside batch file the dummy parameters are denoted by ordinal numbers of corresponding data items in original command line — digits from 0 to 9, preceded by a percent sign (2.03-03). Lines of ARC.BAT file will be interpreted by COMMAND.COM, and then designators of dummy parameters will be replaced by corresponding data items. According to the shown order of data items the dummy parameters will get the following substitutions :
 * %0 – name of currently processed file (ARC.BAT)
 * %1 – RAR (or ZIP): requested archive type
 * %2 – letter-name of a disk, shown in active panel
 * %3 – path to a directory, opened in active panel
 * %4 – filename, highlighted by left mouse's button
 * %5 – file-list of files, selected by right mouse's button
 * %6 – letter-name of a disk, shown in inactive panel
 * %7 – path to a directory, opened in inactive panel

The data, received from file manager, will be complemented by other data, requested by ARC.BAT file from operating system. All these data will be taken into account in order to reveal mistakes, which may inhibit successful execution of archiving procedures. According to results of checks either an archiver program will be called for, or a comprehensive error message will be displayed. Full text of ARC.BAT file, comprising command lines with all checks, is shown below.

Structure of ARC.BAT file is primitive: it is just a succession of checks. No cycles, no subroutines. Jumps are performed, when check conditions are not met. Destination of all jumps is a single label END in the last line. In order to make ordinal search for lines easier, each tenth line is a comment announcing line's number.

The first line of ARC.BAT file switches off ECHO flag, because otherwise it will be difficult to notice the displayed messages. Commands in lines 2–7 check value of the first dummy parameter and presence of 6th dummy parameter's value. If either of these conditions is unmet, an error message informs that parameters are invalid or undefined. But if both conditions are met, then name of archiver program, which is to be called for, is assigned as a value to variable V1.

Command in the 9th line checks whether the selected archiver program can be found in either of those directories, which are specified by paths in value of PATH variable (2.02-02). Proper value of PATH variable should be prepared beforehand: it is one of required conditions, stipulated in introduction article to chapter 9. Examples of value assignments to PATH variable are shown in all sets of configuration files, presented in this book. But whether the selected archiver program will actually be found – this is your own responsibility, though. If archiver program wouldn't be found, then an error message will be displayed, and jump from line 12 to the END label will terminate execution. If archiver program will be found, then its name with preceding path will be assigned as a value to variable V2.

Similarly a command in line 14 arranges a search for FIND.EXE utility (6.14), which is used in several further checks. If FIND.EXE utility will be found, its name with preceding path will be assigned as a value to variable V3.

Commands in lines 17 and 18 of ARC.BAT file check whether a value of the 7th dummy parameter is empty. This value is empty, when inactive file manager's panel shows not a directory, but some other archive. In this case the error message, displayed by ARC.BAT, will prompt the user for the archive in the inactive panel to be closed.

The 19th line of ARC.BAT file checks that name, which the user had to highlight with mouse's left button click. This name later will be assigned to the created archive. But sometimes highlighted line in file manager's panel is left pointing at parent directory, represented by double dot alias. In this case error message will inform about invalid name choice.

Command in the 22nd line of ARC.BAT checks contents of file-list with names of those files, which should be included into new archive. It's just the moment to remind that value of the V3 variable, substituted twice in the 22nd line, is FIND.EXE utility name with preceding path. Being called for the first time, the FIND.EXE utility counts in file-list the filenames not belonging to that type of archives, which is to be created. Presence of such archive in prepared group of files is allowed, but repetitive compression of archives only is inept: reliability of data storage will be decreased. Count result is transferred via intermediate redirection, and then the same FIND.EXE utility, being called for the second time, checks whether the count result is zero. If files of other types wouldn't be found in prepared group, then an error message will point out that the selected files already are archives of the requested type.

Command in line 25 of ARC.BAT files searches inside the selected group for a file with the same name and the same suffix, which are specified for the new archive. If synonymous file exists yet, then new archive must be created outside the current directory, otherwise this synonymous file will be overwritten before it is included into new archive. If such situation is detected, then an error message will inform about conflict of filenames in current directory.

In the 29th line of ARC.BAT file an attempt is undertaken to write a file, synonymous to new archive, into destination directory, where new archive is to be written. Destination directory is addressed with all those precautions, which are needed for addressing to an inaccessible media: the CTTY NUL command in line 28 blocks up panic error messages, and a call for COMMAND.COM interpreter with  parameter guarantees nonstop execution. It should be reminded that the value of the COMSPEC variable, substituted in the 29th line, is just the name of COMMAND.COM interpreter with preceding path. This value is assigned to COMSPEC variable automatically, when command interpreter is launched for the first time (6.04).

An attempt, undertaken in the 29th line, may fail, if destination directory contains yet a synonymous file, protected by HRS attributes (6.01). Another cause of failure may be non-writable or write-protected media. In any case the outcome of writing attempt is reflected by a message, sent by COPY command into STDOUT channel. But in line 29 STDOUT channel is redirected to FIND.EXE utility. If the latter registers writing attempt failure, then execution is terminated because of impossibility to create a file with prescribed name in destination directory. But in case of success the written file will be deleted by DEL command (3.09) in the 34th line. Thus the last obstacle to a success of archiver's mission will be removed.

Before any program is called for, the way this program displays its messages should be taken into account. The RAR.EXE archiver, called in line 35, forms its screen field bypassing STDOUT channel, so that screen needs to be cleared later. When screen is cleared by CLS command, then the following concluding message is shown in the upper screen's row and becomes hidden under file manager's panels. Therefore, in line 37 screen is cleared by FOR command, shifting cursor 20 rows down. Besides that, file manager's panels must not be unfolded to their full length. Length of Volkov Commander panels may be trimmed by mouse or by arrow keys while ALT-F11 or ALT-F12 key combinations are kept pressed. After that selected panel's size should be stored in VC.INI file by SHIFT-F9 keystroke.

The PKZIP archiver sends its messages via STDOUT channel, therefore it is called in line 38 after the screen is cleared. Due to preceding checks probability of archiving procedures failure is infinitesimal, nevertheless it is not neglected. Therefore, in lines 36 and 39 provisions are made for jumps to final END label, so that error message, sent by archiver program, will remain visible after interpretation of ARC.BAT terminates. When archiver mission is finished successfully, then ECHO command in the 41st line displays concluding message, informing about how the created archive is named and in which directory it is written.

Prepared batch file ARC.BAT should be stored in a directory, which may be accessed via paths, specified in value of PATH variable (2.02-02). Common directory with other file manager's files should be preferred. An example of Volkov Commander's menu file VC.MNU with lines launching ARC.BAT is shown in article 6.25-02.

9.03-02 Batch file for media status testing
When you have to repair an unknown computer, the first problem is to explore whether there are disk drives and whether these are accessible. Powerful utilities MSD.EXE (in MS-DOS6.22) and NDIAGS.EXE (from Norton Utilities software release) are aimed at solving this problem; both are compatible with MS-DOS 7, but both don't report media status — whether the media is present, formatted, writable, etc.

Presented batch file — let's name it DISK.BAT — provides a short, but comprehensive survey of disk media status. The main idea is to test disk's accessibility by reading volume's label and then to test disk's writeability by writing the same label back. This is safe, because both success and failure of writing procedure wouldn't inflict changes on disk under test.

On the other hand, the DISK.BAT file may be regarded as a source of several non-obvious solution examples for some urgent tasks : Full text of DISK.BAT file is shown below. In order to make ordinal search for lines easier, each tenth line is a comment announcing line's number. Besides that, labels in DISK.BAT are named after numbers of corresponding lines; for example, label L28 denotes line 28, which marks end of the main part and start of a subroutine. The second line in DISK.BAT file is a check for the 1st dummy parameter's value. If it is ampersand, a jump to subroutine is performed; if don't, execution of the main program's part is continued. Note that address for the jump ("goto L%2") is not fixed, but rather is represented by value of the second dummy parameter. This enables to arrange subroutines as parts of the main batch file, otherwise subroutines have to be separate files.
 * incorporation of subroutines into a batch file ;
 * non-stop testing of disks, including inaccessible ones ;
 * avoiding undesirable error messages ;
 * generation of temporary command files ;
 * catching STDOUT output into an environmental variable.

Lines 3–22 specify preparation operations. First values of PATH and TEMP variables are checked. The PATH variable (2.02-02) must specify paths to MS-DOS 7 files, the TEMP variable must specify a path to directory for temporary files. If either of these variables is not defined, then a jump to label L79 is performed, an error message is displayed, and interpretation of DISK.BAT file terminates. Examples of value assignments to PATH and TEMP variables are shown in all sets of configuration files, presented in this book.

The next check in the 5th line calls for a subroutine, starting from label L28. This subroutine writes into environmental variables the names and paths of all utilities, which will be used for performing further tests. Names of these utilities, listed just in the 5th line, are transferred to subroutine via its dummy parameters. Main operation of particular path extraction from PATH variable's value is performed in line 33. If a path isn't found, the ECHO command in line 34 displays an error message. Until list of dummy parameters isn't empty, a jump from line 37 to L28 label will repeat the same cycle for finding next path to the next utility. Finally paths to Attrib.exe, Debug.exe, Find.exe, Label.exe utilities will become values of variables VA, VD, VF, VL, respectively.

After return from L28 subroutine the command interpreter continues execution of commands in lines 7–11. These operations convert disk's letter-name, specified by user in command line, to upper case. But user may specify some other sign instead of disk's lettername. Therefore, another subroutine, located in lines 39–45 of DISK.BAT, is called from line 13 in order to determine, whether the specified sign belongs to list of disk's letternames. If specified sign is rejected, then a jump is performed from line 14 to label L79, an error message is displayed, and execution terminates. If specified sign is indeed a lettername, it will be assigned as a value to variable V1, and then this disk only will be examined. But DISK.BAT may be launched without parameters, and then a predetermined group of disks should be examined. A list of corresponding letter-names is assigned as a value to variable V1 in line 15.

Disks examination procedures need three auxiliary files to be created in directory for temporary files: TMP.SCR, TMP.TXT, TMP.BAT. In order to guarantee creation of those auxiliary files, operation in line 17 takes off attributes from those synonymous files, which may exist yet in that directory. Value of variable VA, substituted in line 17, is name of ATTRIB.EXE utility with preceding path. The first of auxiliary files – TMP.SCR – is created by output redirections in lines 18–21. Contents and purpose of this file will be explained later.

The FOR command in the line 23 launches the main exploration cycle, sequentially for each of the disks under test. Disks to be tested are represented by value of the V1 variable. Disk's examination is performed by a subroutine, located in lines 53–72 of DISK.BAT file. For examination of one disk a call for this subroutine looks like

where the word "call" means a command to return into the same FOR cycle each time when execution of L53 subroutine terminates. Dummy parameter "%0" causes substitution of batch file name: DISK.BAT or some other, if this file will be named otherwise.

Parameters "& 53" specify label L53 as destination for the jump, which is to be performed from the second line. Substitution of disk's letter-name for "%%Z:" parameter specifies the disk to be examined.

It's important to notice that FOR cycle in line 24 is preceded by a CTTY NUL command (3.07) in line 16, which disrupts default communications with DOS's IN/OUT functions except those specified explicitly. This enables to avoid numerous error messages, which otherwise inevitably will be caused by access attempts to invalid or nonexistent disks. But error messages may be useful for debugging the DISK.BAT file itself; therefore during its first execution it is better to have the CTTY NUL command disabled by preceding it with REM command (3.24). If everything goes well, the preceding REM command in line 16 should be removed.

Disk's examination subroutine starts at label :L53. The first test in line 54 is performed by command

Just before execution, the name of variable %COMSPEC% will be replaced by its value, that is, by the name of COMMAND.COM interpreter with its path. Hence, a separate resident module of command interpreter will be loaded. The "/f" parameter forces this resident module to work non-stop, automatically answering "FAIL" to all queries about errors. The "/c" parameter means that resident module must execute only one following command (DIR) and unload itself just afterwards. The message, sent by DIR command into STDOUT channel, is redirected in line 54 into auxiliary file TMP.TXT.

The contents of TMP.TXT file are examined by FIND.EXE utility four times, in lines 55, 57, 59, and 66. Name FIND.EXE is substituted in these lines for name of VF variable. The first examination enables to reject nonexistent drives; the second – drives for removable media having no media inside, the third examination reveals CD/DVD-ROM drives. If examination conditions are not met, then a jump to label L79 is performed, and a corresponding message is displayed on the screen. Through the first three examinations those disks only will pass, which exist, have a media inside and are not CD/DVD-ROMs. A string, selected by FIND.EXE utility during the first examination in line 55, is sent via output redirection and is written into auxiliary file TMP.BAT; its contents, for example, may look like

After the first three examinations, in line 62, contents of TMP.BAT file are transferred as data to DEBUG.EXE, which accepts commands from command file TMP.SCR. The latter is created beforehand by redirections in lines 18–21; it contains the following lines : In the first line command " " (6.05-05) forces DEBUG.EXE to overwrite a part of the loaded string, which thus is transformed to

The second command "w" (6.05-19) makes DEBUG.EXE to write the transformed string back into file TMP.SCR, and the third command "q" closes debugger's session. After inflicted transformation the TMP.BAT file contains a CALL command (3.02) of COMMAND.COM interpreter. Execution of this CALL command will invoke that program, which will be defined by first dummy parameter %1 of TMP.BAT file. Just that happens, when TMP.BAT file is executed in line 63 of DISK.BAT file. But the first parameter of TMP.BAT file in line 63 is %0 dummy parameter of DISK.BAT file, i.e. the DISK.BAT file itself. Hence, command in line 63 performs a recursive call for DISK.BAT file. While this recursive call is executed, the "& 46" parameters define target label L46 for a jump from the second line, and the sixth parameter ("EXTENDED1" in the shown example) is volume's label of the examined disk. Therefore, control is transferred to a subroutine in lines 46–51 of DISK.BAT file. This subroutine replaces former value of V1 variable with a value of 6th dummy parameter – volume's label of the examined disk. Thus mission of L46 subroutine is fulfilled, and command interpreter returns to line 64 of DISK.BAT file, to subroutine L53.

Line 64 of DISK.BAT file prepares the value of the V2 variable with a single purpose: to avoid wrap-around of command string in line 65, which were otherwise too long. Cycle FOR in line 65 performs two operations, defined by values of variables VL, V1 and V2. The first operation is an attempt to write volume label back onto the same disk. The second operation is a conditional deletion of TMP.BAT file, if errorlevel value, returned by preceding writing attempt, informs about failure of this attempt. Since this moment existence of TMP.BAT file is an evidence of label writing attempt success and, consequently, signifies writeability of the examined disk. A check in line 66 reveals whether disk's serial number is present in file TMP.TXT. The result is represented by errorlevel value. This errolevel value together with existence of TMP.BAT file are those two arguments, which are enough for media status identification by conditional control transfers in lines 67–71 of DISK.BAT file. Control is transferred either to subroutine L73 or to subroutine L79, which both send to CON device (to display) messages, informing about status of the examined media.

Subroutine L73 is executed when examined media is found accessible, so that a command in line 78 will be able to show size of disk under test and percent of occupied disk's space. Subroutine L79 is executed when status of examined media leaves no hope to get more information about it. Subroutines L73 or L79 terminate examination of one disk. Then control is returned to continuation of cycle FOR in line 23, where disk examination procedure was originally called for.

Cycle FOR in line 23 will continue to call for disk's examination subroutine L53, sequentially specifying next disk's letter-names from list of disks to be examined. When all disks are examined, then DEL command in line 24 deletes remaining auxiliary files, CTTY CON command in line 25 restores default communications of DOS's I/O functions, and cycle FOR in line 26 deletes all local environmental variables. A jump from line 27 to final label L87 terminates execution of DISK.BAT file. While using the DISK.BAT file it should be taken into account that it needs direct access to disks under test. Therefore, DISK.BAT file shouldn't be launched inside "DOS box" under WINDOWS OS, it may be launched only under MS-DOS 7 or MS-DOS 8. Besides that, all 5 necessary conditions of successful execution, stipulated in introduction article to chapter 9, certainly must be met.

9.04 Configuration files with relocation to RAM-disk
Presented here versions of configuration files (CONFIG.SYS and AUTOEXEC.BAT) implement two alternatives: either ordinary booting mode or booting with arrangement of a virtual RAM-disk, followed by DOS relocation onto this RAM-disk. Virtual RAM-disk is much faster, than any real disk, its usage decreases load and wear of physical drives. But for computer's reparatory purposes a RAM-disk is essential because of other reason. When a computer boots itself from a removable media – a diskette or a CD-ROM – the drive, containing the media, is permanently busy with its mission. You can't insert other media in the drive unless operating system is relocated elsewhere. In these circumstances RAM-disk is the most suitable target to relocate DOS. The RAMDRIVE.SYS driver (5.05-01) supplied in WINDOWS-95/98 release enables to arrange virtual RAM-disks under MS-DOS 7. Common problem for most RAMdisk drivers, including RAMDRIVE.SYS, is that the letter-name, assigned to virtual RAM-disk, isn't preset in advance. RAM-disk is given the first available letter-name after those assigned to fixed logical disk(s). But number of fixed logical disks in various computers may differ. Therefore, the letter-name, assigned to RAM-disk, can't be known beforehand, it has to be determined. For this purpose MS-DOS 8 employs two special files : batch file FINDRAMD.BAT and an executable file FINDRAMD.EXE. The proposed pair of configuration files (CONFIG.SYS and AUTOEXEC.BAT) solves letter-name determination problem otherwise, exclusively by MS-DOS 7's means and without auxiliary files.

9.04-01 CONFIG.SYS file loading RAMDRIVE.SYS driver
This version of CONFIG.SYS file presents an example of a relatively simple block structure. The first block with reserved name [menu] offers two alternatives. When it is executed, two headers of menu items are shown, and you are invited to select one with UP and DOWN arrow keys. After your confirmation of your choice with ENTER keystroke, the loader IO.SYS assigns a name of the chosen alternative ("relocation" or "ordinary") as a value to the CONFIG environmental variable, and then proceeds to interpretation of commands in synonymous block of CONFIG.SYS file. Block [ordinary] is similar to version of CONFIG.SYS file, presented in article 9.08-01, but there are two differences. First, the ATAPIMGR.SYS driver (5.07-01) is loaded in order to enable access to DVD-ROM disks. Second difference is that MSCDEX.EXE TSR program (5.08-03) is not loaded in this CONFIG.SYS file, because its loading here may affect allotment of disk's letter-names. An equivalent TSR program SHSUCDX.COM (5.08-04) will be loaded later from the next configuration file AUTOEXEC.BAT (9.04-02).

Naturally, all paths, specified in CONFIG.SYS file, must be correlated with actual directory structure in your computer. If you choose the [ordinary] alternative, MS-DOS 7 will be loaded in an ordinary way, without relocation.

Block [relocation] consists of two lines. Command "include=" in the first line forces IO.SYS loader to execute all the lines of block [ordinary]. Then line 2 in block [relocation] loads Microsoft's RAM-disk driver RAMDRIVE.SYS (5.05-01). The latter creates a 5600 kb virtual RAM-disk in extended memory according to specified options. This size of RAM-disk can be afforded in all computers having 8 Mb of RAM memory or more, that is, in all modern and even in somewhat obsolete computers.

The last block in this CONFIG.SYS file has a reserved name [common]. A block with this name is executed always, irrespective of the chosen alternative. Commands in [common] block load "mouse's" driver CTMOUSE.EXE (5.03-03) and combined driver KEYRUS.COM (5.02-05) for switching codepages and keyboard's layouts. The last line in [common] block transfers control to command interpreter COMMAND.COM : the latter has to complete configuration procedure with execution of the last configuration file AUTOEXEC.BAT (9.04-02).

9.04-02 AUTOEXEC.BAT file with relocation to RAM-disk
This version of AUTOEXEC.BAT file is devised for loading MS-DOS 7 from logical disk  with at least one directory. Logical disk  may be represented by a real diskette or may be emulated by BIOS from an image stored in a CD-ROM disc. If you intend to use other disk to boot your computer, you have to Of course, the required corrections may be made automatically, if letter-name of current disk is determined, for example, by REASSIGN.COM utility (9.06), as it is shown in article 9.01-03. But here it's better to concentrate your attention on other problem – on a search for that letter-name, which is assigned to RAM-disk. Most often similar loading scenarios are initiated just from logical disk. This version of AUTOEXEC.BAT begins with a conditional jump in line 2, which enables recursive subroutine calls. When AUTOEXEC.BAT is interpreted for the first time, this jump is not performed. After that ordinary value assignments follow. The 7th line performs a jump to a label, which is stored as a value of CONFIG variable since execution of CONFIG.SYS file (9.04-01). This value may be either "relocation" (if you have chosen DOS relocation) or "ordinary" (if you prefer to leave DOS "as it is").
 * change disk's letter-name assignment in the 5th line ;
 * exclude this disk from list of disks to be tested (line 3 in "_relocation" section)
 * correct conditions of "IF" commands in lines 4 and 5 in "_relocation" section.

If "ordinary" alternative is chosen, then commands in section "_ordinary" are interpreted. These include value assignments for variables TEMP and PATH, loading of SHSUCDX.COM TSR program for access to CD/DVD-ROMs and launching VC.COM file manager. Finally MS-DOS 7 stays active on that disk, which was used to boot the computer.

If "relocation" alternative is chosen, then commands in section "_relocation" are interpreted. In the 3rd line after "_relocation" label a cycle FOR is executed, which recursively calls for a test subroutine in the last section "_test" of the same AUTOEXEC.BAT file. Test procedure is applied to a number of disks, specified by their letter-names inside brackets of the FOR command. This is done in order to find the last letter-name, corresponding to a valid, accessible disk. Just this letter-name corresponds to RAM-disk, if IFS and network drivers are not loaded yet. The latter condition was the reason to postpone loading of SHSUCDX.COM TSR program until test cycle comes to end.

Disk's letter-names are sequentially sent to "_test" subroutine via the third dummy parameter %3. Second line after the "_test" label executes a presence test for the root directory of any given disk. This test can be applied even to inaccessible and nonexistent disks. If root directory exists in the disk under test, then on the current disk the current directory is changed to. The following lines check existence of the parent directory for the current one : the  directory has a parent (the root), but the root itself has no parent. If current directory has been changed, then letter-name of the disk under test is assigned as a value to environmental variable DSK. The last line in "_test" section returns current directory to the root.

In a FOR cycle, being given a sequence of disk's letter-names, the "_test" procedure sequentially overwrites former values of DSK variable with next values, each representing a letter-name of next accessible disk. But letter-name of the last valid disk will not be overwritten, it will be the value of DSK variable after the FOR cycle comes to end. This value will be just the letter-name of RAM-disk.

When FOR cycle terminates, interpretation of commands in "_relocation" section continues. The COMSPEC variable's value is reassigned once more, this time pointing to the root directory of RAM-disk. Then XCOPY.EXE copies all non-hidden files together with whole directory structure from original (current) disk to RAM-disk. Hidden files (IO.SYS and MSDOS.SYS) at that moment have finished their mission and are no more needed. Note that utility XCOPY.EXE, which performs copying, must be able to find its library file XCOPY32.EXE in the same directory (i.e. in \DOS\MS7).

The last line in section "_relocation" recursively transfers control not to original AUTOEXEC.BAT file, but to its copy in the root directory of RAM-disk, because value of DSK variable has been changed and now points just at RAM-disk. Because of the same reason all further addressing, defined by the DSK variable, will also refer to RAM-disk.

Interpretation of AUTOEXEC.BAT file's copy continues from first line in section "_ordinary". Operation in its first line acquires great importance: it changes current disk to RAM-disk. Since that time original bootable disk becomes abandoned, all its files are closed yet, and it may be ejected off the drive. Now active operating system is a copy of MS-DOS 7 on RAM-disk. All following operations in section "_ordinary" will be performed as if MS-DOS 7 were normally loaded from RAM-disk.

9.05 Examples of simple utilities
Though debugger DEBUG.EXE (6.05) is not the most convenient instrument for making executable programs, nevertheless it enables to write simple programs of COM format. Remarkable feature of COM format is that program is laid out in PC's memory for execution just as it is presented in file. Therefore, programmer's experience should start from writing the most simple programs of COM format. Simplest programs are not structured, don't appeal to disks, to files, to user. Simplicity enables to ignore some restrictions, including restrictions on allocated memory space (note 2 to 8.02-50). Further in this part two examples of very simple programs are presented. Both were written spontaneously for solving unexpected problem. Later in internet more perfect programs have been found for solving the same problems. Nevertheless, here the simplest original versions are presented, because perfection shouldn't be the main purpose for a beginner. At this stage our main purpose – your ability to understand the concept and to implement it.

9.05-01 Blue color brightness correction
An impetus for writing this simplest program was a display changeover from former CRT to a newer LCD. Due to different modulation characteristics of LCD screen, the customary dark blue color of file manager's panels became too bright, causing visual irritation. In order to return former color to file manager's panels the BLUE.COM program was written. It has effect on videocard's digital-to-analog converter (DAC) so that blue color brightness is decreased. BLUE.COM program is designed for videomode 03h only and has no adaptation capabilities. Nevertheless, it has proved itself useful ; perhaps you'll find it useful too.

BLUE.COM file is produced by debugger DEBUG.EXE as a result of command sequence execution. This command sequence should be written into command file BLUE.SCR by means of editor program (as described in introduction article to chapter 9) and then sent to debugger via input redirection :

Command file BLUE.SCR has to contain the following lines : The first command "" switches debugger DEBUG.EXE into assembler mode and specifies start address CS:0100h for writing machine codes. The next 7 lines define all actions of BLUE.COM program. Meaning of each action is explained by a comment after semicolon in each corresponding line. The 9th line is left empty (7.01-04), it will force DEBUG.EXE to exit assembler mode. Then "N" command (6.05-12) announces a name for the file, which is to be created, and its length (00000013h = 19 bytes) is written into registers BX and CX. The "W" command in line 15 creates file BLUE.COM and copies there the prepared machine codes. The "Q" command in the last line terminates debugger's session.

While command file BLUE.SCR is processed, the debugger displays a listing on the screen. Listing enables to monitor correctness of BLUE.SCR file's typesetting by comparison of actual offsets in listing with proper offsets, presented just after semicolon as the first item of comment in each line. Comparison technique is described in article 9.07-01. If listing doesn't reveal errors, then BLUE.COM utility is ready for execution. Further testing for such simple programs is not needed. If you are not satisfied with that blue color brightness level, which is set by BLUE.COM utility, then brightness value, written into CX register in the 4th line of BLUE.SCR file, may be corrected as you want. The corrected BLUE.SCR file should be sent once more to DEBUG.EXE via redirection, so that new version of BLUE.COM utility will be created.

The BLUE.COM utility should be launched from that line of AUTOEXEC.BAT file, which precedes launching of Volkov Commander file manager. Besides that, default brightness levels are reset anew, for example, by SCANDISK.EXE utility (6.21) and by LXPIC.EXE viewer, mentioned in relation to VC.EXT file (6.25-03). After such programs the BLUE.COM utility should be executed once more. This may be done automatically, if BLUE.COM is launched from the next line of common batch file or of common configuration file (VC.EXT, for example). Such examples are not presented here, because necessity of color correction depends on personal visual perception. Nevertheless, blue color correction, performed by BLUE.COM utility, has been implemented for making screenshots fig.3 (in article 6.09) and fig.5 (in article 6.25-01).

9.05-02 How an ATX computer can be switched off
One more impetus for writing a simple program has emerged in 1999, when computers of ATX form-factor have ousted former AT computers. Newer ATX computers were designed for being switched off by operating system, and adjustable role of power button in ATX computers was difficult to foresee. DOS has never had a utility for switching power off. Since such utility was needed, it has been written, and it has got name TURN_OFF.COM.

TURN_OFF.COM file is produced by debugger DEBUG.EXE as a result of command sequence execution. This command sequence should be written into command file TURN_OFF.SCR by means of editor program (as described in introduction article to chapter 9) and then sent to debugger via input redirection :

Command file TURN_OFF.SCR has to contain the following lines : Proposed command file TURN_OFF.SCR is indeed very simple, it doesn't specify conditional jumps, it uses two types only of machine codes, and produced executable file is as short as 35 (23h) bytes.

The first command "" switches debugger DEBUG.EXE into assembler mode and specifies start address CS:0100h for writing machine codes. The next 13 lines define all actions of TURN_OFF.COM program. Meaning of each action is explained by a comment after semicolon in each corresponding line. More detailed information about INT 15\AH=53h functions can be found in articles 8.01-70 – 8.01-72.

The 15th line is left empty (7.01-04), it will force DEBUG.EXE to exit assembler mode. Then "N" command (6.05-12) announces a name for the file, which is to be created, and its length (00000023h = 35 bytes) is written into registers BX and CX. The "W" command in 21st line creates file TURN_OFF.COM and copies there the prepared machine codes. The "Q" command in the last line terminates debugger's session.

In order to monitor correctness of TURN_OFF.SCR file's typesetting a comment in each line starts with proper offset of corresponding machine command. This offset should be compared with actual offset, shown by debugger in displayed listing. Comparison technique is described in article 9.07-01. It may be expedient to check the length of created file either with DIR command (3.10) or by length indication in file manager's panels. If both listing and length check don't reveal errors, then TURN_OFF.COM utility is ready for execution. Further testing for such simple programs usually isn't necessary.

While using the TURN_OFF.COM utility it should be taken into account that most part of computers produced in previous millennium have no APM system and therefore will ignore calls for INT 15\AH=53h functions. Besides that, TURN_OFF.COM utility shouldn't be run inside "DOS box" under WINDOWS OS, it must run under native DOS only. It is convenient to launch TURN_OFF.COM via file manager's menu (example in article 6.25-02).

It were desirable, of course, to make provisions against probable errors : against execution inside "DOS box" and against absence of APM system in a particular computer. However, then TURN_OFF.COM utility were not so simple. On the other hand, relevant supplementary checks are also not too complex. For example, recognition of WINDOWS OS operating environment is implemented in lines 13Ah–141h of a file in article 9.10-02.

Multiple examples of error indication are shown in articles 9.06, 9.08 and 9.10. Having acquainted yourself with these examples, you will be able to upgrade TURN_OFF.COM utility as you want.

Note 1: unprepared loss of power supply causes loss of these data, which may be not written yet at that moment by SMARTDRV.EXE driver (5.06-01) from cache buffer to disk. This is equally relevant for both unexpected mains power loss and for switching power OFF with TURN_OFF.COM utility. If you intend to employ SMARTDRV.EXE driver, you may force data writing to disk just before TURN_OFF.COM utility is launched, but it's safer to disable write-behind caching at all.

9.06 Value assignment to an environmental variable
Long time ago DOS has been developed as general purpose operating system, and its set of commands has been formed according to this purpose. But now DOS's role has specialized, so that former set of commands now seems partially redundant and partially deficient. This article presents a utility performing three operations, which replenish the most urgent deficiencies of DOS's commands set. In particular, just these three operations enable to implement adaptive loading scenario, described in section 9.09.

As far as proposed utility replaces current value of some environmental variable with requested other data, it has been named REASSIGN.COM. File REASSIGN.COM is not large — in all 992 bytes long — because it relies on cooperation with DOS's internal SET command (3.26) and doesn't duplicate its functions. The SET command prepares an environmental variable, and the first character of prepared variable's value defines operation for REASSIGN.COM utility : The rest characters in prepared value are ignored, but their presence reserves space for the new value. If this space is not enough to contain the returned result, then an error message is displayed. If the result doesn't occupy the whole reserved space, its rest part is filled with space characters (20h).
 * 1) report size of largest free XMS memory block ;
 * 2) accept input from keyboard ;
 * 3) report letter-name of the current disk.

When computer boots from any removable media, letter-name of the current disk is assigned by BIOS. Function 3 of REASSIGN.COM utility enables to determine the assigned letter-name : Prepared value 33 will be replaced by a new one, for example, D:. Since assigned letter-name becomes known, all further addressing in configuration files can be adapted automatically.

The next problem of adaptive loading procedures is to determine feasible size of RAM-disk for DOS relocation, whereas the amount of available memory isn't known beforehand. But function 1 of REASSIGN.COM utility gives the answer : The last line in the example above displays the returned result. Now you are ready to specify size of RAM-disk, and function 2 of REASSIGN.COM utility will accept the desired value : During execution of function 2 the REASSIGN.COM utility invites you to input the desired value via keyboard. Wrong digits may be erased with BackSpace keystroke. When data input is completed, further execution should be resumed by ENTER keystroke. Command in the last line of the shown example substitutes desired size value into a set of parameters for TDSK.EXE driver (5.05-02), which arranges RAM-disk of desired size. Of course, REASSIGN.COM utility can find a lot of other applications, besides the mentioned ones.

It is important to note that all shown examples can't be executed from command lines, presented by Norton Commander, Volkov Commander or similar file managers. The reason is that file managers execute each command line inside a separate environment. Hence a value, set by SET command in one command line, becomes unavailable in the next command line. But ordinary command lines as well as lines inside batch files are executed in common environment, so that there all shown examples will be executed properly.

REASSIGN.COM utility is produced by debugger DEBUG.EXE as a result of command sequence execution. This command sequence should be written into command file REASSIGN.SCR by means of editor program (as described in introduction article to chapter 9). Verbal commentaries may be omitted. Special attention should be paid to empty line — 8th from the end. It must be there, because empty line forces DEBUG.EXE to exit assembler mode (7.01-04). Then command file REASSIGN.SCR should be sent to debugger via input redirection :

Command file REASSIGN.SCR has to contain the following lines : Text of REASSIGN.COM utility begins with procedure releasing that memory, which certainly wouldn't be needed (details in note 5 to A.12-7). Then in lines 110–11F a check is performed for that name of environmental variable, which should be read by command interpreter from command line, translated to upper case and written into first FCB block (note 4 to A.07-1) starting at offset 005Dh. If a cell at offset 005Dh is empty or contains an interrogation sign, then REASSIGN.COM displays help message and returns control to command interpreter, leaving errorlevel 240. Otherwise the cell at offset 005Dh is considered containing a name of that environmental variable, which is to have its value reassigned.

Section 2 begins in line 122 with a call for variable's name search in current and in underlying environments. Search procedure includes PSP test subroutine, presented in section 5, and name search subroutine, presented in section 6. Commands in lines 175–183 check specific PSP signatures in cells at offsets 0000h and 0050h. If PSP validity is confirmed, then address of corresponding environment is read from a cell at offset 002Ch and is sent to name search subroutine, called for from line 18B.

Name search subroutine inspects the whole environment space and exits with ZF flag set, if the requested name isn't found. But when the search ends successfully, then full address (segment: offset) of that variable's value is written into a memory cell. Offset of this memory cell is calculated by subtraction of 4 from a pointer, stored at offset 0165. Therefore, addresses, found in different environments, don't overwrite each other, but rather are stored side-by-side at the end of the PSP, belonging to REASSIGN.COM utility.

If name search subroutine returns with ZF flag cleared, then PSP test subroutine has to "descend" into underlying ("parent") PSP and to continue its tests there. Pointers in current PSP cells at offsets ES:[0016] and ES:[0010] are regarded as "parent" PSP candidate addresses. With respect to selected "parent" PSP candidate the PSP test subroutine in line 1A3 recursively calls for itself. All checks are repeated in that underlying PSP and in its environment. Recursive descent into underlying PSP may be repeated several times. It comes to end, when it reaches the "bottom" PSP, or when the last PSP is found invalid, or when the requested variable's name isn't found in the last environment.

After termination of PSP test subroutine execution of operations in section 2 continues. There in line 12F the address of variable's value, related to the nearest ("upper") environment, is written into registers ES:DI. This address points just at the first character of variable's value, which defines requested function for REASSIGN.COM utility. This character must be a digit, corresponding to either of ASCII codes 31h, 32h, 33h. If there is some other code, then REASSIGN.COM displays error message and returns control back to command interpreter. But if all checks are successfully passed, then in line 144 a subroutine is called for, which is to execute the requested function. Address of subroutine's entrance point is taken from a list at offset 0167h in section 4.

Execution of function 1 begins from entrance point 0213h in section 8. First a call for INT 2F\AX=4300h (8.03-22) detects whether HIMEM.SYS driver (5.04-01) is loaded or not. If it isn't loaded, then REASSIGN.COM displays no error message, but leaves errorlevel 255 and returns control back to command interpreter. When HIMEM.SYS driver is loaded, then a call for INT 2F\AX=4310h (8.03-23) follows in order to get driver's entrance point address. Returned full address is used in line 22D for a far call to driver's 08h function (A.12-3). It returns several parameters, including size of the largest free XMS-memory block. In lines 236–252 a value of errorlevel is set in order to prompt a feasible size of RAM-disk. Commands in lines 256–263 convert hexadecimal XMS block size into decimal number. Then in lines 265–277 the digits of decimal number are transformed into ASCII codes and are written in place of variable's value in the nearest ("upper") environment. If there is no place enough, REASSIGN.COM displays error message, leaves errorlevel 240 and returns control to command interpreter. If place is sufficient, execution returns from subroutine to final section 3, where a copying subroutine is called for from line 14C. It appends written value with spaces (if needed) and copies it into underlying environments. Thus execution of function 1 terminates.

Execution of function 2 begins from its entrance point 029Ah in section 9. Inputted characters are sequentially accepted and written in place of variable's value in the nearest ("upper") environment. Input by means of INT 16\AH=10h (in line 29C) and display via INT 29 (in line 297) are not subjected to DOS's I/O redirections. Commands in lines 28D–29B patch the place of preceding character with a space, when user presses the BackSpace key. REASSIGN.COM terminates input cycle after ENTER or ESC keystroke. After ESC keystroke commands in lines 2CD–2D0 set flags so that new value is not copied into underlying environments. REASSIGN.COM exits, leaving errorlevel 255 and preserving variable's former value. After ENTER keystroke a return from subroutine and all final operations are performed just as it was described above for function 1. The variable gets a new value, and execution comes to end leaving errorlevel 000.

Execution of function 3 starts from its entrance point 02DCh in section 11. Number of current disk is requested with INT 21\AH=19h, converted into ASCII code of disk's lettername and written in place of variable's former value. If there is a place for at least one more character, then letter-name is appended with a colon.

As far as current disk certainly exists, errorlevel for function 3 is charged with another mission : the determination of the number of floppy drives. That number must be known to adaptive loading procedures, because in computers having one floppy drive, all requests to other floppies are automatically readdressed by MS-DOS to the single drive A:. Floppy problem is complicated further by the possibility of floppy drive emulation, which is not reflected in CMOS memory data.

In order to determine actual number of floppy drives the commands in lines 2F1–30C appeal to DDT tables (A.03-2) for information about correspondence between logical disks and physical drives. This information enables to count actual disks, ignoring repeated references to the same physical drive. After that execution returns from subroutine to final section 3. Having accomplished function 3, REASSIGN.COM leaves errorlevel value, which helps to define proper disks testing order (example in 9.09-02).

More detailed explanation of each command is given in commentaries, complementing each line after a semicolon.

It's worth paying attention to modular structure of REASSIGN.COM utility. Each function is performed by a separate subroutine, independent from other functions. Moreover, there are 3 unfilled positions (16D, 16F, 171) in list of entrance point addresses, so that you may add entrance points for your own subroutines. But before updating REASSIGN.COM, you have to bother about proper typesetting of the current assembler text. It is not as simple as texts in preceding part 9.05. You shouldn't dare to execute at once that file, which will be created by DEBUG.EXE in response to the text you have typed before this text is thoroughly verified.

Some practical recommendations, given in following part 9.07, will help you to detect errors in typesetting, to test executable files and to avoid undesirable consequent complications.

Note 1: if there is any synonymous variable in some underlying environment, then REASSIGN.COM will assign new value to that variable too, and this new value may be truncated according to length of former one. Repeated usage of one name in different contexts should be avoided.

9.07 Some advices on checking and testing
Ordinary practice of verifying assembler texts includes listing analysis, correction of revealed errors and following step-by-step tracing. Error correction is necessary anyway, but user can't expect considerable help from DEBUG.EXE debugger: it doesn't reveal nonsyntactic errors and doesn't provide automatic linking, as more perfect assemblers do. Despite DEBUG.EXE debugger's obvious drawbacks, in some circumstances it has no suitable alternatives. This happens in uncertainty conditions and also when debugging affects essential functions or data structures of either DOS or BIOS. Though debugger's capabilities are limited, nevertheless these capabilities may be used effectively. Examples of debugger's capabilities usage are shown below in part 9.07.

9.07-01 Listing analysis
Presence of errors should be assumed in any assembler text one has typed. When DEBUG.EXE performs commands, constituting assembler text, it displays listing. Errors, which are found by DEBUG.EXE, are marked in that listing. Since listing scrolls over the screen rapidly, error marks can easily be missed. In order to examine the shown part of listing more attentively, you may suspend execution, pressing the PAUSE key. After that any other keystroke resumes execution, which then may be suspended at desired moments as many times as you will. Manipulations with PAUSE key were sufficient in obsolete computers, but modern computers shift listing too rapidly. Therefore, listing may be examined more conveniently later, after it is redirected and written into a file, for example :

Stored file LISTING.TXT may be printed or looked through with any viewer or editor program. A part of REASSIGN.COM program's (9.06) listing is shown in fig. 6. In LISTING.TXT all the errors, detected by DEBUG.EXE, are pointed at from the following line with a word ^Error (preceded by a caret pointer). The caret points at that character in preceding line, which can't be interpreted by DEBUG.EXE. Most often this is sufficient for understanding how the error should be corrected. A caret in fig. 6 points at an error in preceding line: indeed, there is "imp" typed instead of "jmp". Sometimes the caret points at the end of preceding line or at the semicolon sign, where a comment starts. This happens, when some required element in command specification is absent. Which particular element is absent – this can be cleared up from chapter 7, presenting all forms of machine command specifications, acceptable for DEBUG.EXE. In any case a line with an error is not assembled, all offsets below become shifted, and after a single error all following addressing goes wrong. Registered errors must be corrected before any further actions are taken.

Informative listing enables to reveal even those errors, which are not recognized by DEBUG.EXE. Therefore, you have to prepare a sufficiently informative assembler text : correct offset values should be specified in comments, preferably at every line. Almost each line of assembler texts, presented in parts 9.06, 9.08 and 9.10, includes a comment, where correct offset of corresponding machine command is specified just after semicolon sign. Correct offset should be compared with actual offset, displayed in listing at start of each line. Mismatch of these offsets signifies presence of an error in some preceding line. In fig. 6 compared offsets are different from line 147 and on, therefore an error should be expected in preceding line at offset 144. Indeed, comparison of an assembler command at offset 144 in fig.6 with the same line in original text reveals the error: command "call [BX+005]" has been typed instead of "call [BX+0105]". DEBUG.EXE hasn't registered this error. Similar errors emerge during typing of data and textual messages in assembler texts. In any case offsets mismatch should induce a search for its reason and finally must be corrected.

Addresses inside machine commands also may contain errors, which are not detected by DEBUG.EXE. If a comment in assembler line begins with an asterisk, hence this assembler command includes a target address. It must be equal to actual address of first byte in that machine command or in that data block, which have the same correct address specified in a comment. In order to make visual search for target lines easier, comments to these lines are preceded with equality sign. Besides that, separate lines with comments just under a header of each section specify positions of commands with target addresses pointing to this section.

The last important offset to be checked is the one marking that empty line, which forces DEBUG.EXE to exit its assembler mode of operation. In assembler text, presented in part 9.06, this empty line is the 8th from the end. As far as machine codes of ordinary programs are written starting at offset 100h, offset of empty line must be exactly 100h greater, than the whole length of assembled program. If you want to save assembled code in a file, you have to preset the CX register with file length value just 100h bytes less than the actual offset returned in response to the empty line. If you prosecute another aim – to detect possible offset shift errors, then you have to compare the returned offset of empty line with file length value, preset in register CX. In particular, in the third line from the end of assembler text, presented in part 9.06, the CX register is preset with hexadecimal number 03E0h. Hence, in listing the offset value 04E0h, returned in response to the empty line, will signify absence of offset shifts up to the last processed assembler command.

9.07-02 Interactive debugging opportunities
When effect of some command or of an interrupt handler needs to be clarified, it is not difficult to type 5–7 lines and to force DEBUG.EXE to execute these command lines at once. But long successions of command lines cannot be composed so easily. You'll be compelled to prepare long successions of commands as textual command files, which then are to be sent to the interpreter. For DEBUG.EXE the only way to accept command files is via input redirection. When input is redirected, DEBUG.EXE doesn't accept commands from keyboard, and all advantages of interactive debugging become lost. This is usually taken for granted as having no alternatives. But this opinion is wrong.

Via input redirection the DEBUG.EXE debugger is ready to accept and to execute those commands, which will cancel input redirection and restore debugger's interactive capabilities. Required succession of commands may look as follows : The first two command lines restore references to the first SFT table entry in cells of JFT table (note 3 to A.07-1) at offsets CS:0018 and CS:0019. These cells correspond to STDIN and STDOUT channels, and appeals to the first SFT table entry (A.01-4) activate the CON device driver. Hence the performed substitution restores normal interaction with display and keyboard for commands of the program under test. The same operation may be done by INT 21\AH=46h function (8.02-48), but it isn't applied here, because in this particular case the performed substitution is not enough.

DEBUG.EXE doesn't obey to references in that copy of its JFT, which is formed for the program under test. Changes also must be applied to original JFT – to that one, which is formed by COMMAND.COM interpreter inside debugger's own PSP. Therefore, in the 4th line of presented example a call for INT 21\AH=62h (8.02-73) function returns segment address of that original PSP in BX register. In the 5th and 6th lines of the presented example this segment address is used in order to make the same substitution in original debugger's JFT. Thus all preparations are made for restoration of normal interaction between debugger and the user. The last peculiarity is that control is returned to DEBUG.EXE not with RET command (not as in examples in part 9.02), but with a call for INT 20 handler (8.02-01). Unlike the RET command, the INT 20 handler leaves stack pointer in its original state, normal for interactive operation mode.

In order to avoid confusion with commands of the program under test, the proposed commands may be appended to redirected command file in a form of machine codes. These codes can be arbitrary located in any free memory space. Let's assume that memory after offset F00h is available and is certainly free. Then the lines which should replace ordinary last commands "w" and "q" in command file, will look like this: If a command file with these two final lines is sent to DEBUG.EXE via input redirection, then all preceding command lines will be executed as usual, but after that interactive operation mode of DEBUG.EXE will be restored (instead of control transfer to COMMAND.COM interpreter). An obvious advantage of a return to interactive operation mode is that there is no more need to determine beforehand the length of a file, which is to be saved. Actual length of assembled code is shown in listing, and required length value may be then (post factum) inputted by the user into CX register from command line. One more advantage is that there are no more restrictions (note 1 to 6.05) on testing of commands, which appeal to STDIN and STDOUT channels. At last, there is no more need to save the processed program in a file after each correction: now that's enough to insert corrections just into original assembler text.

The mentioned advantages are especially important, when a program is composed of several sequentially complemented parts. Sequential debugging promotes early detection of non-syntactic errors and makes emending of their consequences easier. Advantages of sequential modular composition have evinced themselves to full extent during preparation of those programs, which are presented completed in articles 9.06, 9.08, 9.10.

9.07-03 Batch-file control over tests
When after errors correction the last listing reveals no more errors, then it is time to cope with all the rest mass of errors in course of testing.

That executable file, which is produced at the last assembling iteration, is usually too raw to be launched at once. First it should be conveyed to debugger. DEBUG.EXE can accept a file just from command line, as it is shown in introduction article to part 6.05. Nevertheless, there are some reasons to prefer debugging arrangement by means of a specially prepared batch file. Batch file enables you to get rid of tedious retyping command lines anew each time you will need to repeat the test. Next, batch file always provides common environment. Besides that, batch file can specify auxiliary functions, making test results more informative.

General composition of test batch file includes preparation part, main test execution part and a final part, where test results are analyzed and displayed. Particular implementation of each part, of course, must reflect specific features of the program under test. Let's consider an example of a test batch file, written especially for testing the 2nd function of REASSIGN.COM utility (9.06): The first three lines in proposed batch file represent preparation part ; the fourth line, the main test execution part. It should be taken into account that during debugging you may easily lose orientation in successions of processed commands. Therefore, a source program listing with comments should be prepared beforehand.

In the 4th line DEBUG.EXE gets a group of parameters from command line and, besides that, accepts a command file via input redirection. Here the main purpose of command line parameters is their participation in filling PSP for the program under test. In the simplest case file REASSIGN.COM, specified in command line, may be empty at all, but owing to presence of its name in command line this name together with following parameters, if there are any, will be written into dedicated PSP fields (A.07-1). Of course, the file REASSIGN.COM may be not empty, and then its code will be written by debugger into memory starting from address CS:0100h and on. This feature is convenient for preparation to debugging of relatively large executable files.

Input redirection in the 4th line will force DEBUG.EXE to assemble commands from file REASSIGN.SCR. Translated machine commands will be written into memory starting from arbitrary specified address, either overwriting or complementing that code, which has been initially copied from REASSIGN.COM file. Therefore, file REASSIGN.SCR may contain only those parts of assembler text, which need further debugging. The latter doesn't relate to assembler texts, presented in this book: there is no sense to divide complete texts. In any case the assembler text, sent via redirection, must end with those two command lines, proposed in article 9.07-02. These commands will force DEBUG.EXE to escape from redirection into interactive operation mode.

Waiting for commands from keyboard, DEBUG.EXE presents its prompt — a blinking underscore — and thus invites the user to act further. It's better to begin from testing program parts (or subroutines) with commands "G" (=Go, 6.05-07) and "P" (=Proceed, 6.05-14). Testing program parts is less difficult, than testing step-by-step. Special attention should be paid to states of flags and registers in critical points — for example, in points of return from subroutines. If some part of program returns wrong results, it should be subjected to step-by-step debugging. Even if some part of program causes hanging, it wouldn't take much time to reset computer and to launch the same test batch file anew. Testing step-by-step enables to cope with the most stubborn bugs.

When debugger's session is to be closed in order to make a correction, then you may enter the "Q" (= Quit) command and then press ENTER. After such termination DEBUG.EXE always leaves zero errorlevel. But sometimes it is important to check errorlevel, returned by the program under test. In the latter case debugger's session should be terminated by a call for DOS's INT 21\AH=4Ch function (8.02-55), just as the program under test must be terminated, when it is executed beyond the debugger's shell. After termination of debugger's session the commands in final part of test batch file will be executed. Results of REASSIGN.COM program execution are expressed via errorlevel code and via returned value of some environmental variable. In order to catch the returned errorlevel the program under test may be executed inside a shell of command interpreter COMMAND.COM, launched with undocumented /Z parameter (6.04). However, this shell doesn't convey values of environmental variables. Therefore, lines 5–16 of the proposed test file contain a procedure of errorlevel determination. Then commands in lines 17–18 display returned values of both errorlevel and of that variable, which was to be changed by REASSIGN.COM utility. The last line with PAUSE command prevents the displayed results from being hidden under file manager's panels. In order to check some other function of the program under test, you have to change parameters in preparation part of test batch file. Sometimes command line parameters in main test execution part need to be changed too. Replacement of parameter's values may be performed via dummy parameters of test batch file. But in presented examples dummy parameters are not employed for simplicity reasons. It is assumed that all necessary changes can be made just in batch file text by means of an editor program. When batch file is saved with all necessary changes, it is again ready to be used for testing the next function.

Generally, every program must be subjected to three types of test series. Test series of the first type check all functions of the program in normal conditions. Test series of the second type check program's response to probable abnormal conditions: invalid specifications, absence of required parameters, inadmissible data values, etc. Test series of the third type are for those programs, which perform direct manipulations with hardware : such programs must prove their functionality in all relevant hardware configurations. Naturally, particular composition of tests depends on program's mission and on scope of challenges, but principle is the same for all programs, even as small as proposed REASSIGN.COM utility. When your program passes all tests successfully, then your mission concerning this program may be considered completed.

9.08 Let's try to assemble a driver
When DOS is used to explore some computer for the first time, it is desirable to have a fixed letter-name assigned to RAM-disk, prepared for DOS relocation. This can be achieved by means of a driver, which declares a necessary number of nonexistent (dummy) disks so that DOS is forced to present the desired letter-name to RAM-disk.

As far as I know, three attempts to create such driver have been a success. However, freeware versions of such drivers don't hide dummy disks, and the one version which does hide is not a freeware. Therefore, one more (4th) attempt of my own is presented below. It doesn't follow known solutions. It is undertaken especially for making driver's peculiarities more clear and easy to understand. The proposed driver is tiny: 503 bytes total. Let it be named SKIPDSK.SYS.

SKIPDSK.SYS driver is produced by debugger DEBUG.EXE as a result of command sequence execution. This command sequence should be written into command file SKIPDSK.SCR and should be sent to debugger via input redirection :

The SKIPDSK.SCR file should be prepared by means of editor program (as described in introduction article to chapter 9) according to the text presented below. Verbal comments may be omitted, but proper offset values in comments should be preserved in order to make further debugging and testing easier. Unlike ordinary executable files, drivers are loaded starting from offset 0000h, i.e. without reserved space for PSP (A.07-1). Because of this reason start command for assembling drivers must be not "A 100", as for ordinary programs, but "A 0000". If start address is specified otherwise, a muddle occurs in displayed target offsets.

One more specific feature is that DOS drivers have two entrance points, and neither of these coincides with driver's code start address. The first entrance point, related to strategy routine, is used to accept a request and to initiate its execution by the corresponding device (a printer, disk drive, etc.). The second entrance point, related to interrupt routine, is used to gather the result and to form a response to the accepted request. Time in between is spent in parallel by DOS and by physical devices, each performing its own job. Entrance points are announced in driver's header: for strategy routine at offset 0006h, for interrupt routine at offset 0008h. These and other elements of driver's header are shown in table A.05-1.

Resident part of strategy routine in SKIPDSK.SYS driver is represented by section 3 of assembler text. It is simple and just writes segment address and offset of request data block (A.05-3) into a prepared memory cell. Strategy routine of SKIPDSK.SYS driver has no non-resident part.

All request-specific operations are performed by interrupt routine, which starts in section 5 of assembler text. Section 5 begins with saving states of flags and registers — this is also a specific responsibility of any driver. Then a code of requested operation is checked. As far as SKIPDSK.SYS driver "serves" dummy disks only, requests with operation codes greater than 01h must always cause a return to DOS with "invalid media" status byte. But requests for operations 00h and 01h invoke execution of commands, presented in sections 7–11 or in section 4.0.

The first request to driver is always for initialization with operation code 00h. Since initialization is requested only once, the corresponding sections 7–11 are beyond driver's resident part. Commands in section 7 prepare data for further use, commands in section 8 read letter-name of the disk to be skipped from command line, commands in section 9 are always ready to display an error message. Templates for error messages are prepared yet in section 12. Commands in section 10 calculate number of dummy disks and actual length of driver's resident part. Commands in section 11 fill request block with data, which should be returned to DOS. According to these data DOS corrects its DPB (A.03-1) and CDS (A.03-3) tables so that disk's letter-names up to the one specified appear busy. When later a RAM-disk driver will be initiated, it will be given the next free letter-name, which is thus predetermined by SKIPDSK.SYS driver.

While assigning a letter-name to RAM-disk, DOS must consider the declared dummy disks valid. But afterwards their valid status confines further letter-names assignment. A mixture of actual disks and dummies causes confusion. Therefore, the next task for SKIPDSK.SYS driver is to disable dummy disks. For this purpose SKIPDSK.SYS must be activated once more.

For the second time SKIPDSK.SYS is activated by a request for "media check" operation (code 01h), because it precedes all other requests, addressed to removable disks. Besides that, DOS automatically requests media check operation, when interpretation of CONFIG.SYS file completes. In response to media check request the SKIPDSK.SYS driver executes commands in its resident section 4.0. These commands determine address of the first dummy CDS record, and then perform a cycle of writing an invalid attribute word 0000h into all dummy CDS records. After that all "dummy" disks become hidden and are considered invalid. Their former letter-names may be assigned to CD-ROMs and to network drives.

When former letter-name of a dummy disk is given yet to another driver, then writing of attribute word 0000h into the same CDS record must be prohibited. Therefore, one of commands in 4th section writes a mark FFh into a memory cell at offset 02Fh. Presence of this mark is checked each time when interrupt routine of SKIPDSK.SYS driver is called for. Owing to this check repeated requests to SKIPDSK.SYS driver can't impair proper access to other disks, which have got former letter-names of dummy disks.

More detailed explanation of particular operations can be found in comments to lines of assembler text file SKIPDSK.SCR.

As in most assembler texts, it is important to note an empty line, the 9th from the end. It forces DEBUG.EXE to exit assembler mode of operation and therefore must be present. The next line with "M" command (6.05-11) moves the whole assembled code 100h bytes further, thus making PSP area free. This is necessary in order to specify driver's name, which is to be written just into PSP area and is announced in the following line by "N" command (6.05-12). Concluding lines of SKIPDSK.SCR file prepare length of driver's file in BX:CX registers and write the SKIPDSK.SYS driver to current disk.

Produced file SKIPDSK.SYS shouldn't be considered valid until its listing is thoroughly checked, as it is described in article 9.07-01. The last actual offset in listing is given in response to the mentioned empty line — the 9th from the end of text. As far as assembling started from address CS:0000h, this last offset must be 01F7h, exactly the same as total driver's length, specified in the 8th and 3rd lines from last. If listing reveals no errors, there is a chance for SKIPDSK.SYS to pass tests successfully.

While arranging tests it should be taken into account that for reasons of simplicity and compact size the capabilities of SKIPDSK.SYS driver are limited. It can't affect allotment of disk's letter-names, which are already assigned. It can't accept letter-name specification, preceded with a slash. It can't tolerate tabulation code (09h) instead of a space (20h) in its command line. Finally, it can't work under MS-DOS versions earlier than 4.0.

In practice a necessity may arise to reassign "dummy" disk's letter-names before interpretation of CONFIG.SYS file is finished. For this purpose a media check request to SKIPDSK.SYS driver should be provoked earlier, for example, by the following commands : In this example the letter-name Q: will be assigned to the last dummy disk, and RAMdisk will be given the next letter-name R:. In the last line an explicit appeal to "dummy" disk Q: provokes media check request, and since that moment all "dummy" disk's letternames become free for reassignment by software, which may be loaded afterwards by INSTALL= or INSTALLHIGH= commands. One more similar example of SKIPDSK.SYS driver usage is presented in article 9.09-01.

9.09 Exploratory configuration files
Versions of configuration files CONFIG.SYS and AUTOEXEC.BAT suggested in this article implement several loading modes. Besides MS-DOS 7 loading in an ordinary way, it can be relocated to RAM-disk or to a HDD, and also can be loaded without drivers, as it should be done for RAM testing and for reprogramming BIOS memory chips. Main advantage of proposed configuration files is that a choice of the most suitable loading mode is not necessarily "blind", it can be based on results of preliminary tests. If you prefer MS-DOS 7 relocation onto a RAM-disk, its size choice will be based on results of XMS-memory investigation. If you prefer MS-DOS 7 relocation onto a HDD, you will be informed in advance about which disks are available, about total size and usage percent for all writable disks.

When operating system loading procedures are not completed, then hardware tests can't be performed just as though operating system were loaded yet. Therefore, here disk's tests can't be arranged exactly as in file DISK.BAT (9.03-02). Because of the same reason standard DOS's means are not enough, some other drivers and utilities have to be employed. On the other hand, during OS loading some simplifying assumptions can be adopted. It is assumed that the current disk is the one used to load MS-DOS 7, that the directory structure on this disk is known, and it is known also, which loading operations are not performed yet at each stage. Due to the last assumption, in particular, there is no need to identify RAM-disks and CD/DVD-ROM drives.

Suggested configuration files are most suitable for loading MS-DOS 7 on AT-compatible computers with unknown hardware configuration. Loading adaptation capabilities are especially essential for repairing services.

9.09-01 Multi-alternative CONFIG.SYS file
This version of CONFIG.SYS file presents 5 loading alternatives listed in [menu] section. Several of these alternatives include operations, which can't be performed by standard DOS's means. In particular, an opportunity to adapt RAM-disk's size is implemented by a freeware version 2.42 of TDSK.EXE driver (5.05-02). Suitable replacements for this driver are not known. Besides that, the SKIPDSK.SYS driver (9.08) is used, which you may make yourself. Potentially JDRIVE.SYS driver from JAMSOFT can be used instead, but it is not free.

Data and parameters for other employed drivers can be found in chapter 5. These drivers either are included in WINDOWS-95/98 release or have close equivalents, therefore their choice is not critical. Naturally, each replacement implies command line parameters correction according to driver's requirements. Text of proposed CONFIG.SYS file is presented below. Text of CONFIG.SYS file starts with [menu] section. There are 5 items, each having an explicit header and a name code (L029 – L104). Choice of an item with some name code initiates interpretation of commands in synonymous section of CONFIG.SYS file.

Besides this, name code of selected item is automatically assigned as a value to CONFIG environmental variable; this value is used later in order to select corresponding part of other configuration file — AUTOEXEC.BAT. For this purpose items in menu are named after label marks in AUTOEXEC.BAT file (9.09-02).

Choice of menu items L029, L031, L047, L048 causes loading of almost the same sets of drivers, defined in sections [L047] and [L048]. The only difference between these sections is in their line 2: driver UMBPCI.SYS (5.04-04) gives access to upper memory in CPU's real mode, whereas driver JEMM386.SYS (note 4 to 5.04-02) gives similar access in V86 mode. Both sections L047 and L048 include loading of XMS-memory driver, driver for access to CD/DVD-ROMs, "mouse" driver and some others. Note that TDSK.EXE driver for arranging a RAM-disk, unlike most others, is loaded into conventional memory, and that RAM-disk's size is not specified here. If arranging of a RAM-disk will be considered expedient, its size should be specified later, during interpretation of AUTOEXEC.BAT file (9.09-02).

Sufficient differences between configurations L029–L048 also evince themselves later, during interpretation of AUTOEXEC.BAT file, except one configuration, defined by menu item L104. Corresponding section [L104] includes DOS settings only, without drivers and TSRs. The last section in CONFIG.SYS file is section [common], which is executed in any case. It loads command interpreter COMMAND.COM.

All paths in lines of CONFIG.SYS file don't include disk's letter-name and therefore are suitable for loading from any disk. A care should be taken about presence of all mentioned drivers and other files in prescribed directories. Path changes are not prohibited, but affect conditions of AUTOEXEC.BAT file execution (9.09-02) and therefore must be made consistent.

Proposed CONFIG.SYS file should be typed as non-formatted text and saved in the root directory of bootable removable media — either a diskette or a flash card, dedicated for loading MS-DOS 7 onto AT-compatible computers with unknown hardware configuration.

9.09-02 AUTOEXEC.BAT file for adaptive loading
This version of AUTOEXEC.BAT file implements exploratory and adaptive capabilities of MS-DOS 7. For this purpose the REASSIGN.COM utility is used, which may be assembled by yourself (9.06). Full-functional replacement for REASSIGN.COM utility is not known.

In order to make orientation in AUTOEXEC.BAT file more easy, label marks include corresponding line numbers; for example, label L029 denotes line 29. Besides that, each tenth line is a comment announcing the line number.

Local variables in AUTOEXEC.BAT are named V0–V8. One of them, V8, has no permanent mission. Dedicated missions of the rest local variables are :
 * V0 – list of disks, selected for being tested
 * V1 – size of the largest free XMS-memory block
 * V2 – recommended size of RAM-disk
 * V3 – candidate target disk for relocation
 * V4 – current disk, used to boot the PC
 * V5 – writeability status of the current disk
 * V6 – list of inaccessible or non-writable disks
 * V7 – list of writable disks

Text of AUTOEXEC.BAT file version for adaptive loading is presented below. Specific features of this AUTOEXEC.BAT file version begin with a conditional jump in line 2, which enables to execute recursive calls for internal subroutines. But jump conditions are not met, when AUTOEXEC.BAT is interpreted for the first time. Then in lines 3–5 values are assigned to environmental variables PROMPT and PATH. Value of PATH variable is not final; it will be replaced by final value after DOS relocation. The REASSIGN.COM utility is called for the first time in line 8 in order to determine letter-name of the current disk. Errorlevel value, returned by REASSIGN.COM utility, helps to compile a list of disks, selected for being tested. The next time REASSIGN.COM utility is called for in line 15 in order to ascertain availability of XMS-memory and determine size of the largest XMS-block. This time the returned errorlevel value prompts recommended size of RAM-disk, which may be arranged later. If XMS-memory is found unavailable, then in 21st line a value of CONFIG variable will be altered so that certainly unsuccessful attempts to arrange a RAM-disk will be prevented.

An important jump is performed by GOTO command in line 22: it makes further processing consistent with menu item user's choice, defined by value of CONFIG environmental variable. If quick loading has been chosen, then jump leads to labels L029 or L031. There in line 34 the TDSK.EXE driver arranges a RAM-disk of prescribed size and assigns the letter-name of RAM-disk to environmental variable RAMDRIVE. This is just the time to remind that RAMDRIVE variable is defined by the only version 2.42 of TDSK.EXE driver. If earlier versions of that driver or other similar RAM-disk drivers are used (BITDISK.EXE, SRDISK.EXE, XMSDSK.EXE), then fixed value R: should be assigned to RAMDRIVE variable by SET command (3.26). Naturally, opportunities of RAM-disk letter-name adaptation will be lost.

When the prescribed size of RAM-disk is not large enough, then a jump in line 37 leads to termination part without DOS relocation, and RAM-disk will be used exclusively as a place for temporary files. But normally size of RAM-disk is enough to relocate DOS, and then a jump in line 36 leads to label L086 – to DOS relocation part of AUTOEXEC.BAT file.

Relocation part of AUTOEXEC.BAT file is composed so that it can be used for DOS relocation to RAM-disk and to any non-empty physical disk as well. Therefore, relocation procedure begins with removing file's attributes in target directories, because otherwise standard DOS' utilities can't overwrite synonymous files there and even can't determine their presence. Operation in line 89 creates a typical structure of target directories, if it didn't exist before. Then files AUTOEXEC.BAT and COMMAND.COM are copied into directory %V3%\DOS. If copying is a success, then in line 97 all the rest files are copied to their target directories, and new values are assigned to COMSPEC and to V4 environmental variables. Command in line 103 transfers control to a copy of AUTOEXEC.BAT file in target directory %V3%\DOS so that a return to original AUTOEXEC.BAT file wouldn't happen, and execution of the copy starts from its 105th line.

If the user originally has chosen a user-configurable loading alternative, then a jump from line 22 leads to labels L047 or L048, where disks exploration procedure starts. Disks exploration is performed by subroutine L117, which is a part of the same AUTOEXEC.BAT file. It is called recursively from cycle FOR in line 53, separately for each disk under test. Subroutine L117 undertakes first attempt to access the submitted disk in line 118 in order to check whether it is readable. If disk is not readable, then a jump to label L152 follows, where the next test in line 156 is to discriminate between nonexistent drives and those having no formatted media inside. Nonexistent drives are ignored, but all others are added to list of inaccessible disks, represented by value of V6 environmental variable. As far as status of these disks may be changed, their testing may be repeated.

If disk proves to be readable, then the next examination is writeability test, performed by subroutine L141. It is called from line 122 by a separate module of command interpreter COMMAND.COM. The decisive operation is in line 144: there intermediate redirection implies creation of a temporary file on the submitted disk. If this temporary file can't be created, then the SHIFT command in the same line wouldn't be executed, dummy parameters wouldn't be shifted, subroutine L141 will exit in line 145, and commands in lines 133–134 will add letter-name of this non-writable disk to list of inaccessible disks. If redirection in line 144 can create a temporary file, it will be deleted automatically just afterwards, but the SHIFT command will be executed, the ECHO command in line 148 will display a confirming message, and the DIR command in line 149 will display usage of disk's space. Then in line 151 subroutine L141 terminates, and letter-name of writable disk in lines 126–127 is added to list of accessible disks, represented by value of environmental variable V7.

Disk exploration subroutine L117 terminates either at line 128 or at line 135 – it depends on test result. In both cases control is returned to cycle FOR in line 53. Then subroutine L117 will be called again and again until a list of disk's letter-names, represented by value of variable V0, comes to end. When all disks are tested, the results together with suggested alternatives are displayed to the user by commands in lines 56–65. The user is offered to choose the most suitable alternative. User's answer is accepted by REASSIGN.COM utility in line 69. As far as user's response may be expressed by both upper-case and lower-case letters, commands in lines 74–77 turn any accepted letter to upper case, and then conditional commands in lines 78–85 fulfill user's will.

A check in line 78 is to clear up whether the returned letter is the letter-name of RAMdisk. If yes, then a jump to label L031 is performed, and all the following events repeat the scenario of quick loading onto a RAM-disk just as it was described above. In case of any other choice cycle FOR in line 81 searches for the returned letter through list of inaccessible disks. If the letter is found, then a jump to L042 follows. There in line 45 the L117 exploratory subroutine is called in order to test the selected disk more thoroughly. Thorough mode of investigation, defined by the fourth parameter "S", implies other test criteria and more detailed prompts about the ways to regain disk's accessibility. Subroutine makes a pause, allowing to change removable disk or to close write-protection hole in its cartridge. After that in line 53 a normal call follows for the same subroutine L117 in order to update lists of inaccessible and writable disks, and then the user is offered to make his choice once more.

User's choice of DOS relocation onto a writable disk is registered by cycle FOR in 83rd line. In this case execution proceeds through label L086 to DOS relocation part of AUTOEXEC.BAT file. Relocation procedure is performed just as it is was described above for RAM-disk. It is important to note that DOS relocation procedure doesn't make the selected disk bootable, it only allows to continue current DOS session after removing bootable media from that storage device, which was used to boot the PC. As far as DOS relocation procedure doesn't write files in the root directory, original bootability of the selected disk also can't be affected.

The disk used to boot the PC also may be writable, and its letter-name can be included in the list, represented by value of V7 variable. But DOS relocation onto this disk is senseless and should be avoided. This is why a check in line 84 intercepts such user's choice and directs further execution to label L104. Thus DOS relocation is bypassed. As far as bootable disk is writable, it also will be used as a place for temporary files. However, ordinary 1.44 Mb diskettes have no place enough for temporary files; any other writable disk should be preferred. Therefore, the user is given one more chance to bypass DOS relocation: the ESC keystroke forces a jump from line 73 to the same target label L104, but in this case an attempt will be undertaken to find a place for temporary files on some other suitable disk.

The last item in boot menu (9.09-01) is loading without drivers and TSRs. User's choice of this alternative also leads to the same label L104 via a jump from line 28. But before that in line 24 the exploratory subroutine L117 is called in quiet mode, defined by its fourth parameter Q. Detailed exploration is skipped, intermediate messages are not displayed. In this case the only purpose of exploration is data preparation for warning messages, displayed in lines 25–27.

Label L104 denotes final part of AUTOEXEC.BAT file, where all loading alternatives converge. Cycle FOR in line 105 appoints a writable disk for temporary files, if this appointment was not made yet. Operations in lines 106–114 prepare final values for TEMP, DIRCMD and PATH environmental variables, and delete local variables V0–V8. Unless special loading alternative L104 is chosen, the Volkov Commander file manager is launched. The last operation in AUTOEXEC.BAT file is an unconditional jump to final label END.

This version of AUTOEXEC.BAT is to be stored in the root directory of a removable bootable media. Those files, which are called from lines of AUTOEXEC.BAT file, must be present in specified directories of the same media. It is implied that command interpreter COMMAND.COM is present in the root directory, files ATTRIB.EXE, FIND.EXE and LABEL.EXE are present in \DOS\MS7 directory, utilities REASSIGN.COM and BLUE.COM in \DOS\OTH directory, driver TDSK.EXE (version 2.42) in \DOS\DRV directory, files VC.COM and VC.OVL in \DOS\VC4 directory. Naturally, presence of other files in these directories is allowed. If you intend to implement other file's allocation or other directory structure, then all affected path specifications should be corrected accordingly.

9.10 Experiments with linear addressing
It is often thought that modern 32-bit CPUs in real mode can't address to memory space beyond 1088 kb. Though this opinion is not denied explicitly in official data, nevertheless it is wrong. Since early 1990s several reports have proclaimed usage of undocumented CPUs features for access to extended memory. Tomas Roden is believed to be author of the idea.

Analysis of HIMEM.SYS (5.04-01) driver's code evinces presence of all necessary elements for providing access to extended memory in real mode. May be, this is just what HIMEM.SYS does, but no official confirmation for that has been published. Despite considerable age of this topic, idea of linear 32-bit addressing in real mode is still a matter of rumors.

Now there is no need to prove the possibility of linear addressing in real mode, but there is a need to demonstrate effective implementation of the idea. Therefore, part 9.10 of this book presents texts of two tiny utilities : GS_LIMIT.COM utility takes off segment boundary protection from GS register, and GS_DUMP.COM displays a dump of memory area, pointed at by a given 32-bit linear address. Effect of presented utilities is shown in fig.7: that memory area, which has just been inaccessible beyond segment limits, becomes accessible after a call for GS_LIMIT.COM utility. Those who dare to implement the presented examples will get a unique chance to look into all the corners and foldovers of 32-bit address space.

9.10-01 Segment protection switching on/off
As calculated linear address goes beyond segment boundaries, CPU's segment protection becomes actuated and ruins all hopes to get any benefit from address size override prefix (7.02-07) in real mode. However, the problem is not so hopeless as it seems at a first glance. All modern processors, starting from 80386 model and on, are able to change segment size. When segment size is made equal to highest address space limit, then any calculated segment address will be found allowable, and segment protection in fact becomes turned off.

Is it good or bad to turn off segment protection ? On one hand, this will cause total loss of stability in multi-tasking operating systems. On the other hand, this will open new opportunities for service and diagnostic programs in DOS operating environment. As any effective instrument, turning off segment protection may be both beneficial and dangerous. Therefore, CPU designers have been very cautious about control over segment protection. An opportunity to set arbitrary segment size has been given to protected mode software at the highest (zero) privilege level only.

When in protected mode at the highest privilege level the operating system core is active yet, then all other programs have no chances to get access to critical CPU's settings. But chances are, while CPU operates in real mode: any real mode program may switch CPU into protected mode, set maximum segment size in a "shadow" register, and then switch CPU back into real mode. After that linear 32-bit addressing with respect to affected segment register will be available without a risk to cause actuation of segment protection. This is, in short, the main idea, implemented by the proposed utility.

For the role of affected segment register the GS segment register is chosen, because its usage by real mode programs is not common. Besides that, properly composed programs don't violate segment limits intentionally. The author has tested many ordinary DOS programs, not aimed at GS segment status determination. All such programs have behaved identically both with and without GS segment limit protection.

Because of GS segment register choice the suggested utility has been named GS_LIMIT.COM. It differs from its known counterparts in that it is able to perform its mission not under "bare" DOS only, but also in cooperation with HIMEM.SYS driver (5.04-01). Second difference is that GS_LIMIT.COM is able to turn segment protection both OFF and ON. In order to turn protection OFF you have to specify a command

Restoration of standard 64-kb limit for GS segment is initiated by command

If neither of the shown parameters (OFF or ON) is specified, the GS_LIMIT.COM utility displays a short help.

GS_LIMIT.COM utility (662 bytes long) is produced by debugger DEBUG.EXE as a result of command sequence execution. This command sequence should be written into command file GS_LIMIT.SCR by means of editor program (as described in introduction article to chapter 9). Verbal comments may be omitted. Special attention should be paid to empty line – 8th from the end. It must be there, because empty line forces DEBUG.EXE to exit assembler mode (7.01-04). Then command file GS_LIMIT.SCR should be sent to debugger via input redirection : Debug.exe < GS_limit.scr Command file GS_LIMIT.SCR has to contain the following lines: Assembler text starts in section 1 with ordinary release of allocated memory excess (note 5 to A.12-7). Then parameter's presence check is performed. Form of parameter's presentation is chosen so that parameters are automatically uppercased and written into first FCB (note 4 to A.07-1) inside program's PSP. If required parameters are not specified, then in line 123 a jump occurs to final section, where help message is displayed. After that utility comes to end, leaving errorlevel code 01.

When required command line parameters are specified, execution continues from line 148 in section 3, where two conditions are checked: CPU's suitability and its operation in real mode. The essence of these checks is described in notes 2 and 3 to appendix A.11-4. If either of conditions is not met, then jumps occur to final section, where corresponding error message is displayed, and execution comes to end, leaving errorlevel codes either 04 or 08.

When CPU checks are passed successfully, execution continues from line 16F in section 4, where state of address bus line A20 is prepared. Necessity of such preparation is not obvious, but has been confirmed. Address bus line A20 must be switched ON. If HIMEM.SYS driver is installed yet, its function AH=05 (A.12-3) should be called for in order to switch ON the address bus line A20. If HIMEM.SYS driver is not installed, then a subroutine 022F from section 11 should be called, which attempts to switch ON the address bus line A20 by means of keyboard controller (details in note 1 to A.11-3).

Initial and final states of address bus line A20 are checked in lines 18B and 19B by calls for subroutine 021C in section 10. If attempts to switch ON address bus line A20 fail, then in line 1A5 a jump will be performed to final part of program. There an error message is displayed, and program's execution comes to end, leaving errorlevel code 02. Normally at least one attempt to switch ON address bus line A20 is a success, and then execution continues from line 1A7 in section 5.

Commands in section 5 prepare a pseudo descriptor for GDT table. Address of GDT table is copied from this pseudo descriptor by CPU into its GDTR register. In line 1AC segment address CS is transformed into linear address by shift 4 bits leftwards. Summation in line 1B2 forms linear address of GDT table inside pseudo descriptor template (in lines 12A–12F of section 2).

Detailed structure of GDT table's descriptors is shown in appendix A.12-2. Second and third descriptors are prepared for data segments. In line 138 the second descriptor (selector 0008) defines 4 Gb segment size. It should be used to switch off GS segment protection. In line 140 the third descriptor (selector 0010) defines 64 kb segment size. This descriptor should be used in order to restore back normal protection for GS segment. Before CPU is switched to protected mode, in register CX that selector should be prepared, which corresponds to requested task. A choice between those two selectors — 0008 and 0010 — is made by commands in lines 1B6–1C0 of section 6. Following commands in section 6 prohibit interrupts, including NMI (details in note 1 to article 8.01-03).

The first command in 7th section is LGDT (= Load Global Descriptor Table), which loads data from GDT pseudo descriptor into CPU's GDTR register. DEBUG.EXE doesn't "know" the LGDT command, therefore its code (0F 01 16) is introduced as data by DB instruction. The last two bytes in LGDT command — 2A 01 — represent pseudo descriptor's offset counted from segment address in DS register, i.e. just number 012A of a line, where pseudo descriptor's template is prepared in section 2 of assembler text.

CPU transition to protected mode can be performed by INT 15\AH=89h function (8.01-78), which requires a larger GDT table and reprograms both interrupt controllers. As far as proclaimed task implies a return to real mode, later a backward reprogramming will be needed for interrupt controllers. In order to avoid excess complexity, transition to protected mode is performed here by setting the PE bit (PE = Protection Enable) in CPU's CR0 register (A.11-4). Therefore, a command in line 1CF copies contents of CR0 register into AX, in this copy the PE bit is set, and then in line 1D4 the altered copy is written back into CR0 register. Commands concerning CR0 register (note 1 to 7.03-58) are not "known" to DEBUG.EXE and hence are introduced in lines 1CF and 1D4 as data following DB instruction.

Of course, PE bit setting is not sufficient for obtaining a full-functional protected mode, but in this case full functionality isn't required. In protected mode the GS_LIMIT.COM utility must perform a single operation: write into GS segment register that selector (0008 or 0010), which is prepared yet in CX register. Command copying CX contents into GS (note 2 to 7.03-58) is not "known" to DEBUG.EXE, and therefore its code is introduced in line 1D7 as data after DB instruction. Copying of a prepared selector into GS register brings about that hidden event, which is the main goal of GS_LIMIT.COM utility: new contents, including new segment limit, is written into CPU's GS "shadow" register from the GDT descriptor, pointed at by the copied selector.

When summit is reached yet, it's just the time to begin descent back. First of all, the PE bit must be cleared in that code, which is still preserved in EAX register since it has been copied from CPU's control register CR0. Command in line 1DB writes this twice altered code back into CR0 register. Thus CPU is returned into real mode. The commands in section 8 cancel interrupt prohibition and restore initial state of address bus line A20 by just those facilities, which previously have altered this state. Commands in lines 1FB–215 of section 9 select appropriate final message and display it. In lines 218–21A a call for DOS's INT 21\AH=4Ch function terminates execution of GS_LIMIT.COM utility.

After its termination the GS_LIMIT.COM utility leaves errorlevel code, which may present a separate interest in order to determine CPU's operating mode: The last peculiarity of GS_LIMIT.COM utility is that the value, left behind in GS segment register, retains status of a selector. This enables to experiment with improper linear addressing in CPU. After any operation, writing a new value into GS register, its contents will acquire proper status of a segment address.

9.10-02 Display of a linearly addressed dump
The GS_DUMP.COM utility, presented in this article, shows a 128-byte memory dump on the screen, almost as DEBUG.EXE does in response to its "D" command (6.05-04). The main difference is that GS_DUMP.COM utility instead of ordinary addresses (segment: offset) accepts 32-bit linear addresses, which enable to define just any access point within 4 Gb address space. While segment protection is active, GS_DUMP.COM utility responds with an error message to all requests for access beyond GS segment. But when GS segment protection is switched OFF by GS_LIMIT.COM utility (9.10-01), then dump of any memory region within 4 Gb address space can be displayed.

Besides its obvious demonstration effect, GS_DUMP.COM utility provides answers to many questions, concerning practical implementation of linear addressing in real mode. In command line the name GS_DUMP.COM must be followed by linear address, composed of up to 8 hexadecimal digits, for example :

Specified linear address is interpreted as absolute address, counted from the start of address space irrespective to actual contents of GS register. After linear address there may be one of two optional parameters :
 * A – don't alter initial state of address bus line A20 ;
 * R – write zero into GS segment register.

Command line with an optional parameter may look, for example, as

When address bus line A20 initially is not active, GS_DUMP.COM utility with "A" optional parameter shows address space foldover at address 100000h. By default GS_DUMP.COM utility activates address bus line A20 and always shows address space opened irrespective to its actual initial state.

GS_DUMP.COM utility (1291 bytes long) is produced by debugger DEBUG.EXE as a result of command sequence execution. This sequence should be written into command file GS_DUMP.SCR by means of editor program (as described in introduction to chapter 9). Comments may be omitted. Special attention should be paid to empty line – 8th from the end. It must be there, because it forces DEBUG.EXE to exit assembler mode (7.01-04). Then command file GS_DUMP.SCR should be sent to debugger via input redirection :

Command file GS_DUMP.SCR must contain the following lines : Program starts in section 1 with ordinary release of allocated memory excess (note 5 to A.12-7). CPU checks and protected mode checks are performed exactly as in GS_LIMIT.COM program (9.10-01). But in case of protected mode the GS_DUMP.COM utility is not terminated at once; investigation continues in section 3. If protected mode is controlled not by WINDOWS OS, but by compatible IBM's version 4.50 of EMM386.EXE driver (5.04-02), then execution proceeds further.

In the 4th section linear address, specified in command line, is read into EBX register. In course of reading the ASCII code characters are translated into "raw" code and are checked for correctness. If something else is found there except correct hexadecimal digits, then GS_DUMP.COM utility displays error message and terminates.

In the 5th section of GS_DUMP.COM the address bus line A20 is activated just as it is activated in section 4 of GS_LIMIT.COM program (9.10-01).

Important specific operations in GS_DUMP.COM program begin with preparation of GS register in section 6. Preparation is needed, because contents of GS register may retain status of a selector. In order to get rid of uncertainty, command in line 1E6 performs writing into GS register. Even when contents of GS register should be preserved, command in line 1E6 writes in GS register just that value, which has been read from GS register by a command in preceding line 1E4. After writing operation the contents of GS register acquire normal status of a segment address.

Commands in final lines of 6th section display GS segment address. After that commands in lines 201–20B of 7th section calculate datum point byte and base address, i.e. linear address of the first byte in a line of dump. In line 218 a shift 4 bits leftwards transforms GS segment address into linear address. In line 21F a difference between base address and GS linear address is calculated. This difference represents just that offset, which is necessary for reading data at absolute address, specified by the user in command line.

As far as absolute address reading operation is not necessarily directed within allowed segment limits, it may invoke generation of exceptions INT 0D, INT 0E (notes 6 and 7 to 8.01-09) and INT 11 (note 1 to 8.01-42). Each of these exceptions will cause computer's hanging, unless some special precautions are taken in advance. Exception INT 11 can be prevented by clearing misalignment control bit (12h) in EFLAGS register (A.11-4). Therefore, commands in lines 226–235 copy EFLAGS register contents into stack, initial state of the third read byte is stored in a 03C4 memory cell, misalignment control bit is cleared just in stack, and the altered result is written back from stack into EFLAGS register.

Exceptions INT 0D and INT 0E can't be prevented, processor inevitably will generate these exceptions at attempts of access to protected memory regions. Calls for exception handlers can be intercepted, but in real mode it is difficult to discriminate between CPU's calls for exceptions and external interrupt calls, received via IRQ 5 and IRQ 6 lines of interrupt controller (8.01-09). In order to avoid confusion the GS_DUMP.COM program prohibits reception of external interrupts via lines IRQ 5 and IRQ 6 for the time needed to display the dump. For this purpose commands in lines 236–23D read mask of 21h port, save its initial state in memory cell 03C5, set bits 05 and 06 in this mask, and write the altered mask back to port 21h.

Suitable replacements for INT 0D and INT 0E exception handlers are prepared beforehand in section 13 of GS_DUMP.COM program. Commands in 13th section make return address correction in stack and then return control back to interrupted program. Return address correction prevents hanging in a cycle of single command execution and enables resumption of interrupted program execution from the next command. Prepared handler's replacements are made active by commands in lines 23F–24D of section 8. These commands fill memory cells 03C8 and 03CC with actual segment address, and then twice call for subroutine 03A0, which exchanges interrupt handler's addresses in interrupt table with those prepared in memory cells 03C8 and 03CC. Since that moment the GS_DUMP.SYS program eliminates threat of computer's hanging caused by CPU's exceptions INT 0D and INT 0E.

As far as access rights in address space can be changed with discreteness not less than 16 bytes, readability of all bytes inside a 16-byte paragraph can be determined by one trial access attempt, undertaken in line 257 of section 9. When trial byte is accessible, then CPU while performing the LODSB command (7.03-53) in line 257 increments offset in register SI by 1. But when reading request causes segment protection actuation, then LODSB command is not carried out, and SI register doesn't get its increment. Command in line 258 compares current value in SI register with the former one, saved in 03CE memory cell. Equality of the compared values is an evidence of segment protection actuation. If CPU responds to trial access with segment protection actuation, then further attempts of access to any byte in the same paragraph are useless. For such lines of dump the following commands in section 9 display linear address, display a message about protection actuation, and calculate linear address for the next line of a dump. Then a jump follows to line 286, where number of currently displayed line in a dump is checked. If it is not the last line in dump, then a return is performed to start of trial access procedure, which is to be repeated for the next line of dump.

If SI register contents values, compared in line 258, happen to be different, then a jump from line 25C leads to the main dump display procedures in section 10. These procedures include a call for 0349 subroutine in order to display base linear address, a cycle 26E–273, displaying 16 bytes of dump, and then cycle 278–27D, displaying the same 16 bytes as codes ASCII. If current line of dump is not the last one, then a return is performed to start of section 9, where all the same operations will be repeated for the next line of dump. When dump processing is finished, commands in section 11 restore initial states of all affected elements. Subroutine 03A0 is called twice in order to restore former handler's addresses for interrupts INT 0D and INT 0E. Commands in lines 293–2A3 restore former mask in port 21h and former state of EFLAGS register. Commands in lines 2A4–2B6 restore former state of address bus line A20.

Having restored initial states, GS_DUMP.COM utility proceeds to concluding section 12. If dump has been displayed successfully, then final message is not displayed, and errorlevel is set to zero value. But if attempt to display a dump has failed, then the same operations in lines 2BF–2C4 display an error message. In line 2C7 a call for DOS's INT 21\AH=4Ch function terminates execution of GS_DUMP.COM utility.

Note 1: errorlevel code, left behind by GS_DUMP.COM utility, may present a separate interest. In particular, the largest errorlevel code 8 is left by GS_DUMP.COM utility after attempt of its execution inside the "DOS box" of WINDOWS OS. Registration of termination with errorlevel code 8 (3.15-03) enables to prevent execution of those programs, which shouldn't be launched inside "DOS box", for example, of the TURN_OFF.COM utility (9.05-02).

9.11 MS-DOS 7 loading alternatives
With respect to preservation of data and of main computer's operating system, any experiments with DOS are most safe when DOS is loaded from an external drive or from a removable media – a diskette, or flash card, or compact disc. This way of loading DOS, described in article 9.11-01, is common for emergency service. But it isn't sufficiently reliable for regular DOS usage, because in this role a lifetime of either removable media is not long enough.

For regular DOS usage a multi-alternative loading is arranged either by special boot managers or by loaders of some operating systems. Articles 9.11-02 and 9.11-03 describe usage for this purpose of WINDOWS-2000 and WINDOWS-XP loaders, and also of MS-DOS 7 itself, as far as initially it was devised for launching WINDOWS-95/98 operating systems. Of course, capabilities of MS-DOS 7 as a boot manager are poor, but it has a useful feature: compatibility with loadable BIOS extensions. May be, for alternative loading you'll have to choose just MS-DOS 7.

9.11-01 MS-DOS 7 loading from removable media
Ordinary 1.44 Mb diskette becomes bootable when a valid boot sector and DOS's system files are written onto that diskette. These operations under MS-DOS 7 are performed by SYS.COM utility (6.24). Under Windows you may download a selfextracting file-image of a bootable diskette via Internet, for example, from host http://1gighost.com/ed/jamiephiladelphia/ or from site http://anbcomp.com/files/bootdisk/. Versions without DOS relocation to RAM-disk (files boot95b.exe, boot98c.exe, boot98sc.exe) are preferable, since standard bootable diskettes employ relocation method which may fail in modern computers. Because of the same reason formation of a bootable diskette shouldn't be ordered to standard formatting procedure. However, the mentioned drawback isn't inherent to bootable diskettes with MS-DOS 8, prepared by formatting procedure under Windows XP.

Having got a standard bootable diskette for DOS, you most probably wouldn't be satisfied with its poor contents. Minimal suitable set of utilities you'll have to prepare yourself. Many utilities for MS-DOS 7 can be got from Windows-95/98 release. Bootable diskette images with better sets of software can be found, for example, in http://www.netbootdisk.com/ and in http://www.multiboot.ru/. Drivers and utilities, mentioned in configuration files in parts 6.25, 9.01, 9.04, 9.09 of this book, may be regarded as author's recommendations on compiling sets of software for bootable diskettes. Of course, in any case all specifications and paths in configuration files must correspond exactly to actual placement of drivers and utilities in the chosen bootable media. Your attempt to load MS-DOS 7 from diskette may fail because of inadequate parameter's specifications in BIOS Setup (about entering BIOS Setup in article 1.01). Type of your floppy drive must be specified properly in page "Main" of BIOS Setup. Besides that, page "Boot" of BIOS Setup must assign to floppy drive a higher boot device priority, than to fixed drive(s). In obsolete computers boot device priority was defined by order of disk's letter-names; therefore in page "Boot" a list of letter-names must start from letter "A", which denotes first floppy drive. In modern computers first floppy drive must be the first in a list of removable drives, and loading from removable drives must be given higher priority, than loading from fixed drives.

Unfortunately, active operating system on a diskette is too slow and causes intensive wear-out. It diminishes diskette's lifetime to 10–20 hours. Functioning becomes much more fast and reliable, if DOS is relocated from bootable diskette to a RAM-disk (examples in 9.04, 9.09). However, even in the latter case diskette can't be considered a fortunate bootable media. Slow and noisy DOS relocation procedure causes irritation. Besides that, total capacity of a diskette now seems insufficient. Optical discs seem much more attractive because of their greater reading speed, much larger capacity and longer lifetime. However, a long lifetime is inherent only to optical discs that are produced with fixed contents by matrix replication technology.

Writable discs implement quite different storage principle: decay of organic dye. An optically written track loses contrast each time it is read. Therefore, the active lifetime of writable optical discs is similar to that of diskettes. Rumors about reading speed are also half-true : track seek time in optical drives is about 100 mS, while in HDDs it is about 2 mS. Because of a short active lifetime and slow access, bootable optical disks need DOS relocation no less that floppy disks.

Some complexity is due to difference between optical disc's file systems and those "known" to DOS's core. Therefore, DOS can't be loaded immediately from optical disc. An image of other disk – a bootable disk with a "known" file system FAT12 or FAT-16 – must be written onto optical disc. BIOS system of your computer must be able to emulate a logical disk from this image, and only then MS-DOS 7 can be loaded from that emulated logical disk. If prototype for this image was a bootable diskette, then letter-name "A" is assigned to the emulated logical disk, whereas the real floppy drive is given the next letter-name "B". Almost all programs for writing optical disks are able to copy a bootable diskette into an image and to write this image on optical disc, thus making it bootable. For this role, no special preparation of bootable diskettes is needed. Configurations with MS-DOS 7 relocation onto a RAM-disk are quite suitable. Examples of such configurations are shown in parts 9.04 and 9.09. Of course, configurations should include those drivers and TSRs (5.08-04, 5.09-04), which enable access to optical disc's space beyond emulated logical disk and thus eliminate problem of its insufficient capacity.

DOS can't be loaded from optical disc, unless optical disc drive is registered by computer's BIOS system as bootable device. A list of registered bootable devices is shown on page "BOOT" of BIOS Setup program. In this list different BIOS versions specify either a class of device (for example, CD-ROM) or a particular type of device. A place of device in this list defines its priority. If optical disc drive is found there, then you have to specify that priority order, which will force BIOS to address optical disc drive before any of fixed disk drives is addressed. After that all you have to do is to insert a bootable optical disc into the drive in time before BIOS begins its start tests.

In modern computers registration of a drive by BIOS system may fail because of wrong specification of interface parameters. In order to check parameters of IDE interface you have to open page "Main" of BIOS Setup program and press button "IDE Configuration". A new page will be opened, where parameter "Onboard IDE operate Mode" should be given value "Compatible Mode", and parameter "Combined Mode Option" should be given that value, which corresponds to actual type of IDE connection. Nowadays most internal optical disc drives use parallel P-ATA connection. If there is no devices with serial S-ATA connection in your computer, then parameter "Combined Mode option" should be given the "P-ATA only" value, otherwise "P-ATA+S-ATA" value should be preferred. Any changes of interface parameters will have effect on a list of registered devices not at once, but after reboot.

In order to set parameters of USB interface, page "Advanced" of BIOS Setup program should be opened, and there button "USB Configuration" should be pressed. A new page will be opened, where parameter "USB Function" (or else "USB Controller") must have the "Enabled" value. This is enough for access to USB devices by means of drivers (5.07-05). But those BIOS systems, which enable to connect bootable devices via USB bus, provide more optional parameters. In latest versions of AMI BIOS there is parameter "Legacy USB support"; it must be enabled, if you intend to connect bootable devices via USB bus. It should be reminded that enabled state of "Legacy USB support" parameter may cause conflicts between BIOS and USB bus drivers (5.07-05), therefore USB bus drivers shouldn't be loaded in this case. If there are separate parameters for USB 2.0 controller in "USB Configuration" page, these parameters also should be given the "Enabled" value, and data transmission speed should be set to "HiSpeed".

As far as USB bus allows complex connection configurations, registration of bootable devices with USB interface may fail because of restrictions, imposed on BIOS startup tests. In order to remove these restrictions you have to open page "Boot" of BIOS Setup program, and there button "Boot setting configuration" should be pressed. A new page will be opened, where "Quick Boot" option should be disabled. Naturally, BIOS start tests will become about 3 seconds longer.

When BIOS system registers at least one storage device on USB bus, then in modern computers from page "USB Configuration" of BIOS Setup program you'll be able to open the next page "USB Mass Storage Device Configuration". In the latter page there is a list of all registered USB storage devices, and for each device the applied emulation method is shown. Inadequate emulation method specification can be one more reason of booting failure. By default emulation method is determined automatically, but errors may be caused by absence of media in the drive at the moment of test, by presence of unformatted media and even by media insertion just in course of tests.

Naturally, emulation method must correspond to class of device: for magnetic hard disk drives it should be defined as "Hard Disk", for external optical disc drives – as "CDROM", for external floppy drives – as "Floppy". But sometimes it isn't clear, which class of devices should correspond, for example, to a flash card. In such cases decision should be based on that flash cards with capacity 512 Mb and higher are always formatted as hard disks. For flash cards of smaller capacity a special emulation method may be applied – "Forced FDD", which means that the card will be presented by BIOS as "Big Floppy" irrespective to its actual format.

If you intend to subject a storage media to formatting procedure, then emulation method must correspond to the desired format type. Inaccurate emulation method specifications as "Forced FDD" and "Auto" may lead to unpredictable results. New unformatted storage devices are registered by BIOS, but are not given letter-names as logical disks. For their initial formatting modern programs should be preferred, for example, "Partition Magic" version 8.01 or higher. One of primary partitions must be made active. After a reboot the new partitions will be given letter-names, and then the active partition may be made bootable, for example, by SYS.COM utility (6.24). Configurations with relocation of MS-DOS 7 to a RAM-disk are not necessary, if the formatted media is indeed a hard disk.

Most BIOS systems wouldn't take control over those storage devices, which have media not emulated, but really formatted as "Big Floppy", i.e. without MBR. Normally such media are accessed by means of a driver, for example, ASPIDISK.SYS (5.07-03, 5.07-05). MBR can be written onto such media by utilities, mentioned in note 5 to article 6.13. After a reboot, BIOS will accept media with MBR as a HDD. Having been taken under BIOS control, such media can be treated as hard disk, can be formatted and made bootable.

When at least one storage device is recognized by BIOS system as a hard disk, then BIOS Setup program from its page "Boot" enables to open another page "Hard Disk Drives". There a list of all registered hard disk drives is shown. But only the first of these hard disk drives is regarded by BIOS as bootable device. If you want to boot the computer from an external storage device, registered as a hard disk drive, you should set this device in the first place in a list of drives in page "Hard Disk Drives" of BIOS Setup program. Just at once specification of the chosen storage device will appear in list of bootable devices on page "Boot Device Priority". There the chosen storage device must not necessarily be set in the first place, if devices with higher priority at that moment have no removable storage media inside.

Emulation method "Hard Disk" is suitable for storage devices with removable media, but with one required condition: the same removable media must be permanently present in this storage device since computer is switched on. Another removable disk in the same disk drive can't be read. If a storage device is emulated as hard disk, it will be assigned a lettername of hard disk. But if a removable storage media isn't present in this device at the moment when computer is switched on, then this storage device will get no letter-name at all. This may be beneficial, if your USB adapter has several slots for different types of flash cards, and you don't want to spend letter-names for those types of cards, which certainly wouldn't be used.

Storage devices, emulated as "Floppy" or as "Forced FDD", get a letter-name irrespective of presence or absence of their removable media. Those modern BIOS systems, which were tested by the author, allotted to these storage devices letter-names A: and B: only, and didn't allow to exchange initially inserted removable media. If computer has several such devices, then letter-names are assigned to the first two only; the rest such devices are inaccessible. If you intend to boot your computer from a storage device, registered by BIOS as a floppy, then you have to set it the first in a list on page "Removable Drives" of BIOS Setup program.

Now flash card adapters and solid-state storage devices with USB interface have became widespread. Such devices can be used for loading MS-DOS 7 and other operating systems. For this purpose storage devices with USB interface must be taken under BIOS control, just as external hard disk drives. Emulation method "Hard disk" should be attempted first. If storage device becomes accessible, hence it is formatted as hard disk. Otherwise emulation method "Forced FDD" should be preferred. In the latter case you have to check a place of corresponding storage device in a list on page "Removable Drives" of BIOS Setup program. It must be set there either in the first or in the second place, otherwise BIOS wouldn't allot letter-name to this storage device, and then it can't be addressed to.

If storage device is recognized as a hard disk, you have to check whether its primary partition has status of active (bootable) partition. As far as "Partition Magic" program deals with real HDDs only, partition's status in "fake" HDDs, physically represented by solid-state storage devices, should be checked and changed, if necessary, by FDISK.EXE utility, being launched with parameters  and   (6.13). Many BIOS versions don't provide bootability from HDD partitions with FAT-12 file system, but FDISK.EXE inevitably marks with FAT-12 all 16 Mb and smaller partitions. If necessary, partition table may be read (9.02-02) and written back (9.02-03) with file system identifier changed from 01h to 06h (A.13-6). After that the small partition concerned should be formatted by FORMAT.COM utility with  parameter (6.15), and thus will get the desired FAT-16 file system.

Second stage of solid-state bootable media preparation includes boot sector writing and DOS system files copying by SYS.COM utility (6.24). After that a DOS loading configuration should be prepared. Preferable configurations are those with DOS relocation onto a RAM-disk (9.04, 9.09), because many types of solid-state storage devices are slow, and all types of such devices withstand a limited number of overwriting cycles. According to the desired configuration on solid-state media a directory structure should be formed, and directories should be filled with required files.

When bootable solid-state media is prepared, the corresponding storage device should be set in the first place either in a list on page "Hard Disk Drives" or in a list on page "Removable Drives" – it depends on which emulation method is applied. If necessary, at this stage emulation method "Hard Disk" may be changed to "Forced FDD". When name of corresponding storage device appears on page "Boot Device Priority" of BIOS Setup program, it should be set there in a place with highest priority relative to all other devices, which are ready for booting at that moment. Then you have to close BIOS Setup program, saving the latest settings. After computer's reboot a DOS loading process starts from the prepared solid-state media.

9.11-02 Windows-2000/XP as boot manager for MS-DOS 7
When MS-DOS 7 starts from a hard disk, it requires a primary partition with either FAT-16 or FAT-32 file system. Unlike MS-DOS 7, operating systems Windows-2000/XP can be installed in both primary and non-primary partitions, formatted with either FAT-32 or NTFS file system. Neither combination should be regarded as hopeless. Even if the whole hard disk in your computer is formatted as one NTFS partition, you may release some disk's space for DOS partition with Partition Magic program, and then any appropriate boot manager (for example, System Commander) can arrange alternative loading of either selected operating system. The way described below is a more simple opportunity, using nothing but proprietary loader of Windows-2000/XP operating systems.

Partition structures, comprising partitions with FAT-32 (or FAT-16) file system, may be inherited from former operating system(s). Windows-2000/XP can be installed over Windows-95/98, either losing or preserving an opportunity to load previous operating system. If your computer after being switched on shows a boot menu with item "Previous operating system", and if this previous operating system is just Windows-95/98, hence partition structure on your disk is at least partially inherited. In this case for arranging alternative loading of MS-DOS 7 you have to correct not the loading specifications of Windows-2000/XP, but preserved configuration files of previous Windows-95/98 operating system. Examples of such correction are shown in article 9.11-03.

If boot menu doesn't appear or doesn't contain a line "Previous operating system", then type of file system should be determined on that disk, which is claimed bootable in BIOS specifications. Most often it is disk C:. Having launched the Explorer program, you have to highlight the bootable disk, open context menu with right mouse's button, and choose in context menu the "Properties" item. A window will appear, where type of file system is shown. If this type is "NTFS", then MS-DOS 7 can't be installed in that partition. But if file system type is "FAT", then MS-DOS 7 can be installed. Installation will require BOOT.INI file records correction and copying of MS-DOS 7 files onto that disk.

Officially prescribed path to correction of records in BOOT.INI file starts from menu "Start" and goes via item "Settings", via "Control Panel", via icon "Performance and Maintenance", via item "System", via button "Advanced", via button "Startup and Recovery Settings" to final button "Edit". In the same window a non-zero menu indication time should be set. Corrected version of BOOT.INI should be saved and after that the opened windows must be twice closed with OK button click. Besides that, contents of BOOT.INI file may be corrected by MSCONFIG.EXE utility. It can be launched from command line in a window, opened via item "Run" in menu "Start".

Syntax in BOOT.INI file is the same as that in files MSDOS.SYS (5.01-01) and CONFIG.SYS (9.04-01, 9.09-01). Each line presents a separate specification, which begins with a name, separated from its value with equality sign. Headers of file's sections are enclosed in square brackets. There are two sections in BOOT.INI file: the first specifies loading parameters, the second presents a list of operating systems, which may be loaded. Here is an example of BOOT.INI file, enabling to load any of 3 operating systems : In presented example the 5th and the 6th lines are truncated to size of page, in real file these lines are longer. But it doesn't matter: in any case the tails of truncated lines shouldn't be altered. From line's texts it becomes clear that the shown BOOT.INI file enables to load Windows-XP and Windows-2000 operating systems, installed in the 3rd and in the 2nd partitions of a single hard disk, so that the first partition remains free. As far as the first partition is left free, it may be used for a separate installation of MS-DOS 7. The last line in the shown example is just that line, which you have to add yourself in order to load MS-DOS 7, in particular, from disk C:. The words, enclosed in double quotes, represent just a name of menu item and have no effect on loading process.

Lines of BOOT.INI file are interpreted by NTLDR loader. The latter will "understand" the line you have wrote as command to find a file-image of boot sector BOOTSECT.DOS in the root directory of disk C:. If BOOTSECT.DOS file isn't present there, it should be created anew under MS-DOS 7, which may be loaded from diskette or other removable media. First, current boot sector should be saved into a file, as it is described in article 9.02-01. Then boot sector should be overwritten with SYS.COM utility (6.24). New boot sector similarly must be copied in a file, this time in a file named BOOTSECT.DOS. After that the former contents of boot sector must be restored from the previously saved file, also as it is recommended in article 9.02-01. The SYS.COM utility, used to overwrite boot sector, at the same time copies into the root directory system files COMMAND.COM and IO.SYS. Just the IO.SYS loader will be given control after execution of boot sector's code.

The next task is to ensure that all necessary files for MS-DOS 7 can be found along their proper paths. In the root directory of bootable disk the following files must be present : Three files from this list – MSDOS.SYS, CONFIG.SYS, AUTOEXEC.BAT – you have to compose yourself. The articles where composition examples can be found are specified inside parentheses for each corresponding line in the list.

Besides root directory files, MS-DOS 7 needs drivers, specified in lines of configuration files, and also various programs. The latter may be selected from those described in chapter 6. Drivers and programs should be stored inside a directories structure, which is to be arranged on the same disk. All examples of configuration files in this book are designed for the same directories structure : drivers are stored in  directory, original MS-DOS 7 files in   directory, file manager in   directory, all other files in   directory. You may arrange other directories structure, but in any case it must be exactly consistent with references in your configuration files.

Which particular configuration example should be followed is a matter of choice. Sometimes the simplest version, shown in article 9.01, is quite sufficient. More often some version with DOS relocation to a RAM-disk should be preferred (9.04, 9.09). For experiments with other operating systems one more version is shown in article 9.11-03. You are free to choose and to compose those MS-DOS 7 loading configurations, which are the most suitable for your own tasks.

Note 1: when over MS-DOS 7 or over Windows-95/98 the Windows-2000/XP operating system is installed, the latter assigns attributes H (hidden) and S (system) to COMMAND.COM interpreter in the root directory. Therefore, calls to command interpreter from batch files are not executed. The mentioned attributes should be taken off with ATTRIB.EXE utility (6.01).

9.11-03 MS-DOS 7 as boot manager
Operating systems Windows-95/98 use MS-DOS 7 as primary loader, but don't reveal opportunities of its separate configuration. Meanwhile, it is possible and may be beneficial not only for MS-DOS 7 itself, but also for alternative loading of those other operating systems, which are able to start under DOS.

Below is a CONFIG.SYS file which enables to load Windows-95/98, two configurations of MS-DOS 7, and two other operating systems: QNX and Linux. The author has tested versions of QNX and Linux, requiring bootable disk with file system FAT-16. If you don't need anything more than a choice between Windows-95/98 and MS-DOS 7, then all the lines related to QNX and Linux may be omitted, and the filesystem on the bootable disk may be FAT-32 as well.

This CONFIG.SYS starts with a section [menu]. A choice of an item in menu directs interpretation further to sections [L08]–[L25]: each section corresponds to one of alternatives. Sections are named after corresponding labels in AUTOEXEC.BAT file. Empty lines between sections are inserted for visual clarity only and may be omitted. Sections  and   in the shown version of CONFIG.SYS file load MS-DOS 7 as a separate operating system. Section [L09] provides ordinary type of access to UMB memory region by means of EMM386.EXE driver (5.04-02), but section  provides another type of access, by means of UMBPCI.SYS driver (5.04-04) without switching CPU to protected mode. The latter alternative is necessary for experiments with real mode programs, for example, with DUSE.EXE (5.07-05) and with GS_LIMIT.COM (9.10-01) Each operating system should have its own directory tree. Presence of separate directory trees is not a required condition, but nevertheless is desirable: independence of directories contents makes multialternative loading more reliable.

Section  for loading WINDOWS-95/98 includes a number of specifications, which usually are taken by default, but here are shown explicitly for the sake of consistency with separate loading of MS-DOS 7. Paths in  section correspond to ordinary directories structure, created automatically during installation of WINDOWS-95/98 onto a bootable disk. But if in your computer directories structure is different, all references in configuration files must be made corresponding to actual structure.

Choice of menu items  and   transfers control to loaders of UNIX-like operating systems, which don't return control back to MS-DOS 7 loader. Therefore, commands in section  will not be performed, so that the only way back is via SHUTDOWN command with following reboot. Paths in sections  and   reflect directory structures, created for each UNIX-like operating system in course of unpacking their release packages.

Choice of menu items,   or   enables to proceed to execution of commands in   section. In its last line the SHELL command transfers control to COMMAND.COM interpreter. After that the last stage of MS-DOS 7 loading begins – interpretation of commands in configuration file AUTOEXEC.BAT.

As far as further processing of alternatives  and   is the same, the whole variety of alternatives shrinks to two, and AUTOEXEC.BAT file becomes relatively simple. Particular contents of AUTOEXEC.BAT file may look, for example, like In this version of AUTOEXEC.BAT file the lines 2–6 represent common part, assigning values to ordinary environmental variables. It is important not to leave any trailing space in lines 3 and 5, where values are assigned to variables DSK and TEMP. In the 7th line a jump occurs to the label, defined by value of CONFIG environmental variable. This value is just the code of selected menu item, assigned implicitly by IO.SYS loader during interpretation of [menu] section of CONFIG.SYS file.

As far as execution of AUTOEXEC.BAT file is reached after alternatives L08, L09, L16 only, a jump in the 7th line can be directed to labels,   and.

Labels  and   are followed by a group of final commands for loading MS-DOS 7. Commands of this group define paths, specific for MS-DOS 7, and launch the Volkov Commander file manager.

Label  is followed by another group of commands, presenting final operations for loading Windows-95/98 system. Here the PATH variable gets another paths, specific for Windows-95/98. Attention should be paid to usage of trivial national adaptation method, which enables proper switching of national codepages inside "DOS box" of Windows OS. In final lines the Windows GUI loader — file WIN.COM — is called for. Windows logotype will not be displayed, a textual message is displayed instead. When GUI loading is completed, this message becomes hidden under customary Windows desktop.

Note 1: though Windows XP OS is not devised for being started under MS-DOS 7, the required initial start conditions can be prepared by free utility Dostowxp.com. Its recent version, modified by V.Ashumov, can initiate loading of Windows Vista and Windows-7. Both original and modified versions of this utility are available at http://www.multiboot.ru/files.htm. Thus MS-DOS 7 is enabled to initiate launching of pre-installed modern Windows OS versions similarly to other OS launching examples, shown in article 9.11-03.

Note 2: installation of Linux OS is performed by recompiling its core with a specific set of drivers, required by hardware of a particular computer. Internet server ftp://ftp.wolfmountaingroup.org/pub/linuxware/ presents software package linuxware-09072008.tar.gz enabling to recompile the core 2.4 of Linux OS into a form of DOS's ordinary application. This recompiled core starts Linux under DOS, preserves DOS's structure intact and returns to DOS after shutdown. Core 2.4 is used in Mandrake Linux versions 8–10 and in many other modern clones of Linux OS.