home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / zsus / tcj / tcj27.mag < prev    next >
Encoding:
Text File  |  1994-09-02  |  32.4 KB  |  534 lines

  1.                                Z-System Corne≥ (c)
  2.                                  by Jay Sage
  3.                         The Computer Journal, Issue 27
  4.                           Reproduced with permission
  5.                            of author and publisher
  6.  
  7.  
  8.      When  I  first  offered  to write a regular  column  for  The  Computer
  9. Journal,  I  wondered if I would have enough material for a column every two
  10. months.  Instead, the problem has become one of finding the time to set down
  11. all the thoughts I have.  For this issue I had planned to cover four topics,
  12. there  is only room for three of them.   They are:  1) corrections  of  some
  13. errors in the last column (and an excuse for more discussion of flow control
  14. in  Z  System);  2)  a brief rundown on the files in  the  first  officially
  15. released  ZSIG  diskette;  and  3)  a  discussion  of  command-line-building
  16. programs in ZCPR3, including aliases and shells.
  17.  
  18.  
  19.                                 Corrections
  20.                                 -----------
  21.  
  22.      There  were  two errors that I noticed in the last column.   One was  a
  23. minor one that was Art Carlson's fault;  the other was more serious and  was
  24. my doing.   First for the easy one.   Art was kind enough to add information
  25. at  the  end of the column on how to contact me,  but the Z-Node  he  listed
  26. there  was not mine.   It was the Lillipute Z-Node in Chicago,  which is the
  27. official  ZSIG  remote  access system (its phone  number  is  312-649-1730).
  28. Messages  left for me there will get to me,  but I will get them  sooner  if
  29. they  are left for me on my own node in Boston at 617-965-7259.   I can also
  30. be  reached  on  my voice phone at 617-965-3552 (please don't  mix  the  two
  31. numbers  up,  especially  if you are calling in the middle of  the  night!).
  32. Finding me at home is not always easy,  and your chances will be best if you
  33. call between 10pm and just after 11pm (Boston time, of course).
  34.  
  35.      Now  for  the  error I made.   In the discussion of  the  flow  control
  36. package (FCP) and the transient IF.COM, I said that one can force use of the
  37. transient program by including a DU:  or DIR: prefix or even just a colon in
  38. front  of  the  'IF'.   This is not true.   I thought  I  had  verified  the
  39. statement experimentally,  but my experiment was flawed,  and the conclusion
  40. incorrect.  A colon does force the command processor to skip commands in the
  41. resident  command package (RCP) and in the CPR itself and to proceed with  a
  42. search for a COM file,  but all the FCP resident commands are intercepted no
  43. matter  whether  there is a colon or not.   There is a very good reason  for
  44. this.   The FCP commands must be executed even when the current IF state  is
  45. false.   This is especially clear for commands like ELSE, which reverses the
  46. current IF state, and FI, which terminates the current IF state.  Transients
  47. ELSE.COM  and  FI.COM  could not do this.   After a bit of thought  you  can
  48. probably see that this is true for all the flow control commands.
  49.  
  50.      I  have  long  been searching for ways to give the  user  control  over
  51. whether  IF  processing is performed by resident  or  transient  code.   One
  52. solution  that  I introduced some time ago was adding alternative names  for
  53. ècondition  options  in  IF.COM so that one could  force  the  more  powerful
  54. transient processing to be performed even when the function was supported by
  55. the resident FCP.   The trick was to use condition names in IF.COM that were
  56. different  from  the  names  of  the  same  functions  in  the  FCP  module.
  57. Specifically,  I  changed  the first letters to 'X' (for example  XXIST  for
  58. EXIST and XNPUT for INPUT).  Frank Gaude' in the Echelon Z-News has reported
  59. examples  in  which the transient program is given a name other than  IF.COM
  60. (such as IF13.COM).   Then the command "IF INPUT" gives resident  processing
  61. and  "IF13 INPUT" transient processing.   This will work correctly for first
  62. level IF processing but will not work in general.
  63.  
  64.      Neither of these solutions was really satisfactory.  A proper solution,
  65. I felt,  would operate both correctly and automatically.  I have now written
  66. a  new  FCP  package (FCP10) that is presently under test  by  ZSIG  program
  67. committee  members  and  should  be ready for release  with  the  next  ZSIG
  68. diskette.   It handles both resident and transient code.  It can examine the
  69. command line to see if there was a colon before the IF.   In that case,  the
  70. FCP ignores its internal condition options and invokes the transient  IF.COM
  71. immediately.   If  no colon was present,  the FCP first looks to see if  the
  72. condition option is included in the resident code.  If not, it automatically
  73. invokes  the  transient IF processor.   The user need not be concerned  with
  74. which options are resident in the FCP.   The script "IF NULL $1" in an alias
  75. will  take  advantage  of fast resident processing if  the  NULL  option  is
  76. supported  in  the  resident  code or will  automatically  invoke  transient
  77. processing if not.   When one wants to be sure to get transient  processing,
  78. one simply uses the colon as in ":IF EXIST FILE1,FILE2".
  79.  
  80.      To go along with FCP10 there is a new transient IF processor,  COMIF10.
  81. It supports dozens of additional condition tests.  One is AMBIG, which tests
  82. a file specification for ambiguity (question marks or asterisks).   Register
  83. (numeric)  and string (alphabetic) comparisons are now extended to the  full
  84. range of tests:  equal, not equal, greater, less, greater than or equal, and
  85. less than or equal.  I plan to add file attribute testing (SYS, DIR, RO, RW,
  86. ARC,  WP)  and  testing for the presence of Plu*Perfect Software's  exciting
  87. Backgrounder task-swapping program.
  88.  
  89.      The  new  FCP/COMIF  combination also adds an important  new  twist  in
  90. transient  processing.   They have the option of loading the transient  code
  91. not at 100H,  as has been done until now,  but high in memory, where it will
  92. not  overwrite a user program that is loaded at 100H.   In this way  the  GO
  93. command  can  be  used  to rerun the last user program  after  flow  control
  94. processing no matter whether resident or transient flow processing was used.
  95. Thus  the  user need not concern himself with how the  flow  processing  was
  96. performed.
  97.  
  98.      While  I  was at it,  I also added two new commands to the FCP  module.
  99. One, IFQ (if query), is designed to help users -- advanced as well as novice
  100. -- learn  how  flow  control works (or,  perhaps,  is  not  working  as  one
  101. intends).   It  displays on the screen the complete flow state of the system
  102. -- the true/false status of all IF levels.  The second is ZIF (zero ifs). It
  103. is  like XIF (end all ifs) except for one thing.   XIF clears all IF  states
  104. only if the current IF state is true;  if the current IF state is false, XIF
  105. èis flushed (ignored) just like any other command.   ZIF,  on the other hand,
  106. clears  all  IF  states no matter what.   I'm sure  that  everyone  who  has
  107. experimented  with flow control has at one time or another gotten himself so
  108. messed  up  that  nothing  seemed to work.   The  only  way  out,  short  of
  109. rebooting,  was to type a string of FI's until things started working again.
  110. ZIF  is  a quick way to reinitialize the flow control system (and  it  takes
  111. very little code in the FCP).
  112.  
  113.  
  114.                               ZSIG Diskette #1
  115.                               ----------------
  116.  
  117.  
  118.      Now that I have atoned,  I hope,  for my sin in the last issue,  I will
  119. turn to the first new subject,  the inaugural ZSIG diskette.   Let me remind
  120. you  that this diskette and a number of others put out by NAOG/ZSIG (NAOG  =
  121. North  American  One-Eighty Group,  the group formed to  support  the  SB180
  122. computer  and other computers using the Hitachi HD64180 microprocessor)  can
  123. be  ordered  from  NAOG/ZSIG (P.O.  Box  2781,  Warminster,  PA  18974).   I
  124. encourage all of you to join ZSIG ($15).  You'll get a nice newletter with Z
  125. System tips and details on all the NAOG/ZSIG diskettes.
  126.  
  127.      Here is a listing of the files in ZSIG diskette #1.
  128.  
  129.         Z-RIP.LBR       VERROR17.LBR    VCED18.LBR
  130.  
  131.         ZCRCK.LBR       ZFINDU.LBR      ZLDIR.LBR
  132.         ZTXTTOWS.LBR    ZWC.LBR
  133.  
  134.         PPIP14.LBR      UF.LBR
  135.  
  136.         LDSK20.LBR      W20.LBR
  137. The first three programs are by Paul Pomerleau.   Paul is a speed freak and,
  138. like many of us,  found the process of installing Z programs with Z3INS (the
  139. standard installation utility) tedious and slow.  So Paul wrote Z-RIP, given
  140. that  name  because it rips through an entire disk of  files  at  incredible
  141. speed, automatically identifying the ZCPR programs and installing them.  The
  142. new  autoinstall  versions  of ZCPR3 may make Z-RIP (not to  mention  Z3INS)
  143. obsolete, but it is great for those running standard ZCPR.  VERROR is Paul's
  144. video  error handler.   It provides a screen display of the  entire  command
  145. line  in which an error was detected and allows the user to edit it  freely,
  146. moving  about  using WordStar-like commands.   VCED is Paul's Video  Command
  147. EDitor,  a  video history shell.   With VCED running as a  shell,  the  user
  148. always  has full command-line editing.   In addition,  past commands can  be
  149. recalled,  searched for,  edited,  and run.   As if that were not enough, it
  150. doubles  as  a  video  error  handler as  well!   Paul  astutely  noted  the
  151. functional  similarity  between  correcting old  commands  with  errors  and
  152. entering  new  commands  -- so  he combined the two functions  in  a  single
  153. program.
  154.  
  155.      The  next  group of five programs comprises Z versions of  common  CP/M
  156. utilities.   Most  of these were created by the prolific program  fixer  and
  157. èNAOG/ZSIG chief,  Bruce Morgen.   The main feature that makes these programs
  158. ZCPR3-compatible   is  their  ability  to  accept  named  directory   (DIR:)
  159. references  as  well as drive/user (DU:) references.   For  programmers  and
  160. aspiring programmers reading this,  you should know that the code to do this
  161. in  ZCPR3  is  actually  much  simpler than the CP/M  code  needed  just  to
  162. recognize the DU: form.  This is because the ZCPR3 command processor already
  163. does all the work for the first two arguments on the command line (including
  164. translating  named  directory references into  drive/user  values).   Unlike
  165. CP/M, ZCPR3 saves not only the drive but also the user number in the default
  166. file  control blocks at 5CH and 6CH.   A ZCPR3 program need only  fetch  the
  167. values  from  the appropriate locations.   The hardest part of making  these
  168. ZCPR3  versions  of  the CP/M programs was stripping  out  the  complex  and
  169. lengthy  parsers required to accept DU:  syntax in CP/M.   (So much for  the
  170. myth  of  ZCPR3  complexity!   Programming in ZCPR3 is  often,  as  in  this
  171. example, simpler than programming in standard CP/M.)
  172.  
  173.      The  third  group of programs includes two more ZCPR3 versions of  CP/M
  174. programs.   They  are listed separately only because they do not have  names
  175. with Z's in front!  Here is a quick listing of the functions of all seven of
  176. these converted programs:
  177.  
  178.         ZCRCK           computes cyclic redundancy check codes for files
  179.                         using both common CRC polynomials
  180.         ZFINDU          searches for text strings in files, including
  181.                         files that are squeezed
  182.         ZLDIR           displays a directory of the files in a library
  183.         ZTXTTOWS        converts standard text files to WordStar files
  184.         ZWC             counts the number of words in a text file
  185.         PPIP14          copies files (as does PIP) but with nicer
  186.                         interface and fast -- I renamed it to COPY
  187.                         and use it all the time
  188.         UF              Steven Greenberg's ultrafast file unsqueezer
  189.  
  190.      The last two programs are original creations for the Z  System.   LDSK,
  191. by  Wilson  Bent  with modifications by Earl Boone,  solves  a  longstanding
  192. problem   that  owners  of  floppy-disk-based  computers  had   with   named
  193. directories.   With  hard disks,  there is an unchanging association between
  194. directory  names and drive/user values,  but with floppies  the  association
  195. changes  every  time  the diskette is changed.   Wilson devised  this  nifty
  196. scheme for automatically loading the named directory register (NDR) with the
  197. names associated with user areas on a floppy diskette.   To give a user area
  198. a name,  one simply puts a (usually zero-length) file in that user area with
  199. a  name of the form "-NAME".   When LDSK is run (specifying the drive to  be
  200. loaded),  it  scans  the disk for files of this  type,  strips  the  leading
  201. hyphen,  and creates an entry in the NDR associating the name with that user
  202. number on the drive.   As I wrote in the last column,  I still have a lot of
  203. floppy-only systems, and I love LDSK.
  204.  
  205.      Haven't  you at times wished that you could take some program that only
  206. works  on  a single file and magically make it work with an  ambiguous  file
  207. reference.   Well, Steve Cohen did, so out of his programmer's hat he pulled
  208. the  wildcard shell 'W' to do it.   It just shows again that the  only  real
  209. èlimitation  with the Z System is one's imagination!   Here are some examples
  210. of how 'W' can be used.  Bob Freed wrote a quick little program called PCPCK
  211. that checks a file for proper transmission over Telenet's PC-Pursuit  packet
  212. network (certain character sequences cause problems).  The trouble is, PCPCK
  213. only  works on a single file,  and it is no fun to run it manually on  every
  214. file one is about to send somewhere.   But along comes 'W' and all I have to
  215. do is enter "W PCPCK *.*" and away we go.   Or suppose you are just lazy and
  216. hate  typing exact names of files.   Just put a 'W' in front of the  command
  217. and enter a wildcard file name that specifies the file you want.  That's all
  218. there  is to it.   I have 'W' implemented in an alias on my Z-Node system so
  219. that  users can type a file without having to enter the exact  name.   If  a
  220. user   can't  remember  (or  doesn't  really  care)  whether  the  file   is
  221. AUTOINST.FIX  or AUTOINST.FQZ or AUTOINST.FZX,  all he has to enter is "TYPE
  222. AUTO*.*" and the file (whatever it is called) will appear on the screen.
  223.  
  224.  
  225.                           Command Line Generators
  226.                           -----------------------
  227.  
  228.      Many people call me about problems they are having getting an alias  or
  229. VFILER  script  to  work correctly.   Often the problem turns out  to  be  a
  230. misunderstanding  of what command line generators are really doing.   I will
  231. try to shed a little more light on that subject here.
  232.  
  233.      First  a little philosophy.   There are many features in the  Z  System
  234. about which one might well at first just shrug one's shoulders and say,  "So
  235. what!"   The flow control system discussed earlier is one such feature,  and
  236. multiple  commands on a line might be another.   After all,  how many of  us
  237. actually  think  far enough ahead to enter more than one command at  a  time
  238. anyway?   Well,  the  answer lies in the interplay of all the features in  Z
  239. System and in the ways they allow things to be accomplished automatically.
  240.  
  241.  
  242.                                   Aliases
  243.  
  244.      The multiple command capability of Z System,  for example, is important
  245. not so much because it allows the user to enter a whole sequence of commands
  246. manually but rather because it allows other programs to do so automatically.
  247. The simple, standalone 'alias' created with the original ALIAS.COM or one of
  248. the more sophisticated alias programs like TALIAS,  BALIAS,  or VALIAS is  a
  249. good  example.   Let's see how such an alias might be used.   Suppose we are
  250. working on a new program with a source file called MYPROG.Z80.  Our standard
  251. sequence  of  operations  is to edit the source with a  command  like  "EDIT
  252. MYPROG.Z80" and then to assemble it with a command like "ASM MYPROG.AAZ" and
  253. then to load it with a command like "MLOAD MYPROG".   We can speed things up
  254. and  reduce the amount of typing (and the number of typos!) by  creating  an
  255. alias which we might give the name DO.COM.   We would create it, with VALIAS
  256. for example, with the following script (command line form):
  257.  
  258.         EDIT MYPROG.Z80;ASM MYPROG.AAZ;MLOAD MYPROG
  259.  
  260. Now  when  we want to start a new cycle,  we just enter the  easily  spelled
  261. ècommand "DO".  The rest is automatic.
  262.  
  263.      But  how  does this alias actually work?   When you enter  the  command
  264. "DO",  the  operating system loads DO.COM into memory and starts running it.
  265. DO  contains  within its file the script line put there by  VALIAS.COM  (for
  266. example) when the alias was created.  DO.COM has code to determine where the
  267. Z System multiple command line is located in memory (this information  comes
  268. from  what is called the environment descriptor,  whose address is installed
  269. in  a standard location near the beginning of all true Z  System  programs).
  270. Next  DO.COM  takes its command script,  appends any other commands  in  the
  271. multiple command line that come after the "DO" command,  and then writes the
  272. result  back to the command line buffer.   When it then returns to Z System,
  273. the ZCPR3 command processor,  as usual,  looks at the command line buffer to
  274. see  if  there are more jobs listed there for it to do.   Since  DO.COM  has
  275. filled the command line buffer with the script, ZCPR3 responds just as if we
  276. had typed the long command line script instead of the simple "DO".
  277.  
  278.      Now  let's see how flow control can be used with  alias  scripts.   One
  279. problem  with the command sequence in our example arises when the  assembler
  280. reports  an error.   In that case there is no sense going through the  MLOAD
  281. operation.  Assemblers like ZAS from Echelon and Z80ASM from SLR Systems set
  282. a  flag  in the Z System to show whether or not they encountered  any  fatal
  283. errors during the assembly, and the flow control command "IF ERROR" can test
  284. the state of that flag.  We can improve our script as follows:
  285.  
  286.         EDIT MYPROG.Z80;ZAS MYPROG;IF ~ERROR;MLOAD MYPROG;FI
  287.  
  288. In  this script the MLOAD command will only be executed if the program error
  289. flag has not been set by ZAS (the tilde '~' has the meaning 'not').   Typing
  290. all those flow control commands manually would be more trouble than entering
  291. single  commands at a time,  but with an alias we are still typing only  two
  292. letters: "DO".
  293.  
  294.      So far so good.  But what happens when we want to start work on another
  295. program, say NEWPROG?  Do we have to create a new alias, such as DONEW?  The
  296. answer  is that the alias program actually does much more than just  copy  a
  297. command  script as is into the multiple command line buffer.   It is capable
  298. of making parameter expansions,  the simpler examples of which are like  the
  299. parameter expansions that occur with the CP/M SUBMIT program.   We can store
  300. the alias script as
  301.  
  302.         EDIT $1.Z80;ZAS $1;IF ~ERROR;MLOAD $1;FI
  303.  
  304. The  '$1' is a symbol representing the first token after the command on  the
  305. command line that invoked the alias program.  Thus when we enter the command
  306. "DO  MYPROG"  we get the first script we discussed,  but when we  enter  "DO
  307. NEWPROG"  we  get a command line for working on NEWPROG instead.   A  single
  308. alias  thus becomes very flexible.   There are quite a number  of  parameter
  309. forms  that  can  be processed by aliases,  and I refer you to  Rick  Conn's
  310. "ZCPR3, The Manual" and various HELP files for more detailed information.
  311.  
  312.      Now let's try something a little trickier.   Sometimes we have  already
  313. èedited a file and just want to assemble and load it (if there is no error in
  314. assembling, of course).  So we create an alias called AL (for assemble/link)
  315.  
  316.         ZAS $1;IF ~ERROR;MLOAD $1;FI
  317.  
  318. [I  am  using  ZAS in these examples rather than the  SLR  Z80ASM,  which  I
  319. prefer,  because  the SLR assemblers can produce a COM file directly in  one
  320. pass and do not need MLOAD or the flow control error checking.  Thus they do
  321. not  serve  the  purposes of my example here.]  Now what do you  think  will
  322. happen if we define our DO alias as follows:
  323.  
  324.         EDIT $1.Z80;AL $1
  325.  
  326. Do  you think that will work?   One alias inside  another?   Well,  it  will
  327. indeed!   Aliases can be nested.  How deeply?  Without any limit!  Before we
  328. explain why this is, let's look at an even more fascinating example.  When I
  329. sit  down  to work on a program,  I typically go through  one  edit/assemble
  330. cycle  after  another (just don't seem to be able to get it right the  first
  331. time).  So I make my DO alias have the following script:
  332.  
  333.         EDIT $1.Z80;AL $1;DO $1
  334.  
  335. This alias actually invokes itself!!   When one cycle is finished,  it  just
  336. goes  back for more.   Now let's look at what goes on in the system after we
  337. enter the command "DO MYPROG".   The DO alias expands its script and  writes
  338. the following command line into the multiple command line buffer:
  339.  
  340.         EDIT MYPROG.Z80;AL MYPROG;DO MYPROG.
  341.  
  342. After the editing is finished,  AL runs,  expands its script,  and fills the
  343. command line buffer with the following command line:
  344.  
  345.         ZAS MYPROG;IF ~ERROR;MLOAD MYPROG;FI;DO MYPROG
  346.  
  347. Note  that the alias always appends to its own script any other commands  in
  348. the  command  line after itself (hence the DO MYPROG on the end).   Now  ZAS
  349. runs,  and,  depending on whether there were errors or not,  MLOAD may  run.
  350. Finally  ZCPR3  gets  to  the DO command,  and we are right  back  where  we
  351. started.   The whole process is repeated (and repeated again).  In fact, the
  352. only trouble with this alias is that there is no way out!  You can't stop!
  353.  
  354.      Well,  we  all  hope we will get the program right  eventually,  so  we
  355. really would like to be able to get out of the alias.  Flow control can help
  356. us again.  Consider the script
  357.  
  358.         EDIT $1.Z80;AL $1;ECHO EDIT AGAIN?;IF INPUT;DO $1;FI
  359.  
  360. Now,  before  reinvoking DO,  the alias asks us if we want to edit the  file
  361. again.   If we give a negative answer (anything other than carriage  return,
  362. space bar,  'Y' for yes, or 'T' for true), the loop is broken.  If we answer
  363. affirmatively  with  a quick tap of the return key,  we start  again.   Very
  364. quick and easy.
  365. è
  366.      There is one subtle problem,  however.   If you go through the exercise
  367. of expanding the alias scripts,  you will see that with each cycle an  extra
  368. 'FI'  builds up at the end of the command line.   Even more careful analysis
  369. will  show that with each cycle we go one IF level deeper as well.   One  of
  370. two problems will eventually spoil our plan.   Either the command line  will
  371. get so long that it won't fit in the command line buffer, or we will run out
  372. of IF levels (eight is the maximum).  What can we do about these problems?
  373.  
  374.      The  FCP has the XIF command precisely for this reason.   If we put  an
  375. XIF  command at the beginning of the script,  we will reset the IF system to
  376. level 0 every time we reenter the loop.   Then the limit will be overflow of
  377. the command line.   When this happened to me,  I invented a special type  of
  378. alias  -- the recursive alias -- and incorporated it into my VALIAS  program
  379. (as far as I know only VALIAS and ARUNZ support this alias type).   It works
  380. the  same  as a regular alias except for one thing -- it does not append  to
  381. the  script  expansion any commands that were pending in  the  command  line
  382. buffer;  it  just throws them away.   Thus in the above example all the  FIs
  383. would  be  discarded  when DO was invoked again,  and the  pileup  would  be
  384. avoided.   When  an  alias is created with VALIAS,  one can select either  a
  385. normal alias or a recursive alias.   But note that no other command can ever
  386. follow  a  recursive alias on a multiple command  line.   Recursive  aliases
  387. should be used only in special cases like the one described here.
  388.  
  389.  
  390.                                    Shells
  391.  
  392.      Aliases  are not the only command line generators.   Most  shells  also
  393. generate command lines for the user.   In some cases (VCED, described above,
  394. and  MENU)  this  is  their main purpose;  in other cases  it  is  secondary
  395. (VFILER).  Before we examine the way they generate command lines, let's look
  396. at the way shells operate in the Z System.
  397.  
  398.      The essential purpose of shells is to create just the kind of recursive
  399. command situation we were just developing with our alias example.   But they
  400. achieve  that  function  in a very different way.   A shell has  a  kind  of
  401. schizophrenic personality as a result of being invoked in two  significantly
  402. different circumstances.  One circumstance is when it is invoked directly or
  403. indirectly (e.g.,  from an alias) as the result of a user command.   In this
  404. case,  the shell has one basic purpose -- to perpetuate its own existence as
  405. a  command.   It does this by entering its name as a command into a  special
  406. buffer (area in memory) in the Z System called the shell stack.  Having done
  407. that,  it  can  then return control to the operating system.   (The  smarter
  408. shells generally do something a little more sophisticated at this point, but
  409. the principle is correct as I have described it.)
  410.  
  411.      Now  we come to the unique role of shells in the Z  System.   The  CP/M
  412. command  processor gets commands from only two possible sources:  1) from  a
  413. submit file, if one exists, or 2) from the user.  The Z System gets commands
  414. from  at least four sources and in the following order of priority (ignoring
  415. the tricky role of ZEX): 1) from the multiple command line buffer; 2) from a
  416. submit file;  3) from the shell stack;  and 4) if all else fails,  from  the
  417. èuser.   Observe  that  so long as the shell stack has a command in  it,  the
  418. command  processor will never turn to the user for input!   That is why  one
  419. can regard the shell as taking over the command processor  function.   While
  420. the shell is running, it becomes the source of commands for the system.
  421.  
  422.      How does the shell do this?  By expressing its second and more dramatic
  423. personality.   Another  special buffer in the Z System,  the message buffer,
  424. contains a flag byte that is set by the ZCPR3 command processor to  indicate
  425. whether a program has been invoked as a user command or as a shell (or as an
  426. error  handler).   We have already discussed the simple goal of the shell in
  427. the former case.  In the latter case the shell actually carries out its real
  428. function in life.  Let's consider the MENU shell as an example.
  429.  
  430.      When the MENU.COM is loaded as a shell, it displays a screen of command
  431. choices  to  the user.   Each single-character choice is associated  with  a
  432. command line script,  much like the alias script.   When the user strikes  a
  433. key,  MENU  looks up the script associated with that character,  expands the
  434. script  (substituting parameters),  and puts the resulting command into  the
  435. multiple command line buffer.   It then returns control to the ZCPR3 command
  436. processor.   ZCPR3  executes  the commands in the command buffer  one  after
  437. another until they have all been performed.   Then,  when the command buffer
  438. is  empty  again,  ZCPR3 looks in the shell stack,  finds the  MENU  command
  439. there, and runs MENU again.  This process continues until a special user key
  440. is  entered (control-c in the case of MENU) that signals the shell  that  it
  441. should remove itself from the shell stack.   Then things return to the state
  442. they were in before the shell was invoked initially by the user.     Shells,
  443. by the way,  can be nested (the usual shell stack is four entries deep),  so
  444. when  one shell removes itself from the shell stack,  control may still  not
  445. return  to the user.   Another shell,  whose role was superceded by the most
  446. recent shell, may now come back into control.
  447.  
  448.      With  the  MENU.COM  the  displayed menu of  choices  and  the  scripts
  449. associated with the choices are both included in a text file that is read in
  450. by the program.   This makes it very easy for the user to create and  modify
  451. the  display  and the scripts.   Considering again our  program  development
  452. example, we might create a menu screen with the following display:
  453.  
  454.                 S. Select name of program
  455.                 E. Edit program source code
  456.                 A. Assemble program to HEX file
  457.                 L. Load program to COM file
  458.                 R. Run program
  459.                 F. Full cycle (edit, assemble, load)
  460.  
  461. These choices might be associated with the following command scripts:
  462.  
  463.         S setfile 1 "Enter name (only) of program to work on: "
  464.         E edit $n1.Z80
  465.         A zas $n1
  466.         L mload $n1
  467.         R $n1
  468.         F edit $n1.z80;zas $n1;if ~er;mload $n1;fi
  469. è
  470.      There  are two interesting new parameters illustrated in these scripts.
  471. One is the $N1 parameter.   As part of the Z System environment buffer, four
  472. system file names are defined.   MENU can read these four file names and put
  473. into scripts the complete filename ($Fn),  the name only ($Nn),  or the type
  474. only ($Tn),  where 'n' is 1,  2,  3, or 4.  The 'S' selection sets the first
  475. system file name using the program SETFILE, and the others then use it.
  476.  
  477.      The 'S' selection illustrates the other new script parameter --prompted
  478. user  input.   When the script for choice 'S' is being  expanded,  the  text
  479. between  quotes will be displayed as a prompt to the user,  and one line  of
  480. user input will be substituted into the command line in place of the prompt.
  481. It  is  with prompted input that many users get confused and make  mistakes.
  482. Suppose  you  want  to be clever and helpful by displaying  a  directory  of
  483. existing  programs  to jog the user's memory before asking for  his  choice.
  484. You might think of using the script
  485.  
  486.         S dir *.z80;setfile 1 "Enter program name: "
  487.  
  488. This will not have the effect intended!   One must not forget that the  user
  489. is  prompted for input by the shell at the time the script is expanded,  not
  490. at  the time when the command line is executed.   In this example  the  user
  491. will  be prompted for his choice before the directory is  displayed.   Thus,
  492. the directory display is useless.
  493.  
  494.      To achieve the result intended above you must combine scripts.  You can
  495. create  an  ARUNZ  alias  called SETNAME with the  following  script  (ARUNZ
  496. supports prompted input):
  497.  
  498.         SETNAME setfile 1 "Enter name of file: "
  499.  
  500. The MENU script would then be
  501.  
  502.         S dir *.z80;arunz setname
  503.  
  504. When  the  MENU script is expanded,  the command  becomes  "DIR  *.Z80;ARUNZ
  505. SETNAME",  and  this command is then run.   It is not until ARUNZ SETNAME is
  506. executed  that  ARUNZ prompts the user for the name of the  file.   At  this
  507. point the directory of files with type Z80 has already been displayed on the
  508. screen.
  509.  
  510.      There is obviously much more that could be said about the command  line
  511. generators in ZCPR3.   The discussion here has been only an overview,  but I
  512. hope that it will inspire you to take a fresh look at and to experiment with
  513. aliases and shells of all kinds:  the standalone aliases generated by ALIAS,
  514. VALIAS,  TALIAS,  or BALIAS;  the text-file-based alias generator ARUNZ with
  515. its ALIAS.CMD file;  the menu- or macro-type shells MENU,  VMENU,  FMANAGER,
  516. VFILER, and ZFILER; and the command-line history shells HSH and VCED.
  517.  
  518.  
  519.                             Plans for Next Time
  520.                             -------------------
  521. è
  522.      As  I  said at the beginning of the article,  I had planned  to  cover,
  523. along  with  all the subjects above,  techniques for customizing  the  Z-COM
  524. self-installing  version  of  Z System.   But there just isn't the  time  or
  525. space.   So I will have to leave that for the next issue.   Let me just  say
  526. one  thing  here.   If  you  do not already have Z System  running  on  your
  527. computer and have held back on buying Z-COM from Echelon because you thought
  528. it would not offer you the flexibility of a custom installation, hold off no
  529. longer.   Buy Z-COM!  Start the exhilarating process of discovering Z System
  530. now.   By the time my discussion of Z-COM hacking is complete, you will know
  531. how to get just as much flexibility with Z-COM as with a manually  installed
  532. version.  It is much more fun to start with something that is working and to
  533. improve  it  than  it is to spend many frustrating weeks trying  to  get  an
  534. initial manual version working.
  535.  
  536.      I  want  to close with my usual invitation and encouragement  -- please
  537. write and call with your comments and suggestions of all kinds.
  538.  
  539. [This article was originally published in issue 27 of The Computer Journal,
  540. P.O. Box 12, South Plainfield, NJ 07080-0012 and is reproduced with the
  541. permission of the author and the publisher. Further reproduction for non-
  542. commercial purposes is authorized. This copyright notice must be retained.
  543. (c) Copyright 1987, 1991 Socrates Press and respective authors]
  544.