Previous Contents Next

APPENDIX A: COMMAND DOCUMENTATION

This appendix contains user documentation for each of the commands developed in the book. The commands are given in alphabetical order.

The word "fileref" means the complete designation of a CP/M file: a drive-letter and colon, a filename, and a filetype.

These programs may be called from batch command files run by the SUBMIT command of CP/M. Some of the commands will "abort" under certain error conditions. When they do, they terminate any active submit file. This is done so that submitted commands that follow them, and that might depend on their output, will not be executed.

The Utility Convention

Several commands use the "utility convention" for filerefs. That convention is developed in Chapter 3. In it, a command's first operand designates the input file; its second operand designates the output file. The input fileref must include a filename. If the input drive-letter is omitted, the program will use the drive-letter given in the CP/M prompt.

Omitted parts of the output fileref are supplied from the input fileref. If the output drive-letter is omitted, the output file is put on the same disk as the input. If the output filename is omitted, the input filename is used. If the output filetype is omitted, the input filetype is used. If the entire output fileref is omitted, the output file will replace the input file when the command finishes execution.

Programs that use the utility convention build their output files under a temporary filetype of ".$$$". At the end of their runs, they erase any existing file matching the output fileref and then rename the new output file to its proper type. If one of these programs is terminated early (if the system is reset, for instance), the input file will be safe. There might be a partial output file with the output filename and a type of ".$$$".

Programs that use the utility conventions abort with a standard set of error messages, with these meanings:

An input filename is required
The filename was omitted from the first operand of the command. Perhaps no operand was given at all. The utility convention requires an input filename to be given.
Input file not found
The program couldn't find a file with the drive-letter, filename, and filetype given by the first command operand. Maybe the fileref was misspelled, or maybe the file is on a different drive.
The output file may not be ambiguous
The second operand of the command is an ambiguous fileref—it contains a question mark or asterisk. The program will not proceed; it could do a great deal of damage if it used that fileref, because it would erase every file that matched the output fileref.
Can't create the work file
Most likely, the directory on the output disk is full. There may be space on the disk, but there are no directory entries in which a new file can be recorded. The output file can't be created, so the program quits.
Error writing the work file
The program has received an error signal from CP/M while adding records to the output file. Either the output disk has no more file space or its directory is full.
Not enough room for an output buffer
This unusual message means that the program is too large for the storage capacity of the CP/M system. There is nothing to be done about it.
Error closing the work file
This error should never happen; if it does then there is either a bug in the program or a serious flaw in CP/M or in the directory of the output disk.
Error renaming the work file to proper name
The output file is built under a filetype of ".$$$" and then is renamed to the proper type. No error is expected when renaming it; if this message appears there is probably a bug in the program.

CDUMP

The CDUMP command displays a file at the console in physical (128-byte) units. It displays ASCII control characters in reverse video. The command's form is:

CDUMP fileref

The fileref should be explicit (contain no question-marks or asterisks). If that file does not exist, the program aborts with the message "No File."

Each 128-byte physical unit of the file is displayed as two 64-byte lines, with a record number following the first line. The record number (which is of interest only to programmers) is given in hexadecimal.

In the display, ordinary ASCII characters are displayed in normal (white-on-black) video. ASCII control characters are displayed as uppercase letters and punctuation in reverse video. The letters displayed for control characters are the letters that will produce those control characters when the control key is held down. For example, each line of a file ends with carriage return (control-m) and linefeed (control-j); these appear in the display as "MJ" in reverse video.

Note: the CDUMP program has to be customized for each particular type of terminal. If it displays garbage, it probably hasn't been set up to work with your type of terminal.

DDUMP

The DDUMP command displays the contents of a disk directory at the console in hexadecimal. Its form is:

DDUMP d:

The drive-letter d selects the disk whose directory is to be displayed. The display includes all directory entries that have ever been used, including those for files that have been erased. The number of entries shown may be less than the size of the directory (less than the number of entries shown by the "STAT d:DSK:" command). That is because entries that have never been used are not displayed.

Each entry is shown in two lines, like this:

uu ff ff ff ff ff ff ff ff tt tt tt ex s1 s2 rc filename typ mm mm mm mm mm mm mm mm mm mm mm mm mm mm mm mm

The "uu" byte of an entry for an erased file is "E5." See Chapter 5 for a discussion of the other fields.

DFILE

The DFILE command extracts selected entries from a disk directory and puts them in a file in a form that can be read by a program written in BASIC or Pascal. Its form is:

DFILE outputref scanref /x

The outputref operand designates the output file to receive the directory data. Unlike most of these commands, the output fileref is the first operand rather than the second. The outputref operand is required.

When the "/x" option is omitted, the program processes only active directory entries made under the current user number. The scanref operand selects the directory entries to be processed; its effect is like the operand of the DIR command. Its drive-letter designates the disk whose directory is to be searched. If the filename and filetype are omitted from scanref, the program will select all active entries under the current user number.

When the "/x" option (for "exhaustive search") is given, the drive-letter of scanref selects the disk, but all directory entries that have ever been used are displayed, including those for files that have been erased.

The DFILE program can generate its output either for use by BASIC (with quotes around character strings and commas between numbers) or for use by Pascal (no quotes, blanks between numbers), but not both. The program must be reassembled to change from one format to another. See Chapter 5, Tables 5-1 and 5-2, for the format of the output file.

DLIST

The DLIST program displays selected entries from a disk directory at the console. Its form is:

DLIST scanref /x

When the "/x" option is omitted, the program displays only active directory entries made under the current user number. The scanref operand selects the directory entries to be displayed. It works much like the operand of the DIR command. Its drive-letter designates the disk whose directory is to be displayed. If the filename and filetype are omitted from scanref, the program will select all active entries under the current user number.

When the "/x" option (for "exhaustive search") is given, the drive-letter of scanref selects the disk, but all directory entries that have ever been used are displayed, including those for files that have been erased.

The program displays each selected directory entry in one line, like this:

ua filename typ ex s1 s2 rc as ms h -attributes-

The "ua" field is the user number in hexadecimal; it is "E5" in an erased file. The "ex," "s1," "s2," and "rc" fields are also in hexadecimal; they are discussed in Chapter 5. The "as" field is a count, in hexadecimal, of the number of allocation blocks controlled by this directory entry. The "ms" field is largest number of blocks it could control. The "h" field contains an "h" if the entry has "holes," or unused places, in its allocation map. It contains a "c" for "compact" if there are no holes.

The "-attributes-" field shows the presence or absence of each of the eleven possible file attribute bits. The first three letters of the field show the filetype attributes: "r" for R/O and "w" for R/W, "s" for SYS and "d" for DIR, "a" for Archived and "u" for unarchived. The filetype attribute bits are shown as single digits when they are present and by blanks when absent. If all eleven attributes were present, the field would contain "-rsa12345678-," indicating the R/O, SYS, and Archive attributes and all eight filename attribute bits.

FDUMP

The FDUMP command displays a file at the console in physical (128-byte) units. It displays ASCII control characters as periods. Its form is:

FDUMP fileref

The file designated by fileref is displayed. Each 128-byte unit is shown as two 64-byte lines with a record number (in hexadecimal) at the end of the first.

Normal ASCII characters are shown as themselves. ASCII control characters are shown as dots, except for the carriage return and linefeed characters, which are shown as back-slashes ("\:BS\").

INCLUDE

The INCLUDE command merges units of text into a file. The use of INCLUDE is discussed in Chapter 6, and there are examples of the use of INCLUDE throughout the book. The command's form is:

INCLUDE inputref outputref /drives

INCLUDE uses the utility convention for its inputref and outputref operands. It can accomodate input lines as long as 2,048 bytes. It uses the linefeed character as an end-of-line marker. This accords with normal CP/M practice. MBASIC program lines can contain embedded linefeeds; such lines will be processed in sections.

The /drives operand specifies which disk drives are to be searched for an included file. It is given as a slash followed by from one to sixteen drive-letters. If the /drives operand is omitted, INCLUDE will search only the default drive. When the operand is given, the program will search for an included file on each of the specified drives in the order given.

The program reads the inputref file and copies it to the outputref file. While copying, it looks for lines containing an #include command, a #start command, or an #end command. Each of these commands may appear anywhere in a single line of the file, and may be preceded or followed by other characters. They may be embedded in program-language comments, for example.

The #Include Command

The #include command directs the program to find and insert text from another file following the line that contains #include. The command may have either of two forms:

... #include filename.typ ... ... #include filename.typ,unitname ...

The first form tells the program to insert the entire contents of the named file. The second form tells the program to scan the named file until it finds a unit named "unitname," and insert only that unit of the file. The program searches for the file "filename.typ" on each of the drives named in the /drives command operand. The inserted text appears in the output file following the line with the #include command. If the included text contains #include commands, they are processed in the same way. As many as seven included files may be open at the same time.

No named unit is included more than once in the output file. If an #include command designates the same text as an earlier #include, the second command is ignored. If the program is copying text and encounters a named unit that has already been included, it skips over the named unit.

The #Start and #End Commands

The #start and #end commands are used to delimit named units of text, so that a number of related units may be combined into a single file. Their forms are:

... #start unitname ... ... #end unitname ...

A "unitname" may be up to nineteen characters long. It may consist of letters, digits, and some special characters (the characters "!\:AT\#$%^&*-+" are all permissible, but others should be avoided). Letters may be given in lowercase, but they will be treated as uppercase.

A named unit begins with the line containing the #start and continues through the line containing an #end command with the same unitname. A unit may incorporate other, smaller, named units. If one unit depends on a second unit, it may either contain an #include for the second unit, or it may contain the second unit within itself. The effect is the same in either case; when the first unit is included, it will bring the second along with it. The advantage of nesting the second unit inside the first is that the program will not have to open the file and scan it a second time to find the second unit.

Error Messages

If the /drives parameter is invalid—if there are no letters after the slash, or too many, or letters that aren't valid drive-letters—then the program will abort with the message "Invalid /drives parameter."

INCLUDE displays each #include line at the console as it is processed. It may also display error messages at the console. The command line—#include, #start, or #end—that caused the error is displayed first. Then the console alarm is sounded, and an error message is displayed below the offending line. Such errors do not cause the program to abort. It carries on, perhaps to produce an incomplete output file. These are the messages:

No space to record this unit.
The program notes the fileref and unitname of every named unit it encounters. It has a table with 128 entries to store these names. This message appears when the table is full and another name has been encountered. If the line above is an #include, the include will not be done. If the line above is a #start, the unit it heads will be included but there is no protection against its being included twice; watch out for a later occurrence of this message following the same #start command.
Includes nested too deeply.
The main file and seven other, included, files are open simultaneously. The #include line above the message was found in the innermost file, and the program can't open a ninth file. The #include command will be ignored.
Can't make sense of this command.
The line above the message contains an #include, #start, or #end command verb, but there is something wrong with the operand that follows it. The filename might be missing, or the filename or filetype might be too long, or the unitname might be missing or too long.
The named unit isn't in the file.
The preceding #include called for a named unit. The program scanned the whole file and never found a #start for that unitname. This might be an expected situation; perhaps you haven't yet built that unit of text. If you think it should exist, check that the right file was named and that the unitname was spelled correctly.

PACK

The PACK command copies a file of ASCII text and produces a compressed copy of it. The compressed file takes up less space than the original. The command form is:

PACK inputref outputref

PACK uses the utility convention for its input and output files. It reads the input file and searches for combinations of letters that can be compressed into single bytes in the output. The compressed data can be decompressed with the UNPACK command.

The command is meant for use on document files that contain mostly lowercase letters. It will compress such files to about 70% of their original size. If it is applied to a file that contains a majority of uppercase letters or numbers, it will have little effect. If it is applied to a file that contains non-ASCII data (a file of .COM type, for example, or a file that has already been PACKed), the output file may actually be larger than the input file.

If PACK is applied twice to the same data, no harm will be done. The second output file will be larger than the input. Applying UNPACK twice to the data will restore the original file.

MACREF

The MACREF command copies an assembly language source file, adding a symbol cross-reference and an opcode census to its output file. Its form is:

MACREF inputref outputref

MACREF uses the utility convention for its input and output files. It also reads a file with the same filename as the input file and a filetype of .SYM. That symbol file must exist on the same drive as the input file. If the .SYM file can't be found, the program aborts with the message "Input .SYM file not found."

MACREF can accomodate individual lines as long as 1,024 bytes. It uses the linefeed character as the end-of-line marker, so its input should follow the normal CP/M practice of delimiting lines with carriage return, linefeed.

The program changes the input lines before copying them to the output. If a line begins with a sequence number (any unbroken string of digits, beginning in the first character of the line), MACREF strips it off. It also removes the first tab or blank following the sequence number. Then a new sequence number is inserted at the head of the line, followed by a tab. These sequence numbers begin with 0001 and increment by 1 in each line.

If MACREF finds what appears to be the beginning of an old, MACREF-created, cross-reference in its input, it assumes that it has reached the end of the assembler source and stops reading.

The cross-reference report is written following the end of the input. For each symbol defined in the .SYM file it gives the line number on which the symbol is defined, the hex value given for it in the .SYM file, and a list of points at which the symbol was referenced in the file. For each reference, it gives the opcode of the line. Here is a typical cross-reference line:

* 0244 0040 SKIPPING ANI-274 -301 ORI-388

The symbol SKIPPING is defined on line 244 with a hexadecimal value of 0040h. It is referenced in ANI instructions on lines 274 and 301, and in an ORI instruction on line 388.

The opcode census follows the cross-reference; it gives a count of the number of times each opcode (including macro calls) was found in the input.

The added report lines all begin with an asterisk so that the MAC assembler will treat them as comment lines. Thus a MACREF output file can be edited, reassembled, and resubmitted to MACREF to produce another file.

TABBIT

The TABBIT command copies an input file, replacing strings of blanks with tabs wherever it can do so without changing the appearance of the file as typed. The form of the command is:

TABBIT inputref outputref

TABBIT uses the utility convention for its input and output files. It relies on the CP/M convention that every output device has tab stops set at every eighth column (at columns 1, 9, 17, 25, etc.). It reads its input, looking for sequences of two or more blank characters preceding a tab stop column. It replaces such sequences with a single tab. It does not replace single blanks, even though it could do so.

TABBIT should be applied only to files that are to be printed just as they are. If a file is to become data for some other program, the blanks in it might be significant and so should be left alone.

UNPACK

The UNPACK command undoes the compression produced by the PACK command (see the description of PACK). Its form is:

UNPACK inputref outputref

UNPACK uses the utility convention for its input and output files. It should be applied only to files that were produced by PACK. The result of applying it to an uncompressed file depends on the file's contents. If the file contains only ASCII characters, the output will be unchanged from the input. However, if the file contains non-ASCII data, UNPACK will treat some of its bytes as packed combinations of letters.

There are a few byte values that PACK cannot create. If UNPACK finds one of these, it aborts with the message "Impossible byte in input file." This could occur in two cases: if the input file was not the output of PACK, or if the version of PACK that was used had been enhanced and UNPACK had not been similarly changed.

UNTAB

The UNTAB command removes tabs from its input, replacing them in its output with blank characters. Its form is:

UNTAB inputref outputref /increment

UNTAB uses the utility convention for its input and output files. The /increment parameter specifies a regular increment of columns from one tab stop to the next—for example, "/12." If it is omitted, the program assumes that the CP/M convention (an increment of eight columns between tab stops) is to be used. If the /increment option is given incorrectly (if it isn't numeric or is larger than 255), the program aborts with a message.

UNTAB reads its input, keeping track of the column where each character would be printed. When it finds a tab character, it writes instead enough blank characters to get to the next tab stop column.

VDUMP

The VDUMP command displays a file at the console in physical (128-byte) units, showing each character in both ASCII and hexadecimal form. Its form is:

VDUMP inputref

The inputref should be explicit (have no question marks or asterisks). If that file cannot be found, the program aborts with the message "No file."

Each 128-byte unit of the file's data is displayed in two 64-byte rows. Each row consists of three lines. The first line contains a display of 64 ASCII characters. Normal characters are shown in normal (white-on-black) video, while control characters are shown as uppercase letters and punctuation in reverse video.

The second and third lines of each row contain the hexadecimal values of the characters in the first line. Below each ASCII character appear two hexadecimal digits. The first digit (in the second line of the row) is the most significant; the second digit (in the third line of the row) is the least significant.

VDUMP can be cancelled before it reaches end of file. Pressing any key at the console keyboard will cause the program to terminate at the end of the row it is then typing.

The VDUMP program has to be customized to work with each type of terminal. If it displays garbage in the first line of a row, it probably hasn't been set up to work with your terminal type.