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 / JSAGE / ZSUS / TCJ / TCJ35.WS < prev    next >
Text File  |  2000-06-30  |  29KB  |  528 lines

  1.                                Z-System Corne≥ (c)
  2.                                  by Jay Sage
  3.                         The Computer Journal, Issue 35
  4.                           Reproduced with permission
  5.                            of author and publisher
  6.  
  7.      My column about shells and WordStar Release 4 (WS4) in TCJ issue #33ì
  8. prompted more than the usual level of commentary.  There were extensiveì
  9. discussions on Z-Node-Central and the Lillipute Z-Node (the official TCJì
  10. bulletin board), and several messages reached me over the ARPA network.  Notì
  11. all of the comments were favorable, but I was nevertheless happy to receiveì
  12. them.  They helped further clarify my thinking on the very important subjectì
  13. of shells and have spurred me on to prove my points by actually convertingì
  14. WS4 to a ZCPR2-style shell!  After a bit of follow-up discussion, I willì
  15. describe how this conversion was accomplished.
  16.  
  17.  
  18.                                 Corrections
  19.  
  20.      There were some things I said in the previous column that wereì
  21. factually wrong, and before I do anything else I wish to correct them.
  22.  
  23.      First, I stated that the Z-System code in WS4 was written by someoneì
  24. other than MicroPro.  I was wrong.  David McCord, who was vice president atì
  25. Echelon at the time WS4 was developed, sent me a message with the facts ofì
  26. this matter.  Echelon, through staff like David and through publishedì
  27. materials, educated Peter Mireau of MicroPro on the facilities andì
  28. philosophy of Z-System.  Peter did all the actual programming, so the codingì
  29. mistakes were his fault, not Echelon's or David's.
  30.  
  31.      From a broader perspective, however, as I stated in the previousì
  32. column, the real culprit was inadequate testing.  Bugs in the code wouldì
  33. have been discovered and conceptual issues clarified had more people in theì
  34. Z community been involved as beta testers.  There are so many differentì
  35. styles of using Z-System that it takes a number of testers to uncoverì
  36. problems.  Within days after copies of WS4 were delivered to users of my Z¡
  37. Node, I started getting questions about strange behavior exhibited by WS4,ì
  38. behavior that turned out to result from its operation as a shell.
  39.  
  40.      A second mistake in the earlier column was my implication that WS4 doesì
  41. not get its own name from the ZCPR3 external file control block (XFCB).  Iì
  42. no longer remember what made me think that this was the case, but Davidì
  43. McCord assured me (and I have now verified for myself) that WS4 does,ì
  44. indeed, get its name from the XFCB when it sets up the shell stack entry.
  45.  
  46.      Finally, one reader reported to me that my WSSHLOFF routine (the oneì
  47. that completely disables shells while WS4 is running and reenables them whenì
  48. WS4 terminated) crashed his system.  Unfortunately, a large number ofì
  49. misprints crept into the listings in going from my disk file to the printedì
  50. pages.  Most of the typos were obvious, but one was compounded by a doubleì
  51. error.  In the WSSHLOFF listing, the value for EXITSUB was printed as 03BVh. ì
  52. The 'V' was obviously a mistake, and clever readers looked at the similarìèlisting for WSSHLFIX, where the value was given as 03B3h.  This,ì
  53. regrettably, looks correct but was also a typo.  The proper value is 03BEh. ì
  54. We hope that Art Carlson will make sure that the listings in this column areì
  55. transcribed accurately (so that all the mistakes will be mine!).
  56.  
  57.  
  58.                              More WS4 Comments
  59.  
  60.      While on the subject of WS4, I would like to add a few further commentsì
  61. about how it works.  Not surprisingly (considering when it was developed),ì
  62. in creating its shell stack entry WS4 does not make use of the facilityì
  63. introduced with ZCPR version 3.3 that allows a program to determine from theì
  64. XFCB not only its name but also the directory from which it was actuallyì
  65. loaded (the user number is at offset 13 and the drive, with A=1, at offsetì
  66. 14).
  67.  
  68.      As a result, in order for WS4 to be reinvoked as a shell, the commandì
  69. search path must include the directory in which WS4 is located.  I mentionì
  70. this here as a reminder and suggestion to authors of new or updated shellsì
  71. and error handlers that they use this Z33 facility to avoid the requirementì
  72. that the program be on the path and to speed up loading of the program (byì
  73. eliminating any search for it).  My WordStar conversion described later addsì
  74. this feature.
  75.  
  76.      With WS4 it is generally necessary that the command search path includeì
  77. WS4's directory for an additional reason.  I learned the hard way that whenì
  78. WS4 runs under Z-System, it pays no attention to the drive and user numberì
  79. that WSCHANGE specified as the location for the overlay files; it only usesì
  80. the search path to try to locate them.
  81.  
  82.      This is a problem for me because, as I have explained at length inì
  83. previous columns, I put only my small RAM disk on the path and use ARUNZì
  84. aliases to invoke all programs except the very few that fit on the RAM disk. ì
  85. With this approach, there is no way to get WS4 to find its overlay files. ì
  86. The conversion addresses this problem also.
  87.  
  88.  
  89.                            ZCPR2 vs. ZCPR3 Shells
  90.  
  91.      I would not like to take up again one of the subjects raised in issueì
  92. #33: ZCPR2-style versus ZCPR3-style shells.
  93.  
  94.      First an aside.  Shells seem to be a surprisingly emotional issue.  Iì
  95. thought my earlier column presented a fairly carefully and calmly reasonedì
  96. discussion of some aspects of shells, including their pros and their cons. ì
  97. Some readers, however, took great offense at my even questioning the currentì
  98. method of implementing shells or of what some people are trying to do withì
  99. them.
  100.  
  101.      One reader went so far as to suggest that I had no business commentingì
  102. on the subject when, by my own admission, there are a number of shells thatì
  103. I have never used.  Besides the fact that this is hardly a reasonedìèargument, I would like to make sure that the following facts about shellsì
  104. are fully appreciated.
  105.  
  106.      ZCPR3-style shells are a facility of the command processor.  Withoutì
  107. special code in the CPR, there would be no such shells.  As the author ofì
  108. the two latest versions of the ZCPR command processor, I think I can speakì
  109. with some authority (though certainly not with infallibility) on theì
  110. subject, since in writing that code I had to consider the issue of shellsì
  111. rather carefully from a rigorous theoretical viewpoint.
  112.  
  113.      ZCPR2-style shells, quite the contrary, are not a facility of theì
  114. command processor; they are a facility of the individual shell programs. ì
  115. Their functioning depends only on the operation of the multiple command lineì
  116. facility.  The command processor does not treat a Z2 shell command anyì
  117. differently than it treats any other command.  This is really the key to theì
  118. difference between the two shell implementations.
  119.  
  120.      In the previous column I stated: "...I am coming to the conclusion thatì
  121. only programs like history shells...should be implemented as ZCPR3-styleì
  122. shells.  Other programs, like ZFILER and WordStar should use the ZCPR2ì
  123. style."  I then invited readers to enlighten me if I was missing someì
  124. important point.  I got some responses to this invitation, but no one yetì
  125. has offered me any evidence that I had missed any important point.
  126.  
  127.      One reader reiterated essentially the same difference between Z2 and Z3ì
  128. shells that I attempted to demonstrate with my example in which WordStar wasì
  129. invoked in a multiple command line.  Apparently the point bears repeating.
  130.  
  131.      This reader presented the point using a command line like theì
  132. following:
  133.  
  134.         ZFILER;ECHO TESTING
  135.  
  136. Under ZCPR2, ZFILER would run and present its file display to the user.  Ifì
  137. the user generated a command line "CMDLINE" as the result of a macro or inì
  138. response to the prompt after the 'Z' command, a Z2-shell version of ZFILERì
  139. would build the command sequence "CMDLINE;ZFILER" and insert it into theì
  140. multiple command line buffer just before the next command to be executed. ì
  141. This would give:
  142.  
  143.         CMDLINE;ZFILER;ECHO TESTING
  144.  
  145. The user's command line would run, and then ZFILER would be invoked again. ì
  146. Only on termination of ZFILER would the last command, "ECHO TESTING", beì
  147. performed.
  148.  
  149.      A Z3 shell would respond to the same command line from the user inì
  150. quite a different way.  As before, ZFILER would be invoked first.  It wouldì
  151. determine from the Z3 message buffer that it had been invoked manually andì
  152. would respond by pushing its own name onto the shell stack.  Then it wouldì
  153. terminate.  The command processor would then proceed to run "ECHO TESTING". ì
  154. Only after that, once the command line was empty, would ZFILER be reloaded,ìèthis time as a shell.  Recognizing its shell status, it would now displayì
  155. its screen of file names and do its real work.
  156.  
  157.      The reader who submitted this example, if I understood him correctly,ì
  158. viewed the Z3 behavior as correct and the Z2 behavior as wrong.  If you areì
  159. an experienced Z-System user, you will probably recognize in this reader aì
  160. fellow expert (and, indeed, he is).  He is so used to ZCPR3 that he noì
  161. longer notices that it is the behavior of the Z3 shell that is trulyì
  162. bizarre!
  163.  
  164.      Consider the following two command lines:
  165.  
  166.     (1) ZFILER;ECHO TESTING
  167.     (2) ECHO TESTING;ZFILER
  168.  
  169. We have already analyzed the first one; the second one can safely be left asì
  170. an exercise for the reader.  We will simply state the answer that underì
  171. ZCPR3 they will accomplish exactly the same thing!  This is hardly a resultì
  172. that conforms to intuition, and I still remember in my early days as a Z¡
  173. Node sysop trying to explain to quite a few users why the second command onì
  174. a VFILER command line executes first!
  175.  
  176.      Under ZCPR2 the result is just what one would expect.  In the firstì
  177. case, ZFILER runs first, and ECHO runs only after the user terminates ZFILERì
  178. using its 'X' command.  In the second case, ECHO runs first and ZFILERì
  179. second.  In other words, with Z2 shells, commands are executed in the orderì
  180. they are entered, a notion that does not require long experience and greatì
  181. expertise to understand and get used to!  And it gives the user a greaterì
  182. measure of control.
  183.  
  184.  
  185.                            Mixed Z2 and Z3 Shells
  186.  
  187.      The same reader submitted another interesting example that illustratesì
  188. the confusing behavior that can arise when Z2 and Z3 shells are mixed.  Hereì
  189. we assume that WordStar has been implemented as a Z2 shell and ZFILER as aì
  190. Z3 shell.  Suppose we use the 'R' command of WordStar to enter the commandì
  191. "ZFILER".  WS4, as a Z2 shell, would generate the command line
  192.  
  193.         ZFILER;WS
  194.  
  195. ZFILER, as a Z3 shell, would install itself on the shell stack and proceedì
  196. to execute "WS".  ZFILER would not run in its file maintenance mode untilì
  197. after we terminated WordStar.
  198.  
  199.      This is, admittedly, probably not what one intended, since we mostì
  200. likely entered the ZFILER command with the intention of doing some fileì
  201. maintenance before returning to WordStar.  On the other hand, it isì
  202. certainly no more bizarre than what we saw in our earlier example.
  203.  
  204.      If both WS4 and ZFILER were Z3 shells, then the invocation of ZFILERì
  205. from the WS4 'R' command would cause it to become the active shell (the oneìèon the top of the shell stack).  The WS4 shell would be pushed down in theì
  206. shell stack, and ZFILER would take control.  With a little thought, however,ì
  207. you will see that the same is also true if both ZFILER and WS4 are Z2ì
  208. shells!
  209.  
  210.      The strange behavior with the mixed shells in the above example arisesì
  211. in part because ZFILER was not really being used as a shell in the Z3 sense,ì
  212. namely, as a replacement for the command processor's command-line inputì
  213. routine.  It was intended as a file maintenance utility.
  214.  
  215.      Suppose we had entered the command "EASE" (the Z3-type history shell)ì
  216. instead of "ZFILER" from our Z2 version of WordStar.  This would establishì
  217. EASE as the current shell and return to WordStar.  That behavior would notì
  218. seem strange, because in this case we would be thinking of our EASE commandì
  219. as establishing the shell to be used in place of the command processor theì
  220. next time the command processor needed a new command line.  So long asì
  221. WordStar is running, there is no need for EASE to do anything.  We expect itì
  222. to take effect only after we are finished using WordStar.
  223.  
  224.  
  225.                    Nested Z2 Shells and Recursive Aliases
  226.  
  227.      Although I had once thought that the Z3 shell stack was required inì
  228. order to nest shells, I showed in the earlier column that this is not theì
  229. case. Z2-style shells can, in fact, be nested more flexibly.  There is noì
  230. predetermined limit to the nesting depth or to the amount of informationì
  231. that can be passed with each shell command line.  The only limit is imposedì
  232. by the length of the multiple command line buffer, just as with the nestingì
  233. of aliases.
  234.  
  235.      With the standard shell stack configuration of 4 32-byte entries, if aì
  236. shell command uses only 16 bytes, 16 bytes are wasted.  On the other hand,ì
  237. if a shell command needs 48 bytes to hold its information, it cannot run atì
  238. all under this configuration (NZ-COM can come to the rescue by allowing theì
  239. shell stack configuration to be changed on the fly).  With Z2 shells, theseì
  240. problems go away.  In 64 bytes of command line, one can have two 32-byteì
  241. shell commands or a combination of one 16-byte shell command and one 48-byteì
  242. shell command (or five 12-byte shell commands).
  243.  
  244.      I did overlook one point when I described putting data for the shellsì
  245. on the command line.  In the Z3 shell stack, one can include, after theì
  246. shell command's terminating null, any binary data that one wishes.  Thus 256ì
  247. values are possible for each extra byte in the shell stack entry.
  248.  
  249.      In order to carry shell data on the command line, several additionalì
  250. constraints apply.  First, the command processor strips the high bits offì
  251. all characters in the command line, so only 128 values are available toì
  252. start with.  Secondly, the null character cannot be used because the commandì
  253. processor would interpret this as the end of the command line (that leavesì
  254. 127 values).  Finally, letters are converted to upper case, thereby makingì
  255. the characters from 'a' to 'z' inaccessible (scratch another 26).  Thisì
  256. leaves only 101 possible values out of the original 256.  Moreover, extraìècharacters are required as flags to signal the program to consider itself asì
  257. having been invoked as a shell (a service provided in ZCPR3 by a flag in theì
  258. message buffer).  All of these things reduce the efficiency with which theì
  259. space in the command line buffer can be used compared to the space in theì
  260. shell stack.
  261.  
  262.      One reader pointed out that recursive aliases cannot be used withì
  263. Z2-type shells.  This is true...but only if one is using the pseudo¡
  264. recursive alias that I invented.  This kind of alias accomplishes a crudeì
  265. approximation to recursion by discarding any pending commands in the commandì
  266. line buffer.  This will, indeed, discard any shell reinvocation commands. ì
  267. However, if one uses the logically sound and rigorous recursive aliasì
  268. technique invented by Dreas Nielsen (see my column in issue #28), there isì
  269. no problem.  It sometimes pays to do things right!
  270.  
  271.      In fact, it seems to me that the Z2 shell is, in essence, a recursiveì
  272. alias, a program that keeps invoking itself.  And this is just what most (ifì
  273. not all) Z3 shells actually do.  I am still awaiting an example of somethingì
  274. (good) that a Z3 shell can do that cannot be done in some equivalent wayì
  275. with a Z2 shell or recursive alias.
  276.  
  277.  
  278.                         The Real Difference Between
  279.                               Z2 and Z3 Shells
  280.  
  281.      After much reflection, I think I have finally put my finger on theì
  282. fundamental distinction between Z2 and Z3 shells.  It derives from the factsì
  283. I alluded to earlier: that the Z3 shell is a true creature of the commandì
  284. processor and the Z2 shell is not.
  285.  
  286.      Here is an example that will illustrate the point.  Suppose the historyì
  287. shell EASE were implemented as a Z2-style shell and that while it isì
  288. running, we issue the command "DIR".  EASE will insert into the command lineì
  289. a sequence like the following:
  290.  
  291.         DIR;EASE
  292.  
  293. DIR will run, and then EASE will be reinvoked.  Looks fine!  But now supposeì
  294. the user enters the command "IF EXIST FN.FT".  EASE will then generate theì
  295. command line
  296.  
  297.         IF EXIST FN.FT;EASE
  298.  
  299. If the file FN.FT exists, this will again work just fine, but suppose theì
  300. file does not exist.  Then the system will enter a false flow state, and theì
  301. EASE command (and perhaps other commands pending in the command line afterì
  302. it) will be flushed by the command processor.  The shell function will beì
  303. lost, and any other pending commands will be processed in an unintended way.
  304.  
  305.      For a Z2 shell to function properly in general, all command linesì
  306. inserted by it must result in the same flow state at the end of the commandì
  307. line as at the beginning.  With a MENU shell it could be possible for theìèsystem designer to guarantee this, since he can control which commands areì
  308. generated by the shell.  With a history type shell it would be nearlyì
  309. impossible to ensure that this condition would always be met.
  310.  
  311.      The critical feature of shell processing under ZCPR3 is that flowì
  312. processing is suspended during the operation of shells.  This allows them toì
  313. run, as they must, even after the user has passed a command that leaves theì
  314. system in a false flow state.  The ZCPR33 Users Guide goes into some detailì
  315. on this matter, and had I remembered better what I wrote there, it would notì
  316. have taken me this long to come to the essence of the Z2-vs.-Z3 shell issue.
  317.  
  318.      Some users of ZCPR33 have modified the way the command processor dealsì
  319. with flow control in shell processing.  No one has yet convinced me of theì
  320. value of this (the risks are undeniable).  It still seems to me that Z2-typeì
  321. shells and recursive aliases can accomplish the same thing, but in aì
  322. logically sound way.
  323.  
  324.      I have extended an invitation to Dreas Nielsen to write a series ofì
  325. columns for TCJ explaining his very powerful shell programs.  Since he isì
  326. also one of the people who has made this modification to the CPR, perhaps heì
  327. will also present the other side of this story and explain why it isì
  328. necessary or desirable to treat shells the way he does.
  329.  
  330.  
  331.                         Remaking WordStar Release 4
  332.  
  333.      When I first received my copy of WordStar 4 and encountered problems ì
  334. with the way it handled shells, I fired up the DSD debugger and tried to ì
  335. figure out how to fix it.  After a considerable amount of rummaging about inì
  336. the code (and especially trying to figure out what was going on insideì
  337. WS.OVR), I gave up.  Later I tried again...and failed again.  In the courseì
  338. of preparing this column, I decided to have one more go at it, and this time ì
  339. things started to click.
  340.  
  341.      The patches I will describe here are preliminary and have not yet been ì
  342. extensively tested.  In fact, as I write this, I am the only one who hasì
  343. used them, and you know what I said above about the dangers of a testì
  344. program that does not involve a variety of Z-System users.  So, you areì
  345. hereby recruited, if you are willing, to join the test program.
  346.  
  347.      Since I may very well have made some mistakes, and since there areì
  348. further changes that people may want to make (let's hear your suggestions),ì
  349. I will not only give the results; I will describe the process by which theseì
  350. patches have been developed.
  351.  
  352.  
  353.                              Cracking the Code
  354.  
  355.      The first step toward changing the code was figuring out how the virginì
  356. WordStar was doing what it did.  In particular, I wanted to locate routinesì
  357. related to Z-System functions, so the first thing I tried was searching forì
  358. all references to address 109h, which contains the address of the Z-Systemìèenvironment (ENV).  Any WS4 feature that made use of a Z-System facilityì
  359. would have to get information from the ENV.
  360.  
  361.      As best I recall, this did not turn up many references and did notì
  362. particularly help (though it was a good idea, and that's why I mention it). ì
  363. In the end, I just started tracing the code from the beginning, figuringì
  364. that WS4 would have to determine fairly early whether it was running underì
  365. Z-System or standard CP/M.  This turned out to be correct, and very soon Iì
  366. came to the key Z routine, at address 0AA4h in WS.COM.  This routine returnsì
  367. the address and size of a Z-System module specified by an offset passed inì
  368. the E register.
  369.  
  370.      Having discovered this routine, I used DSD to find all references to itì
  371. in WS.COM and WS.OVR.  They occur with the following values of E:
  372.  
  373.     E =  9h        the command search path (PATH)
  374.     E = 15h        the named directory register (NDR)
  375.     E = 18h        the multiple command line buffer (MCL)
  376.     E = 1Eh        the shell stack (SHL)
  377.     E = 22h        the message buffer (MSG)
  378.     E = 24h        the external file control block (XFCB)
  379.  
  380.  
  381.                          Setting up the Shell Stack
  382.  
  383.      The block of code beginning around address 3CBFh in WS.OVR makesì
  384. references to MCL, XFCB, and SHL.  I guessed correctly that this had to beì
  385. the code where WS4 sets up its shell stack entry.  (This block of code, byì
  386. the way, is where the shell-pushing mistake occurs for the case where theì
  387. shell stack is currently empty.)
  388.  
  389.      The patch for this part of WS.OVR (see Listing 1) modifies this code. ì
  390. First of all, since WS4 is going to operate as a Z2-type shell, we do notì
  391. want it to do anything with the shell stack.  It is easy to disable the codeì
  392. by simply skipping over it, but one has to watch out for subtleties. ì
  393. Indeed, in order for the 'R' command to use the MCL and not chain using theì
  394. greatly inferior CP/M method, WS4 has to think that the shell entry wasì
  395. established successfully.
  396.  
  397.      I noticed that a flag was being set into address 2200h, and I surmisedì
  398. that it is used by WS4 to show that it is running under Z-System.  In theì
  399. patch, I set this flag even though the shell stack entry is not being setì
  400. up.  I have not examined all references to this flag, and there is a chanceì
  401. that there are additional, more complex effects.  If any problems appearì
  402. with the patched version of WordStar, this flag might be involved.  For theì
  403. initial attempt at fixing WS4, I just took the easiest course of action, andì
  404. so far it appears to have worked.
  405.  
  406.      It seemed foolish to waste space in WS.OVR by doing nothing more thanì
  407. setting the flag and jumping to where the original code resumed (60AAh). ì
  408. Instead, I have used the space to compute the command line necessary toì
  409. reinvoke WordStar.  The code gets not only the name by which WordStar wasìèinvoked but also the drive and user number from which it was loaded.  Aì
  410. command line of the form ";DUU:WSNAME" is generated.
  411.  
  412.      There is one extra step in this part of the patch.  When running as aì
  413. Z3 shell, WS4 knows from the command status flag in the message buffer whenì
  414. it was invoked as a shell so it can put up the press-any-key message beforeì
  415. clearing the screen and resuming operation.  As a Z2 shell, WS4 cannot useì
  416. this facility.  Instead, a signal has to be included in the command tail. ì
  417. For reasons that I will not go into in full detail, I chose for this signalì
  418. a comma at the very end of the tail.  Very briefly, the comma is a handyì
  419. character because it is not parsed into the default file control blocks,ì
  420. where a program could confuse it with a file name.
  421.  
  422.      The final reinvocation command line, with its terminating null, takesì
  423. the form
  424.  
  425.         ;DUU:WSNAME ,<0>
  426.  
  427. Since I could not be sure that this section of overlay code would persist inì
  428. memory until the command would be used, I store it at the top of the WS4'sì
  429. user patch area (MORPAT).
  430.  
  431.  
  432.                  The Initialization and Termination Patches
  433.  
  434.      Having made the above modification, we must make two others in order toì
  435. remain consistent.  First, we must modify the WS4 initialization code inì
  436. which it determines whether or not it was invoked as a shell.  This is theì
  437. patch at address 1A2Fh in WS.COM.  The patch calculates the address of theì
  438. last character passed in the command tail and checks to see if it was aì
  439. comma.  If not, it proceeds with normal operation of the program.
  440.  
  441.      If there is a comma, the shell-wait message must be displayed until theì
  442. user presses a key.  But one must also remove the comma from the commandì
  443. tail to ensure that WordStar not think it has been passed a file name.  Atì
  444. present I do this by replacing the comma with a space.  This is notì
  445. rigorous, but it seems to work, since WS4 is apparently not confused by aì
  446. tail consisting only of spaces (unfortunately, a number of programs are).
  447.  
  448.      Since WS4 no longer pushes its name onto the shell stack, we must alsoì
  449. prevent it from popping the shell stack when it terminates.  This is theì
  450. patch at address 13CEh in WS.COM.  This is the easiest patch of all, sinceì
  451. we simply have to skip some code.  As an additional benefit, this frees upì
  452. about 40 bytes of space that we use for some of our other patch code.
  453.  
  454.  
  455.                            Fixing the 'R' Command
  456.  
  457.      Now we come to the main item in this set of patches -- the code thatì
  458. makes the 'R' command work as a ZCPR2-type shell.  The new code here is muchì
  459. more complex than what it replaces, and we can only fit part of it at theì
  460. original location 67B2h in WS.OVR.  We put what we can there and continueìèwith the rest in the MORPAT area in WS.COM.
  461.  
  462.      The basic strategy is to take the command line entered by the user inì
  463. response to the 'R' command prompt, append the WS reinvocation commandì
  464. (including its semicolon separator), and append any remaining command lineì
  465. pending in the multiple command line buffer (if there is one, it will beginì
  466. with a semicolon also).  If there is enough room for the result in the MCL,ì
  467. then it is moved there and chained to.  If not, a warning message isì
  468. displayed on the screen until a key is pressed, and the user command isì
  469. ignored.
  470.  
  471.      To implement this strategy, I chose the simplest method I could thinkì
  472. of.  Since the 'R' command operates from the WordStar no-file menu, theì
  473. entire WS edit buffer is available as a scratch area.  I picked an arbitraryì
  474. address of A000h for a buffer in which to build the new command line. ì
  475. Again, rigorous code calculate the address.  My code is a quick-and-dirtyì
  476. solution.
  477.  
  478.  
  479.                          Finding the Overlay Files
  480.  
  481.      As I noted earlier, with my style of operation, WS4 had trouble findingì
  482. its overlays.  To solve that problem, the patch includes an optional sectionì
  483. to install an internal search path for the overlay files.  This patch isì
  484. installed at address 0F5Fh in WS.COM, where it replaces a call for theì
  485. location of the Z-System path with a call to a routine that returns theì
  486. address and size of an internal path.  In Listing 1 the internal path hasì
  487. the single element B4:, the directory in which I keep my WordStar programì
  488. files.  You can put any values you want here.
  489.  
  490.  
  491.                            Installing the Patches
  492.  
  493.      It is not possible to install the patches in WS.OVR using MLOAD or aì
  494. debugger, because the OVR file is too large to load entirely into memory. ì
  495. ZPATCH, on the other hand, can handle the job splendidly.  ZPATCH assumes anì
  496. offset of 0000 for a file of type OVR, while the addresses in the listingì
  497. are those shown when the file (as much as can fit) is read into memory underì
  498. a debugger.  To make things consistent, you should use the ZPATCH 'O'ì
  499. command to set the offset to 100.  
  500.  
  501.      Key in the new data carefully, checking from time to time that theì
  502. address is still correct.  Also, be careful not to go beyond a recordì
  503. boundary while in ZPATCH.  It wraps from the end of the record back to theì
  504. beginning of that record without warning (this really gave me grief until Iì
  505. caught on to the problem).  When you get to the end of the current record,ì
  506. write it out (^W), advance to the next record (>), and reenter edit modeì
  507. (E).  Then you can resume entering data.
  508.  
  509.      The attached listing was made with a specially configured version ofì
  510. the SLR Z80ASM assembler.  Normally, I have it display addresses in logicalì
  511. order for easier interpretation.  For hand keying of a patch, however, it isìèfar more convenient to have the bytes of a word in physical order.  Justì
  512. watch out when reading the displayed symbol values.  They, too, are storedì
  513. in byte-reversed format.
  514.  
  515.      It is possible to use MLOAD to install just the patches for WS.COM. ì
  516. Simply delete the parts of WSPAT.Z80 that refer to patches in WS.OVR andì
  517. assemble the remaining code to a HEX file.
  518.  
  519.      Enjoy playing with (and using) this different (improved) version ofì
  520. WordStar 4, and let me know what you think and what further suggestions youì
  521. have.
  522.  
  523. [This article was originally published in issue 35 of The Computer Journal,
  524. P.O. Box 12, South Plainfield, NJ 07080-0012 and is reproduced with the
  525. permission of the author and the publisher. Further reproduction for non-
  526. commercial purposes is authorized. This copyright notice must be retained.
  527. (c) Copyright 1988, 1991 Socrates Press and respective authors]
  528.