home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
zcpr33
/
z3-33
/
z33pnote.002
< prev
next >
Wrap
Text File
|
1994-07-13
|
6KB
|
116 lines
ZCPR33 PROGRAMMING NOTES
========================
Note Number: 002
Author: Jay Sage
Date: June 6, 1987
The Design of Shells Under ZCPR33
The ZCPR33 command processor follows a very clear and strict hierarchy
for acquiring new commands. It goes as shown below, with step 1 having the
highest priority and step 5 the lowest. The way this hierarchy functions is
described in more detail in the ZCPR33 Users Guide. We will focus here on
the effect this hierarchy has on the design of shells.
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
The significant change here from ZCPR30 is in the position of ZEX
input. In ZCPR30, ZEX simply took over the function of user input and thus
appeared in the hierarchy in parallel with user input at the lowest priority
level. This would have led to very bizarre behavior under shells, and so
special, and rather lengthy, code was included in every shell to see if ZEX
was running and, if so, to feed its input to the multiple command line
buffer. This resulted in completely useless loads of the shell code for
each line of the ZEX script. For all practical purposes, ZEX scripts could
not be run under shells. Since the ZCPR33 command processor has been
redesigned to place ZEX above shells in the hierarchy, this code should not
be included in new shells and should be removed from existing shells.
There was a second inefficiency in the way shells operated that I fixed
shortly after ZCPR3 was introduced (my first programming contribution). A
little background is required to understand this situation.
Shells have two distinct personalities or functions. When a shell is
invoked by a user command, its function is to install itself on the shell
stack so that later, when there are no pending commands at levels 1, 2, and
3 in the hierarchy above, the command processor will invoke that shell
automatically. When that happens, the shell's second personality comes into
play. When invoked not by the user but by the command processor, the shell
is to perform its real work (this depends on the kind of shell).
The shells that Richard Conn first created for ZCPR30 worked strictly
according to this model. This resulted in very annoying behavior when the
user entered the shell command alone on a command line. The shell would be
loaded from disk, would note that it had been invoked by the user, would
install its command on the shell stack, and then would return to the command
processor. Next, the command processor, noting that no commands were
pending in the command buffer, would turn to the shell stack and execute the
command on the top of the stack (the shell we just installed). It would
load the shell from disk (again), and the shell code, noting that it had
been invoked not by the user but by the command processor, would perform its
shell function.
This second loading of the shell from disk was a complete waste of time
and disk activity, since the shell code was already in memory. Many years
ago I added code to the common shells to prevent this double loading. When
the shell was invoked by the user, the code I added would check to see if
there were any commands pending in the multiple command line buffer. If
there were, after installing itself on the stack it would terminate
execution as before. However, if there were no commands pending, it would
proceed to carry out its shell function immediately. This cut the time to
start up a shell in half.
The logic behind this approach worked most of the time, but it had a
flaw. If a SUBMIT job were in progress at the time the shell was installed
by the user, even using a single command on the command line, the shell
should not have started to perform its shell function but should have
returned to the command processor for the next SUBMIT command. I did not
include the SUBMIT capability in my implementation of ZCPR3, and so I never
thought of this.
With the new command acquisitiion hierarcy under ZCPR33, the shell
should not proceed directly to its shell function when commands are pending
from either the command line, a ZEX script, or a SUBMIT script. Pseudo-code
for a shell should look like this:
entry:
Initialization functions
IF invoked by user (shell bit in command status flag not set)
push the shell command onto the shell stack
IF multiple command line not empty, return
IF ZEX running, return
IF SUBMIT running, return
ENDIF (invoked by user)
Perform real shell function
Return
end
The three tests that determine whether the code should terminate after the
command is pushed onto the shell stack can be performed easily using calls
to library routines. The code will look like this.
call getcl2 ; Z3LIB routine returns with zero flag
; ..reset if there are more commands in
; ..the command line buffer
jr nz,ccp ; If pending commands in buffer, return
call getzrun ; Z3LIB routine resets zero flag if ZEX
; ..is running
jr nz,ccp ; If ZEX is running, return to CCP
call getsrun ; Z33LIB routine resets zero flag if SUBMIT
; ..is running
ccp: jp nz,gotoccp ; If SUBMIT is running, return to CCP
; Else fall through to shell function code
shellfunction: