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 / TCJ28.MZG / TCJ28.MAG
Text File  |  2000-06-30  |  45KB  |  817 lines

  1.                                Z-System Corne≥ (c)
  2.                                  by Jay Sage
  3.                         The Computer Journal, Issue 28
  4.                           Reproduced with permission
  5.                            of author and publisher
  6.  
  7.  
  8.                      The ZSIG Column #4, March 9, 1987
  9.  
  10.      For  this  issue I will finally get to my long promised  discussion  of
  11. techniques  for customizing the Z-COM automatic installation version of  the
  12. Z-System.   Before turning to the main subject, however, there are two other
  13. items  I  would  like to cover.   One is some follow-on  discussion  to  the
  14. material  I  presented  last  time on recursive  aliases;  the  other  is  a
  15. description of the latest ZSIG releases.
  16.  
  17.  
  18.                          More on Recursive Aliases
  19.                          -------------------------
  20.  
  21.  
  22.      Art  Carlson forwarded to me a letter he received from Dreas Nielsen in
  23. response  to  my discussion of recursive alias techniques using  VALIAS  and
  24. ARUNZ.   Dreas,  well  known in the ZCPR community for his  excellent  shell
  25. utility  programs,  GETVAR and RESOLVE,  took me to task for doing something
  26. the  hard  (and  not quite correct) way when there was  a  not-too-hard  and
  27. completely correct way to do it.   And he proved it by offering a  marvelous
  28. technique for 'recursing' aliases without any of the problems I warned about
  29. with  my  technique.   To me this is a wonderful example of the richness  of
  30. ZCPR3.   No matter how thoroughly one knows it, there are always significant
  31. new  techniques  and  applications  to  be  discovered.   The  learning  and
  32. excitement never ends!
  33.  
  34.      We  will illustrate the technique using a simple example based  on  the
  35. following script that is designed to display a message on the screen showing
  36. how many times it has been run already.  The script is
  37.  
  38.         alias ONELOOP:          ECHO THIS IS LOOP NUMBER
  39.                                 REG P6
  40.  
  41. As  the  ZCPR3 user register number 6 is incremented using the  'P'-for-plus
  42. option, its new value is displayed on the screen.
  43.  
  44.      If we wanted to make the alias operate recursively, our first instinct,
  45. as described in my previous column, would be to expand it to the following:
  46.  
  47.         alias MANYLOOP:         ECHO THIS IS LOOP NUMBER
  48.                                 REG P6
  49.                                 ECHO DO IT AGAIN?
  50.                                 IF IN
  51.                                 MANYLOOP
  52.                                 FIè
  53. As  I explained last time,  the trouble with this is that each time  we  run
  54. through  the  loop by answering the input prompt affirmatively we go one  IF
  55. level  deeper  and  accumulate another FI on the end of  the  command  line.
  56. Eventually  either the command line becomes too long  or,  more  likely,  we
  57. exceed the allowed eight levels of IF nesting.
  58.  
  59.      Dreas's  idea is based on turning this alias around so that there is no
  60. FI on the end to accumulate.   He permutes it to the beginning of the script
  61. and writes the alias this way:
  62.  
  63.         alias RECURSE2:         FI
  64.                                 ECHO THIS IS LOOP NUMBER
  65.                                 REG P6
  66.                                 ECHO DO IT AGAIN?
  67.                                 IF IN
  68.                                 RECURSE2
  69.  
  70. If this alias is invoked with a 'true' IF level already in effect, this will
  71. work just fine.   The alias will drop one IF level lower at the FI  command,
  72. do  its  main  work,  and return to the original IF level with the  "IF  IN"
  73. prompt.   If the answer is affirmative,  we will be back in the very same IF
  74. state we were in when the alias was invoked the first time.   The alias will
  75. be re-invoked,  and the whole operation will repeat.   On the other hand, if
  76. the answer to the prompt is negative,  the alias will stop running,  and  we
  77. will  fall out the bottom at the same IF level as we entered originally  but
  78. in the 'false' state.
  79.  
  80.      To deal with the need to enter one IF level higher and to terminate the
  81. 'false'  IF  state at the end,  we simply call the above alias from  another
  82. alias with the following script:
  83.  
  84.         alias RECURSE:          IF TRUE
  85.                                 RECURSE2
  86.                                 FI
  87.  
  88. The  "IF  TRUE"  command will push us one IF level deeper and put  us  in  a
  89. 'true' state.   (This, by the way, is the first time that I have ever seen a
  90. use  for the "TRUE" option with the IF command.   If,  like  me,  you  never
  91. implemented  that  option because you could not figure out what on earth  it
  92. could  possibly  be used for,  you can substitute any other option  that  is
  93. guaranteed to return a 'true' state, such as "IF NULL" with nothing after it
  94. or "IF A=A").   The RECURSE2 alias will now run as we described earlier, and
  95. when  the recursion is terminated by a negative answer,  the FI  in  RECURSE
  96. will  terminate the resulting 'false' IF state and return us to the original
  97. IF level that we were at when RECURSE was invoked.
  98.  
  99.      One  has to stretch things a bit to come up with any  disadvantages  to
  100. this technique.  The best I can do is the following two minor points. First,
  101. two  aliases are required to get things started,  and this will slow  things
  102. down a bit,  especially on a floppy-disk system.   Secondly,  the technique,
  103. while simple in principle, may not be easy to remember when one wants to setèup  a  quick recursive alias,  as in the application I described in my  last
  104. article.   The VALIAS/ARUNZ-type recursive alias may still be useful in such
  105. a case.
  106.  
  107.      If you are a purist and have a strong,  perhaps even irresistible, urge
  108. to  do things right (and especially if you have a RAM disk so that  you  can
  109. afford  to  indulge  such  compulsions),  Dreas's technique  can  be  nicely
  110. automated   by  creating  the  following  two  slightly  more  complex   and
  111. generalized aliases:
  112.  
  113.         alias RECURSE           IF NULL $1
  114.                                 ECHO SYNTAX: $0 ALIASNAME PARAMETERS
  115.                                 ELSE
  116.                                 RECURSE2 $*
  117.                                 FI
  118.  
  119.         alias RECURSE2          FI
  120.                                 $*
  121.                                 ECHO RUN "$1" AGAIN?
  122.                                 IF IN
  123.                                 $0 $*
  124.  
  125. Now  suppose we have our edit/assemble/link alias as follows (where  it,  in
  126. turn, calls on the SYSLINK alias to perform the linkage with the libraries):
  127.  
  128.         alias WORK              EDIT $1.Z80
  129.                                 Z80ASM $1/R
  130.                                 IF ~ERROR
  131.                                 SYSLINK $1
  132.                                 FI
  133.  
  134.      If  we  enter  the command "RECURSE" all by itself,  we  will  get  the
  135. message  "SYNTAX:  RECURSE ALIASNAME PARAMETERS".   If we enter the  command
  136. "RECURSE  WORK MYPROG",   the "IF NULL" test in RECURSE will be 'false'  but
  137. will be toggled 'true' by the ELSE command.   Then RECURSE2 will be invoked,
  138. and the command line and IF status will progress as shown in  Fig.  1.   The
  139. "..."  in the IF states designates any IF levels in effect at the time  that
  140. RECURSE  was called.   Similarly,  the command text 'pending' designates any
  141. command-line text following the invocation of RECURSE.
  142.  
  143.      The  figure  does  not  show  the  operation  of  every  command.   The
  144. edit/assemble/syslink  sequences are not shown in detail.   Between steps  8
  145. and  9  we assume that the "IF IN" prompt was answered  with  a  'Y'.   This
  146. brings us at step 9 back to the exact state we were in at step 4,  and steps
  147. 4  through 8 will be repeated over and over so long as the "IF IN" prompt is
  148. answered affirmatively.
  149.  
  150.      Between steps 10 and 11 we assume that the "IF IN" prompt was  answered
  151. with 'N',  so we get the state shown in step 11.  Since the current IF state
  152. is  'false',  the command "RECURSE2 WORK MYPROG" is flushed,  leaving us  at
  153. step 12.   The FI command terminates the 'false' IF and drops the flow state
  154. one  level lower.   Any pending commands that were on the command line afterèthe invocation of RECURSE are now free to run at step 13.
  155.  
  156.      I  just  tested out these aliases on my SB180 by putting them  into  my
  157. ALIAS.CMD file,  which lives on the RAM disk.  The scripts had to be altered
  158. slightly,  with all invocations of RECURSE2 from within RECURSE and RECURSE2
  159. being replaced by "ARUNZ RECURSE2 ..." or "ARUNZ $0 ...".   They worked like
  160. an absolute charm.  Thank you Dreas Nielsen!!!
  161. ------------------------------------------------------------------------------
  162.  
  163.         Step    IF state        Command Buffer Contents
  164.         ----    --------        -----------------------
  165.  
  166.           1     ...             RECURSE WORK MYPROG;pending
  167.  
  168.           2     ...             IF NULL WORK MYPROG;ECHO SYNTAX: RECURSE
  169.                                 ALIASNAME PARAMETERS;ELSE;RECURSE2 WORK
  170.                                 MYPROG;FI;pending
  171.  
  172.           3     F...            ELSE;RECURSE2 WORK MYPROG;FI;pending
  173.  
  174.           4     T...            RECURSE2 WORK MYPROG;FI;pending
  175.  
  176.           5     T...            FI;WORK MYPROG;ECHO RUN "WORK" AGAIN?;
  177.                                 IF IN;RECURSE2 WORK MYPROG;FI;pending
  178.  
  179.           6     ...             WORK MYPROG;ECHO RUN "WORK" AGAIN?;IF IN
  180.                                 RECURSE2 WORK MYPROG;FI;pending
  181.  
  182.           7     ...             EDIT MYPROG.Z80;Z80ASM MYPROG/R;IF ~ERROR;
  183.                                 SYSLINK MYPROG;FI;ECHO RUN "WORK" AGAIN?;
  184.                                 IF IN;RECURSE2 WORK MYPROG;FI;pending
  185.  
  186.           8     ...             ECHO RUN "WORK" AGAIN?;IF IN;RECURSE2 WORK
  187.                                 MYPROG;FI;pending
  188.  
  189.           9     T...            RECURSE2 WORK MYPROG;FI;pending
  190.  
  191.          10     ...             ECHO RUN "WORK" AGAIN?;IF IN;RECURSE2 WORK
  192.                                 MYPROG;FI;pending
  193.  
  194.          11     F...            RECURSE2 WORK MYPROG;FI;pending
  195.  
  196.          12     F...            FI;pending
  197.  
  198.          13     ...             pending
  199.  
  200. Fig. 1.  Evolution of the command line and IF states as the operation of the
  201. command "RECURSE WORK MYPROG" unfolds.
  202.  
  203. ------------------------------------------------------------------------------
  204.  
  205. è                            A Z-Letters Feature
  206.                             -------------------
  207.  
  208.  
  209.      Thanking Dreas Nielsen for his letter reminds me that Art Carlson and I
  210. would  like  very much to start up a Z-Letters feature in  TCJ,  a  kind  of
  211. letters-to-the-editor section specializing in Z-System questions,  comments,
  212. discussion,  and  ideas.   I  am  willing to handle answering  or  otherwise
  213. responding to those letters,  but I will depend on you readers to send  them
  214. in.   And rest assured that we are not looking only for letters like Dreas's
  215. containing  brilliant  suggestions.   A good set of  simpleminded  questions
  216. would be quite well appreciated, thank you.  They would help us a great deal
  217. in  learning what aspects of Z-System are confusing to users so that we  can
  218. try to clarify them.
  219.  
  220.  
  221.                              New ZSIG Releases
  222.                              -----------------
  223.  
  224.  
  225.      We have quite a few excellent new programs to release on ZSIG diskettes
  226. this  month.   I  have  not yet finalized exactly what will be  included  on
  227. release diskettes #2 and #3, but I don't want to pass up this opportunity to
  228. publicize them.
  229.  
  230.      First  of  all,  I  am very happy to report that  all  the  programs  I
  231. proposed  two  issues back have now been written,  and I will describe  them
  232. first.
  233.  
  234. FCP10.LBR
  235.  
  236.         This  is  the  new  flow control package (FCP)  that  I  wrote  with
  237. valuable assistance from Howard Goldstein (New Haven, CT).  This program was
  238. described  in  some detail in the last column,  so I will not say  too  much
  239. about  it here.   The two most important innovations are 1) the addition  of
  240. AND and OR commands and 2) the FCP's ability to load and run IF.COM in  high
  241. memory  where  it  will  not interfere with data in  the  beginning  of  the
  242. transient program area at 100H.
  243.  
  244. COMIF10.LBR
  245.  
  246.         This  is  the companion transient IF processor that is  intended  to
  247. replace IF.COM.   Also described last time,  it offers an enormous number of
  248. new  test  conditions  and syntax forms.  This one was also  written  by  me
  249. together with Howard Goldstein.
  250.  
  251. SETPATH1.LBR
  252.  
  253.         This is an extended version of the original PATH command.  It allows
  254. one optionally to add and remove path elements from the beginning or the end
  255. of the existing path.   The path display is also improved.  Robert Demrow, a
  256. fellow member of the Boston Computer Society CP/M Group wrote this one.è
  257. EDITND.LBR
  258.  
  259.         Al  Hawley (Z-Node #3 in Los Angeles) really went all out with tools
  260. to work with the named directory register (NDR).   EDITND lets one edit  the
  261. names  directly in the NDR.   Names and/or passwords can be added,  deleted,
  262. and changed.
  263.  
  264. SAVNDR.LBR
  265.  
  266.         After you've edited the NDR,  this program lets you save the results
  267. to an NDR file.  Again by Al Hawley.
  268.  
  269. LOADND12.LBR
  270.  
  271.         The  last in the Hawley set,  this program can automatically  update
  272. the names in the NDR using either the special file name system in LDSK or by
  273. loading an NDR file whose names are applied to the current floppy disk only.
  274.  
  275.  
  276. The next ZSIG release will also include the following programs.
  277.  
  278. ZPATCH11.LBR
  279.  
  280.         This  is another masterpiece from Steve Cohen  (Chicago,  author  of
  281. 'W', the wildcard shell, on the first ZSIG diskette).  It is by far the best
  282. file  patcher I have ever seen -- a real joy to use.   Steve sure is  clever
  283. when it comes to shells!  Who would have thought to make a file patcher into
  284. a  shell?   But  this way one can run a command from inside ZPATCH and  then
  285. return to one's exact place to continue working.   The 'X' command in ZPATCH
  286. automatically runs the file one is currently patching (provided it is a  COM
  287. file) so that one can see the effect of the changes.  Marvelous!
  288.  
  289. MEX2Z.LBR
  290.  
  291.         This  is yet another brainstorm of NAOG chief Bruce Morgen (who  has
  292. quite a stormy brain).   MEX2Z and my adaptation of it for MEX-Plus, MEX+2Z,
  293. give the MEX communication programs the ability to 'shell',  that is, to run
  294. a  Z-System command apparently from within MEX.   For example,  if you enter
  295. the MEX command line "CPM;CRUNCH FN.FT",  you will exit from MEX,  the  file
  296. will be crunched,  and then you go right back into MEX.   This is especially
  297. handy  when  you are trying to debug a MEX script.   Bruce picked up on  the
  298. very  clever trick introduced by Ted Emigh in  FINDERR,  namely,  running  a
  299. program  that examines information left behind in memory by the program that
  300. ran  before  it.   In this case it is the MEX command line  buffer  that  is
  301. picked up.  Even if you don't use MEX, it is worth looking at these programs
  302. just for their educational value.
  303.  
  304. FF10.LBR
  305.  
  306.         I  finally decided to do something about the shortcomings of  FINDF,
  307. the utility for determining where files are located in your system.   FF hasèa 16-bit configuration word that can be patched (roll out ZPATCH!) to define
  308. which drives should be searched by default (this is particularly useful when
  309. your constellation of drives has a hole in it, such as A, B, C, and F).  You
  310. can override the default drive list by specifying a set of drives to scan on
  311. the  command line.   A whole list of file specifications can be  given,  and
  312. each one is automatically wildcarded,  saving the user a lot of typing.   If
  313. you want to find all programs starting with "SD",  just enter "FF SD".   The
  314. "SD" turns into "SD*.*" automatically.   Similarly,  "FF .LBR" will find all
  315. library files.  "FF SD,.LBR" will find both.
  316.  
  317. PPIP15.LBR
  318.  
  319.         This  is  the next step in the evolution of PPIP (PPIP14 is on  ZSIG
  320. diskette  #1).   The main addition is support for DateStamper time and  date
  321. stamping.   Having fallen in love with DateStamper,  I just had to have some
  322. file copying tools that would preserve the time and date information,  so  I
  323. added that capability to PPIP and to ZFILER.
  324.  
  325. ERRSET11.LBR
  326.  
  327.         This  little  tool lets you either display the current  or  directly
  328. enter a new error handler command line.   Strictly speaking,  error handling
  329. in  ZCPR3  is  not  performed by loading an error handling  program  but  by
  330. executing an error handling command line.   This command line is stored in a
  331. 16-byte string in the message buffer.  When an error handler is installed by
  332. invoking  its name manually from the command line,  it writes only its  name
  333. alone  into  that buffer.   ERRSET lets you enter a complete  error  command
  334. line,  such as A15:VERROR.   By including an explicit DU:  or DIR: form, the
  335. error handler will be found and loaded faster.   On the other  hand,  ERRSET
  336. will  let you enter the name of a nonexistent error handler,  so watch  out.
  337. Power has its price.  Written by yours truly.
  338.  
  339.  
  340.                              Customizing Z-COM
  341.                              -----------------
  342.  
  343.  
  344.      We now turn to the piece-de-resistance for this article -- a discussion
  345. of  techniques  for customizing Echelon's automatically installing  Z-System
  346. package known as Z-COM.   This will be the first of a two-part series.  This
  347. time  I  will  cover  the more elementary  aspects  of  the  subject,  those
  348. modifications that can be made by changing only data structures in the Z-COM
  349. files.   Next  time I will delve into customization techniques that  involve
  350. serious hacking (such as modifying the Z-COM code itself).
  351.  
  352.      I will begin with an overview of what Z-COM is,  the philosophy  behind
  353. it,  the  procedure for installing it on a particular computer,  and how one
  354. uses it to create a Z-System automatically.   Then I will give an elementary
  355. discussion of how it works and the structure of the COM file that  magically
  356. transforms one's ordinary CP/M machine into a 'Z' machine.  Next I will show
  357. you  how  to  make  some simple patches that  eliminate  the  initialization
  358. operations  that  are performed by the startup file and make Z-COM  come  upèready to go instantly.   This includes setting the wheel byte,  defining the
  359. symbolic command search path,  putting in the terminal capability descriptor
  360. (TCAP)  for the user's terminal,  installing the user's  named  directories,
  361. installing an external error handler, and even setting up an initial shell.
  362.  
  363.      With  those techniques mastered,  we can then go on to make changes  to
  364. the  system modules.   The simplest of these is replacing the standard ZRDOS
  365. that comes with Z-COM with the latest-and-greatest Public-ZRDOS-Plus version
  366. 1.7.     Slightly  more  complex  is  the  replacement  of  the  environment
  367. descriptor  (ENV)  and the two command modules:  the RCP  (resident  command
  368. package) and the FCP (flow control package).   For these changes we have  to
  369. edit  some configuration files,  assemble new code modules,  and install the
  370. new  modules  into  the Z-COM file.   By this point you  will  be  ready  to
  371. generate  and  install  a new version of the  ZCPR3  command  processor,  an
  372. operation that requires one important extra step (a simple one, but one that
  373. must not be overlooked).
  374.  
  375.  
  376.                                  Why Z-COM
  377.  
  378.  
  379.      Consider  this situation.   The Z-System is a wonderful replacement for
  380. CP/M,  one that greatly enhances the utility and ease of operation of an  8-
  381. bit Z80-compatible computer.   I can't understand why anyone would not enjoy
  382. and benefit from its features and capabilities.   However,  installing it in
  383. the  conventional  fashion  required changing the BIOS (Basic  Input  Output
  384. System), the hardware-dependent part of the operating system. Unfortunately,
  385. many (actually most) manufacturers consider their BIOS to be proprietary (or
  386. embarrassingly poorly written),  and they refuse to release the source code.
  387. And even if they do make it available, perhaps for an extra fee, what if you
  388. do  not know how to make the required changes to support the  ZCPR3  command
  389. processor?  Well, enter Z-COM.
  390.  
  391.      Z-COM  was  the  brilliant  conception  of  Joe  Wright,  the  nation's
  392. preeminent  BIOS  writer (author of the BIOSes for the Ampro  Little  Board,
  393. Micromint SB180, and the soon-to-be-available ON! computer from Oneac). With
  394. Z-COM one does not need the BIOS source code because there are no changes to
  395. make  in  it.   One  doesn't even need MOVCPM.   Z-COM runs  on  almost  any
  396. standard CP/M 2.2 system,  converting it in situ to a Z-System.  There are a
  397. few  CP/M  2.2  computers on which Z-COM will not work (usually  because  at
  398. least  some  part of their memory space operates in a funny  way),  but  the
  399. great majority will.  For those of you with CP/M version 3 (aka CP/M-Plus --
  400. a real misnomer in my opinion),  I'm afraid you are out of luck.   CP/M 3 is
  401. fundamentally  different  from CP/M 2.2,  and no one has yet  been  able  to
  402. concoct magic powerful enough to transform it into a Z-System.
  403.  
  404.      I  hope my discussion here will inspire some of you to purchase  Z-COM.
  405. If  it does,  then see the ads in TCJ by Sage Microsystems East and  Echelon
  406. for more information.   I personally think that a modified Z-COM is the best
  407. way to implement Z-System, because, as we will see by the end of this series
  408. of  articles,  it  gives  one far greater flexibility than with  a  manually
  409. installed system.è
  410.  
  411.                               Installing Z-COM
  412.  
  413.  
  414.      Here  is  a brief description of how one gets Z-COM  running  on  one's
  415. system.   The  standard procedure goes like this.   Take a freshly formatted
  416. disk,  'sysgen'  the CP/M 2.2 operating system to it,  copy onto it all  the
  417. files on the Z-COM release disk,  put this disk into drive A, and reboot the
  418. system either with the reset button or by entering control-c.  Now enter the
  419. command  "SUB ZCCOM".   This starts a batch operation,  and you can now  sit
  420. back, relax, and watch your computer do all the work.  Toward the end of the
  421. process, which takes a couple of minutes, a program called TCSELECT will run
  422. and ask you to choose your terminal from a large menu.  The result will be a
  423. file  called  MYTERM.Z3T  containing information about  your  terminal  that
  424. permits Z-System programs to perform screen operations without installation.
  425.  
  426.  
  427.                     What's Going On During Installation
  428.  
  429.  
  430.      In  the  first  part of the  installation  process,  the  Z-COM  system
  431. creation  program ZCLD.COM determines the memory address at which your  BIOS
  432. operates and generates a corresponding Z-System.   To do this, it reads in a
  433. number  of special relocatable files (most with file type SPR,  which stands
  434. for system page relocatable) and produces four new files:  ZC.COM,  ZCX.COM,
  435. ZC.ENV,  and  ZC.CP.   The first file,  whose operation we will describe  in
  436. detail  below,  is  the one that transforms the vanilla CP/M system  to  the
  437. amaretto-double-chocolate  almond Z-System with jimmies (if you  don't  know
  438. what jimmies are, ask someone from Boston).
  439.  
  440.      The second file,  ZCX.COM, is a program that transforms you back.  Why,
  441. you ask, would one ever go back to vanilla after experiencing the ecstasy of
  442. amaretto-double-chocolate-almond?   Well, Z-System does have one significant
  443. drawback.   You  don't get all those great features for free.   They cost  a
  444. considerable chunk of TPA (transient program area) -- 5.5K in the case of Z-
  445. COM  (though we will see next time how to reduce this if you are willing  to
  446. forego  some of the features).   The smaller TPA has almost never caused any
  447. problem with the programs I use, but some people do have problems, and it is
  448. nice  to know that a simple "ZCX" command will bring back the old CP/M  with
  449. its  full-sized TPA.   Next time I will explain how we can even change to  a
  450. different Z-COM system with a larger TPA.
  451.  
  452.      The  third file,  ZC.ENV,  is the environment descriptor file  for  the
  453. system  that ZCLD created.   It is automatically included in ZC.COM,  so  it
  454. does not have to be loaded using LDR, but it is used by Z3INS to install the
  455. environment information into the utilities.
  456.  
  457.      The last file,  ZC.CP,  does not even appear in a directory listing; it
  458. is hidden up in user area 15,  out of harm's way.   The user is not normally
  459. concerned with this file,  though if you want to create another Z-COM system
  460. disk,  you  have  to remember to copy it,  as well as the  others  mentionedèabove, to the new diskette.  We will discuss its purpose later.
  461.  
  462.  
  463.                               How ZC.COM Works
  464.  
  465.  
  466.      As  we said above,  ZC.COM is the program that transforms your  mundane
  467. CP/M  system  into an exciting and powerful Z-System.   How does it  do  it?
  468. Several simple principles are involved.
  469.  
  470.      ZC.COM is basically a loader program.   The file itself consists of two
  471. parts.   The  first  page of code (100H to 1FFH) is the  loader  code.   The
  472. second part (200H to 2DFFH) is the memory image of a Z-System that is copied
  473. into  place  by the loader.   The process is like the 'big bang'  theory  of
  474. creation -- the whole Z-System just appears complete in one operation!
  475.  
  476.      The memory map of the ZCOM-System generated for my BigBoard I computer,
  477. on which I performed these experiments,  is shown in Fig.  2.  Its real CP/M
  478. BIOS  is  at E800H.   The Z-System addresses were determined by running  the
  479. utility SHOW.COM after Z-COM was loaded.  The corresponding addresses in the
  480. ZC.COM  file  were obtained by inspecting it with a debugger.   Once  a  few
  481. addresses  (like  the  RCP  and  FCP,  which  have  obvious  headers),  were
  482. determined,  the rest was obvious.  The ZC.COM system image is at a constant
  483. offset from the real system.   In this example, that offset is BA00H.  If Z-
  484. COM  is installed on a different system,  the real system addresses and  the
  485. offset value will be different,  but the addresses of the system segments in
  486. the  ZC.COM  image will be the same.   In general,  the offset  between  the
  487. corresponding  addresses will be 2E00H less that the address of  the  native
  488. BIOS.
  489.  
  490. -----------------------------------------------------------------------------
  491.  
  492. System Component                ZC.COM Address          System Address
  493. ----------------                --------------          --------------
  494.  
  495.   CPR                             0200 - 09FF             BC00 - C3FF
  496.   ZRDOS                           0A00 - 17FF             C400 - D1FF
  497.   Virtual BIOS                    1800 - 19FF             D200 - D3FF
  498.   Named Directory Register        1A00 - 1AFF             D400 - D4FF
  499.   Shell Stack                     1B00 - 1B7F             D500 - D57F
  500.   Z3 Message Buffer               1B80 - 1BCF             D580 - D5CF
  501.   External FCB                    1BD0 - 1BF3             D5D0 - D5F3
  502.   PATH                            1BF4 - 1BFE             D5F4 - D5FE
  503.   Wheel Byte                      1BFF - 1BFF             D5FF - D5FF
  504.   Environment Descriptor          1C00 - 1C7F             D600 - D67F
  505.   TCAP                            1C80 - 1CFF             D680 - D6FF
  506.   Multiple Command Line           1D00 - 1DCF             D700 - D7CF
  507.   External Stack                  1DD0 - 1DFF             D7D0 - D7FF
  508.   Resident Command Package        1E00 - 25FF             D800 - DFFF
  509.   Flow Control Package            2600 - 27FF             E000 - E1FF
  510.   I/O Package                     2800 - 2DFF             E200 - E7FF
  511. èFig. 2.  Addresses of system components in the ZC.COM file and in the
  512. example system for which it was generated.
  513.  
  514. -----------------------------------------------------------------------------
  515.  
  516.      How does this system function?  If you are familiar with Z systems, you
  517. probably  recognize  all of the system components above except for  the  one
  518. called 'virtual BIOS'.   That is where the key to Z-COM lies.   Remember, we
  519. needed  a  BIOS  that would run below the Z buffers,  but we had no  way  to
  520. relocate the actual BIOS.  So instead we create a virtual BIOS -- a block of
  521. code structured just like a real BIOS.  It has a table of jump instructions,
  522. one after the other, that perform the required BIOS functions: CBOOT, WBOOT,
  523. CONST,  CONIN, CONOUT, LIST, and so on.  How does this virtual BIOS actually
  524. carry  out  those  functions  without  knowing  anything  about  the  system
  525. hardware?   Easy!   It simply jumps to the corresponding entry points in the
  526. real BIOS!
  527.  
  528.      Well,  it  actually is not quite that easy.   There are a  few  special
  529. details that have to be taken care of.   Most of the functions are performed
  530. as  described  above,  but there are some important  exceptions.   The  most
  531. important one is the WBOOT,  or warm boot,  function.   Normally when a warm
  532. boot is performed, the CPR (and often the BDOS as well) is reloaded from the
  533. system  tracks  of  the A diskette.   If that were allowed to  happen  here,
  534. goodbye  Z-System!   ZC.COM  would  only  work until  the  first  warm  boot
  535. occurred, and then we would have to run it again.  Not very satisfactory!
  536.  
  537.      To prevent that from happening and to keep Z-COM running,  the  virtual
  538. BIOS 'traps' warm boot calls.  That is a fancy way of saying that instead of
  539. simply passing the call to the real BIOS it does the work itself.  What does
  540. it  do?   Well,  it has to reload the ZCPR3 command processor to the  proper
  541. address,  BC00H in this example.   Since the ZCPR command processor does not
  542. reside  on the system tracks,  we have to get it from somewhere  else.   Joe
  543. Wright  could  have gotten it from records 2 through 17 in  ZC.COM,  but  he
  544. chose instead to maintain a separate file with just the image of the command
  545. processor.   Remember  the  file ZC.CP that we mentioned  earlier,  the  one
  546. stashed away in A15:?  That's it.
  547.  
  548.      Although  I don't know of any reason why CBOOT,  the cold boot routine,
  549. would  ever be called once the computer was initially booted up,  the  CBOOT
  550. routine  is  also trapped by the virtual BIOS and  vectored  (another  fancy
  551. word) to the same code as the virtual warm boot.
  552.  
  553.      In  Echelon's simpler auto-install package Z3-DOT-COM,  which does  not
  554. have  support  for  Input/Output Packages (IOPs),  the story  would  now  be
  555. complete.   The IOP,  however, has to get first shot at some of the BIOS I/O
  556. routines, namely console status, console input, console output, list output,
  557. list status, punch output, and reader input.  In a manual installation of Z-
  558. System with IOP support,  the BIOS code would have to be modified.   With Z-
  559. COM  this  is  quite  straightforward.   The virtual  BIOS  calls  to  these
  560. functions  simply  go (are vectored) to the appropriate entry points in  the
  561. IOP  module.   The initial IOP code included in ZC.COM is just a  dummy  IOP
  562. that  simply  turns around and forwards the calls from the IOP to  the  realèBIOS entry points.
  563.  
  564.  
  565.                              Easy Z-COM Patches
  566.  
  567.  
  568.      Now that we understand what Z-COM is and how it works,  we can start to
  569. make  some changes.   If you look at the STRT startup alias with Z-COM,  you
  570. will see that it turns on the wheel byte, loads the TCAP and named directory
  571. register,  and  sets  up the symbolic search path.   For our  first  set  of
  572. patches,  we will eliminate the need for a startup alias.   We will make the
  573. system come up fully tailored to our preferences,  and we will save the time
  574. wasted by the STRT alias.
  575.  
  576.      The  first step is to get Z-COM running and to use the utility programs
  577. to set it up as we like it.   We will generally turn the wheel byte on  (the
  578. STRT  alias presumably already ran WHEEL to do that for us).   We can set up
  579. our  named directories using MKDIR and LDR or the new ZSIG  named  directory
  580. editor  EDITND.   We  can choose our path using the PATH command or the  new
  581. ZSIG  SETPATH  utility.   An external error handler can be  defined  in  the
  582. message buffer by invoking the desired error handler manually at the command
  583. line  or  by  running  the  ERRSET utility (this can include  a  DU  or  DIR
  584. specifier  to speed up the search for the error handler).   Finally,  if  we
  585. want to, we can even invoke a shell, such as the history shell HSH.
  586.  
  587.      Now all we have to do is clone this system using our favorite debugger.
  588. If you can afford Echelon's DSD,  I cannot recommend it highly  enough.   It
  589. will  quickly  spoil  you.   On the other hand,  I will  describe  here  the
  590. procedure using Prof. Falconer's lovely DDTZ, a public-domain Zilog-mnemonic
  591. version of DDT.  Here is the sequence of commands to use.  Don't forget that
  592. the  addresses  that refer to the real system are the ones for my  BigBoard.
  593. You  should  make a table like that in Fig.  2 with the addresses  for  your
  594. system and make the appropriate substitutions in the commands below.
  595.  
  596.     A0:SYS>ddtz zc.com          ; Run debugger and load ZC.COM
  597.     -md400,d6ff,1a00            ; Copy running NDR, Shell Stack, MSG
  598.                                 ; ..buffer, PATH, WHL, ENV, and TCAP
  599.                                 ; ..into ZC.COM image
  600.     -g0                         ; Exit from debugger
  601.     A0:SYS>save 2dh zcnew.com   ; Save new version of ZC
  602.  
  603. If  you have a shell running while this process is being  carried  out,  you
  604. have to include the SAVE command on the same line as the DDTZ command, since
  605. when  the shell loads it wipes out the memory image in the TPA.   By putting
  606. the SAVE command on the same line, it is run before the shell is reloaded.
  607.  
  608.      I have used the above technique and found it to work very nicely, but a
  609. word of caution is in order.   A purist would copy the memory areas only for
  610. the specific segments to be modified.   The external file control block  and
  611. the parts of the message buffer other than the byte at offset 0 (D580, where
  612. the  error-handler-flag is kept) and bytes at offsets 10H to 1FH (D590-D59F,
  613. where the error handler command line is kept) would not be copied.   Copyingèthe entire message buffer works as described above, but if you try to make a
  614. ZEX batch file to do this,  you will get into trouble,  since ZCNEW.COM will
  615. then contain an image of the message buffer with the ZEX-running flag set.
  616.  
  617.      To  test  ZCNEW,  make a new STRT.COM alias that just echoes  a  signon
  618. message (first rename the old one in case you want it back later),  run  ZCX
  619. to  exit  from Z-COM,  and then run ZCNEW.   Your own personalized  Z-System
  620. should pop (almost) instantly to life.   After determining that it is really
  621. working correctly,  you can rename ZCNEW.COM to ZC.COM.   Again, I recommend
  622. keeping  old versions with names like ZC1.COM,  ZC2.COM,  and so on,  on  an
  623. archive disk.
  624.  
  625.  
  626.                             Putting in a New DOS
  627.  
  628.  
  629.      Now  let's make a change that could not be accomplished  using  utility
  630. programs,  as  all of the above changes could be.   Let's replace the older,
  631. non-public  version of ZRDOS that comes with Z-COM with the  latest  version
  632. 1.7 of Public-ZRDOS-Plus.   The first part of the process is same as that in
  633. a  manually  installed  Z-System.   One takes the ZRDOS  generating  program
  634. ZRDINS17.COM,  installs it using Z3INS, and runs it.  Having been installed,
  635. it will automatically know the three facts it needs: where the DOS, ENV, and
  636. wheel byte are located.   After it finishes running,  there will be a binary
  637. image file called ZRDOS17.BIN.
  638.  
  639.      With  a manually installed Z-System we would now have to go  through  a
  640. somewhat  complex  process  involving 'sysgening' a system  image  from  the
  641. system tracks, patching in the new DOS using a debugger, and 'sysgening' the
  642. image  back  onto  the  system  tracks.   With  Z-COM  things  are  actually
  643. considerably easier,  since the two 'sysgening' steps can be skipped.   Here
  644. is the command sequence:
  645.  
  646.     A0:SYS>ddtz zc.com          ; Run debugger and load ZC.COM
  647.     -izrdos17.bin               ; Initialize the file control block
  648.     -r900                       ; Read with offset 900h so that the object
  649.                                 ; ..file will load at A00h
  650.     -g0                         ; Warm boot out of debugger
  651.     A0:SYS>save 2dh zcnew.com   ; Save new version
  652.  
  653. As  before,  exit from Z-System with the ZCX command (or just hit the  reset
  654. button  if that is more convenient).   Then load the new system and run  the
  655. DOSVER utility.  Voila!  There is version 1.7.
  656.  
  657.      Now let me show you a trick that makes patching even easier and doesn't
  658. require a debugger at all.  Just use the following command sequence:
  659.  
  660.     A0:SYS>get 100 zc.com       ; Load ZC.COM at address 100H
  661.     A0:SYS>get a00 zrdos17.bin  ; Load ZRDOS17.BIN at address A00H
  662.     A0:SYS>save 2dh zcnew.com   ; Save the new memory image
  663.  
  664. With this technique there is no computing of offsets, and it uses only ZCPR3èbuilt-in  commands  (GET and SAVE).   The one thing you have to remember  is
  665. that the GET command loads entire files,  and so this technique can only  be
  666. used to patch in things that come in contiguous blocks with a length that is
  667. an  integral  multiple  of 128 bytes.   If you look at the memory  table  of
  668. ZC.COM,  however,  you  will see that this includes all system modules  that
  669. ever exist in the form of files: the CPR, DOS, NDR, ENV, TCAP, RCP, FCP, and
  670. IOP.   These  patches  can  be done very nicely  from  alias  scripts.   For
  671. example, since one might often change one's named directories, the following
  672. alias might be handy:
  673.  
  674.         alias PUTNDR:
  675.  
  676.                 IF NULL $1
  677.                 ECHO SYNTAX: $0 NDR-FILE-NAME
  678.                 ELSE
  679.                 ERA ZCNEW.COM
  680.                 GET 100 ZC.COM
  681.                 GET 1A00 $1.NDR
  682.                 SAVE 1DH ZCNEW.COM
  683.                 ECHO TEST ZCNEW.COM
  684.                 FI
  685.  
  686. Similar  aliases could be used for replacing other modules such as RCPs  and
  687. FCPs.
  688.  
  689.  
  690.                        New Command and System Modules
  691.  
  692.  
  693.      Speaking  of RCPs and FCPs,  let's talk a little about how we  generate
  694. new versions of these and other system modules.  There is no need to discuss
  695. the  patching techniques.   They are the same as what we have already  seen.
  696. The question is:  how do we generate the new SYS.RCP,  SYS.FCP,  and SYS.ENV
  697. modules?
  698.  
  699.      The procedure is the same as in a manual install system, except that in
  700. a manual install system we already had the necessary Z3BASE.LIB file that is
  701. required for the assembly of new system modules.   So far we have not needed
  702. one with Z-COM.   To make things easier,  Joe Wright has kindly provided  us
  703. with  a generalized Z3BASE.LIB file.   All we have to do to adapt it to  our
  704. system  is  to  use  an editor to fill in the  address  of  the  environment
  705. descriptor in the "Z3ENV SET ..." definition near the top of the file.   One
  706. further  hint:  while you are at it,  change the SET to an EQU.   If you use
  707. Z3BASE.LIB  to assemble a file in Zilog mnemonics,  the assembler  will  not
  708. accept  SET,  since that is a Zilog opcode.   You would have to change it to
  709. ASET in that case, but there is no reason not to use the universal EQU. Some
  710. programs also require definitions for YES and NO,  so you might want to  add
  711. the lines:
  712.  
  713.                 YES     EQU     TRUE
  714.                 NO      EQU     FALSE
  715. èOne last addition.   The RCP, FCP, and ENV modules do not need it, but other
  716. files,  and  most notably the command processor code,  require an equate  to
  717. define  the address of the entry point to the command processor.   This is a
  718. part  of  the  normal  Z3BASE file,  but Joe Wright forgot  to  put  it  in.
  719. Someplace after the Z3ENV equate, add the line:
  720.  
  721.                 CCP     EQU     Z3ENV - 1A00H
  722.  
  723. Now  you should be all set to assemble up new system modules,  like the  new
  724. FCP10 from ZSIG.   You might also want to assemble a customized SYS.ENV with
  725. the  correct values of maxdrive and maxuser and your own choice  of  printer
  726. and console definitions (see "ZCPR3, The Manual" for details).
  727.  
  728.      "ZCPR3, The Manual" explains in detail how to carry out the assemblies,
  729. though  I  find  that  the  discussion there makes  the  process  look  more
  730. complicated than it really is.   Basically, you assemble the module to a HEX
  731. file,  convert the HEX file to a COM file using MLOAD,  and then rename  the
  732. COM  file to the proper name for the module (e.g.,  "REN SYS.FCP=FCP10.COM).
  733. If  you have the SLR assemblers,  you can assemble the module directly to  a
  734. COM in a single pass and skip the MLOAD step.   Finally you test the  module
  735. by loading it using LDR.
  736.  
  737.  
  738.                       Replacing the Command Processor
  739.  
  740.  
  741.      Replacing  the command processor is no more difficult than changing any
  742. of the other modules in the system.   In fact,  as we will soon see,  it  is
  743. much  easier  to  test  a new CPR with Z-COM than it is  with  the  manually
  744. installed Z-System.
  745.  
  746.      The basic procedure is as we described for the RCP or FCP.   As  usual,
  747. edit the configuration LIB file (Z3HDR.LIB or Z31HDR.LIB if you are using my
  748. experimental version ZCPR315D) and assemble the code.   One additional hint.
  749. Again,  if you have the fabulous SLR Systems assemblers SLRMAC,  Z80ASM,  or
  750. SLR180,  select the option to assemble directly to a COM file,  not to a HEX
  751. file.   It  is  a  shame  that so many books and articles  have  taught  the
  752. unnecessarily  complex  patching  method  based  on  HEX  files  with  their
  753. extremely tricky offset calculation.   It is much easier to work with a  COM
  754. file where the load offset in the debugger is quite straightforward, namely,
  755. 100H  below  where you want the file to go,  no matter what address  it  was
  756. assembled  for.   If you are using an assembler that can produce only a  HEX
  757. file,  then  use the public-domain MLOAD to convert it to a COM file just as
  758. was done to make the RCP and FCP files.
  759.  
  760.      Now  that you have ZCPR3.COM or some such file,  all you have to do  is
  761. substitute it for the file ZC.CP in A15:.   It would be a sign of  foolhardy
  762. optimism  to destroy the original ZC.CP.   I would recommend renaming it  to
  763. something  like  ZCOLD.CP  and then copying the new one into  place  with  a
  764. command  like  "PPIP A15:ZC.CP=ZCPR3.COM".   Now just hit control-c to  warm
  765. boot, and the new CPR will be running!
  766. è     If  things did not work out as you intended (and especially if the  new
  767. CPR just crashed the system),  you can reboot and reload ZC.COM.   Remember,
  768. you did not change the CPR image in ZC.COM yet,  and things will be fine  so
  769. long  as  you  don't warm boot.   Before that  happens,  you  should  rename
  770. ZCOLD.CP back to ZC.CP.   Then you can try again.  That is sure a lot easier
  771. than  all  the  'sysgening'  required to test a new CPR  with  the  manually
  772. installed Z-System.
  773.  
  774.      If all went well,  the system is now running just the way you hoped  it
  775. would.   Once  you've tested it and are satisfied that it really is  working
  776. correctly,  you  can patch the new CPR into ZC.COM so that it will be  ready
  777. immediately after Z-COM loads.  The following commands will do it:
  778.  
  779.         A0:SYS>get 100 zc.com
  780.         A0:SYS>get 200 a15:zc.cp
  781.         A0:SYS>save 2dh zcnew.com
  782.  
  783. As usual, once you have verified that ZCNEW is working, rename it to ZC.COM.
  784.  
  785.  
  786.                              Summary and Plans
  787.                              -----------------
  788.  
  789.  
  790.      That  wraps things up for this time.   You now know how to make  enough
  791. patches to mold a Z-COM system pretty well to your own tastes.   If you have
  792. Z-COM,  I hope you will experiment some before the next column appears.   In
  793. that  column we will really dig into Z-COM and do some wild things.   If you
  794. have any suggestions or questions,  please send them along.   My address and
  795. phone numbers are listed below.
  796.  
  797.      As a little reward for those of you who plowed through this whole piece
  798. (or who were taught the trick I was as a freshman in college to read the end
  799. of  a paper or essay before you start at the beginning),  here is  a  little
  800. tidbit.   ZCPR  version  3.3 is coming very soon.   I already have a  nearly
  801. complete version of it patched into the Z-COM I worked up for this  article.
  802. I  expect that Z33 will have been released or will be very close to  release
  803. by  the  time  this  column  appears,  and I will devote  some  space  to  a
  804. discussion of its new features in the next column.
  805.  
  806.                                         Jay Sage
  807.                                         1435 Centre Street
  808.                                         Newton Centre, MA 02159
  809.                                         voice: 617-965-3552
  810.                                         modem: 617-965-7259
  811.  
  812. [This article was originally published in issue 28 of The Computer Journal,
  813. P.O. Box 12, South Plainfield, NJ 07080-0012 and is reproduced with the
  814. permission of the author and the publisher. Further reproduction for non-
  815. commercial purposes is authorized. This copyright notice must be retained.
  816. (c) Copyright 1987, 1991 Socrates Press and respective authors]
  817.