This is the file containing the INFO-ized documentation describing the
formal specs for PCNET protocol. It largely replaces oldstyle
non-treeified documents, at least for the time being.

[This info-frame: Definition of the word "protocol", what PCNET
 protocols are designed to accomplish, overview of our layered
 protocol, and index of info about individual layers of PCNET protocol]

In order for two entities to communicate, they need agreements as to
what physical medium will be used, what signals may be sent on it,
what those signals mean, and what actions an entity is required to
perform upon receipt of any particular signal.
The meaning of the word "protocol" includes all of that.

PCNET is designed primarily for reliable unattended data communication
using low-speed modems over direct-dial telephone lines. Since
only two parties are connected at one time, we can save a lot of
overhead by not requiring a node address in every packet. Since the
link is direct, transmitted data reaches the other end virtually
instantly, we don't have to worry about having many packets already
transmitted but not yet arrived at the other end, so we can use a
simple acknowledgement method using a small outstanding-packet window.

Because the protocol is layered, with clean simple interfaces, it's
easy to patch layers of PCNET protocol with layers of other protocols,
to communicate over other media. For example, the telephone interface
could be replaced by a satellite transponder or EtherNet tap, node
addresses could be added to packets to handle multi-tap connections,
and the outstanding-packet window could be enlarged to handle the long
turnaround delay inherent in synchronous satellite communications.

But at the present time we're concentrating on those layers adapted to
low-speed direct-dial communications between small computers. All the
protocol definitions below are optimized for this environment. The
alternative layers that might be used for alternative environments
aren't described here.

    ---- FIRST SOME INRODUCTORY SUMMARIES OF THE OVERALL PROTOCOL ----

    ---- NOW THE MAJOR PARTS OF THE PROTOCOL, TREATED SEPARATELY ----

    (Everything after here sits above microlayer 7)

    ---- NOW SOME OTHER ITEMS PERHAPS NOT PROPERLY INCLUDED HERE ----

    Technically this next item has nothing to do with formal protocol
    (and in fact I might move this section elsewhere in the info tree),
    and we have no business imposing on implementors how to do this,
    but if we don't say something here, at least throw up a straw man for
    programmers to either emulate or replace, the world-net based on PCNET
    protocol may never come to be...

    ---- MISC RELATED INFO ----

Date: 4 May 1983 06:22 EDT
From: Robert Elton Maas <REM @ MIT-MC>
Subject: Recent progress, capsule summary of PCNET
To: INFO-PCNET @ MIT-MC

PCNET protocol/software has two major interfaces:
 - the lower interface, whereby PCNET protocol/software talks to the
    hardware (modem&uart) drivers,
 - the upper interface, whereby application programs talk to the PCNET
    packet protocol/software.

When connecting, disconnecting, or changing modes in a dangerous way
that requires dropping out of packet protocol, only the lower
interface exists. The hello or bye or dangerous-mode-change
protocol/software talks through the lower interface to the hardware drivers.

At all other times when online, both interfaces exist. The application
program talks through the upper interface to the PCNET packet
protocol/software, which in turn talks through the lower interface to
the hardware drivers.

PCNET packet protocol/software provides error- and flow-control,
including multiple logical streams. Application programs provide
services desired by the user, such as electronic mail, file transfer,
loopback testing, remote virtual-terminal login, or whatever.

Most of these important files exist only on SU-AI backup tapes.
Please send REM any requests for files you urgently need.
They'll be restored from tape and mailed here and incorporated into
 this info tree in the appropriate spot.

    ?...
81106A	PRO		Upper levels of non-watered PCNET protocol
81207A	WRU		PCNET flow control (TVR wanted it)

	Initially only the NODE-CONTROL program is activated.
NODE-CONTROL messages are sent to it asking for ECHO or MAIL1 to
be activated. Logical channels are allocated for the program on
one node to talk to the corresponding program on the other node.
Communication then shifts to these logical channels where the
two programs conduct their business. When they are done, communication
reverts to the NODE-CONTROL program. When all activity is finished
for this particular telephone connection, the NODE-CONTROL programs
agree to terminate the call.

ASKING FOR PROGRAMS.
	To request activation of a program and allocating streams to it,
a NODE-CONTROL message of Please-Do Open-Streams (C0+04 = C4) is issued.
It contains a query number, used to identify requests when more than
one is outstanding, and the name of the program wanted.  The opcode,
then the query number, then the ASCII name of the process, is sent
on logical stream 0.  For example, to request the MAIL1 process:
  O-->A Stream=0 EOD:  C4 01 "MAIL1"
The other (answer) node then replies with an I-Will Open-Streams (80+04)
NODE-CONTROL message. It contains the query number from the query it
is answering, the starting stream number (always 41 in simple mode
or for the first/only application program in advanced mode), and
the number of streams (hexadecimal 3F for ECHO and 2 for MAIL1).
For example, the reply to the above request would be:
  A-->O Stream=0 EOD:  84 01 41 02
To refuse the request, perhaps because the program hasn't been installed,
send a I-Won't Open-Streams NODE-CONTROL message. It contains the opcode,
the query number from the request, followed optionally by an explanation
of the problem, which may be put in the log or printed on the operator's
console or just ignored. For example, to refuse the above request,
the following might be sent:
  A-->O Stream=0 EOD:  04 01 "Has bug, maybe up tomorrow"
or just:
  A-->O Stream=0 EOD:  04 01

<<Addenda on releasing streams when done, and on exiting>>
At the time an application program is invoked, streams are opened on
both nodes. When an application program is all done (presumably the
program on both nodes arrives at this point essentially simultaneously
by means of some explicit cue sent from one to the other, such as a
BYE opcode in the private application protocol or an End-of-Data bit
set on some critical stream), it exits. At that time the streams that
were allocated to it are deallocated, returned to the pool of
available streams. Although both nodes must now stop using these
streams, only the node that allocated them must update its table of
free streams that might be reallocated later. -- Although it's
conceivable that the appliction program itself might do this updating
of the allocation tables, this is rather dangerous. Perhaps the right
way to implement this is that each node has a table listing
application programs and how many streams they require. When a request
to invoke an application program is being processed, the node-control
program looks in this table to decide how many streams to allocate.
The node granting the request then performs the allocation and sends
the starting stream number and count of streams to the other node, and
that other node then verifies the proper number of streams have been
allocated. Alternately these tasks may be performed by a support
subroutine that is called from inside each application program. Later
when the application programs exit, that is after a RETURN is executed
and control returns to the node-control process, the node-control
process then deallocates those streams. Alternately deallocation could
be performed by service subroutines called from inside the two
application programs just before RETURNing.

Date:     15 March 1983 1439-mst
From:     Paul Schauble    <"Schauble@M.PCO.LISD.HIS"@udel-relay>

   ISO Model            PCNet
------------------------------------------------------------------
  Application        Application      Basically the same

  Presentation       None             Incorporated into application

  Session            None             Services not needed

  Transport          Directing layer  PREAD/PWRITE

  Network            None             Assumed point-to-point

  Link               Sequencing

   "                 Validating

   "                 Translating&framing

   "                 Half duplex

  Physical           Physical         PCNet assumes Bell 103, which
                                      is one of several ISO standards.

The result of this is that the PCNet protocols could be used in an
ISO structured system, and that ISO protocols could be used in PCNet,
with only minor modifications.

When an application program (or the node-control "program") wants to
send data across to the corresponding application program on the other
node, it uses PCNET-WRITE which is often abbreviated to PWRITE. The
program at the other end uses PCNET-READ, abbreviated PREAD, to see if
there is any data that has arrived, and to fetch that data if it has.
If the application program is sure there should be some data arriving,
it can use PCNET-READ-WITH-WAIT, abbreviated PREADW, to keep calling
PREAD over and over until some data arrives or the communication link
breaks down preventing any further arrival of data.

PWRITE	PRO		PCNET: proposal for read/write interface under servers

[Need to extract from the protocol document specs for PREAD.]

[Need to extract from the protocol document specs for PWRITE.]

[Need to extract from the protocol document specs for PREADW.]

 [See to do, edit, below]

[This info-frame: Introduction to PCNET protocols describing what the
hardware provides and what the application program really needs,
listing of individual needs and layers of protocol that satisfy them.]

Suppose we have two computers on opposite ends of a telephone line,
with modems to convert between binary and analog signals, a UART to
convert between octets of binary data and carefully-timed sequences of
bits in real time, and some very primitive software to perform
device-dependent things through the modem&UART such as establishing a
connection, sending bytes of data, and collecting bytes of data that
have arrived from the other computer. Thus either of the two computers
can send an octet of data to the other which will be received it if no
phone line noise interefered with the analog signals used to carry the
data.

Suppose we an application program on one of the two machines that
wants to communicate to an application program on the other. It wants
to be able to open several data channels (streams) to the other so it
can send commands on one channel and data on another, or perhaps
several kinds of data on different channels. It wants the receiving
program to be able to distinguish data on the different channels, and
it doesn't want the data to be damaged (deleted, duplicated, changed,
rearranged, put on the wrong stream) en route. The receiving program
doesn't want to hassle with bad data or temporary errors. It wants to
receive exactly the correct data on exactly the correct stream,
without being bothered by temporary error conditions that can be
corrected, but it does want to be told if the communication link has
completely broken down preventing further data transfer.

The purpose of the lower&middle layers of PCNET protocol is to fill
the gap between the needs of the application program and the services
offered by the low-level software that drives the telephone-interface
hardware, i.e. to insulate the application program from the
error-prone telephone line and to provide the multiple streams and
other facilities not available on a bare modem&UART link.  Below are
the various problems that exist in two application programs trying to
communicate with each other, and the solutions provided by various
micro-layers of PCNET protocol. (There are two major layers, the Link
layer, also known as the packet layer, and the Directing layer, also
known as the stream-multiplexing layer. But the Link layer is
subdivided into about six smaller layers called "micro-layers".)

	microlayers are stacked on top of each other when putting them
	all together to make the full PCNET protocol, where 0
	represents the device-dependent code for modem&UART, 8
	represents the application program, and 1 thru 7 represents
	the lower&middle layers to be inserted between them.)

Whatever the difference is between services provided by the 0-1
interface and services needed by the 7-8 interface, represent
protocol that must supplied in addition to the 0-1 interface to
satisfy the needs of the 7-8 interface, i.e. layers of protocol that
sit on top of the 0-1 interface before the 7-8 interface can be created.
The microlayers introduced below provide these additional services.
Thus the 0-1 interface (including the hardware and device-dependent
software implied by it), plus the additional layers introduced below,
provide all the functionality required by the 7-8 interface, that is
by the application program that uses the 7-8 interface to obtain its
communication services. Both of the above sections should be studied
before the problems listed below will make much sense.

    motivation for each micro-layer, rearranged into teaching sequence...

[To do, edit: Stuff about app'l program needing multiple streams and
EOD bit should be moved into the 7-8 interface, while stuff about need
to put number in directing byte to accomplish this keep in 7str/7eod]

Summary, micro-layers listed here in normal sequence as data feeds
through each micro-layer to the next:

	Application program sits at the top, transmitting data
	downward, and receiving data that arrived at the bottom and
	has now made its way to the top.

	Application-level command to other program "PLEASE DO ACCEPT MAIL"
	Encoded as [8-bit opcode and binary arguments], on some stream.
	Sent down via a call to PWRITE.   Received on other node via PREAD
7		Directing layer
	Block prefixed by header octet telling stream number and EOD bit.
6		Sequencing layer
	Structure passed between these layers includes sequence
	number, acknowledgement number, and the original
	[directing octet & opcode octet & args] from above.
5		Validating layer
	Sequence & acknowledgement numbers packed into one octet which
	is appended, checksum or CRC in two more appended octets.
	Now have: [dir. octet & opcode octet & args & sequence octet & cksm]
3&4		Translating layers
	All data from just above translated into Radix-41, which
	doesn't include any characters that would conflict with
	framing atsigns or turnaround characters below, or data kept
	in binary as-is except characters that would conflict with
	framing/turnaround or with quoting mechanism are quoted.
2		Packet framing layer
	Each block now has atsigns around it to reframe the UART and
	to signal the start of each block. [NB 1983.March, there is a
	possibility atsign may be changed to another character in
	Simple mode, to permit communication with Honeywell computers
	which don't pass atsign to user programs.]
1		Half-duplex turnaround handshake
	(Used only when in HDX software mode using FDX modems.)
	Nodes take turns sending one or more packets, sending trailing
	brackets, watching for lead-in atsigns from the other node
	within ten seconds sure it saw the turnaound (if not,
	retransmit turnaround and wait for atsigns again), then
	buffering up the other node's transmissions until receiving
	the trailing brackets from the other node, immediately sending
	leading atsigns to acknowledge turnaround, then processing the
	data that has been buffered and preparing the outgoing data to
	be sent as packets at the top of this loop. [NB 1983.March,
	there is a possibility brackets may be changed to other
	characters in Simple mode, to permit communication with IBM
	computers which use EBCDIC internally and don't convert brackets.]
0		Modem interface software
	UART/modem hardware sit at the bottom.
	(Well, actually the telephone line is at the VERY bottom.)

Sigurd.UDel-CC-Relay@UDel-Relay wants this when it's written.

A communication application consists of two parts, a program on the
originate node and its mate on the answer node. The two parts talk to
each other, sending and receiving blocks of data that have particular
meanings to them. For example a file-transfer program might need to
communicate the name of the remote file (the one on the machine
different from the machine on which filenames on both machines are
initially known; the local file is the one on the same machine where
both names are initially known, and that needn't be communicated to
the other machine) as well as the data of the file.

To simplify the code provided by PCNET, i.e. everything except the
application program itself, we assume each application program can
reblock its own data, that is break data into blocks small enough to
fit into PCNET packets, and at the receiving end collect the data from
PCNET packets and put them where they belong. To support applications
that want multiple logical streams, we provide that. For example, an
FTP program might send commands on one stream and data files on
another.

PCNET therefore provides two basic mechanisms: PCNET-WRITE (PWRITE) to
transmit a block of data to the the other machine along some logical
stream, analagous to WRITE or OUTPUT from a program to an operating
system; and PCNET-READ (PREAD) to check for incoming data that has arrived
from the other machine and if such data has arrived then to return the
data together with the number of the stream it arrived on, somewhat
analagous to READ or INPUT except with the ability to return
immediately if no data has yet arrived thus allowing applications that
listen for input that may or may not arrive while in the midst of
transmitting.  For programs that are expecting incoming data and can't
do anything else until it arrives, we also provide a waiting form of
PCNET-READ called PCNET-READ-AFTER-WAIT (PREADW), which merely calls
PREAD over and over until it has data.

[need to define calls to RCWBT, SDWBT etc.]

-- Why the "Directing layer", in particular multiple streams? --

Almost any application program needs more than one logical stream, for
example it needs one stream to transmit data and another to transmit
occasional commands to initiate terminate or modify the data stream.

Arpanet protocol does this in a very clumsy manner. All data in a
particular direcion travels on a single stream, but commands are
prefixed by a byte of hexadecimal FF while data isn't. If a data byte
of FF is to be transmitted, it is sent as two bytes, FF FF, which is a
command to quote a byte of FF. Thus commands must be parsed exactly
correctly in real time as data is passing by, and the slightest
parsing error causes commands to be interpreted as data or vice versa.
This is complicated by variable-length commands such as anything with
a file name in it, requiring the command structure to contain
length-of-command information as well as the actual command.

Many other protocols either don't allow commands at all when in
the midst of transmitting data, or use special kinds of packets which
somehow must be delivered to the application program by special means.

Arpanet and some other protocols use multiple streams to allow
multiplexing several application programs on a single hardware device.
PCNET has extended this concept to allow individual application
programs to have multiple streams themselves, thus solving both the
control-vs-data problem described above and the multiple-program
problem by a single mechanism. An advantage of this is that commands
don't have to be carefully parsed and don't need to have length
information contained in them, since commands can simply run to the
end of the data block (on the control stream). Unknown commands can be
ignored or explicitly rejected by the receiving machine without having
to know their internal syntax.

The PCNET directing layer provides 128 logical streams, 64 of which
are allocated by the originate node at the request of the answer node,
and 64 of which are allocated by the answer node at the request of the
originate node. Thus if the machines are in full-duplex, both talking
and listening at the same time, requests can be issued and granted in
both directions at the same time without need for synchronizing to
avoid the same stream being allocated by the different machines for
different purposes at the same time. In each group of 64, number 0 is
pre-allocated and is reserved for the Node-Control program, while the
remaining 63 are dynamically allocated to any desired application
program. Even in the most unbalanced case where only one group is
used, because one node is making all the requests and the other node
is merely granting them, there should be enough streams to allow as
many application programs as one would ever want to be running at the
same time, even if some of them use several more than the normal two
streams (control and data). Of course, if some application program
really needs a very large number of logical streams, it can always
multiplex its logical streams onto a single PCNET logical stream, for
example by reserving the first byte of each 7-8 data block for its
own logical stream number, thus effectively multiplying the number of
logical streams available by 256. But a majority of application
programs use only a small number of logical streams, and the PCNET
directing layer adequately handles these needs.

-- Why the "EOD bit" in the Directing layer? --

Given that we have multiple logical streams, it's often useful to
indicate something like an end-of-stream signal. For example, when
sending a long file, rather than declaring the length of the file at
the start and carefully keeping track of the byte count all along,
one might just start sending data and then when the end of the file is
reached send an end-of-file mark as an end-of-stream signal on the
data stream. If commands can sometimes be longer than a single data
block (even if the current implementation doesn't allow that), an
end-of-stream signal can be sent on the control stream when each
command is done, which will normally be on every block if commands
don't actually use more than block currently.

It takes only a single bit to specify whether an end-of-stream occurs
at the end of a particular bit, thus the PCNET directing layer
provides this useful feature.

Together the stream number (1 bit to specify the group, that is who
allocated the stream, and 6 bits to specify the stream number within
the group), and the end-of-stream bit (1 bit), are 8 bits. These are
packed (by the directing layer) into a single octet when transmitting
data and unpacked on receipt. An application program thus sends a
certain number of bytes of data on a particular stream with the
end-of-stream bit either 1 (end) or 0 (normal). (Elsewhere the
end-of-stream bit is called the end-of-data or EOD bit.)

-- Why the "Validating layer" and how in general it works? --

Now that we're sending data on multple streams to possibly multiple
application programs, things would really get confused if an error
occurred on the telephone line causing data to go to the wrong stream,
and it takes only a single-bit error in the stream number to do that!

Obviously we need some way to detect when an error has occurred, so
that we can reject the bad data. But bad data can take many forms:
Individual bits can be clobbered, causing a 1 to become a 0 or vice
versa. Several bits in a row can be so clobbered, with some accidently
clobbered to their correct value while others changed to the opposite
value. Due to the way UARTs handle start&stop bits, the UART can be
thrown out of corrct frame, causing bits to be shifted in a strange
way, with each byte as received to be composed of bits from two
adjacent bytes as originally transmitted. Due to problems in the
software, or due to rather long bursts of noise, entire bytes or
several bytes in a row can be totally lost with no indication of
trouble or with only a single data-overrun flag for several lost
bytes. Finally due to the strange way voice-grade telephone circuits
are sometimes switched on long distance circuits, especially via
satellites, data may possibly be rearranged.

PCNET transmits two bytes of checksum with each block of data. These
two bytes are an alternating checksum (one byte for bytes in first,
third, ... position; other for second, fourth, ...) when using
Radix-41 (see later, microlayers 3&4), and a Cyclic Redundancy Check
(CRC) when using 8-bit mode. These methods assure that the bits in the
checksum are pseudo-random, so that out of every 65536 bad blocks only
one will get through these error checks. Since there is usually only
about one error-burst each 5-10 minutes even on noisy low-quality
residential telehone circuits, this means there's an undetected error
only about every 3E5 to 6E5 minutes which is about a year of
continuous 24-hour-a-day operation. Even so, this represents a
compromise between ideal performance (less than one error in the
lifetime of the network) and overhead (only two bytes of checksum per
packet). Applications requiring a higher level of data assurance
should include additional error protection, such as a 4-byte checksum
on an entire file or an additional 2-byte CRC (using a different CRC
plynomial!!) on each data block. But for ordinary electronic mail and
file transfer our undetected errorrate should be quite sufficiently low.

-- Why the "Sequencing layer" and how in general it works? --

Now that we have detected blocks of data that got munged by telephone
line noise, and have ignored such blocks, how do we get the correct
data retramitted so we can have another chance to receive it,
hopefully correctly the second time?

PCNET solves this problem elegantly by including in each data block
(packet) a sequence number for that block and also a "want" number
that says what block number in the reverse direction hasn't yet been
received even though all earlier blocks have been received. "Received"
in this context means "received correctly", since anything that wasn't
correct has been rejected by microlayer 5 already. Each node maintains
a want number, telling which block it wants next. If it receives that
block, the number is bumped up to the next value. If it receives an
earlier block, it is rejected, since it's a duplicate of a block
already received. If it receives a later block, that block may either
be saved for looking at later (if there is enough buffer space) or
simply ignored (if there isn't enough buffer space to keep it around).
Each time a block is sent out (in the reverse direction from blocks this
"want" number refers to), the current value of the want number is
stuffed into it. If that block reaches the other node, that node knows
we've received all blocks preceding the one "want"ed. If after a
reasonable time our want number as seen by the other node hasn't moved
past some particular value, the other node realizes that block we are
still wanting must have gotten lost somewhere, so it sends us that
block again.

To avoid needing more than one byte for all this sequence and want
numbering, we use three bits for each. The mathematics is that if we
never transmit more then the currently wanted block plus three
additional blocks after it, there will never be confusion as to
whether we're talking about a certain block or the block with the same
3-bit number that is 8 earlier or 8 later in the overall sequence.

For simple nodes that don't have enough buffer space to receive blocks
out of sequence and put them back in to order, the window is 1, which
means only the one block with the "want"ed number is ever accepted,
and it must be sent over and over until it gets through, before any
later block will be accepted. Since blocks with any later or earlier
number are rejected, and the want number is bumped up by one each time
a block is received, it's impossible for blocks to get out of sequence
as they are passed up to the directing layer above, and it's
impossible for any block to be duplicated or skipped over. The worst
that can happen is that no data at all is passed up for a while if the
same block keeps getting munged each time it is retransmitted, but
finally it gets thru correctly and the data is passed up to the
directing layer as if nothing had gone wrong in the first place; or
else that after many retries without success the sequencing layer
finally gives up and declares the telephone line too noisy to be used
at all, and aborts, forcing the application program to abort whatever
it was trying to do. Thus either correct data in correct sequence is
passed, with possible delays due to retransmissions (which are
invisible to higher layers except for their realtime delay, which most
application programs won't notice at all), or a clean abort of the
whole connection is signaled.

There is one minor hitch. If no data is being sent in one direction,
for example in the midst of a long file-transfer, how do we send the
want number in the reverse direction. (Remember that normally a packet
contains one byte of sequence&want numbers, two bytes of checksum, one
byte with stream number and EOD bit, and some bytes of data being sent
on that stream.) We could of course pick a stream number at random and
send zero bytes of data on it, but that might confuse some
applications, and it's rather strange to pick on some random
application when the problem is down in the lower layers that should
be invisible to it. PCNET solves the problem this way: It sends an
empty packet, that is one that doesn't have the directing byte at all,
even though it still has the sequence&want number byte and the two
bytes of checksum. The sequencing layer filters out these empty
packets on receipt, processing the sequence and want number as usual,
but not passing anything up to the directing layer. These empty
packets can therefore be inserted by the transmit side of the
sequencing layer any time it needs to acknowledge incoming data but
doesn't have any outgoing data to send, without messing up the rest of
the protocol. Lower layers (up through validating) treat these the
same as ordinary data packets, while higher layers (directing and
application) never see them at all.

-- Why the "packet-framing layer", and how it's accomplished? --

The validation layer assumes we can recognize the start and end of
incoming blocks (packets) of data. But all that is provided by the 0-1
interface for receiving data is the ability to receive individual
bytes. How do we know the start and end of each checksummed&numbered
block of data?

We could put a length field in each packet, somewhere near the start,
so then we can be counting bytes until we reach the end. But if phone
line noise happens to mung that length field we are lost. The checksum
will fail, so we can reject this packet, but how do we know where the
next packet starts?

A better (more robust) way is to put special bytes of data between
packets to separate them. PCNET has chosen atsign with mark parity,
because it tends to re-frame the UART, thus assuring the subsequent
block will be seen even if the preceding was lost due to phone line
noise knocking the UART out of frame, because it's a printing
character, and because it's not a lowercase character that might be
converted to upper case. To assure that not only will the subsequent
block of data be seen in correct UART frame but also that the atsign
itself will be seen, we transmit two of them together, the first to
reframe the UART and the second to be actually seen. If both are seen,
the normal case in the absense of an error, the software simply
rejects the zero-length "block" between the two atsigns, since every
actual packet (even "empty" packets inserted by the sequencing layer)
contains at least three bytes, the two bytes of checksum and the one
byte containing the sequence and want numbers.

-- Why handle Half-Duplex by software? How to do it? --

Most modems available on small computers, as well as the normal dialup
modems on large machines (except on IBM 360/370/3033 systems) are
inherently full-duplex, that is they can both receive and transmit at
the same time. Accordingly they have no means built-in for allowing
the two machines to take turns talking.

When a human is using a text editor or other program, it's generally
useful to have full-duplex. That way the human doesn't have to wait
after each command for the remote host to finish executing it and be
ready for the next command, with the keyboard locked (logically if not
physically) in the meantime.  (Have you ever broken your fingernails
or painfully stubbed your fingertips on an IBM 2741 terminal, because
you made the mistake of trying to press a key too early while the
keyboard was still locked, with the keys as hard as rocks? Or have you
ever tried to use an IBM system from a normal non-locking keyboard,
and had to wait a second or two after every prompt just to make sure
it was really your turn to type, lest the machine reject your whole
line of input *AFTER* you had spent a half minute carefully typing it,
because at the *START* of the line it wasn't yet your turn yet, and as
soon as it WAS your turn to talk the IBM system recognized that you
had tried to type ahead and the controller had lost some of your
input, but the IBM machine couldn't tell you until you were done with
your line because it wasn't IBM's turn to talk until then???
Half-duplex is totally in-humane!!)

Given that we need full-duplex modems to achieve a decent humane
interface to the remote computer during editing and other interactive
sessions, and given that we can't afford to have two different sets of
modems, full-duplex for direct interactive use and half-duplex for
PCNET connections, we are stuck with using full-duplex modems for
PCNET use. But writing software to receive and transmit packets at the
same time is much harder than writing software to take turns receiving
and transmitting. In fact, in some languages it's impossible to handle
interrupts or in any other way service the receive side of the UART
fast enough to avoid losing most of the data, except by running in
half-duplex mode where when receiving we're sitting in a wait-for-data
loop most of the time and not trying to do anything else like
transmit. Thus we need to provide a half-duplex mode of communication
even though our modems are designed for full duplex.

We do this by sending some data that means "I'm done sending, your
turn to send, I'll be listening now" which can be recognized at the
other end. That's what microlayer 1 of protocol does. We send brackets
to say we're done, and the other node sends atsigns back to say it got
the brackets ok and will be sending packets now.

Sigurd.UDel-CC-Relay@UDel-Relay wants this when written.

-- Why use Radix-41 or 8-bit transparency instead of just packet as-is? --

Now that we can turn the line back and forth so we don't have to write
code that listens for incoming data while transmitting, and we can
recognize packets, throw away the bad ones, put the good ones in
correct sequence, and pass the data to the correct application program
along the correct logical stream, we're almost done. We have one
problem: What if some data we want to transmit, or some byte generated
by the directing or validating layer, happens to be an atsign or
bracket that might be mis-interpreted as the end of a packet or as
half-duplex turnaround (I'm done transmitting)? We need some way to
represent atsigns and brackets in some way that doesn't involve
actually transmitting an atsign or bracket on the UART. Furthermore
there are many systems that can't handle all eight bits of data (in
particular they throw away the parity bit), or which can't even handle
all 128 possible 7-bit characters as data (for example they interpret
certain control characters in magic ways, ignore NUL and RUBOUT,
convert all text to upper case, etc.). We need a way to represent more
than half the 8-bit characters in some way that is restricted to the
very few remaining characters that are handled correctly.

When BOTH machines, originate and answer, can handle 8-bit data
correctly, and the only problem is atsigns and brackets, we offer
8-bit mode. Most octets are transmitted as-is. One value is reserved
as a quote signal. The quote signal is then used to quote itself as
well as atsigns and brackets.

When EITHER machine can't handle 8-bit data, we offer Radix-41 mode,
whereby we use an extremely restricted set of characters (41 out of
the possible 256) in triples to represent pairs of 8-bit values
(41*41*41 is slightly larger than 65536). Radix-41 mode slightly
complicates the validating layer since when transmitting an odd-length
block an extra byte of zero must be appended and when receiving a
block the validating layer must decide whether to throw away the last
octet or not. The rule is: if the last octet received isn't zero, or
if the block checksumms correctly as-is without dropping the zero
octet, it isn't thrown away; if the last octet IS zero and the block
checksumms incorrectly with it but correctly with it dropped, then it
is dropped. This is slightly ugly, but it's the best solution we could
come up with.

<this section not yet written; contact fylstra.tsca@sri-unix for ideas>

(tim.uci@Rand-Relay wants this when ready for release)

After establishing hardware (modem&UART) connection and logging in and
selecting the generic mode as PCNET, the specific PCNET sub-mode must be
negotiated before any packets can be exchanged. Possible modes are:
  Simple at same speed (110 or 300 or 1200);
  Enhanced at same speed (300 or 1200);
  Enhanced at faster speed (was 300, will be 600 baud).
Details of this negotiation is in a separate file not online presently.
Update 1983.3.19, the file name is 82120A.PRO, and has been requested
at SU-AI for restoration from magtape. Awaiting arrival of file.

79C07A	RFC		PCNET -- How to change modes at bottom level
82120A	PRO		PCNET: Proposal for HELLO (from 80A01A.PRO,81202A.PRO)
CRIPPL	ICP		PCNET: Initial Connection Protocol for crippled mode
RCVMSG	PRO		PCNET, propose dialout to deliver msgs to customers

	PCNET LAYER OVERVIEW To support mix&match of layers

Mixing and matching parts of various protocols has been suggested.
Before this can be done intelligently, we must understand just what
services are provided by each layer of protocol and what the
interfaces are at the top and bottom of each layer. I haven't yet seen
a clear description of Internet layers in this way (although from
reading their documents one can sort of piece together some of this,
and the Internet protocol is surely layered cleanly), nor the other
big protocols (X.25, SDLC, HDLC, DIALNET, IFIP WG6.5, Arpanet, TYMNET,
Telenet) although they too are probably cleanly layered, and maybe
somewhere there's an overview of layers like this. In the case of the
several micro protocols proposed here (MMDF, MODEM2, CIS/MNET, Kermit)
I haven't seen this kind of overview either, but I doubt it could be
done because I don't think these protocols aren't as cleanly layered,
but I might be mistaken. Advocates of those protocols, take this as a
challange!

Anyway, here's my attempt at describing PCNET major layers in this way:

PCNET is divided into two major parts, the part that makes it possible
for applications programs to talk to each other using multiple
streams (called here the "support protocol"), and those applications
programs themselves. The support protocol is further divided into
three major layers:
 (1) The communications-channel drivers and interfaces.
    This package provides a way to open a channel, which for the
    telephone means dialing or answering a call and initializing the
    modem; a way to send/receive data over the modem&phone, which
    includes four essential functions (see if receive-data available,
    read a byte, see if transmit-buffer free, send a byte); and a way
    to terminate a channel, which for the telephone means to hang up.
 (2) The character-mapping and error-control methods.
    This includes mapping between a subset of ASCII and full 8-bit
    binary data to allow communication over user-dialup ports into
    timesharing systems, handling logical half-duplex turnarounds so
    that the higher levels of protocol can effectively have use of
    virtual full-duplex, ignoring packets that have been damaged and
    thus contain uncertain data, acknowledging packets that have been
    received correctly, retransmitting packets that haven't been
    acknowledged, and putting data from packets back in sequence after
    an out-of-sequence retransmission has occurred.
 (3) Multiplexing multiple logical streams on a single lower-level stream.
    Up to 63 two-way streams may be allocated by the local node and up
    to 63 may be allocated by the remote node.

Level (1) lower interface is hardware dependent.

Level (1) upper interface consists of 8-bit bytes of data in
half-duplex or full-duplex mode, with possible restrictions on the
characterset allowed, and with uncertain error rate depending on
hardware used.

Level (2) lower interface matches level (1) upper interface except
that in Radix-41 mode it uses only the following characters:
Letters (upper case only), numerals, specials ";:<=>@", and <cr>.

Level (2) upper interface consists of alternately accepting (to
transmit) and returning (after receiving) blocks of 8-bit bytes.
Blocks may be of varying lenths, including empty, thus effectively
emulating full-duplex (asynchronous send/receive) half-duplex (take
turns send/receive) and simplex (long monolog) modes of communication
at various times during a single connection even when the level (2)
lower interface is half-duplex only. This data has an error rate that
is less than 1/(2^16) of the error rate at the level (2) lower interface.
Thus with a typical noisy-phone-line error rate of one per minute or
so, the undetected error rate in level 2, which becomes the total
error rate at the upper interface, is less than one every three
months, adequate for most personal-computer applications, and masked
by more frequent errors on the microcomputers themselves such as
diskette read errors.

Level (3) lower interface requires a virtually error-free 8-bit-binary
channel, such as that provided by level (2) upper or by a short direct
connection between two computers. It also requires alternating
send/receive of varying length blocks (including empty ones) such as
provided by level (2) upper.

Level (3) upper interface consists of one permanently-allocated
channel for handling control information such as opening/closing
channels and changing communication parameters (baud rate, maximum
packet size), and 254 other channels that may be opened and closed at
will. Each open channel can send a block of data, check for receipt of
a block of data, or receive a block of data that has arrived, at any
time. (Trying to send a block when there's already received data
waiting fails with an error flag, as does trying to receive a block
when there isn't any waiting, but these failures may be used as normal
programming practices in lieu of pre-checking for data-arrived, to
avoid race conditions when the modem is operating in true full-duplex
mode.) In various implimentations, the responsibility of matching
these logical streams to the corresponding logical I/O channels of the
applications programs may be the responsibility of the application
program itself (in simple mode, for both the control stream and other
streams), the node-control program (in advanced mode, for all streams
except the control stream), or the level (3) itself (in advanced mode,
for asynchronous/unanticipated control messages only).

We currently have several (three at last count) application programs
defined:
 (A) Node-control, permamently assigned to logical stream 0, generates
    and answers requests to activate/deactive other application
    programs and open/close the associated streams, and handles other
    assorted general node functions.
 (B) ECHO, allows testing of the support layers by sending data from
    the master ECHO program to the slave ECHO program and back again,
    then comparing to see if what came back was on the same stream and
    with the identical data as what was sent.
 (C) MAIL1, supports electronic mail (text files addressed to
    people's mailboxes and to mailing lists, optimized for automatic
    forwarding) and electronic file transfer (text or binary files
    addressed to a particular file name; both in blind mode that
    permits automatic forwarding, and in end-to-end negotiated mode).

(A,B,C) all have what may be considered major level (4) of protocol,
interpretation of opcodes and arguments (syntax may be regarded as the
lower interface, semantics may be regarded as the upper interface)
communicated along one of the logical data channels between two
applications programs of the same type.
(C) also has what may be regarded as major level (5) of protocol, the
header of electronic messages that continues to exist even after the
connection has been closed and levels (1,2,3,4) have effectively
ceased to exist, and the interpretation (semantics) of the header.
Both (B) and (C) use (require) more than one logical channel (stream)
at their lower interfaces.

We hope that many other applications programs, many using multiple
logical channels (streams) to simplify program logic (control on one
channel, data on another, for example), will be written and then run
over PCNET support layers. For example, one might write a
multiple-disk-channel server, and then random applications programs on
another machine can connect to it and act as if the disk were local,
reading and writing several files at the same time on the remote
system. Or one might install a multi-terminal TIP, multiplexed thru a
high-speed leased line using PCNET protocol, demultiplexed at some
Arpanet host into separate local jobs and/or TELNET connections, and
run some FTP or electronic mail task in background whenever no
terminal needs service.

In summary, we start with a hookup to TPC (The Phone Company), which
supplies simple direct-dial switching and voice-grade connections,
then value-added services are as follows: Level 1 (modem&UART
hardware) provides unreliable octet-binary data communications, level
2 (turnaround, framing, translation, validation, sequencing) provides
one reliable block-of-octet-binary full-duplex data channel, level 3
(directing) provides multiple logical channels connecting various
applications programs together, level 4 (online portion of application
programs) performs individually desired applications tasks, level 5
(offline portion of applications software) maintains permanent data
structures such as electronic-mail archives&queues.

PCNET uses the standard direct-dial telephone system together with
standard modems and UARTs or ACIAs. None of this is the invention of
PCNET.

[This was formerly in the separate file PCNET;MODEM REQUIR]

                                        August 1979

PCNET MODEMS
All telephone based data communication systems require modems to
function. The features required for a PCNET modem are as follows:

Hardware Features

-Receive sensitivity of at least -40dBm; -45 to -50 dBm preferred.

-10 pole receive filter; 6 pole transmit filter.

-300 baud operation.

Features Under Software Control

-Answer/originate mode select.

-Switch hook control;pulse dialling.

-Carrier detection.

-Incoming ring signal detection.

Desirable But Not Necessary Features

-FCC Part 68 registration, permitting direct connection to
the phone line without an otherwise legally required
Data Access Arrangement.

-Telephone signalling tone discrimination, allowing software to
detect DIAL TONE, BUSY, CALLED PARTY RING, etc.

-Software selectable baud rate

-Power up on incoming ring detect.

The PCNET Project has found a number of modems that are suitable
for PCNET use. A list of them is given below.

TYPE - S100 Compatible

The MM-103, from
Potomac Micro-Magic, Inc.
First Lincolnia Bldg, Suite B1
4810 Beauregard St
Alexandria,VA 22312
Costs $359.95; is FCC Part 68 certified

The Micromodem-100, from
D.C. Hayes Associates, Inc.
16 Perimeter Park Dr, Suite 101
PO Box 9884
Atlanta, GA 30319
Costs $350.00; is FCC Part 68 certified

The 88-MODEM, from
International Data Systems, Inc.
400 N. Washington St
Suite 200
Falls Church,VA 22046
Costs $395.00

TYPE - Apple Compatible

The Micromodem II, from
D.C. Hayes (see address above)
Costs $389.00; is FCC Part 68 certified

TYPE - PET Compatible

The TNW488, from
The TNW Corporation
5924 Quiet Slope Drive
San Diego, CA 92120
Costs $320.00

TYPE - TRS-80 Compatible

The AFFS Modem, from
Bill Abney
7600 E 48th Terr.
Kansas City,MO 64129
Costs $299.95
We have not seen the specs on this unit, but believe it to be
suitable for PCNET use.

Here's a description of this layer from the point of view of
value-added services.

The telephone switching system uses primitive on/off signals in
varying time-patterns to make&break connections. Lifting a phone
off-hook closes a circuit. If the phone is "ringing" from an incoming
call, this establishes a connection with the calling party. Otherwise
lifting off-hook connects the phone to a "dialer" unit in the central
office, which accepts sequences of on-hook pulses in an off-hook
background to convey a telephone number from the telephone to the
central office, to establish a connection with a remote phone.
Touch-tone (TM) phones use the same system for going off-hook but use
dual tones of audio frequencies to convey the telephone number to the
central office. After establishing a connection, voice and similar
signals may be sent between the two telephones. There's a little
crosstalk, but mostly there are two independent channels, one in each
direction. When either telephone (the one that originated and dialed
the call, or the one that answered) goes off-hook for longer than
about a half second, it signals the central office to break the
connection. The other phone gets a dead line for a while, then sooner
or later it gets a new dial-tone if it is still off-hook.

During the time the two phones are connected, that is after
establishing a connection and before either hangs up, a voice-grade
connection exists between them. A modulator may be connected at one
end and a demodulator at the other end to transmit binary (two-valued,
i.e. on/off) data across the phone connection. When a zero value is
present at the input to the modulator, one frequency is sent
continuously, and when a one value is present another frequency is
sent. The demodulator discriminates between these two frequencies and
outputs a zero or one accordingly. Thus a modulator and demodulator
using the same pair of frequencies may send data in one direction
(from the modulator to the demodulator) across a voice-grade line.

With both a modulator and demodulator at each end of the phone
connection, using two pairs instead of one pair of frequencies, with
the pairs crossed (one pair is used by the originate-modulator and by
the answer-demodulator, the other pair used by the answer-modulator
and by the originate-demodulator), data may be sent in both
directions, at the same time if there isn't too much crosstalk between
the two pairs of frequencies traveling in the two different
directions. A single device with both modulator and demodulator is
called a "modem" (MOdulator + DEModulator). If both parts can be used
at the same time, to transmit data in both directions at the same
time, it's called "full duplex", while if only one direction can be
used at one time, either because there's too much crosstalk or because
in fact only one pair of frequencies is actually used instead of two
pairs, it's called "half duplex". PCNET is designed to use modems in
either half-duplex or full-duplex modes.

When binary data is sent/received in the above way, it's unclocked.
That means a zero can switch to a one or a one back to a zero at any
random time. The exact time at which it switched at the modulator
can't be determined at the demodulator because signals travel at only
the speed of light (or slower) and the two telephones could have an
arbitrary amount of wire between them. The duration during which the
signal stays at one before switching back to zero, i.e. the difference
between the times of the two events (switch zero-to-one, then switch
back to zero), or between any other two events, can be determined
since the transit time is pretty much a constant during one phone
connection, but only to a certain accuracy, typically about a
millisecond with low-speed modems down to a tenth of a millisecond
with medium-speed modems. If we can identify the start of a sequence
of on/off switchings, then we can measure the binary state at certain
times after that and determine whether a zero or one was being sent at
that time. If the modulator is given regularily-spaced data, and if
the the signal from the demodulator is checked for binary value in
the middle of each individual data value, the data values can be read
off with high reliability. This is how a UART or ACIA works. The
transmitter sends a continuous value of one until it's ready to start
sending a byte of data. Then it sends one datum of zero, then each of
the data in sequence, then at least one datum of one before starting
the next zero+data+one pattern. The receiver starts timing when it
sees the initial zero bit, samples the middle of each data bit, and
checks to make sure the final one bit is present.

Usually eight bits of data are sent (oldstyle Baudot communication
uses only five bits of data, but PCNET uses the new eight-bit ASCII
method). An octet of data is fed (in parallel) to the transmitter,
which stores it in an 8-bit buffer. It waits until it's finished with
any preceding data plus the trailing one bit, then it sends the eight
bits of data from its buffer, one after another, starting with the low
order bit and ending with the high-order bit, and finally sends the
final one bit. The receiver sees the initial zero bit, stores the
following eight data bits, checks for the final one bit, and then
signals the computer that it's ready with an octet of data. The
computer then strobes the UART, and the the eight bits of data are
sent from the UART to the computer (in parallel).

The result of all this equipment, from the computer's view (and from
the programmer's view) is that an integrated dialer&modem&UART device
is available with the following capabilities:

Ring from an incoming call can be detected as a status bit.

Under computer command, the incoming call can be answered.

Outgoing calls can be established under computer command.

Once a voice-grade connection is established, a modem&UART connection
is automatically established. (The answer modem puts up carrier, the
originate modem responds with its carrier and also signals its
computer that the modems are half-connected and presumably will be
fully-connected in a moment, and finally the answer modem sees the
originate carrier and signals its computer that the modems are now
fully-connected.)

Once a modem&UART connection is established, status bits from the UART
tell whether there is any incoming data not yet fetched by the
computer and whether there is any outgoing data still being sent bit
by bit thus occupying the single-byte buffer in the UART. Whenever
status indicates incoming data available, the computer may fetch it.
Whenever status indicates the output buffer isn't busy with previous
data still in transit, and at the same time the computer has some data
it now wants to transmit, one byte of that data may be sent to the UART.

There are two problems with this. First, the only reliable signals
obtainable from the telephone system are the incoming ring and the
remote carrier. In particular when first going off-hook to establish a
connection it's not possible to tell the difference between (1)
accidently picking up just as an incoming call arrives (2) getting a
normal dial tone (3) getting a dead line due to busy or broken
equipment. Also, after dialing, it's not possible to distinguish
between (4) a long pause before the telephone equipment actually
starts to ring the remote phone, often as long as fifteen seconds (5)
ringing (6) busy signal (7) wrong number or other out-of-order
condition (8) somebody answered the phone but didn't put up
answer-carrier. To solve all these initial-connection problems, it's
necessary to guess a little, to wait a couple seconds after going
off-hook to be reasonably sure a dial-tone is present, then after
dialing to wait perhaps ten seconds before checking for carrier and
continue to wait perhaps 15 more seconds before giving up. We just
have to live with this cruftiness by designing software with all these
allowences and timeouts.

The second problem is that the voice-grade lines aren't entirely
noise-free. Those little chatters and clicks you hear when talking on
a phone can really confuse demodulators, making a zero where there
should be a one or vice versa. Adding the UARTs, we get missing data
because the start or stop bit was missing, extra data because a start
bit appeared out of nowhere, data with bits wrong because the noise
appeared during the data bits, and data that has been shifted because
an early or late start bit occurred. We have to live with this
unreliable data by designing software that distinguishes good from bad
data, eliminating the bad data and asking the data it should have been
to be retransmitted.

In summary, the interface between the hardware (phone & modem & UART)
and the software consists of:
 - Status of incoming ring detect and remote carrier present;
 - Control to establish and terminate connections;
 - Status of receive-data-available and transmit-buffer-busy;
 - Receiving data and transmitting data;
with all the above subject to errors due to signalling deficiencies
and noise.

In our 1980 PCNET workshop we decided to specify standard functions
for accessing the telephone interface (hook control, dialer, modem,
UART/ACIA), and to propose standard names for these functions. Later
REM wrote an 8080-asm interface to the PMMI modem according to these
specs, then realized a lot of code was duplicated between this PMMI
access module and his 88-2SIO module. He then proposed improved specs
which include all terminal-like I/O devices in a single unified
interface that shared as much code as feasible, and wrote a second
version of the 8080-asm interface using this new unified design.

Some additional high-level functions have been found very useful in
writing PCNET software. They'll be documented here soon...
SELMO -- Select modem channel by calling SELCH with appropriate constant.
SELLO -- Select KBD&CRT channel by calling SELCH with appropriate constant.
R7WBT -- Call RCWBT and strip off the parity bit.
S1WBT -- Turn the parity bit on and call SDWBT.
S1WST -- Transmit string with mark parity by calling S1WBT for each
    character of the string.
S1AST -- Same as S1WST except watch for ISTRR between each character.
    If ISTRR comes true, abort the output-string.

OLD TEXT:
	* Call SETOF(TRUE).
NEW TEXT:
	* Call SETOH(TRUE).

GETCH: --> NUM
	Obtain the current logical channel number, i.e. tell what
	channel was selected by the most recent SELCH. This is useful
	if a subroutine wants to save and restore the channel number
	but doesn't know (until it calls this function) what the
	current channel number is.

SELCH: NUM --> status
	Select the logical channel to be used for subsequent
	operations. Each implementation has its own conventions for
	channel numbers, for example channel 0 might be the local
	keyboard and CRT while channel 1 might be the modem.

OLD TEXT:
	Initialize modem after power-up or non-PCNET use.  This
	routine does whatever system-specific stuff may be needed
	before the other routines will work correctly.
NEW TEXT:
	Initialize modem and other I/O devices (local keyboard&CRT)
	serviced by this package, after power-up or non-PCNET use.  This
	routine does whatever system-specific stuff may be needed
	before the other routines will work correctly.

OLD TEXT:
 either in a high-level language or in machine language. These
 routines perform almost all the functions called directly by the
NEW TEXT:
 either in a high-level language or in machine language. Furthermore
 they are uniform across all devices, thus they may be written once
 for an entire system rather than once per device. (This is part of the
 reason for having channel numbers. The low-level functions earlier can
 execute different code depending on which device is currently
 selected. These functions merely call those low-level functions in a
 uniform way regardless of which device is currently selected. In fact,
 these functions don't even have to know what channel number is
 currently selected when they are called in order for them to execute
 correctly.)
 These routines perform almost all the functions called directly by the

OLD TEXT:
 routines, together with INITM and ISTRG, are the only routines ever
 needed to be called from high-level half-duplex software such as PCNet
 (checking ISTCA is implicit in the failure-return from various of
 these routines).
NEW TEXT:
 routines, together with INITM SELCH GETCH and ISTRG, are the only
 routines ever needed to be called from high-level half-duplex software
 such as PCNet (for example, checking ISTCA is implicit in the
 failure-return from various of these routines). Full-duplex code will
 also have to call ISTRR and ISTTR inside the polling routine or
 interrupt handler.
 Note that the internal workings of the next three functions (ORICL
 ANSCL and ENDCL) are purely suggestive. Some kinds of modems don't
 allow direct access to the mode-setting actions (SETOH, SETAN etc.),
 doing things in a more streamlined way. In any case, it's the function
 that is wanted, originating a call, answering a call, or ending a
 call, that is wanted, not the particular sequence of internal workings.

Once a telephone&modem connection is established and the local and
remote UARTs or ACIAs are effectively in communication with each
other, the functions for sending and receiving data to/from the local
CRT and keyboard are analagous to those for sending and receiving data
to/from the remote modem via the telephone link. We have therefore
extended this "modem interface" to include multiple logical I/O
channels for handling both remote (modem) and local (direct) I/O
within a uniform framework. Functions relating to establishing and
breaking telephone and modem communications are of course defined only
for the modem, not the local CRT&keyboard.

	Message from EH and GENTRY about DL-11E and CAT modems

EH@MIT-AI 09/09/81 22:41:01 auto-CAT and other good&cheap modems
To: GENTRY at MIT-AI, REM at MIT-MC
CC: EHUANG at MIT-AI
    GENTRY@MIT-AI 09/09/81 00:07:14
    ... Anyway, in regards to your query about RS-232 ports on my machine.
    Yes, I have a DL11-E interface for my unibus machine. It has complete
    MODEM control and 20ma or RS-232 capabilites. I have one
    attached to a second terminal on my system and the other is attached to
    my A-J 300 baud coupler. As I mentioned in a previous letter, I have a
    chance of getting ahold of a DF03 (DEC modem, $1700) for my use at home.
    It has 300/1200 baud auto originate (dialing under computer control) and
    auto answer. Unfortunately, I will not receive it until sometime in
    october. It is my groups property, so I can't keep it. Ah, well...

Blast! So thats what DEC,TI,IBM charges for things as they always
make BIG computers and charges LOTS of bucks..so,TI failed in their
personal computer attempt..
So,here's the Novation 4202B auto-ans/org 1200 buad for $540.
Or 300 buad modems:
Novation AUTO-cat Org/auto-ans/dial $240
Micropheral Corp Auto-COnnection Org/auto-ans/dial $270
they use Rs-232 interface. My book says the DL-11e (Ihave a bunch
of DEC books) is one serial port/asych./with all control lines.
I would like to know how much the DL-11E costs!

ps: I havea Novation CAT acoutics..maybe will buy a Auto-CAT
esp for PCnetting..SHouldnt be hard to get $240 from mother..

EH@MIT-AI 09/12/81 00:04:13 Re: auto-CAT and other good&cheap modems
To: REM at MIT-MC
CC: EHUANG at MIT-AI
SUPRISE!!!!!!!!!!!!!! MODEM-80 by ICROM Ents has auto-answer/auto-dial/org
and plugs directly into the TRS bus thus the $99 rs-232 is free for
other things! And it's complete with detailed software for binary/text
transmission between TRS-80s and its ONLY a cheep $210.
Remeber,this kind of modem plugs direct into TRS-80 so it cant be compared
with Auto-CAT but you can compare it with the MicroCOnnection and
Lynx which are $300 and $350 repectvely.

People who want a copy of this node when it's ready:
 heller.umass-coins@UDel-TCP what I mainly want is the lowlevel packet format
 tim.uci@Rand-Relay -- all of it??

Except for some random items at the end of this menu,
here are the different micro-layers of PCNET, presented as problems
and solutions (what communication problem exists, how does a
microlayer of PCNET protocol solve it), with the bottommost (nearest
modem) layer at the TOP (start) of this section of this menu.

Given full-duplex modems and UART/ACIAs talking to each other, over
noisy phone lines, with software incapable of full-duplex operation,
how do we reliably turn the phone line back and forth to emulate
half-duplex (taking turns talking) mode...

Given that nodes are taking turns talking, how do we stuff one or more
packets of data into a turn-talking, in a way that doesn't get
confused badly when phone noise causes characters to occasionally get
modified, and sometimes even the UART goes out of correct frame...
  Packet-framing microlayer::

Given that nodes are exchanging packets of data, possibly in a
restricted characterset consisting only of printing characters, due to
limitations of the operating system modem interface, how do we
represent binary data in this medium so that higher levels of protocol
don't have to use different protocols depending on what characterset
limitations are imposed, and so that in fact binary data may be
transmitted&received and the packet-header information may assume
arbitrary binary values...
  Translation microlayer::

Given that nodes are exchanging packets of binary data, except error
due to phone line noise may appear, how to error-protect the packets
so that bad data is rejected, so that only good data gets through
unchallanged...
  Validation microlayer::	(Could be called the "error-control" layer)

Given that packets that appear wrong (both normal packets that have
been damaged by phone line noise, and bursts of noise that at first
appear to be additional packets but which don't pass the validation
checks) are rejected, how do we cause normal packets that were damaged
and rejected to be retransmitted so that we have another chance to
receive them correctly...
  Sequencing microlayer::	(Analagous to packet-reassembly layer)

Given that we now have a way to exchange blocks of binary data, with
virtually no errors present, how do we direct this data to various
programs and to various channels of a given program, so that for
example control information can be separated from actual data...

    Until I can get around to filling in all those menu items, refer
    to this instead for all the above micro-layers...

Below are some miscellaneous items...

In summary, a node transmits about five lead-in characters (atsigns),
then one or more framed packets (see the next layer up for info about
packet framing), then five turnaround characters (brackets), then an
optional carriage return just to force IBM systems to let the program
see the preceding characters.

See menu items for parity on lead-in and turnaround characters and
other detailed matters.

When five turnaround characters (brackets) are sent by one node, the
other node stops receiving and gets ready to transmit as soon as it has
seen three of them. In this way if one or two of them are lost for
some reason, turnaround will still be effective.

Now if the node that was receiving and is now transmitting starts
sending packets of data immediately, the first few characters of the
first packet will usually be lost by the other node because it was
still transmitting the last of the turnaround characters and hadn't
yet switched to receiving mode. Typical UARTs and ACIAs have room to
buffer only one character ahead, thus it's impossible for them to
retain all the characters that arrived while the node was still
transmitting. We're also assuming the software can't receive data
while transmitting (if it could, it would be using full-duplex mode
instead of half-duplex mode).

Therefore we have to arrange that the node that is starting to
transmit doesn't send any real data (packets) until several character
times after it sees three turnaround characters. Since realtime delays
are not available on all machines, and timeouts (such as not
transmitting until the other node seems to have stopped sending) are
undesirable (tricky to program on most machines, unavailable on some),
the only solution seems to be to transmit a few characters of no data
value before starting to transmit real data. We decided to use the
same character as packet framing, to avoid the need for yet another
character beyond the fourty-five we already use (radix-41, packet
framing, two kinds of turnaround, and <cr>).

Sending five or so lead-in characters has a fringe benefit. The node
that just stopped transmitting can use these as a reliable signal that
turnaround has been successful, rather than waiting to see if regular
data arrives. Majority logic can be used, with 3-of-5 lead-in
characters being clearly distinguished from phone line noise. Also if
the node that is starting to transmit is very slow, it may not have
actual data available for several seconds, whereas it can transmit the
lead-in characters immediately, allowing for a short (5-10 second)
timeout to be used in this one place (elsewhere we use a longer
timeout, perhaps 50 seconds, since some systems on PCNET are *very*
slow and may take 20 or 30 seconds of processing to handle the data it
received and to get a block of data ready for transmitting).

Note that only node needs to have timeout capability under our design.
If the node ending transmission doesn't see lead-in within ten
seconds, and it has timeout capability, it then re-sends turnaround
and listens for lead-in again. If that node doesn't have timeout
capability but the other node does, the other node times out after 50
seconds of no data arriving, sends turnaround, and then the first node
tries again. It's not optimal, but it works. With both nodes having
timeout of course the delay is 10 seconds worst-case regardless of who
doesn't see turnaround. In any case, with 3-of-5 majority logic to
start with, timeout should be quite rare, and even the 50 seconds once
in a blue moon should be tolerable.

In the process of turning the line around (in half-duplex mode) it's
possible for the UART/ACIA to go out of correct frame, for example by
crosstalk from the transmit side due to low-quality residential phone
lines and cross-country echo suppressors out of adjustment. Also
during normal data transmission the UART/ACIA can go out of correct
frame due to random noise spikes that override a bit of data,
especially the start bit. With normal data being received after the
out-of-frame condition is initiated, it's possible for this state of
incorrect frame to persist for a very long time. (REM) I've observed
this condition to persist for a full screenful of data, over a
thousand characters. It would be a shame if some transient during
half-duplex turnaround could create incorrect frame, and cause
half-duplex lead-in to be missed and/or cause a whole packet (or
several packets in a row) to come through as total garbage. Even
worse, the longer such a mis-frame persists the higher the likelihood
of some nasty control character to be seen instead of a data
character, some control character that for example aborts the PCNET
job and logs the terminal out or possibly even worse leaves the
originate node talking to a bare EXEC on the other machine, attempting
to execute Radix 41 packets as Tops-20 or Unix commands!!!

To avoid loss of half-duplex lead-in (turnaround acknowledgement), we
try to put the UART/ACIA back into frame during lead-in. Since we
don't know when the other node will be done transmitting and start to
listen to the lead-in, we re-frame on each character. To avoid loss of
a packet unnecessarily due to some error that misframed the UART/ACIA
before the packet even started, we also reframe the UART/ACIA just
before the start-of-packet signal. To avoid proliferation of
characters, we use the same character for (1) lead-in, (2) UART/ACIA
reframing, (3) start-of-packet signal. This has the fringe benefit
that we don't have to alternate UART/ACIA reframing and lead-in
characters, we just send five or so of these combined-purpose
characters, the first one puts the UART/ACIA in frame and the rest are
actually received correctly as lead-in.

I (REM) did experiments in 1977 when PCNET first started. I tried all
possible printing characters, making my 6502 spew them out at full
speed to my Beehive terminal, and glitching the incoming data every so
often by pressing some key (I forget which) on the Beehive
momentarily. Each time I pressed it the UART was thrown out of frame
and I got garbage on my screen instead of the correct data being sent
by the 6502. With every character except atsign it got into a
mis-framed state permanently, getting out only when I glitched it
again and by random luck the glitch put it in correct frame again.
With atsign, there were a few characters of garbage during the glitch
itself, but immediately after it reframed and gave me atsigns again.

I then tried sending normal data with atsigns ever so often. When I
glitched it, there'd often be garbage until the next atsign, then good
data after that. Therefore I reccommended that atsign be chosen for
this magic multi-purpose framing character, and the PCNET Protocol
committee accepted my reccommendation.

Note that atsign works this way regardless of the parity bit on my
Beehive, and I don't know why. It's easy to explain why it works with
mark parity, since the serial data is 0,0000001,1,1; i.e. start=0, 7
data bits low-order-first, parity=1, stop=1), and thus there's only
one transition from 1 back to 0 (the signal to the receiving part of
the UART/ACIA to get ready to start the next character), at the start
of the next character, never in the middle of the character as would
be possible with most other bit patterns. Thus we specify mark-parity
atsign to be used where possible, although space-parity isn't too bad
(0,0000001,0,1), and does somehow magically work on my Beehive's UART.

Note that mark-parity NUL (0,0000000,1,1), back-apostrophe
(0,0000011,1,1), lower-case-p (0,0000111,1,1), lower-case-x
(0,0001111,1,1), vertical bar (0,0011111,1,1), tilde (0,0111111,1,1),
and rubout (0,1111111,1,1) might be as good as atsign, but are less
likely to be accepted by upper-case-only text-only systems. Atsign
seems to be acceptable on all systems except some old Univacs an
possibly some Honeywells.

This layer might also be called the "Multiplexing" layer since it
multiplex several logical streams onto one physical stream.
Unfortunately Kim Harris insisted that random people with personal
computers don't know what "Multiplexing" means, hence "Directing".

	RAD41.WRU -- Explains Radix-41

	EXPLANATION OF RADIX-41 IN PCNET
	by Robert Elton Maas (REM at SU-AI,MIT-MC)
	written 1977.Aug.27 via Beehive 3A terminal

(Disclaimer:  The Beehive 3A isn't worth the  $3000  it  costs
new, probably worth about $1200-1500, I got mine for $800.)

INTRODUCTION
	A lot of complaints about Radix-41 have been received,
mostly based on misunderstandings as to the use we make of it.
This writeup is an attempt to explain just what  Radix-41  is,
what  we  are using it for, why we selected it, and under what
circumstances we will phase it out.

DEFINITION
	Radix-41  is  a  mapping  between  characters  and the
numbers from 0 to 40 (decimal) defined as follows:  ("(" =  0)
("0"  = 1) ("1" = 2) ("2" = 3) ... ("8" = 9) ("9" = 10) ("A" =
11) ("B" = 12) ... ("Z" = 36) ("/" = 37) ("+" = 38) ("-" = 39)
(")"  =  40).   It  was  invented  by  Mike  Wilber  and first
presented in [Wilber Ciespec].  When  applied  to  data  being
transmitted  over  a  serial  I/O  line  such as RS-232 and/or
BELL-103, there is an implicit mapping composed of  the  usual
ASCII  or  EBCDIC encoding plus the Radix-41 mapping.  Thus in
the case of ASCII Radix-41, the  following  composite  mapping
occurs  (in each tuple below, the first field is in bit-serial
binary as it appears on the line with start+stop bits and  low
order  bits of data first, the second field is in octal as DDT
might print it when examining a byte that has arrived via  the
UART,  the  third  field is an abstract printable character as
above, and the fourth field is a  decimal  number  as  above):
(00001010p1  050 "(" 0) (00000110p1 060 "0" 1) (01000110p1 061
"1" 2) ... (01001110p1 071 "9" 10) (01000001p1 101 "A" 11) ...
(01011010p1  055  "-"  39)  (01001010p1  051  ")"  40).   When
receiving, the UART  parses  the  serial  input  of  bits  and
creates the 8-bit byte, and the software (eventually hardware)
maps directly from the 8-bit byte to the  decimal  value  0:40
with   values  above  40  reserved  for  special  representing
non-Radix-41 characters received.

PURPOSE
	Serial  I/O  would  seem  to  allow us to transmit and
receive binary data in 8 out  of  every  10  bits  transmittid
across   the  line.   But  most  computer  installations  have
installed hardware and/or software (usually the latter)  which
severely  restricts  what  can be transmitted and/or received.
The parity bit is usually set by a flag  in  the  hardware  to
always transmit odd or even parity with respect to the other 7
bits, and this bit is almost always ignored upon receipt of  a
character.   Thus at most 7 bits of data can be transmitted or
received when  talking  to  almost  all  existing  timesharing
systems  over  dialup  lines.   We need to interface with such
systems in order to rent disk space which they have  and  most
personal  computers don't have much of, and we want to be able
to exchange network mail with such sites and with the networks
they  are  on  (Arpanet,  Tymnet,  Decnet,  ...).  Also, until
answering modems are cheap enough that most personal  computer
systems can have them installed, we will have to rely on using
their  answering   modems,   using   timesharing   houses   as
intermediaries  between  personal  computers  that  have  only
originate modems.  Thus we  are  virtually  forced  to  use  a
subset of the 7-bit characterset.
	Most  timesharing  houses   totally   ignore   certain
characters,   for  example  IBM  360/370  systems  ignore  177
(rubout) and most DEC PDP-10 systems ignore 000 (null).   Also
most  systems  have  a  large  number  of  control  characters
reserved for special purposes (DEC SYSTEM10: 003 to  interrupt
system,  002  to  hold and release output, 017 to kill output,
032 to terminate input file -- TENEX: 003  to  put  EXEC  into
command  mode,  024  to type out statistics of system load and
job running status, 037 to hold and release output).  Due to a
several  changes  in the design of the ASCII characterset, and
current ambiguity  about  what  certain  character  codes  are
supposed    to    do,   different   systems   have   different
interprtations of the same character, and  certain  interfaces
between  computers provide mapping between different character
codes that are supposed  to  have  the  same  meaning  at  the
different   computers   (note  in  particular  the  following:
Carriage-return  vs.  linefeed  vs.  altmode  vs.  escape  vs.
newline  vs.  backspace  vs. leftarrow vs. underscore, altmode
vs. close-brace vs. tilde, and uparrow vs. carat). Eliminating
all  control characters and other ambiguous characters, we are
left with the specials from 040 to 100, the uppercase  letters
from 101 to 132, the specials from 133 to 135 and 140, and the
lowercase  letters  from  141  to  172,  for  a  total  of  89
characters.
	Several   programming   languages   map   lower   case
characters  to  upper case, and also several low-cost computer
timesharing houses we might  use  do  too,  thus  we  have  to
eliminate   lower-case   characters,  leaving  63  characters.
Finally, BASIC which is the only language  available  on  most
computers  built  as  a kit from hobby stores, doesn't like to
see certain characters  as  input,  namely  040  (space),  054
(comma)  and  a  few  others.  When inputting and one of these
characters appears, either the string of input is  prematurely
terminated  or  the  character is simply ignored.  Thus we are
down to 59 characters. In order to reserve  a  few  characters
for  framing  and  other  control  functions (they must not be
characters used fo data), it is desirable to transmit our data
in  a characterset somewhat smaller than 59 characters.  41 is
an obvious choice because 41*41*41  is  slightly  larger  than
65536  thus  two bytes of binary data can be transmitted every
three bytes on the line, thus minimizing the need to  transmit
our  data  in  blocks  that are quantized by a large number of
characters,  and  simplifying   the   routine   that   unpacks
characters on the line to produce internal binary data.
	Thus we have decided that in our  protocol,  at  least
the  first-year  version  that  is  compatible  with  existing
computer systems, at the very bottom  (just  above  the  UART)
will   be   a   routine  to  translate  between  the  Radix-41
representation that is transmitted and received  on  the  line
and  the  8-bit  binary representation that is used everywhere
else in our protocols.
	Although  division  of  two  arbitrary  numbers  on  a
microprocessor is rather slow, dividing by  a  known  constant
can  be  compiled  into  a  much  faster routine that actually
multiplies by the inverse of  the  divisor  (with  appropriate
scaling  because  all  numbers are integers).  Mike Wilber and
Marc Kaufman have written 8080 routines that divide by 41 with
various time/space tradeoffs, one takes a lot of memory but is
very fast, the other is only moderately fast (but much  faster
than division) but takes a tiny amount of memory.  By escaping
to machine language routines on hobby computers,  and  relying
on the gross speed of the timesharing-house computers to do it
by actual division, the mapping from binary to Radix-41 should
run  reasonably fast everywhere.  The mapping from Radix-41 to
binary requires only multiplication by 41 and thus should  run
reasonably fast everywhere without any special programming.

CODING EFFICIENCY
	When  transmitting  text  (English  or  other  natural
language   using   ASCII   characters   having   their   usual
interpretation, as contrasted with binary data  representating
programs  etc.),  a  simple  compression  scheme  based  on  a
truncated Huffman code can be used to  reduce  the  text  data
into  about  4  bits per character.  After mapping this binary
data into Radix-41 we have about 6/8 of  a  character  on  the
line  for  each  character  in the English text.  After adding
framing and checksums, and  all  the  other  overhead  in  our
protocol,  we  end up with about one character on the line for
one  character  of  text   data.    The   difference   between
transmitting  the original text across the line, and doing all
this mapping and encoding, is that we have gained (1)  virtual
elimination  of  errors  caused  by  phone-line noise, and (2)
ability  to  relay  our  text   messages   through   arbitrary
intermediary  computer  systems  without  worrying  about  the
restrictions on charactersets that each enforces.  This allows
us  to  implement  the  higher  level  protocols for automatic
forwarding of mail without  worrying  about  a  message  going
astray  due  to  line noise garbaging the address or any other
part of the header or message-proper.  (The  author  plans  to
use  the lower levels of the protocol plus data compression to
alleviate  the  problem  of   losing   edits   and   premature
terminations  of  messages due to the horrible amount of phone
line noise on the  Ames-TIP,  including  Diffie-Hellman-Rivest
trapdoor    codes   for   protecting   transmissions   against
eavesdropping -- it is impossible to encrypt and then  decrypt
data if any errors happen during transmission of the encrypted
data.)

ALTERNATIVES
	The smallest fraction between 1/2 and 1/1 is 2/3, thus
if transmission of 2 bytes on the line for  every  1  byte  of
binary data is intolerably inefficient, and if transmission of
full 8  bits  of  data  on  the  line  is  impossible  due  to
timesharing-house  restrictions  listed above, our 2/3 mapping
is the simplest in terms of the number of characters that must
be  passed  to  and received from the machine language routine
that performs the mapping.  Other fractions such as 3/4 or 4/5
etc.  require  larger routines to perform all the special-case
mappings for  each  of  the  characters  that  come  into  the
routine,  or  else  a  loop  with  indexed  shifting  or other
operations that runs slower  than  a  straight-line  piece  of
code.   If   we   want   to   avoid   division  (simulated  by
multiplication by the inverse that has been computed ahead  of
time)  we'll  have  to use either a 32-character-set (with 5/8
mapping) or a 64-character-set (with 3/4 mapping).  The former
is  intolerably  inefficient  and  suffers from an intolerably
large blocking factor.  The latter is incompatible with almost
every  BASIC  in  the  world, making machine language from the
UART thru the  conversion  to  8-bit  binary  mandatory,  thus
preventing implementation on any timesharing house that offers
BASIC (with no machine-language routines allowed) as the  only
programming language.

PHASE OUT
	When enough personal computers have  answering  modems
so  that  direct  personal-computer to personal-computer links
become the rule  instead  of  the  exception,  we  will  start
publishing ICP (Initial Connection Protocol) for those systems
which have dial-up ports that initialize themselves  in  8-bit
mode instead of Radix-41.  Dialout nodes that can handle 8-bit
mode will be encouraged to dial into one of these ports rather
than  dialing  into a Radix-41 ICP port and switching to 8-bit
mode after ICP.  When virtually every node has 8-bit mode  and
our  directory  of  dial-up  ports  servicing  8-bit  mode  is
complete enough to make 8-bit mode the rule  rather  than  the
exception,  we  will  announce  that Radix-41 is no longer the
standard.
	After  8-bit mode has become the standard, it too will
gradually be replaced by one of the several bit-oriented  line
protocols  such  as  HDLC  (these  protocols  require  special
hardware which isn't yet on the market at prices hobbyists can
afford,  and none of the competing protocols has yet become an
industry standard, hence we  aren't  even  specifying  in  our
protocols  what this will be, although we are rather sure that
that  general  type   of   protocol   will   totally   replace
start+7+parity+stop  within 5 or 10 years). The same procedure
for advertising nodes that  can  handle  the  not-yet-standard
protocol, and eventually making it the standard, will apply.

BIBLIOGRAPHY
	[Wilber Ciespec] ARPANET SRI-KL <WILBER>CIESPEC.TEXT

	RADIX-41 Worked-out example

Date: 17 Dec 1978 0148-PST
From: Robert Maas <REM at SU-AI>
Subject: How to go from <SP> T to AWB
To:   FFM at MIT-MC

Data entry:  The character <SP> on your keyboard is hexadecimal 20 inside
the computer.  The character T on your keyboard is hexadecimal 54.

Binary to Mod-41 conversion:  See the "Simplified Protocol" document, in
the transmit pipeline, for description of packing two bytes into a 16-bit
value then dividing by 41 twice to get two remainders and final quotient.
0B 21 0C (hexadecimal) are the remainders and quotient.

Mod-41 to Radix-41:  See the table right after that description where it
shows what Radix-41 characters correspond to which Mod-41 bytes.

	In addition to activating application-programs and assigning
stream numbers, the NODE-CONTROL program has some duties of its own.

The NODEID message exchange (see interim mail protocol)
causes global variables to be set and/or a log entry to be made,
identifying the node to which communiction has been established.
Application programs such as MAIL1 may consult this information
to help make decisions about forwarding of mail or willingness to
accept mail at all.

The BYE message exchange (see interim mail protocol) causes the phone to be
hung up.

[Note, some of these opcodes, proposed in 1978 in PROTO.WR2, conflict
with newer ones installed during or after the 1980 workshop.
Presumably these old ones will have to be changed.]

	The mapping  between  server-level functions
and PURE-BINARY-DATA-STREAM bytes
needs  two  more  items  of information before it can be considered
completely defined, a table of opcodes  and arguments for
control messages (messages to process 0), and a similar
table for messages sent between other processes (together with
a narrative of how process-to-process protocol
works since that hasn't yet been stated clearly).
	The 8-bit opcode (for both control and server-process) is
composed  of  two parts.  The two high-order bits (hexadecimal
mask C0) contain a flavor code,
and the 6 low-order bits (mask 3F) contain the type of message code.
Together, this 8-bit field is called the "opcode" and determines
how many arguments will follow and what they mean.  Flavors
are listed here in binary:\.
\F0	00 = I WON'T			(00)
	01 = PLEASE DON'T		(40)
	10 = I WILL IF OK WITH YOU	(80)
	11 = PLEASE DO IF YOU CAN	(C0)
\F1\JThe idea (invented by Arpanet for the "New Telnet" protocol
which became the default for TIP software sometime in 1977 summer)
 is that if a node receives a 10 or 11 flavor  message
it  doesn't  understand  at  all,  it  can refuse whatever was
requested or offered by merely returning an identical  message
with these two bits complemented (10 to 01, 11 to 00).
If it receives a 00 or 01 flavor message it doesn't understand
at all, it simply ignores it.
In either case, the receiving node wouldn't know how many bytes
long the message is, but since each control message occupies exactly
one PPS, the receiving node simply ignores or NAKs the entire PPS.
For the mail/ftp server, the relation between the request and the PPS it is in
isn't 1-to-1, so the situation
is more complicated and no
satisfactory uniform method of
NAKs has been designed.
Probably the receiving node will simply ignore anything
it can't understand.
	Arguments (parameters) are listed beside each flavor of
each opcode where needed.  Arguments are numbered 1,2,... in
consecutive order (each number represents one 8-bit byte), where
0 represents the opcode+flavor byte itself.  Where a single
parameter requires more than one byte, for example control-3A
in flavor-11 (bytes 2 and 3 are amount of additional-allocation),
the first (lower-numbered) byte is the lowest-order part of
the numeric value.  The exception to this rule is any parameter
that is in ASCII text, for example as control-01 flavor-10
 (MY NODEID IS ...),
where normal left-to-right printing sequence is used.
	For control messages, the 6-bit type-of-message  codes  have  been  assigned
so-far as follows (hexadecimal).  Arguments are
shown with their bytes numbered 1,2,...  Note that required messages
are numbered 01, 02, ... to allow a simple table lookup and dispatch
to a routine to handle them, 00 is assigned to Close-Connection-Protocol,
and optional messages are numbered from 3F downward to leave
room at the lower end for more required messages to be
added later:\.
	01 = MY NODE ID IS
		10-FLAVOR ARGS: 1,2,... = ASCII NODE IDENTITY (UP TO END OF PPS)
	02 = SWITCH TO FDX
	03 = SWITCH TO 8-BIT TRANSMISSIONS (MUST ALREADY BE IN FDX)

	00 = HANG UP PHONE NOW (CCP)

	3F = (ESCAPE TO EXTENDED OPCODE SET IF EVER NEEDED)

	3E = SEND LTBs UP TO THIS LENGTH (MINIMUM=7, MAXIMUM=255)
		11-FLAVOR ARGS: 1 = MAXIMUM NUMBER OF CHARACTERS IN LTB
	3D = CHANGE N-OF-8 WINDOW FOR LTBs
		11-FLAVOR ARGS: 1 = NUMBER OF LTBs IN WINDOW I CAN ACCEPT (MAXIMUM=4)
		10-FLAVOR ARGS: 1 = # OF LTBs I'LL SEND YOU (unnecessary)
	3C = SEND HDX UP TO THIS MAXIMUM TOTAL NCHAR
		11-FLAVOR ARGS: 1 = NUMBER OF CHARACTERS
	3B (THIS CODE WITHDRAWN, IGNORE)
	3A = INCREASE TEMPORARY DATA ALLOC BY THIS MANY BYTES
		11-FLAVOR ARGS: 1 = PPS-NO AFFECTED IN DESTINATION NODE
			2,3 = AMOUNT OF ADDITIONAL ALLOCATION
	39 = TELL WHAT VERSION OF SOFTWARE
		10-FLAVOR ARGS: 1,2,... = ASCII VERSION ID (UP TO END OF PPS)
		11-FLAVOR, NO ARGS
	38 = UNSYNC LT-BLOCKING FROM PPS-BLOCKING
	37 = BACK TO RADIX-41 MODE

	In advanced nodes, additional NODE-CONTROL messages may be
used to change parameters of operation, such as switching to
full-duplex or changing the baud rate. These matters are not
discussed in this document. Also in advanced nodes, it's possible for
the answer node to request an application program and the originate
node to grant it. In such a case the words "originate" and "answer"
must be reversed in the above descriptions, for example the answer
node would then be the initial master and the originate the initial
slave in the MAIL1 program, and the originate node would be echoing
data back to the answer node in the ECHO program.

Each application program is a separate entity, performing some useful
task for the person invoking it or for some higher level of protocol.
Each application program has its own protocol for communicating with
its mates. That protocol is the main topic of the application-program
descriptions below. The user-interface might also be described, but
that isn't really a proper matter for PCNET protocol specs to decide,
since two programs with totally different user interfaces can talk to
each other if they use the same protocol.

    Application programs whose protocol has been defined...

Other application programs whose design is in progress or planned...

TCPIP -- Encapsulates TCP/IP datagrams into PCNET packets.
GAME -- Ties into a network of gamesters, matching players and refereeing
 their online games with each other.
UNTALK -- Two-window talk with other user, one person types in one window
 and other in other, thus allowing true full-duplex chatting, both can talk
 at same time without interupting each other.

%% end-user applications
LABEL	WRU		Proposal for PCNET service of making labels remotely

Please read and understand the TELNET protocol before attempting to
read this. Also to appreciate this service one should be familar with
multi-window editors such as EMACS and/or with multi-window shells
(execs) such as various Xerox systems, Swinehart's ETV-based proposal,
the ETV-based interface to MacLISP "EMACLS" at SU-AI, the similar
EMACS-based interface to MacLISP at MIT, Apple's LISA, or the
Buroviseur proposed by the KAYAK project at INRIA.

This is a generalization of the TELNET and the NVT (Network Virtual
Terminal) protocols. It is designed to make full use of CRTs and other
display terminals with random-access screen update. The basic concept
is still that the user is typing on a keyboard and seeing results on a
CRT. The difference is that the CRT screen is divided into windows,
and each window corresponds to a different logical stream to the host.
Furthermore, while some windows will be operated in standard
teletype-emulator mode (keys pressed are sent immediately, and
whatever comes back is display, typically end-to-end echo of what was
typd plus anything output by the remote program), others may be
operated in remote-display mode (keys pressed are still sent
immediately, but the remote host has total control over what appears
in the window), or in local edit mode (keys pressed cause the screen
to change locally, nothing is sent to the host except when a special
SEND-THIS command is typed or after the mode is changed back to one of
the other modes).

While text typed on the keyboard is normally sent to the job currently
selected (the job corresponding to what window the cursor is currently
in), text output from ANY of the jobs is immediately send from the
host to the local system which upon arrival causes the appropriate
window to be updated. Thus the user may be interacting with one
program actively while watching several other jobs on the side.

Text that appeared as program output in one window may later be edited
locally and/or copied to some other window. Thus it's easy to prepare
documentation containing edited transcripts of online sessions without
disturbing the still-running program being documented. Text that was
read in from a file in an edit window can be copied to another window
so it can be fed as input to a remote program. Or for a simpler case,
the user can be running some long program and editing an unrelated
document on the same terminal at the same time, running the program in
on window but editing in the other window most of the time,
occasionally watching to see how the long program is coming along.

It's even possible for single programs on suitable hosts to be
connected to more than one PCNET EWIND stream, and thus be able to
produce output of different types into two different windows. For
example normal echo of typed input may appear in one window, normal
program-to-operator output may occur in a second, error diagnostics
may be emitted in a third (and the local system may be set to beep
whenever anything is sent to this window), and finally two files of
actual desired output may be written, one on the remote system and one
into yet a fourth window on the local system.

		* TESTIMONIAL BY REM *
I believe this kind of multiwindow interface, with many more specific
features like splitting or appending two windows, making some windows
invisible, keeping a window-status meta-window around, ... is the
shell of the future, both for operating local multiprocessing systems
and for operating remote systems via a network link from the local
workstation/system.

The purpose of the TELNET (also called virtual-login or
virtual-terminal or remote-login) protocol is to allow somebody to
connect across the net from his/her terminal to some host without
being subject to errors caused by phone-line noise on the way. In the
case of PCNET, it simply means an error-free link between the terminal
and the CBBS or other host.

The simplest implementation will have no method to abort data already
in route. The abort facility is important on the Arpanet where perhaps
a half minute of data may be en route and it's painful to have to sit
and watch it stream out after a command to abort that and switch
context has already been received at the host and acted on. But with
direct single-link connections such as PCNET the abort facility is not
essential.

Nevertheless some commands may need to be sent along a different
channel from the ordinary data. Thus TELNET will use two logical
streams, one for ordinary data and another for end-to-end magic
commands. (But at this time no actual end-to-end commands will be
defined here.)

SPECIFICATION:

The application program is called TELNET. Ordinarily the originate
node requests service which is granted by the answer node. Ordinarily
the node requesting the service is the "master" or "user" while the
othernode is the "slave" or "host". In the description below, "local"
will mean "master" or "user" while "remote" means "slave" or "host".

Two streams are allocated, #1 for TELNET-control messages and #2 for
normal data. Any key pressed on the local keyboard is sent along
stream #2 to the host where it is entered into the input buffer of a
virtual terminal port assigned to the user. Ordinarily the user will
first send a command to log in, then will send text
(monitor/exec/shell) commands to various programs and data text to
those programs. Finally the user will send a command to log out.

All data output from the host thru that virtual-terminal port will be
send back along stream #2 (remember all PCNET streams are
bidirectional) where they will affect the CRT or teleprinter in some
way. Ordinarily text characters will be written on the CRT or typed on
the teleprinter while control characters will affect cursor or
carriage movement.

It is possible that certain keys on the user's keyboard will be
defined by software in that local computer/PCNET system to affect the
local computer/system instead of being immediately transmitted to the
remote host. Some of these local effects may be to generate control
messages along stream #1. Anything sent along stream #1 will be
intercepted and acted upon by the remote TELNET program. Possible
effects are to directly modify the environment of the user's job that
is running on the remote system underneath the virtual terminal
interface, or to indirectly affect that remote job by generating (at
the host!) some text that is spliced into the stream of data coming
into the host system from PCNET stream #1.

It is also possible for the host system to send TELNET-control
messages back to the local system along stream #1, either replies to
TELNET-control messages sent earlier from the local system to the host
system, or new messages totally initiated by the host PCNET system.
For example, the host might send a message indicating the host system
will be going down for maintenance in five minutes, and in response to
this the local system might want to flash a warning countdown at the
bottom of the screen or sound a beeper or even turn off the television
set to avoid distraction during the critical last minutes.

Note that unlike the Arpanet TELNET protocol which uses a single
bidirectional stream, and thus needed to insert commands on the data
stream by sending a code of hexadecimal FF preceding each command, and
thus needed a way to quote FF if it ever appeared as normal data;
PCNET uses two streams, so the one dedicated to data is totally
transparent to 8-bit data and doesn't need any escape or quoting
mechanism.

Since the New-Telnet protocol on the Arpanet has withstood a lot of
usage and experience, we might choose to simply use their protocol as
is, with the only difference being the separation of control and data
streams. Would anybody object to that? (I could FTP the relevant RFC
and edit it to be correct for PCNET, and insert it here for reference.)

STREAM NUMBERS.
	As far as the application program is concerned, it can send
and receive data on any of n logical channels starting with channel 1.
Thus it can use channels numbered 1 thru n.  The number of channels
depends on the application program. ECHO uses all 63 available channels
while MAIL1 uses only 2 channels.
	The actual channels as specified in the directed-block depend
on whether SIMPLE or ADVANCED mode is being used. In SIMPLE mode, the
offset between logical channels used by the application program and
the actual channel numbers is a constant hexadecimal 40. Thus channels
41 thru 40+n are actually used. Lazy programmers intending their software
for use only in simple nodes may write it to actually use logical channels
41 thru 40+n instead of 1 thru n, and thus avoid the mapping. It's not too
hard later to upgrade it if and when mapping is installed. Note that
because of the constant offset, only one application program may be active
at any one time, because otherwise the stream numbers would conflict,
regardless of whether constant-offset is used or lazy-programming with
no offset at all is used.
	In ADVANCED mode, the offset is variable. ECHO must exist by
itself, but MAIL1 may co-exist with other programs (not yet designed
at the time of writing this document). For example, MAIL1 may be
invoked first and get channels 41 and 42 (logical 1 and 2, offset 40),
then TTY may be invoked and get channel 43 (logical 1, offset 42).
Since the first (or only) program invoked always gets an offset of 40
when requested by the originating node (the normal mode of operation),
SIMPLE and ADVANCED nodes may talk to each other freely using what
amounts to SIMPLE-mode protocol.
	All the protocols and examples in this document will assume
SIMPLE mode. Stream numbers given will be logical, with the offset
of 40 supplied by the directing layer by turning on or off a bit.
The reader can make the appropriate modification to obtain the
fullblown ADVANCED protocol specification.

<<Addenda, motivation for dividing stream numbers into two blocks...>>
When we decided to allocate all streams for a process at the time it's
invoked (rather than have each process keep one stream open even when
the process was inactive, as our pre-1980 protocol did), we had the
choice of making streams uni-directional or bidirectional. If
uni-directional, then receive and transmit streams would have to be
allocated separately, increasing the code needed to allocate streams
and the table space needed to keep track of them, as well as the
protocol needed to tell the other node what streams were allocated to
a given process. We therefore decided to make all streams
bi-directional. But in full-duplex there's a possible problem. Suppose
that at some moment when both the originate and answer nodes are idle,
they each come up with something they want to do. For example
originate says "Please Do open MAIL1" while answer says "Please Do
open TCPIP". Suppose the packets requesting these services are en
route in opposite directions at the same time, that is each starts
before the other finishes. The tables of unused stream numbers are the
same on both nodes, so it's likely that each machine will allocate the
same stream to the other. Thus two different applications programs
will be using the same stream, and total confusion and crash of the
protocol can be the only result. To avoid this problem, we decided to
split the space of possible stream numbers into two parts, determined
by the high-order bit of the seven available (the high-order bit of
the directing octet is already used for the End-of-Data bit). This bit
(hexadecimal 40) is set according to the node that allocated the
streams, which is the stream granting the request for service. To
avoid confusion, stream zero in BOTH parts (i.e. streams 00 and 40)
are reserved for node-control, leaving the remainder (i.e 01-3F and
41-7F) for allocating to application programs. Of course in simple
mode where only the originate node can request service and only the
answer node can grant the request, only the range 41-7F is used.

NOTATION.
	Examples of this protocol are given in a notation that combines
values of various parameters (direction between the two nodes, stream number
end-of-data bit) and the program-to-program (directed) data itself.
The data is given as a combination of hexadecimal-notation and actual ASCII
text, in the same format as input and output by the LISP program PCNSR6.
Here's an example:
  O-->A STREAM#43 EOD:  C2 "Test."
This is being sent by the Originate node and received by the Answer node,
using stream number 43 (hexadecimal), with End-Of-Data bit set, and the
data consists of a byte with hexadecimal value C2 followed by five bytes
of text "T" "e" "s" "t" and ".". (Text is with the high-order bit equal
to zero, for example "T" is hexadecimal 54 rather than D4. Note that
the above example could also have been presented as:
  O-->A STREAM#43 EOD:  C2 54 65 73 74 2E
which would have been correct but too obscure to the reader.

[Warning, a lot of stuff here needs to be cleaned up!!]

	For FTP/MAIL server-processes, the following 6-bit type-of-message
codes have been assigned (hexadecimal):
	01 = INIT FTP (IFTP)
		11-FLAVOR ARGS:  1,2,3 = EXPECTED LENGTH OF FILE IN BITS
		10-FLAVOR ARGS:  1,2,3 = GUARANTEED FILESIZE ALLOCATED
			4,5 = MAXIMUM BUFFER SIZE THAT CAN BE FILLED
			      BEFORE GETTING ACK TO PROCEED WITH MORE
			6 = PPS-NO OF REQUEST THIS IS REPLY TO
	02 = ACCEPT THIS FILE
		11-FLAVOR ARGS:  1,2,... = DATA OF FILE (TO END OF PPS)
		10-FLAVOR ARGS: 1,2,3,4 = CHECKSUM AT EOF (0 IF NOT COMPUTED)
\J	The overall way this works is that some process sends an
IFTP request to process 1 (the FTP/MAIL listener) and upon receiving
a I WILL reply to it the data is sent in a ACCEPT THIS FILE message
until the buffer allocation is filled, then transmission is
suspended until an ok for one more buffer is received.
After end of file, the transmit PPS is closed, and upon
receiving an ack of the entire file the checksum is compared
(if implemented and return checksum is nonzero).
	The initial buffer allocation given in the I WILL IFTP
message has a special meaning if it is zero, namely that accounting
for allocation isn't being done, and hence the full size of the file
is allocated or can be allocated as fast as it is likely to be sent
over the link.  Otherwise (nonzero allocation) the receiving node
(which sent the I WILL IFTP message) is guaranteeing that it will keep
track of buffer fullness and grant additional allocations as it empties
its buffers.  If the file is less than 2^16 bits, another way to grant
the full allocation at once is simply to specify the file size in the
initial allocation.

	With all that at hand, it should be easy to
figure out what various internode messages will become in binary.
Here are the internode messages described above in the REM to HILLMAN
netmail relay.  English (as used above) is at left (messages
from node#0 to node#1 are uppercase, from node#1 to node#0
are lowercase), extra explanation
is in parenthesis:\.
\F0\N
		F/L/..../MOD8	PPS-NO	LEN	SRC/DES/DATA
PLEASE DO FDX	C	0 	00 	06	00  00  C2
\F1\N
	(8=0,000=(LAST-BLOCK-BIT=1, MOD-8-BLK=0)
	 C2=11,000010=(PLEASE DO, FDX))
\F0\N
I will fdx	C	0	  00	06	00  00  82
PLEASE 4-OF-8	C	0	01	07 	00  00  FD 04
Please 4-of-8	C	0	  01	07 	00  00  FD 04
PLEASE DO 8-BIT	C	0	02	06	00  00  C3
My node id is	C	0 	  02	27	00  00  81 33342E35...3041
MY NODE ID IS	C	0	03	28	00  00  81 33372E32...2D31
I won't 8-bit	C	0	  03	06 	00  00  03
\F1\N
	(C3 changed to 03 and repeat back rest of not-understood request,
	 which in this case is nothing except low-order 6 bits of C3=03)
\F0\N
PLEASE UNSYNC	C	0 	04	06	00  00  F8
I won't unsync	C 	0	  04 	06	00  00  38
PLEASE IFTP, I'LL SEND 1997 BITS
		8	0	05	09	01  01  C1 0007CD
I will iftp, I'll accept 2000 bits, each buffer 255 bytes, re PPS-NO 05
		8	0	  05	0C	01  01  81 0007D0 00FF 05
"MAIL:34.52N... ... ..." (text of message)
		0	1	05	F9	        C2 4D41494C...
		0	2	05	F9		   ......
		4	3	05	53		   ...CD18
Ack ftp		4	1	  05	08		82 00 00 00 00
\F1\J\N
(Note that these nodes aren't allocating PPS buffers (using
opcode (11)3A = FA) because with only one active stream blockage of
the whole link due to PPS-buffer constipation doesn't do any harm.
If data in the FTP is sent faster than node#1 can unbuffer it, LTBs
are simply not-acknowledged and node#0 retransmits them.)\.
\F0\N
PLEASE CCP	C	0	06	04	00  00  00
I will CCP	C	0	  05	04	00  00  00

MAIL1 is the first version of a MAIL/FILE
transfer program. It can send mail addressed to the other node, send mail
to other nodes via forwarding, collect (receive) mail for a specified
geographical area, negotiate to send a file to the other node (no
forwarding possible), and negotiate to receive a particular file
from the other node. By using the protocol for forwarded mail,
with a slight change in the header, files may be sent blindly with
forwarding, and requests may be issued (with forwarding) for files
to be sent back (again with forwarding).

MAIL1 PROGRAM.

	The protocol used by MAIL1 is essentially the interim mail
protocol defined by John Gilmore and implemented in existing software,
except (0) the commands defined here are sent on logical stream 1 (the
MAIL1 control stream), rather than logical stream 0 (the node-control
stream), thus are interpreted directly by the MAIL1 program instead of
by the node-control program; (1) ECHO command is flushed since it
belongs in the ECHO program; (2) BYE command means terminate this
process, not hang up the phone (The same BYE command, when issued by
the NODE-CONTROL program, i.e. on logical stream 0, means hang up the
phone.); (3) NODEID command is flushed since it belongs in the
NODE-CONTROL program.
	Persons who have already implemented the interim mail protocol
may use that code for MAIL1 by making the above changes and by using
logical stream 1 instead of 0 for exchanging service requests.
	For those who wish to implement MAIL1 from scratch, here's
the complete specs of the protocol:

	When MAIL1 is first invoked, the originate node is the master
and the answer node is the slave. The originate node issues requests for
service which the answer node either grants or rejects. When the
originate node is finished, it issues a PLEASE-QRU (I have nothing for you,
do you have anything for me?) command. The answer node then becomes
the master and the originate node the slave, so that the answer node
issues requests which the originate node grants or rejects. Finally
when the answer node is done too, it issues an I-WILL-QRU command
and exits, returning the node to the idle state when node-control
messages may be handled.

Note, the term "QRU" comes from amateur radio Q-signals.
There doesn't seem to be anything more mnemonic that means the same thing.

	While MAIL1 is active, requests for services and grants/rejections
are passed on logical stream 1, data on 2, and end-of-data acknowledgements
on 3.
  C3 = PLEASE-DO ACCEPT-MAIL
  83 = I-WILL ACCEPT-MAIL
  03 = I-WON'T ACCEPT-MAIL
	The master issues a C3, and the slave replies 83 or 03.  If the
slave accepted (83), data is passed from master to slave on stream 2,
the last block having EOD bit set. When the slave sees EOD on stream 2,
it processes the message to see if the header is correct and the message
can be delivered or forwarded. It issues a reply on stream 3 which is
"GOOD:..." or "BAD:..." depending on whether it is accepting responsibility
for delivering the mail or not. "..." may be any explanatory text, for example
some nodes say "GOOD:thanks for the good header" or "BAD:no header".
	EOD is always set on the request&reply on stream 1 an on the
end-of-message final-ack on stream 3. (Multiple-block service requests
and acks are not permitted here.)  EOD is set only on the last block
of the data on stream 2.

Proposed change: None of the stream-1 commands take any arguments, but
I'm planning to add length-of-message-in-bits to both C3 and 83.  I'm
thinking of 3 bytes, high-order-first. If all three bytes are zero,
it means "I have no idea how long the message is but I think it's
short enough to be acceptable to you".

  C1 = PLEASE-DO QRU
  81 = I-WILL QRU
	These are used to relinquish masterhood to the other node,
as described in the introductory paragraph above. If the answer node
has no mail that it wants to send to the originate node, or the
answer node isn't programed for automatic downloading of mail, then
C1 from the originate node will be followed immediately by 81 from
the answer node, as if to grant the requested service of being done.
Otherwise reverse-direction (answer=master, originate=slave) requests
will appear after C1 and before 81.
	Of course if the originate node isn't programmed to handle
reverse (answer-->originate) forwarding of electronic mail, or if
it's calling long distance and is unwilling to pay for the phone call
during reverse transfer of mail, it may either sit online refusing
all requests for service, or it may just hang up impolitely.

	The data transferred via the ACCEPT-MAIL protocol consists of
a header, a blank line, and some text or binary data, as specified by
SERPRO TTY.  Briefly, the header contains one or more "MAIL:" lines
specifying the destination of the mail, one "FROM:" line specifying
the originator, an optional "SUBJECT:" line and any number of other
random lines. The "MAIL:" lines must be before all other lines.  Binary
(non text) data may never be put in the header.  Binary data may be
put after the blank line only if the node accepting the mail is known
to be able to handle the binary data AND the header somehow warns that
binary data will follow, such as by saying that it's compressed or
encrypted. -- As an alternative to "MAIL:", the header may begin with
a "FILE:" or any of several other services, but none of these are
implemented in any software presently known to this author.

From the file (now deleted in favor of this info-tree frame):
  16  BOURN  1        0 +907    9/18/82 18:57:36  (8/18/83) REM

	A Proposal for Addressing Stations of the Personal Computing Network

			by Doug Bourn

			19 May 1977

	Among the proposed addressing schemes discussed at the last meeting
of the protocol committee were zip codes (with suffix extensions) and
latitude and logitude values.  Each method has certain advantages.
However, I believe that any addressing system adopted for the PCNet
should have the following features:

   1. Relatively easy comprehension by humans.
   2. A sufficiently universal framework to be implemented anywhere on the
      planet.
   3. Some inherent form of interstation direction and distance.
   4. A capability for dynamically altering the size and location of
      regional zones.

The rationale for each of these features follows.

	Point 1 results from my conjecture that many computer hobbyists
will want to "try the network" with very minimal hardware (e.g.
a Penney-Whistle modem and a TV Typewriter).  Thus, interfacing to the
network will be a manual operation for the most part.  An address
which is understandable to humans would accommodate such experimentation
and would supply a potentially large number of nodes to the network.
	Point 2 envisions the expansion of the PCNet to neighboring countries
and beyond.  Already there is significant computerist activity in Canada.
Any addressing philosophy considered should be applicable to cultures
lacking a domestic structure such as the zip code system.
	Point 3 allows intelligent routing decisions to be made.  As the
PCNet matures it may be more economical to use radio links over certain
routes rather than land lines.
	Point 4 presumes the existence of arbitrarily defined service areas.
The size of these areas might be determined by the number of nodes within
its borders.  A node in a service area or regional zone would store the
addresses of each of the other nodes in the zone.  Overlapping zone boundaries
would guarantee a path from one node to any other node in the network.
The size of the zone would decrease as the density of nodes increased.
Thus, a relatively small table of addresses could be maintained by a
given node.
	In view of the considerations outlined above, I propose the following
addressing arrangement.  On the lowest level, a station address would
consist of a telephone number or radio station call letters suffixed by
an extension number or name.  A unique and highly understandable address
is thus created.
	On a higher level, values of latitude and longitude could be used to
define service areas.  A node would contain a table of values corresponding
to the boundaries of its service zone.  As a message enters a zone the
receiving staion compares the longitude and latitude components of the
message address with those stored in its table.  If the message target is
within the current zone, the station forwards the message to the node
specified by the low level address.  If the target is outside the current
zone, the message is sent in the direction computed from the difference
between the latitude and longitude parameters of the message and those of
the current zone.  This forwarding operation is accomplished by referring
to a list of addresses of nodes within the current zone boundaries as
described above.
	A header supplying routing information would consist of the
originator's address, the final destination address, and an intermediate
destination address which would be modified as a message was forwarded from
zone to zone.  An example of such a header might be:

	FR:40.33N110.35W/333.123.4321.JOHN/TO:35.52N100.46W/402.233.4545.MIKE/
	VIA:38.22N104.31W/908.456.3241.DON

[Note by REM, this isn't exactly the format we eventually decided
 upon, see other info nodes for the exact format.]

While such an address may consume more bandwidth than say a zip code
based system, I believe that the universal nature of the scheme outweighs
its disadvantages.
	In conclusion I offer two additional comments.  First, the problem of
determining one's latitude and longitude is solved by calling a local
airport or a branch office of the U.S.G.S.  Second, broadcasting over
the PCNet might be accomplished by omitting the final destination
address (or at least the low level portion) from a message header.
A message so transmitted would be disseminated in a tree-like fashion.

ECHO is a test program to echo back (on the same stream) whatever
data is sent to it.

ECHO PROGRAM.
	The ECHO program is simple. The answer node acts as a slave
under control of the originate node, just echoing back anything
sent to it, on the same stream.  For example, if the originate node
ECHO program sends:
  O-->A Stream=25: "Hi, this is a test." 0D 0A "Another line." 0D 0A
the answer node will reply with:
  A-->O Stream=25: "Hi, this is a test." 0D 0A "Another line." 0D 0A
	If End-Of-Data is seen on ANY nonzero stream (that is, any data
stream, any stream except the node-control stream), ECHO exits, returning
to the state when node-control messages are accepted.