.*         To print this document on the 3800, say SCRIPT86 ICATS
.*         To print this document on the 6670, say 6670C    ICATS
.im myprof
.hy off
.dh 1 noj npa
:gdoc sec='IBM Internal Use Only'
:frontm
:titlep
:TITLE.ICATS Functional Specification
:title.*** Final Version ***
:date.September 26, 1983
:author.Rick Jasper
:address
:aline.A68-861
:aline.San Jose, CA
:eaddress
:etitlep
:toc
:body
:h1.Scope
.sk
.il 5
This is the fourth draft of the "ICATS Functional Specifications"
and is an expansion of, and obsoletes, the first three drafts.
The ICATS project is complete (unless Jeff dreams up something else
he wants added like reading in files from the reader) and, as with
most projects, has developed and changed quite a bit
since its original conception.
Included in this revision are
:ul
:li.explanation of the virtual terminal support to the UTS,
:li.available console commands.
:li.source code format for files to and from the UTS,
:li.other minor technical errors corrected.
:eul
.*
.sk
.il 5
The ICATS virtual machine is a service machine,
servicing the users of a UTS machine from a 370 VM system.
This document will explain how to maintain and use the ICATS
virtual machine.
The intent of this paper is threefold,
to explain ICATS's purpose and capabilities,
to detail each function and its use,
and to show how to manage the ICATS configuration.
As of this writing, both the software and hardware development
are done and ICATS has been operational
and stable for a few months.
This paper is the authoritative source regarding
function details and data format.
.*
:H1.ICATS VIRTUAL MACHINE OVERVIEW
.*
.sk
.il 5
The ICATS virtual machine (hereafter referred to as simply ICATS)
is a virtual machine running under the VM operating system
on a 370 computer.
It is written in 370 assembler language and runs under
CMS as a normal user program.
Its purpose is to serve requests from
users of one or more UTS machine, like
:ul
:li.take this data I'm sending you and write it to a file
on my CMS minidisk,
:li.send me a file I've got stored on my CMS minidisk,
:li.allow me to log on to the UTS machine from this VM terminal,
:li.or what time is it?
:eul
.*
.sk
.il 5
ICATS is automatically logged on when VM
is originally IPL'ed on the 370 computer.
Once logged on, ICATS starts itself and
waits until it receives
an interrupt from a DIALable terminal or a request.
A request can be received in any one of three different ways;
:ul
:li.from an ATTENTION interrupt from any of the
UTS machines it it servicing,
:li.from somebody logged onto the ICATS virtual machine
under VM and entering something from its console,
:li.or from a special message (SMSG) from another virtual
machine under VM.
:eul
When a terminal interrupt comes in, ICATS passes that
interrupt on to whichever UTS that terminal is "plugged into."
Likewise, once a request is received, ICATS awakens and services
that request.
When ICATS finishes with its current task, it looks to see if
any other task came in while it was busy servicing
this one.  If so, it services the new request.
Otherwise, it waits again for a new request.
.*
:h2.Multitasking, or Lack Thereof
.*
.sk
.il 5
ICATS is a relatively simple-minded program.
Although ICATS can service multiple terminals and multiple UTS machines,
it can only handle one request from any source at a time.
There is no multitasking of service requests.
In other words, ICATS does not start servicing another request
until the current request is completely finished.
However, if ICATS is busy with one request and receives another,
it "remembers" it, and services the second request when it
finishes with the first.
This isn't a serious restriction however, because all
of ICATS's requests are short.  They either work quickly or fail
quicker, so this lack of multitasking should not be missed.
Also, there cannot be multiple requests from the same UTS
machine.  One UTS machine must not initiate another request
until any previous request it has made, is completely serviced.
This requirement is to just keep things simple, and its fulfillment
is dependent upon the UTS software.
.*
:h2.Configuration
.*
.sk
.il 5
There's a CMS file on the ICATS 191 disk that is
used to configure the ICATS virtual machine upon
start up.:fnref refid=foot1.:fn id=foot1
I also considered having a command that rereads
this configuration file and dynamically reconfigures,
but I never implemented it.
It wouldn't be that difficult to add, but I don't
feel it's really necessary.  It's so easy right now to shut
ICATS down, update the ICATS CONFIG file, and restart ICATS.
Total down time is a couple of minutes.
:efn
.*
This configuration file specifies things like
:ul
:li.how many UTS machines ICATS is to
service,:fnref refid=foot2.:fn id=foot2
Currently, ICATS is servicing only one UTS.  The program
however, is designed to handle multiple UTS machines.
Although it's never been tested, I believe any realistic
number of UTS machines could be put on the same system and
serviced by the same ICATS virtual machine.
:efn
:li.what their addresses are,
:li.the number of DIALable terminals ICATS is to handle,
:li.the UTS users for each UTS machine,
:li.the CMS minidisks for each user,
:li.and the passwords for each minidisk.
:eul
See the next chapter for an example ICATS configuration.
This CONFIG file is a simple EBCDIC CMS file that is easy
to maintain and change.  All one needs to do to change the
ICATS configuration in some way is to LOGON to ICATS, stop
the ICATS program if it's running, make the changes to the
ICATS CONFIG file with some editor, and restart the ICATS program.
.*
:h2.ICATS Functions
.*
.*  ---  QUIT  TRACE  TEST  FAKIT  RESTART STATUS
.*  ---  CAT   READ   TIME  WRITE  TERMIO
.sk
.il 5
Each request, regardless of where it comes from,
invokes some function of ICATS.
Not all functions are valid from every source, though.
For example, QUIT is only allowed from the console.
Currently, the ICATS functions are QUIT, TRACE, TEST, FAKIT, RESTART,
STATUS, CAT, READ, TIME, WRITE, and TERMIO.
I have thought of more that would be nice to have (like SEND, PRINT, or
RECONFIG) and people will undoubtedly dream up of more yet.
ICATS is designed with this probable expansion in mind.
New ICATS functions are fairly easy to create, integrate
into the software, debug, and modify.
See the chapter on the ICATS functions for details on each function.
.*
:h2.Protocol For UTS-Initiated Requests Between ICATS and the UTS Machine
.*
.sk
.il 5
Requests from the console or from SMSG's are straightforward enough.
From the console, one merely types in a command and
gets a response using normal CMS macros.
From another virtual machine, one uses the CP command SMSG,
and receives a message back from the ICATS virtual machine.
Communication between the UTS machines and ICATS however,
is a little more complex.  Refer to figure 2.1.
To initiate a request, the UTS machine causes an interrupt
to the 370 CPU with the Attention bit on in the CSW.
ICATS sees this attention interrupt and knows there is a UTS
that needs servicing.
.*
.sk
.il 5
When ICATS gets around to servicing the request, he
issues a START I/O with a CCW op code of
X'06' (Read Modified), length of 128
(8-bit) bytes:fnref refid=foot3.:fn id=foot3
.*
Throughout this paper, when I use the term "byte", I'm
referring to an 8-bit quantity.  The term "word" refers
to 4 bytes (32 bits).  There might be some
confusion because each address in a UTS main memory holds
16 bits, so one might be tempted to call a byte, 16 bits,
or a word, 16 bits.  I'm not.  My byte is 8 bits, my word
is 32 bits.
:efn
to the requesting UTS machine.  The UTS
then ships over a 128-byte request control block.
This request control block
contains the UTS user's ID, the function
desired, and whatever other information is required for
that function.  If that function requires further I/O to
the UTS machine (for example, a WRITE request would need another
SIO to get the data to write to the CMS file),
the CCW op code used is X'02' (Read).
.*
.sk
.il 5
When ICATS finishes with the request, another SIO
is done to the UTS machine,
with a CCW op code of X'01' (Write)
and a length of 128 bytes or more,
depending on whether or not there is any data
following the reply control block
(the byte count of the data following the reply control block
if any, is imbedded in the reply control block).
.*
.sk
.il 5
Figure 2.1 shows this sequence graphically.  A request is initiated
by a UTS.  ICATS gets the request control block and interprets it.
If need be, ICATS does another SIO to get some data, then
he services the request.  Afterwards, ICATS sends a reply control
block and again waits until another request comes in.
.*
:line65
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
           UTS MACHINE                      ICATS/370
 %------------------------------@------------------------------›
 |                              |                              |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |              WAIT            |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |                .             |
 |             |     Attention  |  Interrupt     .             |
 |             #----------------+--------------->›             |
 |           WAIT  (I want some | work done)     |             |
 |             .                |                |             |
 |             .                |                |             |
 |             .           SIO  |  X'06'         |             |
 |             %<---------------+----------------$             |
 |             |          Send  |  Request     WAIT            |
 |             #----------------+--------------->›             |
 |           WAIT      (What do | you want ?)    |  Interpret  |
 |             .                |                |  Request    |
 |             .                |                |             |
 |             .      Optional  |  SIO X'02'     |             |
 |             %<---------------+----------------$             |
 |             |     Send File  |  Data        WAIT            |
 |             #----------------+--------------->›             |
 |           WAIT               |                |  Service    |
 |             .                |                |  Request    |
 |             .                |                |             |
 |             .                |                |             |
 |             .                |                |             |
 |             .                |                |             |
 |             .                |                |             |
 |             .           SIO  |  X'01'         |             |
.TR & EC
 |             .<---------------+----------------&             |
.TR & &
 |             .    Send Reply  |  and Data      |             |
 |             %<---------------+----------------$             |
 |             |   (Here's what | I did)       WAIT            |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |                .             |
 |             |                |                .             |
 |                              |                              |
 #------------------------------*------------------------------$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR > >;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sk 2
:hp2.
Figure 2.1.  Communication Protocol between the UTS machine and ICATS.
:ehp2.
 Time is shown vertically.
.kp off
:line6
.*
:h2.Logging On To The UTS Machine Through ICATS
.*
.sk
.il 5
The UTS machine supports 327X terminals as console devices.
Since the communication link to the UTS was there and VM of course,
supports 327X terminals, we decided to use VM terminals
to log on to the UTS machine.
Modeled after VM's PASS-THROUGH (a.k.a. PVM),
"virtual terminals" came into being.
After clearing away the VM logo from the screen, you can enter
"DIAL ICATS" and get a menu similar to PVM's menu.
All you do is move your cursor to the UTS you wish to log on to
and hit enter, and from then on, it's as if your terminal is
"plugged into" that UTS.  There's even a facility
similar to PVM's four pound signs ("####") to get
back to the menu by entering four dollar signs ("$$$$").
The "virtual terminal" facility has probably been the most
tangible and impressive function for showing off the ICATS project.
.*
.sk
.il 5
Once a terminal gets "plugged into" a UTS,
further interrupts from that terminal get passed on to that UTS.
The communication sequence for this, since it's initiated by ICATS and
not by the UTS, is different than that for normal ICATS requests.
For real terminals, a typical interaction would be an interrupt
comes in from the terminal, its buffer is read, and a new screen
is written.  The way this is accomplished for virtual terminals is
:ol
:li.To pass the interrupt on to the UTS,
ICATS does a SIO with a CCW op code of X'05' (write modified)
for 128 bytes.  Those 128 bytes, which are similar to the request
and reply control blocks, specify which terminal is causing the
interrupt and its CSW status.
The UTS knows that since this is a write modified,
it represents an interrupt from a terminal and not any of the
other I/O sequences, like read request control block, send file
data, or write reply control block.
.*
:li.Sometime later, in a normal ICATS request sequence,
the UTS requests a SIO to be done to that terminal (via
the TERMIO function).  This SIO might be to do a read modified, a
read buffer, or whatever.  The data from the 327X gets
transferred, and
:li.sometime later still,
the UTS would come back with another terminal I/O request
to write an updated screen.
:eol
Terminal I/O, of course, doesn't have to follow this sequence,
this is just an illustrative example.
This terminal interaction took three distinct steps,
the first of which was initiated by ICATS.
The actual terminal I/O (if any)
is initiated by the UTS in the normal fashion.
.*
:h1.ICATS Example Configuration
.*
.sk
.il 5
This section will go through an example configuration of UTS
machines, ICATS minidisks, UTS users, DIALable terminals,
and the configuration file required to define it.
This configuration file is a normal CMS file
residing on ICATS's 191 minidisk which, as are all
files on ICATS's A-disk, should not be made generally available
to UTS users for transfer or manipulation.
The configuration file contains records defining the physical
hardware configuration of the UTS machines and the 370 computer, the
user community under each UTS machine, and the accessible minidisks
for each user.  This file is read once upon
initial bring up of the ICATS virtual machine and from then on,
ICATS is guided by the information that was in
the file at that time.
.*
:h2.What's Out There
Imagine, for our example, this hypothetical configuration
(see figure 3.1).
On SJEVM2, we have two UTS machines, let's name them UTS#1
and UTS#2 (such original names).  Both UTS machines are on
channel 0, UTS#1 has device address 020 and
UTS#2 is 080.:fnref refid=foot4.:fn id=foot4
.*
It's no coincidence that both UTS addresses end with zero.
The current implementation of the Dobbox (Jeff Dobbek's control unit)
only works for the lowest address in its address range.
The box takes up eight addresses on the channel, but only
responds correctly to the first address.
Jeff says this will be fixed in the next version.
The ICATS software doesn't care, it'll work with any address.
:efn
Let's also say that there's one project group using UTS#1,
code named ENTERPRISE,
and there's two projects using UTS#2, code named CAPTAIN
and JLA.  For our purposes, these three projects are
completely independent and, except for CAPTAIN
and JLA sharing the same UTS, have nothing at all to do with
one another.
We also want ICATS to service up to 3 DIALable terminals.
.*
.sk
.il 5
Let's further suppose that besides the system programmer,
SPOCK, there are two users on the
ENTERPRISE project, KIRK and SULU.  Each user will
need access to their own private disk, the common project
disk, and to the UTS system source disk.  KIRK, being
the project leader, will have control over the common
project disk.
.*
.sk
.il 5
Our second UTS machine, UTS#2, has two projects using it,
CAPTAIN and JLA.  The CAPTAIN project has two users,
AHAB and KIRK.  Notice that the user
named KIRK under the CAPTAIN project is completely separate from
the user with the same name under the ENTERPRISE project.  Even
though they have the same user ID, they are distinguishable
because they are on different UTS machines.
The JLA project has three users, FLASH, BATMAN, and ROBIN.
SPOCK, of course, needs a user id on this system as well.
.*
.sk
.il 5
Let's see what the configuration file for our example looks like.
See figure 3.2.
Afterwards, I'll go through each type of statement
in the file and explain the different options.
.*
:line65
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR > EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
TERMINALS         370 COMPUTER (SJEVM2)          ICATS' MINIDISKS
  %---›    %--------------------------------›    %---›  %---›  %---›  %---›
  |100|    |  VM                            |    |190|  |191|  |19E|  |200|
  #---$    |                                |    #---$  #---$  #---$  #---$
  %---›    |        %--------------›        |    %---›  %---›  %---›  %---›
  |101|    |        |  ICATS       |        |    |201|  |202|  |203|  |210|
  #---$    |        |              |        |    #---$  #---$  #---$  #---$
  %---›    |        #------›%------$        |    %---›  %---›  %---›  %---›
  |102|    |               ||               |    |220|  |221|  |222|  |223|
  #---$    |               ||               |    #---$  #---$  #---$  #---$
           #---------------><---------------$    %---›  %---›  %---›
                           ||                    |230|  |238|  |5FF|
.TR > >
   370 CHANNEL 0 --------->||                    #---$  #---$  #---$
.TR > EC
                           ||
---------------------------><----------------------------------------------
  UTS MACHINES             ||
      %--------------------$#--------------------›
      |%----------------------------------------›|
      ||                                        ||
      ||                                        ||
%-----$#-----›                            %-----$#-----›
.TR # #
|  UTS#1     |                            |  UTS#2     |
.TR # AB
|            |                            |            |
#------------$                            #------------$
ENTERPRISE:                               CAPTAIN:
     KIRK                                      AHAB
     SULU                                      KIRK
                                          JLA:
                                               FLASH
                                               BATMAN
                                               ROBIN
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR > >;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 3.1.  Example UTS Configuration:
:ehp2.
Figure shows the ICATS virtual machine under VM,
its DIALable terminals, its
associated minidisks, and the two UTS machines it is
servicing.  Also shows the code names of the projects
using each UTS and the user ID's for each project.
.kp off
.*   :line6
.*
.*   :line65
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR > EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-----------------------------------------------------------------------›
.TR # #
.TR * *
|*                    ICATS CONFIGURATION FILE FOR SJEVM2     (1-28-83) |
|TERM 100                                                               |
|TERM 101                                                               |
|TERM 102                                                               |
|UTS  UTS#1  020  020                          ENTERPRISE PROJECT       |
|   USER  SPOCK 33                                SYSTEMS PROGRAMMER    |
|        DISK  B  210  POINTY    EARS                PERSONAL DISK      |
|        DISK  H  200  ALL       3DCHESS             ICATS#1 SYSTEM DISK|
|        DISK  I  220  ALL       LOGICAL             ICATS#2 SYSTEM DISK|
|   USER  KIRK  26                                PROJECT LEADER        |
|        DISK  B  201  BEAM      DOWN                PERSONAL DISK      |
|        DISK  C  202  PHASOR    KLINGON             SHARED PROJECT DISK|
|        DISK  H  200  ALL       NONE                ICATS#1 SYSTEM DISK|
|   USER  SULU  B5                                                      |
|        DISK  B  203  KARATE    WATCHOUT            PERSONAL DISK      |
|        DISK  C  202  PHASOR    NONE                SHARED PROJECT DISK|
|        DISK  H  200  ALL       NONE                ICATS#1 SYSTEM DISK|
|*                                                                      |
|UTS  UTS#2  080  080                     CAPTAIN AND JLA PROJECTS      |
|   USER SPOCK  33                                SYSTEMS PROGRAMMER    |
|        DISK  B  210  POINTY    EARS                PERSONAL DISK      |
|        DISK  H  220  ALL       LOGICAL             ICATS#2 SYSTEM DISK|
|        DISK  I  200  ALL       3DCHESS             ICATS#1 SYSTEM DISK|
|   USER  AHAB  60                                CAPTAIN PROJECT LEADER|
|        DISK  B  221  WHITE     WHALE               PERSONAL DISK      |
|        DISK  C  222  BOSSES    PEGLEG              SHARED PROJECT DISK|
|        DISK  H  220  ALL       NONE                ICATS#2 SYSTEM DISK|
|   USER  KIRK  4A                                                      |
|        DISK  B  223  ESL       PROJECT             PERSONAL DISK      |
|        DISK  C  222  BOSSES    NONE                SHARED PROJECT DISK|
|        DISK  H  220  ALL       NONE                ICATS#2 SYSTEM DISK|
|*                                                                      |
|   USER  FLASH 21                                JLA PROJECT LEADER    |
|        DISK  B  230  SPEEDY    KEN                 PERSONAL DISK      |
|        DISK  H  220  ALL       NONE                ICATS#2 SYSTEM DISK|
|   USER  BATMAN 9                                                      |
|        DISK  B  238  BATCAVE   BRUCE               PERSONAL DISK      |
|        DISK  H  220  ALL       NONE                ICATS#2 SYSTEM DISK|
|   USER  ROBIN 69                                                      |
|        DISK  B  238  BATCAVE   DICK                PERSONAL DISK      |
|        DISK  H  220  ALL       NONE                ICATS#2 SYSTEM DISK|
.TR # AB
.TR * CB
#-----------------------------------------------------------------------$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR > >;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 3.2.  Sample ICATS Configuration File:
:ehp2.
Figure shows the ICATS configuration file for the example
UTS configuration described in this section.
This file exists on ICATS' 191 minidisk (its A-disk) and
is in fixed length, 80-character format.
.kp off
:line6
.*
:h2.The ICATS Configuration File
.*
.cp 9
:h3.Comment Statements
.*
.sk
.il 5
Any line in the configuration file starting with an asterisk
in column one is considered to be a comment statement and is
ignored.  This is handy for documenting the configuration file
or to delete statements be simply "commenting" them out.
Also, you can add comments on any of the other statements
after the required fields.
.*
.cp 8
:h3.The TERM Statement
.*
.sk
.il 5
The TERM statements in the configuration file are used to
identify the number and addresses of the DIALable terminals
ICATS is to handle.  In our example, we want ICATS to handle
up to three terminals,
so there are three TERM statements.  The fields in the TERM
statements are
:ul
:li.the keyword "TERM".  This defines this line to be a
TERM statement.
:li.terminal virtual address.  This is not the terminal's real
address of course, since it could be any terminal under VM.
Rather, it's this terminal's address as it will be known
by the ICATS virtual machine and later, to the UTS machine
it will be "plugged into."
These addresses should be on channel 1 (1XX).
This is because that's how the UTS software distinguishes between
a real terminal and one that's coming through ICATS.
:eul
.*
.cp 8
:h3.The UTS Statement
.*
.sk
.il 5
The UTS statements in the configuration file are used to
identify the various UTS machines the ICATS virtual machine
is to handle.  In our example, there are two UTS machines
so there are two UTS statements.  The fields in the UTS
statements are
:ul
:li.the keyword "UTS".  This defines this line to be a
UTS statement.
:li.UTS unique identifier.  This field is used
to distinguish this UTS from other UTS machines ICATS is
servicing.
:li.Real device address of this UTS machine.
:li.Virtual device address of this UTS machine.  This is in
case of a UTS machine occupying say, real address 01F, the
virtual address of ICATS' virtual printer.  This field tells
ICATS to attach the UTS machine to himself as this address.
Since there are no address conflicts in our example, each UTS
machine is defined as its real address.
:eul
.*
.cp 8
:h3.The USER Statement
.*
.sk
.il 5
The USER statement simply identifies the UTS user ID of each
user on this particular UTS.  It also serves to group the
following DISK statements together and associate them to this
UTS user.  Again, notice that the user KIRK on UTS#1 is
completely different than the user KIRK on UTS#2.  One
has nothing to do with the other and is not even aware of
the other's existence.  You cannot, however, have two users
identically named on the same UTS machine.  For example, you
cannot have a KIRK on the CAPTAIN project on UTS#2 and
a different KIRK on the JLA project on the same UTS.  One
of them must be renamed.
The fields of the USER statement are
:ul
:li.the keyword "USER".  This defines this line to be a
USER statement.
:li.User id.  Each user id can be up to 8 characters long.
:li.User's encoded machine type.  This is a hexadecimal
number that is this user's encoded machine type down at the UTS.
Don't ask me what an "encoded machine type" is.
If you don't know either, ask Jeff Dobbek.
:eul
.*
.cp 8
:h3.The DISK Statement
.*
.sk
.il 5
The DISK statements are the backbone of the configuration file.
It is in these statements that the view a UTS user perceives of
the minidisks available to him is defined.  Referring back to
Figure 3.1, we see that even though the ICATS virtual machine
has 15 minidisks defined, each UTS user sees, and has access to,
only those that are defined for him in the configuration file.
For example, the user KIRK on UTS#1 has access to 3 of ICATS's
minidisks, 200, 201, and 202.  KIRK does not have access to
the other 12 minidisks (191, 208, 210, etc) and doesn't even
know that they exist.
The password fields of this statement are to provide some
security among UTS users.  These passwords are not to be
confused with other CP passwords like LOGON passwords, or
minidisk passwords.  The passwords in these DISK statements
are completely separate from CP and are seen only by the ICATS
software.
The fields of the DISK statement are
:ul
:li.the keyword "DISK".  This defines this line to be a
DISK statement.
:li.UTS user's virtual disk identifier.  This is what the
UTS user uses to refer to this particular disk.
When doing anything with this disk, ICATS will access it
with this access mode, then do the read or write.
For this reason, don't use the letters 'A', 'S', 'U', or 'Z'.
ICATS has his own minidisks at these addresses that he needs.
:li.ICATS real minidisk address.
:li.Read password.  A password of "ALL" means that password
checking is not done so no password need be supplied.  A password
of "NONE" means that no password is valid.  "NONE"
probably wouldn't be used as a read password unless you
wanted the disk to be write-only (kind of like write-only memory).
:li.Write password.  "ALL" or "NONE" could be specified here
as well and "NONE" makes more sense as a write password,
effectively making this a read-only disk.
:eul
.*
.sk
.il 5
Here is how disk accesses are made.
When KIRK on UTS#1 says to read a file from his
B-disk, a quick table look up is done to determine that the ICATS
201 minidisk is the disk he is referring to.  When SPOCK
refers to his B-disk, the ICATS 210 minidisk is
used.  When the other KIRK on UTS#2 refers to his
B-disk, the ICATS' 223 minidisk is used.
Thus, everybody can have their own personal B-disk or even
share a B-disk as in the case of BATMAN and ROBIN.
Notice that disks can be shared in a variety of ways.
Group disks might be shared on a read-only basis
to some users in a group,
and kept read/write to group leaders (refer to the
ICATS 202 and 222 disks).  Or, a disk containing source
code might want to be shared by all users on a
UTS-wide basis as in
the case of ICATS's 200 and 220 minidisks.
Also notice that minidisks can be shared across systems
as in the case of SPOCK on UTS#1 and UTS#2.
This might be the system programmer in charge of all the
UTS source, and so has access to multiple UTS systems and
would need read/write access to all the system disks.
This scheme allows for the greatest flexibility in allocating
disk space for UTS machines and UTS users.
.*
:h1.Generic Request Control Block and Reply Control Block Formats
.*
.sk
.il 5
The request control blocks for each ICATS function all
share a common format (see figure 4.1).
There are 16 8-byte fields for
a total of 128 bytes.  The first ten of these 8-byte fields
have a meaning common for all functions,
the other six fields are for
parameters peculiar to the particular function.
Not all functions use each of the first 10 fields
(TIME, for example, only uses the second field).
The unused fields can have anything in them but should be left
blank in case that field becomes meaningful at a later date.
All fields in the request control block are in EBCDIC,
even the all-numeric fields like the number of bytes to transfer
(the only exception is the TERMIO request control block).
All fields are left justified, padded with blanks on the right.
See the next chapter on
how the request control block is used for each function.
.*
.sk
.il 5
The fields of the request control block are described below.
:ul
:li.The "UTS User ID" is the field that must match a USER
statement in the configuration file, else this request
is rejected with a return code of X'4004'.
The only exceptions are those functions that aren't user oriented,
like TERMIO or TIME.
:li.The "ICATS Function" field defines the service being requested
(WRITE, READ, TIME, CAT, etc.).
ICATS functions are described in chapter 5.
If this field (with the required trailing blanks)
does not match one of the known ICATS functions, this request
is rejected with a return code of X'1000'.
:li.The "ICATS Subfunction" is an optional field depending
upon the function selected.  Currently, only the WRITE function
uses this field.
:li.The "Number of Bytes to Transfer" is either
the CCW byte count in the X'02' CCW ICATS gives
the UTS to get the data (as in a WRITE request),
or the maximum number of data bytes the
UTS can handle (as in a Read request - i.e. don't send more
than this many bytes).
:li.The "File Name", "File Type", and "File Mode" fields are
the standard CMS file identifiers.
The File Mode is one character long, and must be in the
first byte of the seventh field.
:li.The last byte of the seventh field is a pad character.
The pad character is used to pad a small record
that must be converted to a larger sized fixed length,
or to pad an odd length CMS record that is
to be shipped down to the UTS in variable-length format
(since variable-length UTS record lengths must be even).
Most of the times the user will want his records padded with blanks
but if he wants them padded with X'00' for example,
he has the facility to change the pad character.
:li.The "Write or Read Password" is the password required when
writing to or reading from one of ICATS' minidisks.
:eul
.*
:line65
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-------------------------------›       %-------------------------------›
|  UTS User ID                  | ----> |  UTS User ID                  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  ICATS Function               | ----> |  ICATS Function               |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  ICATS Subfunction            |       |  Next ICATS Subfunction       |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  Number of Bytes to Transfer  | ----> |  Number of Bytes to Transfer  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Name                    |       |  Actual File Name Used        |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Type                    | ----> |  File Type                    |
<---+---*---*---*---*---*---+---&       <---+---*---*---*---*---*---+---&
| FM|       not used        |Pad| ----> | FM|       not used        |Pad|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  Write or Read Password       | ----> |  Write or Read Password       |
<---+---*---*---*---*---*---*---&       <---+---*---*---*---*---*---*---&
|URF|          not used         | ----> |URF|          not used         |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  UTS LRECL if Fixed Length    | ----> |  UTS LRECL if Fixed Length    |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  Starting Record Number       |       |  Next Starting Record Number  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |        Free                   |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       | Day of Week in MM/DD/YY Format|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
.tr & :
|          not used             |       | Time in HH&MM&SS Format       |
.tr & EC
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       |        Free                   |
<---*---*---*---*---*---*---*---&       <---*---+---*---*---*---*---*---&
.TR # #
|          not used             |       |RetCode| # Data Bytes Following|
.TR # AB
#---*---*---*---*---*---*---*---$       #---*---*---*---*---*---*---*---$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 4.1.  Standard Generic Request Control Block and Reply Control Block Format:
:ehp2.
Each line represents 8 bytes.
The arrows between the two control blocks mean that this parameter is
copied over to the reply control block unchanged.  Most of the time
this is the case, but sometimes fields are changed.
See the next chapter for details.
.kp off
:line6
.*
:ul
:li.The "UTS Record Format" is the format the UTS user sees
the data in, either "F" for fixed-length records, "V" for
variable-length records, or "S" for source records.
For example, if this is a read request,
the output is in the format specified in this field
regardless of whether the CMS file is in that format or not.
If this is a write request, the data the UTS is shipping up is in
that format, and the resulting CMS file,
if it's a new file, will also be in that format.
See the discussion on each of the three formats
in the next chapter under the write command.
:li.If the UTS Data Format specifies fixed-length records,
this field contains the logical record length (LRECL) or the
record blocking factor.  This blocking factor does not necessarily
have to be equal to the CMS file's LRECL.  If, for example,
the UTS user wants to read a fixed, 60-byte CMS file and
wants it in fixed 80-byte format, each record will be padded with
20 of the pad characters.
:li.The "Starting Record Number" field is used for read
requests and direct access write requests only.
Blanks, zeros, or a one here will all start with the first record.
A two will skip the first record and start with the second.
:eul
.*
.sk
.il 5
The reply control block is, for the most part, an unchanged
copy of the request control block.  Depending on the function
however, some fields may be modified.
The twelfth and thirteenth 8-byte fields are used
by some functions to return
the current date and time in the same format as the TIME function.
The fourteenth field in the reply control block is
used by some functions to return some informational data not
directly requested.  See the READ and WRITE functions for details.
The last field will
.us always
be changed to show the return code (used to determine
what, if anything, went wrong) and the number of bytes of data
that follow this reply control block (which could be zero).
The data in these last two fields, unlike everything else in the
request and reply control blocks, is in
hexadecimal, not EBCDIC.  So, when I say the return code is zero,
it will be two bytes of hex zeros (X'0000'),
not two bytes of EBCDIC zeros (X'F0F0').
.*
.sk
.il 5
The function of the reply control block is twofold.  One, to tell the
UTS machine the result of the function he requested, and two, to use
as the next request control block.  For example, assume a user on a
UTS machine has a big file he wants written on his CMS minidisk.
Since the file is so big, it must be written in two steps.
The first request control
block might request the WRITE and Replace function.  The reply
control block coming back from this WRITE request will have the
subfunction field changed to APPEND since, if the UTS user is
going to continue to write to this file, he will probably want to
append the new data,
not write over the data he just got through writing.
This reply control block can be examined to insure that the first
write went O.K. and then used as the request control block for the
second write.
Likewise, if he's now reading that big file, the first request
control block would say READ, starting with the first record.
Let's say he read the first 250 records, the reply control block
would have 251 for the starting record number since, if he's going
to continue reading, that's where he would want to start the next
read from.
.*
.sk
.il 5
The return code in the reply control block will be a 16-bit
hexadecimal number.
Return codes are uniform throughout the ICATS system,
regardless of which ICATS function is used.
That means that return codes will always have the same meaning.
For example, a return code of X'1000' always means that
this is an invalid ICATS function and X'1010' always means
you supplied the wrong password.
The first 8 bits will give the class of error that occurred,
the last 8, the particular error inside that class.
The different error classes which are arranged
in order of severity, are
:ul
:li.X'0000' - X'0FFF' = None, expected, or only a minor error occurred.
:li.X'1000' - X'1FFF' = Invalid parameter found in request control block.
:li.X'2000' - X'2FFF' = Miscellaneous error.
:li.X'3000' - X'3FFF' = UTS or terminal I/O error.
:li.X'4000' - X'4FFF' = Configuration file error.
:li.X'5000' - X'5FFF' = CMS detected error.
:li.X'6000' - X'6FFF' = "Should never happen" errors.  Logically impossible.
:li.X'7000' - X'5FFF' = Program detected error.  Should also never happen.
:li.X'8000' - X'FFFF' = Unused.
:eul
.*
.sk
.il 5
Any data shipped down to the UTS machine will be prefixed by a
reply control block.  Inside this reply control block will be a
count field telling the UTS machine how many (8-bit) bytes of data
were shipped over in this I/O operation.
The data, if any, will directly follow the reply control block.
The last 6 bytes in the reply control block is this count.
The count will be a hexadecimal number and will
.us not
include the 128 bytes for
the reply control block itself.  So, if there is no data
following the reply control block, the count will be zero.
If there's 1000 bytes of data following the reply control block
(1128 bytes transferred in all), the count will be 1000
(X'0000000003E8').
.*
:h1.ICATS Functions - Detailed Description
.*
.*  ---  QUIT  TRACE  TEST  FAKIT  RESTART STATUS
.*  ---  CAT   READ   TIME  WRITE  TERMIO
.sk
.il 5
The eleven ICATS functions (QUIT, TRACE, TEST, FAKIT, RESTART, STATUS,
CAT, READ, TIME, WRITE, and TERMIO) are described below,
along with a functional description of what happens
when each is invoked,
the input specifications,
the output description,
and the possible return codes for each function.
.*
:h2.QUIT
.*
.sk
.il 5
The QUIT command is only valid from the console.
It is used to shut ICATS down and return to CMS.
One should use the STATUS command before shutting down
to see if anybody is using ICATS.
The format for the QUIT command is simply,
.fo off
 
           QUIT
 
.fo on
There are no parameters and Q is the abbreviation for QUIT.
.*
:h2.TRACE
.*
.sk
.il 5
ICATS keeps an internal trace table that records various
events in the ICATS virtual machine.
The TRACE command turns this tracing on or off, and is only
valid from the console or from an SMSG.
The format for the TRACE command is
.fo off
 
            TRACE | T   <? | ON | OFF>
 
.fo on
The abbreviation for TRACE is T.
TRACE ? will tell you whether tracing is being done right now or not
and, if entered from the console, will tell you the addresses of the
beginning, next entry, and end of the trace table.
Use the command #CP D Txxxxx.xxx to see the trace table entries.
The trace table entries are prefixed by an 8-byte hex time stamp, but
the rest is in EBCDIC to make for easy reading.
TRACE ? is the default if you just say TRACE.
Normally, ICATS comes up with tracing off.
.*
:h2.TEST
.*
.sk
.il 5
The TEST command is only valid from the console.
The ICATS program has 96 test flags available that produce
messages under various circumstances.
The TEST command queries these flags or turns them on or off.
The messages produced by the test flags are useful for program
debugging and are not for general use.
The format for the TEST command is
.fo off
 
            TEST   <nn | ALL>  <? | ON | OFF>
 
.fo on
There is no abbreviation for TEST.
NN is a number from 1 to 96.
TEST ALL ? is assumed if you just enter TEST.
Normally, ICATS comes up with all the test flags off.
As of this writing, the test flags get you the following messages
from the following modules;
:ol
:li.READ - BYTE COUNT THUS FAR IS nnn, NUMWANTS IS STILL nnn.
:li.READ - RECORD NUMBER nnn IS nnn BYTES BIG.                          .
:li.WRITE - MVCL TO aaaaaa, LENGTH = nnnn.
             FROM aaaaaa, LENGTH = nnnn.
:li.WRITE - I'M GOING TO WRITE nnnn BYTES STARTING AT aaaaaa.
:li.WRITE - THE FILE JUST WRITTEN WAS fn ft fm.
:li.WRITE - AFTER nn RECORDS, THE RETURN CODE IS nn.
:li.READ - DONE FOR NOW.  RETURN CODE = nn, # BYTES TRANSFERRED = nnnn. n.
        # COMPLETED RECORDS = nnnn, # COMPLETED BYTES = nnnn.
        # BYTES YOU WANTED = nnnn, UTS LRECL = nnn, STARTING RECORD # = nn.
        THE PAD CHAR WAS HEX xx AND THE BIGGEST RECORD I FOUND WAS nn.
        BUFFER ENDS AT aaaaaa.
        END OF FILE WAS <NOT> HIT.
        LAST RECORD IS <NOT> INCOMPLETE.
:li.WRITE - THIS IS RECORD # nn IN THIS BLOCK AND THERE'S nnn BYTES LEFT TO DO.
:li.UTSIOIH - IGNORING THIS UTS INTERRUPT.  CSW STATUS = xxxx.
:li.TERMIOIH - GOT A TERMINAL INTERRUPT FROM aaa, CSW STATUS = xxxx.
:eol
The rest of the test flags are not assigned.
.*
:h2.FAKIT
.*
.sk
.il 5
The FAKIT command is only valid from the console or via an SMSG.
Out of necessity, since the software was developed before the
hardware was available, I developed a means of testing the software
be faking an attention interrupt from the UTS.
Once the attention interrupt got faked, the program would go
through it's normal code for whatever function got requested.
All I/O for the duration of this request however, is also faked.
The request control block is read from the file ICATS REQUEST A.
Any data "read" from the UTS is read from ICATS INDATA A.
Any data "written" to the UTS is written to ICATS OUTDATA A.
The format for the FAKIT command is
.fo off
 
           FAKIT   <xxx>
 
.fo on
XXX is a optional hex address of which UTS address to fake the
attention interrupt from (the default is the first UTS).
The abbreviation for FAKIT is F.
Generally, this setup works quite well for testing new functions
or for seeing what gets sent to the UTS for a given input.
.*
:h2.STATUS
.*
.sk
.il 5
The STATUS command is valid from the console or from a SMSG.
It's used to see what's been going on in the ICATS virtual machine.
The format for the STATUS command is
.fo off
 
            STATUS
 
.fo on
There is no abbreviation for STATUS.
The STATUS command tells you which terminals are being used,
which UTS they're "plugged into" or that they're looking at a menu
right now, and the time of their last interrupt.
It will also tell you which UTS machines are offline or
the time of their last interrupt.
The STATUS command was intended to be used just prior to shutting
down ICATS to see whether or not it is being used.
.*
:h2.RESTART
.*
.sk
.il 5
The RESTART command is used to bring online those UTS machines that
are currently offline.
When ICATS first starts up, it tries to vary on and attach each UTS
machine.  If the UTS machine doesn't respond, it's considered to be
offline.  The RESTART command instructs ICATS to try again to get
those offline UTS machines.
The RESTART command is valid from either an SMSG, the console, an
online UTS, or from a DIALed terminal.
The format for the RESTART command from the console or an SMSG,
is simply,
.fo off
 
           RESTART
 
.fo on
There are no parameters and there is no abbreviation.
.*
.sk
.il 5
From the menu on a DIALed terminal,
position the cursor under an offline UTS and hit the enter key.
ICATS will know that that UTS is offline and try to get it online.
If it succeeds, you will be "plugged in" to that UTS.  If not,
you'll be told that ICATS failed to get it online.
.*
.sk
.il 5
From a UTS machine, the request control block needs only the
ICATS function field (the second 8-byte field) to specify
RESTART.  The return code in the reply control block will
always be zero, as will the Number of Data Bytes Following.
.*
:line65
:h3.RESTART Request and Reply Control Blocks
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-------------------------------›       %-------------------------------›
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| R   E   S   T   A   R   T     | ----> | R   E   S   T   A   R   T     |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---+---*---*---*---*---*---+---&       <---+---*---*---*---*---*---+---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---+---*---*---*---*---*---*---&       <---+---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---+---*---+---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---+---*---*---*---*---*---&
.TR # #
|          not used             |       |RetCode| # Data Bytes Following|
.TR # AB
#---*---*---*---*---*---*---*---$       #---*---*---*---*---*---*---*---$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 5.3.RESTART Request and Reply Control Blocks
:ehp2.
The return code and the number of data bytes following in
the reply control block will always be hex zeros.
.kp off
:line6
.*
:h2.WRITE
.*
.sk
.il 5
Write requests can come from another user via an SMSG (what I'll
call SMSG writes) or from a UTS machine (UTS writes).
All write requests write data to a CMS file
onto one of ICATS' minidisks.
For SMSG writes, the file is copied from one of
the requestor's minidisks.
For UTS writes, the data comes from a
separate SIO operation
(that is, separate from the SIO's for the
request and reply control blocks).  This separate SIO
will have one CCW with an op code of X'02' (Read).
The data length for this one CCW will be specified by the
"Number of Bytes to Transfer" field in the request control block.
.*
.sk
.il 5
Write is a very powerful function.
An SMSG write only works one way - it copies a whole file
from the requestor's minidisk onto one of ICATS's disks,
overlaying the old copy if there was one.
For UTS writes though, there are five different ways to write
to the CMS file and three different formats the input data can
be in.
You can write the whole file, rewrite any one record or a block
of records, or append records to the CMS file.
If a file already exists with this file name, you can choose to
abort this write request, rewrite the file, or write the data
to a new file with a different file name.
The data can be fixed-length, variable-length, or in UTS
source code format.
The five different kinds of writes are,
.*
:ol
:li.:hp2.Create.:ehp2.  If you say to write the file
TEST DATA B and a file already exists with that name,
then this Write request is aborted.  The original TEST DATA B
file is left undisturbed.
.*
:li.:hp2.Replace.:ehp2.  If you say to write the
file TEST DATA B, and a file already exists with that name,
that file is first erased and a new TEST DATA B file
is then written with the transferred data.
If the file TEST DATA B does not already exist, then the
file TEST DATA B is created.
.*
:li.:hp2.Increment the Version Level.:ehp2.  If you say
to write the file TEST DATA B and the file TEST DATA B
already exists, then ICATS will change the file name to TEST000
and create the file TEST000 DATA B with the new data.
If the files TEST DATA B and TEST000 DATA B both exist,
then the data will be written to the file TEST001 DATA B.
If TEST, TEST000, and TEST001 all exist, TEST002 will be used;
et cetera, until an unused file name is found.  This gives
the UTS user 1001 file names (TEST, TEST000-TEST999) to
go through until this write request cannot be serviced.
The reply control block I send back to the UTS machine will
inform the UTS user of the actual file name used.
See the paragraph on the next page for more details
on the file name search order.
This method of writing was designed for those times where
you want this data saved and you cannot stand to resend it
if there's an error.  For example, if some test is
collecting data every hour and sending it up to VM,
you would probably want to do the write by this method.
Besides avoiding the conflict of duplicate file names,
the data will be in separate files.
So if anything should go wrong, it only affects one hours' testing.
.*
:li.:hp2.Append.:ehp2.  The data that gets transferred is
appended to the already existing CMS file.  If the file
does not already exist, the request is treated as
a create and a new file is created.
.*
:li.:hp2.Direct Access.:ehp2.  The file is
presumed to already exist, and the data is to replace the
records starting at the specified record number.  For example,
if the file TEST DATA B is 75 80-byte records large, and
you say to write 240 bytes starting at record 49, then
record numbers 49, 50, and 51 get replaced with the new data.
The starting record number must be less than the total
number of records in the file plus one.
The CMS file must be a fixed-length file, else the Write
request will be rejected.  Writing in the middle of
variable-length CMS files is not supported.
:eol
.*
.sk
.il 5
The search order ICATS goes through to find an unused file name
for the increment the version level write is
first, try the original file ID.
If the original file ID is being used by another file, then
change the file name by appending three zeros and see if that
file ID is being used.  If so, then continue to increment the
three zeros in the file name until either a free file ID
is found or it goes past 999.
The reason I chose to use three zeros instead of some other
number is because file names on the UTS are only five characters
long.  That leaves three positions to get up to CMS's eight
character limit.
So a file can have identical file names on the UTS machine
and on VM, with just the last three characters being a
version level number.
If the original file name is shorter than five characters,
the three zeros are appended after the last character.
If longer, they overlay the sixth through eighth characters.
Here are some examples;
.sk;.fo off;.cp 16
Original
.ti ^ 05;.tb 14
.usFile Name^File Name Search Order
.sk
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
A             A, A000, A001, .... A999
TEST          TEST, TEST000, TEST001, .... TEST999
ATEST         ATEST, ATEST000, ATEST001, .... ATEST999
TESTDATA      TESTDATA, TESTD000, TESTD001, .... TESTD999
                   |||       |||
                   #**-------***- The "ATA" gets overlayed.
TEST000       TEST000, TEST0000, TEST0001, .... TEST0999
                  |        |
                  #--------*- This '0' does not get incremented.
ATEST000      ATEST000, ATEST000, ATEST001, .... ATEST999
                 |        |
                 #--------*- Yes, ATEST000 is checked twice.  No biggy.
ATEST123      ATEST123, ATEST000, ATEST001, .... ATEST999
                 |                        |
                 #------------------------*- Yes, ATEST123 is checked twice.
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.*
.sk
.il 5
The first three types of writes will always create a new CMS file.
Append writes may, if the file does not already exist, create a
new file.  Direct access writes will never create a new file.
If the CMS file already exists, its file characteristics
(record format and logical record length) are already fixed,
they cannot be changed.
If the CMS file is going to be created, then its file
characteristics will have to be specified.
The file characteristics for new CMS files shall be determined
by the characteristics of the input data.
If the input data is in either variable-length or source code
format, then the new CMS file will be variable-length.
If it's in fixed length format, then the CMS file will also
be fixed length and have the same LRECL as the input data.
.*
.sk
.il 5
File names on the UTS may start with a cent sign (›),
but the CMS file system does not like cent signs.  Therefore,
if a WRITE request ever specifies a cent sign as the first
character of the file name, ICATS will substitute a pound sign.
For example, if you say to create a file with a file name
of '›TEST', then ICATS will write a file with a file name of '#TEST'.
Likewise, if you say to read '›TEST', ICATS will read '#TEST'.
.*
:h3.SMSG Write Request Format
.sk
.il 5
To write a file from your VM signon, to one of ICATS's minidisks,
enter the CP command
.fo off
      SMSG ICATS WRITE fn ft yda ydrp utsid userid ud udwp
.fo on
where
:ul
:li."SMSG ICATS WRITE" tells ICATS that you want to copy a file
from your disk to one of his.
:li.fn ft is the file name and file type as the file sits on your
disk now.  This will also be the file name and file type when the
file gets copied onto ICATS's disk.
:li.yda is your disk address.  This is
.us not
the file mode of your minidisk (i.e. 'A').
Rather, this is its address (e.g. '191').
:li.ydrp is the read password for your minidisk.  This is the
password CP needs when ICATS links to your disk to read the file.
:li.utsid is the UTS unique identifier that distinguishes this UTS
from other UTS machines ICATS is servicing.  This is the second
parameter on the UTS statement in the ICATS CONFIG file.
:li.userid is the UTS user id to identify which disk you wish to
write on.  This is the second parameter on the USER statement
in the ICATS CONFIG file.
:li.ud specifies which of this user's disks you want to write on.
This is the second parameter on the DISK statement
in the ICATS CONFIG file.
:li.udwp is the write password for this user's disk.
This is the fifth parameter on the DISK statement
in the ICATS CONFIG file.
:eul
.*
.sk
.il 5
Basically, what ICATS does when doing an SMSG write, are these
three commands.
.fo off
      CP LINK vmuserid yda 5FF RR ydrp
      ACCESS 5FF Z
      COPYFILE fn ft Z = = ud ( REPLACE
.fo on
You can see why 'yda' must be your disk address ('191'), not your disk
access mode ('A'), because ICATS has to LINK to your minidisk.
This also explains why ICATS needs your disk read password ('ydrp')
and why 5FF is a reserved ICATS minidisk address (see figure 3.1).
As you can also see from this method of writing, you can only write
from a disk that your virtual machine owns.  For example, if I'm
logged on to VM as JASPER and link to another disk by saying,
.fo off
      CP LINK DOBBEK 191 222
      ACCESS 222 B
.fo on
then I won't be able to write to an ICATS disk
from what is now my 222 disk, because
ICATS will try to do the link to JASPER's 222 disk and JASPER
doesn't have a 222 disk defined in his directory entry.
What I would have to do is to copy the file over to my A-disk and
then do the SMSG write from my 191 disk.
.*
:line65
:h3.WRITE Request and Reply Control Blocks
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-------------------------------›       %-------------------------------›
|  UTS User ID                  | ----> |  UTS User ID                  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| W   R   I   T   E             | ----> | W   R   I   T   E             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|        subfunction            |       |       next subfunction        |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  Number of Bytes to Transfer  | ----> |  Number of Bytes to Transfer  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Name                    |       |  Actual File Name Used        |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Type                    | ----> |  File Type                    |
<---+---*---*---*---*---*---+---&       <---+---*---*---*---*---*---+---&
| FM|       not used        |Pad| ----> | FM|       not used        |Pad|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|        Write Password         | ----> |        Write Password         |
<---+---*---*---*---*---*---*---&       <---+---*---*---*---*---*---*---&
|         Input Format          | ----> |         Input Format          |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  LRECL if Fixed-Length Input  | ----> |  LRECL if Fixed-Length Input  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| Starting Record Number if DA  |       |  Next Starting Record Number  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       | Day of Week in MM/DD/YY Format|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
.tr & :
|          not used             |       | Time in HH&MM&SS Format       |
.tr & EC
<---*---*---*---*---*---*---*---&       <---+---+---*---+---*---+---*---&
.TR # #
.TR " |
|          not used             |       |F"V|   | LRECL |# RCDS |Biggest|
<---*---*---*---*---*---*---*---&       <---*---+---*---*---*---*---*---&
|          not used             |       |RetCode| # Data Bytes Following|
.TR # AB
.TR " "
#---*---*---*---*---*---*---*---$       #---*---*---*---*---*---*---*---$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 5.1.WRITE Request and Reply Control Blocks
:ehp2.
.kp off
:line6
.*
.cp 8
:h3.Input Specification
.*
.sk
.il 5
The request control block has these required fields;
:ul
:li.UTS User ID.
:li.ICATS Function ('WRITE').
:li.ICATS Subfunction.  This will be 'CREATE', 'REPLACE',
'INCRVL', 'APPEND', 'DA', or blank (defaults to 'CREATE').
:li.Number of Bytes to Transfer.  This number is the number of bytes
the UTS user is going to send to ICATS to write to the CMS file.
:li.File Name, File Type, and File Mode.
:li.Pad Character.  If input records must be
expanded to a larger fixed-length LRECL, this character will
be used to pad the trailing portion of the record.
:li.Write Password.  This is the write password for this
UTS user for this minidisk.
:li.Input Format.  The input data can be in one of three formats,
fixed-length, variable-length, or source code format.
See the next paragraph for details on the format of each.
This field designates which format the input will be in.
Only the first letter of this field is checked and must be
the letter 'F', 'V', or 'S'.
:li.LRECL if Fixed-Length Input.  If the input is going to be
fixed-length, ICATS will need to know the blocking factor, or
LRECL, of the input.  This field will be that LRECL.
:li.Starting Record Number.  If this is a Direct Access Write
request, this field tells ICATS which record number in the CMS
file to start writing at.  A zero or one will start writing at
the start of the CMS file, a two will start at the second record, etc.
If this field specifies a number that is larger than the number of
records plus one, an error is recognized and the write operation
is aborted.  Specifying a starting record number equal to the
number of records currently in that CMS file plus one, appends the
data to the end of that file.
:eul
.*
.sk
.il 5
Input data from the UTS:fnref refid=foot5.:fn id=foot5
.*
This discussion applies as well to data sent to the UTS
from a READ request.  If the UTS user specifies the data to
be shipped in variable-length format, the CMS file data will
be converted to the variable-length format described here.
If source code format is requested,
then ICATS packages the CMS file data into the required
1740-byte blocks.
:efn
can be in one of three different formats, fixed-length,
variable-length, or source code format.
Fixed-length format is simply each record blocked back-to-back.
The input is solid data and the blocking factor (also known as
record length or LRECL) is given in the request control block.
.*
.sk
.il 5
Each record in variable-length format however, is prefixed
by a 2-byte length field.  This length field specifies
the length of this record divided by two.  In other words,
if a record is 10 characters long,
its length field will be X'0005'.
As you can see, all record in UTS variable-length format will
have an even length.  There are three anomalies with the length
field.
:ul
:li.The high order bit of the length field is used to indicate a
"tabbed" record.  The tab is six blank characters.  For example,
if the length field of a record is X'8005', its true length is
.fo off
                 6 + (2*5) = 16 bytes
.fo on
and it has six leading spaces.  When this record is written to a
CMS file, those six leading spaces will be placed in the record.
However, when this record is read by the UTS user, ICATS does
.us not
take out those six spaces, they are left in.  Data shipped to the
UTS user in variable-length format will never have the "tabbed"
bit on.
:li.X'0000'.  A length field of all zeros is an end-of-file marker.
There's no more data belonging to this file.  If X'0000' is
encountered in the middle of variable-length
input data, the rest of the data
is ignored.  An end-of-file marker is put in variable-length
output if the end of the CMS file is encountered.
:li.X'FFFF'.  A length field of all ones is an end-of-block marker.
There's no more data in this data transmission.  If X'FFFF' is
encountered in the middle of input data, the rest of the data
is ignored.  An end-of-block marker is put in variable-length
output if the last record in the CMS file was not read.
:eul
.*
.sk
.il 5
UTS source code format is how source code is kept on the UTS.
A UTS source code file consists of one or more 1740-byte blocks.
Each 1740-byte block consists of a 10-byte header of 4 fields,
1710 bytes of variable-length data as described above,
and a 20-byte trailer consisting of 5 fields and 10 bytes of hex
zeros.
When writing to a CMS file,
ICATS takes the data from each 1740-byte block,
ignores the header and trailer (except for the "number of data bytes in
this block" field), and writes the records to the CMS file.
When reading, ICATS takes the records from the CMS file,
packs them into 1710-byte blocks of variable-length data,
appends the header, and tacks on the trailer.
The fields inside each 1740-byte block are as follows,
.fo off
.cp 11
 
Number
Bytes   Field Name         Field Description
 
   1    Encoded Machine    This single  hexadecimal  digit  is the  same
        Type               field as on the  USER statement in the  ICATS
                           CONFIG file.   It is ignored  on  a write and
                           filled in  with the value on the  USER state-
                           ment for this user on a read.
 
   5    File Name          This five-byte EBCDIC field is the  file name
                           this file is known as,  on  the  UTS.   It is
                           ignored  during a write  (since the file name
                           is given in the request control block) and is
                           filled in with the first  five  characters of
                           the CMS file name during a read.
 
   2    ??????             This two-byte field is x'F900'.  I don't know
                           what its  purpose is,  so  it's ignored  on a
                           write and filled in with x'F900' on a read.
 
   2    Number of Data     This two-byte  hexadecimal number is a  count
        Bytes In This      of the number of bytes of data in the records
        Block              in this block, including lengths, divided  by
                           two.   For example,  if there were only three
                           20-byte  records  in  this  block, then  this
                           field  would  contain  x'0021'  (3*(2+20)/2).
                           This field is used during a write to get only
                           valid record data,  and is properly filled in
                           during a read.
 
1710    Record Lengths     As many complete records that can fit are put
        and Data           in  these  bytes, in variable-length  format.
                           Each record  is prefixed  by a  2-byte length
                           field  as described above.   The rest of this
                           field is padded with hex zeros.
 
   2    Block Sequence     This hexadecimal field specifies the sequence
        Number             number  of this block in this file.   It will
                           be  x'0001' for the first block  of the file,
                           x'0002'  for  the  second,  x'0003'  for  the
                           third, etc.  This field is ignored on a write
                           operation and filled in on a read.   The only
                           time this field would need to be corrected by
                           the  UTS software,  is after a read  starting
                           from the middle of the CMS file.
 
   2    Number of Records  This field gives  the number of records  that
        In This Block      are in the 1710-byte data area in this block.
 
   2    Number of Data     This field is a duplicate of the fourth field
        Bytes In This      in this block by the same name.
        Block
 
   2    Next Block         This hexadecimal field is the sequence number
        Sequence Number    of the  :hp1.next:ehp1. block.   It will  simply  be one
                           plus  this  block's  sequence  number.   This
                           field is ignored  on a write  operation,  and
                           correctly  filled  in on  a read  (except  as
                           described above, after a read from the middle
                           of the CMS file).
 
   2    Number of Lines    This  hexadecimal  field is the count  of the
        Before This Block  number of records  :hp1.before:ehp1. this block.   Since
                           there are no records  before the first block,
                           this  field  in  the  first   block  will  be
                           x'0000'.  This field in the second block will
                           be the number of records in the first  block.
                           This field in the third block will be the sum
                           of the  number of records  in the  first  two
                           blocks.  This field is ignored during a write
                           operation and correctly filled  in  during  a
                           read.
 
  10    Unused             This field is  unused  and  ignored  during a
                           write.   It is set to  all hex zeros during a
                           read operation.
 
.fo on
.*
.cp 5
:h3.Output Specification
.*
.sk
.il 5
The reply control block is a duplicate of the request control block
except for the subfunction, the file name, the starting record number,
and the last 32 bytes.  The modified fields in the reply control
block are;
:ul
:li.Subfunction.  ICATS makes an educated guess at what the next
request, if any, will be.  Assuming the UTS user will continue to
write to this CMS file, the next subfunction will probably be
APPEND.  That is what is put in the subfunction field of the reply
control block.  The one exception is if this was a Direct Access Write.
Then the next request will probably be another Direct Access Write,
so the subfunction field is left unchanged.
.*
:li.File Name.  This field is modified only if this was a Write and
Increment the Version Level and ICATS had to
increment the version level in the file name to write the file.
This field notifies the UTS user of the
actual file name ICATS used to write the CMS file.
.*
:li.Starting Record Number.  In keeping with the philosophy of
making the reply control block usable as the next request control
block, this field is changed (Direct Access Write only) to point
to the record following the last record that was written this time.
.*
:li.Today's date and Time of Day.  This is the current date and time
in the same format as in the TIME function.
.*
:li.CMS File Record Format.  The next 8 bytes contain information on
the CMS file just written.  This one-byte field will be the
character 'F' or 'V' depending on whether the CMS file has
fixed or variable length records.  This is the only field of the
last 16 bytes to be in EBCDIC, all the rest are in hexadecimal.
.*
:li.CMS File LRECL.  This field will be the logical record length if
the CMS file is fixed length, else it's variable length and this
field is the longest record now in the file.
.*
:li.Number of Records in the CMS File.
.*
:li.Biggest Record Found in the Input Data.
If an input record gets truncated to fit
into a fixed-length CMS file, that fact will not be reflected in
the return code.  The return code will still be zero.
Instead, the UTS user
can compare the CMS File LRECL with this field.  If this field
is larger than the CMS File LRECL, then he knows that truncation
has occurred.
.*
:li.Return Code.  See the next section for possible return codes.
.*
:li.Number of Data Bytes Following.  There is never any data following
the reply control block of a Write request, so this will always be zero.
:eul
.*
.cp 8
:h3.WRITE Return Codes
.*
Return Code
:dl tsize='11'
:dt.X'0000'
:dd.All went O.K.  There were no detected errors.
The input data ended exactly at the end of a record,
an end-of-block marker (X'FFFF'), or
an end-of-file marker (X'0000').
.*
:dt.X'0004'
:dd.An end-of-block marker (X'FFFF') or an end-of-file marker
(X'0000') was found in the input data before the end of the
input data was reached.  Only data up to this point in the
input data was written to the CMS file, the rest was ignored.
Other than that, everything went O.K.
.*
:dt.X'0008'
:dd.The last input record was incomplete and padded.  This
would happen when we've run out of input data before completing
the last record.  You didn't send enough data.  The record
.us was
written to the CMS file, but ICATS is just warning you that
maybe something went wrong at your end.
.*
:dt.X'1000'
:dd.Invalid ICATS function.  The second field of the request
Control block is not a known ICATS command.
Possibly you don't have it left-justified, or padded with
blanks, or not all in upper case.
.*
:dt.X'1004'
:dd.Invalid "Number of Bytes to Transfer".
The third field of the request control block is not a valid
EBCDIC decimal number, or it's zero.
.*
:dt.X'1008'
:dd.Invalid File ID.  Either the file name or file type (or both)
violates the rules for a valid CMS file ID.  File names and file types
must be 1-8 characters.  Valid characters are A-Z, 0-9, $, #, and @.
.*
:dt.X'100C'
:dd.Invalid File Mode.  There is no such disk for this user
defined in the configuration file.
Verify the file mode in the request control block.
.*
:dt.X'1010'
:dd.Incorrect Write password given.
.*
:dt.X'1014'
:dd.Invalid Starting Record Number.  The starting record number
in the request control block is not a valid EBCDIC, decimal
number.
This can only happen with a Direct Access Write.
See also Return Code X'200C'.
.*
:dt.X'1018'
:dd.Invalid LRECL.  The logical record length in the request
control block for this fixed-length input data is not a valid
EBCDIC, decimal number or it is zero.
.*
:dt.X'101C'
:dd.Invalid Subfunction specified.  The third field in the
request control block is not a valid Write subfunction.
Possibly you don't have it left-justified, or padded with
blanks, or not all in upper case.
.*
:dt.X'2004'
:dd.You do not have write access to this disk.  The write
password for this user for this disk is 'NONE', meaning
it is a Read only disk.
.*
:dt.X'2008'
:dd.The CMS file does not exist.  This can only happen with
the Direct Access Write.
.*
:dt.X'200C'
:dd.The Starting Record Number is too big.  It is bigger than
the number of records in this CMS file plus one.
This can only happen with the Direct Access Write.
See also Return Code X'1014'.
.*
:dt.X'2010'
:dd.This variable-length input data ended right in the middle of
the length field for the last record.  Nothing was written for
the last record.
.*
:dt.X'2014'
:dd.You tried to do a Direct Access Write into a variable-length
CMS file.  Direct Access Writes are only supported with fixed-length
CMS files.  The CMS file is left unchanged.
.*
:dt.X'2018'
:dd.All file names used.  You tried to do a Write and Increment the
Version Level, and ICATS could not find an unused file name.
For example, you said to write the file TEST DATA, and the files
TEST DATA, TEST000 DATA, TEST001 DATA, TEST002 DATA, ..... TEST999
DATA already exist on that minidisk.
.*
:dt.X'201C'
:dd.File already exists.  You said to Write and Create, and a CMS
file already exists with that file name and file type.
.*
:dt.X'4004'
:dd.No such UTS user for this UTS.
Possibly you don't have it left-justified, or padded with
blanks, or not all in upper case.
If that's not it, then check to insure that that user is in the
configuration file for that UTS.
.*
:dt.X'4008'
:dd.No minidisk exists at that address.  The address specified
in the configuration file for this disk for this user does
not exist or is not a CMS minidisk.  Check the ICATS virtual
machine configuration.
.*
:dt.X'400C'
:dd.You tried to do a Write to a minidisk that
is a Read only minidisk for the ICATS virtual machine.
Either the configuration file is in error or the ICATS virtual
machine is not getting set up correctly.
.*
:dt.X'5004'
:dd.Unexpected error with the CMS command ACCESS.
:dt.X'5008'
:dd.Unexpected error with the CMS macro FSSTATE.
:dt.X'500C'
:dd.Unexpected error with the CMS macro FSOPEN.
:dt.X'501C'
:dd.Unexpected error with the CMS macro FSERASE.
:dt.X'5020'
:dd.Unexpected error with the CMS macro FSWRITE.
.*
:dt.X'5024'
:dd.This minidisk is full.  As much of the data as we could was
written to the CMS file, but some data (maybe all of it) was lost.
.*
:dt.X'6004'
:dd.UTS was not found in UTSCB chain.
:dt.X'600C'
:dd.Unexpected error with the CMS macro FSPOINT.
:dt.X'7004'
:dd.Unexpected return code from the ACCESS routine
in the ICATS mainline program.
:edl.
.*       End of Write Return Code list
.*
:h2.READ
.*
.sk
.il 5
Fortunately, the read function is a whole lot simpler than the write.
The read function is used to read data from a CMS file and
ship it to the UTS machine.
Read requests can only come from a UTS machine.
The UTS user specifies the CMS file id,
the maximum number of bytes he wants,
and the format he wants it in,
and the file is shipped down to him.  If the end of the
CMS file is reached before the maximum number of bytes
is reached, then only that number of bytes are shipped to
the UTS and the byte count is given in the reply control block.
The UTS user should ask for as much of the file as he can handle
at a time, which would probably be the whole file.
But if the file is really huge or his buffer space really small,
then he could ask for the file n bytes at a time.
.*
:line65
:h3.READ Request and Reply Control Blocks
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-------------------------------›       %-------------------------------›
|  UTS User ID                  | ----> |  UTS User ID                  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| R   E   A   D                 | ----> | R   E   A   D                 |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|           not used            | ----> |           not used            |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  Number of Bytes to Transfer  | ----> |  Number of Bytes to Transfer  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Name                    | ----> |  File Name                    |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Type                    | ----> |  File Type                    |
<---+---*---*---*---*---*---+---&       <---+---*---*---*---*---*---+---&
| FM|       not used        |Pad| ----> | FM|       not used        |Pad|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|         Read Password         | ----> |         Read Password         |
<---+---*---*---*---*---*---*---&       <---+---*---*---*---*---*---*---&
|        Output Format          | ----> |        Output Format          |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  LRECL if Fixed-Length Output | ----> |  LRECL if Fixed-Length Output |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| Starting Record Number        |       |  Next Starting Record Number  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       | Day of Week in MM/DD/YY Format|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
.tr & :
|          not used             |       | Time in HH&MM&SS Format       |
.tr & EC
<---*---*---*---*---*---*---*---&       <---*---*---*---+---*---+---*---&
.TR # #
.TR " |
|          not used             |       |#Complete Bytes|# RCDS |Biggest|
<---*---*---*---*---*---*---*---&       <---*---+---*---*---*---*---*---&
|          not used             |       |RetCode| # Data Bytes Following|
.TR # AB
.TR " "
#---*---*---*---*---*---*---*---$       #---*---*---*---*---*---*---*---$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 5.2.READ Request and Reply Control Blocks
:ehp2.
.kp off
:line6
.*
.cp 7
:h3.Input Specification
.*
.sk
.il 5
The request control block has these required fields;
:ul
:li.UTS User ID.  This identifies the CMS disk the file is to
be read from by correlating it to the ICATS CONFIG file.
:li.ICATS Function ('READ').
:li.Number of Bytes to Transfer.  This number should be the
maximum number of bytes the UTS user can handle at one time.
:li.File Name, File Type, and File Mode.  The CMS standard file id,
left-justified and padded with blanks.
:li.Pad Character.  If a CMS record needs to be expanded to fit a
larger size fixed-length output, or if an odd-sized record must have
one character added to make the output record's length even (since
UTS variable-length records have even lengths), then this
character will be used to pad the trailing portion of the record.
Normally, I should think this character should be a blank, but if the
UTS user wants a different pad character, he has control over it.
:li.Read Password.  This should be the read password for this
UTS user for this minidisk.
:li.Output Format.  The format the output will be in is independent of
the CMS file's record format.
The input data can be put in either of the three formats, fixed-length,
variable-length, or source code format, whichever is desired by the
UTS user.  See the discussion in the previous section on the format
of each.  This field will be the single
character 'F', 'V', or 'S' and will determine which of the three
formats the output data will be in.
:li.LRECL if Fixed-Length Output.  If the output is going to be in
fixed-length format, ICATS will need to know the blocking factor, or
logical record length (LRECL),
of the output.  This field will be that LRECL.
:li.Starting Record Number.  This field determines which record
number to start reading at.
The starting record number can range from zero to the number of
records in this file.
It will generally be zero or one, meaning to start with the first
record in the CMS file.
:eul
.*
.cp 12
:h3.Output Specification
.*
.sk
.il 5
The reply control block is a duplicate of the request control block
except for the the starting record number,
and the last 32 bytes.  The modified fields in the reply control
block are;
:ul
:li.Next Starting Record Number.  In keeping with the philosophy of
making the reply control block usable as the next request control
block, this field is changed to point
to the record following the last record that was read this time.
For example, if the first 25 records were read this time, this field
will contain an EBCDIC 26 ('00000026').
.*
:li.Day of Week and Time of Day.  This is the current date and time
in the same format as in the TIME function.
.*
:li.Number of Bytes in the Completed Records.  If the output is in
fixed length format, this is the number of complete records times
the LRECL.  If it's in variable length format, this field includes
all the length fields as well as the data in the completed records.
If in source code format, this will be the number of complete
blocks times 1740, and so will always be a multiple of 1740.
See the discussion in the next two paragraphs for a more detailed
explanation of this field.
.*
:li.Number of Complete Records or Blocks.  If the output is in
fixed- or variable-length format, this field tells the UTS user
how many complete records there are in the output data.
If it's in source code format, this field gives the number of
complete 1740-byte blocks in the output.
See the discussion in the next two paragraphs for a more detailed
explanation of this field.
.*
:li.Biggest Record Found in the CMS file.  This field is the
size of the biggest record ICATS found in the CMS file.
.*
:li.Return Code.  See the next section for possible return codes.
.*
:li.Number of Data Bytes Following.  This will be the Number of
Bytes to Transfer specified in the request control block,
or the Number of Bytes in the Completed Records given in the
reply control block, whichever is smaller.
:eul
.*
.sk
.il 5
When a UTS user makes a read request, he probably doesn't know
the size of the CMS file, and so doesn't know how many bytes to ask
to be transferred.
Typically, the read request should be for the maximum number of
bytes the UTS can handle which would probably be enough to contain
the whole CMS file.
But if there's more data in the CMS file than he asked
to be transferred, then only a portion of the file will be sent
and the rest will have to be sent in a second read request.
If this is the case, the UTS user can find out how much
data he got in this read by examining the two reply control
block fields, "Number of Bytes in the Completed
Records" and "Number of Complete Records or Blocks".
To illustrate, let's suppose a UTS user makes a read request
for the ridiculously small amount of 1024 bytes.
The CMS file he's reading from has 30 records in it and he wants
the output blocked in 50-byte fixed-length records.
Since only 20 of the 30 records will fit in the 1024 bytes,
he will not get the whole file.
He will have read the first 20 records, part of the 21st, and
missed the last 9.  The number of
complete records will be 20, the number of bytes in the completed
records will be 1000 (20*50), and the next starting record
number will be 21.  Even though the last record has
only 24 of its 50 bytes in it and is incomplete, it is still
transferred (the UTS user said he wanted 1024 bytes, ICATS is
going to give him 1024 bytes of data if possible).  In this example, the
number of bytes in the completed records was simply the number of
completed records times the output LRECL.  But if the UTS user
wanted variable-length output, then the number of bytes in the
completed records would include the length fields for each record and
the trailing end-of-block marker (x'FFFF'),
or the end-of-file marker (x'0000') if end-of-file was hit,
and would be more useful.
.*
.sk
.il 5
If the output is in source code format, the "Number of Completed
Records or Blocks" field gives the number
of complete 1740-byte blocks given to the UTS, :hp1.not:ehp1. the
the number of records in those complete blocks.  Since normally, the
UTS will ask for some large multiple of 1740 number of bytes,
this field will indicate the number of blocks needed to contain the
whole CMS file.  But for illustrative purposes, let's assume
the UTS user asks for only 2000 bytes.
The CMS file contains 30 records, and let's say that
the first 23 records plus their length fields fit
into 1707 bytes and the 24th record is 10 bytes long, so that it
doesn't fit in the first block.
Then it would take two 1740-byte blocks to ship this file to the UTS.
But since the UTS user only asked for 2000 bytes, only one complete
block can be shipped in this read request.
The number of complete blocks will be 1, the number of
bytes in the completed records will be 1740, and the
next starting record number will be 24.
Note that 2000 bytes of data will be shipped
(the "Number of Data Bytes Following" field will be 2000),
but the last 260 will only be the beginning of the second block.
.*
.sk
.il 5
If, during reading, a record gets truncated to fit into a
smaller size fixed-length output, this fact will not be reflected
in the return code.
The return code will still be zero.
Instead, the UTS user must compare the output LRECL he
specified with the "Biggest Record Found" field of the reply
control block.  If the biggest record found in the CMS
File is larger than his output LRECL, then he knows that
data truncation has occurred.
That field might also come in handy if the UTS user tries something
stupid like reading a file in source code format, that contains a
record larger than 1708 bytes,
so that it won't fit in a 1740-byte block.
In that case, the return code would be x'2020' and that field
will show the size of the record that didn't fit.
.*
.cp 8
:h3.READ Return Codes
.*
Return Code
:dl tsize='11'
:dt.X'0000'
:dd.All went O.K.  There were no detected errors and we did
.us not
hit the end of file of the CMS file.  In other words,
there's still more data yet to read in this CMS file.
.*
:dt.X'0004'
:dd.All went O.K.  There were no detected errors and we
.us did
hit the end of file of the CMS file.  In other words,
there's no more data to read in this CMS file.
.*
:dt.X'1000'
:dd.Invalid ICATS function.  The second field of the request
Control block is not a known ICATS command.
Possibly you don't have it left-justified, or padded with
blanks, or not all in upper case.
.*
:dt.X'1004'
:dd.Invalid "Number of Bytes to Transfer".
The third field of the request control block is not a valid
EBCDIC decimal number.
.*
:dt.X'1008'
:dd.Invalid File ID.  Either the file name or file type (or both)
violates the rules for a valid CMS file ID.  See the CMS User's
Guide for a description of valid File ID's.
.*
:dt.X'100C'
:dd.Invalid File Mode.  There is no such disk for this user
defined in the configuration file.
Verify the file mode in the request control block.
.*
:dt.X'1010'
:dd.Incorrect Read password given.
.*
:dt.X'1014'
:dd.Invalid Starting Record Number.  The starting record number
in the request control block is not a valid EBCDIC, decimal
number.
.*
:dt.X'1018'
:dd.Invalid LRECL.  The logical record length in the request
control block is not a valid EBCDIC, decimal number or it's zero.
.*
:dt.X'2004'
:dd.You do not have read access to this disk.  The read
password in the configuration file
for this user for this disk is 'NONE'.
.*
:dt.X'2008'
:dd.The CMS file does not exist.
.*
:dt.X'200C'
:dd.The Starting Record Number is too big.  It is bigger than
the number of records in this CMS file.
.*
:dt.X'2020'
:dd.The CMS file you wanted read, contains a record larger than
1708 bytes.  This record will not fit in UTS source code format
block.  This file cannot be read in source code format.
.*
:dt.X'4004'
:dd.No such UTS user for this UTS.
Possibly you don't have it left-justified, or padded with
blanks, or not all in upper case.
If that's not it, then check to insure that that user is in the
configuration file for that UTS.
.*
:dt.X'4008'
:dd.No minidisk exists at that address.  The address specified
in the configuration file for this disk for this user does
not exist or is not a CMS minidisk.  Check the ICATS virtual
machine configuration.
.*
:dt.X'5004'
:dd.Unexpected error with the CMS command ACCESS.
:dt.X'5008'
:dd.Unexpected error with the CMS macro FSSTATE.
:dt.X'500C'
:dd.Unexpected error with the CMS macro FSOPEN.
:dt.X'5010'
:dd.I/O error while reading from the CMS minidisk.
:dt.X'5014'
:dd.Ran out of buffer space inside the ICATS program while reading
the CMS file.  Currently, I'm allocating 192K
for buffer space, and you've just exceeded that.
:dt.X'5018'
:dd.Unexpected error with the CMS macro FSREAD.
:dt.X'6004'
:dd.UTS was not found in UTSCB chain.
:dt.X'600C'
:dd.Unexpected error with the CMS macro FSPOINT.
:dt.X'7004'
:dd.Unexpected return code from the ACCESS routine
in the ICATS mainline program.
:edl.
.*       End of Read Return Code list
.*
:h2.TIME
.*
.sk
.il 5
Since the UTS machines do not have a time of day clock, the Time
function delivers the time and date to the UTS machine
in a variety of formats.
The different formats ICATS gives are,
:ul
:li.Date in script format (i.e. January 22, 1983),
:li.Date in Julian format (i.e. 83.022),
:li.Date in month, day, year format (i.e. 01/22/83),
:li.Time in hours, minutes, seconds (i.e. 14:22:59),
:li.And a 64-bit binary counter.
:eul
Time is also valid from the console or an SMSG and returns a
line similar to this.
.fo off
        TODAY IS MONDAY, OCTOBER 10, 1983 - THE TIME IS 14:22:41.
.fo on
.*
:line65
:h3.TIME Request and Reply Control Blocks
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-------------------------------›       %-------------------------------›
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| T   I   M   E                 | ----> | T   I   M   E                 |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---+---*---*---*---*---*---+---&       <---+---*---*---*---*---*---+---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       |             Date              |
<---+---*---*---*---*---*---*---&       <---+---*---*---*---*---*---*---&
|          not used             |       |              in               |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       |            Script             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       |            Format             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       |  Julian Date in YY.DDD Format |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       | Day of Week in MM/DD/YY Format|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
.tr & :
|          not used             |       |    Time in HH&MM&SS Format    |
.tr & EC
<---*---*---*---*---*---*---*---&       <---*---*---*---+---*---+---*---&
|          not used             |       |  64-Bit Binary Clock Counter  |
<---*---*---*---*---*---*---*---&       <---*---+---*---*---*---*---*---&
.TR # #
|          not used             |       |RetCode| # Data Bytes Following|
.TR # AB
#---*---*---*---*---*---*---*---$       #---*---*---*---*---*---*---*---$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 5.3.TIME Request and Reply Control Blocks
:ehp2.
.kp off
:line6
.*
.cp 8
:h3.Input Specification
.*
.sk
.il 5
The request control block has only one required field,
the function field.  The function field must contain the eight
EBCDIC characters 'TIME    '.  The rest of the request
control block is ignored.
.*
.cp 13
:h3.Output Specification
.*
.sk
.il 5
The reply control block is a duplicate of the request control block
except for the last 9 fields.  The first 7 fields contain EBCDIC
data and the last 2, hexadecimal data.  The last 9 fields are;
:ul
:li.Date in Script Format.  This field will be variable in length
and will be padded as necessary to fill the 32 bytes allotted for it.
.fo off
The minimum length is 19 characters
          ('Monday, May 1, 1983')  plus 13 blanks.
The maximum length is 29 characters
          ('Wednesday, September 22, 1983')  plus 3 blanks.
.fo on
:li.Julian Date.  The format for the Julian date is YY.DDD.
.fo off
For example, January 1, 1983 would be '83.001',
           December 31, 1983 would be '83.365',
       and December 31, 1982 would be '82.366' (1982 was a leap year).
.fo on
:li.Date in month, day, year format.  Leading zeros are not
suppressed.  For example, January 1, 1983 would be '01/01/83'.
:li.Time in hours, minutes, seconds format.  Leading zeros are not
suppressed.  Also, it's a 24-hour clock.
.fo off
For example, 1:05 a.m. and  3 seconds would be '01:05:03',
            11:59 p.m. and 59 seconds would be '23:59:59',
                         and midnight would be '00:00:00'.
.fo on
:li.64-Bit Binary Clock.  This is the result of the 370 instruction,
Store Clock.  Bit 51 (bit 0 is on the far left) is calibrated in
microseconds.  From my observations, this also seems
to be the resolution of the clock.  I've never seen any of the bits
past bit 51 (bits 52-63) be anything but zero,
but don't take my word on it.  The resolution of the CPU's clock
depends on which model CPU it is.  See the 370 Principles of
Operation manual for more details.
:li.Return Code.  This will always be zero.
:li.Number of Data Bytes Following.  This will also always be zero.
:eul
.*
.cp 5
:h3.TIME Return Codes
.*
.sk
.il 5
This is easy.  Nothing can go wrong with the TIME function
(famous last words), so the only return code possible is zero.
.*
:h2.CAT
.*
.sk
.il 5
The CAT function is only valid from a UTS.
It's similar to the CMS command, LISTFILE.
All the files on any minidisks this user has access to
can be listed.  As the CMS LISTFILE command
allows partial names to be specified (e.g. LIST TEST* * A),
this function also allows the same feature.
However, since the user must specify a read password and read
passwords may be different for different minidisks, the CAT
function will not allow an asterisk for the file mode.
Only the catalog of one minidisk may by queried at a time.
The data returned by this function includes all the details
of each file the CMS command LISTFILE gives with the DATE option.
This includes file name, file type, file mode, record format,
logical record length (LRECL),
the number of records in each file,
and probably,:fnref refid=foot6.:fn id=foot6
.*
The reason I say probably, is because there is a quirk
about CMS files that occasionally the date and time get
fouled up.  If this happens, there's nothing ICATS can
do to get them back again.  The CAT function will pass
on whatever CMS gives it, but be forewarned that there
can be no guarantees on the validity of the date and time.
:efn
the date and time the file was last modified.
.*
:line65
:h3.CAT Request and Reply Control Blocks
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-------------------------------›       %-------------------------------›
|  UTS User ID                  | ----> |  UTS User ID                  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| C   A   T                     | ----> | C   A   T                     |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  Number of Bytes to Transfer  | ----> |  Number of Bytes to Transfer  |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Name                    | ----> |  File Name                    |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|  File Type                    | ----> |  File Type                    |
<---+---*---*---*---*---*---+---&       <---+---*---*---*---*---*---+---&
| FM|       not used            | ----> | FM|       not used            |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|         Read Password         | ----> |         Read Password         |
<---+---*---*---*---*---*---*---&       <---+---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             |       | Day of Week in MM/DD/YY Format|
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
.tr & :
|          not used             |       | Time in HH&MM&SS Format       |
.tr & EC
<---*---*---*---*---*---*---*---&       <---*---*---*---+---*---+---*---&
.TR # #
|          not used             |       |# compltd bytes|# lines|# files|
<---*---*---*---*---*---*---*---&       <---*---+---*---*---*---*---*---&
|          not used             |       |RetCode| # Data Bytes Following|
.TR # AB
#---*---*---*---*---*---*---*---$       #---*---*---*---*---*---*---*---$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 5.4.CAT Request and Reply Control Blocks
:ehp2.
.kp off
:line6
.*
.cp 6
:h3.Input Specification
.*
.sk
.il 5
The request control block has these required fields;
:ul
:li.UTS User ID.
:li.ICATS Function ('CAT').
:li.Number of Bytes to Transfer.  This number should be the
maximum number of bytes the UTS user can handle.
Since each CMS file found generates 64 bytes of output data,
this number should be a multiple of 64.
:li.File Name and File Type.
These fields comprise the search criteria for this CAT command.
Only CMS files on this user's minidisk that satisfy this search
criteria will be returned to the UTS user.
They can contain any number of asterisks ('*') with their
normal CMS meaning of representing any number of characters.
:li.File Mode.  Unlike the CMS command LISTFILE, this field
cannot contain an asterisk.  The minidisk must be explicitly
specified.
:li.Read Password.  This should be the read password for this
UTS user for this minidisk.
:eul
.*
.cp 16
:h3.Output Specification
.*
.sk
.il 5
The reply control block is a duplicate of the request control block
except for the last 16 bytes.  The last 16 bytes contain hexadecimal
data in this format;
:ul
:li.Number of Bytes in Completed Lines.  This will be 64 times
the next field, the Number of Complete Lines.
:li.Number of Complete Lines.  This is the number of CMS files
satisfying the search criteria specified in the request control block
that would fit in the Number of Bytes to Transfer.
This would normally be the same as the next field, the
Number of Files Found, but if all the data wouldn't fit in the
Number of Bytes to Transfer, then this field would represent the
number of files that actually did fit.
:li.Number of Files Found.  This is a count of the number of CMS
files on this user's minidisk that satisfied the search criteria,
whether or not they all fit in the Number of Bytes to Transfer.
:li.Return Code.  See the next section for possible return codes.
:li.Number of Data Bytes Following.  This will be the smallest of
the Number of Bytes to Transfer or the Number of Bytes in
Completed Lines.
:eul
.*
.sk
.il 5
Following the reply control block will be the CMS file data.
As always, the amount of file data given will be reflected
in the last field of the reply control block.
The file data will be alphabetically ordered by file name
and file type.  The data will have 8 fields of 8 bytes each
(64 bytes) for each file found satisfying the search criteria.
The 8 fields, all EBCDIC, left-justified, and padded with
blanks, will be;
.kp on;.fo off;.sk
.ti ^ 05;.tb 8 17 38
.us^Offset^What It Is^Additional Comments
.sk;.in 7
 0 -  7   File Name
 8 - 15   File Type
16 - 23   File Mode            2 characters (e.g. 'A1')
24 - 31   Record Format        The character 'F' for fixed-length
                               or 'V' for variable-length files.
32 - 39   LRECL                No leading zeros.  The Logical Record
                               Length if fixed-length or the longest
                               record in the file if variable-length.
41 - 47   # Records in File    No leading zeros.
48 - 55   Date Last Modified   Date is in the format  'MM/DD/YY'.
                               No leading zeros (e.g. '1/03/83 ').
.tr & :
56 - 63   Time Last Modified   Time is in the format  'HH&MM   '.
.tr & &
                               No leading zeros (e.g. '1:07    ').
                               24-hour clock    (e.g. '14:59   ').
.kp off;.fo on;.in 0
.*
.cp 7
:h3.CAT Return Codes
.*
Return Code
:dl tsize='11'
:dt.X'0000'
:dd.All went O.K.  All the data on all the files that satisfied
the search criteria fit in the number of bytes you wanted.
.*
:dt.X'0004'
:dd.All the data on all the files that satisfied
the search criteria did
.us not
fit in the number of bytes you wanted.
You didn't ask for enough bytes.
.*
:dt.X'1004'
:dd.Invalid "Number of Bytes to Transfer".
The third field of the request control block is not a valid
EBCDIC decimal number.
.*
:dt.X'100C'
:dd.Invalid File Mode.  There is no such disk for this user.
Verify the file mode in the request control block.
.*
:dt.X'1010'
:dd.Incorrect Read password given.
.*
:dt.X'2004'
:dd.You do not have read access to this disk.  The read
password in the configuration file
for this user for this disk is 'NONE'.
.*
:dt.X'2008'
:dd.No files were found that satisfied the search criteria.
.*
:dt.X'4004'
:dd.No such UTS user for this UTS.
Possibly you don't have it left-justified, or padded with
blanks, or not all in upper case.
If that's not it, then check to insure that that user is in the
configuration file for that UTS.
.*
:dt.X'4008'
:dd.No minidisk exists at that address.  The address specified
in the configuration file for this disk for this user does
not exist or is not a CMS minidisk.  Check the ICATS virtual
machine configuration.
.*
:dt.X'5004'
:dd.Unexpected error with the CMS command ACCESS.
:dt.X'5014'
:dd.Ran out of buffer space inside the ICATS program while reading
the CMS file.  Currently, I'm allocating 192K
for buffer space, and you've just exceeded that.
:dt.X'6004'
:dd.UTS was not found in UTSCB chain.
:dt.X'6010'
:dd.Unexpected error with the CMS command LISTFILE.
:dt.X'7004'
:dd.Unexpected return code from the ACCESS routine
in the ICATS mainline program.
:edl.
.*       End of CAT Return Code list
.*
:h2.TERMIO
.*
.sk
.il 5
To do an I/O operation to a DIALed and "plugged in" terminal,
the UTS requests a TERMIO function.  This function performs
the I/O operation, waits around for ending status, and
then presents ending status to the UTS machine.
TERMIO is a peculiar function in that it could be a read
or a write operation.
If the channel command word (CCW) specified in the request
control block indicates a read, then
the terminal's buffer is read and data is sent to the UTS.
If the CCW specifies a write operation,
ICATS does another I/O operation to the UTS to get the data
to write to the terminal.
The sequence of I/O operations to the UTS are similar to
the sequence for the read and write functions.
.*
.sk
.il 5
If the CCW specifies a READ MODIFIED operation, ICATS may not
actually do another read to the terminal.
You see, this READ MODIFIED is probably in response to an
attention interrupt provided by the terminal.  When ICATS
saw that attention interrupt and before he passed the interrupt
on to the UTS, he did a READ MODIFIED of his own to check for
this terminal's session terminate string (usually four dollar
signs, '$$$$').  At that time, ICATS saved the data he got from
his READ MODIFIED (if it's 100 bytes or less), then passed
the interrupt on to the UTS.
Now, when the UTS comes around with a READ MODIFIED of its own,
ICATS can save an I/O operation and simply give the UTS the
data from the previous READ MODIFIED.
As always, the data from the read, regardless of when it occurred,
follows the reply control block.
.*
:line65
:h3.TERMIO Request and Reply Control Blocks
.kp on;.fo off
.TR - BF;.TR % AC;.TR * CB;.TR › BC;.TR & EC;.TR + 8F
.TR | FA;.TR # AB;.TR @ CC;.TR $ BB;.TR < EB
.*                     |
.*    %--*--›       |--|--|
.*    >  +  <  ==> -|  +  |-
.*    #--@--$       |--|--|
.*                     |
%-------------------------------›       %-------------------------------›
| Terminal Address              | ----> | Terminal Address              |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| T   E   R   M   I   O         | ----> | T   E   R   M   I   O         |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
| Channel Command Word (CCW)    |       | Actual CCW Used               |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---+---*---*---*---*---*---+---&       <---+---*---*---*---*---*---+---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---+---*---*---*---*---*---*---&       <---+---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---*---*---*---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---*---*---+---*---+---*---&
|          not used             | ----> |          not used             |
<---*---*---*---*---*---*---*---&       <---*---+---*---*---*---*---*---&
.TR # #
|          not used             |       |RetCode|x00|Sns|USt|CSt|# Bytes|
.TR # AB
#---*---*---*---*---*---*---*---$       #---*---*---*---*---*---*---*---$
.*
.TR - -;.TR % %;.TR * *;.TR › ›;.TR & &;.TR + +
.TR | |;.TR # #;.TR @ @;.TR $ $;.TR < <
.fo on
.sp 2
:hp2.
Figure 5.3.TERMIO Request and Reply Control Blocks
:ehp2.
.kp off
:line6
.*
.cp 8
:h3.Input Specification
.*
.sk
.il 5
Only the first three fields of the request control block are required,
the terminal address, the function field, and the CCW field.
The rest of the request control block is ignored.
The terminal address must be three left-justified, EBCDIC characters
(i.e. '100     ').
The function field must contain the eight EBCDIC characters
'TERMIO  '.  The CCW field contains the single CCW to use in
this I/O to this terminal.  Only CCW chains of one CCW long are
supported.  Only the command code (the first byte) and the
byte count (the last two bytes) of the CCW field are used,
the rest are filled in by ICATS.
This field is different from other fields in the
request control blocks for every other function in that
this field is given in hexadecimal, :hp1.not:ehp1 in EBCDIC.
.*
.cp 11
:h3.Output Specification
.*
.sk
.il 5
The reply control block is a duplicate of the request control block
except for the CCW field and the last field.  The CCW field is
modified to the actual CCW used (CCW bytes 2-6 are filled in).
This should be transparent to the UTS software since those fields
in the request control block are ignored anyway.
The last eight bytes contain,
:ul
:li.Return Code.  This is another unique feature of the TERMIO
function, these two bytes will always be zero.  Any error
indication will be reflected in the two CSW status bytes
and the sense byte.
:li.Free byte.  This byte is unused and will always be hex zero
(x'00').
:li.Sense Byte.  If the terminal gives a unit check in response to
this I/O operation, this will be the sense byte.  Normally, there
is no unit check, and this byte will be zero.  However, if the
terminal address is invalid, that terminal isn't "plugged into"
that UTS, or the terminal was turned off, the sense byte will show
intervention required (x'40').
:li.CSW Unit Status.
:li.CSW Channel Status.
:li.Number of Bytes Following Reply Control Block.  As always,
if any data is following the reply control block, this field
tells the UTS how many bytes of data there are.  For a write
operation, this will always be zero, but for a read operation,
this will give the number of bytes of data read.
:eul
.*
.cp 12
:h3.TERMIO Error Conditions
.*
.sk
.il 5
As stated above, the return code in the reply control block will
always be zero.  Any error indications will be posted in the
CSW status fields and the sense byte.
We decided it was better this way because the error handling
on the UTS side would be identical as with a direct terminal.
The errors that occur because of some error with the
request control block will respond as if the terminal is not
there, i.e. unit check in the CSW unit status and intervention
required in the sense byte.  Real I/O errors caused by
an invalid CCW op code, invalid data, or the terminal being
powered off will result in
whatever CSW status and sense byte the real terminal
provides to ICATS.
.*
:egdoc.