;;07-10-85 GSUB.DOC v2.0 (09/20/86) Eric Gans French Dep't UCLA Los Angeles, CA 90024 Version 2.0 Allows default parameters in SUB file, "quiet" mode (suppress messages/filenames). GOTOG now accepts filenames (GOTOG WS) as well as command numbers. Fixed IFG bug that disallowed messages after IFG or ELSEG. Thanks to James Quillin and Ernest Helliwell for their suggestions. The (formerly separate) IFG.DOC is now included in this file. Version 1.5 (4/86) Allows lower case internal input in direct mode with "%". Thanks to L. Patrick Purtell for pointing out that v1.4 wouldn't implement PerfectCalc's ^Xm.. command (^XM won't do it). ***** GSUB is a SUBMIT substitute that puts its command buffer in memory instead of in a $$$.SUB disk file. It allows: - internal program input separate from CCP input - IF-ELSE-GOTO structures including counted loops - chaining of batch files (v1.1+) - run from command line or SUB file - unlimited command space (v1.2) - output messages to console from SUB file (v1.4) - variables ($1 - $9) permitting null values and defaults (2.0) - control characters, lower case (1.5) - wait for console input - comments - "quiet" mode (2.0) - reentrant: can chain with itself GSUB is smaller & faster than EX (or any other CP/M batch program). It only does a long CCP return (for chaining with SUBMIT or to reset drives) on request. Its command buffer has no size limit; only what is filled is placed in memory. Like SUBMIT, GSUB can be aborted by typing a character before it regains control. Why not EX? EX can't distinguish between console input within a program and input to the CCP. Thus it can't run a SUB file that contains a series of programs one of which allows console input; it just reads the rest of the SUB file into the program. For example, I use a little file Z.SUB for writing assembly language programs: ws $1.azm z80mr $1.bbz mload $1 EX can't handle this; as soon as it gets into Wordstar it writes the other two lines into my source file instead of waiting to get back to the console. GSUB solves this problem while allowing full control of the batch process with IF-ELSE-GOTO and counted loop structures. But... Although GSUB can handle any "reasonable" internal program input, it can't pass commands to a few programs (like VDE) that use the BIOS CONSTAT function to check for a keypress before allowing input. To disable this function would be asking for trouble. (Thanks to Rick Charnes for revealing this problem.) Command syntax: (1) Command line: to run GSUB in direct mode (without a SUB file) you enter the command line as follows (CP/M will process a maximum of 127 characters): gsub =[?;]cmd1[;{file-internal commands}][cmd2;[~]..[;&] CCP commands (except the last in line) must be followed by ";". These follow standard syntax. ? entered as a separate command (not necessarily first) will put GSUB in quiet mode. CCP commands (e.g., COM filenames, DIR...) will not be displayed. In SUBfile mode, messages <...> will also be suppressed. File-internal commands must be within "{...}". The closing "}" need not be followed by a ";", although it makes things clearer, $ will take as a literal (i.e., to use "{" in the command line, write "${") ~ entered at the beginning of a command will produce an input request; this is better done in SUBfile mode where you can enter a prompt message. ^ will produce a control character "&" entered as a separate command at the end of the line will produce a "long" CCP return that allows chaining with SUBMIT. Use this switch if you want to use GSUB to run a program like SUBMIT that creates $$$.SUB disk files, or if your operations require a disk reset after Warm Boots (the default avoids this). Internal Commands (within {...}) | = carriage return (0Dh = ^m) ~ waits for a character input % ( must be a letter) used in direct mode will produce a lower-case letter. Since the CCP folds all lc letters to uc, this is the only way of getting lower-case letters that certain program commands (e.g., PerfectCalc ^Xm...) require. This command is not required in file mode, since you can simply enter the lower-case letter in the file, nor is it necessary for CCP commands which will be "folded" anyway. Examples: gsub =ws;{nblurk.azm^m}era *.bak will enter WS & open the non-document file blurk.azm, then on exit erase the BAK file(s) gsub =ddt;{dd200|lea00~s100|42|4c|55|52|4b|.|^c}save 1 blurk will enter ddt, dump d200-, write out the command "lea00" and wait for you to type a key (e.g., a CR), then display the byte at 100H and enter five characters and a "." to end, exit with ^C and save the result. Note that except for the wait for input, the second example might have been accomplished (several times slower) with SUBMIT and XSUB, but not the first, since "n" in Wordstar does not use CPM function #10 and is thus inaccessible to XSUB. EX could handle the "n" OK, but would then proceed to write "era *.bak" into the first line of BLURK.AZM. (2) File input: Variables: as in normal SUB files, variables should be numbered consecutively from $1 to $9. You may enter "@" alone in the command line to signify a null variable, or "@@" to use the default value. Default values: (v2.0) You may enter a default value in the subfile using the format $n^default^. Thus $3^ws urk^ will set WS URK as the default command if no third variable is given. NB that you still have the choice of entering a null value (using @ instead of @@ on the command line). "&" entered separately at the end of the command line will switch on the long CCP return as above. ? entered separately on the command line will produce quiet mode; CCP commands and messages (<...>) will be suppressed. As with SUBMIT, each CCP command must be followed by a CRLF. Internal commands may include CRLF's also; usually a CR alone (|) suffices. The internal command line, if any, must end with a CRLF after the closing "}". Messages to be displayed to the console during operation (either in CCP or file-internal mode) are placed between "<...>". GSUB will check for closed brackets of both {} and <>; you are advised not to try structures like "{ ... < ... } ... >" (GSUB would interpret the "}" as display text). NB - Within the display brackets, the character "|" is inter- preted as a CRLF. To kill the CRLF at the end of a line (e.g., if the line you want to display contains control characters that won't actually print but will set video controls), enter "\" just before the CR. The message will not end with a CRLF unless it is within the brackets: zap will run ZAP.COM OK, but will display as "Hi there!ZAP" on screen. Comment lines beginning with ";" will not be copied to the command buffer. You may also add comments after the end of the internal command line. $ will produce a literal of for anything but the variables $1-$9. Otherwise, the $, ^, | and ~ symbols function as above. Examples: (1) ws {nblurk.azm|} era *.bak (2) ddt { .... } (as above) save 1 blurk Another way of entering a CR into the internal input is to go to the next line; the program kills the LF's that are usually misinterpreted by word-processors & other programs (Wordstar thinks you want to set the help level with ^J): (3) ;for the literary ws charlott.let {Liebchen, I can't live without you. Death is my only recourse. ;don't believe a word - The Editor - Werther ^kx} ;pretty hot stuff? To output control characters etc. to the screen in immediate mode, enter them as external commands (NOT within {...}): gsub =^g^z^[B0^[=00BLURK!^[C0^m will sound the bell (^g), then (on an ADM 3A) blank the screen, set inverse video, go sixteen lines down and sixteen across, print BLURK!, then turn off inverse video and do a CR. (You can't use | here.) SELF-CHAINING GSUB can chain with itself an indefinite number of times. This feature can be useful with SUB files; if you want to run a SUB file along with some other programs you can enter: gsub =gsub zlurk;zap;blurk;gsub zlonk... etc. Even gsub =gsub gsub zlurk;... is possible, although the second gsub can't do much since the first semicolon will return control to gsub No. 1. CHAINING WITH SUBMIT If "&" is entered at the end of the command line in either file or immediate mode, GSUB returns control after Warm Boots to the start of the CCP and thus allows the accessing of $$$.SUB files from within the program. This allows you to include calls to SUBMIT (or other disk-based batch utilities like my program OFFRUN) within a GSUB command line or SUB file. Thus you can enter: gsub =submit blurk urk1 urk2;submit zlonk urk3 ur4 urk5;& (NB the "@"=null feature won't work here) and both blurk.sub and zlonk.sub will be submitted. Or you can put this series in YECCH.SUB and enter: gsub yecch urk1 urk2 @ urk4.. & In this case, remember not to use SUBMIT with YECCH.SUB! Technical notes: GSUB distinguishes between CCP and internal program input by trapping BDOS calls to CP/M function 10. The location of the "late" CCP return is determined from the stack. GSUB also checks for changes in the BDOS jump address (at 0006) made by programs that want to keep themselves resident in memory, and locates itself just under the resident program. CP/M function 6 (direct console I/O) is handled by trapping calls to the BDOS. When internal program input is finished, GSUB puts back the BIOS CONIN address not only in the BIOS jump table but in its own console input routine in order to work with programs (like MBasic) that skip past the jump table. GSUB 2.0 should be usable on any CPM system under any circumstances. Additional notes: GSUB will work with "anything" only so long as the "true" address of the BDOS is not required. So don't try it with programs like SYSGEN or MOVCPM. If you use a SMARTKEY like program within GSUB, it will disappear when GSUB does; if you want it to stay in memory, load it first, or use SUBMIT, OFFRUN, CMDLN etc. ***** IFG/ELSEG/GOTOG GOTOG now accepts command names as well as numbers. This version of IFG/ELSEG/GOTOG/ENDIFG also fixes a bug that mishandled GSUB screen messages (enclosed in <>). It should now be possible to use messages after IFG or ELSEG without difficulty. Since IFG outputs its own message, to put your message on a new line, precede it with a CR, thus: <|message after IFG|>. The new IFG series is compatible with GSUB 1.4-1.5, but not with earlier versions of GSUB. IFG, ELSEG, ENDIFG and GOTOG are faster and more versatile than the corresponding IF, ELSE... series written for SUBMIT. (To be fair, a good deal of IFG was taken from IF.ASM.) Out of deference to the latter, and to avoid confusion for those who use both, I have added a "G" to all the commands. IFG offers the same command structure as IF, plus a couple of enhancements. As with IF, only the first letter of the commands count (as long as there are no spaces). The options are: IFG N[ull] = if command line is null (e.g., a null variable in a SUB file) IFG E[xists] filespec IFG A[mbig] filespec = if the filespec contains wildcards IFG M[issing] filespec = if the filespec cannot be found IFG Z[ero] filespec = if filespec either zero-length or missing Additions: IFG D[rive] dr = if current drive is dr IFG U[user] userno = if current user is userno Whether these conditions are true or false, IFG will print the information on the screen (another improvement). The command structure is predictable: if the condition is true, what follows the IFG will be executed; if it is false, an ELSEG will be sought else commands will be executed following the ENDIFG. (Leave this out and you get an error message.) Since GSUB operates in memory rather than on disk, IFG et al perform far faster than the IF series. Like the IF series, IFG allows nesting to any depth. ELSEG merely skips to the next ENDIFG since, like ELSE, it is only executed when the original condition was true. ENDIFG is, like ENDIF, a one-byte file consisting of a "ret". GOTOG Format: gotog command-number|command [#c] V2.0 allows entry of a command name afte GOTOG. This name cannot contain blanks; control will pass to the first occurrence of the name in the SUBfile/command line. Thus GOTOG WS will GOTO the first appearance of WS. If the command was WS BLURK, it will be executed correctly, but you can't write GOTO WS BLURK to make GOTOG avoid (say) an earlier command of WS ZAP. In such cases, you must use the command-number option. Unlike GOTO, GOTOG can jump backward as well as forward and includes a count option, permitting the creation of loops. Each command is numbered according to its position in the series of commands (in the SUB file or in immediate mode). Only CCP commands are counted, not internal file commands in GSUB. You may include the numbers as comments in the SUB file, but this is not necessary. GOTOG xx performs an unconditional goto. To create a loop, use the count option GOTOG xx #c where "c" is the desired number of executions. The command number "n" must be between 1 and 255; "c" is a single (hex) digit from 1 to F (=15). (If you don't like hex numbers, just use the digits 1 through 9.) Examples: ifg e blurk.com ;tests existence of file zlonk {^nr354|} ;commands between {} don't count for GOTOG ;message to be displayed dir gotog 7 ;goes to 7th command in list (era *.bak) elseg ;if blurk.com doesn't exist, then rename rn zlonk.com=blurk.com era *.bak endifg ----------------------------------------------------------------- ifg u 10 ;if user 10, edit zap.txt ws zap.txt elseg u 10 ;else change user* gotog 2 ;& go back to edit (the "else" clause will be endifg ;skipped, as always) *unlike SUBMIT, GSUB won't get lost when you change user numbers, but IFG &c must be accessible on disk ----------------------------------------------------------------- blurk zap zlonk gotog zap #a ;will go back to zap and execute the loop 10 times NB that GSUB converts all lower-case to upper case (except within the brackets {...} or <...>) when it creates its buffer in high memory. *** ALERT.COM (v1.0) is for use in SUB files when something goes wrong and your attention is required. It will sound the bell twice a second for about a minute (on 4MHz Z80 systems; ALERT is actually written in 8080 code) and then continue to wait for a keystroke.