IK0POR.HLP                                               1991 Sept
 
Notes on porting Kermit-370 to other operating systems.  This document
consists of three parts: a general specification of functionality, a
detailed guide to some of the more arcane sections of system-specific
code in Kermit-370, and a summary of all the modules within Kermit-CMS.
 
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
A. Feasibility.
 
The following is a list of system-specific operations that must (or
should) be performed by Kermit-370.  Each item is labeled with its
degree of importance and with the name(s) of the macro and/or routine(s)
that perform the function.  The importance level is marked with ">>" and
the program components with "<<".  Names of macros are further marked
with asterisks; routines are usually coupled with function codes.  The
presence of both a macro and a routine indicates that the macro serves
only to invoke the routine.
 
       TERMINAL FUNCTIONS
 
 1. Read from the terminal with possible prompt.  Return length read.
    Leave text in specified buffer (unedited, if possible).  Should
    follow techniques of utility programs, if any, such that command
    procedures can issue Kermit subcommands (if possible).
    >> Essential.
    << * RTEXT
 
 2. Display text at the terminal.  Ok if system supplies a CRLF.
    >> Essential.
    << * WTEXT
 
 3. Test for stacked lines of terminal (or pseudo-terminal) input.
    >> Cosmetic.  Avoids extra prompts and synchronizes "banner" display
       at startup.
    << SUPFNC,7
 
 4. Set up a new prompt string, if necessary, for subsequent terminal
    read requests.
    >> Only if needed for #1.
    << SUPFNC,11
 
 5. Clear the screen (if possible).
    >> Cosmetic.
    << SCRNIO,0
 
       SYSTEM FUNCTIONS
 
 6. Analyze user environment at startup and determine if suitable.  Save
    any quantities needed and condition the line for entering commands.
    Determine, if possible, the terminal controller type insofar as that
    is necessary for establishing the method of file transfer.
    >> Essential.
    << SETMSG,1
 
 7. Reperform system-dependent initialization after SET LINE command
    selects a new communication line.
    >> Needed for SET LINE subcommand.
    << SETMSG,5 + SCRNIO,3
 
 8. Reverse any setup performed in #6 and clean up before returning to
    system.
    >> Essential.
    << SETMSG,4
 
 9. Obtain free storage block of specified length.  Return error code,
    if possible, when enough storage is not available.  Method should
    be re-entrant if possible and must preserve registers 2-13 without
    recourse to the save area pointed to by R13.
    >> Essential.
    << * DMSFREE
 
10. Release free storage block of specified address and length.
    >> Essential.
    << * DMSFRET
 
11. Invoke the system HELP facility with optional operand string.
    >> Cosmetic, but very useful.
    << KHELP
 
12. Start typeout interception.  If possible, this should include all
    possible terminal output regardless of source.  At a minimum, it
    must result in messages from Kermit itself being saved in a buffer
    instead of displayed.  The intercepted output may be stored wherever
    convenient.
    >> Needed for REMOTE operations in server mode.
    << SUPFNC,1
 
13. Stop interception and restore normal terminal functions.
    >> Needed for REMOTE operations in server mode.
    << SUPFNC,5
 
14. Retrieve intercepted messages and copy them, if necessary, to the
    Kermit disk buffer.
    >> Needed for REMOTE operations in server mode.
    << SUPFNC,2
 
15. Execute a host command (with or without interception).  Generally,
    the command text may be of two different forms: either a text
    string extracted from a text buffer or a canonical, internal
    representation requiring perhaps less system overhead.  Commands
    invoked by Kermit for purely internal purposes should be of the
    latter form.  If possible, detect whether the command is legal
    before invoking it.  Detect in any case whether the command is legal
    sooner or later.
    >> Cosmetic, but very useful.  If necessary, a minimal set of host
       commands can be emulated.
    << SUPFNC,3
 
16. Retrieve original command string by which Kermit was invoked.  This
    need not be done more than once (at startup).
    >> Needed for specifying a subcommand in original command line.
    << SUPFNC,6
 
17. Log off the current session.
    >> Needed for honoring BYE command.
    << SUPFNC,8
 
18. Wait for a specified time (in seconds).
    >> Needed for DELAY parameter and possibly for screen synchronizing.
    << SUPFNC,9
 
19. Return the current clock time (in centiseconds).  The code is fully
    generic, even though the function is done in SUPFNC.
    >> Needed for statistics and long-packet optimizing.
    << SUPFNC,10
 
       DISK/FILE-SYSTEM FUNCTIONS
 
20. Select a "working directory" specified by a string extracted from
    a text buffer.  The directory is, of course, a concept defined
    within the context of the operating system.  Subsequent files are
    preferentially read from and written to the directory.
    >> Needed if the directory concept is implemented: CWD subcommand.
    << CWDSET
 
21. Show space available in the "working directory" or other area.
    >> Needed for the SPACE subcommand.
    << DSPACE
 
22. Open a disk file by name for input (or return a non-zero code in
    case of failure).  If necessary, refer to default file attributes
    specified to Kermit to aid in locating the file.  Return a data area
    filled with the file attributes and a pointer to a storage block
    reserved for controlling the I/O (a "ticket").  OPENF is a generic
    macro.
    >> Essential.
    << * OPENF I + DISKIO,1
 
23. Open a disk file by name for output (or return a non-zero code in
    case of failure).  If the file already exists, prepare to either
    overwrite it or append to it as the occasion requires.  If the file
    is to be extended, be sure its attributes are not altered.  Return
    a data area and "ticket" as with opening for input.
    >> Essential.
    << * OPENF O + DISKIO,2
 
24. Test for the existence of a file by name.  Return a data area with
    the file attributes if found.
    >> Essential.
    << * OPENF T + DISKIO,3
 
25. Close the file specified by a "ticket".  The ticket should then be
    "blank", so that reclosing would have no ill effects.  CLOSF is
    generic.
    >> Essential.
    << * CLOSF + DISKIO,4
 
26. Write a record out to a disk file specified by a "ticket".  The data
    address and length must be subject to change with each invocation,
    but must be retained if not explicitly changed.  A completion code
    of 13 must be returned if the write encounters a full disk.  Any
    other I/O error must return some other non-zero code.
    >> Essential.
    << * WRITF + DISKIO,10
 
27. Read a record in from a disk file specified by a "ticket".  The
    buffer address and length must be subject to change with each
    invocation, but must be retained if not explicitly changed.  If line
    numbers are kept in predictable locations within each record, there
    must be an option to remove them before returning the length of data
    read.  If the end of the file is reached, a completion code of 12
    must be returned.  An error must return some other non-zero code.
    >> Essential.
    << * READF + DISKIO,9 or DISKIO,0
 
28. Update the disk directory for given file (specified by a "ticket")
    such that the file is still open for output.
    >> Needed for SET DEBUG SAVE subcommand.
    << * SAVEF + DISKIO,21
 
29. Set up disk directory search for files matching a given pattern
    name.  This may entail as little as saving the pattern or as much
    as creating a file with the complete list of matches.  Note: the
    former is dangerous in a multi-user system if the name space to be
    searched can be altered while Kermit is searching, especially if
    control blocks can be unchained.  The latter approach also has a
    drawback, in that files can still be created or deleted after the
    "complete" list is made.  NXTFSET is a generic macro.
    >> Needed for wildcard filespecs.
    << * NXTFSET + DISKIO,5
 
30. Fetch the next filespec from a directory search and get a pointer to
    a list of its file attributes.  Must return a non-zero code if no
    more files (and must persist even if called repeatedly).  NXTF is
    a generic macro.
    >> Needed for wildcard filespecs.
    << * NXTF + DISKIO,6
 
31. Clean up after a disk directory search.
    >> Needed for wildcard filespecs.
    << * NXTFSET END + DISKIO,7
 
32. Check candidate name of a directory for validity and accessibility.
    >> Needed for CWD subcommand.
    << * NXTFSET CWD + DISKIO,8
 
33. Test current directory (or environment) for sufficient disk space.
    >> Cosmetic, used for processing A-packets.
    << DISKIO,11
 
34. Analyze disk I/O error; set up error message and code.  ERRF is a
    generic macro.
    >> Cosmetic, but useful.
    << * ERRF + DISKIO,12
 
35. Display directory information about specified file (possibly with
    wildcard notation).
    >> Needed for DIR subcommand.  Cosmetic, but very useful.
    << DISKIO,13
 
36. Delete a specified file.  ERASF is a generic macro.
    >> Cosmetic, but useful, especially for REMOTE server functions.
    << * ERASF + DISKIO,14
 
37. Rename a specified file.
    >> Cosmetic, but useful, especially for REMOTE server functions.
    << DISKIO,15
 
38. Copy a specified file.
    >> Cosmetic, but useful, especially for REMOTE server functions.
    << DISKIO,16
 
39. Parse input string for a filespec under a variety of circumstances.
    The name must be converted to a uniform internal format suitable for
    Kermit I/O routines.
      a) Native file for input (possible wild-card notation).
      b) Native file for output.
      c) Foreign filespec.
      d) TAKE file (input or output).
      e) Native file for utility operations.
    >> Essential.
    << FSPEC (q.v.)
 
40. Check a given filespec for uniqueness and either generate a unique
    new name if possible or return an error indication if necessary.
    Possibly query the user for permission to overwrite a file that
    already exists, provided the filespec was entered by hand.
    >> Essential.
    << FSPEC (q.v.)
 
41. Convert an internal filespec to the form for transmission.
    >> Essential.
    << FSPEC (q.v.)
 
42. Convert an internal filespec to the display form.
    >> Needed for STATUS display and transaction log.
    << FSPEC (q.v.)
 
43. Open a library *per se* for purposes other than transferring its
    members.  OPENF is a generic macro.
    >> Useful if the concept of libraries is important.
    << * OPENF L + DISKIO,22
 
44. Skip over the first "n" records of a newly-opened input file.
    POINTF is a generic macro.
    >> Useful for SEND with line range.
    << * POINTF + DISKIO,23
 
       COMMUNICATION FUNCTIONS
 
45. Open a specified communication line for I/O (default to the terminal
    connection).  Set parameters needed for transparent operation.  The
    procedure may depend on the type of terminal (or line) controller
    and should include both linemode and fullscreen types.  After the
    line is open, if it is the terminal, no display messages will be
    issued by Kermit, and messages from other sources should also be
    suppressed, if possible.  These opening functions are to be divided
    into controller-specific (of which there may be different variants)
    and general.
    >> Essential.
    << TERMIO/SCRNIO,1 + SETMSG,2
 
46. Close the current communication line.  Restore normal operation.
    The same division of functions obtains as in #45.
    >> Essential.
    << TERMIO/SCRNIO,2 + SETMSG,3
 
47. Write a packet to the communication line.  If possible, control the
    entire contents, including terminators.  Also, if possible and if
    Kermit will immediately be requesting a read, begin the following
    read operation so that there is no delay between the completion of
    the write and the readiness of the system to read -- this may be
    important in a heavily loaded time-sharing environment.
    >> Essential.
    << TERMIO/SCRNIO,4
 
48. Read a packet from the communication line.  If possible, suppress
    any prompts the system might normally supply.  If possible, arrange
    for a timer interrupt after a specified wait such that the I/O
    request can be cancelled.
    >> Essential.
    << TERMIO/SCRNIO,5
 
49. For fullscreen lines, write a message to the screen despite the line
    having been opened.
    >> Cosmetic, but useful.
    << SCRNIO,6
 
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
B. Hints.
 
In general, the operation of porting Kermit-370 entails starting from
one or more existing versions of the system-specific code (IKxMAC.ASM
and IKxUTL.ASM) and replacing one set of system-specific code with
another.  Each subroutine has comments documenting the interface with
the rest of the program, and a fair amount of the code itself deals with
such bookkeeping details and can be carried over.  Similarly, each macro
begins with a brief function/syntax description.  In one example
(porting Kermit-370 to the MUSIC O.S.), about 2/3 of the final macro
definition code had been carried across from CMS as well as about 2/5 of
the final MUSIC-specific subroutine code.  In all, only about 850 lines
of non-comment code had to be written.  In another example (porting to
CICS), only about 1/2 of the macro definition code had been carried
across, along with about 1/4 of the subroutine code.
 
In some cases, particularly when the operating system is supplied in
source form, it may be useful to examine the system code and macro
definitions for helpful hints on the techniques of invoking system
functions, manipulating filespecs, and the like.  Care should be taken,
of course, not to violate copyright restrictions.
 
------------------------------------------------------------------------
Parameters.
 
It is necessary to define the symbols in the SSYMS macro.  A useful
technique is to compare two existing variants to determine which
symbols are always present.  Items in the KSYSTF macro are also system-
specific, and many of them are required in all variants; some are not
required, but are generally useful (again, compare existing variants
for tips).
 
------------------------------------------------------------------------
Entry and exit conditions.
 
Kermit at entry should have R13 -> 72-byte save area and R15 -> Kermit,
and there must be a macro SAVE similar to that of MVS.  If there is no
system macro SAVE, Kermit must supply one itself.  If necessary, that
macro can distinguish between internal linkages (in which R13, R14, and
R15 *must* follow type-I conventions) and the initial call from the
system (which may be anything at all).  The entry conditions for Kermit
consist of two macro calls:
         SAVE  (14,12),,&LABEL
         KMAIN ENTER
plus code appropriate to internal linkages.  &LABEL will be either GUPI
or KERMIT.  For internal linkages, that parameter is always "*".  After
the invocation of KMAIN, R13 must point to the original save area, of
which the first 12 bytes must be unused, and if the values originally in
R0 and R1 were important, they must be saved in bytes 20-27.  KMAIN
ENTER must assign free storage and zero-fill it; point register KWRKBASE
at the storage, register KSUBBASE at Kermit, and R10 at COMMON; and set
up pointers to the stack.  KMAIN RETURN must release the storage,
restore any registers necessary, and return to the system with the
proper condition code (initially in R15).
 
------------------------------------------------------------------------
FSPEC.  Notes from source code:
 
* Entry: R1->name field, R0=flags selecting operation (see below)
*        For parse operations, SCANPTR defines the input string.
*        For getting foreign or display filespec, R7->output buffer
* Exit: if not FFNEW, then R15=0 if ok, 1 if ?, 2 if bad.
*        For R15=1 or 2 R3,R4 give message.  ERRNUM may be leftover.
*
*                                 Flags:                  Notes:
*   Tasks:               FFRCF FFSND FFGET FFNEW
* Parse RECV               X                     set ROVR properly
* Parse SEND 1st                 X
* Parse SEND 2nd           X     X
* Parse GET 1st                        X
* Parse GET 2nd            X           X         set ROVR properly
* Parse F-packet   (FFHDR) X     X     X
* Parse for Generic(FFUTL)       X     X         FFWLD: allow partial
* Parse TAKE
*
* Get unique name                            X     R15: 0=>ok, 1=>bad
* Interactive name check               X     X     R15: 0=>ok, 1=>bad
* Get foreign name (FFENC) X                 X     R15->end of string
* Get display form (FFDSP)       X           X     R15->end of string
 
Further explanation of entry conditions -
"name field" is a fixed-length string of length LFID to be filled with
the internal representation of a file name.  SCANPTR is a pair of
pointers (LEN, ADR) of a character string to be parsed, typically a
string typed by the user, possibly in lower case.  Note: Kermit assumes
that a file specification will fit into a string of no more than 256
bytes, i.e., LFID must be <257.
 
FSPEC parses out one filename at a time.  There is, of course, the
alternate command syntax for SEND that allows the user to specify a list
of files.  The only contribution of FSPEC to the parsing is to note the
delimiter it finds after the name; the list control is managed by the
generic code.
 
SEND takes one or two parameters, namely, the native filename and,
optionally, a different filename to send to the other Kermit.  A
reversed pair of parameters is taken for the GET subcommand: a required
"foreign" filename and an optional overriding "native" one.  Foreign
filenames, since they depend on the system of the other Kermit, might be
thought of as independent of the IBM/370 operating system, but
Kermit-CMS offers a special syntax extension that isn't implemented in
Kermit-TSO.  Anyway, that is the meaning of SEND 1st, etc.  The foreign
filename, by the way, is stored in JFSPEC, which is a varying-length
string in COMMON (one-byte length indicator, followed by a maximum of 47
bytes).  "Parse RECV", in case that's not clear, means grab the
filename, if any, entered on the RECEIVE subcommand, and (as the Note
says), set flag ROVR in FL1, if a filename is actually found.  I also
note that the code clears flag NMOK in FL4 (in the CMS version), but
that happens to be part of the internal logic of FSPEC to avoid
duplicate efforts in filename collision testing.  "Parse F-packet" means
grab a (valid) filename from the file header sent from the other Kermit.
"Parse for Generic" means grab a filename from the text string sent by
the other Kermit for one of the Generic Server mode commands.  The
corresponding Note says that FFWLD set in the input flags means that
part or all of the filename can be omitted to indicate all matching
files, as in the DIRECTORY command.  "Parse TAKE" means grab a file name
from the text of a TAKE subcommand.
 
The difference between "Get unique name" and "Interactive name check" is
that the latter is permitted to type out a message and query the user
for further instructions if necessary (as might be the case when the
user types RECEIVE DUP.FILE), while the former must either find a unique
name, or return an error condition.  "Get foreign name" means putting
the foreign filespec into a buffer (in ASCII) with JFSPEC taking
precedence over whatever is found at (R1).  Finally, "Get display form"
is just the reverse of the various parse operations: the internal
representation is converted to conventional external representation
(with excess blanks, if any, removed according to whatever convention
holds).
 
------------------------------------------------------------------------
FDB.  File Descriptor Block + File Access Block:
 
In IKxMAC.ASM, the FDBD macro has two parts, an FAB and FDB.  The FAB is
intended to map the operating system's macro, whereas the FDB is
Kermit's local variables.  Some of the variables in the FDB are used
throughout the generic Kermit code.  The common part begins at FDBD and
includes everything mapped by FDBPAT macro, and also includes FABLRTR,
which is a recent addition giving the maximum record length for output
to a file (which may in CMS, for example, differ from the current
largest record length).
 
------------------------------------------------------------------------
Host command execution.
 
Not all operating systems make it possible for one application program
(such as Kermit) to invoke another.  When that is not possible, Kermit
should make an effort to emulate the basic file-management commands
corresponding to DISKIO functions 13-16 plus the appropriate commands
(even if the system doesn't have them) to invoke on-line help and to
display a file at the terminal.  For an example of how such emulation
can be done, see function 3 of SUPFNC in the MUSIC version of Kermit.
Some calls to SUPFNC are generated internally by Kermit-370 itself
(these are identified by *not* having flag UCMD set in FL4).  Such calls
should not require any syntax checking and may, in fact, be already
converted to a special "system" format, if any, suitable for passing
directly to the command processor.  The details of formatting and syntax
check will, of course, be highly system-specific.
 
------------------------------------------------------------------------
SCRNIO.  Fullscreen packet I/O.  See part C for calling sequence info.
 
For the Series/1 interface (and whenever else possible), Kermit-370
takes advantage of a Read chained to a Write to speed up the I/O.
Actually, the operation is chained by the Series/1, so Kermit issues
both a write and a read synchronized by a hardware interrupt from the
Series/1.
 
Fullscreen buffer limits are defined by symbols MAXWS and MAXRS set in
macro SSYMS.
 
In principle, all you need to know is the sequence of calls to SCRNIO.
You can handle the system interface in any convenient manner.  The
sequence is (by R0 code): 1, 6 (with greetings message), 4, 5, 4, 5, ...
4, 5, 2.  The value of WRRD determines whether a "4" means Write/Read
(value is 5) or just Write (value is 0) -- that value will always be 5
except possibly the last time.  Even if WRRD is 0 on the last call with
R0=4, there will still be a call with R0=5 just afterwards, followed by
a call to release control of the screen.
 
The difference between "4" and "6" is just that no read is required
following a "6".  Also, "6" is intended for displaying messages to the
user, in case he's watching, but "4" is for sending to the micro Kermit.
 
------------------------------------------------------------------------
TERMIO.  Similar to SCRNIO in many respects.
 
TTY buffer limits are defined by symbols MAXWT and MAXRT set in the
macro SSYMS.
 
The way to signal a timeout from TERMIO is to return a packet of exactly
one character: an ASCII 'T'.  You can see an example by looking at the
TSO version.
 
There is a potential problem for Kermit transfers that arises if the
user has a printable character for any editing functions used in the
interpretation by the system of terminal input.  Examples of such
functions include character-delete and line-end (both normally found
only on line-mode terminals).  If such a character appears in a packet
sent to the 370, the packet will be mangled unless Kermit takes special
precautions.  CMS Kermit deals with the problem by noting the LINEDIT
setting when it starts up, turning off LINEDIT during a protocol
transfer, and restoring LINEDIT afterwards.  TSO Kermit, on the other
hand, simply suppresses the user's line and character deletes during a
transfer (and simultaneously saves the current values) and then restores
them afterwards.  The functions of saving, changing, and restoring the
edit characters would be performed under variants 1, 2, and 3,
respectively, of SETMSG.
 
------------------------------------------------------------------------
Type-out interception.
 
Intercepting host command output depends on the operating system
facilities.  In any case, the info would go directly to the screen
unless you first call SUPFNC,1 to start typeout interception.  For
example, under CMS that means intercepting all SVC's (and BALR's to the
system typeout entry point) and copying the corresponding info into a
buffer as it's generated (leaving x'15' separators).  That sort of
operation is self-pacing, so that the cleanup consists of nothing more
than copying the end-of-buffer pointer into a global variable.  Under
TSO, the setup call creates a STACK entry such that the TSO-type
utilities will write to a pre-allocated dataset.  Cleanup in that case
consists of closing the file and then reading the file into the buffer,
again with X'15' (Newline) characters separating lines, and finally
copying out the end-of-buffer pointer.
 
If there's no general way to save the output of a class of utility
programs, then you would just have to do what you can: put any
preliminaries in SUPFNC,1 and the nitty-gritty (for, say, DIR) in
DISKIO,13 with the buffer-read-back in SUPFNC,2/SUPFNC,5.  You might
want to get a copy of TSO Kermit to see how it does things.
 
The expansion for WTEXT in the TSO version generates a call to a
subroutine in COMMON which checks the interception flags and then either
issues a TPUT or copies the info into the output buffer.
 
------------------------------------------------------------------------
GUPI.
 
Updates for Kermit-370 are in the same format as in CMS, except that the
multi-level updates are applied from a single, concatenated file, rather
than a flock of separate updates listed by an AUX.  You should take a
look at implementing the generic update program GUPI for your operating
system.
 
Bear in mind that there are almost always some updates to the base
generic source, so the "package" for installation must include a means
of applying those, and it would also be nice if subsequent changes,
particularly generic changes, could be transmitted to all systems in the
same form.  In any case, instructions for applying updates should be
included in the IKxKER.BWR file (see IKCKER.BWR for a pattern).  It is
pretty easy to make a GUPI, once you've got Kermit: just take subroutine
DISKIO (functions 1, 2, 3, 4, 9, and 10) plus any associated data
structures and tack on a command interface.  GUPI uses the same macros
as Kermit.  You can see a working example by getting IKTGUP.ASM +
IK0GUP.ASM from Columbia.  The only complication is that you'll need to
make a macro library consisting of the macros in IK0MAC.ASM, IKxMAC.ASM,
and IKxGUP.ASM.  The awkward (but workable) alternative would be to
convert all the COPY blocks in GUPI into macros as the MUSIC version
does.  Making a macro libary is simplified by the structure of the code:
 
 a) All the pieces have *COPY cards imbedded appropriately (the source
    components have each macro preceded by a card of the form
    *COPY                                              macro-name
    to improve legibility).
 
 b) The builder may concatenate all the pieces in any order, both for
    Kermit itself and GUPI, then change the *COPY cards into the
    appropriate member-separators, and finally run the result through a
    PDS (library) generator.
 
 c) The "real" source for Kermit or GUPI can then be a small skeleton
    which consists of comments and COPY instructions (which refer to
    members of the macro+source library).
 
------------------------------------------------------------------------
Reentrancy.
 
Kermit-370 is fully re-entrant in the generic sections, and provides a
simple means for any system-specific code to be re-entrant as well.  The
ENTER, LOCALS, and EXIT macros can (and should) be used to begin a new
routine, end the static code, and end the routine, respectively.
Storage locations defined between the LOCALS and EXIT macros are
allocated as temporary variables and initialized to zeroes for each
invocation of the subroutine (and may be allocated recursively, if
necessary).  Sufficient stack space must be reserved for Kermit by
setting the symbol STKDWDS in the SSYMS macro.  The requirement is 18
doublewords per subroutine call plus the sum of all temporaries (rounded
up to doublewords) for the subroutines in the longest path.  There is
automatic overflow checking at each subroutine call performed by COMMON
code routine named SUBENT.  The result of overflow is an immediate
return with an error code from the subroutine, but that may still lead
to unpredictable consequences, and STKDWDS should be given generous
proportions.  When TEST is set on in Kermit-370, the STATUS subcommand
displays the maximum extent of stack space used (in doublewords).
 
------------------------------------------------------------------------
Miscellaneous notes.
 
1. Does your O.S. have a LINEND character facility like VM?  If not, it
   might pay to copy the implementation of that from TSO Kermit.  This
   will, of course, mean some changes to IKxMAC.
2. Would TAKE files generated by Kermit users tend to have line
   numbers imbedded?  If so, it would pay to copy/adapt the stripping
   facility of TSO or CMS Kermit.
3. Does your O.S. have a way of timing out on a line-mode terminal read?
   The way to signal a timeout from TERMIO is to return a packet of
   exactly one character: an ASCII 'T'.  You can see an example by
   looking at the TSO variant.
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
C. Module summary
 
This summary was produced for Kermit-CMS 4.2.2.  The system-specific
modules vary (of course), but all should be quite similar to the
CMS variant.  Some of the differences lie in whether a particular
entry point is treated as a separate routine or not.
 
          ALPHABETIC LIST OF SUBROUTINES
Each item begins with a one-line description, possibly followed by more
details, including entry and exit conditions and function.  If any
alternate entry points exist, each one is similarly described.  Finally,
all common references, callers, and calls are lists -- these are joint
lists in the cases of routines with alternate entries.
 
ACCTNG: save statistics for a transfer in the transaction log
     ENTRY ACCTST
 * add a new entry (name only) to the transaction log
     CALLERS- RECEIV  SEND
 
COMMON: Kermit-370 common routines/data areas
       CALLS- CWDSET  DECODE  DISKIO  DUMP    ENCODE  FSPEC   INTINI
              RIO     RPACK   RPAR    SET     SPACK   SPAR    STATUS
              SUPFNC
 
CRCCLC: calculates crc
 * Calculate the CRC and return it in R15.  Expects R5 to point to the
 * start of the data on which the CRC is calculated, and R6 to the
 * char after the last one.
     CALLERS- RPACK   SPACK
 
CWDSET (system-specific): set working directory
 * Set new 'working directory', i.e., filemode letter
 * Entry: SCANPTR string has option
 * Exit: R15=0 if ok, R15=1 if error or help needed. ERRNUM unchanged.
     ENTRY DSPACE
 * Show space in 'working directory' or other minidisk
 * Entry: SCANPTR string has option (none => working directory)
 * Exit: R15=0 if ok, R15=1 if error or help needed. ERRNUM unchanged
     COMMONS- COMMON
     CALLERS- COMMON  SERVER  SET
       CALLS- DISKIO
 
DECODE: decode pkts from RDATA to WBUF
 * Exit: ERRNUM left unchanged unless there is an error.
     CALLERS- COMMON  GENCMD  RECEIV
       CALLS- OUTBUF
 
DISKIO (system-specific): performs disk I/O functions
 * ERRNUM unchanged unless there is a disk error.
 * Function selected on entry by R0:
 * 0=> unnum: R1->FAB.  Return R1->buffer,R0=# and remove the sequence
 *     number (if any) from the buffer (used for TAKE files)
 * 1=> open (in): R1->pattern FDB, R2->name.  Returns R0->FAB, R1->FDB
 * 2=> open (out): (same)
 * 3=> test name: R2->name.  Returns R1->FDB if found (else R15=1)
 * 4=> close file: R1->adr(FAB).
 * 5=> set up search: R1->pattern name.
 * 6=> return next file in list:  Returns R1->FDB + sets up FILNAM
 * 7=> close search (if any).
 * 8=> test CWD string: R1->string.  Returns R15=0 if ok, else =1.
 * 9=> read: R1->FAB.  Returns R15=12 if EOF, 0 if ok; R0=# data
 * 10=> write: R1->FAB.  Returns R15=13 if disk full, 0 if ok.
 * 11=> test space: R1->pattern FDB (has size in Kbytes),
 *   R2->name (used if FAB not found), R6->adr(FAB). Return R15=0 if ok.
 * 12=> analyze R/W error, set ERRNUM, make EMSG: R1->FAB, TMPDW=code
 *      always returns R15=1
 * 13=> directory info on file: R1->name.  Returns R15=0 if ok.
 * 14=> delete file: R1->name.  Returns R15=0 if ok.
 * 15=> rename file: R1->name, R2->new name.  Returns R15=0 if ok.
 * 16=> copy file: R1->name, R2->new name.  Returns R15=0 if ok.
 * 21=> save file status in directory: R1->FAB. (not used)
 * 22=> open library (in): R2->DDNAME.  Return R15=0 if ok.
 * 23=> point for next read, R1->adr(FDB), R2=records to skip.
 *      Return R15=0 if ok.
     CALLERS- COMMON  CWDSET  DUMP    FSPEC   GENCMD  INBUF   KERMIT
              OUTBUF  RECEIV  RIO     SEND    SERVER  SET     USNTRF
       CALLS- SUPFNC
 
DUMP: show translation table or transaction log
 * Display current contents of table or log
 * Entry: SCANPTR string has option
 * Exit: R15=0 if ok, R15=1 if error or help needed. ERRNUM unchanged.
     ENTRY DUMPTOD
 * Extra entry point for dumping TOD (in sec) from R0 into buf
 * at R1 and return updated buffer ptr in R15
     ENTRY GIVTAB
 * Save current translation table in STORAG into a TAKE file on disk
 * Entry: SCANPTR string has option
 * Exit: R15=0 if ok, R15=1 if error or help needed.  ERRNUM set
 *       appropriately as long as command syntax is ok, else unchanged.
     COMMONS- ERRTAB
     CALLERS- COMMON  SCRNIO
       CALLS- DISKIO  FSPEC   STATUS  TBLSET
 
ENCODE: encode from RBUF into SDATA buffer
     CALLERS- COMMON  SEND
       CALLS- INBUF
 
ERPACK: send error packet based on ERRNUM
     COMMONS- ERRTAB
     CALLERS- GENCMD  RECEIV  SEND    SERVER
       CALLS- SPACK   STATUS
 
FOPSTR: test string for file options
 * Entry: R1->Address of option field, R6->string, R7=length - 1
 * Exit: R15=0 + R6,R7 fixed if ok, R15=1 if error (msg ptrs set up)
     CALLERS- FSPEC
 
FSPEC (system-specific): extract filespec from scan string
 * Entry: R1->name field, R0=flags selecting operation (see below)
 *        For parse operations, SCANPTR defines the input string.
 *        For getting foreign or display filespec, R7->output buffer
 * Exit: if not FFNEW, then R15=0 if ok, 1 if ?, 2 if bad.
 *        For R15=1 or 2 R3,R4 give message.  ERRNUM may be leftover.
 * See part B for calling flags.
     CALLERS- COMMON  DUMP    GENCMD  RECEIV  SERVER  SET     USNTRF
       CALLS- DISKIO  FOPSTR
 
GENCMD: send a Generic command
 * Entry: SCANPTR has string
 * Exit: R15=0 if ok, 1 if help needed, 2 if bad parameter
 *       ERRNUM set appropriately
     CALLERS- USNTRF
       CALLS- DECODE  DISKIO  ERPACK  FSPEC   INTINI  OUTBUF  RECEIV
              SEND
 
INBUF: read next disk record into RBUF
 * Exit: R15=0 if ok, -1 if EOF, 1 if read error (ERRNUM set)
     CALLERS- ENCODE  NPREAD
       CALLS- DISKIO
 
INTINI: Initialize/reset terminal for protocol
 * If R1 is 0, reset for interactive unless in Server mode.
 * If R1 is positive, set up for protocol:
 *  1 for SERVER, 2 for SEND, 3 for RECEIVE, 4 for short msg
 * R15 = 0 on return if ok
     CALLERS- COMMON  GENCMD  SEND    SERVER  USNTRF
       CALLS- SCRNIO  SUPFNC  TERMIO
 
KERMIT: main entry point
 * Assign buffers, initialize STORAG section; do Kermit; return.
     COMMONS- COMMON  KSYSNIT
       CALLS- DISKIO  SCRNIO  SPAR    TBLSET  USNTRF
 
KHDMP: dump storage to log file (not generated unless &KTRACE is YES)
 * Dump area to log
 * Entry: R1->area, R0=length, R2-> 8-byte title for area
 * Exit: R15=0 if ok
 
KHELP (system-specific): perform HELP command
 * Handle HELP command, rest of string given by SCANPTR.
     COMMONS- SETCMDS
     CALLERS- USNTRF
       CALLS- SUPFNC
 
NPREAD: copy from RBUF to SDATA buffer (no encoding)
     CALLERS- SEND
       CALLS- INBUF
 
OPTPKT: compute optimum packet size
 * Entry: TINSV contains stack of data
 * Exit: R15=0 if no limit, else optimum packet size (per algorithm)
     CALLERS- SEND    STATUS
 
OUTBUF: write record from WBUF to a disk file
 * Entry: R1=length of buffer (which starts where WBUF points)
 * Exit: R15=0 if ok, other if error (ERRNUM set)
     CALLERS- DECODE  GENCMD  RECEIV
       CALLS- DISKIO
 
RECEIV: receives a file
 * Receive file(s) and set ERRNUM appropriately
 * Entry: filespec in FILNAM if ROVR is set, latest received packet
          in buffer
     COMMONS- COMMON
     CALLERS- GENCMD  SERVER  USNTRF
       CALLS- ACCTNG  DECODE  DISKIO  ERPACK  FSPEC   OUTBUF  RPACK
              RPAR    SPAR    SUPFNC  TBLSET
 
RIO: Read packet into receive packet buffer
     ENTRY SIO
 * Send packet in SNDPKT
     CALLERS- COMMON  RPACK   SEND    SPACK
       CALLS- DISKIO  SCRNIO  TERMIO
 
RPACK: Read and validate a packet
 * ERRNUM set if error found, unchanged otherwise
     CALLERS- COMMON  RECEIV
       CALLS- CRCCLC  RIO
 
RPAR: sets up parms to send to other host
     ENTRY RPARSET
 * set up for exchange (RPAR to be called 1st)
     CALLERS- COMMON  RECEIV  SEND    SERVER
       CALLS- SCRNIO  TERMIO
 
SCRNIO (system-specific): Handle screen I/O via protocol converter
 * R1 points to a pair of (adr,len) for read or write.  If I/O is
 * successfull, R15 returns transferred byte count (else returns -1).
 *               Command code is in R0:
 * 0 => Clear screen on console (not comm line)
 * 1 => Open screen for I/O            4 => Write packet
 * 2 => Close screen                   5 => Read packet
 * 3 => Reset screen status after      6 => Write message (no ATTN)
 *      environment changes            7 => Read screen buffer
     ENTRY SETMSG
 * Entry: R1 selects operation
 * Exit: R15=0 if ok
 * 1-> Analyze user environment, determine if suitable.
 *     Save quantities needed and condition line for entering commands.
 *     Perform any system-dependent initialization.
 * 2-> Condition line for protocol transfers.
 * 3-> Decondition line at end of transfer.
 * 4-> System-dependent clean-up at exit.
 * 5-> Reperform system-dependent initialization after SET LINE.
     COMMONS- KSYSNIT
     CALLERS- INTINI  KERMIT  RIO     RPAR    SET     SUPFNC
       CALLS- DUMP    USNTRF
 
SEND: sends a file
 * Send file(s) and set ERRNUM appropriately
 * Entry: filespec pattern in IFILE, Disp code (if any) in R1
     CALLERS- GENCMD  SERVER  USNTRF
       CALLS- ACCTNG  DISKIO  ENCODE  ERPACK  INTINI  NPREAD  OPTPKT
              RIO     RPAR    SPAR    SUPFNC
 
SERVER: performs Server mode functions
 * Exit: ERRNUM set appropriately.
     CALLERS- USNTRF
       CALLS- CWDSET  DISKIO  ERPACK  FSPEC   INTINI  RECEIV  RPAR
              SEND    SPAR    SUPFNC  USNTRF
 
SET: perform SET command options
 * Set/change values in STORAG.
 * Entry: SCANPTR string has option
 * Exit: R15=0 if ok, 1 if help needed, 2 if bad parameter name
 *       ERRNUM unchanged
     ENTRY SHOW
 * Display current values in STORAG.
 * Entry: SCANPTR string has option
 * Exit: R15=0 if ok, 1 if help needed, 2 if bad parameter name
 *       ERRNUM unchanged
     COMMONS- SETCMDS ETCETERA
     CALLERS- COMMON
       CALLS- CWDSET  DISKIO  FSPEC   SCRNIO  SETCMDS SUPFNC  TBLSET
 
SPACK: fill sending packet buffer and send it
     CALLERS- COMMON  ERPACK  USNTRF
       CALLS- CRCCLC  RIO
 
SPAR: use parms from other host in RDATA
     ENTRY SPARSET
 * set up for exchange (SPAR to be called 1st)
     CALLERS- COMMON  KERMIT  RECEIV  SEND    SERVER
 
STATUS: display latest error (if any), transfer statistics, etc.
 * Exit: R15=0.  ERRNUM unchanged.
     ENTRY PEMSG
 * Display just error message and its backup explanations.
     COMMONS- ERRTAB
     CALLERS- COMMON  DUMP    ERPACK  USNTRF
       CALLS- OPTPKT
 
SUPFNC (system-specific): various supervisor functions
 *  On entry, R1 = operation code, R0 = possible ptr
 * Exit: R15 set (0 => ok, <0 => illegal cmd, >0 => depends)
 *       ERRNUM set appropriately (R1=1,3,4) or unchanged (2,5-11)
 * 1 -> Start typeout interception.  N.B.  &MAXLR >> 2048 for this
 * 2 -> Clean up afterwards and stop interception
 * 3 -> Execute host command with or without interception
 *      If UCMD set, SCANPTR gives text, else R0->text,R6=len
 * 4 -> Execute CP command with or without interception
 *      R0->text, R6=len
 * 5 -> Stop interception if going
 * 6 -> Retrieve original cmd parm string into CBUF (R15=1 if null)
 * 7 -> Test for stacked lines, return number in R15
 * 8 -> Log off (doesn't return!)
 * 9 -> Wait specified time
 * 10-> Return clock time in R15 (centisec)
 * 11-> Setup up new prompt string at (R0)
     CALLERS- COMMON  DISKIO  INTINI  KHELP   RECEIV  SEND    SERVER
              SET     USNTRF
       CALLS- SCRNIO
 
TBLSET: set up character set
 * Define new translation tables
 * Entry: Names of table in TRNALF and FILALF, R1->tables
 *        R0->item just changed, if any (else, 0)
 *        Tables should be a pair with ATOE first
 * Exit: R15=0 if ok, R15=1 if error ERRNUM unchanged.
     ENTRY TBLATT
 * Entry: R6->Designator string, R7=length
 * Exit:  Correct table set up and R15=0 if ok, else 1
     COMMONS- COMMON  TRNTBLD
     CALLERS- DUMP    KERMIT  RECEIV  SET
 
TERMIO (system-specific): Handle terminal I/O
 * R1 points to a pair of (adr,len) for read or write.  If I/O is
 * successfull, R15 returns transferred byte count (else returns -1).
 *               Command code is in R0:
 * 1 => Open line for I/O            4 => Write packet
 * 2 => Close line                   5 => Read packet
 * 3 => Reset line status after    ( 6 => Write message ) not used
 *      environment changes        ( 7 => Read buffer ) not used
     COMMONS- COMMON
     CALLERS- INTINI  RIO     RPAR
 
USNTRF: execute main loop
 * Execute Kermit commands (beginning with default TAKE files)
 * Entry: environment already set up
 * Exit: R15=0, ERRNUM set appropriately
     COMMONS- COMMON
     CALLERS- KERMIT  KHELP   SCRNIO  SERVER
       CALLS- DISKIO  FSPEC   GENCMD  INTINI  KHELP   RECEIV  SEND
              SERVER  SPACK   STATUS  SUPFNC
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
          ALPHABETIC LIST OF COMMON BLOCKS
 
COMMON: Kermit-370 common data areas
     USED BY- CWDSET  KERMIT  KSYSNIT RECEIV  TBLSET  TERMIO  USNTRF
 
ERRMSGS: text of error messages
     USED BY- ERRTAB
 
ERRTAB: List of error messages
     COMMONS- ERRMSGS
     USED BY- DUMP    ERPACK  STATUS
 
ETCETERA: overflow from COMMON
     USED BY- SET
 
KSYSNIT: initial parameter values
     USED BY- KERMIT  SCRNIO
 
SETCMDS: tables of command keywords
     USED BY- KHELP   SET
 
TRNTBLD: translation tables and variations thereon
     USED BY- TBLSET
