RFC 120

Network PL1 subprograms

πŸ“… published April 1971, from ietf

NETWORK PL1 SUBPROGRAMS ✨

okay bestie, this doc is all about how to use the Network from PL1 programs πŸ’– It's by Mark Krilanovich from the Computer Research Lab at the University of California, Santa Barbara, dated April 21, 1971 πŸŽ€ The title block I was given doesn't list a category or status, and it doesn't say what it obsoletes or updates, so I'm not making any of that up πŸ™ˆ

PREFACE πŸŽ€

The subroutines in here have been implemented at UCSB, and they make the Network (through the NCP) reachable from PL1 programs running on the 360/75 πŸ–₯️ They're callable from inside any PL1 main program or subroutine compiled at UCSB, so you can just call them 🧚

They're assembly-language subprograms that make life easier for PL1 programmers. They're the middleman between you and the Network Control Program (NCP), which supervises all Network operations at this site πŸ’…

Okay, this is the big one πŸ‘‘ Every socket that isn't in the closed state gets its own unique variable, called a completion code variable. It does two jobs: it identifies the local socket you're talking about, and when the operation finishes, it holds a completion code telling you how it went. You can use it for anything else whenever you want. Its value at the start of a Network operation doesn't matter, because it's the variable itself that's important 🫢 For every Network operation that needs one, the only acceptable attributes are BINARY FIXED(31,0)ALIGNED.

Usually, the subprograms start the operation and then enter the WAIT state (no CPU time eaten, bestie 😭) until the NCP says it's done. For those, you give a time limit with the attributes BINARY FIXED(31,0). It's measured in tenths of a second and tells the subprogram the maximum time to wait. If that limit gets exceeded, you get a completion code for the error, control goes back to your calling program, and the operation is still pending πŸ“

For operations that need a socket to be named by its socket identifier, it's a BINARY FIXED(31,0) array. It's singly dimensioned, has at least two elements, and its lower subscript bound is one. The first element is the site number and the second is the socket number. A socket number can be positive, negative, or zero. Negative numbers are stored in two's complement, so for the gender of a socket, a socket number is even or odd based on whether its absolute value is even or odd πŸ’œ

Here's each subprogram, what it does, and how to call it πŸ¦‹


(1) OPEN πŸ¦‹

Calling OPEN asks for the specified local socket to come out of the closed state so it's ready to take part in data transfer. There are three distinct operations you can do with it, and they're all below: CONNECT, LISTEN, and ACCEPT πŸ’–

(A) CONNECT πŸ”Œ

This one asks for the specified local socket to be logically connected to the specified foreign socket, with data transfer between the two enabled. The subprogram waits until the foreign socket either accepts or rejects the connection attempt. This operation is only valid when the socket is in the closed state.

The calling sequence goes like this:

CALL @OPEN(cmpcd, time,lclsck,fgnsck,ws);

where:

  • cmpcd is the completion code variable to be associated with the local socket.
  • time is how long the subprogram waits for the operation to complete.
  • lclsck is the socket identifier of the local socket.
  • fgnsck is the socket identifier of the foreign socket.
  • ws is a workspace with the same attributes as a socket identifier. If the operation is successful, it becomes associated with the local socket for the life of the connection. Certain future operations may return information to the programmer in this workspace πŸŽ€

These completion codes are possible for this operation:

   0,  The operation was successful and the connection has
       been established
   4,  The specified completion code variable is already
       assigned to a socket;  the operation was suppressed
   8,  The specified local socket is not in the closed
       state;  the operation was suppressed
  12,  All communication paths to the specified foreign site
       are in use;  the operation was suppressed
  16,  Local resources are insufficient to support another
       connection;  the operation was suppressed
  20,  The connection attempt was rejected by the foreign
       process
  24,  The specified local socket is not local to UCSB;  the
       operation was suppressed
  28,  The specified foreign site is invalid;  the operation
       was suppressed
  32,  An addressing or protection exception was encountered
       with respect to the specified workspace;  the
       operation was suppressed
  36,  Either hardware at the foreign site is inoperative or
       the NCP's counterpart at the foreign site does not
       exist or has failed
  40,  Local and foreign sockets are both either send or
       receive sockets;  the operation was suppressed
  44,  By operator command, all Network operations were
       terminated;  the socket will be closed
  60,  An NCP control transmission error occured;  the
       operation was suppressed
 252,  The specified time limit was exceeded;  the operation
       was initiated but not completed

(B) LISTEN πŸ‘‚

This is a request to be notified about any connection attempt aimed at the specified local socket. The subprogram waits until such a call comes in, and then the calling process's socket identifier is returned to the calling program. This operation is only valid when the designated local socket is in the closed state πŸ’«

The calling sequence goes like this:

CALL @OPEN(cmpcd, time,lclsck,ws);

where:

  • cmpcd is the completion code variable to be associated with the local socket.
  • time is how long the subprogram waits for the operation to complete.
  • lclsck is the socket identifier of the local socket.
  • ws is a workspace which, if the operation is successful, will contain the socket identifier of the calling socket, and will become associated with the local socket for the life of the connection. ws has the same attributes as a socket identifier 🧚

These completion codes are possible for this operation:

   0,  The operation was successful and a call has been
       received
   4,  The specified completion code variable is already
       assigned to a socket;  the operation was suppressed
   8,  The specified local socket is not in the closed
       state;  the operation was suppressed
  12,  Local resources are insufficient to support another
       connection;  the operation was suppressed
  16,  The specified local socket is not local to UCSB;  the
       operation was suppressed
  20,  An addressing or protection exception was encountered
       with respect to the specified workspace;  the
       operation was suppressed
  44,  By operator command, all Network operations were
       terminated;  the socket will be closed
 252,  The specified time limit was exceeded;  the operation
       was initiated but not completed

(C) ACCEPT 🫢

This one accepts the connection with the foreign socket whose call caused a previous LISTEN operation by the specified local socket to complete successfully. Once it's done, data can be transferred to or from the local socket, depending on its gender. This operation is only valid when the last operation that referenced the local socket was a LISTEN. The subprogram waits until the operation is completed 🌸

The calling sequence goes like this:

CALL @OPEN(cmpcd, time);

where:

  • cmpcd is the completion code variable associated with the local socket by a previous LISTEN operation.
  • time is how long the subprogram waits for the operation to complete.

These completion codes are possible for this operation:

   0,  The operation was successful, and the connection is
       established
   4,  The specified local socket is in the closed state
       (the NCP may have received an abort notification from
       the foreign process);  the operation was suppressed
   8,  The previous operation specifying the designated
       local socket was not a LISTEN;  the operation was
       suppressed
  12,  All communication paths to the specified foreign site
       are in use;  the socket has been returned to the
       closed state
 252,  The specified time limit was exceeded;  the operation
       was initiated but not completed

part 1 of 4 πŸ¦‹ more coming up next, bestie πŸ’–

(2) CLOSE πŸ¦‹

Okay so CLOSE is the "pls return this local socket to the closed state" request πŸ’… and it's lowkey so careful about everyone's data. If the last thing that happened on the socket was a LISTEN, CLOSE refuses the foreign process's connection attempt. If the last thing was a CONNECT, that attempt gets aborted. If a connection is already established, any data still in transit from the local socket is allowed to reach the foreign socket, and then it gets either received or flushed before the local socket closes. The subprogram waits until the socket is back in the closed state. Iconic behavior, no cap 🫢

The calling sequence looks like this:

CALL @CLOSE(cmpcd,time);

where cmpcd is the completion code variable tied to the local socket, and time is how long the subprogram is going to wait for the operation to finish ⏳

These are the completion codes you can get back from CLOSE:

0,  The operation was successful, and the socket has been
    returned to the closed state
8,  The specified completion code variable is not currently
    assigned to a socket;  the operation was suppressed
12,  The specified local socket is in the process of being
    closed;  the operation was suppressed, but the local
    socket will be closed
36,  Either hardware at the foreign site is inoperative, or the
    NCP's counterpart at the foreign site does not exist or
    has failed
44,  By operator command, all Network operations were
    terminated;  the socket will be closed
60,  An NCP control transmission error occured;  the operation
    was aborted
64,  A transmission error occured;  the operation was aborted,
    but the socket will be closed
252,  The specified time limit was exceeded;  the operation was
    initiated but not completed

(3) SEND πŸ’Œ

SEND is where the data actually goes out to the foreign socket πŸš€ The subprogram sits and waits until the foreign socket has received the data, or until the NCP has queued it locally. Either way, it's giving reliable vibes.

The calling sequence is:

CALL @WRITE(cmpcd, bfr,len,time[,offset]);

where cmpcd is the completion code variable tied to the local socket. bfr is the data being sent, and it has to be a singly dimensioned array that's either DECIMAL or BINARY, FIXED or FLOAT πŸ“¦ len is the number of bits to send. If len is non-positive, no operation happens at all. len has the attribute BINARY FIXED(31,0). time is how long the subprogram waits for the operation to finish. offset is the bit offset from the first bit of bfr where transmission starts, and it has the attribute BINARY FIXED(31,0). If you don't specify it, offset defaults to zero.

These are the completion codes for SEND:

0,  The operation was successful, and the data has been sent
4,  The specified local socket is not a SEND socket;  the
    operation was suppressed
8,  The specified completion code variable is not assigned to
    a socket;  the operation was suppressed
12,  A previous SEND operation is in progress;  the operation
    was suppressed
16,  The connection is not fully open;  the operation was
    suppressed
20,  The foreign socket terminated the connection before

    completion of the SEND operation;  not all data was
    transmitted
36,  Either hardware at the foreign site is inoperative, or the
    NCP's counterpart at the foreign site does not exist or
    has failed
44,  By operator command, all Network operations were
    terminated;  the socket will be closed
52,  One or more interrupts were received from the foreign
    socket;  the operation was suppressed
56,  An addressing exception was encountered with respect to
    the data buffer;  the operation was suppressed
60,  An NCP control transmission error occured;  the operation
    was suppressed
64,  A transmission error occured;  the operation was aborted,
    and the socket will be closed
252,  The specified time limit was exceeded;  the operation was
    initiated but not completed

(4) RECEIVE πŸ“₯

RECEIVE is the mirror image of SEND πŸͺž It pulls data in from the foreign socket, and the subprogram waits until the reception is complete. Main character energy.

The calling sequence is:

CALL @READ(cmpcd,bfr,len,time[,offset]);

where cmpcd is the completion code variable tied to the local socket. bfr is the variable the data gets placed into, and it has to be a singly dimensioned array, DECIMAL or BINARY, FIXED or FLOAT. len is the number of bits to receive. If len is non-positive, no operation happens. len has the attribute BINARY FIXED(31,0). time is how long the subprogram waits for the operation to complete. offset is the bit offset from the first bit of bfr where the first bit of data gets placed, and it has the attribute BINARY FIXED(31,0). If you don't specify it, offset defaults to zero.

These are the completion codes for RECEIVE:

0,  The operation was successful and the data has been
    received

4,  The specified local socket is not a receive socket;  the
    operation was suppressed
8,  The specified completion code variable is not assigned to
    a socket;  the operation was suppressed
12,  A previous RECEIVE operation is in progress;  the
    operation was suppressed
16,  The connection is not fully open;  the operation was
    suppressed
20,  The foreign socket terminated the connection before
    completion of the RECEIVE operation;  data is
    unpredictable
36,  Either hardware at the foreign site is inoperative, or the
    NCP's counterpart at the foreign site does not exist or
    has failed
44,  By operator command, all Network operations were
    terminated;  the socket will be closed
24,  An addressing or protection exception was encountered with
    respect to the data buffer;  the operation was suppressed
52,  One or more interrupts were received from the foreign
    socket;  the operation was suppressed
60,  An NCP control transmission error occured;  the operation
    was aborted, and the socket will be closed
252,  The specified time limit was exceeded;  the operation was
    initiated but not completed

(5) CHECK πŸ”

CHECK is the "hey, what's the vibe on this socket?" call πŸ‘€ It returns the status of the specified local socket. There's no completion code variable for this one, because it always succeeds and the socket is identified by its socket number. It's valid at any time and always finishes immediately, so it's basically the most chill operation ever πŸ§˜β€β™€οΈ

The calling sequence is:

CALL @CHECK(lclsck,stat,mnem,fgnsck,deficit);

where lclsck is the socket identifier of the local socket. stat is a code for the status, with the attribute BINARY FIXED(31,0). mnem is a mnemonic for the status, with the attribute CHARACTER, of any fixed length greater than or equal to eight. If mnem is longer than eight bytes, it gets padded to the right with blanks. fgnsck is the socket identifier of the foreign socket, or zero. deficit is the send/receive deficit in bits, or zero, with the attributes BINARY FIXED(31,0).

Only lclsck is something the programmer needs to define. Everything else is output from the subprogram πŸ’–

Here are the status codes, their mnemonics, and what they mean:

'STAT'  'MNEM'        MEANING
 ----    ----
   0    OPEN       A connection is fully established.  No
                   SEND/RECEIVE operation is in progress.
                   'fgnsck' is the socket identifier of the
                   connected socket.  'deficit' is the number
                   of bits queued locally at the socket by the
                   NCP and available to satisfy a future
                   RECEIVE operation, or awaiting output as
                   the result of a previous SEND operation.

   1    LISTEN     A LISTEN has been issued.

   2    CONNECT    A CONNECT has been issued.  'fgnsck' is the
                   socket identifier of the foreign socket.

   3    DECISION   A LISTEN has been completed.  'fgnsck' is
                   the socket identifier of the calling
                   socket.

   4    CALL(S)    One or more calls have been received for
                   the local socket.  No LISTEN or CONNECT has
                   been issued.

   5    I/O        A connection is fully established.  A
                   SEND/RECEIVE operation is in progress.
                   'fgnsck' is the socket identifier of the
                   connected socket.  'deficit' is the number
                   of bits yet to be sent or received.

   6    CLOSED     The socket is in the closed state.

   7    <--DRAIN   The foreign socket is attempting to close
                   the connection.  The NCP has data yet to be
                   read by the local socket.  'fgnsck' is the
                   socket identifier of the connected socket.
                   'deficit' is the number of bits yet to be
                   received.

   8    DRAINED    The foreign socket is attempting to close
                   the connection.  The NCP is awaiting
                   arrival at the foreign site of data
                   currently in transit.  'fgnsck' is the
                   socket identifier of the connected socket.

   9    CLOSING    The local socket has issued a CLOSE.  The
                   NCP is in the process of returning the
                   local socket to the closed state.  'fgnsck'
                   is the socket identifier of the connected
                   socket.

  10    DRAIN-->   The local socket has issued a CLOSE.  The
                   NCP is completing the last SEND operation
                   before returning the local socket to the
                   closed state.  'fgnsck' is the socket
                   identifier of the connected socket.
                   'deficit' is the number of bits the NCP has
                   yet to transmit.

6. IDENTIFY ✨

okay so IDENTIFY is how you tag a local socket with its completion code variable πŸŽ€ It's valid at any time and always finishes immediately. It always succeeds, so there are no completion codes for it, and the contents of the completion code variable don't change πŸ’…

The calling sequence is:

CALL @ID(cmpcd,lclsck);

where

  • cmpcd is the completion code variable to be associated with the local socket
  • lclsck is set to the socket identifier of the local socket if the completion code variable is associated with a socket, or to zero otherwise.

7. SIGNAL πŸ¦‹

bestie, SIGNAL sends a signal to the foreign process πŸ’Œ What the signal means is totally up to the user. The effect is that the next time the foreign socket tries to start a RECEIVE or SEND, that operation gets suppressed and comes back with a completion code saying a signal was received 😭 The subprogram waits until the signal has actually been sent to the foreign NCP. This operation only works when the socket is fully open.

The calling sequence is:

CALL @ID(cmpcd,time);

where

  • cmpcd is the completion code variable associated with the local socket.
  • time is the length of time the subprogram is to wait for completion of the operation.

These are the completion codes this operation can return:

0,  The operation was successful, and the signal has been sent
4,  The specified completion code variable is not assigned to
    a socket;  the operation was suppressed
8,  The connection is not fully open; the operation was
    suppressed

Okay, now the On-Line System Network operators πŸ–₯️✨ Certain Network subprograms are meant for these operators, though they aren't limited to them. Lowkey the most important thing to know is the data format: every chunk of data travels in a message made of three fields, in this order: op code, length, and text πŸ“ The op code is one byte and tells you how to read the text field. The length field is two bytes and gives the length of the text field in bits. The text field holds the actual data. (The op code and length fields together are called a header πŸŽ€)

These are the op codes that are defined right now:

  op code        meaning

     0     The op code is a NOP.  No text field exists, and the
           contents of the length field are unpredictable.  (This op
           code is used mainly as a delimiter.)

     1     The text field contains EBCDIC characters, one character
           per byte.  The On-Line System Network operators consider
           the characters as intended for display as soon as the
           text field has been received.

     2     The text contains codes for keypushes, one byte per key.
           The On-Line operators consider the text as intended for
           execution as soon as the text field has been received.

     3     The same as for an op code of 2, except that the On-Line
           operators consider that the execution of the keys will be
           delayed until all data for that receive operation has
           been received.

The standard format for data sent or received by the On-Line System operators is a string of messages, and the last one is marked by a header with a NOP op code. That's called a trailer 🧚 These are just the defaults, though. Any of them may be overridden by appropriate programming. (Yes, I said "may" like a lawyer, but it's just the normal word here πŸ™ˆ)

The next parts are the subprograms meant for use with the On-Line System operators πŸ’…


8. WRITE TO ON-LINE CONSOLE πŸ“

This subprogram sends data from the specified local socket. The data is assumed to be characters represented by their EBCDIC codes πŸ”₯ The characters go out in a standard message with a header in front, and optionally a trailer after. The subprogram waits until the foreign socket has received the data, or until the NCP has queued it locally. This operation is only valid when the local socket is a send socket and is fully open.

The calling sequence is:

CALL @WTOLC(cmpcd,bfr,len,level,across,down,time);

where

  • cmpcd is the completion code variable associated with the local socket.
  • bfr is the character string to be sent. It must have the attribute STRING, either CHARACTER or BIT, of any length, fixed or varying.
  • len, in absolute value, is the number of characters to be sent. If len is positive or zero, the end of the data is marked by a trailer. If len is negative, no trailer is sent. len has the attributes BINARY FIXED(31,0).
  • level sets the mode of typing. The absolute value of level, if it's non-zero, is the shift level to type on, and it must be less than or equal to nine. If it's greater than nine, one is used. If level is positive, across and down are relative to the current typing location. If level is negative, the carriage is moved to the upper left-hand corner before typing begins, which makes across and down absolute coordinates. If level is zero, the typing is in case one characters, and a carriage return comes before the positioning for across and down. If the characters to be displayed are case one characters, the header sent will have an op code that says the characters should be displayed as soon as they're received. Otherwise, the op code will say the buttons should be executed as soon as they're received. level has the attributes BINARY FIXED(31,0).
  • across is the number of spaces to move horizontally across the display tube before typing begins. across can be any value, positive, negative, or zero, and has the attributes BINARY FIXED(31,0).
  • down is the number of lines to move vertically down the display tube before typing begins. down can be any value, positive, negative, or zero, and has the attributes BINARY FIXED(31,0).
  • time is the length of time the subprogram is to wait for completion of the operation.

The completion codes for this operation are the same as for SEND.


9. READ FROM ON-LINE CONSOLE πŸ“–

This subprogram receives data from the foreign socket, in one or more standard messages. The data is assumed to be characters represented by their EBCDIC codes 🌸 The subprogram waits for the data to arrive, optionally followed by a trailer, at the local socket. This operation is only valid when the local socket is a receive socket and is fully open.

The calling sequence is:

CALL @RFOLC(cmpcd,bfr,len,time);

where

  • cmpcd is the completion code variable associated with the local socket.
  • bfr is the variable the data gets placed into. It has the attribute CHARACTER, of any fixed length. If bfr is longer than the amount of data received, it gets padded on the right with blanks.
  • len, in absolute value, is the maximum number of characters to put in bfr. If the length fields of the headers received add up to more data than len, the extra data is still received, but it isn't placed into bfr and the program can't access it. If len is positive or zero, data is received until a trailer shows up. If len is negative, a single message is received, not counting the trailer. len has the attributes BINARY FIXED(31,0).
  • time is the length of time the subprogram is to wait for completion of the operation.

The completion codes for this operation are the same as for RECEIVE.


10. WRITE TO ON-LINE CONSOLE WITH REPLY πŸ’¬

This one's a combo meal 🍟 It does the jobs of 'WRITE TO ON-LINE CONSOLE' and 'READ FROM ON-LINE CONSOLE' together. First, it sends a string of data from the specified send socket to the foreign socket, then waits for that data to be received by the foreign socket (or queued locally by the NCP). After that, it waits for a reply directed at the specified receive socket. This operation is only valid when the sockets have the correct gender and both are fully open πŸ‘‘

The calling sequence is:

CALL @WTOLCR(cmpcd, bfr, len, level, across, down, time,
             cmpcd2, bfr2, len2);

where

  • cmpcd is the completion code variable associated with the local send socket.
  • bfr is as in 'WRITE TO ON-LINE CONSOLE'.
  • len is as in 'WRITE TO ON-LINE CONSOLE'.
  • level is as in 'WRITE TO ON-LINE CONSOLE'.
  • across is as in 'WRITE TO ON-LINE CONSOLE'.
  • down is as in 'WRITE TO ON-LINE CONSOLE'.
  • time is the length of time the subprogram is to wait for completion, separately, of the transmission and the reception of data.
  • cmpcd2 is the completion code variable associated with the local receive socket.
  • bfr2 is as bfr in 'READ FROM ON-LINE CONSOLE'.
  • len2 is as len in 'READ FROM ON-LINE CONSOLE'.

The completion codes for the send socket are the same as for the SEND operation, and the completion codes for the receive socket are the same as for the RECEIVE operation πŸ’–

(11) ERASE ✨

okay bestie, ERASE is giving "wipe the whole screen" energy πŸ§ΉπŸ’– This subprogram sends out the data for an On-Line System command that erases the display tube, going out from whatever local socket you point it at 🫢 The whole thing travels in one standard message. That message has an op code telling the other side to display characters as they arrive, plus an optional trailer at the end πŸŽ€ Then the subprogram just waits until the foreign socket has received the data, or the NCP has queued it locally 😭

ngl this one is picky. ERASE is only valid when the local socket is a send socket AND it's fully open πŸ’€

Here's how you call it:

CALL @ERASE(cmpcd,delay1,delay2,time);

And here's what each piece does:

  • cmpcd is the completion code variable linked to the local socket πŸ”₯
  • delay1 is, in absolute value, how long (in tenths of a second) the subprogram hangs out in the WAIT state before sending the erase ⏳ If delay1 is positive or zero, a trailer gets sent after the erase. If it's negative, no trailer gets sent πŸ™…β€β™€οΈ delay1 has the attributes BINARY FIXED(31,0), periodt.
  • delay2 is how long (also in tenths of a second) the subprogram pauses after sending the erase and before handing control back to the calling program 🌸 It has the attributes BINARY FIXED(31,0).
  • time is how long the subprogram is going to wait for the operation to finish 🧚

The completion codes for ERASE are the same as the ones for SEND, so if you already know SEND, you're already set πŸ‘‘

          [ This RFC was put into machine readable form for entry ]
           [ into the online RFC archives by Rune Skaarsmoen 6/97 ]
πŸ“¦ where this page comes from