BATCH FILE TIPS AND UTILITIES The Ninth in a series by Mitchell A. Hoselton USING ANSI.SYS TO CONTROL THE CONSOLE After you've installed ANSI.SYS in your PC, the next reasonable question to ask is, "What do I do with it?" In fact, there are several things. ANSI.SYS can change the display mode, select colors and character attributes on the screen, control the cursor position and reassign keys on the keyboard. Some applications require access to ANSI.SYS functions and will not work properly unless CONFIG.SYS installs the ANSI.SYS driver. Reassigning keys may be useful in special situations but I've generally found it to be more trouble than it's worth. This article concentrates on commands for controlling the console display device (monitor, screen, display) with ANSI.SYS functions. Of course, the techniques used to generate the {ESC} character apply equally well to all ANSI.SYS functions. CONFIG.SYS must install the ANSI.SYS driver before you can use the ANSI.SYS functions. The syntax for including the ANSI.SYS driver in CONFIG.SYS is as follows. DEVICE=[drv:][\path\]ANSI.SYS [/x][/k][/w] ANSI.SYS uses the optional /k switch in conjunction with the SWITCHES=/k command discussed earlier. It uses the optional /x switch for remapping the extended keys on the 101 key keyboard. For example, with the /x switch enabled, the {HOME} key on the number pad and the {HOME} key on the extended cursor pad are distinguishable and can be reassigned separately using the ANSI.SYS key reassignment feature. When the /k switch is in effect, both {HOME} keys look the same to DOS. After rebooting the PC and installing the ANSI.SYS driver, the ANSI.SYS functions are invoked simply by writing (more precisely, you might say, attempting to write) special commands to the console display device. Unlike other DOS commands, there is no way to type ANSI.SYS functions directly from the keyboard. An application program, a batch file or COMMAND.COM, when it processes the PROMPT variable, are the only routes for issuing ANSI.SYS commands. ANSI.SYS is a screen capture utility. It only responds to characters the PC sends to the monitor. It scans everything sent to the monitor and passes most of it along without alteration. ANSI.SYS intercepts the commands that it recognizes as its own and executes them. Intercepted ANSI.SYS commands do not appear on the screen. The ANSI.SYS commands are sometimes called ANSI escape sequences. All ANSI escape sequences start with the {ESC} character. This is not the same as the {ESCAPE} key on the keyboard. The {ESC} character is ASCII character 027 or 1Bh. Sometimes it appears in text editors as CTRL-[ or ^[. In other text editors it appears, instead, as a small left arrow. There is no key or key stroke combination on the keyboard that can send the {ESC} character to the console. Generating the {ESC} character is the single biggest hurdle that users who want to take advantage of ANSI.SYS functions must overcome. METHODS FOR GENERATING THE {ESC} CHARACTER All the ANSI.SYS commands start with the {ESC} character. In fact, they all start with the same pair of characters; the {ESC} character followed by a left square bracket, [. ANSI.SYS scans the data going to the screen looking for this pair of characters. This particular pair of characters turns out to be confusing to new ANSI.SYS users because some ASCII text editors use a left square bracket, [, as part of their compound symbol for the {ESC} character. Depending on which ASCII text editor you use, the {ESC} character alone might look like any one of the following. CTRL-[ or CTL-[ or ^[ or {ESC} or {left arrow} (I'm using the string, {left arrow}, to stand in for the actual left arrow character, which some text editors use to represent the {ESC} character.) Then, depending on the ASCII text editor, the pair of characters, {ESC}[, might display in one of the corresponding formats. CTRL-[[ or CTL-[[ or ^[[ or {ESC}[ or {left arrow}[ In this article I always use {ESC} to stand for the escape character and {ESC}[ to stand for the pair of characters that ANSI.SYS recognizes as the beginning of an ANSI escape sequence. However a particular editor displays this pair of characters, they are the {ESC} character, ASCII character 027 (1Bh), followed by the left square bracket, ASCII character 091 (5Bh). Before discussing what can be done with ANSI escape sequences, we have to learn how to generate the {ESC} character. Fortunately, there are a number of readily available solutions for handling that chore. The first method I learned was using the meta-string $e in the DOS PROMPT command. COMMAND.COM converts $e to an {ESC} character whenever DOS processes the PROMPT variable. The PROMPT command creates an environment variable, named PROMPT, and assigns a string value to it. While processing this string, COMMAND.COM issues an {ESC} character to the console every time it encounters the $e meta-string. COMMAND.COM processes the PROMPT string in the DOS environment every time it regains control of the system or displays the DOS PROMPT. The second method of generating the {ESC} character is to use an ASCII text editor to create embedded escape sequences in an ASCII text file. DOS's EDLIN is an ASCII text editor that can handle the job. No one should be using EDLIN to write batch files any longer. It can still be used in a pinch, however, for generating {ESC} characters, and in a few other specialized circumstances. With EDLIN, an {ESC} character alone or the pair of characters, {ESC}[, can be edited into a previously written text file. Even easier, use EDLIN to create a template file that contains several {ESC} characters. When you need a few {ESC} characters in a file, just edit the template your text editor. Many ASCII text editors can display, copy and move an {ESC} character. They just can't create one. Use one of these editors to write the rest of the file and to complete the ANSI escape sequences started in EDLIN. If you own DOS 5.0's EDIT, you don't need to use EDLIN to create the {ESC} characters. EDIT has the capability to create {ESC} characters whenever and wherever you need them. The third approach to generating {ESC} characters is using utilities like ESC.COM, FORANSI.COM and ESC2.COM. They send the {ESC} character directly to the console and pass along, as command line parameters, the other characters that complete the escape sequence. All three of these utilities avoid the arcane keystrokes required to generate the {ESC} character in some ASCII text editors. There are also a number of ANSI.SYS extenders. The most notable of these is the Norton Utilities Batch Enhancer (BE). BE appeared in release 4.5. It controls screen colors and cursor positions better than ANSI.SYS can. You must install ANSI.SYS before some of BE's features will work, however. The advantage of using BE is that it eliminates the need to create {ESC} characters all together. Finally, though not a specific topic of this article, there are any number of ANSI.SYS work-alike drivers. Some of these may make it easy to generate the {ESC} character, but most don't make it any easier than ANSI.SYS does. These are usually available on bulletin boards, as shareware, from discount software vendors or from the NTPCUG Disk-of-the-Month desk. They have names like NANSI.SYS, ZANSI.SYS, etc. They are desirable for their decreased size and increased speed over the older ANSI.SYS drivers. Some of these drivers work with more video modes than ANSI.SYS supports. ANSI.SYS in DOS 5.0 is very fast and compares favorably with the work-alikes. However, even in the DOS 5.0 release, ANSI.SYS does not work with many common display modes. I usually use an ANSI.SYS work-alike driver called EANSI.SYS. My VGA video board manufacturer provided EANSI.SYS to take advantage of the unique features of that particular video board. EANSI.SYS has the advantage of having an installed size about half that of ANSI.SYS (1.9K vs 4.1K), but it runs a little slower than the DOS 5.0 version of ANSI.SYS. I still prefer to use EANSI.SYS because it supports all the video modes of my video controller. ISSUING ESCAPE SEQUENCES WITH THE PROMPT COMMAND Simply insert $e into the PROMPT string wherever you need the usual escape sequence lead-in. COMMAND.COM creates the {ESC} character for you each time it displays the PROMPT. This technique can be a little inconvenient because, unless the old DOS PROMPT is saved, this operation destroys it. Sometimes you'll want to use an {ESC} character in your working PROMPT. That's fine, there is no problem. But if you are using a temporary PROMPT to send and ANSI escape sequence to the screen, destroying the working PROMPT is inefficient. There is a work-around for that, too, as you'll see. Some care must also be taken to ensure that COMMAND.COM actually writes the temporary PROMPT containing the escape sequence to the console, but that is a minor problem. The usual procedure for using the PROMPT command to issue ANSI escape sequences in a batch file is as follows. a) Save the old PROMPT, b) Issue the escape sequence with a temporary PROMPT command and c) Reinstate the old PROMPT. There are a couple of ways to do this. Neil J. Rubenking pointed out the cleanest version in his column on page 407 of the May 28, 1991 edition of PC Magazine. His procedure works something like this. SET oldpmpt=%PROMPT% @ECHO on @PROMPT escape_sequence @PROMPT %oldpmpt% @ECHO off SET oldpmpt= The @'s suppress echoing of the PROMPT and ECHO commands while the echo status is on. The procedure requires the blank line following the temporary PROMPT containing the escape_sequence. It forces DOS to write the escape sequence to the console when the echo status is on. ANSI.SYS is a screen capture utility. It only responds to characters sent to the console. When the echo status is on, the extra carriage return, created by that blank line, forces COMMAND.COM to write the escape sequence without the word PROMPT in front of it. ANSI.SYS captures the escape sequence and never writes it to the screen. The escape sequence begins with the symbols $e[. That issues the {ESC} character and the ubiquitous [ character. Write the rest of the escape sequence in normal text on the same line. One PROMPT command can issue a whole series of consecutive escape sequences. These can be intermingled with normal text messages. Each escape sequence must start with its own $e[. The only limitation is the 127 character limit of the command line. CREATING A TEMPLATE FILE USING EDLIN To enter the {ESC} or {ESC}[ characters while editing a file with EDLIN, type the {CTRL}-V key combination followed by one or two [ characters. On the screen this looks like one of the following. {ESC} = ^V[ or {ESC}[ = ^V[[ After terminating the line entry mode, however, EDLIN's LIST function displays them as follows. {ESC} = ^[ or {ESC}[ = ^[[ The V has disappeared, but the {ESC} character is still there. For reasons of its own, EDLIN represents the same character two different ways. EDLIN is not a very good editor, but it still has its uses. The best way to use EDLIN is for creating a template file that includes several {ESC} characters. Use another ASCII text editor to edit the template file at a later date. Use any ASCII text editor except EDLIN to complete the ANSI escape sequences, to complete the rest of the file and to save the completed file under a new name. Always leave the template file unchanged so that it can be used over and over again. The first step is to create the template file. Here is the way to do it with EDLIN. First change to the DOS directory. At the DOS PROMPT type the following. EDLIN template.txt EDLIN comes back with the following response. New file * That star (*) is the EDLIN command prompt. At the EDLIN command prompt type i1, or simply i. That means start insert mode at line one. After hitting {ENTER} EDLIN responds by indenting about six spaces on the next line, displays the line number and leaves the screen looking like this. New file *i1 1:* This is an invitation to type in the first line. After each line, hit the {RETURN} or {ENTER} key and EDLIN will start the next line, automatically. The * moves to the current line being edited in each case. EDLIN literally means LINe EDitor. It only works on one line at a time. Type some innocuous header for this template file on line one and hit {ENTER}. The screen now looks like this. New file *i1 1:*This is the start of the TEMPLATE.TXT file 2:* On line two enter the keystroke combination {CTRL}-V and [. That is, hold down the {CTRL} key and press the V key. Release both keys and tap the left square bracket key. For good measure, hit the left square bracket again. Press the {ENTER} key and the display looks like this. New file *i1 1:*This is the start of the TEMPLATE.TXT file 2:*^V[[ 3:* Repeat this process several more times and add a closing comment to mark the end of your template file. The screen should look something like this. New file *i1 1:*This is the start of the TEMPLATE.TXT file 2:*^V[[ 3:*^V[[ 4:*^V[[ 5:*^V[[ 6:*^V[[ 7:*This is the end of the TEMPLATE.TXT file 8:* If you make a mistake on a line, do not try to back up. EDLIN cannot handle that. Just continue to the next line. Edit the error out of the template at a later time using a real text editor. At this point hold down the {CTRL} key and press C. Release both keys and EDLIN will respond with a new * prompt. You can also use the F6 key and hit {ENTER} to terminate insert mode. Do not hold the F6 key down. The work on the screen now looks like this. New file *i1 1:*This is the start of the TEMPLATE.TXT file 2:*^V[[ 3:*^V[[ 4:*^V[[ 5:*^V[[ 6:*^V[[ 7:*This is the end of the TEMPLATE.TXT file 8:* * The {CTRL}-C terminates insert mode and returns the EDLIN command PROMPT. EDLIN waits for the next command. The smart thing to do is hit the E key and {ENTER}. That saves the file named TEMPLATE.TXT with the seven lines just created and exits to DOS. The curious may want to hit the L key and {ENTER}. That will list the file so you can check it before saving it. The screen will look like this. New file *i1 1:*This is the start of the TEMPLATE.TXT file 2:*^V[[ 3:*^V[[ 4:*^V[[ 5:*^V[[ 6:*^V[[ 7:*This is the end of the TEMPLATE.TXT file 8:* *l 1: This is the start of the TEMPLATE.TXT file 2: ^[[ 3: ^[[ 4: ^[[ 5: ^[[ 6: ^[[ 7: This is the end of the TEMPLATE.TXT file * The only thing to notice is that the V's have disappeared. The {ESC} character is still there. EDLIN has only changed the way it displays the {ESC} character. Remember, too, that the first [ is part of EDLIN's symbol for the {ESC} character. The second [ is the one that appears right after the {ESC} character. Now that curiosity is satisfied, type E at the EDLIN command prompt and {ENTER}. EDLIN will save the file and exit to the DOS PROMPT. CREATING ESCAPE SEQUENCES FROM THE TEMPLATE FILE Once TEMPLATE.TXT is safely tucked away on the hard disk, use it to create any number of other files containing complete ANSI escape sequences. Most text editors include a copy function that you can use to copy lines containing the {ESC} character. That's the way to produce an unlimited supply of {ESC} characters beginning with the few created in TEMPLATE.TXT. Delete any extra {ESC} characters before using the new file. Make sure that the edited file is saved under a new name. The new file can issue escape sequences in two ways. The first technique is to turn it into a batch file with ECHO commands that issue the escape sequences. These lines could look something like the following. ECHO {ESC}[31;47;1m Different editors will display that {ESC} character differently. A batch file containing this particular line will change the color display to bright red letters on a white background. A single ECHO command can issue many escape sequences. The only limitation is the 127 character limit of the DOS command line. Multiple ECHO commands can be issued to complete more complex tasks. There is only one complication with using this technique. DOS issues carriage return and line feed characters at the end of every ECHO command. They will change the cursor position. The next ECHO command may have to restore the cursor position before printing its first message. The other option is to create an unformatted text file instead of a batch file. An unformatted text file has no carriage return or line feed characters in it. Basically, the file contains one continuous line. In an unformatted text file there is no limit to the number of characters on that single line. For convenience while preparing and editing the file, feel free to include lots of carriage returns and line feeds. They make everything easier to read. Just remember to delete the carriage returns and line feeds before saving the file for the last time. It's possible to live with one pair of carriage return and line feed characters at the very end of the unformatted text file. The cursor position will change at the end of the file just as it does in the case of ECHO commands in a batch file, however. A better solution is to find a text editor that does not feel obliged to put carriage return and line feed characters at the end of the last line. Both DOS 5.0's EDLIN and EDIT are editors that insist on adding the unwanted pair of carriage return and line feed characters to the end of every file. 1WORD, the editor in XTree, does not add those two characters unless you tell it to. CREATING ESCAPE SEQUENCES WITH DOS 5.0's EDIT EDIT can create almost any ASCII character using the following technique. Among the first 32 ASCII characters (the ASCII control codes) the only exceptions are ASCII characters 000 (CTL @=00h=null), 010 (CTL J=0Ah=line feed), 012 (CTL L=0Ch=form feed), 013 (CTL M=0Dh=carriage return), and 021 (CTL U=15h). The first step is to send a {CTRL}-P. That is, hold down the {CTRL} key and tap the P key. Then release the {CTRL} key. {CTRL}-P tells EDIT to interpret the next character literally. Following the {CTRL}-P, there are three types of responses. The most general response can create all ASCII characters except those listed above. The next most general response has two additional exceptions. The least general response will only create three of the 32 control codes. The most general way to enter an ASCII character following a {CTRL}-P is to hold down the {ALT} key and press three digits on the numeric key pad. Then release the {ALT} key. The {ESC} character is ASCII 027. To create the {ESC} character press {CTRL}-P and then {ALT}-027. EDIT displays the {ESC} character as a small left arrow. Matthew Lake pointed out how to use EDIT this way in the LETTERS column on page 30 of the February 1992 edition of PC/Computing. If you are patient, you can also find {CTRL}-P on one of EDIT's help screens, but without any detailed explanation of how to use it. The next most general way to enter an ASCII character following a {CTRL}-P is to enter another {CTRL}-letter sequence. You can even hold the {CTRL} key while you tap both letters. To create the {ESC} character hold the {CTRL} key down. Then tap P and [ in order before releasing the {CTRL} key. In addition to the exceptions mentioned above, this technique will not create ASCII character 030 (CTL ^=1Eh) or ASCII character 031 (CTL _=1Fh). The least general way to enter an ASCII character following a {CTRL}-P is to hit one of the special keys, ESC, TAB or BACKSPACE. First, create the {CTRL}-P by holding down the {CTRL} key, tapping the P key and then releasing the {CTRL} key. Then hit one of those three keys. Hitting the ESC key creates the {ESC} character (CTL [=1Bh={ESC}). Hitting the TAB key creates the horizontal tab character (CTL I=09h={TAB}). {TAB} displays as a small circle when created in EDIT this way. However, if the file is saved and then retrieved, the {TAB} is executed rather than displayed in the retrieved file. Hitting the BACKSPACE key creates the backspace character (CTL H=08h={BS}). USING DEBUG TO REMOVE UNWANTED CR, LF AND END-OF-FILE CHARACTERS To create unformatted text files, you'll need to remove the carraige return and line feed characters at the end of some files. XTree's text editor 1WORD adds only the end-of-file marker, {CTRL}-Z, to end of each text file it creates unless you hit {ENTER} at the end of the text. Then it also adds the carriage return and line feed characters. DOS 5.0's EDIT does not add a {CTRL}-Z to the end of the files it creates. DOS 5.0's EDIT does add at least one set of carriage return/line feed characters. If you hit {ENTER} at the end of the last line in the file it adds another pair. DOS 5.0's EDLIN always adds one pair of carriage return/line feed characters and one end-of-file character. DEBUG can easily delete a small number of characters from the end of the file. The trick is to find out how many characters to delete. If the file has one carriage return, one line feed and one end-of-file-marker at the end, delete all three characters. To delete the last three characters from a text file, use the following command to load the file into DEBUG. DEBUG filename.ext DEBUG responds with a dash (-) prompt. Type the RCX command to determine the length of the file. The answer is a hexadecimal number. After reporting the length, DEBUG issues a special colon (:) prompt that lets you change the length of the file. Here is an example of the complete procedure. -rcx CX 001F :1c -w -q Following the RCX command, DEBUG reported that the length was 1Fh bytes long. That is 31 bytes. Remove 3 bytes and shorten the file to 28 bytes. The hexadecimal equivalent of 28 is 1Ch. Enter 1C at the colon prompt. Then write the file to the disk with the W command and then quit DEBUG with the Q command. This works for files of any length. I would use XTree to view the file in HEX mode in order to find out how many characters to delete. It is also possible to use DEBUG to view the file before shortening it. At the first dash prompt, issue an RCX to determine the file length. When the colon prompt appears hit {ENTER} rather than entering a new length. Here is an example of a complete procedure where four characters are found at the end of the file and deleted. -rcx CX 001F : D 100 L1f xxxx:0100 4E 6F 74 65 73 3A OD 0A-74 68 69 73 20 69 73 20 XXXX:0110 61 20 74 65 73 74 20 66-69 6C 65 0D 0A 0D 0A -rcx CX 001F :1b -w -q If the file is a long one, it might take a few seconds for DEBUG to list the entire file following the D command in line 4. Just wait for it to finish. Note that the last four characters are 0D, 0A, 0D and 0A. That is two pair of carriage return/line feed characters. Those are the four to remove. The hexadecimal value 1Bh is four less than the hexadecimal value 1Fh. When using the D command to display the file, feed it a file length that matches the length reported by the first RCX command (1F in this example). That way it will be obvious where the end of the file occurs in the listing. Remember that DEBUG only works with hexadecimal numbers. If the file was 1A1h bytes long and you need to remove 5 bytes, the new file length is 19Ch. Those who own the Norton Utilities can use NU instead of DEBUG. In NU all you have to do is edit the directory listing for the program. NU will let you view the file to find out how many bytes to delete. When you edit the directory, it reports the file length in decimal notation. You can directly edit the file length and shorten the file to leave out the unwanted bytes at the end. ISSUING ESCAPE SEQUENCES CONTAINED IN TEXT FILES It is possible to execute the ANSI escape sequence stored in a text file two ways . Either the text file is a batch file with one or more ECHO commands containing escape sequences or it is an unformatted text file. If it is a batch file, execute it in any of the usual ways, from the DOS prompt, with a jump from another batch file or as a subroutine. The ECHO commands will write the ANSI escape sequences to the console even if the echo status is off. There are three ways to write an unformatted text file to the console. Using the TYPE command: TYPE file.ext Using the MORE filter: MORE NUL The "MS-DOS 5.0 User's Guide and Reference" only mentions using the TYPE command. Paul Somerson mentions all three techniques in his book "PC Magazine DOS Power Tools" 2nd Edition. He fails to mention redirecting the COPY command to NUL in order to suppress the confirmation message, however. An unformatted text file called BLU_WHIT.TXT, for example, might contain the following single line. {ESC}[0;37;44;1m That is the ANSI escape sequence for converting the color monitor to display bright white letters on a blue background. The trick is to send that escape sequence to the console so ANSI.SYS can intercept it. That is easy to do at the DOS PROMPT or in a batch file using one of the following commands. TYPE blu_whit.txt or MORE NUL The redirection to NUL at the end of the last command suppresses the standard DOS message "1 file(s) copied." For testing purposes, it works fine to use a text file that still has its carriage return, line feed and end-of-file characters. ISSUING ESCAPE SEQUENCES WITH ESC.COM, FORANSI.COM and ESC2.COM LISTING 1 contains the script files for creating three utility programs, ESC.COM, FORANSI.COM and ESC2.COM. ESC.COM was introduced by Hardin Brothers in his article on page 83 of the June 1989 edition of PCResource. FORANSI.COM was introduced by Chris DeVoney in his article on page 182 of the April 1991 issue of PC/Computing. ESC2.COM was introduced by Richard C. Jones (as ESC.COM) in his letter on page 261 of the February 1992 edition of PC World. Brett Glass in the Star-Dot-Star column of the February 1992 edition of PC World pointed out that the DOS DEBUG assembler uses slightly different syntax in different versions of DOS. Some of the scripts appearing in this series and elsewhere, specifically those using the mini-assembler mode, might not work with all DOS versions. Scripts that use the hexadecimal entry mode should work regardless of the DOS version, however. At least one of the following scripts should create a working utility no matter which DOS version you use. All three of them work fine with the DOS 5.0 version of DEBUG. (In fact, all the scripts reported in this series create working utilities in my tests using DOS 5.0.) =========================================================================== LISTING 1 - Script files ESC.SCR, FORANSI.SCR and ESC2.SCR Script File for ESC.SCR n esc.com a100 mov si,80 mov ch,0 mov cl,[si] mov byte ptr [si+1],1b mov dx,81 mov bx,1 mov ah,40 int 21 int 20 rcx 17 w q Script File for FORANSI.SCR n foransi.com e 0100 2e 80 3e 80 00 00 74 21 e 0108 b8 00 09 ba 2e 01 cd 21 e 0110 b8 80 00 2e 02 06 80 00 e 0118 fe c0 8b f8 a0 30 01 88 e 0120 05 ba 82 00 b8 00 09 cd e 0128 21 b8 00 4c cd 21 1b 5b e 0130 24 rcx 0031 w q Script File for ESC2.COM n esc2.com a100 mov bx,80 mov cx,1 mov dx,cx add cl,[bx] mov word [bx],5b1b mov ah,40 xchg dx,bx int 21 ret rcx 15 w q =========================================================================== Type each script file carefully. Each file starts with the N command. Make sure there is a blank line ahead of each RCX command and following the Q command at the end of each file. Notice that using lower case letters is perfectly acceptable and may even be easier to read. Store the text files in the TESTUTIL directory. Change to the TESTUTIL directory, which should also contain a copy of DOS's DEBUG utility. Still at the DOS PROMPT, issue the following commands one at a time. DEBUG