home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / ZCPR33 / TCJ / TCJ33.WS < prev    next >
Text File  |  2000-06-30  |  51KB  |  1,031 lines

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