True, February is a short month, but somehow I don't think that explainsì
why the beginning of February (the due date for this column) came quickerì
than usual. It is probably a good thing that I have convinced severalì
others to start contributing regular columns to TCJ. That way, Art Carlsonì
may be busy enough not to notice that the deadline passed without my column. ì
Because it is late and because we now have quite a few prolific writersì
joining the TCJ ranks, I'm going to keep my column shorter than usual thisì
time (I know I have said that before, but this time I think it really willì
be true).
For this issue I will be catching up on some correspondence, informingì
you of the imminent release of the first high level language for Z-Systemì
programming, bringing you up to date on Z-Node developments (there is a newì
Z-Node Central), and beginning a discussion of issues related to bringing upì
a remote access system (so that more of you might decide to set up a Z¡
Node).
Letters
Despite our requests for letters with your comments and suggestions, weì
don't get very many. Recently, however, Art forwarded to me two lengthy andì
thoughtful letters from James Ott. I would like to begin by addressing someì
of his comments and questions.
The ZCPR33 Programmer's Reference Manual
First, Mr. Ott asked about the "Programmer's Reference Manual" to which Iì
made reference in my ZCPR33 User's Guide. Well, the truth is that afterì
writing the user's guide, I really didn't have energy left for another majorì
manual. Instead, I started to release programming notes one at a time asì
files on the Z-Nodes. Even at that, I only got to three of them. The filesì
have names of the form Z33PNOTE.###, where "###" is a sequence number. Noteì
001 deals with the command status flag in the message buffer and theì
extensions in its use introduced with ZCPR33. Note 002 discusses properì
coding techniques for shells under ZCPR33 and later. The third note coversì
the parsing of files by the Z33 and Z34 command processors. I am tempted toì
reproduce some of that material here, but then I would surely fail in myì
resolve to keep this column to a reasonable length. So you will just haveì
to look for them at the Z-Node in your neighborhood. If it is not there,ì
see if the sysop will get a copy from Z-Node #3.
Shells and ZEXè
Mr. Ott continued: "The User's Guide mentions an addition to shell codingì
necessary to ensure the shell pushes its name onto the shell stack when itì
is called by ZEX." I think there is some misunderstanding here. It wasì
under previous versions of ZCPR3 that special code was required in shells toì
deal with ZEX (and it never had to do with pushing anything onto the shellì
stack). Under Z33 and later, this code can (and, to make the programsì
smaller, should) be removed. It has now been quite some time since theì
release of ZCPR33, and I think that most shells are now coded in the moreì
efficient way.
As we have discussed in previous columns, a shell command comes into playì
when the command line buffer becomes empty. In that case, if there is aì
command on the shell stack, the command processor invokes that commandì
instead of asking the user for the next command line. In this way, theì
shell takes over the function of the command processor.
ZEX's function is similar to that of SUBMIT and XSUB together. Whileì
SUBMIT stores its script data in a disk file, ZEX keeps it in memory. Thisì
enables ZEX to run much faster, but it reduces the memory available toì
programs. A simple SUBMIT script feeds a series of commands to the commandì
processor, thus doing under CP/M what the multiple command line of ZCPRì
does. SUBMIT can be useful even under ZCPR, however, because it can supplyì
a longer string of commands than could fit into the command line buffer.
XSUB running under SUBMIT allows characters in the script to be fed notì
only to the command processor but also to programs as they run. This isì
what is called input/output (I/O) redirection. In this case it is inputì
redirection; the operating system is made to take its characters not fromì
its normal source -- the keyboard -- but from a disk file (SUBMIT) or aì
memory buffer (ZEX). This is both extraordinarily useful andì
extraordinarily tricky. Long ago I promised to discuss this subject atì
length in this column, but I have never gotten around to it. Bridgerì
Mitchell, Joe Wright, and I are now engaged in a joint project to perform aì
major upgrading of ZEX, and I am sure it will be the subject of TCJ columnsì
by one or more of us.
The ZCPR33 command processor observes the following hierarchy forì
acquiring new commands, where step 1 has the highest priority and step 5 theì
lowest. The way this hierarchy functions is described in more detail in theì
ZCPR33 User's Guide.
1. Commands pending in the multiple command line buffer
2. Commands from a ZEX script
3. Commands from a SUBMIT script
4. A shell command
5. User input
Under ZCPR30, ZEX did not appear explicitly in this hierarchy; it cameì
into play only by virtue of its ability to redirect input at step 5. Thisì
posed a serious problem when a ZEX command was issued under a shell. ì
Although the user intended the script to be performed as commands, the shellìèwould take it as input to the shell instead. To avoid this, rather lengthyì
code had to be included in every shell to see if ZEX was running and, if so,ì
to feed its input directly to the multiple command line buffer. Thisì
resulted in completely useless loads of the shell code for each line of theì
ZEX script. Execution was so slow and annoying that for all practicalì
purposes ZEX scripts could not be run under shells.
The ZCPR33 command processor was redesigned to deal with ZEX explicitlyì
just as ZCPR30 always did with SUBMIT. ZEX was placed above SUBMIT in theì
hierarchy so that ZEX scripts would function like arbitrarily long commandì
lines and could be invoked from SUBMIT scripts.
The New Libraries
Mr. Ott had several questions about the assembly-language libraries thatì
support the Z-System. I will not comment extensively here, but I would likeì
to announce that new versions of the libraries, which have been in use by aì
number of us for many months already, will soon be made available to theì
public. I had expected them to be a commercial product, but, for severalì
reasons, it now appears that the code will be made available at no charge. ì
Only the manual, which will be quite a large book, will be sold. This isì
good news.
One of Mr. Ott's suggestions was that the Z3LIB routine called PRGLOAD,ì
which is used for chaining from one program to another, be updated to allowì
for type-3 programs. This probably could be done without a great deal ofì
difficulty, but I am not sure that it is worth the trouble. What aboutì
type-4 programs? Loading them is much more complex because of the need toì
compute the relocation to a run-time address. It seems to me that a betterì
way for programs to chain to other programs is via the multiple command lineì
buffer. If anyone can suggest any advantages of a direct load, I would beì
interested in hearing them.
The Command Line Tail
One of the mistakes in ZCPR30 was its failure to check for command lineì
tails that would not fit in the buffer from 80H to FFH. CP/M had no problemì
with this because the whole command line was not long enough to allow thisì
to occur. With a 200-or-more-character command line buffer, there isì
nothing to stop a user from entering a command with a tail longer than 128ì
bytes. Under Z30 this caused a catastrophe, because the tail was copiedì
into the buffer after the program was loaded, and then the tail couldì
overwrite the beginning of the code. Z33 and later monitor the length ofì
the tail and stop copying before this can happen.
With type-3 programs that load at addresses higher than 100H, longerì
tails could be copied without damaging the code, and Mr. Ott requested thatì
this be implemented in future versions of the command processor. I thinkì
this would be a very bad idea. One of the reasons for using type-3 programsì
is so that any code residing at 100H can be run again later using the GOìècommand. If the type-3 program's tail overwrote the TPA, then trouble wouldì
occur when the GO command was executed.
Moreover, there is absolutely no need for such a feature. If a programì
wants to support a tail longer than 126 bytes (it doesn't even have to be aì
type-3 program), it can simply read its arguments not from the buffer at 80Hì
but directly from the multiple command line buffer. As an aside, I haveì
thought of making the command processor not convert the command line bufferì
to upper case. Then programs could process lower case input directly (as inì
MS-DOS) without the special symbols to indicate case shifts as in the ECHOì
and IF INPUT commands. The command tail buffer at 80H must be converted toì
upper case for compatibility with CP/M programs, which assume that that willì
be done. Besides the fact that there might be a significant code penaltyì
(the command tail buffer and the command file control block would both haveì
to be individually case shifted), I worry that there may be a number of Z¡
System programs that either rely on the command line being in upper case or,ì
worse, convert it to upper case. I'd be interested in hearing any opinionsì
on this topic.
Still More on Z3 vs. Z2 Shells
Mr. Ott sent me a lengthy letter with some interesting examples of theì
use of the shell stack. I think his is the first response I have receivedì
that pointed out an aspect of the shell stack that I had not previouslyì
appreciated.
I don't think about shell command lines with more than one command, soì
the following distinction never occurred to me. One can think of the shellì
stack as containing not just, say, four commands but rather four groups ofì
commands. The shell stack not only holds these commands; it also providesì
the mechanism for grouping them, for providing parentheses, if you will. ì
The Z2 approach to shelling would have a very hard time doing this. Forì
example, if the first element on the shell stack contains the command lineì
"CMD1A;CMD1B" and the next lower element the line "CMD2A;CMD2B;CMD2C", theì
equivalent Z2 situation would have the command line
CMD1A;CMD1B;CMD2A;CMD2B;CMD2C
The SHCTRL POP command removes an entire Z3 shell entry, containingì
possible multiple commands. How could we implement this function with aì
Z2-style shell? Even if each command were marked with a "/s" token, oneì
could still not tell which ones were grouped with which. There might be aì
solution to this problem, but the Z3 shell approach certainly handles itì
nicely.
Mr. Ott's letter included a very interesting application example. I'veì
made a few changes that, I hope, do not harm its essence. When the computerì
is booted, the STARTUP alias loads the command sequence "FIRSTSH;MENU",ì
where FIRSTSH is a special utility that places the following commandì
sequence onto the shell stack:
è PARK;VID RST.MSG;STOP
When this sequence runs, it will park the heads on the disk drive, display aì
message to shut off the computer, and run a program called STOP that locksì
the machine. Of course, this multiple-command shell could easily beì
replaced by an alias SHUTDOWN.
This termination shell does not run immediately because of the commandì
MENU following it in the command sequence. This loads a second shell ontoì
the shell stack. The user then lives inside the MENU shell for some time. ì
At some point, the user may make a selection that generates the command "CDì
WORK:". This would log into the WORK: directory and issue an automatic STì
command there. The ST alias might have the script
LDR WORK.NDR;SHCTRL POP;ZFILER
This would install a new set of named directories, pop MENU off the shellì
stack, and replace it with the ZFILER shell. The user could then do someì
work using ZFILER. From ZFILER, a macro command might make another shellì
change by popping the shell stack and installing another shell.
The above process would continue until the user made an exit selection. ì
This would pop the shell stack without installing a new shell. As a result,ì
that first line we put on the shell stack would become active, forcing theì
computer to be shut down in an orderly, preplanned way. Of course, thisì
approach is not totally foolproof if the user has access to the power switchì
or power cord. But it certainly helps.
Mr. Ott worried that this example could not be achieved using a Z2 shellì
system. I think it could, though not with quite the same ease and elegance. ì
The STARTUP alias would contain the line
MENU;SHUTDOWN
When MENU ran, it would substitute for itself in the command line theì
desired command line plus its own reinvocation command with the flag "/S" toì
mark it as a shell. Thus the command line would become
USERCMD;MENU /S;SHUTDOWN
For the user command CD WORK:, the command buffer would evolve as follows:
CD WORK:;MENU /S;SHUTDOWN
ST;MENU /S;SHUTDOWN
LDR WORK.NDR;SHCTRL POP;ZFILER;MENU /S;SHUTDOWN
When the SHCTRL command ran, it would scan the command line for the nextì
shell command as marked by the "/S" flag and remove it from the commandì
line. This would leave one with
ZFILER;SHUTDOWN
èWhen ZFILER generates a macro command, the command buffer would have
MACROCMD;ZFILER /S;SHUTDOWN
This would continue until one cancelled the shell. Then the SHUTDOWN aliasì
would run.
Mr. Ott was concerned that the command line would grow longer and longerì
as old shell commands piled up. Indeed, this would happen if there were noì
'popping' mechanism. The "/S" marker I proposed in my previous columns isì
critical here, since without it there would be no way to tell which commandì
to pop. This approach, I think, would fail with aliases as shell commands. ì
The Z3-type shell really helps us in this case.
High-Level-Language Support for Z-System
I have some especially exciting news about the first high level languageì
specially designed for Z-System. In late January, I got a phone call fromì
Leor Zolman, author of BDS C. He was interested in bringing out a newì
version of his C compiler for the modern 8-bit market. After someì
consultation with me on what was needed to support Z-System, Leor went toì
work on the run-time code, and in less than two weeks he had a version readyì
for beta testing
He came over to my house to demonstrate the result, and I was amazed toì
see how easily one could write a utility, complete with named-directoryì
support, even including password protection. A little fine-tuning is stillì
needed, but I am already excited about the impact that the availability ofì
this quality high level language will have on Z-System development. ì
Marketing details have not been worked out at this point, but you can expectì
the new BDS C to be available at an attractive price through Z Systemsì