home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-02 | 49.8 KB | 1,037 lines |
- This text is a version of my column in TCJ issue 33 which has been edited toì
- reflect the changes in ARUNZ from version 0.9J to 0.9N. Not all newì
- features are reflected, but the example alias scripts should now work.
- JPS 11/13/88
-
-
-
- The ZCPR Corner
-
- TCJ Issue 33
-
-
- For my column this time I plan to cover two subjects, both of which Iì
- have dealt with somewhat at length in the past. Nevertheless, there justì
- seems to be a lot more to say on these subjects. The first is ARUNZ; theì
- second is shells in general, and the way WordStar 4 behaves (or ratherì
- misbehaves) in particular.
-
- I was quite surprised and pleased by the enthusiastic response to myì
- detailed treatment of ARUNZ in issue 31. Apparently, there were many, manyì
- people who were unaware of what ARUNZ was and who are now quite eager to putì
- it to use. There are two specific reasons for taking up the subject ofì
- ARUNZ here again so soon.
-
- First of all, I think that readers will benefit from a discussion ofì
- some additional concrete examples. Since my own uses are the ones I knowì
- best, I plan to take the ALIAS.CMD file from my own system as an example andì
- discuss a number of interesting scripts. My first cut at doing that forì
- this column came out much too long, so I will cover half of the file thisì
- time. The other half will be covered in the next column.
-
- The second reason is that I have just gone through a major upgrade toì
- ARUNZ. It is now at version 0.9J. Several aspects of its operation asì
- described in my previous column have been changed, and quite a few newì
- parameters have been added.
-
- The changes in ARUNZ were stimulated by two factors. One is the twoì
- new dynamic Z Systems that will have been released by the time you readì
- this: NZCOM for Z80 computers running CP/M 2.2 and Z3PLUS for Z80 computersì
- running CP/M-Plus. These two products represent a tremendous advance in theì
- concept of an operating system, and everyone interested in experimentingì
- with or using Z System -- even if he already has a manually installed ZCPR3ì
- running now -- should get the one that is appropriate to his computer.
-
- With these new Z System implementations, if your level of computerì
- skill is high enough to run a wordprocessor or menu program, then you canì
- have a Z System designed to your specifications in a matter of minutes. Youì
- can change the design of your Z System at any time, even betweenì
- applications. As described later, ARUNZ now has some parameters to returnì
- addresses of system components so that aliases can work properly even whenì
- those system components move around, as they may do under these dynamicì
- systems.
-
-
- My New Computer System
-
- The second impetus came from my finally building for myself a state-of¡
- the-art computer! For most of my work in the past I have used a BigBoard Iì
- with four 8" floppy disk drives and an SB180 with four 5" disk drives. ì
- Neither machine had a hard disk.
-
- The SB180, my main system for the past year and a half, had beenì
- sitting on the floor in the study. The pc board was mounted in a makeshiftì
- chassis with two power supplies, just as I got it from someone who bought itì
- at the Software Arts liquidation auction and after they had stripped out theì
- disk drives (at $25 I could hardly complain!). I added my own drives, whichì
- sat in the open air (for cooling among other reasons) in two separate driveì
- cabinets elsewhere on the floor. All in all not very pretty and not asì
- functional as it could have been.
-
- The sad part of it is that during all this time I had everything neededì
- to turn the SB180 into an enjoyable and productive system. A high-speed 35ì
- Mb hard disk was collecting dust on a shelf; an attractive surplus Televideoì
- PC-clone chassis adorned the work bench in the basement; the XBIOS softwareì
- disks sat ignored in one of my many diskette boxes.
-
- Finally one weekend I decided that it would be more efficient in theì
- long run to take some time off from my programming and writing work toì
- reconstruct the system. Indeed, it has been! The SB180 is now attractivelyì
- mounted in the Televideo chassis with one 96-tpi floppy and one 48-tpiì
- floppy. The hard disk is configured as four 8 Mb partitions and runs veryì
- nicely with the fast Adaptec 4000 controller.
-
- With the hardware upgraded, I then did the same to the software. ì
- Installing XBIOS on the SB180 took so little time that I really had to kickì
- myself for not doing it sooner. Richard Jacobson was quite right in hisì
- description of it in issue 31. Thank you, Malcom Kemp, for a really niceì
- product.
-
- Once I was fixing things up, I decided I should really do it up right,ì
- so I also purchased the ETS180IO+ board from Ken Taschner of Electronicì
- Technical Services -- this despite the fact that a Micromint COMM180 boardì
- was also a part of my longstanding inventory of unused equipment. I cannotì
- compare the ETS board to the COMM180, never having used the latter, but Iì
- certainly am highly pleased with it. XBIOS includes complete support forì
- the ETS board, so configuring the system to make use of the extra ETS180IO+ì
- features, like the additional parallel and serial ports and the battery¡
- backed clock, was very easy.
-
- I have been so pleased with the new system that I even went out andì
- bought a real computer table for it to sit on. For the past years, theì
- terminal's CRT unit had been sitting on one of those flimsy folding dining¡
- room utility tables, with a yellow-pages phone book under it to jack it upì
- to the right height. The keyboard sat on a second folding table, and theì
- whole thing was always in imminent danger of toppling over. What a pleasureì
- it is to sit at the new system.
-
- While I'm waxing enthusiastic, let me mention one other thing I did toì
- reduce the disarray in the study. I bought four Wilson-Jones media drawersì
- to house my vast collection of floppies. These diskette cabinets resembleì
- professional letter filing cabinets. A drawer, which can hold more than 100ì
- floppies, pulls out on a full suspension track so that one can easily reachì
- all the way to the back. Since there is no top to flip open, units can beì
- stacked on top of each other to save a great deal of table space. Clips areì
- provided to secure the units to their neighbors both horizontally andì
- vertically.
-
- The only drawback to these disk drawers has been their cost. Inmac andì
- the other major commercial supply houses want more than $60 each! Butì
- Lyben, which sends its catalogs out to many computer hobbyists, offers themì
- for only $35. Extra dividers, which I recommend, are just under $6 perì
- package of five. Lyben can be reached at 313-589-3440 (Michigan). [Noteì
- added at last moment -- I am sorry to say that I just received the new Lybenì
- catalog, and the price has now gone up to $45. Although this is still aì
- bargain when compared to other vendors' prices, I'm glad I put in my orderì
- when I did.]
-
-
- ARUNZ VERSION 0.9J
- (edited for version 0.9n)
-
- Now that I have had my chance to show my excitement over the new stateì
- of my computer and computer room, let's get on with the discussion of ARUNZ. ì
- First we will discuss the changes introduced since version 0.9G, both theì
- old features that have changed and the new features that have beenì
- introduced.
-
-
- Changes in Old Features
- -----------------------
-
- Because, as noted in my last column, ZCPR34 can pass commandsì
- containing explicit file types or wildcard characters ('?' and '*'), theì
- characters used to define special matching conditions in the alias names inì
- ALIAS.CMD had to be changed. The period, which had been used to indicateì
- the beginning of optional characters in the alias name, has been replaced byì
- the comma. The question mark had been used to indicate a wild-characterì
- match in the alias name. Since it can now be an actual character to beì
- matched, the underscore has replaced it.
-
- Since the command verb can now include an explicit file type (notì
- necessarily COM) and/or a directory prefix, several changes have been madeì
- to the parameters that parse the command verb. In general, all of theì
- command line tokens are now treated in the same way; all four token parsingì
- parameters ('D', 'U', ':', and '.') now work with digits from 0 to 9 and notì
- just 1 to 9. Thus the command line
-
- C3:TEST>arunz b12:test.z80 commandtail
-
- or, with ARUNZ running as the extended command processor (ECP), the command
-
- C3:TEST>b12:test.z80 commandtail
-
- will have the following parameter values for token 0, the command verb:
-
- $TD0 B (Token 0 Drive)
- $TU0 12 (Token 0 User)
- $TN0 TEST (Token 0 fileName)
- $TT0 Z80 (Token 0 fileType)
-
- THIS IS A SIGNIFICANT CHANGE. PLEASE TAKE CAREFUL NOTE OF IT. Theì
- parameters $TD0 and $TU0 no longer necessarily return the logged-in driveì
- and user. For the standard configuration of ZCPR33 (and 34) a verb of theì
- form B12:TEST cannot be passed to the extended command processor; theì
- presence of an explicit directory specification results in the immediateì
- invocation of the error handler (skipping the ECP) if the file cannot beì
- found in the specified directory. However, if a file type is included, theì
- 'bad' command will be passed to the ECP.
-
-
- New Features
-
- There are now three new parameters that do return information about theì
- directory that was current (logged in) when ARUNZ was invoked. Theseì
- parameters are shown below with their meaning and the values they would haveì
- with the example command above:
-
- parameter meaning value
- --------- ------- -----
- $HD Home Drive (D) C
- $HU Home User (U) 3
- $HB Home Both (i.e., DU) C3
-
- There is also a new parameter to denote the entire command line,ì
- including both the command verb and the command tail. Many people in theì
- past confused "command line" with "command tail" and attempted to use theì
- parameter $* for the former. The new parameter is '$!'. It is roughlyì
- equivalent to '$0 $*', but there is one important difference. The latterì
- parameter expression always includes a space after the command verb, even ifì
- there was no tail ('$*' was null). This space caused problems with someì
- commands. For example, when the SLR assembler SLR180 is invoked withì
- nothing after it, it enters interactive mode and allows the user to enter aì
- series of assembly requests. Unfortunately, the code is not smart enough toì
- distinguish a completely nonexistent command tail from one with only spaces. ì
- When the command "SLR180_" is entered, where '_' represents a blank space,ì
- the assembler looks for a source file with a null name. Not finding it, itì
- returns with an error message.
-
- I used to deal with this problem by writing a complex alias of theì
- form:
-
- SLR180 if nu $*;asm:slr180;else;asm:slr180 $*;fi
-
- With the new parameter, all this complication can be avoided. The script isì
- simply:
-
- SLR180 asm:$!
-
- If you are wondering why one would want an alias like this, just wait aì
- while. It will be explained later.
-
- There is also a whole set of new parameters that generate the addressesì
- of almost all of the Z System modules. This capability will becomeì
- important with the dynamic Z Systems now being introduced (NZCOM andì
- Z3PLUS). With those systems, the addresses of the RCP, FCP, CCP, and so onì
- can all change during system operation. The new parameters permit one toì
- make reference to the addresses of those modules even when they move around. ì
- My ALIAS.CMD file described below will have some examples of how theseì
- parameters are used.
-
- These parameters begin with $A ('A' for address) and are followed by anì
- additional letter as follows:
-
- B BIOS L MCL (command Line)
- C CCP M MSG (message buffer)
- D DOS N NDR
- E ENV P PATH
- F FCP R RCP
- I IOP S STK (shell stack)
- X XFCB (external FCB)
-
- Amazingly enough, these names are all mnemonic except for the conflict overì
- 'M' between the multiple command line buffer (MCL) and message buffer (MSG). ì
- I resolved this by using 'L' (think of LINE) for the MCL.
-
- Finally, there is a new symbol that can be used to make a special kindì
- of alias name specification in ALIAS.CMD. If a name element begins with aì
- '>', then only the file type of the command verb is used in the comparison. ì
- Without this feature one had to use very complex forms to recognize a fileì
- type. For example, suppose you want to be able to enter the name of aì
- library file as LBRNAME.LBR as a command and have VLU invoked on it. Theì
- following script used to be required:
-
- ?.LBR=??.LBR=???.LBR=????.LBR=?????.LBR=??????.LBR=
- ???????.LBR=????????.LBR vlu $0
-
- Every possible number of characters in the library name had to be dealt withì
- explicitly. With the new symbol and the other ARUNZ09J features, one canì
- define this script more simply as follows:
-
- >LBR vlu $TN0
-
-
- Example ALIAS.CMD File
-
- Now that we have described the new resources available in ARUNZ09J, weì
- will begin our look at part of the ALIAS.CMD file that I am using right nowì
- on the SB180. It will be the second half of the file, because that partì
- contains some items of immediate relevance.
-
- First some words of philosophy. There are many ways in which Z Systemì
- can be used effectively, and I am always amazed and impressed at theì
- different styles developed by different users. What I will now describe isì
- my approach. As they say, yours may differ! In any case, I hope theseì
- comments will stimulate some good ideas, and, as always, I eagerly awaitì
- your comments and suggestions.
-
- I am a strong believer in short search paths. When I make a mistake inì
- typing a command, I do not want to have to twiddle my thumbs while theì
- command processor thrashes through a lot of directories searching for theì
- nonexistent command. I want the error handler to take care of it as quicklyì
- as possible. As a result, the search path on my SB180 includes only oneì
- directory, A0, the RAM disk. (With XBIOS, the RAM disk can be mapped to theì
- A drive.)
-
- When I enter a command, it is searched for only in A0. If it is notì
- found there, then ARUNZ (renamed to CMDRUN.COM) is loaded from A0, and itì
- looks for a script in ALIAS.CMD, also in A0. If ARUNZ cannot resolve theì
- command, then the error handler, EASE in my case, is invoked (you guessedì
- it, also on A0). Thus no directory other than the RAM disk is accessedì
- except by an explicit directory reference generated either by an aliasì
- script or by a manually entered command. Everything appears to operateì
- instantaneously.
-
-
- Aliases to Provide Explicit Directory Prefixes
-
- Obviously, I cannot keep all the COM files that I use in directory A0. ì
- In fact, with the tiny RAM disk on the SB180 (and allowing about 100K for aì
- BGii swap file), there is barely enough room for CMDRUN.COM (ARUNZ),ì
- ALIAS.CMD, EASE.COM, EASE.VAR, IF.COM, ZF.COM (ZFILER), ZFILER.CMD,ì
- SAVSTAMP.COM, ZEX.COM, ZEX.RSX, and a few directory programs. Fortunately,ì
- this is all that really needs to be there.
-
- So what do I do about all the other COM files that I want to use? ì
- There are two possibilities. I could invoke them manually with explicitì
- directory references, as in "B0:CRC FILESPEC", but this would clearly be aì
- nuisance (and contrary to the spirit of Z System!). The other alternativeì
- is to provide alias definitions in ALIAS.CMD for all the commands in otherì
- directories that I want to use.
-
- A second half of my ALIAS.CMD file is shown in Listing 1. The group ofì
- aliases at the very end comprises several sets of definitions that do justì
- what I have described for several of the directories on the hard disk. As Iì
- use programs in other directories, I add them to the ALIAS.CMD file.
-
- These aliases are included at the end, by the way, so that otherì
- definitions can preempt them as desired. If you look carefully, you willì
- see some aliases defined here that are also defined earlier in the ALIAS.CMDì
- file. The earliest definition always takes precedence, because ARUNZ scansì
- ALIAS.CMD from the beginning and stops as soon as it encounters a matchingì
- name specification.
-
- Directory B0, named SYS, contains most of my system utilities. ì
- Directory B1, named ASM, contains my assembly language utilities. A fewì
- commonly used files are in other directories. The aliases defined in theseì
- sections do nothing more than add an explicit directory prefix to theì
- command entered. For example, the script definition
-
- AFIND b0:$!
-
- would take my command line "AFIND TAIL..." and turn it into "B0:AFINDì
- TAIL...". Note how compact the definitions can be. You do not need aì
- separate line for each command. Similar scripts could be constructed, byì
- the way, for COM files kept in COMMAND.LBR and extracted and executed by LX. ì
- I do not use LX, so I have no examples to show.
-
- There are several fairly easy ways to automate the construction ofì
- these entries in the ALIAS.CMD file. If you use PMATE or VEDIT as your textì
- editor, you can write macros that will perform the entire process. That isì
- how I generated the aliases you see. With the PMATE macro, I can easilyì
- repeat the process from time to time to make sure that all my COM files areì
- represented by aliases. So far I have run my PMATE macro on user areas 0,ì
- 1, 2, 3, and 4 of hard disk partition B.
-
- Lacking these tools, you can run "SD *.COM /FX" to get a file DISK.DIRì
- containing a horizontally sorted listing of all the COM files in a directoryì
- (without going to a lot of trouble, I do not get a sorted listing fromì
- PMATE). Then use your favorite editor, whatever it is, to add carriageì
- returns so that each file is on its own line and to delete all of the textì
- after the file name (i.e., the dot, file type, and file size). If there areì
- any commands for which you want to have special aliases (we'll see someì
- examples shortly), you may delete their names from the list (or you canì
- leave them -- they do no harm). Then close up the list, inserting equalì
- signs and, when the line is wide enough, add the command script. Finally,ì
- merge this with the rest of your ALIAS.CMD file.
-
-
- Aliases for Special Command Redefinitions
-
- Just before the simple redefinition aliases there are six commands thatì
- have been separated out for special treatment. Consider the first of them:
-
- ZP,ATCH b0:zpatch $*
-
- I find that my fingers have some difficulty typing the full ZPATCHì
- correctly, and this alias permits me to enter simply ZP. Note that in thisì
- case we cannot use "b0:$!" for the script because the alias name allows forì
- forms other than an exact ZPATCH. If the script used the $! parameter andì
- the command was entered as ZP, then the expanded script would become "B0:ZPì
- ...", which would not work.
-
- The alias for crunching is similar in some respects but more elaborate. ì
- The letter combination CH must give me trouble, because I often type CRUNCHì
- wrong, too, unless I work very carefully. This alias not only lets me useì
- the short form CR; it also allows the command to work with namedì
- directories.
-
- CR,UNCH b0:crunch $td1$tu1:$tf1 $td2$tu2:
-
- By expanding the first and second parameters explicitly, named directoryì
- references can be converted to the DU: form that CRUNCH can deal with.
-
- The alias for DATSWEEP goes a little further than the other two insofarì
- as alternative forms are concerned.
-
- DATSW,EEP=DS=SWEEP b0:datsweep $*
-
- It allows abbreviated forms as short as DATSW, but it additionally allowsì
- alternative nicknames for the command, such as DS or the more familiarì
- SWEEP, which it replaces on my system.
-
- The next example in this section shows how a program that does not knowì
- about Z System file specifications at all can be made to work with themì
- anyway.
-
- LDIR $td1$tu1:;b0:ldir $tn1;$hb:
-
- For LDIR I just started to use LDIR-B, which displays date stamp informationì
- about files in the library. Unfortunately, it does not know about namedì
- directories; in fact, it does not even know anything about user numbers. Ifì
- he is true to form, Bruce Morgen, the Intrepid Patcher, will soon have aì
- ZLDIR-B or an LDRZ-B that will accept full Z System file specs, and I willì
- be able to retire this alias.
-
- At present, however, LDIR-B accepts only the standard CP/M syntax forì
- files. As a result, it is not enough simply to pick apart the token, as itì
- would be if LDIR would accept the form DU:NAME.TYP. Instead, the directoryì
- specified for the library is logged into, then the LDIR command is run onì
- the library name, and finally the original directory is relogged. This willì
- work very nicely unless the user number specified is higher than 15 (andì
- your Z33/Z34 is not configured for logging into high user numbers).
-
- The last two examples in this series illustrate still another way toì
- make aliases lighten the typing burden. With XBIOS, alternative versions ofì
- the operating system are described in model files. These typically have aì
- file type of MDL, but that type is not required or the default. ì
- Consequently, the SYSBLD system-defining utility and the XBOOT system¡
- loading utility must be given an explicit file type. Since I always use MDLì
- for the type, I created these aliases to add the file type for me so that Iì
- can enter the commands simply as "SYSBLD TEST" or "XBOOT BIGSYS".
-
- SYSBLD b0:;b0:$0 $1.mdl;$hb:
- BOOT=XBOOT b0:;b0:xboot $1.mdl
-
- The XBOOT alias lets me save a little typing by omitting the leading 'X' ifì
- I wish. The SYSBLD alias returns to the original directory when it isì
- finished. Since XBOOT coldboots a new operating system, any trailingì
- commands are lost anyway. The XBOOT command will soon support a warmbootì
- mode, in which, like NZCOM and Z3PLUS, the new system is created withoutì
- affecting the multiple command line, shell stack, or other loaded systemì
- modules that have not changed their address or size. I might then add anì
- alias REBOOT or WBOOT (warmboot) that will load a new system and return toì
- the original directory.
-
-
- Memory Display Aliases
-
- In my system development work I often have occasion to examine variousì
- parts of memory. I might want to look at the beginning of the BIOS to checkì
- the hooks into an RSX (resident system extension), or I might want to seeì
- the contents of the ZCPR3 message buffer to see how some flags are beingì
- used.
-
- I used to have a set of aliases like these with explicit addresses inì
- the script ("P FE00" to look at the ENV, for example). This relieved myì
- mind of the task of remembering the addresses where these modules wereì
- located in memory. With the new dynamic systems, even a good memory willì
- not suffice, since the modules can move around, and one can not easily beì
- sure just where they are at any given time.
-
- By using the new parameters that I described earlier, the scriptsì
- always have the correct addresses. [Actually, they can still be fooled ifì
- these parameters are used in multiple-command-line scripts that include theì
- loading of a new dynamic system. As I warned in my earlier article onì
- ARUNZ, all parameters are expanded at the time the alias is invoked. If theì
- system is changed after that, the parameter values may no longer be correctì
- when that part of the script actually runs.]
-
-
- =============================================================================
-
-
- ; Memory display aliases
-
- PBIOS=BIOS p $ab
- PCCP=CCP=CPR p $ac
- PDOS=DOS p $ad
- PENV=ENV p $ae
- PFCP=FCP p $af
- PIOP=IOP p $ai
- PMCL=MCL p $al
- PMSG=MSG p $am
- PNDR=NDR p $an
- PPATH p $ap
- PRCP=RCP p $ar
- PSHL=PSHELL=SHL=SHELL p $as
- PXFCB=XFCB=PFCB=FCB p $ax
-
- ; Special equivalents
-
- ZP,ATCH b0:zpatch $*
- CR,UNCH b0:crunch $td1$tu1:$tf1 $td2$tu2:
- DATSW,EEP=DS=SWEEP b0:datsweep $*
- LDIR $td1$tu1:;b0:ldir $tn1;$hb:
- SYSBLD b0:;b0:$0 $1.mdl;$hb:
- XBOOT=BOOT b0:;b0:xboot $1.mdl
-
- ; Complete set of direct equivalents
-
- CMDRUN=LPUT=EDIT0=ERA=IF=REN=SD=SDD=XD=ZEX=ZF=VLU=W=ZPATCH=COPY=ECHO b0:$!
- FF=GOTO=JF=JETLDR87=NULU=PWD=SAVE=SP=UNCR=VTYPE=XDIR=AFIND=SALIAS=AREA b0:$!
- BD=CRUNCH=DFA=DIFF=DISKRST=DOSERR=DU=EDITNDR=ERRSET=HSH=ALIAS b0:$!
- LLF=LGET=LOADNDR=LPUT14=LT23=LUSH=LX=MOVE=MU3=PATH=PAUSE=PIP=PROT b0:$!
- PROTCCP=PUBLIC=PUTDS=Q=SAP=SAVENDR=SAVSTAMP=SFA=SHCTRL=SHOW=SQ=STAT b0:$!
- SUB=SYSGEN=UF=UNERASE=XSUB=DATE=DATSWEEP=MKDIR=SHSET=TPA=Z3INS=Z3LOC b0:$!
- ZRIP=ASSGN=BSX=FVCD=HDINIT=HDUTIL=MDINIT=MPTEST=SETDFLT=STARTHD4=SWX b0:$!
- SYSBLD=XSYSGEN=TIME=XBOOT0=XVERS=MCOPY=LZED=PUTBG=STARTHD=STARTHD1 b0:$!
- STRTFULL=LDR=JETLDR=LHC=SSTAT=XBOOT=MAP=STARTBIG=LT=LDIR=QL=SETD=CRC b0:$!
- 4ERA=4MU3=4REN=4SAVE=T4MAKE=DOSVER=DRO=LOGGED=SRO=SRW=LBREXT b0:$!
-
- SLR180+=SLRNK=SLRNK+=Z80ASM=DDT=DSDZ=FORM7=MAKESYM=MLOAD=SLRMAC=XIZ b1:$!
- ZAS=ZLINK=ZXLATE=SLR180=180FIG32=180FIG+=LNKFIG+=SLRIB=ZLIB=ZREF b1:$!
- ZZCNFG=LNKFIG=180FIG b1:$!
-
- BGSERIAL=LOADBG=STARTBG=BGPRINT=BGPRNCFG=DSCONFIG=Q=REMOVE=SECURE b2:$!
- SETBG=SPOOLER=DATSWEEP=SDD=SETTERM b2:$!
-
- INSTALL=MEX b3:$!
-
- WSCHANGE=WS=WINSTALL=MOVEPRN b4:$!
- Listing 1. The second half of the ALIAS.CMD file from my SB180 with XBIOS,ì
- slightly shortened and rearranged.
-
- =============================================================================
-
- Shells and WordStar Release 4
-
-
- As I noted in an earlier column, WordStar Release 4 was a very excitingì
- event for the CP/M world in general and the Z-System world in particular. ì
- It was the first major commercial program to recognize Z System and to makeì
- use of its features. Unfortunately, the Z System code in WS4 was notì
- adequately tested, and many errors, some quite serious, slipped through. ì
- Some of the most significant errors concern WS4's operation as a ZCPR3ì
- shell.
-
- Let's begin with a little background on the concept of a shell in ZCPR. ì
- Normally, during Z System operation the user is prompted for command lineì
- input. This input may consist of a string of commands separated byì
- semicolons. When the entire sequence of commands has been completed and theì
- command line buffer is again empty, the user would be prompted again forì
- input.
-
- This prompting is performed by the ZCPR command processor, which,ì
- because it is limited in size to 2K, is correspondingly limited in itsì
- power. Richard Conn, creator of ZCPR, had the brilliant idea of including aì
- facility in ZCPR3 for, in effect, replacing -- or, perhaps better said,ì
- augmenting -- the command processor as a source of commands for the system. ì
- This is the shell facility.
-
- Under ZCPR3, when the command processor finds that there are no moreì
- commands in the command line buffer for it to perform, before it prompts theì
- user for input, it first checks a memory buffer called the shell stack. Ifì
- it finds a command line there, it executes that command immediately, withoutì
- prompting the user for input. The program run in that way is called aì
- shell, because it is like a shell around the command processor kernel. Theì
- shell is what the user sees instead of the command processor, and the shellì
- will normally get commands from the user and pass them to the commandì
- processor. In effect, the outward appearance of the operating system can beì
- changed completely when a shell is selected.
-
- A perfect example of a shell is the EASE history shell. To the user itì
- looks rather like the command processor. But there are two very importantì
- differences. First of all, the command line editing facilities are greatlyì
- augmented. One can move the cursor left or right by characters, words, orì
- commands; one can insert new characters or enter new characters on top ofì
- existing characters; characters or words can be deleted. One has, in a way,ì
- a wordprocessor at one's disposal in creating the command line.
-
- The second feature is the ability to record and recall commands in aì
- history file. Many users find that they execute the same or similarì
- commands repeatedly. The history feature of EASE makes this veryì
- convenient. These two command generation features require far too much codeì
- to include in the command processor itself, so it is very convenient to haveì
- the shell capability.
-
- Programs designed to run as shells have to include special code toì
- distinguish when they have been invoked by the user and when they have beenì
- invoked by the command processor. ZCPR3 makes this information available toì
- such programs. When invoked by the user, they simply write the appropriateì
- command line into the shell stack so that the next time the commandì
- processor is ready for new input, the shell will be called on. After that,ì
- the user sees only the shell. Shells normally have a command that the userì
- can enter to turn the shell off.
-
- ZCPR3 goes beyond having just a single shell; it has a stack of shells. ì
- A typical configuration allows four shell commands in the stack. When theì
- user invokes a command designed to run as a shell, it pushes its name ontoì
- the stack. When the user cancels that shell, any shell that had beenì
- running previously comes back into force. Only when the last shell commandì
- has been cancelled (popped from the shell stack) does the user see theì
- command processor again.
-
- Let's look at some of the shells that are available under Z System. Weì
- have already mentioned the EASE history shell. There is also the HSHì
- history shell, which offers similar capabilities. It was written in C andì
- cannot be updated to take advantage of innovations like type-3 and type-4 commands. I would say that EASE is the history shell of choice today. Thisì
- is especially true because EASE can do double service as an error handler asì
- well, with the identical command line editing interface.
-
- Then there are the menu shells, programs that allow the user with justì
- a few keystrokes to initiate desired command sequences. They come inì
- several flavors. MENU stresses the on-screen menu of command choicesì
- associated with single keystrokes. VFILER and ZFILER stress the on-screenì
- display of the files on which commands will operate; the commands associatedì
- with keys are not normally visible. Z/VFILER offer many internal fileì
- maintenance commands (copy, erase, rename, move, archive). VMENU andì
- FMANAGER are inbetween. Both the files in the directory and the menu ofì
- possible commands are shown on the screen.
-
-
- What Kind of Programs Should be Shells?
-
- Not all programs should be shells. From a strict conceptual viewpoint,ì
- only programs that are intended to take over the command input function fromì
- the command processor on a semipermanent basis should be shells. Theì
- history shells and the MENU and VMENU type shells clearly qualify. Oneì
- generally enters those environments for the long haul, not just for a quickì
- command or two.
-
- ZFILER and VFILER are marginal from this viewpoint. One generallyì
- enters them to perform some short-term file maintenance operations, afterì
- which one exits to resume normal operations. It is rare, I believe, toì
- reside inside ZFILER or VFILER for extended periods of time, though I amì
- sure there are some users who do so.
-
- Many people (I believe mistakenly) try to set up as shells any programì
- from which they would like to run other tasks and automatically return. ì
- This is the situation with WordStar. No one will claim that the mainì
- function of WordStar is to generate command lines! Clearly it is intendedì
- to be a file editor. Why, then, was it made into a ZCPR3 shell in the firstì
- place? I'm really not sure.
-
- WordStar's 'R' command really does not offer very much. In neither theì
- ZCPR nor the CP/M configuration does any information about the operatingì
- environment seem to be retained. For example, one might expect on return toì
- WordStar that the control-r function would be able to recall the mostì
- recently specified file name. But this does not seem to be the case,ì
- although it could easily have been done. In the ZCPR version, the nameì
- could be assigned to one of the four system file names in the environmentì
- descriptor; in the CP/M version it could be kept in the RSX code at the topì
- of the TPA that enables WordStar to be reinvoked after a command isì
- executed.
-
- The WordStar 'R' command does not save any time, either. Essentiallyì
- no part of WordStar remains in memory. The user could just as well use theì
- 'X' command to leave WordStar, run whatever other programs he wished, andì
- then reinvoke WS. Nevertheless, I can understand why users would enjoy theì
- convenience of a command like the 'R' command that automatically brings oneì
- back to WordStar. Shells, however, are not the way to do this, at least notì
- shells in the ZCPR3 sense.
-
-
- ZCPR2-Style Shells
-
- In ZCPR2 Richard Conn had already implemented an earlier version of theì
- shell concept which, interestingly enough, would be the appropriate way forì
- WordStar and perhaps even ZFILER/VFILER to operate. He did not have a shellì
- stack, but he did have programs like MENU that, when they generatedì
- commands, always appended their own invocation to the end of the commandì
- line. Thus if the menu command script associated with the 'W' key was "WSì
- fn2", where fn2 represents system file name #2, then the actual commandì
- placed into the command line buffer would be "WS fn2;MENU". In this way,ì
- after the user's command ran, the MENU program would come back.
-
- Let's compare how the two shell schemes would have worked withì
- WordStar. Suppose we want to edit the file MYTEXT.DOC and then copy it toì
- our archive disk with the command "PPIP ARCHIVE:=MYTEXT.DOC". We might haveì
- created the following alias script for such operations:
-
- WSWORK ws $1;ppip archive:=$1
-
- Then we just enter the command "WSWORK MYTEXT.DOC" when we want to work on theì
- file and have it backed up automatically when we are done.
-
- Here is what WS4 does as a ZCPR3-type shell. The command line starts outì
- as:
-
- WSWORK MYTEXT.DOC
-
- When the alias WSWORK is expanded the command line becomes:
-
- WS MYTEXT.DOC;PPIP ARCHIVE:=MYTEXT.DOC
-
- When WordStar runs, it pushes its name onto the shell stack so that it will beì
- invoked the next time the command line is empty. Noting that the command lineì
- is not empty, it returns control to the command processor. Then the PPIPì
- command is executed, backing up our unmodified file (horrors!!!) Finally theì
- command line is empty and WS, as the current shell, starts running. Since itì
- was invoked as a shell, it prompts the user to press any key before it clearsì
- the screen to start editing. By this time it has forgotten all about the fileì
- we designated and it presents us with the main menu. All in all, a ratherì
- foolish and useless way to go about things.
-
- You might think that the problem would be solved if WS did not check forì
- pending commands but went ahead immediately with its work. Indeed, this wouldì
- work fine until the 'R' command was used. Then either the pending PPIP commandì
- would be lost (replaced by the command generated by the 'R' operation) orì
- executed (if the 'R' command appended it to the command it generated). Inì
- either case we have disaster!
-
- Now suppose WS4 had used the ZCPR2-style shell concept. After the aliasì
- had been expanded, the "WS MYTEXT.DOC" command would run, and we would edit ourì
- file. While in WS4, suppose we want to find where on our disks we have filesì
- with names starting with OLDTEXT. We use the 'R' command to enter the commandì
- line "FF OLDTEXT". The 'R' command would append ";WS" to the end the commandì
- we entered and insert it into the command line buffer before the currentì
- pointer, leaving the following string in the buffer:
-
- FF OLDTEXT;WS;PPIP ARCHIVE:=MYTEXT.DOC
-
- After the FF command was finished, WordStar would be executed again. Just whatì
- we wanted.
-
- In fact, under ZCPR3 WS could be much cleverer than this. First of all,ì
- it could determine from the external file control block the name (and under Z33ì
- the directory) used to invoke WordStar in the first place. There would be noì
- need, as there is now, to configure WS to know its own name and to make sureì
- that the directory with WS is on the command search path. The 'R' commandì
- could have appended "B4:WSNEW" if WSNEW had been its name and it had beenì
- loaded from directory B4.
-
- There is one problem, however. We would really like WS to wait beforeì
- clearing the screen and obliterating the results of the FF command. With theì
- ZCPR3-type shell, WS can determine from a flag in the ZCPR3 message bufferì
- whether it was invoked as a shell. For the ZCPR2-style shell we would have toì
- include an option on the command line. WS could, for example, recognize theì
- command form "WS /S" as a signal that WS was running as a shell. It would thenì
- wait for a key to be pressed before resuming, just as under a ZCPR3-styleì
- shell. Of course, you would not be able to specify an edit file with the nameì
- "/S" from the command line in this case, but that is not much of a sacrifice orì
- restriction.
-
- We could continue to work this way as long as we liked. Only when weì
- finally exited WS with the 'X' command would the PPIP command run. This, ofì
- course, is just the right way to operate!
-
-
- ZCPR2 vs ZCPR3 Shell Tradeoffs
-
- Once I started thinking about the old ZCPR2-type shells, I began to wonderì
- why one would ever want a ZCPR3-type shell. At first I thought that Z2-styleì
- shells could not be nested, but that does not seem to be the case. Suppose weì
- run MENU and select the 'V' option to run VFILER. The command line at thatì
- point would be
-
- VFILER;MENU /S
-
- where we have assumed that a "/S" option is used to indicate invocation as aì
- shell. While in VFILER we might run a macro to crunch the file we are pointingì
- to. The macro could spawn the command line "CRUNCH FN.FT". The command lineì
- buffer would then contain
-
- CRUNCH FN.FT;VFILER /S;MENU /S
-
- After the crunch is complete, VFILER would be reentered. On exit from VFILERì
- with the 'X' command, MENU would start to run. Thus nesting is not onlyì
- possible with Z2-type shelling, it is not limited by a fixed number of elementsì
- in the shell stack as in ZCPR3 (the standard limit is 4). Only the size of theì
- command line buffer would set a limit.
-
- What disadvantages are there to the Z2-style shell? Well, I'm afraid thatì
- I cannot come up with much in the way of substantial reasons. The shell stackì
- provides a very convenient place to keep status information for a program. Iì
- do that in ZFILER so that it can remember option settings made with the 'O'ì
- command. On the other hand, this information could be kept as additional flagsì
- on the command line, as with the "/S" option flag. There is no reason why theì
- information could not be stored even in binary format, except that the nullì
- byte (00 hex) would have to be avoided.
-
- If the 128 bytes currently set aside for the shell stack were added to theì
- multiple command line buffer, the use of memory would be more efficient than itì
- is now with Z3-style shells. Z3 shells use shell stack memory in fixed blocks;ì
- with Z2 shells the space would be used only as needed. I rarely have more thanì
- one shell running, which means that most of the time 96 bytes of shell stackì
- space are totally wasted. Of course, with the present setup of ZCPR3, theì
- multiple command line buffer cannot be longer than 255 bytes, because the sizeì
- value is stored in the environment descriptor as a byte rather than as a word. ì
- The command line pointer, however, is a full word, and so extension to longerì
- command lines would be quite possible (I'll keep that in mind for Z35!).
-
- Following this line of reasoning, I am coming to the conclusion that onlyì
- programs like history shells and true menu shells should be implemented asì
- ZCPR3-style shells. Other programs, like ZFILER and WordStar should use theì
- ZCPR2 style. If I am missing some important point here, I hope that readersì
- will write in to enlighten me.
-
-
- Forming a Synthesis
-
- So long as the command line buffer is fixed at its present length and soì
- long as 128 bytes are set aside as a shell stack, one should make the best ofì
- the situation. Rob Wood has come up with a fascinating concept that does justì
- that.
-
- Rob was working on Steve Cohen's W (wildcard) shell. He recognized thatì
- on many occasions one wants to perform a wildcarded operation followed by someì
- additional commands (just as with the WordStar example followed by PPIP). As aì
- ZCPR3-type shell, W could not do this. It always executed what it was supposedì
- to do after the wild operation before the wild operation!
-
- Rob came up with a brilliant way to combine the ZCPR2 and ZCPR3 shellì
- concepts. When his version of W is invoked manually by the user, it pushes itsì
- name, as a good ZCPR3 shell does, onto the shell stack. But it does not thenì
- return to the command processor to execute commands pending in the commandì
- line. It starts running immediately, doing the thing it was asked to do andì
- using the shell stack entry to maintain needed data.
-
- In the course of operation, however, it does one unusual thing. Afterì
- each command that it generates and passes to the command line buffer, itì
- appends its own name, as a good ZCPR2 shell does. This command serves as aì
- separator between the shell-generated commands and those that were on theì
- original command line after the W command. After the shell-generated commandsì
- have run, W starts to run. It checks the top of the shell stack, and if itì
- finds its own name there, it says "Aha, I'm a shell," and proceeds to use theì
- information in the shell stack to generate the next set of commands. Thisì
- process continues until W has no more work to do. Then it pops its name offì
- the shell stack and returns to the command processor. The commands originallyì
- included after the W command are still there and now execute exactly asì
- intended. Beautiful!
-
-
- WordStar Shell Bugs
-
- It is bad enough that WordStar's conceptual implementation as a shell isì
- flawed. On top of that, the shell code was not even written correctly. Theì
- person who wrote the code (not MicroPro's fault, I would like to add) tried toì
- take a short cut and flubbed it. When a shell installs itself, it shouldì
- always -- I repeat, always -- push itself onto the stack. WordStar tries toì
- take the following shortcut. If it sees that the shell stack is currentlyì
- empty, it just writes its name into the first entry, leaving the other entriesì
- as they were.
-
- When WordStar terminates, however, it pops the stack. At this pointì
- whatever junk was in the second shell stack entry becomes the currently runningì
- shell. The coding shortcut (which I would think took extra code rather thanì
- less code, but that is beside the point) assumed that if the current shellì
- stack entry was null, all the others would be, too. But this need not be theì
- case at all. And in many cases it has not in fact been the case, and veryì
- strange behavior has been observed with WordStar. Some users have reportedì
- that WordStar works on their computers only if invoked from a shell! That isì
- because WordStar properly pushes itself onto the stack in that case.
-
- There are basically two strategies one can take for dealing with the shellì
- problems in WordStar. One is to fix the above problem and live with the otherì
- anomalies (just don't ever put commands after WS in a multiple command line). ì
- The other is to disable the shell feature entirely.
-
- To fix the bug described above, Rick Charnes wrote a program calledì
- SHELLINI to initialize the shell stack before using WordStar. On bulletinì
- boards in the past both Rick and I presented aliases that one can use toì
- disable the shell stack while WS is running and to reenable it after WS hasì
- finished. I will now describe patches that can be made directly to WordStarì
- itself. First I will explain what the patches do; later I will discuss how toì
- install them.
-
- Listing 2 shows a patch I call WSSHLFIX that will fix the bug justì
- described. The code assumes that you do not already have any initialization orì
- termination patches installed. If you do, you will have to add the routinesì
- here to the ones you are already using.
-
- The patch works as follows. When WS starts running, the initializationì
- routine is called. It extracts the shell stack address from the ENV descriptorì
- and goes there to see if a shell command is on the stack. If there is, noì
- further action is required, since WS already works correctly in this case. If,ì
- on the other hand, the first shell entry is null, then the routine calculatesì
- the address of the beginning of the second shell entry and places a zero byteì
- there. When this stack entry is popped later, it will be inactive.
-
- Listing 3 shows a patch I call WSSHLOFF that will completely disable theì
- shell feature of ZCPR3 while WS is running. It works as follows. When WSì
- starts running, the initialization routine is called. It gets the number ofì
- shell stacks defined for the user's system in the ENV descriptor and saves itì
- away in the termination code for later restoration. Then it sets the value toì
- 0. WordStar later checks this value to see if the shell feature is enabled inì
- ZCPR3. Since WordStar thinks that there is no shell facility, it operates theì
- 'R' command as it would under CP/M. Later, on exit from WS, the terminationì
- routine restores the shell-stack-number so that normal shell operation willì
- continue upon exit from WS.
-
- The easiest way to install these patches is to assemble them to HEX filesì
- and use the following MLOAD command (MLOAD is a very useful program availableì
- from remote access systems such as Z Nodes):
-
- MLOAD WS=WS.COM,WSSHLxxx
-
- Substitute the name you use for your version of WordStar and the name of theì
- patch you want to install. That's it; you're all done.
-
- If you do not have MLOAD, you can install the patches using the patchingì
- feature in WSCHANGE. From the main menu select item C (Computer), and fromì
- that menu select item F (Computer Patches). From that menu, work through itemsì
- C (initialization subroutine), D (un-initialization subroutine), and E (generalì
- patch area), installing the appropriate bytes listed in Table 1.
-
-
- Summary
-
- We have covered a lot of material this time. The issue of shells is aì
- very tricky one, and I hope to hear from readers with their comments. I wouldì
- also enjoy learning about interesting ARUNZ aliases that you have created.
-
-
- =============================================================================
-
- ; Program: WSSHLFIX
- ; Author: Jay Sage
- ; Date: March 26, 1988
-
- ; This code is a configuration overlay to correct a problem in the shell
- ; handling code in WordStar Release 4.
- ;
- ; Problem: WS takes a mistaken shortcut when installing its name on the shell
- ; stack. If the stack is currently empty, it does not bother to push the
- ; entries up. However, when it exits, it does pop the stack, at which point
- ; any garbage that had been in the stack becomes the active shell. This patch
- ; makes sure that the second stack entry is null in that case.
-
- ;---- Addresses
-
- initsub equ 03bbh
- exitsub equ 03b3h
- morpat equ 045bh
-
- ;---- Patch code
-
- org initsub ; Initialization subroutine patch
-
- init: jp initpatch
-
- ;----
-
- org morpat ; General patch area
-
- initpatch: ; Initialization patch
- ld hl,(109h) ; Get ENV address
- ld de,1eh ; Offset to shell stack address
- add hl,de ; Pointer th shell stack address in HL
- ld e,(hl) ; Address to DE
- inc hl
- ld d,(hl)
- ld a,(de) ; See if first entry is null
- or a
- ret nz ; If not, we have no problem
- inc hl ; Advance to ENV pointer to
- inc hl ; ..size of stack entry
- ld l,(hl) ; Get size into HL
- ld h,0
- add hl,de ; Address of 2nd entry in HL
- ld (hl),0 ; Make sure that entry is null
- ret
-
- end
-
- Listing 2. Source code for a patch to fix the bug in the coding of shell
- stack pushing and popping in WordStar Release 4.
-
- =============================================================================
-
- ; Program: WSSHLOFF
- ; Author: Jay Sage
- ; Date: March 26, 1988
-
- ; This code is a configuration overlay to correct a problem in the shell
- ; handling code in WordStar Release 4.
- ;
- ; Problem: Because WordStar runs as a ZCPR3 shell, it is impossible to use
- ; WS in a multiple command line with commands intended to execute after WS is
- ; finished. One can disable this by patching the ZCPR3 environment to show
- ; zero entries in the shell stack while WS is running. This effectively
- ; disables WS4's shell capability. Unfortunately, it means that the extended
- ; features of the 'R' command under ZCPR3 are also lost.
-
- ;---- Addresses
-
- initsub equ 03bbh
- exitsub equ 03beh
- morpat equ 045bh
-
- ;---- Patch code
-
- org initsub ; Initialization subroutine
-
- init: jp initpatch
-
- ;----
-
- org exitsub ; Un-initialization subroutine
-
- exit: jp exitpatch
-
- ;----
-
- org morpat ; General patch area
-
- initpatch: ; Initialization patch
- call getshls ; Get pointer to shell stack number
- ld a,(hl) ; Get number
- ld (shstks),a ; Save it for later restoration
- ld (hl),0 ; Set it to zero to disable shells
- ret
-
- exitpatch: ; Termination patch
- call getshls ; Get pointer to shell stack number
- shstks equ $+1 ; Pointer for code modification
- ld (hl),0 ; Value supplied by INITPATCH code
- ret
-
- getshls:
- ld hl,(109h) ; Get ENV address
- ld de,20h ; Offset to number of shell entries
- add hl,de ; HL points to number of shell entries
- ret
-
- end
-
-
- Listing 3. Source code for a patch that disables the shell feature of
- ZCPR3 while WordStar 4 is running and reenables it on exit.
-
- =============================================================================
-
- WSSHLFIX patch bytes:
-
- initialization subroutine: C3 5B 04
-
- un-initialization subroutine: 00 00 C9 (should be this way already)
-
- general patch area: 2A 09 01 11 1E 00 19 5E 23 56 1A
- B7 C0 23 23 6E 26 00 19 36 00 C9
-
-
- WSSHLOFF patch bytes
-
- initialization subroutine: C3 5B 04
-
- un-initialization subroutine: C3 65 04
-
- general patch area: CD 6B 04 7E 32 69 04 36 00 C9 CD 6B
- 04 36 00 C9 2A 09 01 11 20 00 19 C9
-
-
- Table 1. List of HEX bytes for installing either of the patches into
- WordStar Release 4 to deal with the problems in the shell code.
-
-