home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / tcj / tcj33upd.ws < prev    next >
Encoding:
Text File  |  1994-09-02  |  49.8 KB  |  1,037 lines

  1. This text is a version of my column in TCJ issue 33 which has been edited toì
  2. reflect the changes in ARUNZ from version 0.9J to 0.9N.  Not all newì
  3. features are reflected, but the example alias scripts should now work.
  4.       JPS 11/13/88
  5.  
  6.  
  7.  
  8.                               The ZCPR Corner
  9.  
  10.                                 TCJ Issue 33
  11.  
  12.  
  13.      For my column this time I plan to cover two subjects, both of which Iì
  14. have dealt with somewhat at length in the past.  Nevertheless, there justì
  15. seems to be a lot more to say on these subjects.  The first is ARUNZ; theì
  16. second is shells in general, and the way WordStar 4 behaves (or ratherì
  17. misbehaves) in particular.
  18.  
  19.      I was quite surprised and pleased by the enthusiastic response to myì
  20. detailed treatment of ARUNZ in issue 31.  Apparently, there were many, manyì
  21. people who were unaware of what ARUNZ was and who are now quite eager to putì
  22. it to use.  There are two specific reasons for taking up the subject ofì
  23. ARUNZ here again so soon.
  24.  
  25.      First of all, I think that readers will benefit from a discussion ofì
  26. some additional concrete examples.  Since my own uses are the ones I knowì
  27. best, I plan to take the ALIAS.CMD file from my own system as an example andì
  28. discuss a number of interesting scripts.  My first cut at doing that forì
  29. this column came out much too long, so I will cover half of the file thisì
  30. time.  The other half will be covered in the next column.
  31.  
  32.      The second reason is that I have just gone through a major upgrade toì
  33. ARUNZ.  It is now at version 0.9J.  Several aspects of its operation asì
  34. described in my previous column have been changed, and quite a few newì
  35. parameters have been added.
  36.  
  37.      The changes in ARUNZ were stimulated by two factors.  One is the twoì
  38. new dynamic Z Systems that will have been released by the time you readì
  39. this: NZCOM for Z80 computers running CP/M 2.2 and Z3PLUS for Z80 computersì
  40. running CP/M-Plus.  These two products represent a tremendous advance in theì
  41. concept of an operating system, and everyone interested in experimentingì
  42. with or using Z System -- even if he already has a manually installed ZCPR3ì
  43. running now -- should get the one that is appropriate to his computer.
  44.  
  45.      With these new Z System implementations, if your level of computerì
  46. skill is high enough to run a wordprocessor or menu program, then you canì
  47. have a Z System designed to your specifications in a matter of minutes.  Youì
  48. can change the design of your Z System at any time, even betweenì
  49. applications.  As described later, ARUNZ now has some parameters to returnì
  50. addresses of system components so that aliases can work properly even whenì
  51. those system components move around, as they may do under these dynamicì
  52. systems.
  53.  
  54.  
  55. My New Computer System
  56.  
  57.      The second impetus came from my finally building for myself a state-of¡
  58. the-art computer!  For most of my work in the past I have used a BigBoard Iì
  59. with four 8" floppy disk drives and an SB180 with four 5" disk drives. ì
  60. Neither machine had a hard disk.
  61.  
  62.      The SB180, my main system for the past year and a half, had beenì
  63. sitting on the floor in the study.  The pc board was mounted in a makeshiftì
  64. chassis with two power supplies, just as I got it from someone who bought itì
  65. at the Software Arts liquidation auction and after they had stripped out theì
  66. disk drives (at $25 I could hardly complain!).  I added my own drives, whichì
  67. sat in the open air (for cooling among other reasons) in two separate driveì
  68. cabinets elsewhere on the floor.  All in all not very pretty and not asì
  69. functional as it could have been.
  70.  
  71.      The sad part of it is that during all this time I had everything neededì
  72. to turn the SB180 into an enjoyable and productive system.  A high-speed 35ì
  73. Mb hard disk was collecting dust on a shelf; an attractive surplus Televideoì
  74. PC-clone chassis adorned the work bench in the basement; the XBIOS softwareì
  75. disks sat ignored in one of my many diskette boxes.
  76.  
  77.      Finally one weekend I decided that it would be more efficient in theì
  78. long run to take some time off from my programming and writing work toì
  79. reconstruct the system.  Indeed, it has been!  The SB180 is now attractivelyì
  80. mounted in the Televideo chassis with one 96-tpi floppy and one 48-tpiì
  81. floppy.  The hard disk is configured as four 8 Mb partitions and runs veryì
  82. nicely with the fast Adaptec 4000 controller.
  83.  
  84.      With the hardware upgraded, I then did the same to the software. ì
  85. Installing XBIOS on the SB180 took so little time that I really had to kickì
  86. myself for not doing it sooner.  Richard Jacobson was quite right in hisì
  87. description of it in issue 31.  Thank you, Malcom Kemp, for a really niceì
  88. product.
  89.  
  90.      Once I was fixing things up, I decided I should really do it up right,ì
  91. so I also purchased the ETS180IO+ board from Ken Taschner of Electronicì
  92. Technical Services -- this despite the fact that a Micromint COMM180 boardì
  93. was also a part of my longstanding inventory of unused equipment.  I cannotì
  94. compare the ETS board to the COMM180, never having used the latter, but Iì
  95. certainly am highly pleased with it.  XBIOS includes complete support forì
  96. the ETS board, so configuring the system to make use of the extra ETS180IO+ì
  97. features, like the additional parallel and serial ports and the battery¡
  98. backed clock, was very easy.
  99.  
  100.      I have been so pleased with the new system that I even went out andì
  101. bought a real computer table for it to sit on.  For the past years, theì
  102. terminal's CRT unit had been sitting on one of those flimsy folding dining¡
  103. room utility tables, with a yellow-pages phone book under it to jack it upì
  104. to the right height.  The keyboard sat on a second folding table, and theì
  105. whole thing was always in imminent danger of toppling over.  What a pleasureì
  106. it is to sit at the new system.
  107.  
  108.      While I'm waxing enthusiastic, let me mention one other thing I did toì
  109. reduce the disarray in the study.  I bought four Wilson-Jones media drawersì
  110. to house my vast collection of floppies.  These diskette cabinets resembleì
  111. professional letter filing cabinets.  A drawer, which can hold more than 100ì
  112. floppies, pulls out on a full suspension track so that one can easily reachì
  113. all the way to the back.  Since there is no top to flip open, units can beì
  114. stacked on top of each other to save a great deal of table space.  Clips areì
  115. provided to secure the units to their neighbors both horizontally andì
  116. vertically.
  117.  
  118.      The only drawback to these disk drawers has been their cost.  Inmac andì
  119. the other major commercial supply houses want more than $60 each!  Butì
  120. Lyben, which sends its catalogs out to many computer hobbyists, offers themì
  121. for only $35.  Extra dividers, which I recommend, are just under $6 perì
  122. package of five.  Lyben can be reached at 313-589-3440 (Michigan).  [Noteì
  123. added at last moment -- I am sorry to say that I just received the new Lybenì
  124. catalog, and the price has now gone up to $45.  Although this is still aì
  125. bargain when compared to other vendors' prices, I'm glad I put in my orderì
  126. when I did.]
  127.  
  128.  
  129.                              ARUNZ VERSION 0.9J
  130.                          (edited for version 0.9n)
  131.  
  132.      Now that I have had my chance to show my excitement over the new stateì
  133. of my computer and computer room, let's get on with the discussion of ARUNZ. ì
  134. First we will discuss the changes introduced since version 0.9G, both theì
  135. old features that have changed and the new features that have beenì
  136. introduced.
  137.  
  138.  
  139. Changes in Old Features
  140. -----------------------
  141.  
  142.      Because, as noted in my last column, ZCPR34 can pass commandsì
  143. containing explicit file types or wildcard characters ('?' and '*'), theì
  144. characters used to define special matching conditions in the alias names inì
  145. ALIAS.CMD had to be changed.  The period, which had been used to indicateì
  146. the beginning of optional characters in the alias name, has been replaced byì
  147. the comma.  The question mark had been used to indicate a wild-characterì
  148. match in the alias name.  Since it can now be an actual character to beì
  149. matched, the underscore has replaced it.
  150.  
  151.      Since the command verb can now include an explicit file type (notì
  152. necessarily COM) and/or a directory prefix, several changes have been madeì
  153. to the parameters that parse the command verb.  In general, all of theì
  154. command line tokens are now treated in the same way; all four token parsingì
  155. parameters ('D', 'U', ':', and '.') now work with digits from 0 to 9 and notì
  156. just 1 to 9.  Thus the command line
  157.  
  158.     C3:TEST>arunz b12:test.z80 commandtail
  159.  
  160. or, with ARUNZ running as the extended command processor (ECP), the command
  161.  
  162.     C3:TEST>b12:test.z80 commandtail
  163.  
  164. will have the following parameter values for token 0, the command verb:
  165.  
  166.     $TD0    B    (Token 0 Drive)
  167.     $TU0    12    (Token 0 User)
  168.     $TN0    TEST    (Token 0 fileName)
  169.     $TT0    Z80    (Token 0 fileType)
  170.  
  171. THIS IS A SIGNIFICANT CHANGE.  PLEASE TAKE CAREFUL NOTE OF IT.  Theì
  172. parameters $TD0 and $TU0 no longer necessarily return the logged-in driveì
  173. and user.  For the standard configuration of ZCPR33 (and 34) a verb of theì
  174. form B12:TEST cannot be passed to the extended command processor; theì
  175. presence of an explicit directory specification results in the immediateì
  176. invocation of the error handler (skipping the ECP) if the file cannot beì
  177. found in the specified directory.  However, if a file type is included, theì
  178. 'bad' command will be passed to the ECP.
  179.  
  180.  
  181. New Features
  182.  
  183.      There are now three new parameters that do return information about theì
  184. directory that was current (logged in) when ARUNZ was invoked.  Theseì
  185. parameters are shown below with their meaning and the values they would haveì
  186. with the example command above:
  187.  
  188.       parameter              meaning            value
  189.       ---------             -------            -----
  190.     $HD        Home Drive (D)              C
  191.     $HU        Home User (U)              3
  192.     $HB        Home Both (i.e., DU)          C3
  193.  
  194.      There is also a new parameter to denote the entire command line,ì
  195. including both the command verb and the command tail.  Many people in theì
  196. past confused "command line" with "command tail" and attempted to use theì
  197. parameter $* for the former.  The new parameter is '$!'.  It is roughlyì
  198. equivalent to '$0 $*', but there is one important difference.  The latterì
  199. parameter expression always includes a space after the command verb, even ifì
  200. there was no tail ('$*' was null).  This space caused problems with someì
  201. commands.  For example, when the SLR assembler SLR180 is invoked withì
  202. nothing after it, it enters interactive mode and allows the user to enter aì
  203. series of assembly requests.  Unfortunately, the code is not smart enough toì
  204. distinguish a completely nonexistent command tail from one with only spaces. ì
  205. When the command "SLR180_" is entered, where '_' represents a blank space,ì
  206. the assembler looks for a source file with a null name.  Not finding it, itì
  207. returns with an error message.
  208.  
  209.      I used to deal with this problem by writing a complex alias of theì
  210. form:
  211.  
  212.     SLR180    if nu $*;asm:slr180;else;asm:slr180 $*;fi
  213.  
  214. With the new parameter, all this complication can be avoided.  The script isì
  215. simply:
  216.  
  217.     SLR180    asm:$!
  218.  
  219. If you are wondering why one would want an alias like this, just wait aì
  220. while.  It will be explained later.
  221.  
  222.      There is also a whole set of new parameters that generate the addressesì
  223. of almost all of the Z System modules.  This capability will becomeì
  224. important with the dynamic Z Systems now being introduced (NZCOM andì
  225. Z3PLUS).  With those systems, the addresses of the RCP, FCP, CCP, and so onì
  226. can all change during system operation.  The new parameters permit one toì
  227. make reference to the addresses of those modules even when they move around. ì
  228. My ALIAS.CMD file described below will have some examples of how theseì
  229. parameters are used.
  230.  
  231.      These parameters begin with $A ('A' for address) and are followed by anì
  232. additional letter as follows:
  233.  
  234.     B    BIOS            L    MCL (command Line)
  235.     C    CCP            M    MSG (message buffer)
  236.     D    DOS            N    NDR
  237.     E    ENV            P    PATH
  238.     F    FCP            R    RCP
  239.     I    IOP            S    STK (shell stack)
  240.                     X    XFCB (external FCB)
  241.  
  242. Amazingly enough, these names are all mnemonic except for the conflict overì
  243. 'M' between the multiple command line buffer (MCL) and message buffer (MSG). ì
  244. I resolved this by using 'L' (think of LINE) for the MCL.
  245.  
  246.      Finally, there is a new symbol that can be used to make a special kindì
  247. of alias name specification in ALIAS.CMD.  If a name element begins with aì
  248. '>', then only the file type of the command verb is used in the comparison. ì
  249. Without this feature one had to use very complex forms to recognize a fileì
  250. type.  For example, suppose you want to be able to enter the name of aì
  251. library file as LBRNAME.LBR as a command and have VLU invoked on it.  Theì
  252. following script used to be required:
  253.  
  254.     ?.LBR=??.LBR=???.LBR=????.LBR=?????.LBR=??????.LBR=
  255.       ???????.LBR=????????.LBR   vlu $0
  256.  
  257. Every possible number of characters in the library name had to be dealt withì
  258. explicitly.  With the new symbol and the other ARUNZ09J features, one canì
  259. define this script more simply as follows:
  260.  
  261.     >LBR    vlu $TN0
  262.  
  263.  
  264. Example ALIAS.CMD File
  265.  
  266.      Now that we have described the new resources available in ARUNZ09J, weì
  267. will begin our look at part of the ALIAS.CMD file that I am using right nowì
  268. on the SB180.  It will be the second half of the file, because that partì
  269. contains some items of immediate relevance.
  270.  
  271.      First some words of philosophy.  There are many ways in which Z Systemì
  272. can be used effectively, and I am always amazed and impressed at theì
  273. different styles developed by different users.  What I will now describe isì
  274. my approach.  As they say, yours may differ!  In any case, I hope theseì
  275. comments will stimulate some good ideas, and, as always, I eagerly awaitì
  276. your comments and suggestions.
  277.  
  278.      I am a strong believer in short search paths.  When I make a mistake inì
  279. typing a command, I do not want to have to twiddle my thumbs while theì
  280. command processor thrashes through a lot of directories searching for theì
  281. nonexistent command.  I want the error handler to take care of it as quicklyì
  282. as possible.  As a result, the search path on my SB180 includes only oneì
  283. directory, A0, the RAM disk.  (With XBIOS, the RAM disk can be mapped to theì
  284. A drive.)
  285.  
  286.      When I enter a command, it is searched for only in A0.  If it is notì
  287. found there, then ARUNZ (renamed to CMDRUN.COM) is loaded from A0, and itì
  288. looks for a script in ALIAS.CMD, also in A0.  If ARUNZ cannot resolve theì
  289. command, then the error handler, EASE in my case, is invoked (you guessedì
  290. it, also on A0).  Thus no directory other than the RAM disk is accessedì
  291. except by an explicit directory reference generated either by an aliasì
  292. script or by a manually entered command.  Everything appears to operateì
  293. instantaneously.
  294.  
  295.  
  296. Aliases to Provide Explicit Directory Prefixes
  297.  
  298.      Obviously, I cannot keep all the COM files that I use in directory A0. ì
  299. In fact, with the tiny RAM disk on the SB180 (and allowing about 100K for aì
  300. BGii swap file), there is barely enough room for CMDRUN.COM (ARUNZ),ì
  301. ALIAS.CMD, EASE.COM, EASE.VAR, IF.COM, ZF.COM (ZFILER), ZFILER.CMD,ì
  302. SAVSTAMP.COM, ZEX.COM, ZEX.RSX, and a few directory programs.  Fortunately,ì
  303. this is all that really needs to be there.
  304.  
  305.      So what do I do about all the other COM files that I want to use? ì
  306. There are two possibilities.  I could invoke them manually with explicitì
  307. directory references, as in "B0:CRC FILESPEC", but this would clearly be aì
  308. nuisance (and contrary to the spirit of Z System!).  The other alternativeì
  309. is to provide alias definitions in ALIAS.CMD for all the commands in otherì
  310. directories that I want to use.
  311.  
  312.      A second half of my ALIAS.CMD file is shown in Listing 1.  The group ofì
  313. aliases at the very end comprises several sets of definitions that do justì
  314. what I have described for several of the directories on the hard disk.  As Iì
  315. use programs in other directories, I add them to the ALIAS.CMD file.
  316.  
  317.      These aliases are included at the end, by the way, so that otherì
  318. definitions can preempt them as desired.  If you look carefully, you willì
  319. see some aliases defined here that are also defined earlier in the ALIAS.CMDì
  320. file.  The earliest definition always takes precedence, because ARUNZ scansì
  321. ALIAS.CMD from the beginning and stops as soon as it encounters a matchingì
  322. name specification.
  323.  
  324.      Directory B0, named SYS, contains most of my system utilities. ì
  325. Directory B1, named ASM, contains my assembly language utilities.  A fewì
  326. commonly used files are in other directories.  The aliases defined in theseì
  327. sections do nothing more than add an explicit directory prefix to theì
  328. command entered.  For example, the script definition
  329.  
  330.     AFIND    b0:$!
  331.  
  332. would take my command line "AFIND TAIL..." and turn it into "B0:AFINDì
  333. TAIL...".  Note how compact the definitions can be.  You do not need aì
  334. separate line for each command.  Similar scripts could be constructed, byì
  335. the way, for COM files kept in COMMAND.LBR and extracted and executed by LX. ì
  336. I do not use LX, so I have no examples to show.
  337.  
  338.      There are several fairly easy ways to automate the construction ofì
  339. these entries in the ALIAS.CMD file.  If you use PMATE or VEDIT as your textì
  340. editor, you can write macros that will perform the entire process.  That isì
  341. how I generated the aliases you see.  With the PMATE macro, I can easilyì
  342. repeat the process from time to time to make sure that all my COM files areì
  343. represented by aliases.    So far I have run my PMATE macro on user areas 0,ì
  344. 1, 2, 3, and 4 of hard disk partition B.
  345.  
  346.      Lacking these tools, you can run "SD *.COM /FX" to get a file DISK.DIRì
  347. containing a horizontally sorted listing of all the COM files in a directoryì
  348. (without going to a lot of trouble, I do not get a sorted listing fromì
  349. PMATE).  Then use your favorite editor, whatever it is, to add carriageì
  350. returns so that each file is on its own line and to delete all of the textì
  351. after the file name (i.e., the dot, file type, and file size).  If there areì
  352. any commands for which you want to have special aliases (we'll see someì
  353. examples shortly), you may delete their names from the list (or you canì
  354. leave them -- they do no harm).  Then close up the list, inserting equalì
  355. signs and, when the line is wide enough, add the command script.  Finally,ì
  356. merge this with the rest of your ALIAS.CMD file.
  357.  
  358.  
  359. Aliases for Special Command Redefinitions
  360.  
  361.      Just before the simple redefinition aliases there are six commands thatì
  362. have been separated out for special treatment.  Consider the first of them:
  363.  
  364.     ZP,ATCH        b0:zpatch $*
  365.  
  366. I find that my fingers have some difficulty typing the full ZPATCHì
  367. correctly, and this alias permits me to enter simply ZP.  Note that in thisì
  368. case we cannot use "b0:$!" for the script because the alias name allows forì
  369. forms other than an exact ZPATCH.  If the script used the $! parameter andì
  370. the command was entered as ZP, then the expanded script would become "B0:ZPì
  371. ...", which would not work.
  372.  
  373.      The alias for crunching is similar in some respects but more elaborate. ì
  374. The letter combination CH must give me trouble, because I often type CRUNCHì
  375. wrong, too, unless I work very carefully.  This alias not only lets me useì
  376. the short form CR; it also allows the command to work with namedì
  377. directories.
  378.  
  379.     CR,UNCH         b0:crunch $td1$tu1:$tf1 $td2$tu2:
  380.  
  381. By expanding the first and second parameters explicitly, named directoryì
  382. references can be converted to the DU: form that CRUNCH can deal with.
  383.  
  384.      The alias for DATSWEEP goes a little further than the other two insofarì
  385. as alternative forms are concerned.
  386.  
  387.     DATSW,EEP=DS=SWEEP    b0:datsweep $*
  388.  
  389. It allows abbreviated forms as short as DATSW, but it additionally allowsì
  390. alternative nicknames for the command, such as DS or the more familiarì
  391. SWEEP, which it replaces on my system.
  392.  
  393.      The next example in this section shows how a program that does not knowì
  394. about Z System file specifications at all can be made to work with themì
  395. anyway.
  396.  
  397.     LDIR        $td1$tu1:;b0:ldir $tn1;$hb:
  398.  
  399. For LDIR I just started to use LDIR-B, which displays date stamp informationì
  400. about files in the library.  Unfortunately, it does not know about namedì
  401. directories; in fact, it does not even know anything about user numbers.  Ifì
  402. he is true to form, Bruce Morgen, the Intrepid Patcher, will soon have aì
  403. ZLDIR-B or an LDRZ-B that will accept full Z System file specs, and I willì
  404. be able to retire this alias.
  405.  
  406.      At present, however, LDIR-B accepts only the standard CP/M syntax forì
  407. files.  As a result, it is not enough simply to pick apart the token, as itì
  408. would be if LDIR would accept the form DU:NAME.TYP.  Instead, the directoryì
  409. specified for the library is logged into, then the LDIR command is run onì
  410. the library name, and finally the original directory is relogged.  This willì
  411. work very nicely unless the user number specified is higher than 15 (andì
  412. your Z33/Z34 is not configured for logging into high user numbers).
  413.  
  414.      The last two examples in this series illustrate still another way toì
  415. make aliases lighten the typing burden.  With XBIOS, alternative versions ofì
  416. the operating system are described in model files.  These typically have aì
  417. file type of MDL, but that type is not required or the default. ì
  418. Consequently, the SYSBLD system-defining utility and the XBOOT system¡
  419. loading utility must be given an explicit file type.  Since I always use MDLì
  420. for the type, I created these aliases to add the file type for me so that Iì
  421. can enter the commands simply as "SYSBLD TEST" or "XBOOT BIGSYS".
  422.  
  423.     SYSBLD            b0:;b0:$0 $1.mdl;$hb:
  424.     BOOT=XBOOT        b0:;b0:xboot $1.mdl
  425.  
  426. The XBOOT alias lets me save a little typing by omitting the leading 'X' ifì
  427. I wish.  The SYSBLD alias returns to the original directory when it isì
  428. finished.  Since XBOOT coldboots a new operating system, any trailingì
  429. commands are lost anyway.  The XBOOT command will soon support a warmbootì
  430. mode, in which, like NZCOM and Z3PLUS, the new system is created withoutì
  431. affecting the multiple command line, shell stack, or other loaded systemì
  432. modules that have not changed their address or size.  I might then add anì
  433. alias REBOOT or WBOOT (warmboot) that will load a new system and return toì
  434. the original directory.
  435.  
  436.  
  437. Memory Display Aliases
  438.  
  439.      In my system development work I often have occasion to examine variousì
  440. parts of memory.  I might want to look at the beginning of the BIOS to checkì
  441. the hooks into an RSX (resident system extension), or I might want to seeì
  442. the contents of the ZCPR3 message buffer to see how some flags are beingì
  443. used.
  444.  
  445.      I used to have a set of aliases like these with explicit addresses inì
  446. the script ("P FE00" to look at the ENV, for example).  This relieved myì
  447. mind of the task of remembering the addresses where these modules wereì
  448. located in memory.  With the new dynamic systems, even a good memory willì
  449. not suffice, since the modules can move around, and one can not easily beì
  450. sure just where they are at any given time.
  451.  
  452.      By using the new parameters that I described earlier, the scriptsì
  453. always have the correct addresses.  [Actually, they can still be fooled ifì
  454. these parameters are used in multiple-command-line scripts that include theì
  455. loading of a new dynamic system.  As I warned in my earlier article onì
  456. ARUNZ, all parameters are expanded at the time the alias is invoked.  If theì
  457. system is changed after that, the parameter values may no longer be correctì
  458. when that part of the script actually runs.]
  459.  
  460.  
  461. =============================================================================
  462.  
  463.  
  464.  ; Memory display aliases
  465.  
  466. PBIOS=BIOS        p $ab
  467. PCCP=CCP=CPR        p $ac
  468. PDOS=DOS        p $ad
  469. PENV=ENV        p $ae
  470. PFCP=FCP        p $af
  471. PIOP=IOP        p $ai
  472. PMCL=MCL        p $al
  473. PMSG=MSG        p $am
  474. PNDR=NDR        p $an
  475. PPATH            p $ap
  476. PRCP=RCP        p $ar
  477. PSHL=PSHELL=SHL=SHELL    p $as
  478. PXFCB=XFCB=PFCB=FCB    p $ax
  479.  
  480.  ; Special equivalents
  481.  
  482. ZP,ATCH            b0:zpatch $*
  483. CR,UNCH             b0:crunch $td1$tu1:$tf1 $td2$tu2:
  484. DATSW,EEP=DS=SWEEP    b0:datsweep $*
  485. LDIR            $td1$tu1:;b0:ldir $tn1;$hb:
  486. SYSBLD            b0:;b0:$0 $1.mdl;$hb:
  487. XBOOT=BOOT        b0:;b0:xboot $1.mdl
  488.  
  489.  ; Complete set of direct equivalents
  490.  
  491. CMDRUN=LPUT=EDIT0=ERA=IF=REN=SD=SDD=XD=ZEX=ZF=VLU=W=ZPATCH=COPY=ECHO    b0:$!
  492. FF=GOTO=JF=JETLDR87=NULU=PWD=SAVE=SP=UNCR=VTYPE=XDIR=AFIND=SALIAS=AREA    b0:$!
  493. BD=CRUNCH=DFA=DIFF=DISKRST=DOSERR=DU=EDITNDR=ERRSET=HSH=ALIAS        b0:$!
  494. LLF=LGET=LOADNDR=LPUT14=LT23=LUSH=LX=MOVE=MU3=PATH=PAUSE=PIP=PROT    b0:$!
  495. PROTCCP=PUBLIC=PUTDS=Q=SAP=SAVENDR=SAVSTAMP=SFA=SHCTRL=SHOW=SQ=STAT    b0:$!
  496. SUB=SYSGEN=UF=UNERASE=XSUB=DATE=DATSWEEP=MKDIR=SHSET=TPA=Z3INS=Z3LOC    b0:$!
  497. ZRIP=ASSGN=BSX=FVCD=HDINIT=HDUTIL=MDINIT=MPTEST=SETDFLT=STARTHD4=SWX    b0:$!
  498. SYSBLD=XSYSGEN=TIME=XBOOT0=XVERS=MCOPY=LZED=PUTBG=STARTHD=STARTHD1    b0:$!
  499. STRTFULL=LDR=JETLDR=LHC=SSTAT=XBOOT=MAP=STARTBIG=LT=LDIR=QL=SETD=CRC    b0:$!
  500. 4ERA=4MU3=4REN=4SAVE=T4MAKE=DOSVER=DRO=LOGGED=SRO=SRW=LBREXT        b0:$!
  501.  
  502. SLR180+=SLRNK=SLRNK+=Z80ASM=DDT=DSDZ=FORM7=MAKESYM=MLOAD=SLRMAC=XIZ    b1:$!
  503. ZAS=ZLINK=ZXLATE=SLR180=180FIG32=180FIG+=LNKFIG+=SLRIB=ZLIB=ZREF    b1:$!
  504. ZZCNFG=LNKFIG=180FIG                            b1:$!
  505.  
  506. BGSERIAL=LOADBG=STARTBG=BGPRINT=BGPRNCFG=DSCONFIG=Q=REMOVE=SECURE    b2:$!
  507. SETBG=SPOOLER=DATSWEEP=SDD=SETTERM                    b2:$!
  508.  
  509. INSTALL=MEX                                b3:$!
  510.  
  511. WSCHANGE=WS=WINSTALL=MOVEPRN                        b4:$!
  512. Listing 1.  The second half of the ALIAS.CMD file from my SB180 with XBIOS,ì
  513. slightly shortened and rearranged.
  514.  
  515. =============================================================================
  516.  
  517.                        Shells and WordStar Release 4
  518.  
  519.  
  520.      As I noted in an earlier column, WordStar Release 4 was a very excitingì
  521. event for the CP/M world in general and the Z-System world in particular. ì
  522. It was the first major commercial program to recognize Z System and to makeì
  523. use of its features.  Unfortunately, the Z System code in WS4 was notì
  524. adequately tested, and many errors, some quite serious, slipped through. ì
  525. Some of the most significant errors concern WS4's operation as a ZCPR3ì
  526. shell.
  527.  
  528.      Let's begin with a little background on the concept of a shell in ZCPR. ì
  529. Normally, during Z System operation the user is prompted for command lineì
  530. input.  This input may consist of a string of commands separated byì
  531. semicolons.  When the entire sequence of commands has been completed and theì
  532. command line buffer is again empty, the user would be prompted again forì
  533. input.
  534.  
  535.      This prompting is performed by the ZCPR command processor, which,ì
  536. because it is limited in size to 2K, is correspondingly limited in itsì
  537. power.  Richard Conn, creator of ZCPR, had the brilliant idea of including aì
  538. facility in ZCPR3 for, in effect, replacing -- or, perhaps better said,ì
  539. augmenting -- the command processor as a source of commands for the system. ì
  540. This is the shell facility.
  541.  
  542.      Under ZCPR3, when the command processor finds that there are no moreì
  543. commands in the command line buffer for it to perform, before it prompts theì
  544. user for input, it first checks a memory buffer called the shell stack.  Ifì
  545. it finds a command line there, it executes that command immediately, withoutì
  546. prompting the user for input.  The program run in that way is called aì
  547. shell, because it is like a shell around the command processor kernel.  Theì
  548. shell is what the user sees instead of the command processor, and the shellì
  549. will normally get commands from the user and pass them to the commandì
  550. processor.  In effect, the outward appearance of the operating system can beì
  551. changed completely when a shell is selected.
  552.  
  553.      A perfect example of a shell is the EASE history shell.  To the user itì
  554. looks rather like the command processor.  But there are two very importantì
  555. differences.  First of all, the command line editing facilities are greatlyì
  556. augmented.  One can move the cursor left or right by characters, words, orì
  557. commands; one can insert new characters or enter new characters on top ofì
  558. existing characters; characters or words can be deleted.  One has, in a way,ì
  559. a wordprocessor at one's disposal in creating the command line.
  560.  
  561.      The second feature is the ability to record and recall commands in aì
  562. history file.  Many users find that they execute the same or similarì
  563. commands repeatedly.  The history feature of EASE makes this veryì
  564. convenient.  These two command generation features require far too much codeì
  565. to include in the command processor itself, so it is very convenient to haveì
  566. the shell capability.
  567.  
  568.      Programs designed to run as shells have to include special code toì
  569. distinguish when they have been invoked by the user and when they have beenì
  570. invoked by the command processor.  ZCPR3 makes this information available toì
  571. such programs.  When invoked by the user, they simply write the appropriateì
  572. command line into the shell stack so that the next time the commandì
  573. processor is ready for new input, the shell will be called on.  After that,ì
  574. the user sees only the shell.  Shells normally have a command that the userì
  575. can enter to turn the shell off.
  576.  
  577.      ZCPR3 goes beyond having just a single shell; it has a stack of shells. ì
  578. A typical configuration allows four shell commands in the stack.  When theì
  579. user invokes a command designed to run as a shell, it pushes its name ontoì
  580. the stack.  When the user cancels that shell, any shell that had beenì
  581. running previously comes back into force.  Only when the last shell commandì
  582. has been cancelled (popped from the shell stack) does the user see theì
  583. command processor again.
  584.  
  585.      Let's look at some of the shells that are available under Z System.  Weì
  586. have already mentioned the EASE history shell.  There is also the HSHì
  587. history shell, which offers similar capabilities.  It was written in C andì
  588. 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ì
  589. is especially true because EASE can do double service as an error handler asì
  590. well, with the identical command line editing interface.
  591.  
  592.      Then there are the menu shells, programs that allow the user with justì
  593. a few keystrokes to initiate desired command sequences.  They come inì
  594. several flavors.  MENU stresses the on-screen menu of command choicesì
  595. associated with single keystrokes.  VFILER and ZFILER stress the on-screenì
  596. display of the files on which commands will operate; the commands associatedì
  597. with keys are not normally visible.  Z/VFILER offer many internal fileì
  598. maintenance commands (copy, erase, rename, move, archive).  VMENU andì
  599. FMANAGER are inbetween.  Both the files in the directory and the menu ofì
  600. possible commands are shown on the screen.
  601.  
  602.  
  603. What Kind of Programs Should be Shells?
  604.  
  605.      Not all programs should be shells.  From a strict conceptual viewpoint,ì
  606. only programs that are intended to take over the command input function fromì
  607. the command processor on a semipermanent basis should be shells.  Theì
  608. history shells and the MENU and VMENU type shells clearly qualify.  Oneì
  609. generally enters those environments for the long haul, not just for a quickì
  610. command or two.
  611.  
  612.      ZFILER and VFILER are marginal from this viewpoint.  One generallyì
  613. enters them to perform some short-term file maintenance operations, afterì
  614. which one exits to resume normal operations.  It is rare, I believe, toì
  615. reside inside ZFILER or VFILER for extended periods of time, though I amì
  616. sure there are some users who do so.
  617.  
  618.      Many people (I believe mistakenly) try to set up as shells any programì
  619. from which they would like to run other tasks and automatically return. ì
  620. This is the situation with WordStar.  No one will claim that the mainì
  621. function of WordStar is to generate command lines!  Clearly it is intendedì
  622. to be a file editor.  Why, then, was it made into a ZCPR3 shell in the firstì
  623. place?  I'm really not sure.
  624.  
  625.      WordStar's 'R' command really does not offer very much.  In neither theì
  626. ZCPR nor the CP/M configuration does any information about the operatingì
  627. environment seem to be retained.  For example, one might expect on return toì
  628. WordStar that the control-r function would be able to recall the mostì
  629. recently specified file name.  But this does not seem to be the case,ì
  630. although it could easily have been done.  In the ZCPR version, the nameì
  631. could be assigned to one of the four system file names in the environmentì
  632. descriptor; in the CP/M version it could be kept in the RSX code at the topì
  633. of the TPA that enables WordStar to be reinvoked after a command isì
  634. executed.
  635.  
  636.      The WordStar 'R' command does not save any time, either.  Essentiallyì
  637. no part of WordStar remains in memory.  The user could just as well use theì
  638. 'X' command to leave WordStar, run whatever other programs he wished, andì
  639. then reinvoke WS.  Nevertheless, I can understand why users would enjoy theì
  640. convenience of a command like the 'R' command that automatically brings oneì
  641. back to WordStar.  Shells, however, are not the way to do this, at least notì
  642. shells in the ZCPR3 sense.
  643.  
  644.  
  645. ZCPR2-Style Shells
  646.  
  647.      In ZCPR2 Richard Conn had already implemented an earlier version of theì
  648. shell concept which, interestingly enough, would be the appropriate way forì
  649. WordStar and perhaps even ZFILER/VFILER to operate.  He did not have a shellì
  650. stack, but he did have programs like MENU that, when they generatedì
  651. commands, always appended their own invocation to the end of the commandì
  652. line.  Thus if the menu command script associated with the 'W' key was "WSì
  653. fn2", where fn2 represents system file name #2, then the actual commandì
  654. placed into the command line buffer would be "WS fn2;MENU".  In this way,ì
  655. after the user's command ran, the MENU program would come back.
  656.  
  657.      Let's compare how the two shell schemes would have worked withì
  658. WordStar.  Suppose we want to edit the file MYTEXT.DOC and then copy it toì
  659. our archive disk with the command "PPIP ARCHIVE:=MYTEXT.DOC".  We might haveì
  660. created the following alias script for such operations:
  661.  
  662.     WSWORK    ws $1;ppip archive:=$1
  663.  
  664. Then we just enter the command "WSWORK MYTEXT.DOC" when we want to work on theì
  665. file and have it backed up automatically when we are done.
  666.  
  667.      Here is what WS4 does as a ZCPR3-type shell.  The command line starts outì
  668. as:
  669.  
  670.     WSWORK MYTEXT.DOC
  671.  
  672. When the alias WSWORK is expanded the command line becomes:
  673.  
  674.     WS MYTEXT.DOC;PPIP ARCHIVE:=MYTEXT.DOC
  675.  
  676. When WordStar runs, it pushes its name onto the shell stack so that it will beì
  677. invoked the next time the command line is empty.  Noting that the command lineì
  678. is not empty, it returns control to the command processor.  Then the PPIPì
  679. command is executed, backing up our unmodified file (horrors!!!)  Finally theì
  680. command line is empty and WS, as the current shell, starts running.  Since itì
  681. was invoked as a shell, it prompts the user to press any key before it clearsì
  682. the screen to start editing.  By this time it has forgotten all about the fileì
  683. we designated and it presents us with the main menu.  All in all, a ratherì
  684. foolish and useless way to go about things.
  685.  
  686.      You might think that the problem would be solved if WS did not check forì
  687. pending commands but went ahead immediately with its work.  Indeed, this wouldì
  688. work fine until the 'R' command was used.  Then either the pending PPIP commandì
  689. would be lost (replaced by the command generated by the 'R' operation) orì
  690. executed (if the 'R' command appended it to the command it generated).  Inì
  691. either case we have disaster!
  692.  
  693.      Now suppose WS4 had used the ZCPR2-style shell concept.  After the aliasì
  694. had been expanded, the "WS MYTEXT.DOC" command would run, and we would edit ourì
  695. file.  While in WS4, suppose we want to find where on our disks we have filesì
  696. with names starting with OLDTEXT.  We use the 'R' command to enter the commandì
  697. line "FF OLDTEXT".  The 'R' command would append ";WS" to the end the commandì
  698. we entered and insert it into the command line buffer before the currentì
  699. pointer, leaving the following string in the buffer:
  700.  
  701.     FF OLDTEXT;WS;PPIP ARCHIVE:=MYTEXT.DOC
  702.  
  703. After the FF command was finished, WordStar would be executed again.  Just whatì
  704. we wanted.
  705.  
  706.      In fact, under ZCPR3 WS could be much cleverer than this.  First of all,ì
  707. it could determine from the external file control block the name (and under Z33ì
  708. the directory) used to invoke WordStar in the first place.  There would be noì
  709. need, as there is now, to configure WS to know its own name and to make sureì
  710. that the directory with WS is on the command search path.  The 'R' commandì
  711. could have appended "B4:WSNEW" if WSNEW had been its name and it had beenì
  712. loaded from directory B4.
  713.  
  714.      There is one problem, however.  We would really like WS to wait beforeì
  715. clearing the screen and obliterating the results of the FF command.  With theì
  716. ZCPR3-type shell, WS can determine from a flag in the ZCPR3 message bufferì
  717. whether it was invoked as a shell.  For the ZCPR2-style shell we would have toì
  718. include an option on the command line.  WS could, for example, recognize theì
  719. command form "WS /S" as a signal that WS was running as a shell.  It would thenì
  720. wait for a key to be pressed before resuming, just as under a ZCPR3-styleì
  721. shell.  Of course, you would not be able to specify an edit file with the nameì
  722. "/S" from the command line in this case, but that is not much of a sacrifice orì
  723. restriction.
  724.  
  725.      We could continue to work this way as long as we liked.  Only when weì
  726. finally exited WS with the 'X' command would the PPIP command run.  This, ofì
  727. course, is just the right way to operate!
  728.  
  729.  
  730. ZCPR2 vs ZCPR3 Shell Tradeoffs
  731.  
  732.      Once I started thinking about the old ZCPR2-type shells, I began to wonderì
  733. why one would ever want a ZCPR3-type shell.  At first I thought that Z2-styleì
  734. shells could not be nested, but that does not seem to be the case.  Suppose weì
  735. run MENU and select the 'V' option to run VFILER.  The command line at thatì
  736. point would be
  737.  
  738.     VFILER;MENU /S
  739.  
  740. where we have assumed that a "/S" option is used to indicate invocation as aì
  741. shell.  While in VFILER we might run a macro to crunch the file we are pointingì
  742. to.  The macro could spawn the command line "CRUNCH FN.FT".  The command lineì
  743. buffer would then contain
  744.  
  745.     CRUNCH FN.FT;VFILER /S;MENU /S
  746.  
  747. After the crunch is complete, VFILER would be reentered.  On exit from VFILERì
  748. with the 'X' command, MENU would start to run.  Thus nesting is not onlyì
  749. possible with Z2-type shelling, it is not limited by a fixed number of elementsì
  750. in the shell stack as in ZCPR3 (the standard limit is 4).  Only the size of theì
  751. command line buffer would set a limit.
  752.  
  753.      What disadvantages are there to the Z2-style shell?  Well, I'm afraid thatì
  754. I cannot come up with much in the way of substantial reasons.  The shell stackì
  755. provides a very convenient place to keep status information for a program.  Iì
  756. do that in ZFILER so that it can remember option settings made with the 'O'ì
  757. command.  On the other hand, this information could be kept as additional flagsì
  758. on the command line, as with the "/S" option flag.  There is no reason why theì
  759. information could not be stored even in binary format, except that the nullì
  760. byte (00 hex) would have to be avoided.
  761.  
  762.      If the 128 bytes currently set aside for the shell stack were added to theì
  763. multiple command line buffer, the use of memory would be more efficient than itì
  764. is now with Z3-style shells.  Z3 shells use shell stack memory in fixed blocks;ì
  765. with Z2 shells the space would be used only as needed.  I rarely have more thanì
  766. one shell running, which means that most of the time 96 bytes of shell stackì
  767. space are totally wasted.  Of course, with the present setup of ZCPR3, theì
  768. multiple command line buffer cannot be longer than 255 bytes, because the sizeì
  769. value is stored in the environment descriptor as a byte rather than as a word. ì
  770. The command line pointer, however, is a full word, and so extension to longerì
  771. command lines would be quite possible (I'll keep that in mind for Z35!).
  772.  
  773.      Following this line of reasoning, I am coming to the conclusion that onlyì
  774. programs like history shells and true menu shells should be implemented asì
  775. ZCPR3-style shells.  Other programs, like ZFILER and WordStar should use theì
  776. ZCPR2 style.  If I am missing some important point here, I hope that readersì
  777. will write in to enlighten me.
  778.  
  779.  
  780. Forming a Synthesis
  781.  
  782.      So long as the command line buffer is fixed at its present length and soì
  783. long as 128 bytes are set aside as a shell stack, one should make the best ofì
  784. the situation.  Rob Wood has come up with a fascinating concept that does justì
  785. that.
  786.  
  787.      Rob was working on Steve Cohen's W (wildcard) shell.  He recognized thatì
  788. on many occasions one wants to perform a wildcarded operation followed by someì
  789. additional commands (just as with the WordStar example followed by PPIP).  As aì
  790. ZCPR3-type shell, W could not do this.  It always executed what it was supposedì
  791. to do after the wild operation before the wild operation!
  792.  
  793.      Rob came up with a brilliant way to combine the ZCPR2 and ZCPR3 shellì
  794. concepts.  When his version of W is invoked manually by the user, it pushes itsì
  795. name, as a good ZCPR3 shell does, onto the shell stack.  But it does not thenì
  796. return to the command processor to execute commands pending in the commandì
  797. line.  It starts running immediately, doing the thing it was asked to do andì
  798. using the shell stack entry to maintain needed data.
  799.  
  800.      In the course of operation, however, it does one unusual thing.  Afterì
  801. each command that it generates and passes to the command line buffer, itì
  802. appends its own name, as a good ZCPR2 shell does.  This command serves as aì
  803. separator between the shell-generated commands and those that were on theì
  804. original command line after the W command.  After the shell-generated commandsì
  805. have run, W starts to run.  It checks the top of the shell stack, and if itì
  806. finds its own name there, it says "Aha, I'm a shell," and proceeds to use theì
  807. information in the shell stack to generate the next set of commands.  Thisì
  808. process continues until W has no more work to do.  Then it pops its name offì
  809. the shell stack and returns to the command processor.  The commands originallyì
  810. included after the W command are still there and now execute exactly asì
  811. intended.  Beautiful!
  812.  
  813.  
  814. WordStar Shell Bugs
  815.  
  816.      It is bad enough that WordStar's conceptual implementation as a shell isì
  817. flawed.  On top of that, the shell code was not even written correctly.  Theì
  818. person who wrote the code (not MicroPro's fault, I would like to add) tried toì
  819. take a short cut and flubbed it.  When a shell installs itself, it shouldì
  820. always -- I repeat, always -- push itself onto the stack.  WordStar tries toì
  821. take the following shortcut.  If it sees that the shell stack is currentlyì
  822. empty, it just writes its name into the first entry, leaving the other entriesì
  823. as they were.
  824.  
  825.      When WordStar terminates, however, it pops the stack.  At this pointì
  826. whatever junk was in the second shell stack entry becomes the currently runningì
  827. shell.  The coding shortcut (which I would think took extra code rather thanì
  828. less code, but that is beside the point) assumed that if the current shellì
  829. stack entry was null, all the others would be, too.  But this need not be theì
  830. case at all.  And in many cases it has not in fact been the case, and veryì
  831. strange behavior has been observed with WordStar.  Some users have reportedì
  832. that WordStar works on their computers only if invoked from a shell!  That isì
  833. because WordStar properly pushes itself onto the stack in that case.
  834.  
  835.      There are basically two strategies one can take for dealing with the shellì
  836. problems in WordStar.  One is to fix the above problem and live with the otherì
  837. anomalies (just don't ever put commands after WS in a multiple command line). ì
  838. The other is to disable the shell feature entirely.
  839.  
  840.      To fix the bug described above, Rick Charnes wrote a program calledì
  841. SHELLINI to initialize the shell stack before using WordStar.  On bulletinì
  842. boards in the past both Rick and I presented aliases that one can use toì
  843. disable the shell stack while WS is running and to reenable it after WS hasì
  844. finished.  I will now describe patches that can be made directly to WordStarì
  845. itself.  First I will explain what the patches do; later I will discuss how toì
  846. install them.
  847.  
  848.      Listing 2 shows a patch I call WSSHLFIX that will fix the bug justì
  849. described.  The code assumes that you do not already have any initialization orì
  850. termination patches installed.  If you do, you will have to add the routinesì
  851. here to the ones you are already using.
  852.  
  853.      The patch works as follows.  When WS starts running, the initializationì
  854. routine is called.  It extracts the shell stack address from the ENV descriptorì
  855. and goes there to see if a shell command is on the stack.  If there is, noì
  856. further action is required, since WS already works correctly in this case.  If,ì
  857. on the other hand, the first shell entry is null, then the routine calculatesì
  858. the address of the beginning of the second shell entry and places a zero byteì
  859. there.  When this stack entry is popped later, it will be inactive.
  860.  
  861.      Listing 3 shows a patch I call WSSHLOFF that will completely disable theì
  862. shell feature of ZCPR3 while WS is running.  It works as follows.  When WSì
  863. starts running, the initialization routine is called.  It gets the number ofì
  864. shell stacks defined for the user's system in the ENV descriptor and saves itì
  865. away in the termination code for later restoration.  Then it sets the value toì
  866. 0.  WordStar later checks this value to see if the shell feature is enabled inì
  867. ZCPR3.  Since WordStar thinks that there is no shell facility, it operates theì
  868. 'R' command as it would under CP/M.  Later, on exit from WS, the terminationì
  869. routine restores the shell-stack-number so that normal shell operation willì
  870. continue upon exit from WS.
  871.  
  872.      The easiest way to install these patches is to assemble them to HEX filesì
  873. and use the following MLOAD command (MLOAD is a very useful program availableì
  874. from remote access systems such as Z Nodes):
  875.  
  876.     MLOAD WS=WS.COM,WSSHLxxx
  877.  
  878. Substitute the name you use for your version of WordStar and the name of theì
  879. patch you want to install.  That's it; you're all done.
  880.  
  881.      If you do not have MLOAD, you can install the patches using the patchingì
  882. feature in WSCHANGE.  From the main menu select item C (Computer), and fromì
  883. that menu select item F (Computer Patches).  From that menu, work through itemsì
  884. C (initialization subroutine), D (un-initialization subroutine), and E (generalì
  885. patch area), installing the appropriate bytes listed in Table 1.
  886.  
  887.  
  888. Summary
  889.  
  890.      We have covered a lot of material this time.  The issue of shells is aì
  891. very tricky one, and I hope to hear from readers with their comments.  I wouldì
  892. also enjoy learning about interesting ARUNZ aliases that you have created.
  893.  
  894.  
  895. =============================================================================
  896.  
  897. ; Program:    WSSHLFIX
  898. ; Author:    Jay Sage
  899. ; Date:        March 26, 1988
  900.  
  901. ; This code is a configuration overlay to correct a problem in the shell
  902. ; handling code in WordStar Release 4.
  903. ;
  904. ; Problem:  WS takes a mistaken shortcut when installing its name on the shell
  905. ; stack.  If the stack is currently empty, it does not bother to push the
  906. ; entries up.  However, when it exits, it does pop the stack, at which point
  907. ; any garbage that had been in the stack becomes the active shell.  This patch
  908. ; makes sure that the second stack entry is null in that case.
  909.  
  910. ;---- Addresses
  911.  
  912. initsub    equ    03bbh
  913. exitsub    equ    03b3h
  914. morpat    equ    045bh
  915.  
  916. ;---- Patch code
  917.  
  918.     org    initsub        ; Initialization subroutine patch
  919.  
  920. init:    jp    initpatch
  921.  
  922. ;----
  923.  
  924.     org    morpat        ; General patch area
  925.  
  926. initpatch:            ; Initialization patch
  927.     ld    hl,(109h)    ; Get ENV address
  928.     ld    de,1eh        ; Offset to shell stack address
  929.     add    hl,de        ; Pointer th shell stack address in HL
  930.     ld    e,(hl)        ; Address to DE
  931.     inc    hl
  932.     ld    d,(hl)
  933.     ld    a,(de)        ; See if first entry is null
  934.     or    a
  935.     ret    nz        ; If not, we have no problem
  936.     inc    hl        ; Advance to ENV pointer to
  937.     inc    hl        ; ..size of stack entry
  938.     ld    l,(hl)        ; Get size into HL
  939.     ld    h,0
  940.     add    hl,de        ; Address of 2nd entry in HL
  941.     ld    (hl),0        ; Make sure that entry is null
  942.     ret
  943.  
  944.     end
  945.  
  946. Listing 2.  Source code for a patch to fix the bug in the coding of shell
  947. stack pushing and popping in WordStar Release 4.
  948.  
  949. =============================================================================
  950.  
  951. ; Program:    WSSHLOFF
  952. ; Author:    Jay Sage
  953. ; Date:        March 26, 1988
  954.  
  955. ; This code is a configuration overlay to correct a problem in the shell
  956. ; handling code in WordStar Release 4.
  957. ;
  958. ; Problem:  Because WordStar runs as a ZCPR3 shell, it is impossible to use
  959. ; WS in a multiple command line with commands intended to execute after WS is
  960. ; finished.  One can disable this by patching the ZCPR3 environment to show
  961. ; zero entries in the shell stack while WS is running.  This effectively
  962. ; disables WS4's shell capability.  Unfortunately, it means that the extended
  963. ; features of the 'R' command under ZCPR3 are also lost.
  964.  
  965. ;---- Addresses
  966.  
  967. initsub    equ    03bbh
  968. exitsub    equ    03beh
  969. morpat    equ    045bh
  970.  
  971. ;---- Patch code
  972.  
  973.     org    initsub        ; Initialization subroutine
  974.  
  975. init:    jp    initpatch
  976.  
  977. ;----
  978.  
  979.     org    exitsub        ; Un-initialization subroutine
  980.  
  981. exit:    jp    exitpatch
  982.  
  983. ;----
  984.  
  985.     org    morpat        ; General patch area
  986.  
  987. initpatch:            ; Initialization patch
  988.     call    getshls        ; Get pointer to shell stack number
  989.     ld    a,(hl)        ; Get number
  990.     ld    (shstks),a    ; Save it for later restoration
  991.     ld    (hl),0        ; Set it to zero to disable shells
  992.     ret
  993.  
  994. exitpatch:            ; Termination patch
  995.     call    getshls        ; Get pointer to shell stack number
  996. shstks    equ    $+1        ; Pointer for code modification
  997.     ld    (hl),0        ; Value supplied by INITPATCH code
  998.     ret
  999.  
  1000. getshls:
  1001.     ld    hl,(109h)    ; Get ENV address
  1002.     ld    de,20h        ; Offset to number of shell entries
  1003.     add    hl,de        ; HL points to number of shell entries
  1004.     ret
  1005.  
  1006.     end
  1007.  
  1008.  
  1009. Listing 3.  Source code for a patch that disables the shell feature of
  1010. ZCPR3 while WordStar 4 is running and reenables it on exit.
  1011.  
  1012. =============================================================================
  1013.  
  1014. WSSHLFIX patch bytes:
  1015.  
  1016.   initialization subroutine:    C3 5B 04
  1017.  
  1018.   un-initialization subroutine:    00 00 C9  (should be this way already)
  1019.  
  1020.   general patch area:        2A 09 01 11 1E 00 19 5E 23 56 1A
  1021.                 B7 C0 23 23 6E 26 00 19 36 00 C9
  1022.  
  1023.  
  1024. WSSHLOFF patch bytes
  1025.  
  1026.   initialization subroutine:    C3 5B 04
  1027.  
  1028.   un-initialization subroutine:    C3 65 04
  1029.  
  1030.   general patch area:        CD 6B 04 7E 32 69 04 36 00 C9 CD 6B
  1031.                 04 36 00 C9 2A 09 01 11 20 00 19 C9
  1032.  
  1033.  
  1034. Table 1.  List of HEX bytes for installing either of the patches into
  1035. WordStar Release 4 to deal with the problems in the shell code.
  1036.  
  1037.