EXC The EXeCution Processor USER'S GUIDE Copyright 1993 by Gary C. Crider Is writing scripts a pain? See Appendix C about the new EXCR script recorder. TABLE OF CONTENTS: What is EXC? ..................................... 1.0 Requirements ..................................... 1.1 The EXC command line ............................. 2.0 Parameters that contain quotes ................. 2.1 Operational notes ................................ 3.0 General notes .................................. 3.1 Interrupt keys ................................. 3.2 Memory usage ................................... 3.3 Timing considerations .......................... 3.4 When EXC may not function or cause problems .... 3.5 Specific problems .............................. 3.6 Remote control communications ................ 3.6.1 MS-DOS external command programs ............. 3.6.2 Error handling ................................. 3.7 Scripts .......................................... 4.0 Script Basics .................................. 4.1 Script Commands ................................ 4.2 BEEP ......................................... 4.2.1 CAPS ......................................... 4.2.2 CASE ......................................... 4.2.3 CLEAR ........................................ 4.2.4 CURSOR ....................................... 4.2.5 CURSX ........................................ 4.2.6 CURSY ........................................ 4.2.7 DELAY ........................................ 4.2.8 FAST ......................................... 4.2.9 FILE ......................................... 4.2.10 GET .......................................... 4.2.11 GOTO ......................................... 4.2.12 HIDEWIN ...................................... 4.2.13 HLOCATE ...................................... 4.2.14 IFN .......................................... 4.2.15 IFY .......................................... 4.2.16 INT9 ......................................... 4.2.17 KEY .......................................... 4.2.18 LOCATE ....................................... 4.2.19 LOOK ......................................... 4.2.20 NOINT9 ....................................... 4.2.21 ON ........................................... 4.2.22 ONRESET ...................................... 4.2.23 PAUSE ........................................ 4.2.24 QUIET ........................................ 4.2.25 QUIT ......................................... 4.2.26 READ ......................................... 4.2.27 REWIND ....................................... 4.2.28 SCRMAX ....................................... 4.2.29 SEARCH ....................................... 4.2.30 SET .......................................... 4.2.31 SETWAIT ...................................... 4.2.32 SHOW ......................................... 4.2.33 SHOWAT ....................................... 4.2.34 SHOWIN ....................................... 4.2.35 SLOW ......................................... 4.2.36 TICK ......................................... 4.2.37 TIME ......................................... 4.2.38 TIMEOUT ...................................... 4.2.39 TYPE ......................................... 4.2.40 TYPFILE ...................................... 4.2.41 VLOCATE ...................................... 4.2.42 WAITCHG ...................................... 4.2.43 WAITFOR ...................................... 4.2.44 WAITSCR ...................................... 4.2.45 WINCOLS ...................................... 4.2.46 WINMAX ....................................... 4.2.47 WINROWS ...................................... 4.2.48 Labels ......................................... 4.3 Remarks ........................................ 4.4 Using variables ................................ 4.5 Environment variable substitution .............. 4.6 User variables ................................. 4.7 Example script ................................. 4.8 Installation ..................................... Appendix A Keycode table .................................... Appendix B EXCR Script Recorder ............................. Appendix C EXCDEMO .......................................... Appendix D Definition of Shareware .......................... Appendix E Disclaimer ....................................... Appendix F Support .......................................... Appendix G Registration ..................................... Appendix H 1.0 What Is EXC? As administrator of a large local area network, I believe whole- heartedly in automating every task that can be automated. Even though many tasks are computerized, that does not make them automated. By automated I mean that you enter one command or batch file name on the DOS command line and forget about it until the task is performed. Unfor- tunately many, if not most, programs require an operator to fill in blanks, select choices or otherwise interact with the PC to accomplish a task in which all of these parameters and choices were known to the user beforehand. I, for one, do not want to have to sit and watch my backups take place. In fact, I want them done while I am away from the office. After backups, what better time to defragment a hard disk? Do I want to have to chase menus to achieve this after the backup completes? One of the worst offenders of this I have seen is Stacker's SDEFRAG program. You can automate just about everything until the defrag has finished, then a stupid dialogue box pops up and asks you if you want to exit the program. No way to just move on back to the batch file and begin defragmenting the next drive. I first experimented with various keyboard stuffers such as PC Magazine's KEY-FAKE by Charles Petzold and STACKEY by Barry Simon and Richard Wilson. These programs take pre-programmed key sequences and stuff them into the keyboard buffer as if you had typed them at the keyboard. The trouble is that many programs rudely clear the keyboard buffer before requesting you to enter something or they allow you to interrupt the processing by pressing any key. Since you have already simulated pressing the key, oops!. In either case, you can't simply preprogram your reply and go. Stacker's SDEFRAG exit prompt is an example. Stuffers usually offer a way to get around this by programming a delay into the keystrokes that causes so many seconds to elapse before the key code is stuffed into the keyboard buffer. This is a help, but what if the time for a task (backup and defrag, for example) to complete varies greatly from one execution to another? You have to program for the longest possible execution time and the task then takes way too long to run in most cases. Another problem I have with stuffers is that they are almost always terminate-and-stay-resident (TSR) programs. I hate to stuff another program in my 640k when I don't have to. Although most allow you to unload them, you will forget more often than not. I then came across a program called AUTOMATE by Geoff Friesen that was a better approach. You built a script, compiled it and executed it. No TSR remained in memory. The trouble is, the only commands in the script were (1)execute a program, (2) wait, and (3) insert keys in the buffer. Also, you couldn't pass parameters to the program. AUTOMATE served as my inspiration to take it further. What I wanted was a program that had the intelligence to monitor the screen and detect when an event occurred that required me to insert more keycodes in the buffer. I would also like to see logical branching in the script and the ability to plan for exception processing as well as when everything performs normally. I want to be able to enter keyboard input when a certain string appears on the screen or when a string such as "Please wait..." disappears from the screen. There are times I just want to wait until any change at all occurs on the screen. EXC then, is more than just a buffer stuffer. It is a script (a.k.a. macro) processor that has a very simple script language that allows very complex scripts to execute much faster than you could execute them in attended mode. There are only slightly over thirty commands in the entire script language! Only about a dozen of these will be used often. The script language is interpretive, so no compile is needed. It is not a TSR, so nothing remains to eat up your precious RAM. EXC can even be used with your favorite DOS communications program to process online scripts. Send E-mail, download files, etc. EXC can even be used to automate mainframe tasks through your 3270 emulation gateway. You simply execute EXC specifying the script file to use and the program to be executed. You include all command line parameters for the program as usual. By combining EXC executions in batch files, extremely complex processing can be reduced to a single DOS command. EXC even returns the same DOS ERRORLEVEL that your program returned upon completion. All you need to know now is the format of the EXC command line and how to write a script. 1.1 Requirements EXC works on any Intel 80x86 and compatible processors. At this time, we are unaware of any unresolved incompatibilities with any software or hardware configurations. Any that are reported and not resolved will be reported here. Since Borland C++ v4.0 no longer supports code generation for 8086/8088 processors, EXC requires a 286 (80286) or better. 2.0 The EXC Command Line Format: EXC [path]scriptfile [[path]program] [command-line parameters] The scriptfile is the filename of the script to be processed. The extension, if specified, must be .SCR, but is not required to be specified. the script file is assumed to be in the current directory if a path is not specified. The program does not require a file name extension, but it must be a .EXE or .COM executable program file. .BAT files cannot be executed by EXC. If the path is not specified, the environment PATH= directories are searched. If the program is omitted from the command line, COMMAND.COM (or whatever command processor is reported in the COMSPEC environment variable) is assumed. Letting the program defaut to COMMAND.COM will probably cause a fatal memory violation error in an OS/2 DOS box. The command-line parameters are any parameters that you would specify on the DOS command line if you were executing the program without EXC. 2.1 Parameters that contain quotes If you try to pass command-line parameters to the spawned program that contain imbedded quotes, you must use \q in place of the quotes to be imbedded within the parameter. Parameters that contain spaces, |, < or > must be enclosed in quotes in order to be treated as a single parameter. If you want the spawned program to receive a parameter that looks like: Help "Me" Out, you would include it on the EXC command line as "Help \qMe\q Out" Confusing? You bet! But I have to work within the rules of DOS and the parameter passing rules of different languages and compilers. Amazingly, they do not all handle quoted strings in the same manner. I learned this the hard way by publishing a release (v2.2) that did not work when spawning most PASCAL and assembler programs and passing quoted parameters. 3.0 Operational notes 3.1 General notes If you want EXC scripts to execute multiple programs and/or enter intrinsic DOS commands on the DOS command line, omit the program from the EXC command line or specify COMMAND.COM which is the default (unless a different command processor such as 4DOS and NDOS is specified in the COMSPEC environment variable). Your script will begin executing on an empty DOS command line. EXC automatically issues an EXIT if COMMAND.COM was invoked. If you terminate the script with LEFT SHIFT-RIGHT SHIFT, or the script terminates with an error, you need to type EXIT at the DOS prompt to terminate the COMMAND.COM that you started and remove EXC from memory. Don't get cute and try to execute EXC as the object program of an EXC command. While it might logically work, I can see no possible need for such action and you and your system are at your own risk. EXC creates an extended keyboard buffer that will hold 256 keycodes. The DOS keyboard buffer will hold 16 keycodes. Thus you may stuff up to 272 keycodes with TYPE and KEY before the program requests keyboard input. If you overflow this buffer (very unlikely), a runtime error occurs and script processing is halted. EXC is written in Borland C++, a product of Borland International. 3.2 Interrupt keys You can pause execution of a script by pressing the Scroll Lock key. If your keyboard has a Scroll Lock indicator light, the light will be on while the script is paused. Pressing Scroll Lock again resumes execution of the script exactly where it left off. Any unexpired wait time must elapse before another command is processed. You can terminate execution of a script by holding down both the LEFT and RIGHT SHIFT keys. A beep will indicate that the script is being terminated. Execution of any spawned program will continue. The Pause key on your keyboard pauses all execution at the time the next screen write occurs. Timer interrupts continue. EXC detects the pause state and suspends itself. When you strike any key, both EXC and the spawned task will resume processing. Any unexpired wait time must elapse before another command is processed. While paused, the spawned program remains active. Since EXC is executing as a timer interrupt with your program operating as a spawned subtask, cycle-stealing multitasking is occurring. This can cause a few problems. If you must interrupt execution of your program, your best bet may actually be pressing CTRL-ALT-DEL to reboot the computer. If you hit CTRL-BREAK, you will normally interrupt just one task while the other continues. Pressing CTRL-BREAK again then interrupts the remaining task. This can confuse the remaining task to no end and lead to a system lock-up or other undesirable result. If you are lucky, you may actually get by with it, but I don't recommend it. Even if you terminate EXC with LEFT SHIFT- RIGHT SHIFT, the timer interrupt is still active until your program terminates, so the same problem can occur. 3.3 Memory usage EXC requires approximately 40K of conventional memory overhead. After loading, it then allocates a buffer to hold your script file and a buffer for reading the screen contents. If your application program's requirements are pushing the limits of available RAM, you may not be able to execute it under EXC control. If COMMAND.COM is spawned, an additional 3K (DOS 5) is used. The screen buffer varies according to the screen size active at startup or the value specified in an SCRMAX command. It will require one byte for every character position on the screen, plus 4 bytes. Thus an 80 x 25 text mode will require a buffer of 2004 bytes. If SCRMAX is present, that buffer size is always allocated, regardless of the initial text mode. The script buffer is the size required to hold all script commands strung end-to-end with 1 byte between each command. Leading and trailing spaces are not counted. If you use TYPFILE, the contents of the specified file are added to the script buffer. Thus, your script buffer will increase by the size of all files specified in TYPFILE commands. If you specify the same file in two different TYPFILE commands, the file will be loaded into memory twice. If the TYPFILE is executed multiple times within a loop, it only requires buffer space for a single copy of the file. With 604k of available memory, I am able to load a simple script with 35,000 fairly short commands. Versions prior to 2.0 were limited to a total memory allocation of 64k for all buffers. If your script is too large, you may encounter an error allocating script memory, allocating screen buffer memory or you will see an error message that says you do not have enough memory to spawn your program. 3.4 Timing considerations EXC installs itself as a timer interrupt that is invoked 18.2 times per second. If it has no work to do, it simply executes the system timer interrupt and any other chained timer interrupts and returns. During waits (DELAY, WAITFOR, etc.) the frequency of invocation is reduced to twice per second. This minimizes the impact of the interrupt on the performance of your program. A half-second is forever to most computers. This also means that if you are searching for a string with WAITFOR, and the string flashes on the screen for less than 1/2 second, it will not be detected. Needless to say, EXC does not have but 1/18th of a second to retrieve and execute a command. This is a long time in a fast computer and a short time to a slow system. I try to break commands down into logical parts that are executed in consecutive interrupts. Obviously, there are some commands that will probably take longer than 1/18th of a second, especially on slower systems. EXC is a handler for interrupt 1C. No new 1C interrupts are initiated by the system until the active one is complete. While missing a few interrupts has minimal effect on EXC or DOS, it could effect a spawned task or TSR that is also servicing 1C interrupts. Very slow CPUs (6 Mhz or slower) may experience problems getting some tasks to function properly. Sometimes a few judiciously placed DELAY or TICK commands will help. Sometimes you may have to break down very long typed strings into multiple TYPE commands. Others just may not work at all if they just cannot accomplish their tasks fast enough. Most of the more commonly used commands should work fine. 3.5 When EXC may not function properly GRAPHICS MODES do not store text characters in video memory, only pixels of differing colors. EXC cannot interpret these pixels into characters, thus commands that are based on screen reads will not work in graphics modes. This includes WINDOWS, OS/2 and their apllications. Note that EXC can be run in a WINDOWS or OS/2 DOS session. EXC also does not support recording mouse movement and clicks. In order to execute screen reads and writes rapidly due to timing restraints, EXC reads and writes (SHOW, SHOWIN, READ, WAITFOR, WAITSCR, etc.) directly to and from video memory at pages B000-B7FF. If you use DESQVIEW or a special graphics mode that relocates the active video page outside this area, screen reads and writes will not function properly. This also prevents these commands from working properly in CGA modes. All VGA text modes and most SVGA text modes should work properly. If you use programs that change to a different text resolution during processing, please be sure to read about the SCRMAX command. If the program you are executing or a TSR that is loaded in memory moves or otherwise messes with the DOS keyboard buffer, it could cause EXC to malfunction. The most likely symptom would be keys that you TYPE or KEY not showing up or not appearing to have been pressed. EXC uses BIOS interrupt 16h, service 5 to insert the keys into the keyboard buffer. It does not reallocate or move the buffer. It merely creates a new extended buffer that only EXC is aware of. As the timer interrupts occur, EXC always checks to see if anything is in the extended buffer, if so it will move as many keycodes as the PC keyboard buffer will hold into the keyboard buffer, or until the extended buffer is empty. BIOS interrupt 16h is not available until later XT BIOSes. As a general rule, EXC should not be used except on AT models or later. Other factors that could cause EXC to malfunction include programs and TSRs that have timer and keyboard interrupt handlers. Customary usage of these interrupts provides for allowing other installed handlers to perform their function, but you cannot count on all programmers to abide by these conventions. Since even "behaved" handlers can do virtually anything within these routines, EXC cannot be guaranteed to function on these programs. Fortunately, they are very rare. EXC will work with many of them (i.e. QBASIC and EDIT from MS-DOS 5.0 up). If a TSR or spawned task is using timer interrupt 1C for timing (music, communications, etc.) the timing could be thrown off slightly by EXC, especially in slower systems. In most cases, the effect will be negligible, but in some it will prevent you from being able to use EXC. If you experience problems with keys being ignored or missing or out of order, try the SLOW and/or NOINT9 commands. See the description of these commands for more details. If you spot another program, video mode or anything else that causes EXC to malfunction, send me a CIS mail or U.S. mail note and I will check it out if I can. I will include a note in this section on those reported problems if they cannot be fixed. 3.6 Specific problems 3.6.1 Remote control communications Some communications programs, especially those used for remote control of a PC, may cause some particular problems for EXC. WIZLINK, a very good shareware implementation, evidently runs a timer interrupt that empties the comm buffer and paints the screen. This interrupt has a lot to accomplish and does not take kindly to another interrupt handler stealing CPU cycles that it needs. The symptoms seen are unusual characters appearing on the screen and WIZLINK occasionally logging off the host. This is seen when a WAITCHG, WAITFOR or WAITSCR is active at this point in your script. The WAITFOR may not detect a matching string because of the garbaged screen display. The best solution is not to use WAITCHG, WAITFOR and WAITSCR commands. By using DELAY instead, all seems to work well. Here is a compromise that appears to work O.K. with a little experimentation and tuning: In your script, just before the connection is made with the host, issue a SLOW command. Then in the place of WAITFORs during an active session, use the following: :LOOP1 DELAY 5 SEARCH "String I Want" IFN LOOP1 Use this loop in the place of the WAITFOR and make sure you place the DELAY before the SEARCH. Experiment with the amount of delay to find the lowest value that repeatedly eliminates the garbled screen. The slower the baud rate used for the session, the longer the DELAY has to be. Similar problems have been reported, but not yet verified by me, with pcANYWHERE III and SmartTerm 240. pcANYWHERE IV has a whole different problem. While WAITCHG, WAITFOR and WAITSCR appear to work ok, TYPE and KEY do not work at all. pcANYWHERE IV has an intricate keyboard handler that allows both the host and remote keyboards to work concurrently. It appears to be monitoring hardware interrupts and reading the keyboard device directly at the remote PC. Thus any software-generated keys and interrupts are ignored and not sent to the host during a pcANYWHERE-to-pcANYWHERE session. The problem is only with keys being sent to the host, not keys recognized and acted upon by AWREMOTE. If you are logged on to a BBS or otherwise using it as a normal communi- cations program, it appears to work fine. If you need to control a program on the host with EXC, it needs to be started with EXC on the host computer, rather than starting AWREMOTE with EXC. This appears to work OK, but the host PC will need a license for EXC. 3.6.2 MS-DOS external command programs Some MicroSoft DOS external command programs obtain command line parameters in some flaky parsing routine that does not allow proper passing of arguments by the C spawn function. Some of these include CHKDSK, FORMAT and EDLIN. Some others, such as XCOPY, appear to work O.K. It appears that they are using control area pointers to access the command line parameters in a non-standard manner. The original command line, of course, includes EXC and the script file name. Thus the parameters are shifted into positions where the program does not expect them. I tried removing them from the command line that is stored in the PSP for EXC, but the programs still fail to function properly. You can, however, invoke FORMAT (for example) and use EXC to process it by invoking the command processor and having EXC type the format command on the command line. The following script is a modified version of one created by Don Davenport of Albany Georgia. It assumes that it is invoked from a batch file that sets the environment variable DRV to the letter of the desired floppy drive: SETWAIT 25 TIMEOUT TOUT GOTO DRV%DRV% :DRVA TYPE "FORMAT A: /S /U" KEY GOTO CONT :DRVB TYPE "FORMAT B: /S /U" KEY :CONT WAITFOR "ENTER when ready..." KEY :CONT2 SETWAIT 360 TIMEOUT TOUT2 WAITFOR "ENTER for none" KEY GOTO END :TOUT SEARCH "ENTER when ready..." IFN END2 KEY GOTO CONT2 :TOUT2 SEARCH "ENTER for none" IFN END2 KEY GOTO END :END2 QUIT 7 :END WAITFOR "(Y/N)?" TYPE "N" KEY QUIT The batch file looks something like this (simplified greatly from Mr. Davenport's orginal batch file): SET DRV=A EXC FMT IF ERRORLEVEL 7 GOTO ERROR SET DRV=B EXC FMT IF ERRORLEVEL 7 GOTO ERROR GOTO END :ERROR ECHO Error formatting drive %DRV% :END SET DRV= 3.7 Error handling If an error occurs that prevents EXC from initiating the program, a message will appear and a DOS ERRORLEVEL of 255 will be returned. If the program is successfully initiated, EXC will return the DOS ERRORLEVEL that the program returned when it completed. There is an RC = nnn message after EXC terminates that displays the DOS ERRORLEVEL returned by your program and by EXC. When COMMAND.COM is executed, the ERRORLEVEL will not reflect what was returned from one of the programs you executed and will always be zero. If EXC encounters an error while processing the script (i.e. an invalid script statement) it will sound two short beeps on the PC speaker and terminate processing any more script commands. When the spawned program completes or is exited, a message will appear specifying the error EXC encountered. If the spawned program terminates before EXC has finished processing the script, all script processing terminates at that point. Keycodes that have been stuffed into the buffer remain there. This allows you to enter a new command on the DOS command line from within your script. You can actually chain EXC processing without the use of a batch file. 4.0 Scripts Scripts can be written with any ASCII text file editor. There is one command per line. Leading and trailing blanks and tabs, lines beginning with a semicolon (;) and blank lines are ignored by the script processor. You may have more than one blank between the command and its parameter(s). All window coordinates specified in some commands are based on the full screen currently displayed. The upper left corner is column 1, row 1. All "string" parameters can accept quotes within the string by placing the characters \q (lower case) in the string where you want a quote to occur. 4.1 Script Basics Scripts are text files created with your favorite text editor that emulate your actions and reasoning as you perform an interactive task while using a DOS-based program. As you would say to yourself, "When I see this on the screen, I will type this and press these keys and wait for that to appear before I enter this", etc. You can create EXC scripts that use this same logic and perform the same tasks, even to making decisions when different results may appear on the screen. Creating a script is not that difficult. Do not be intimidated by all the commands below. You will find that 90% of your scripts may only use three or four of them. The rest are for more esoteric applications, but they are there if you need them. To create a script to preform a repetitive task, perform the task as you normally do, taking notes as to what changes on the screen and what keys you press. Then simply reproduce these actions with script commands, testing a little at a time as you go. Commands may start anywhere on a line, but only one command per line is allowed. This allows indentation for clarity. If the first non-blank character on a line is a semi-colon (;), the line is treated as a comment and disregarded. Blank lines are also disregarded. If the first non-blank character is a colon (:), the following text is treated as a label, to be used as a branching destination. There must be at least one space between the command and the first parameter and between parameters. More than one space is allowed, but could increase the memory requirements of EXC. As mentioned earlier there are a few basic commands that can handle most of your needs. These include TYPE, KEY, WAITFOR, and DELAY. These are the true workhorse commands of EXC. READ, LOOK and SEARCH may come in handy when looking for more than one thing on the screen and WAITCHG and WAITSCR are handy when you don't care what the results are, only that something was sent back to the screen. Some commands are truly useful only while debugging. These include commands such as BEEP, SHOW, SHOWIN, SHOWAT, HIDEWIN and PAUSE. Decision making, looping and branching within the script to different logic paths are facilitated by commands such as GOTO, IFN, IFY, ON, ONRESET, QUIT, and TIMEOUT. Moving the data entry cursor around the screen are facilitated by commands like CURSOR, CURSX, CURSY, LOCATE, VLOCATE, and HLOCATE. The last two are exceptionally valuable when moving menu bars to the selection you need. Sectioning the screen to limit your reads and searches to a sector of the screen is done with WINCOLS, WINROWS and WINMAX. FILE, GET and REWIND are particularly beneficial to projects that seek to convert data from one database or database type to another. To do this you export or print to disk a listing of the contents of the source database, one field per line. You can create a script that uses the exported ASCII file as input and does the data entry into the new database manager. The uses for EXC scripts are many and varied, from automating repetitive tasks, to creating elaborate "macros." Many users use it to automate data communications tasks such as downloading files from a remote computer. Think of EXC as a macro processor for any type of DOS text-based program. Of course, if the program you are using has a built-in macro or script processor, you would be better off using the one that is native to your program. 4.2 Script Commands Note: Brackets ([]) indicate an optional parameter and should not be included as part of the command. Quotes (""), where specified, are required to be entered as part of the parameter. BEEP Sound a short beep on speaker. Useful in debugging scripts. CAPS Toggle the CAPS LOCK state from its current state to the opposite state. CAPS OFF Turn CAPS LOCK off. CAPS ON Turn CAPS LOCK on. CASE OFF Enables case-insensitive compares by WAITFOR and SEARCH. The initial mode is CASE ON. CASE ON Enables case-sensitive compares by WAITFOR and SEARCH. CLEAR Clear the screen. CURSOR col row Move the cursor to the specified coordinates. CURSX col Move the cursor to the specified column. CURSY row Move the cursor to the specified row. DELAY n Wait n seconds FAST Turns off SLOW mode if SLOW was invoked. FILE filespec Open a file for processing with GET commands. GET eoflabel blanklbl Read a record from and external file into variable 16. GOTO label Unconditional branch to label. IFN label If condition set to N, go to label. IFY label If condition set to Y, go to label. INT9 Issue interrupt 9 (default mode). HIDEWIN Restore a window displayed with SHOWIN to it's original color attributes. HLOCATE "string" Same as LOCATE except cursor only moves horizontally to the column where the search string was found. KEY mnemonic [n] Push the key onto the keyboard stack. 'n' is the number of times you want the keycode inserted. LOCATE "string" Reads the screen until the string appears, then moves the cursor to the start of the string. LOOK "string" Test to see if the string was on the screen at the time the screen was last read. Screen reads occur during execution of READ, SEARCH, WAITCHG, WAITSCR and WAITFOR commands. Sets "Y/N" condition. NOINT9 Stop issuing interrupt 9s. ON n label Command will do nothing n times and on pass n+1, it will branch to label. ONRESET Reset the ON counter when terminating an ON loop early. PAUSE Causes the script to be paused as if Scroll Lock were pressed. QUIET Supresses messages to screen from EXC. QUIT Halt processing the script file. End-of-file on the script file issues an automatic QUIT. READ Read the current screen contents. REWIND Go to the start of an external file (see FILE, GET). SCRMAX cols rows Specifies the largest screen size that will be used during execution. Used to allocate screen buffer. SEARCH "string" Read screen and test to see if the string is on the screen. Sets "Y/N" condition. SET n "string" Set variable n to value "string". SETWAIT nnn Wait nnn seconds before a WAITFOR, WAITCHG or WAITSCR times out. SHOW attr "string" Display the string using the specified attribute. Displays at the location specified in SHOWAT. SHOWAT col row Specifies location for subsequent SHOW command strings to be displayed. SHOWIN attr Rewrite the current window text in the specified attribute. SLOW [n] SLOW mode can help you on slow CPUs or slow programs. Slower keying. TICK n Same as DELAY except n represents 1/18th of a second instead of a second. TIME hhmmss Pause execution of subsequent commands until the specified time of day. TIMEOUT label Branch to label when the next WAITCHG, WAITFOR or WAITSCR timeout occurs. TYPE "string" Type the ASCII string. TYPFILE filespec [mnemonic] Type the contents of the specified file. Replace CR/LFs with specified key mnemonic. VLOCATE "string" Same as LOCATE except cursor only moves vertically to the row where the search string was found. WAITCHG Wait for any change on the screen since the last READ was executed. WAITFOR [NOT] "string" Wait until the string appears on the screen. If NOT specified, wait until string is not on screen. WAITSCR Read the screen and wait for any subsequent screen changes. WINCOLS start end Limit screen reads and SHOWIN to the screen columns specified. WINMAX Remove row and column restraints imposed by WINCOLS and WINROWS. Subsequent reads read the full screen. WINROWS start end Limit screen reads and SHOWIN to the screen rows specified. :label Define a label. 4.2.1 BEEP Sounds a short BEEP on the PC speaker. Since there is no visual feedback for many of the operations and branches performed while processing a script, debugging a script can be tough if it is complex. Inserting a BEEP at a strategic location in the script will tell you if processing ever reached that point in the script. NOTE: BEEP does not extend the duration of the timer interrupt. It actually is turned on, then turned off a few ticks later. 4.2.2 CAPS, CAPS OFF and CAPS ON The CAPS commands control the status of the CAPS LOCK indicator on the keyboard. CAPS with no parameter is just like hitting the CAPS LOCK key. It reverses the current state of CAPS LOCK. CAPS OFF forces the CAPS LOCK condition to be inactive, while CAPS ON forces the CAPS LOCK condition to be active. Examples: CAPS CAPS ON CAPS OFF 4.2.3 CASE OFF and CASE ON The CASE commands determine case sensitivity during SEARCH, LOOK and WAITFOR string searches. If CASE is ON, the search string and screen contents are unchanged during the search, and must match in upper and lower case. If CASE is OFF, the search string and all characters read from the screen are converted to upper-case before the search begins so that case does not influence the result of the compare. The initial CASE mode is ON. NOTE - You must reread the screen after changing the CASE mode before the new CASE mode will take effect. See TIMEOUT for example. 4.2.4 CLEAR The CLEAR command clears the entire screen, not just the active window. It also homes the cursor. Use with caution, this could cause problems within many applications. 4.2.5 CURSOR col row The cursor is moved to the location on the screen (not just within the active window) specified by col and row. Col and row are the screen column and row. CURSOR is designed primarily to be used in a full screen editor or similar applications where the cursor can be moved with the arrow keys. The destination must be in an area of the screen where the active application allows typing. CAUTION: In order for your application to recognize that the cursor has been moved, a series of and keys are stuffed into the buffer and executed until the cursor is at the desired location. If you send the cursor to a location that is not in an acceptable input area of the active application, the cursor will jump around the destination, but never get there. You will have to terminate the script with LEFT SHIFT- RIGHT SHIFT. Some applications require the use of other keys such as TAB to move from one field to another. Example: CURSOR 17 41 4.2.6 CURSX col The cursor is moved to the column specified. No vertical movement keys are issued. See CURSOR for more details and a CAUTION. Example: CURSX 12 4.2.7 CURSY row The cursor is moved to the row specified. No horizontal movement keys are issued. See CURSOR for more details and a CAUTION. Example: CURSY 20 4.2.8 DELAY n Pauses execution of subsequent script commands until the specified number of seconds has elapsed. Example: DELAY 3 4.2.9 FAST FAST is used to reverse the effect of a previous SLOW command. FAST is the initial state. See the SLOW command for a full explanation. FAST has no parameters. 4.2.10 FILE filespec FILE specifies an external ASCII text file path/name to be opened for input when EXC initializes. The records of the file can be retrieved one at a time using the GET command. When the script terminates, the file is closed. There can only be one FILE statement within a script. If you attempt to issue another, a message indicating an open error will be issued and the spawned program will not be invoked. The FILE statement can occur anywhere within the script, before or after any GET statements. The filespec is any valid DOS file name. If it is not in the current working directory, include the drive and path to access the file. CAUTION! File I/O from within a timer interrupt such as EXC is a DOS no-no. EXC invokes some tricks to pull it off, but if you experience problems using FILE and GET in a particular script, you should abandon the idea and seek another approach. See GET for example. 4.2.11 GET eoflabel blanklabel GET reads the next record (up to 128 bytes) from the file specified in a FILE command. The record is retrieved into variable 16 and can be used as any variable can. Trailing blanks are removed from the record as are carriage return and new line characters. If there is no FILE command in the script, GET is ignored. To return to the first record in the file, use the REWIND command. The eoflabel parameter is a label to which control is transferred upon reaching end-of-file on the file. The blanklabel parameter is a label to which control is passed if the current record is blank or empty. When a blank record is read, variable 16 contains nothing, therefore special handling may be required. If not, just specify a label immediately following the GET command. Please see the FILE command for additional information and a caution. Example: Reads file TESTEXC.FIL and types each record followed by pressing ENTER. If a blank record occurs, the ENTER key is pressed. Returns to the start of the file and does it again. FILE TESTEXC.FIL :LOOP GET ENDLOOP BLANK TYPE "@16@" :BLANK KEY GOTO LOOP :ENDLOOP REWIND :LOOP2 GET ENDLOOP2 BLANK2 TYPE "@16@" :BLANK2 KEY GOTO LOOP2 :ENDLOOP2 4.2.12 GOTO label Executes an unconditional branch to the command following the specified label. See ON for example. 4.2.13 HIDEWIN Restore the active window to its original attributes after a SHOWIN command has be executed. If no SHOWIN has been executed, the results will not be pleasing to the eye. Also, screen reading commands must not be executed between a SHOWIN and its corresponding HIDEWIN. See SHOWIN for reasons for using SHOWIN and HIDEWIN. See SHOWIN for example. 4.2.14 HLOCATE "string" Same as LOCATE except that only horizontal movement keys are issued to place the cursor in the same column where the search argument was located. It is actually the column of the first character of the located string. See LOCATE for more details and a CAUTION. Example: HLOCATE "Help" 4.2.15 IFN label This tests the results of a previous SEARCH or LOOK command. If the search string was not located on the screen, processing resumes at the command following the specified label. If the string was found on the screen, processing resumes with the next command after the IFY command. If no previous SEARCH or LOOK has been issued, processing continues after branching to the specified label. Thus, without a preceding SEARCH or LOOK command, the IFN command becomes an unconditional branch equivalent to a GOTO command. The IFN statement does not have to be the next command after the SEARCH or LOOK. Example: :Loop READ LOOK "XYZ" IFN LoopEnd . . . GOTO Loop :LoopEnd . . . 4.2.16 IFY label This tests the results of a previous SEARCH or LOOK command. If the search string was located on the screen, processing resumes at the command following the specified label. If the string was not found on the screen, processing resumes with the next command after the IFY command. If no previous SEARCH or LOOK has been issued, the result is negative and processing continues without branching. Thus, without a preceding SEARCH or LOOK command, the IFY statement appears as a null or nonexistent command. The IFY statement does not have to be the next command after the SEARCH or LOOK. See ON for example. 4.2.17 INT9 INT9 is used to reverse the effect of a previous NOINT9 command. INT9 is the initial state. See the NOINT9 command for a full explanation. INT9 has no parameters. 4.2.18 KEY [n] KEY is used to enter special keys that require mnemonics (special names enclosed in <> that represent their function) in order to input them to the keyboard buffer. If n is specified, it is the number of times will be inserted into the keyboard buffer. For instance, if you wanted three TABs, you would type "KEY 3". If n is not specified, it is assumed to be 1. The following key mnemonics are recognized: Single keys mnemonics: - Two key mnemonics (see note below): Shift key combinations: or CTL key combinations: or ALT key combinations: or Three key mnemonics (see note below): Shift + ALT key combinations: or CTL + ALT key combinations: or CTL + Shift key combinations: or Four key mnemonics (see note below): or x = any ASCII value that can be entered from the keyboard with a single key, or SHIFT + a single key. s = any of the single key mnemonic keywords or character except . NOTE: Some SHF, CTL and ALT key combinations are undefined. See the keycode table in Appendix A. Do not use to simulate a capital A, or any other letter. Just use the appropriate case in a TYPE statement, i.e. TYPE "A". When entering 3-or-more-key combinations you must make sure you are at the correct point in your program for entering these keys and that no other keys are still unprocessed in the buffer. To detect these combinations, a program must interrogate the BIOS keyboard flags to see if CTL, ALT or SHIFT are being held down. This can only be done in real time as the keys are being pressed, therefore they cannot be stuffed into the keyboard buffer, and must be executed immediately upon encountering the KEY command in the script. The appropriate flags are set, the keycode is stuffed and an interrupt 9 is issued. If there is already a key in the buffer, the flags will accompany the wrong keycode when the interrupt 9 is processed. Not all programs will recognize these combinations as simulated by EXC. Attachmate's EXTRA!, for example, maintains such tight control of the keyboard, that EXC's control key combinations are ignored. The mnemonic causes a system warm boot. It does not work properly in a WINDOWS DOS session. WINDOWS will intercept the jump to the system BIOS and produce a "System integrity violation" message. Examples: KEY 3 KEY KEY 4.2.19 LOCATE "string" The LOCATE command is mostly a combination of WAITFOR and CURSOR. You provide a string. Processing will be suspended until that string appears in the active window or a timeout occurs. Once the string is located, the cursor is moved, via a sequence of arrow keys stuffed in the keyboard buffer, to the location of the first character of the string. LOCATE is designed primarily to be used in a full screen editor or similar application where the cursor can be moved with the arrow keys. The located string must be in an area of the screen where the active application allows typing. CAUTION: In order for your application to recognize that the cursor has been moved, a series of and keys are stuffed into the buffer and executed until the cursor is at the desired location. If you send the cursor to a location that is not in an acceptable input area of the active application, the cursor will jump around the destination, but never get there. You will have to terminate the script with LEFT SHIFT- RIGHT SHIFT. Some applications require the use of other keys such as TAB to move from one field to another. Example: LOCATE "Help" 4.2.20 LOOK "string" Look at the last screen that was read to see if it contains the value in "string". The entire active window contents will be searched to see if "string" was being displayed when the last screen read occurred. The string may be any valid screen characters. There is no wait involved as with WAITFOR. The screen contents are read each time a READ, SEARCH, WAITCHG, WAITSCR, WAITFOR or LOCATE command is executed. In the case of WAITCHG, WAITFOR and WAITSCR, multiple reads occur until a search string or change is detected. The contents of the screen buffer remain as they were when the last read was executed at the time the search string or change was detected or a timeout occurred. Once it has been determined whether or not "string" was being displayed, an internal variable is set to "Y" or "N". IFY and IFN can then be used to test the result of the search and then branch accordingly. Example: LOOK "Help" 4.2.21 NOINT9 A few certain programs (i.e. MS-DOS's EDIT and the QBASIC editor) require a keyboard interrupt before they will process keys in the keyboard buffer. For this reason, EXC normally issues the interrupt 9 keyboard interrupt. It is conceivable that other programs may have interrupt handlers that do not like the INT9 being issued. The most likely symptom would be keys not processed or processed out of order. Specifying NOINT9 will cause EXC to not issue the INT9. Try this command if you are having problems you can't seem to resolve. Also try the SLOW command. INT9 should normally be issued once in the script before any TYPE, KEY or TYPFILE commands are issued. It can however, be turned on to get you over a sticky area, then reversed by issuing the INT9 command. You can issue the NOINT9/INT9 commands as many times as you wish. NOINT9 has no parameters. Example: NOINT9 TYPFILE C:\MYFILE.TXT INT9 4.2.22 ON n label For the first n executions of the ON command, execution simply passes to the next command. On the next pass through the ON command, a branch occurs to label. The value of n can range from 1 to 9999. A second ON command must not be issued while another ON command is active. This will cause unpredictable results. After an ON command has counted down and branched, another ON command may be issued. You can reset the ON counter to zero by using the ONRESET command. Then an additional ON command can be issued even if the previous one has not reached zero. Obviously, multiple ON commands cannot be processing at the same time. For instance, you may not call a subroutine that contains an ON command from within an ON loop. A good practice is to always issue the ONRESET command when exiting an ON loop via any branch other than that specified in the ON command. Example: :LOOP ON 5 ENDLOOP SEARCH "ERROR:" IFY ERROR TYPE "xyz" - These two instructions are executed five KEY - times unless an error message pops up. GOTO LOOP :ENDLOOP KEY :ERROR ONRESET :LOOP2 ON 3 QUITPGM . . . GOTO LOOP2 :QUITPGM QUIT 4.2.23 ONRESET Used to reset the ON counter so than another ON may be issued if the previous one has not completed. See ON for further explanation and example. 4.2.24 PAUSE PAUSE simulates pressing the Scroll Lock key to pause the script execution. See the section on interrupt keys for a description of pause processing. 4.2.25 QUIET The QUIET command, placed anywhere in a script will cause EXC to supress displaying any messages on the screen. It is only operable on registered copies of EXC. This prevents suppression of the registration notice and is the only command in EXC that operates any differently in the registered and unregistered copies of EXC. Exceptions to the quiet suppression are error messages that prevent EXC from reading the script file and initiating. 4.2.26 QUIT [n] QUIT stops processing a script at the point where it is encountered during script execution. The same result is obtained when there are no more script commands to process. Normally on exit, EXC returns the return code of the executed program. If a number (0-255) is specified with the QUIT command, that value is returned as the DOS ERRORLEVEL return code instead of what was passed from the spawned program. An example of why you would want to set a return code: I use EXC to control PROCOMM PLUS to execute a script that synchro- nizes my clock with the Naval Observatory. I need to know if it fails. I can detect the error with my EXC script, but when I exit PCPLUS, PCPLUS always returns a return code of 255. Using the QUIT 1 command, I can set a DOS ERRORLEVEL of 1 on error and 0 when there is no error. If COMMAND.COM was invoked by the EXC command line, QUIT types EXIT and keys in order for EXC to be able to complete. If you issue the QUIT while another program is active, you will not obtain the desired results. See TIMEOUT for example. 4.2.27 READ Reads the active window for subsequent testing with the LOOK or WAITCHG command. Using a READ followed by several LOOKs that examine the same screen contents can be much more efficient than issuing several SEARCHes, each of which reads the entire screen contents. See WAITCHG for example. 4.2.28 REWIND The REWIND command returns the file pointer for an external file to the start of the file so that the next GET command will return the first record in the file. GET and FILE contain additional information regarding the use of external files. See GET for example. 4.2.29 SCRMAX cols rows I hate including technical parameters in my commands, but this one is a must for successful operation of EXC in larger screen modes. Specify SCRMAX if you expect a spawned application to change to a text screen mode larger than the text mode in use when EXC is initiated. For instance, if you are in DOS with 25 rows of 80 column text and you initiate an editor with EXC and the editor places the screen in 80x50 text mode, specify "SCRMAX 80 50" in your script (no quotes). Since this command is processed when the script is being loaded into memory and not after the script processing begins, it may be placed anywhere within your script. Logically, it should occur at the start. If multiple SCRMAX commands are encountered, only the last one input will be used. If your application will use multiple screen sizes, specify the largest (in area: cols times rows) that will be used. If you do not include SCRMAX in your script, it is assumed that the screen size in effect when EXC is loaded and before the spawned program is loaded will be the maximum size needed. The range of text mode screen sizes supported by EXC includes from 40x20 to 200x100 characters. SCRMAX can have a major impact in the amount of memory occupied by EXC. It would seem that the logical thing for EXC to do would be to examine the screen size before each read and allocate the screen memory buffer accordingly at that time. However, since EXC spawns another program which can, and often does, allocate all of the remaining memory, EXC must pre- allocate the largest buffer that will be required before spawning the program. A screen buffer requires the same number of bytes as the rows times the columns, plus 4 bytes. Thus, an 80x25 VGA text screen will require a 2,004 byte buffer. I actually had a user contact me who uses a 132x66 display (great eyes or a huge monitor!). This would require 132 * 66 or 8,712 bytes of memory. If you do not specify SCRMAX and your program bumps up the screen size, the effective area of the larger screen is the upper left quadrant corresponding to the size of the screen when EXC was loaded. This is also true if you specify an SCRMAX smaller than the largest screen. In other words, if you specify SCRMAX 80 25 and your program changes to a 132x44 screen, Only the first 80 columns and 25 rows are read by EXC's READ, WAITFOR, WAITCHG, WAITSCR, LOCATE and SEARCH commands. If all of the strings you search for and changes you wish to detect are in the upper left of the screen, you can save memory by specifying a smaller SCRMAX size. You would really have to be in a memory crunch to bother with this approach, I suspect. Examples: SCRMAX 80 50 SCRMAX 132 25 4.2.30 SEARCH "string" At any point in processing the script, you may check to see if certain information is on the screen. The entire active window will be read and searched to see if "string" is being displayed. The string may be any valid screen characters. There is no wait involved as with WAITFOR. Once it has been determined whether or not the string is being displayed, an internal variable is set to "Y" or "N". IFY and IFN can then be used to test the result of the search and then branch accordingly. SEARCH is basically a READ followed immediately by a LOOK. See ON for example. 4.2.31 SET n "string"|NULL SET is used to set one of the 16 user variables to a value, where n is the variable number (1-16) and string is the value which will be assigned to the variable. Do not surround n with @s which are used to reference variables for substitution. To clear a variable, type SET n NULL. See "User variables" for more information and examples. 4.2.32 SETWAIT seconds This sets the timeout limit for WAITCHG, WAITSCR, WAITFOR and LOCATE commands. If processing is waiting after invoking any of these commands and the specified number of seconds elapses, TIMEOUT processing, described under TIMEOUT, will be invoked. You may change the SETWAIT timeout limit at any point while processing the script. If SETWAIT is set to zero, no timeout ever takes place and EXC will wait indefinitely during WAITFOR, WAITCHG, WAITSCR and LOCATE. The initial value of the SETWAIT timer is zero. See TIMEOUT for example. 4.2.33 SHOW attr "string" SHOW displays a string at a given location on the screen. This command is mostly useful for debugging scripts by displaying information about the progress of the script during execution. While mostly harmless, it can cause problems if a spawned program reads screen memory. Use it cautiously. The string is displayed at the location specified in the last executed SHOWAT command. The screen attribute is the sum of a background value plus a foreground value from the table below. Add 128 if you want it to blink. Background colors: Foreground colors: 0 Black 0 Black 16 Blue 1 Blue 32 Green 2 Green 48 Cyan 3 Cyan 64 Red 4 Red 80 Magenta 5 Magenta 96 Brown 6 Brown 112 Light Gray 7 Light Gray 8 Dark Gray 9 Light Blue 10 Light Green 11 Light Cyan 12 Light Red 13 Light Magenta 14 Yellow 15 White See TIMEOUT for example. 4.2.34 SHOWAT col row Specifies the location on the screen where subsequent SHOW commands will display their strings. The location does not have to be within the active window set via WINROWS and WINCOLS. See TIMEOUT for example. 4.2.35 SHOWIN attr SHOWIN is designed as an aid to script writing. Sometimes you will want to restrict the active window to certain rows and columns, thus creating a smaller active window for processing commands that read the screen. To make sure you have calculated the correct area for the active window, you can use SHOWIN to show you where the active window is located on the screen. SHOWIN will change the attribute of all characters and spaces within the active window to that specified. See the SHOW command for attribute values. HIDEWIN can then be used to restore the window to its normal attributes. There must never be any screen reading commands (WAITFOR, WAITCHG, WAITSCR, SEARCH, READ and LOCATE) executed between the SHOWIN and its associated HIDEWIN. Example: WINCOLS 10 30 WINROWS 12 22 SHOWIN PAUSE HIDEWIN 4.2.36 SLOW [n] Some slow CPUs may have problems where a few characters in TYPEd strings get entered out of order or are missing. The problem may also occur when TYPFILE is used. The problem can also occur with an application that is slow in reading the keyboard. Using the SLOW command can often resolve the problem, although the strings will be typed in a little slower. Other problems, as yet undetermined, might be fixed by using SLOW, so give it a try if your script is not responding properly, regardless of the speed of your CPU. You might also try the NOINT9 command. SLOW should normally be issued once in the script before any TYPE, KEY or TYPFILE commands are issued. It can however, be turned on to get you over a sticky area, then turned off by issuing the FAST command. You can issue the SLOW/FAST commands as many times as you wish. SLOW has no parameters. The parameter [n] controls the amount of slowing, with 1 being the slowest and 16 being the fastest keyboard entry speed. SLOW 16 is still much slower than FAST mode on large strings and files. SLOW 3 is assumed if n is not specified. Example: SLOW 5 TYPFILE C:\MYFILE.TXT FAST 4.2.37 TICK n Pauses execution of subsequent script commands until the specified number of system clock ticks (18.2 per second) have elapsed. Example: TICK 12 4.2.38 TIME hhmmss Pauses execution of subsequent script commands until the specified time of day. The time must be specified in 24-hour format. If the time has already passed when the TIME command is processed, processing is suspended until the next time the specified time of day occurs. Leading zeros are required if the hour, minute or second is less that two digits. For instance two minutes after one in the morning is entered as 010200. Note- The real time clock (set by the DOS TIME command in AT and later machines using DOS 3.x or later) and the system timer (which EXC uses) are not always in synch to the second. There may be a few seconds variation. Example: ; At 1:15 PM, set off an alarm that can be shut off with LEFT SHIFT-RIGHT ; SHIFT TIME 131500 :Loop BEEP GOTO Loop 4.2.39 TIMEOUT label When the timeout limit specified by SETWAIT expires while waiting for a WAITCHG, WAITSCR, WAITFOR or LOCATE, TIMEOUT processing is invoked. Timeout processing is as follows: If no TIMEOUT command has yet been issued in the script, processing of the script is halted at this point. Otherwise, the control will pass to the command following the label specified in the last TIMEOUT command encountered. Example: SETWAIT 20 TIMEOUT TimedOut SHOWAT 17 25 WINCOLS 20 40 WINROWS 15 22 CASE ON WAITFOR "XYZ" SHOW 79 "Found XYZ in window." QUIT :TimedOut SHOW 79 "Timed out waiting for XYZ to appear in window." WINMAX CASE OFF . . . 4.2.40 TYPE "string" The string following the TYPE command contains ASCII characters to be placed in the keyboard buffer. ASCII character are those with a decimal equivalent of 0-127. Do not use high-bit characters (graphics characters, foreign language characters and most symbols) that range from 128-255 in their decimal equivalents. These characters hove no valid keycode associated with them. To enter special keys such as function keys, ENTER, ESC, etc., use the KEY command followed by the required mnemonic. You cannot enter these mnemonics with the TYPE command. The string must be enclosed in quotes. See ON for example. 4.2.41 TYPFILE filespec [mnemonic] TYPFILE allows you to type the contents of a file into the keyboard buffer. The filespec is the filename with optional path information. A possible use for this would be to feed an electronic mail message to a communications program. Each line of the file is entered as is (no deletion of leading or trailing spaces, conversion of quotes, etc.). If no mnemonic is specified, the carriage return/line feed characters at the end of each line are ignored by EXC, and nothing is entered in their place. If a mnemonic is specified, carriage return/line feed pairs are converted to the key mnemonic specified. For instance, if the file is being copied into a word processor or editor that uses the ENTER key to move to the next line, you may want to convert CR/LFs to . If you want the word processor to split the lines according to its margins, you would not specify a mnemonic or you would specify . Specifying for the mnemonic will keep the last word on a line from running into the first word on the next line when the CR/LF is removed. All other key mnemonics are described under the KEY command. Since EXC only has a 256 byte extended keyboard buffer, it feeds a maximum of 80 bytes every clock tick into the extended buffer. This should give time for the spawned program to read characters from the buffer and will usually prevent the buffer from overflowing. Please see the notes in section 3 regarding memory usage to determine the effects on memory of using TYPFILE. 4.2.42 VLOCATE "string" Same as LOCATE except that only vertical movement keys are issued to place the cursor on the same row where the search argument was located. This is especially useful in moving menu selection bars up or down to a specific choice. See LOCATE for more details and a CAUTION. Example: VLOCATE "Help" 4.2.43 WAITCHG Wait until there is any change to the screen since the last READ command was executed before executing the next script command. If there is no screen change before the SETWAIT limit expires, TIMEOUT processing will be invoked. See WAITSCR for an explanation of the difference between WAITCHG and WAITSCR. Example: READ SETWAIT 10 TIMEOUT HUNGUP KEY WAITCHG QUIT :HUNGUP KEY QUIT 4.2.44 WAITFOR [NOT] "string" No further script file command will be processed until "string" appears on the screen. The entire screen will be searched for "string". The string may be any valid screen characters. If the string does not appear before the SETWAIT limit expires, TIMEOUT processing will be invoked. If NOT is specified, processing will be halted until "string" is not on the screen. This is handy for waiting on a "Please wait.." type message to disappear. Since WAITFOR reads the screen each 1/2 second, values that flash on the screen for less than 1/2 second may not be detected. See TIMEOUT for example. WAITFOR NOT example: WAITFOR NOT "XYZ" 4.2.45 WAITSCR Read the screen, then wait until there is any subsequent change to the screen before executing the next script command. If there is no screen change before the SETWAIT limit expires, TIMEOUT processing will be invoked. Example: SETWAIT 10 TIMEOUT HUNGUP KEY WAITSCR QUIT :HUNGUP KEY QUIT In the above example, we press ENTER and wait until some response appears on the screen. Once the response appears, we terminate the script, if the response does not appear in 10 seconds, we reboot the system. The trouble is, with some fast systems, the response may already be on the screen by the time the WAITSCR reads the screen. Thus you wait for an additional change which does not happen, and the system is rebooted even though the response was generated. To prevent this, see the example in WAITCHG. In that example we read the screen before pressing ENTER, then wait to see if it is changed. 4.2.46 WINCOLS start end Sometimes you may want to restrict your screen searches to a certain area of the screen. WINCOLS allows you to specify what columns (far left = 1) you want read by all commands that read the screen (READ, SEARCH, WAITFOR, WAITCHG, WAITSCR and LOCATE). Specify the starting and ending columns inclusively. By combining WINCOLS with WINROWS, you can restrict reads to a selected box within the screen. This is referred to as the active window. Use WINMAX to return the active window to the full screen. See TIMEOUT and SHOWIN for examples. 4.2.47 WINMAX If you have restricted the active window with WINCOLS and/or WINROWS, you can return the active window to the full screen area by issuing a WINMAX command. The size of the new active window will be determined by the currently displayed columns and rows, but never exceeding the values specified in SCRMAX. See TIMEOUT for example. 4.2.48 WINROWS start end Sometimes you may want to restrict your screen searches to a certain area of the screen. WINROWS allows you to specify what rows (top = 1) you want read by all commands that read the screen (READ, SEARCH, WAITFOR, WAITCHG, WAITSCR and LOCATE). Specify the starting and ending rows inclusively. By combining WINCOLS with WINROWS, you can restrict reads to a selected box within the screen. This is referred to as the active window. Use WINMAX to return the active window to the full screen. See TIMEOUT and SHOWIN for examples. 4.3 Labels Labels can be up to 15 characters long and may contain letters, numbers, special characters or spaces. They are treated as upper case regardless of how they are coded. Duplicate labels are not allowed in the same script. END, end and End would all be considered duplicate labels. If duplicate labels exist, all branches to the duplicate labels will go to the first one in the script. Labels must be immediately preceded by a colon (:) and placed on a line which does not contain any commands. labels are used as destinations for branching commands (TIMEOUT, GOTO, ON, IFY and IFN). It doesn't hurt a thing if you want to use labels for comments, but the semicolon (;) remark is a better approach since there is no length limitation on remarks and they will not be confused with labels that are actual destinations. See TIMEOUT and ON for examples. 4.4 Remarks Anything on a line for which the first non-blank character is a semicolon (;) is treated as a comment line and is ignored by the script processor. 4.5 Using variables You may not specify variables in data included with the TYPFILE command. Any variables found in the file data will not be interpreted as variables by EXC. 4.6 Environment variable substitution You may use environment strings (initialized with the DOS SET command) in any command parameter by typing %VAR% where you want the environment string labeled VAR to be substituted. Here are some examples: Given these environment variables: SET ATTR=15 SET ME=Gary SET LAST=Crider SET FULL="Gary Crider" SET FULL2=Gary Crider SHOW %ATTR% "I am %ME%" would equate to SHOW 15 "I am Gary" TYPE "%ME% %LAST%" would equate to TYPE "Gary Crider" TYPE %FULL% would equate to TYPE "Gary Crider" TYPE "%FULL2%" would equate to TYPE "Gary Crider" DELAY %ATTR% would equate to DELAY 15 SHOW %ATTR% "%FULL%" would equate to SHOW 15 "\qGary Crider\q" TYPE "%LAST%, %ME%" would equate to TYPE "Crider, Gary" The substitution is made before EXC begins to evaluate the parameters. This could be handy on networks where the values keyed or searched might vary with the user's network ID, which could be stored in an environment variable. Many other uses also come to mind. If you want to use a set a variables that are only used in the script and are not normally maintained in the environment, set up a batch file to set the variables, execute the script, and then delete the variables after the script has executed. This frees up the environment space so that it can be reused. An example of such a batch file would be: SET X1=abc SET X2=5 SET X3=Gary Crider EXC MYSCRIPT 123 SET X1= SET X2= SET X3= If you get a message from DOS that says "Out of environment space", you can increase the size of the environment region by placing the following line in your CONFIG.SYS file and rebooting: SHELL=C:\COMMAND.COM /p /e:nnnn Replace nnnn with the number of bytes (160-32768) that you want used by the environment region. The default is 256. The number should be divisible by 16. 1024 is usually pretty good. Note that each byte you increase the region by will decrease the amount of free conventional memory used to run programs. Each variable name, the equal sign, and the variable value are stored in your environment. To see what is currently stored in your environment, type the word SET at the DOS prompt. Your full PATH= state- ment is also stored there. If you use 4DOS, NDOS or another different command interpreter, or locate it in another directory, adjust the SHELL= statement accordingly. 4.7 User Variables EXC reserves 16 variables which can be set to string values of up to 120 characters each. The variable values may contain leading, trailing or embedded spaces. The variables are numbered 1 to 16. The variables are initialized or cleared with the SET command. You can then reference any variable in any command parameter or string by enclosing the variable number in @s. For instance to substitute a variable destination label in a GOTO statement, when the destination label name is stored in variable 4, type GOTO @4@. If variable 4 contained the value "SUB1", the above notation would be equivalent to typing GOTO SUB1. You can also use the variable substitution within strings such as: TYPE "Good morning, @1@" A very beneficial side effect of allowing variables is that it now allows you to perform multiple executions of a subroutine, returning each time to a different area of the script. Here is an example from TESTEXC.SCR: SHOW 12 "TESTING 3 subroutine executions. " SET 2 1 SET 1 DO2 GOTO SUB1 :DO2 SET 2 2 SET 1 DO3 GOTO SUB1 :DO3 SET 2 3 SET 1 EXIT GOTO SUB1 :EXIT SHOW 12 "Done, exiting Microsoft Editor " DELAY 1 KEY WAITFOR "Exit" TYPE "x" WAITFOR "Save it now?" TYPE "n" QUIT :SUB1 TYPE "Subroutine execution number @2@." KEY GOTO @1@ 4.8 Example Script The following example demonstrates the use of most of the more commonly used commands. Please note that the QUIT statement after the End label is not needed since the same action takes place when there are no more commands to execute. Also please note that the SEARCH and IFN statements after the Loop label could more easily be accomplished with a WAITFOR command. This just demonstrates that looping logic is supported in scripts. SETWAIT 30 TIMEOUT End CASE OFF WAITFOR "Entries" CASE ON TYPE "FO" WAITFOR "OPEN CATALOG" TYPE "E:\NOVLIB\" KEY KEY TYPE "NOVLIB.L11" KEY WAITSCR :Loop SEARCH "NOVLIB.L11" IFN Loop TYPE "SLADDNAEA" KEY DELAY 2; WAITFOR NOT "Sorting Index" TYPE "FS" KEY DELAY 2 WAITFOR NOT "Please wait." :End BEEP KEY QUIT For a more comprehensive example, see the script file, TESTEXC.SCR. Please read the comments before and after that script. APPENDIX A Installation EXC is distributed in a self-extracting ZIP file called EXC3.EXE or a ZIP file called EXC.ZIP. It contains the following files: EXC.EXE The executable file for EXC. EXC.DOC The documentation file. HELP.TXT Script command quick reference. It is formatted as script file comments so that it can be included in you script for quick referencing.z TESTEXC.SCR Example script used to test EXC functionality. TESTEXC.TXT Text file for testing with TESTEXC.SCR. TESTEXC.FIL Another text file for testing with TESTEXC.SCR. TESTEXC.BAT Batch file for executing TESTEXC.SCR. TESTOS2.BAT Batch file for executing TESTEXC.SCR in an OS/2 DOS window. EXC.HST Text description of past updates. EXC.Vnn Text description of latest updates in version nn. PRODUCTS.DOC Description of other Parity Solutions products. For best results, extract the file into a directory on your PATH. If you don't use a directory in your path, you will have to designate the directory containing EXC.EXE when executing the program. If you have a utility directory that is on your PATH, this is an excellent location for EXC. An example installation would be: C: CD \UNTIL COPY [path]EXC3.EXE EXC3 DEL EXC3.EXE If they are not currently in your path, simply copy all of the files to a directory in your path. Keep the EXC3.EXE file anywhere you like, but give plenty of copies, as is, to your friends. If you register EXC, you are not licensed to give your serial number to anybody without first removing the serialization from your copy. APPENDIX B Keycode Table Although you do not need to know these codes to write EXC scripts, the following table does show you which combinations are defined and available by using the appropriate mnemonics. Do not try to use combinations which indicate N/A in the table, unless they are followed by an asterisk (*). Key Norm Shift Ctrl Alt ---- ---- ----- ---- --- A 1E61 1E41 1E01 1E00 B 3062 3042 3002 3000 C 2E63 2E42 2E03 2E00 D 2064 2044 2004 2000 E 1265 1245 1205 1200 F 2166 2146 2106 2100 G 2267 2247 2207 2200 H 2368 2348 2308 2300 I 1769 1749 1709 1700 J 246A 244A 240A 2400 K 256B 254B 250B 2500 L 266C 264C 260C 2600 M 326D 324D 320D 3200 N 316E 314E 310E 3100 O 186F 184F 180F 1800 P 1970 1950 1910 1900 Q 1071 1051 1011 1000 R 1372 1352 1312 1300 S 1F73 1F53 1F13 1F00 T 1474 1454 1414 1400 U 1675 1655 1615 1600 V 2F76 2F56 2F16 2F00 W 1177 1157 1117 1100 X 2D78 2D58 2D18 2D00 Y 1579 1559 1519 1500 Z 2C7A 2C5A 2C1A 2C00 1 0231 0221 N/A * 7800 2 0332 0340 0300 7900 3 0433 0423 N/A * 7A00 4 0534 0524 N/A * 7B00 5 0635 0625 N/A * 7C00 6 0736 075E 071E 7D00 7 0837 0826 N/A * 7E00 8 0938 092A N/A * 7F00 9 0A39 0A28 N/A * 8000 0 0B30 0B29 N/A * 8100 , 332C 333C N/A * 3300 . 342E 343E N/A * 3400 / 352F 353F N/A * 3500 ; 273B 273A N/A * 2700 ' 2827 2822 N/A * 2800 [ 1A5B 1A7B 1A1B 1A00 ] 1B5D 1B7D 1B1D 1B00 ` 2960 297E N/A * 2900 - 0C2D 0C5F 0C1F 8200 = 0D3D 0D2B N/A * 8300 \ 2B5C 2B7C 2B1C 2B00 F1 3B00 5400 5E00 6800 F2 3C00 5500 5F00 6900 F3 3D00 5600 6000 6A00 F4 3E00 5700 6100 6B00 F5 3F00 5800 6200 6C00 F6 4000 5900 6300 6D00 F7 4100 5A00 6400 6E00 F8 4200 5B00 6500 6F00 F9 4300 5C00 6600 7000 F10 4400 5D00 6700 7100 Enter 1C0D 1C0D* 1C0A 1C00 Ins 5200 5200* 9200 A200 Del 5300 5300* 9300 A300 Esc 011B 011B* 011B* 0100 Home 4700 4700* 7700 9700 End 4F00 4F00* 7500 9F00 PgUp 4900 4900* 8400 9900 PgDn 5100 5100* 7600 A100 0F09 0F00 9400 A500 0E08 0E08 0E7F 0E00 4B00 4B00* 7300 9B00 4D00 4D00* 7400 9D00 4800 4800* 8D00 9800 5000 5000* 9100 A000 4C00 4C35 8F00 N/A 372A 372A 7200 3700 4A2D 4A2D 8E00 4A00 4E2B 4E2B 9000 4E00 3920 3920* 3920* 3920* 8500 8700 8900 8B00 8600 8800 8A00 8C00 *These combinations, while not discreet key codes, are specially handled by EXC to operate properly in most instances. In addition, the (print screen) mnemonic can be used in EXC to cause a screen print. The cannot be placed in the keyboard buffer since it does not have a key code. KEY is executed immediately. The mnemonic causes a system warm boot. It does not work properly in a WINDOWS DOS session. WINDOWS will intercept the jump to the system BIOS and produce a "System integrity violation" message. APPENDIX C EXCR: The script recorder for EXC. EXCR.EXE is a program written to record scripts for playback with EXC. It is also available from Parity Solutions. If you would like to give it a try, order the shareware diskette on the order form at the end of this file. EXCR is also available on the same CompuServe forums where EXC is distributed. APPENDIX D EXCDEMO - A demonstration version of EXC that you can distribute to demonstrate your software. If you are a software author or distributor and wish to distribute an auto- mated demonstration of your software using EXC, you would have to also distribute EXC. Since it is only legal to distribute EXC in its shareware form, with no serialization, the EXC registration reminder would appear with your demonstration. EXCDEMO is a revision of the current version of EXC which can be freely distributed with your demo with no royalty fees. It uses a specially encrypted script file which you create and test with EXC. You then encrypt it with EXCENCR.EXE and distribute the encrypted script with EXCDEMO.EXE and your program, plus a batch file to execute your demo. There is also a small text file which must be included on your diskette giving copyright and promo- tional information about EXC and EXCDEMO. EXCDEMO executes with only a single copyright statement display at end-of-job unless an error is encountered. EXCDEMO is not distributed with EXC and must be purchased separately for $100. You then can distribute it as much as you like. See the order form to order EXCDEMO. APPENDIX E Definition of Shareware by Paul Mayer, author of GRAB Plus Shareware distribution gives users a chance to try software before buying it. If you try a shareware program and continue using it, you are expected to register. Individual programs differ on details -- some request regis- tration while others require it, some specify a maximum trial period. With registration, you get anything from the simple right to continue using the software to an updated program with printed manual. Copyright laws apply to both shareware and commercial software, and the copyright holder retains all rights, with a few specific exceptions as stated below. Shareware authors are accomplished programmers, just like commercial authors, and the programs are of comparable quality. (In both cases, there are good programs and bad ones!) The main difference is in the method of distribution. The author specifically grants the right to copy and distribute the software, either to all and sundry or to a specific group. For example, some authors require written permission before a commercial disk vendor may copy their shareware. Shareware is a distribution method, not a type of software. You should find software that suits your needs and pocketbook, whether it's commercial or shareware. The Shareware system makes fitting your needs easier, because you can try before you buy. And because the overhead is low, prices are low also. Shareware has the ultimate money-back guarantee -- if you don't use the product, you don't pay for it. EXC.EXE is a shareware program and is provided at no charge to the user for a 30-day period of evaluation. Feel free to share it with your friends, but please do not give it away altered or as part of another system. The essence of "user-supported" software is to provide personal computer users with quality software without high prices, and yet to provide incentive for programmers to continue to develop new products. APPENDIX F Disclaimer BECAUSE OF THE DIVERSE NATURE OF COMPUTER EQUIPMENT AND EXPERTISE OF USERS, PARITY SOLUTIONS AND GARY C. CRIDER MAKE NO WARRANTY ON THE EXC PROGRAM WHATSOEVER, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY AND OF FITNESS FOR ANY PURPOSE. THE USER ASSUMES ALL RISK OF DAMAGE TO DATA OR EQUIPMENT RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OR MISUSE OF THIS PROGRAM PRODUCT. USERS ARE ADVISED TO TEST PROGRAMS AND SCRIPTS THOROUGHLY ON DATA FOR WHICH A BACKUP EXISTS. ANY LIABILITY OF THE AUTHOR OR PARITY SOLUTIONS IS LIMITED TO REPLACEMENT OR REFUND OF THE REGISTRATION FEE. APPENDIX G Support I have tried to test the program to the fullest, but I am limited as to systems and configurations with which to test. I have been programming for 19 years and the one thing I know for sure is that bug free programs are very few and far between. I can only promise to support the program to the best of my ability and provide fixes as expeditiously as possible. Anyone can report problems and suggest changes. Registered users get top priority in resolving their problems. There are three ways you can report problems. The preferred method is to contact me through CIS mail (not forum messages). My CIS ID is 71760,3413. This is the method that is most likely to be most successful if you are in a hurry as I usually check my mail more than once per day. You can also write me at: Gary C. Crider Parity Solutions 1903 Pavia Ct. Arlington, TX 76006 The last method is to phone (817) 261-9552. Since I am the sole technical support and the line is also used for my network consulting business, it is often hard to get through to me. Please call and leave a message between 7:30 am and 6:30 pm Central time, or you may actually talk to me after 6:30 pm. Please don't call after 10:00 pm Central time. No matter which method you use, please give a brief description of your problem, your registration serial number if you are registered, and your phone number. If I need more information, I will contact you as soon as I can. When I have a solution, I will contact you however you prefer. Never post your serial number on forum messages. CIS mail is OK. I seldom read forum messages and, in most cases, they are not private. At this time there is no charge for support or upgrades and no time limit for these. Parity Solutions does reserve the right, however, to imposes time limitations for free support and upgrades in the future, if it becomes necessary. The time limit on free support will never be less than six months. Registered users who are dissatisfied with EXC may request a refund if your problem cannot be resolved and is within the scope of the purpose for which EXC was designed. You may request the refund up to 60 days after registration. If Parity Solutions chooses not to address problems specific to a particular hardware or software environment, you are entitled to a refund of the registration amount. Refunds do not include any applicable shipping charges or charges for diskettes, unless the diskette is defective. I work full time, have a consulting business to run in my spare time and write programs instead of sleeping. So please be a little patient with me. Program updates are available on CompuServe or can be requested from us for a $5 shipping and handling charge. Add $1 for international shipping outside the North American continent. A distribution disk of all Parity Solutions products will be sent to you. Specify disk size and format. You may use the order form at the end of this document. APPENDIX H Registration EXC's full capabilities are available for you to evaluate before you invest your hard-earned money. The only difference in operation of a registered vs. a non-registered program is that the registration prompt will no longer appear once the program is serialized. You are also entitled to support, both while you are evaluating and after you register the program. See the previous section on support policies. You are licensed to use this program freely for thirty (30) days. At the end of 30 days you are expected to either register the program or quit using it. It is a violation of your trial period license to use EXC longer than 30 days without registering it. Registered users will receive a unique serial number and instructions on how to serialize the program. Serialization can be re-applied to updated versions and in no way hinders your use of the program. You can compress or decompress the program with no effect (LZEXE or PKLITE). I use Fabrice Bellard's LZEXE program on EXC.EXE before distribution. As a registered user, you will be able to upgrade without re-registration or additional fees. You will also be kept on my PRIVATE mailing list to receive additional information on this and other Parity Solutions products. To register your copy, please use the order form below and send $24 US ($95 per file server on LANs) check or money order (sorry, no credit cards yet) to: Gary C. Crider Parity Solutions 1903 Pavia Ct. Arlington, TX 76006 Or, you can register individual (non-network) licenses online quickly and easily in Compuserve. Simply GO SWREG and register ID #753. Your regis- tration fee will be added to your Compuserve bill. International exchange was never easier and you save the $1 international postage charge. Texas residents and companies should register by mail and include 7.75 percent sales tax on the total amount of the order. You can still register by CompuServe, but I then have to pay the taxes. If you send your CIS id or register via CIS:SWREG, your registration will be sent to you via CIS mail, along with instructions on how to serialize your copy of EXCR. This usually involves one or two days turnaround. If you register online and do not receive a serial number within 3 days, please contact me via CIS mail. Program diskettes are not normally shipped. Normal distribution of EXC and upgrades is via CompuServe. If you need a diskette, please see the instructions under Support above, or use the order form below. You will receive a serial number and instructions for serializing your copy of the program. Single use license: Each license gives you or your company a single use permit for EXC. It is not restricted to a single machine as long as no two users can be simul- taneously using the program. As Borland says, "treat it like a book." As an example, if you register EXC for your home computer, but during the day you use a portable or a computer at work, you may keep EXC on both machines as long as no one is at home using it while you are using it at work, and vice versa. LAN license: LAN licenses grant rights to all workstations on the same physical LAN. If internetworking, a license must exist for each file server that contains a copy of EXC.EXE or for each physical local area network that will be given rights to access EXC.EXE. If two or more file servers exist on a single LAN strictly for mirroring data and fault-tolerance, these will be counted as a single file server for licensing purposes. If in doubt, contact me. We can work out an agreement. Site license: Site and enterprise licensing is also available on a negotiated price basis. I guarantee it will be an economical alternative to buying licenses for each user. You may freely distribute the original shareware EXC3.EXE file or distribution diskette intact in any way you see fit other than selling it. Users' groups and shareware distribution services may charge a reasonable fee for the medium and duplication costs. Bulletin boards may not charge additional fees for downloading this specific program, other than normal connect-time and/or membership charges. As long as it meets the above criteria, any BBS may post EXC for down- loading, but should try to keep it up to date. The latest version is on CompuServe, or can be obtained from Parity Solutions. Parity Solutions will not normally upload upgrades to bulletin boards other than CompuServe. You are NOT licensed to give anyone your serial number unless you first remove all serialization from your computer. You may then no longer use that serial number. Only Parity Solutions has the authority to issue serial numbers. If you give or sell your licensed EXC to anyone else, please have them send their name, address and serial number to us so that we may update our customer database. Modification of EXC.EXE in any manner other than lossless compression, is prohibited and unlawful. ============================================================================= ORDER FORM FOR EXC Send checks payable to: Parity Solutions 1903 Pavia Court Arlington, TX 76006 BILLING ADDRESS: SHIP TO (If different): NAME: _____________________________ NAME: ___________________________ COMPANY: _____________________________ COMPANY: _____________________________ STREET: _____________________________ STREET: _____________________________ _____________________________ _____________________________ CITY/ST: _____________________________ CITY/ST: _____________________________ ZIP/POSTAL CODE: _____________________ ZIP/POSTAL CODE: _____________________ COUNTRY: _____________________________ COUNTRY: _____________________________ PHONE: _____________________________ PHONE: _____________________________ CompuServe/Internet ID: ________________________________________(Optional) NOTE: Parity Solutions sends a serial number for each registration and instructions for serializing your program. A diskette containing the latest releases of all Parity Solutions shareware products is available for $5.00 U.S. The current release of EXC is available for downloading on CompuServe in the IBMSYS forum. QTY DESCRIPTION PRICE EA. TOTAL PRICE ___ EXC license and registration $24.00 ___________ ___ EXC Network license and registration 95.00 ___________ ___ Parity Solutions shareware diskette 5.00 ___________ ___ EXCDEMO demonstration software 100.00 ___________ Postage for international orders outside 1.00 ___________ the U.S., Canada and Mexico. Subtotal: ___________ You may deduct 10% from the sub- Sales tax (Texas total if more than one license is only. - 7.75%) ___________ ordered. Total Enclosed: ___________ Diskette size (if ordered): __ 5.25" 1.2M __ 3.5" 1.44M Thank you for doing business with Parity Solutions. (817) 261-9552 Parity Solutions is a partnership of Gary C. Crider and Russell L. McCloud. Federal tax identification number 75-2468376. ==============================================================================