@Section(Overview) In this chapter, the two important communication components of the Network (the ether and the System bus) are discribed. Anyone who wonders how to get files from one filestore to the other (ie. from Vax to Bravo, from Bravo to Vax,...) will find the answer reading the section @Ref(EFTP) on the EFTP (File transfer utility). You will also find some useful information on the VAX ETHER link driver and at the last sections will provide a complete description of FS (Ethernet and Filestore communications) and VTLIB (Video Terminal library) packages. @NewPage @Section(EUCSD Bus) @SeeAlso(Primary="Bus",Other="EUSCD System bus") @Index(EUSCD System bus) The EUCSD bus is an interconnection system for computer components. Its design goals where those of simplicity, flexibility and high performance. It was assummed that the components to be connected would fall into three categories : @Begin(Enumerate) Memories - accessible from all other devices. Main processors - with no I/O capability. I/O processors - providing I/O facilities for the system. @End(Enumerate) The two significant features of the system is that there are multiple processors sharing common resources and that there are no simple I/O devices connected directly to the bus. Multiple processors imply that the bus must be shared fairly between them. To achieve this a bus controller that gives bus arbitration facilities must be provided as part of the bus structure. We have chosen to implement this as a central facility that has separate connections to each of the potential bus masters. As there are no simple I/O devices on the bus it is possible to avoid providing a fixed interrupt structure. These facilities are provided by control registers associated with processors which when accessed from the bus will interrupt the corresponding processor. The form and of these registers will be determined by the nature of the processor with which they are associated. As we deal only with 'intelligent' interrupting devices on the bus, differences between the processors can be handled in software. As a result the only transfers on the bus are those of fully addressed exchanges of data between 'active' masters and 'passive' slaves. @NewPage @SubSection(Mechanical Details) All boards are double height extended depth Eurocards (233.4mm X 220mm). The Bus is connected by a single DIN41612 C 96 way connector positioned as in the following diagram : @Begin(Format,Group) |----------------- 220 mm ----------------| _____ _________________________________________ | | _| | | | | | | | | | | | | | | | | Bus | | | | Connector | | | | | | | | | | | | | | |_| | | | | | | 233.4 mm | Component Side. | | | | | | _| | | | | | | | | | | | | | | | | Unused | | | | Connector | | | | | | | | | | | | | | |_| _|___ |_________________________________________| @End(Format) The unused connector position may be used freely to provide off-board or inter-board connections. The problems of mechanical connection and compatibility with other systems are solely those of the implementer who uses them. @NewPage @SubSection(Connector Pin Assignment) @IndexSecondary(Primary="EUSCD System bus", Secondary="Connector pin assignment") @Begin(FileExample) pin no row a b c 1 GND GND GND 2 GND GND GND 3 +12V +12V +12V 4 -12V -12V -12V 5 AD2L AD3L AD4L 6 AD5L AD6L AD7L 7 AD8L AD9L AD10L 8 AD11L AD12L AD13L 9 AD14L AD15L AD16L 10 AD17L AD18L AD19L 11 AD20L AD21L AD22L 12 AD23L AD24L AD25L 13 AD26L AD27L AD28L 14 AD29L AD30L AD31L 15 CO0L CO1L CO2L 16 CO3L reserved R/WL 17 BRQiL CBRL BGRiL 18 RSTL MCLK PFLL 19 TACL ATML TRQL 20 ERRL DA37L DA36L 21 DA35L DA34L DA33L 22 DA32L DA31L DA30L 23 DA27L DA26L DA25L 24 DA24L DA23L DA22L 25 DA21L DA20L DA17L 26 DA16L DA15L DA14L 27 DA13L DA12L DA11L 28 DA10L DA07L DA06L 29 DA05L DA04L DA03L 30 DA02L DA01L DA00L 31 -5V -5V -5V 32 +5V +5V +5V @End(FileExample) @SubSection(Signal Descriptions) @IndexSecondary(Primary="EUSCD System bus", Secondary="Signal descriptions") @IndexSecondary(Primary="EUSCD System bus", Secondary="Unused pins") @Paragraph(Unused pins) Pins 16b and 19b are unused and reserved. Under NO circumstance should these pins be used. @IndexSecondary(Primary="EUSCD System bus", Secondary="Power supplies") @Paragraph(Power supplies) @Begin(FileExample, Group) GND Common signal and supply ground. +12V Positive 12 volt supply. -12V Negative 12 Volt supply. +5V Positive 5 Volt supply. -5V Negative 5 Volt supply. @End(FileExample) @Paragraph(Bus signals) @IndexSecondary(Primary="EUSCD System bus", Secondary="Signals") All bus signals are considered active low TTL level signals. Thus we define the Asserted (Ass) state to be <=0.8V and the Negated (Neg) state to be >=2.0V. The signal type specifies whether the signal driver is a TTL totem pole output (ttl), a TTL open collector output (o/c) or a TTL three state output (3-s). We do not specify the significance of assertion or negation of Address and Data signals on the bus. This will be dermined by mutual aggrement of the masters and slaves in any given system. However all simple memory devices MUST present read data in the SAME state as it was written. By convention the address selection logic will assume TTL low on the bus to be binary 1 and TTL high on the bus to be binary 0, with AD2L the least significant bit and AD31L the most significant bit. In general, module address recognition logic will not decode more than the 16 most significant address lines. @Begin(FileExample, LeftMargin +0) @b(Signal Type Driver Validity Description) @IndexSecondary(Primary="EUSCD System bus", Secondary="BRQiL") BRQiL ttl Masters always Bus request from master to arbiter. Asserted whenever master wishes to NOT BUSSED use the bus and for the period ---------- while the master has control of the bus. @IndexSecondary(Primary="EUSCD System bus", Secondary="BGRiL") BGRiL ttl Controller always Bus grant from arbiter to master. Asserted whenever master has NOT BUSSED requested and been granted use ---------- of the bus. @IndexSecondary(Primary="EUSCD System bus", Secondary="CBRL") CBRL o/c Masters always Common bus request. Asserted whenever a master has requested but not yet been granted use of the bus. This indicates to the current bus master that other potential masters are requesting the bus. @IndexSecondary(Primary="EUSCD System bus", Secondary="TRQL") TRQL o/c Masters always Asserted by the master in control of the bus when a transfer is required. This must occur only after AD2L-AD31L, R/WL, CO0L-CO4L and possibly DA00L-DA37L are valid and stable. It is negated only after these signals are deselected in response to TACL being asserted. @IndexSecondary(Primary="EUSCD System bus", Secondary="ATML") ATML o/c Masters always Asserted by the master in control of the bus at the begining of a set of indivisable transfers. Is negated only when TRQL is negated on the last transfer in the atomic set. The set may consist of a single transfer. @IndexSecondary(Primary="EUSCD System bus", Secondary="R/WL") R/WL 3-s Masters TRQL Ass Read/write line. Determines the TACL Neg direction of transfer on the bus. When asserted the direction is from Master to Slave. When negated is from Slave to Master. @IndexSecondary(Primary="EUSCD System bus", Secondary="AD2L-AD31L") AD2L - 3-s Masters TRQL Ass Word address signals. AD31L TACL Neg AD2L is the least significant line. @IndexSecondary(Primary="EUSCD System bus", Secondary="CO0L-C03L") CO0L - 3-s Masters TRQL Ass Byte strobes. Determines which CO3L TACL Neg data bus bytes are active in a transfer. Used as follows : If CO0L asserted then DA00L-DA07L are active. If CO1L asserted then DA10L-DA17L are active. If CO2L asserted then DA20L-DA27L are active. If CO3L asserted then DA30L-DA37L are active. Otherwise the corresponding data lines are held in the high impedance state and take no part in the transfer. @IndexSecondary(Primary="EUSCD System bus", Secondary="TACL") TACL o/c Slaves Always Asserted by the slave addressed in a transfer once the transfer is complete. This must occur only after ERRL and possibly DA00L-DA37L are valid and stable. It is negated only after these signals are deselected in response to TRQL being negated. Controller In the event of no slave asserting TACL within 2000ns of TRQL being asserted the controller will assert both TACL and ERRL to unsuccessfully terminate the reqested transfer. @IndexSecondary(Primary="EUSCD System bus", Secondary="ERRL") ERRL o/c Slaves TRQL Ass Slave error response. TACL Ass Asserted if the slave cannot succesfully completed the transfer. Controller In the event of no slave asserting TACL within 2000ns of TRQL being asserted the controller will assert both ERRL and TACL to unsuccesfully terminate the requested transfer. @IndexSecondary(Primary="EUSCD System bus", Secondary="DA00L-DA07L") DA00L - 3-s Masters TRQL Ass 0 address byte data signals. DA07L (R/WL Ass) TACL Neg AD07L is the least significant CO0L Ass line. Slaves TRQL Ass (R/WL Neg) TACL Ass CO0L Ass ERRL Neg @IndexSecondary(Primary="EUSCD System bus", Secondary="DA1OL-DA17L") DA10L - 3-s Masters TRQL Ass 1 address byte data signals. DA17L (R/WL Ass) TACL Neg CO1L Ass Slaves TRQL Ass (R/WL Neg) TACL Ass CO1L Ass ERRL Neg @IndexSecondary(Primary="EUSCD System bus", Secondary="DA20L-DA37L") DA20L - 3-s Masters TRQL Ass 2 address byte data signals. DA37L (R/WL Ass) TACL Neg CO2L Ass Slaves TRQL Ass (R/WL Neg) TACL Ass CO2L Ass ERRL Neg @IndexSecondary(Primary="EUSCD System bus", Secondary="DA30L-DA37L") DA30L - 3-s Masters TRQL Ass 3 address byte data signals. DA37L (R/WL Ass) TACL Neg CO3L Ass Slaves TRQL Ass (R/WL Neg) TACL Ass CO3L Ass ERRL Neg @IndexSecondary(Primary="EUSCD System bus", Secondary="RSTL") RSTL ttl Controller Always System reset. Forces all devices into a known initial state. @IndexSecondary(Primary="EUSCD System bus", Secondary="MCLK") MCLK ttl Controller Always Mains derived 100Hz clock. A train of 1ms wide low going pulses within 1ms of the zero crossing of the AC mains. @IndexSecondary(Primary="EUSCD System bus", Secondary="PFLL") PFLL ttl Controller Always Mains supply failure. DC supplies should be stable while this signal is negated and for at least 5ms after the assertion of this signal. @End(FileExample) @SubSection(Bus Protocol) @IndexSecondary(Primary="EUSCD System bus", Secondary="Protocol") A master wishing to perform an exchange of data on the bus must proceed in two stages. Firstly it must aquire control of the bus, before secondly requesting a transfer and acknowledging the slaves response. The protocol involved in both of these steps is given below. @Paragraph(Bus Aquisition Protocol) @Begin(FileExample, LeftMargin +0) @b(Step Controller Action Master i Action) 1 Wait until BGRiL negated. Asserr BRQiL. Assert CBRL. 2 Wait until it is Master i's turn to control the bus and previous master j has negated BRQjL. Negate BGRjL. Assert BGRiL. 3 Note Assertion of BGRiL. Negate CBRL. 4 Perform one or more bus transfers according to the protocol below. If CBRL is asserted relinquish control of the bus as soon as possible. 5 Negate BRQiL. @End(FileExample) @NewPage @Paragraph(Bus Transfer Protocol) @IndexSecondary(Primary="EUSCD System bus", Secondary="Transfer protocol") @Begin(FileExample, LeftMargin +0) @b(step Current Master Action Slaves and Controller Action) 1 Wait until TACL negated. 2 Drive AD2L-AD31L, R/WL and CO0L-CO3L. If R/WL is asserted then drive DA00L-DA37L as specified by CO0L-CO3L. 3 Assert TRQL. 4 Note TRQL asserted. Wait 25ns. 5 Decode AD2L-AD31L to see if selected If selected then proceed otherwise wait until TRQL negated. If operation cannot be performed succesfully then assert ERRL, otherwise If R/WL is asserted then accept data on DA00L-DA37L as specified by CO0L-CO3L, otherwise present data on DA00L-DA37L as specified by CO0L-CO3L. 6 Assert TACL. If TACL not asserted by any slave within 200ns of TRQL asserted then the Controller asserts TACL and ERRL. 7 Note TACL asserted. Wait 25ns. 8 If ERRL asserted then note that transfer failed, otherwise If R/WL negated then accept data on DA00L-DA37L as specified by CO0L-CO3L. Remove AD2-AD31L, R/WL and CO0L-CO3L. If R/WL was asserted then remove DA00L-DA37L as specified by CO0L-CO3L. 9 Negate TRQL. 10 Note TRQL negated. 11 Negate ERRL. If R/WL was negated then remove DA00L-DA37L. 12 Negate TACL. @End(FileExample) @NewPage @SeeAlso(Primary="EUSCD Ethernet",Other="EUSCD Ether") @SeeAlso(Primary="ETHERNET",Other="EUSCD Ether") @SeeAlso(Primary="Ether",Other="EUSCD Ether") @Index(EUSCD Ether) @Section(EUSCD Ether) @IndexSecondary(Primary="EUSCD Ether", Secondary="CLIENT") @IndexSecondary(Primary="EUSCD Ether", Secondary="PORT") @IndexSecondary(Primary="EUSCD Ether", Secondary="PACKET") @IndexSecondary(Primary="EUSCD Ether", Secondary="STATION") @SubSection(CLIENT, STATION, PACKET, PORT) Ether "Stations" are devices connected to "Clients" (computers). It is the job of stations to forward messages across the ether between and on behalf of clients or processes within clients. Physically, messages are transmitted in "packets" which consist of a 15-byte header, the data part containing the actual message (up to 532 bytes) and a 4-byte trailer. Client software has very little control over the actual scheduling of transmissions, or of what exactly goes into the header and trailer. These details are left up to "firmware" running within the station. The interface presented to the client is of a number (32) of "ports" which are endpoints of transmissions. These ports are addressable objects, each having a six-byte address. Within the EUCSD ether, the first address byte (usually) uniquely identifies a station, the second byte (usually) identifies a port within a station, and the remaining four bytes must all be zero. Client software treats ports number 1 to 31 of its station as independent general-purpose bi-directional streams through which messages of between 0 and 532 bytes in length may be sent or received. Port number 0 is rather more special-purpose and is discussed later. The services offered by the station fall into one of three categories: Connection, Datagram and Broadcast. @IndexSecondary(Primary="EUSCD Ether", Secondary="CONNECTION") @SubSection(Connection) The virtual connection provides a reliable bi-directional link between a port in one station and a port in another station. The connection is reliable in the sense that the station deals with any requirement for re-transmitting packets which have collided or have been lost for some other reason (usually congestion at the destination station). Packets are guaranteed to arrive at their destination in the same order in which they were transmitted and receiving stations guarantee to suppress the forwarding of duplicated packets. The transmitting client is notified when a packet just sent has been accepted by the receiving station (not the receiving client). Alternatively, when the transmitting station reckons that further retransmissions due to absence of acknowledgements would be futile, the transmitting client is notified of the transmission failure. Transmissions of datagrams and broadcasts are not reliable in the sense that connections are; packets merely arrive at their destination with a high probability and are duplicated with low probability. In a virtual connection there is always a unique "other end" associated with each end-point (port). So there is the concept of a port being "closed", i.e. having no other end associated with it, or "open to station S port P", i.e. having a particular endpoint associated with it. A port which is closed will not accept any packets addressed to it, and a port which is open will only accept packets coming from the particular other end in which it is interested. Once various bits of software running in different clients have established that they wish to communicate they would normally seek to establish a reliable connection by agreeing which of their respective ports to open. Such agreement can be established by the programmer beforehand, if he knows which physical machines are going to be involved. For example, this approach, rather inelegant but dictated at the time for various reasons, is taken in the way the APM talk to the 1976 Departmental filestore. The machines know that the filestore has address 16_70, the filestore knows that the APMs have addresses in the range 16_11 to 16_2F, so the filestore starts up by opening its port I to machine 16_10+I, port F, for I between 1 and 16_1F, and each APM (with address J) opens its port F to machine 16_70, port J-16_10. @IndexSecondary(Primary="EUSCD Ether", Secondary="DATAGRAM") @SubSection(Datagram) The datagram is a message sent through port 0 of any machine. Port 0 is in a sense deemed permanently open to any other end, and so always accepts any packet addressed to it. Because there is no permanent remote address information associated with port 0, any message sent through port 0 must be prefixed by six address bytes, i.e. the first six bytes of a message (which must be between 6 and 538 bytes in length) are interpreted by the station as a destination address, and any message received through port 0 will have the six-byte source address prefixed to it by the station. This allows receiving clients to determine where the datagram came from and transmitting clients to instruct the station where a message is to go to. For example, the 1982 mini-filestore and the 1983 replacement filestore use datagrams from a prospective customer machine to the filestore (the station address of which is known to the prospective customer) to convey a request to establish a connection. The filestore responds with a datagram saying which port it has allocated, and opened, to the prospective customer. @IndexSecondary(Primary="EUSCD Ether", Secondary="BROADCAST") @SubSection(Broadcast) The broadcast is a message sent to (port 0 of) all machines on the ether. Address filtering hardware in the ether receiver of every station makes the station deaf to all packets other than those which are either addressed specifically to that station (the first byte of the header is in fact the destination station address), or else addressed to pseudo-station number 0 (deemed the broadcast address). Since packets are always addressed to a remote object (port) with a six-byte (effectively two-byte) address, and the first byte being zero designates a broadcast, and since broadcasts are always accepted by port zero, the meaning of the second address byte of a broadcast message cannot be a port number. Instead it is taken to be a notional broadcast "channel" number. Receiving stations may be configured to tune in to all, no, or an arbitrary selection of these broadcast channels, currently numbered 0 to 63. Broadcasts are sent in the same way as datagrams, i.e. if they are sent through port 0 they are prefixed by the six-byte address in which the pseudo station number is zero and the pseudo port number is the channel number, if they are sent through a non-zero port then that port must have been opened to remote "station" zero and "port" . Reception of broadcasts, however, is different from datagrams in that, though they both come through port 0, there must be some way of deciding whether an incoming packet was a datagram or a broadcast. Since of the six-byte prefix the first is the source station address and must hence be non-zero, a broadcast is further prefixed by two bytes of which the first is zero and the second is the channel number. In other words, a datagram is prefixed by the six bytes , , , and a broadcast is prefixed by the eight bytes , , , , . For example, where a particular service (such as the CS4 X25 exercise "other end" machine) is provided by software running in some machine on the ether, but where it is not known in which particular machine that software happens to be running, it would be appropriate to allocate (a priori) a broadcast channel number to that service, and to expect customer machines to broadcast on that channel to establish communication with the server. Once the server responds, the customer will know which machine the server is running in and subsequent communication may be by datagrams or virtual connections. @SubSection(Ethers, ECMA and ISO)@Index(ECMA)@Index(ISO)@Index(Ether) This section is intended to provide a moderately readable resume of the European Computer Manufacturers Association (ECMA) protocols for use on Ethers. The information is taken from the standards documents ECMA -72, -80, -81, -82 and TR/14. Terminology is less formally correct than that employed in the protocol standards so defined acronyms and page references are included in the text to provide points of contact between the two descriptions. Extensions to the protocols are not discussed and neither are variants such as ECMA-72 classes 0-3 which are unlikely to be used here. A comparison is made with the EUCSD ether protocols. @Paragraph(Terminology) The term Ether is used loosely here to refer to those networks including CSMA/CD baseband local area networks over which the ECMA protocols may be used. Apologies to the Xerox Corporation. The term "service" is used to describe the upper interface to a protocol layer, thus the transport layer provides a transport service to the client and so on. @Paragraph(Protocol layer Model) The ECMA protocol layers follow the ISO Open Systems Interconnection model. Working up from the electrical level these are: @Begin(Description, LeftMargin 20, Indent -20) @IndexSecondary(Primary="ECMA", Secondary="Physical medium") Physical Medium @\(Coaxial Cable System) This is covered by ECMA-80 and covers items such as the cable diameter, attenuation, distortion etc. @IndexSecondary(Primary="ECMA", Secondary="Physical layer") Physical Layer @\This is covered by ECMA-81 and covers the attributes to do with bit transmission. The Medium must be driven at 10 MHz using Manchester Phase Encoding. @IndexSecondary(Primary="ECMA", Secondary="Data link layer") Data Link layer @\This is covered by ECMA-82 and describes the procedures for sending data packets between stations on the same Ether. This layer is described in more detail below. @IndexSecondary(Primary="ECMA", Secondary="Network layer") Network layer @\This layer has not yet been defined but covers transmission of datagrams between stations not necessarily on the same Ether. It includes specifications of an internet datagram and routing function. This layer is currently represented by a single byte with value 0 in transport layer packets. @IndexSecondary(Primary="ECMA", Secondary="Tranport layer") Transport layer @\This layer is described by ECMA-72 and covers transmission of data over virtual circuits (connections) between endpoints over an arbitrary number of intermediate networks. It includes error recovery and flow control procedures and allows multiplexing (of what is not yet clear). This layer is described in detail below. It provides a transparent, error-free, network independant end-to-end data path between clients. @End(Description) @Paragraph(Architectural Overview) These protocol layers fit together thus @IndexSecondary(Primary="ECMA", Secondary="Protocol layers") @Begin(FileExample) --------------- Transport Service Transport Layer --------------- Network Service Network Layer --------------- Link Service Data Link Layer --------------- Physical Layer --------------- Physical Medium @End(FileExample) Each layer is managed by an entity which may be thought of as carrying on a dialogue with its opposite number at some other communicating device using the services of the layers below. As we climb up the hierarchy, the dialogues occur between progressively further and further separated entities. The data link layers talk between stations on the one Ether, Network layers talk between stations on different networks and transport layers talk between endpoints, thus @Begin(FileExample, LeftMargin +2) |TL1|-----------------------------------------------------------|TL2| ---- ----- |NL1|---------------------|NL2| |NL3|---------------------------|NL4| ----- ----- ----- ----- |DL1|----|DL2| |DL3|------|DL4| |DL5|-----------|DL6| |DL7|-----|DL8| Endpoint Gateway Gateway Gateway Endpoint 1 1 2 3 2 @End(FileExample) The dialogue consists of an exchange of Protocol Data Units (PDUs) which will occur as a result of or will result in an exchange of service primitives ("Service Data Units" or SDUs) with the layer above. It is perhaps useful to think of SDUs as moving up and down across the protocol boundaries (Services) within one host and PDUs as moving across between pairs of entities in different hosts. @IndexSecondary(Primary="ECMA", Secondary="Protocol hierarchy") The protocol hierarchy is discussed in ECMA TR/14 as is "Protocol Set 1" which defines a set of parameter limits to be imposed on the ECMA protocols to guarantee open interconnection of different manufacturers' hosts on different networks. It is this protocol set which imposes the 527 byte limit on transport service packets. @NewPage @IndexSecondary(Primary="ECMA", Secondary="Protocol layers") @Paragraph(The Protocol Layers) @b(Data Link Layer) @IndexSecondary(Primary="ECMA", Secondary="Data link layer") This layer sends point-to-point or multicast datagrams between stations on one ether. This is achieved by use of the L-DATA Request and L-DATA Indication primitives which are sent between the Link and Network layers. @Begin(FileExample) L-DATA Indication L-DATA Request ^ | | | Network | | Layer | | -----------|-------------------------|------- Link | | Layer | V LLCDU LLCDU --------------------------------------------- @End(FileExample) Each L-DATA packet (-Request and -Indication) has the form @Begin(FileExample, LeftMargin +0) 8/7 1 6 6 2 1 1 1 n q 4 1 ------------------------------------------------------------------- |Pre- |Start of |Dest |Source | L |Dest |Srce |Ctrl|Data|Pad|FCS|E| |amble|Inf. Fld.|DTE | DTE | |LSAP |LSAP.| | | | | | ------------------------------------------------------------------- |----------------- LPDU = Physical Frame -------------------------| |-------------------- MADU ---------------------| |----------- LLCDU -------| @End(FileExample) where the figures along the top are field widths in bytes. The terms MADU and LLCDU refer to areas of the packet defined in terms of a link sublayer and will not be discussed further here. @Begin(Itemize) The Preamble consists of the bit sequence 10101.. (16_AA) repeated for 8 characters (ECMA) or 7 (ISO). The Start of Information field is the character 16_AB. The source and destination DTE fields are 48 bits wide. The top bit determines whether the address is individual (0) or multicast (1) and the next bit whether the other 46 bits represent an address unique to the world (0) or purely local (1). The other uses of these fields is not entirely clear. The LLCDU octet count L gives the number of bytes in the LLCDU part of the block. DEC and ECMA differ over the definition of this field (DEC use it for a a protocol identifier a' la Blue Book and a clash exists. The Source and Destination service (LSAP) fields are 8 bits wide and are used to address individual services at a station (A concept similar to the EUCSD port number). The first bit indicates an individual service (0) or a group (1). The following bits contain the specified group except for the value 16_FF which indicates a broadcast to all services. The ISO spec. attaches special significance to LSAP = 16_00, 16_40 & 16_C0 The control field is one octet. For Datagrams this takes the value 16_C3. The frame may contain between 0 and 1497 data bytes (n) of user data. q Pad bytes are appended to the user data to bring the minimum MADU size up to 64 bytes. Q is thus between 0 and 43. The MADU must not exceed 1518 bytes. @End(Itemize) @IndexSecondary(Primary="ECMA", Secondary="Procedural considerations") @b(Procedural considerations) The link layer is responsible for detecting collisions and for backing off and retrying. @IndexSecondary(Primary="ECMA", Secondary="Transport layer") @b(Transport Layer) The first thing to note about the Transport Layer is that it is bound in with Connections (Virtual Circuits). The connectionless Transport layer is for further study, thus if you want connections over the Ether you must go to Transport Layer and if you go to Transport Layer you must have connections. Protocol set 1 requires the use of ECMA-72 Class 4 which is what is described here. This layer provides an error free, network independant etc. end-to-end data path between clients. It does this by use of the following primitives and Transport PDUs @Begin(FileExample) @b(Transport Service Primitives Associated T-PDUs) T-CONNECT request/indication CR (Connect Request) T-CONNECT response/confirmation CC (Connect Confirm) T-DATA Request/Indication DT (Data) AK (Acknowledgement) T-EXPEDITED DATA request/indication ED (Expedited Data) EA (Expedited Ack.) T-DISCONNECT request/indication DR (Disconnect Request) DC (Disconnect Confirm) ERR (Error) @End(FileExample) @Begin(Group) Examples of procedures: @IndexSecondary(Primary="ECMA", Secondary="Connection establishement") @b(Connection Establishment:) @Begin(FileExample, LeftMargin +0) @b(Transport Service Connection . Transport Service Connection) @b( Initiated by remote Client . Initiated by local Client) T-CONNECT T-CONNECT . T-CONNECT T-CONNECT Indication Response . Request Confirmation ^ | . | ^ | | . | | Client | | . | | --------|---------------|-------.-------|---------------|-Transport Transprt| | . | | Service Layer | V . V | | ^ | . | -------- | | . | ^ | | V . V | | Incoming Connection . Connection Incoming V Connection Confirm . Request Connection (DT) or Request (CC) . (CR) Confirm (AK) or (CR) (CC) (ED) ----------------------------------------------------------------- @End(FileExample)@End(Group) @IndexSecondary(Primary="ECMA", Secondary="Connection termination") @b(Connection Termination) Procedures for connection termination are similar to those of connection establishment. Either client may terminate the connection by sending a T-DISCONNECT request which appears at the far end as a T-DISCONNECT indication. It is not clear whether these are handshaked but the implication is that they are not. @Begin(FileExample, LeftMargin +0, Group) @b(Connection Termination . Connection Termination) @b( by remote client . by local client) T-DISCONNECT . T-DISCONNECT Indication . Request ^ . | | . | --------------|------------------.----------|---------------- | . | | . V ------------------- . | ^ | . | ^ | V . V | Disconnect Disconnect . Disconnect Disconnect Request Confirm . Request Confirm (DR) (DC) . (DR) (DC) . @End(FileExample) A disconnect request may be taken as a disconnect confirm if requests cross over. Similarily a disconnect request may appear as the reply to an unsuccessful connection attempt. @IndexSecondary(Primary="ECMA", Secondary="Data transfer") @b(Data Transfer) Data transfer may begin once the connection is fully established. Data packets (DT T-PDUs) carry sequence numbers modulo 128 which may generate positive acknowledgements (AKs). These carry the sequence number of the next expected frame (a la X25) but also a credit count which represents the number of frames the receiver is willing to accept (Maximum 1). AKs may be sent out at any time provided the sequence number is valid and will be used to dynamically adjust the credit limit and expected sequence number. PDU sizes are chosen such that packets need not be broken up and reassembled by any intermediate entities. The EOT bit is thus not used. @IndexSecondary(Primary="ECMA", Secondary="Error recovery") @b(Error Recovery) A Reject (RJ) T-PDU is defined but is not used in this class of ECMA-72. Instead, a number of counters and timeout intervals are negotiated at connect establishment. These define a maximum lifetime for a datagram in the network as a function of the maximum allowed delay between a packet and its response and the maximum allowed number of times a lost (non-AKed) packet will be retransmitted. Error recovery consists of rebroadcasting lost packets till they are AKed or the sender gives up and of discarding but AKing duplicate packets received. This is very similar to the EUCSD approach but contains a more complex parameter negotiation. @Begin(Group) @Begin(FileExample,LeftMargin +0) @IndexSecondary(Primary="ECMA", Secondary="Packet formats") @b(Packet Formats) 1 1 2 2 1 v n -------------------------------------------------------- Connect |Hdr. | 1110 . CDT | 0 | Source | Class |Var | User | Request |Lgth | (CR) . | | Ref. | Opt. |Part | Data | -------------------------------------------------------- -------------------------------------------------------- Connect |Hdr. | 1101 . CDT |Dest.| Source | Class |Var | User | Confirm |Lgth | (CC) . |Ref. | Ref. | Opt. |Part | Data | -------------------------------------------------------- -------------------------------------------------------- Disconnect |Hdr. | 1000 . 0000|Dest.| Source |Reason |Var | User | Request |Lgth | (DR) |Ref. | Ref. | |Part | Data | -------------------------------------------------------- 1 1 2 2 v -------------------------------------------- Disconnect | Hdr. | 1100 . 0000| Dest.| Source | Var | Confirm | Lgth | (DC) | Ref. | Ref. | Part | -------------------------------------------- 1 1 2 1 v n --------------------------------------------------- Data | Hdr. | 1111 . 0000| Dest.|E. TPDU | Var | User | | Lgth | (DT) | Ref. | . NR | Part | Data | --------------------------------------------------- --------------------------------------------------- Expedited | Hdr. | 0001 . 0000| Dest.|1.EDTPDU| Var | User | Data | Lgth | (ED) | Ref. | . NR | Part | Data | --------------------------------------------------- -------------------------------------------- Data | Hdr. | 0110 . CDT | Dest.|0. YR-TU| Var | Acknowledg | Lgth | (AK) . | Ref. | . NR | Part | -------------------------------------------- -------------------------------------------- Expedited | Hdr. | 0010 . 0000| Dest.|0. YR-TU| Var | Data Acknow. | Lgth | (EA) | Ref. | . NR | Part | -------------------------------------------- -------------------------------------------- Reject | Hdr. | 0101 . CDT | Dest.|0. YR-TU| Var | | Lgth | (RJ) . | Ref. | . NR | Part | -------------------------------------------- 1 1 2 1 1 -------------------------------------------- TPDU Error | Hdr. | 0111 . 0000| Dest.| Reject | Param| | Lgth | (ERR) | Ref. | Cause | | -------------------------------------------- @End(FileExample) @End(Group) @b(Fixed Part Fields) @Begin(Description) Header Length @\The header length contains the length of the fixed-length fields plus the variable part and excluding itself. Header Length for the Data packet is thus 1+2+1+v. TPDU code @\The next byte is the TPDU code and includes the credit count CDT for some frame codes. Class field @\ Bits 8-5 contain the Class number and certain option bits. This field should take the value 16_40 for standard class 4. Reject Cause @\This octet gives the transport service disconnection reason. @End(Description) @b(Variable Part Fields) If present these define one or more optional parameters. Each parameter is of the form @Begin(FileExample, LeftMargin +8) 1 1 p ------------------------------------------- | Param Code | Param Length | Param Value | | | p | | ------------------------------------------- @End(FileExample) @Begin(FileExample, LeftMargin +0, Group) @b(Relevant Parameter codes and values) @b[ Code Length Value Applicable TPDU ] @b[ codes] 16_C1 p Calling TSAP Identifier CR 16_C2 p Called TSAP Identifier CR 16_C0 1 Log_2 TPDU size (octets) CR 16_80 2 Checksum All 16_C1? p Erroneous TPDU ERR @End(FileExample) @IndexSecondary(Primary="EUSCD Ether", Secondary="Protocol") @Paragraph(The EUCSD Ether protocol) The EUCSD Ether protocols were developed to run over the EUCSD 2MHz ether and are fully described in Enos's Thesis . They comprise two levels: A Datagram-based link layer and a minimal virtual circuit Transport Protocol. @IndexSecondary(Primary="EUSCD Ether", Secondary="Link layer") @b(The Link Layer) This performs the same function as the ECMA link layer and is supported by two primitives: DATA and ACK. DATA packets are sent out with a sequence number modulo 255 and are replied to by an ACK carrying the sequence number of the last frame received. Since the DATA and ACK packets differ only by one bit, all the receiver need do to ack a packet is flip the bit and return the packet sans data. @Begin(FileExample, LeftMargin +0) Each packet has the following form: 1 6 6 1 1 n 2 2 ------------------------------------------------------------------------ | * | Destination | Source | Type | Sequence | Data | Check | FCS | | | Address | Address| | No. | | Length| | ------------------------------------------------------------------------ @End(FileExample) The first byte of the destination address (*) is actually transmitted twice by the station hardware. The source and destination addresses are six bytes wide. The top byte contains the station number and the next byte the port number. The remaining 4 bytes are unused. Multicast packets are flagged by having a destination address of 0. The type field takes the value 16_01 for DATA and 16_81 for ACK packets. The Sequence number starts from 0 and runs modulo 255 but value 0 is not reused. Note that the format is completely different from ECMA-82 and that the two packets cannot coexist on the one Ether. @IndexSecondary(Primary="EUSCD Ether", Secondary="Transport layer") @b(Transport Layer) The EUCSD protocol allows establishment and termination of virtual circuits through the CONNECT and DISCONNECT primitives. @SubSection(Summary of the Installation Criteria for Ether Coaxial Cable) @IndexSecondary(Primary="EUSCD Ether", Secondary="Installation") @Begin(Enumerate) Maximum cable segment length is 500 metres using a single production batch of cable. If a mixtue of batches is used the maximum length will be 491.4m (see below). Where possible, a continuous run of cable from a single production batch should be installed. Where this is impractical different batches may be connected provided that only approved lengths from each batch are used. These lengths are 23.4 metres, 70.2 metres and 117 metres. Any combination of these lengths may be used provided total cable length does not exceed 491.4 metres. Transceivers may only be connected at the 2.5 metre makings on the cable. A maximum of 100 transceivers may be connected per 500 metre length. The cable screen must be earthed at a single point with a bonding section of at least 1.5 mm (square). Cable sections must be connected together using 'n' type connectors. All sections of cable must be terminated with MALE plugs and sections must be interconnected using FEMALE to FEMALE barrel connectors. All connectors must be protected from possible extraneous earth connections by an insulating boot. Transceivers make connection to the Ether cable in one of two ways: @Begin(Enumerate) Bee-sting connection. For this method a special jig and drill are required. Connection may be made whilst the Ether is live but care is needed to ensure correct functioning of the jig and drill. 'N' type connectors. To make this type of connection all power must be removed from the cable before it is cut and the connectors terminated. @End(Enumerate) Both ends of the total cable section must be terminated with a 50 ohm terminator. In addition to the above offficial requirements a number of points have come to light as a result of our experience or in discussion with other installers. @Begin(Enumerate) Where a length of cable has to be cut this should only be done at eiher a 2.5 metre marker or at one of the standard lenths. The lenth of installed cable from a single batch need not be of a standard length but accurate record keeping is essential. Additions to an existing section must be connected such tht the cable orientation remains the same (usually taken as direction of pull off the drum). If the added section is reversed a detectable discontinuity results which will degrade performance. Minimum bending radii for cable from different manufacturers may vary but for the BICC cable currently used by ERCC a minimum radius of 6 inches has been found (by TDR test) to be permissible. BICC claim that 2.4 inches is acceptable and will not damage the cable. On grounds of caution we have elected to bend the cable no more sharply than 6 inches. Record keeping. It is essential to know the following: @Begin(Enumerate) Which Ether you are dealing with (there may be more than one in some areas). How long the cable is. Whic batch or batches go to make it up and how long the sections are. For each batch of cable, what is the direction of installed cable. Number of transceivers connected. Location of single earth connection. Location of terminators. Location of any joints in the cable not associated with transceivers. @End(Enumerate) @End(Enumerate) @End(Enumerate) @NewPage @SeeAlso(Primary="Inter-filestore file transfer utility",Other="EFTP") @SeeAlso(Primary="File transfer",Other="EFTP") @SeeAlso(Primary="Transfer",Other="EFTP") @SeeAlso(Primary="File",Other="EFTP") @SeeAlso(Primary="Filestore",Other="EFTP") @Index(EFTP) @Section[INTER-FILESTORE FILE TRANSFER UTILITY (EFTP)] The APMs have no local disc storage. All APM files reside on one of a small number of dedicated file stores which are accessed through the 2MHz departmental Ether. APMs "Connect" to the filestores then access files as required, either by explicit reference to the file name by the user or by implicit reference by the system dictionaries. Files may be "remembered" i.e. cached in store if necessary. Some files may require user-specific access permissions before they can be read or altered. This is achieved by the user Logging on to a filestore directory (at which point he may claim total control over its files) and maybe quoting the password of another directory in order to claim control over its files. A user therefore accesses the file stores on three levels. In the simplest case: @Begin(Enumerate) His APM establishes a connection to the required filestore. Within this connection (it may last for days) he may log off and on to various directories. Within each logged-on session he may move files around. @End(Enumerate) A connection is completely described by the Ether Station (DTE) addresses and ports (LSAPs) of the two ends. The DTE addresses are permanently assigned to the stations and the LSAPs are negotiated during the connection setup procedure. The APM needs to establish a connection in order to bootstrap itself so the DTE address of a preferred filestore is held in the ROM of each APM. This connection is referred to as the default connection. The LSAP at the filestore end is sometimes referred to as the "Context". A Logged-on session is completely described by the connection and a filestore user number (UNO). The user issues a filestore Login primitive down the connection, quoting his username and password and receives back the UNO. If he is not logged on he may use UNO 0, permanently assigned to the mythical user ANON for those activities which do not require accrediting. A file access is described by the UNO and a file access transaction number or XNO. The user quotes the UNO in a filestore Open primitive and receives back the XNO. He then quotes the XNO while reading or writing to & from the file. @SubSection(EFTP : file transfer utility) @Label(EFTP) The EFTP program is used for inter-filestore transfer of files residing on the various filestores, including the departmental Vax, connected to the Ether. All commands may be abbreviated. Where a command takes several parameters, these are separated by spaces. File names conform to the following rules: If a name begins with `::`, then the part immediately following, up to but excluding the next `:`, which is discarded, denotes the NODE, i.e. the file server on which the file resides. The following node names are accepted (and may be abbreviated). Node names not found in the list are interpreted (in hex) directly as ether addresses. @Begin(FileExample) Vax 72 ECSVAX running a FS server process. Alpha 14 APM with 1Mb of memory and a 160 Mb disk. Bravo 15 APM with 1Mb of memory and a 300 Mb disk. Charlie 1B Portable 3F (the mini-filestore) @End(FileExample) The remainder of the filename is subject to system-dependent interpretation. It may or may not contain a (directory) pathname part. Wildcards are allowed in filenames, but not in pathnames or nodenames. @Begin(FileExample) Examples: ::vax:dra1:[bloggs.project]test.pas (Node=vax, directory=dra1:[bloggs.project], file=test.pas) ::70:fmacs:frame {Node=70, directory=fmacs, file=frame) @End(FileExample) @IndexSecondary(Primary="EFTP", Secondary="LOGIN") @Paragraph(EFTP: LOGIN) The Login command takes a single parameter, namely the username, which will usually be prefixed by a nodename. The password, if not supplied as an optional second parameter, is requested separately on the next line. It is only necessary to log in where public authority is insufficient to access the files you want. @Begin(FileExample) Examples: Login ::vax:cs4test Login ::15:public @End(FileExample) @IndexSecondary(Primary="EFTP", Secondary="TRANSFER") @Paragraph(EFTP: TRANSFER) The Transfer command takes two parameters, being the source and destination filenames. If a filename contains a node prefix but omits the directory part, the default directory will be determined by the file server on the basis of the username, if any, under which you have previously logged on, if at all, to that server. If the filename part is omitted in the destination, the same name as in the source is assumed. If the name part is omitted in the source, `*` is assumed. @Begin(FileExample) Examples: Transfer ::vax:opsys.asm ::charlie Transfer ::bravo:guest:xyz* ::vax:[xyz.test]* @End(FileExample) @IndexSecondary(Primary="EFTP", Secondary="COMPARE") @Paragraph(EFTP: COMPARE) The Compare command takes two parameters, being the names of two files to be compared. Default rules are as for Transfer. No details of differences are reported. Use this only to yield yes/no results. @IndexSecondary(Primary="EFTP", Secondary="BACKUP") @Paragraph(EFTP: BACKUP) The Backup command is like the Transfer command (qv), but takes an additional parameter, which is a date (form: DD/MM/YY HH.MM). It transfers only those source files younger than the specified date to the destination. Wildcards are mandatory. @IndexSecondary(Primary="EFTP", Secondary="EXIT") @Paragraph(EFTP: EXIT) The Exit command terminates the EFTP session, after logging you off and disconnecting you from all machines involved during the session, except the machine to which you were connected and logged on before running EFTP. @IndexSecondary(Primary="EFTP", Secondary="FILES") @Paragraph(EFTP: FILES) The Files command takes a wildcard file name parameter, and prints a list of all file names which match the parameter. @IndexSecondary(Primary="EFTP", Secondary="SOURCE") @IndexSecondary(Primary="EFTP", Secondary="DESTINATION") @Paragraph(EFTP: SOURCE, DESTINATION) The Source and Destination commands each take one parameter, which is used to fill in defaults for the Node, Directory, and File fields of filenames typed to all the other commands. @NewPage @Section(VAX ETHER LINK DRIVER) @Index(VAX Ether link driver) @IndexSecondary(Primary="Driver", Secondary="VAX Ether link driver") This driver allow VAX users to transmit and receive packets on the department's ether. Each station port is treated as an individual device (ELA0..ELA31), with multiplexing of the read and write requests to these devices being dealt with in the driver. Furthermore, the user is not required to have any knowledge of the protocol used to talk to the station, as this too is handled invisibly by the driver. Logical and physical I/O privileges are required by the user. The normal sequence of operations: @Begin(Enumerate) Allocate a unit (= port). Open it to a remote station. Conduct a dialogue with the remote station. Close the port. Deallocate the unit. @End(Enumerate) Port 0 will normally be allocated by a special process whose job it is to demultiplex incoming requests to server processes running on VAX. The following QIO functions are provided: @Begin(FileExample, LeftMargin +0) @b(Functions Parameters Description) @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_Create") IO_Create P1 = Remote station port Open a port to a remote P2 = Remote station Address station. @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_WriteEOF") IO_WriteEOF Close a port. @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_ReadLBlk") IO_ReadLBlk P1 = Address of buffer Read data from the ether. P2 = Length of buffer @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_ReadPBlk") IO_ReadPBlk P1 = Address of buffer Read data from the ether. P2 = Length of buffer @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_WriteLBlk") IO_WriteLBlk P1 = Address of buffer Write data to the ether. P2 = Length of buffer @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_WritePBlk") IO_WritePBlk P1 = Address of buffer Write data to the ether. P2 = Length of buffer @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_SenseMode") IO_SenseMode Obtain VAX station address. @IndexSecondary(Primary="VAX Ether link driver", Secondary="IO_SetMode") IO_SetMode P1 = Address of AST Enable/Disable attention (or 0, to diable ASTs) AST delivery on receipt P2 = AST parameter of an incoming packet. @End(FileExample) After the I/O request has completed the IOSB will contain a success code and the number of bytes transferred. In all cases, except for IO_SenseMode, the device dependent part of the IOSB will contain the unit (= port) number used for the operation. @IndexSecondary(Primary="VAX Ether link driver", Secondary="IOSB") The following completion codes are returned in the IOSB: @Begin(Description) @b(Code) @\@b(Meaning) @IndexSecondary(Primary="VAX Ether link driver", Secondary="SS_NORMAL") SS_NORMAL @\The I/O request has completed successfully. @IndexSecondary(Primary="VAX Ether link driver", Secondary="SS_BufferOvf") SS_BufferOvf @\The read I/O request has completed successfully, but the incoming packet was too long for the buffer supplied and has been truncated. @IndexSecondary(Primary="VAX Ether link driver", Secondary="SS_Abort") SS_Abort @\The I/O request which is currently active was cancelled. @IndexSecondary(Primary="VAX Ether link driver", Secondary="SS_Cancel") SS_Cancel @\The I/O request was cancelled before it reached the head of the device's queue. @IndexSecondary(Primary="VAX Ether link driver", Secondary="SS_Timeout") SS_Timeout @\The dialog between the driver and the station has timed out. This may be caused by trying to read a packet before one is available; otherwise it is indicative of a station or driver problem. @IndexSecondary(Primary="VAX Ether link driver", Secondary="SS_CtrlErr") SS_CtrlErr @\A protocol error has occurred in the dialogue between the driver and the station. This may be caused by attempting to read or write a packet using a port which has not been opened. @IndexSecondary(Primary="VAX Ether link driver", Secondary="SS_DevReqErr") SS_DevReqErr @\The packet was not acknowledged by the remote station. This may be caused by specifying an incorrect remote address, by problems at the remote machine or by ether problems. @End(Description) For the benefit of Imp programmers a package is available to sanitise the interface. The following external procedures are provided: @Begin(FileExample, LeftMargin +0) @IndexSecondary(Primary="VAX Ether link driver", Secondary="External procedures") @b(Type Name Function) ExtRout Ether Allocate Zero Allocate port zero. ExtRout Ether Free Port Close and deallocate a port. ExtRout Ether Free All Close and deallocate all ports owned by the process. ExtRout Ether Open Port Open a port to remote station remaddr port remport. The port being opened must previously have been allocated using one of the above procedures. ExtRout Ether Close Port Close a port. ExtRout Ether Transmit Block Send a buffer. The port must previously have been opened to a remote station. ExtFunc Ether Station Address Obtain the station address. ExtRout Ether enable AST Enable an attention AST to be triggered when a packet arrives for the specified port. @End(FileExample) In all cases error conditions are indicated by the Imp signalling mechanism, with @Begin(Itemize) event_event = 15, event_sub = the error status, event_extra = some additional information (usually the port number) and event_message = a textual indication of the error condition. @End(Itemize) These interface procedures are available by linking with *********. @NewPage @Section(SOFTWARE TOOLS) @Begin(comment) APM Note 3.5 18 Jun 84 jhb:chario.lay @End(Comment) @IndexSecondary(Primary="I/O", Secondary="Character") @SubSection(APM asynchronous character I/O to and from the local terminal) @Paragraph(Input) The APM operating system reads in characters by interrupt from a Motorola M6850 ACIA at locations 16_400C1 (control/status) and 16_400C3 (data). The ACIA interrupts through auto-vector 5 at location 16_40074 . The ACIA transmit and receive speed can be set using a 16-position switch on the processor board front edge. Allowed speeds are @IndexSecondary(Primary="I/O", Secondary="Allowed speed") @Begin(FileExample) 19k2, 9k6, 7k2, 4k8, 3k6, 2k4, 2k0, 1k8, 1k2, 600, 300, 150, 134.5, 110, 75, 50 baud for switch settings 16_0 - 16_F respectively. @End(FileExample) The recommended maximum speed is 9k6 baud, the Visual 200 Z80 processor may be unable to keep up if this is exceeded. The ACIA is set up with control = 16_11 (2 stop bits, 8 bits). Characters are then processed: @Begin(Enumerate) @Begin(Multiple) Non-control characters (ASCII value >= 16_20) are assembled into a 100-byte cyclic keyboard buffer starting at KBBEG. This is indexed by two absolute pointers: @IndexSecondary(Primary="I/O", Secondary="KBBEG") @IndexSecondary(Primary="I/O", Secondary="KBIN") @IndexSecondary(Primary="I/O", Secondary="KBEX") KBIN points to where the next character will be inserted . KBEX points to the next character to be removed from the buffer. The buffer is empty when KBIN = KBEX. @End(Multiple) Control characters (ASCII values 16_00 - 16_1F) are checked against the bitmap EXEMPT MASK. A 1 indicates an exempted control character which is to be treated as a normal ASCII character ( 1) above). Exempt mask defaults to 0. @IndexSecondary(Primary="I/O", Secondary="EXEMPT MASK") and are trapped and exchange values. Typing thus enters (=). @IndexSecondary(Primary="I/O", Secondary="DLE") DLE (Ctrl-P) is trapped. It is not stored in the keyboard buffer but the next character is read and exempted as in 2) above. @IndexSecondary(Primary="I/O", Secondary="DC1") DC1 (X-On or Ctrl-Q) and DC3 (X-Off or Ctrl-S) are trapped and switch output on and off respectively. @IndexSecondary(Primary="I/O", Secondary="EM") EM (Ctrl-Y) is trapped and causes an event 0, 1. @IndexSecondary(Primary="I/O", Secondary="DC4") DC4 (Ctrl-T) is trapped and causes the software front panel to be entered. @IndexSecondary(Primary="I/O", Secondary="SI") SI (Ctrl-O) is trapped and causes output to the terminal to be discarded until either SI is entered again or input is next requested. @End(Enumerate) @IndexSecondary(Primary="I/O", Secondary="BEL") The kernel will echo BEL (ASCII 7) to any attempt to enter a character when the keyboard buffer is full and to any non-exempted, non-trapped control character. @b(Reading Mechanisms) Characters may be read from the keyboard buffer by one of two basic mechanisms: @IndexSecondary(Primary="I/O", Secondary="READSYMBOL") @b[READSYMBOL] This causes symbols to be read from the keyboard buffer into a line buffer unless line reconstruction is suppressed (see SET TERMINAL MODE below) in which case symbols are read directly from the keyboard buffer. Line reconstruction is performed using the editing characters DEL and CAN (Ctrl-X). The entire line is made available to the program when a terminating key is typed. Terminators are , , EM (Ctrl-Y) and the escape sequences or ? . Escape sequences correspond to Visual 200 pre-programmed keypad and function key sequences and are never echoed. Other terminators will generally be echoed but this can be suppressed by SET TERMINAL MODE bit 1. All terminators are included in the data read by the program. BS () and NAK (Ctrl-U) are mapped onto CAN. SUB (Ctrl-Z) is mapped onto EM. HT (TAB or Ctrl-I) is mapped into two spaces. Event 9, 1 is signalled when EM is read from the line buffer. The line buffer is 96 bytes long, starts at LBEG and is indexed by absolute pointer LPOS. The buffer has three significant states: @Begin(FileExample) 1) LEND = LBEG; LPOS Undefined. - Line buffer is empty. 2) LBEG <= LPOS < LEND. - Line buffer contains data with some left still to read. 3) LBEG < LPOS = LEND. Line buffer is exhausted - all data has been read. @End(FileExample) READSYMBOL will suspend the program until a character is read. @IndexSecondary(Primary="I/O", Secondary="TESTSYMBOL") @b[TESTSYMBOL] This reads a character from the line buffer if present failing which the keyboard buffer is examined. If TESTSYMBOL finds a character in either buffer it will be returned via the result and the appropriate buffer pointer incremented. A -1 will be returned otherwise so the program never suspends. No line reconstruction will be performaed on characters read from the keyboard buffer but the character processing described in 1) - 8) above will be performed unless disabled using EXEMPT MASK. Note that characters following a command verb will remain in the line buffer and will be the first characters read on that stream unless they are first read in using PAM or CLI PARAM. @b(Derived I/O routines:) a) There are a large number of IMP I/O routines derived from READSYMBOL. The most important related routine is @IndexSecondary(Primary="I/O", Secondary="NEXTSYMBOL") @Begin(Description, LeftMargin 26, Indent -26) NEXTSYMBOL @\Returns the value of the next symbol in the line or keyboard buffers but doesn't advance the pointer. Suspends until a symbol is read. @End(Description) @IndexSecondary(Primary="I/O", Secondary="TESTSYMBOL") b) There are several routines related to TESTSYMBOL. @IndexSecondary(Primary="I/O", Secondary="PENDSYMBOL") @Begin(Description, LeftMargin 26, Indent -26) PENDSYMBOL @\Returns the value of the next symbol in the line or keyboard buffer if present and -1 otherwise. Program is not suspended. @IndexSecondary(Primary="I/O", Secondary="INPUT PENDING") INPUT PENDING @\Returns a count of the unread characters in line and keyboard buffers. @IndexSecondary(Primary="I/O", Secondary="PROBE SYMBOL") PROBE SYMBOL(character) @\Returns TRUE if the character is present in line or keyboard buffers, FALSE otherwise. @IndexSecondary(Primary="I/O", Secondary="CANCEL INPUT") CANCEL INPUT @\Discards all unread characters from line and keyboard buffers. @End(Description) @IndexSecondary(Primary="I/O", Secondary="Output") @Paragraph(Output) Characters are output as transmitted unless SI has been entered. An Event 0 is signalled when ETX (Ctrl-C) is inserted into the line buffer. By default, 22 lines will be output at which point output will be suspended until either @Begin(Enumerate) A DC1 (Ctrl-Q) is entered, in which case output will resume freely. The key is typed in which case one line is output and output is suspended again. The key is typed in which case 23 further lines are output and output is suspended again. @End(Enumerate) The default can be overridden by SET TERMINAL MODE bit 3. @Index(Terminal) @IndexSecondary(Primary="I/O", Secondary="Terminal characteristics") @b(Terminal characteristics: ) Normal VDU mode is character echo on, echo terminators, enable line buffering and halt output after one screenful of data (page mode). This can be altered using the IMP routine SET TERMINAL MODE. This takes a bitmap parameter with bits @Begin(FileExample) 0: 0 = normal echo 1 = suppress echo 1: 0 = normal echo 1 = suppress terminator echo 2: 0 = normal line buffering 1 = suppress line buffering 3: 0 = page-mode 1 = cancel page-mode @End(FileExample) Default value in all cases is 0. The ASCII character set is used throughout. All 8 bits are significant. Text characters are assumed to be generated with the parity bit (2^7) = 0. @Index(Terminal)@Index(Visual 200) @b(A note about Visual 200's ) The Visual 200 reference manual should be consulted for a definitive answer to any questions concerning the Visual 200 but the following information proved particularily difficult to extract. @b(Numeric Keypad) The keypad transmits the characters indicated on the keycaps until the sequence is received wherupon it transmits the following sequences @Begin(FileExample) Sequence ; < = ? <16_40 + > > resets the keypad for normal operation. @End(FileExample) The cursor arrows left, right, up, down, home transmit the sequences where is 16_68, 16_67, 16_65, 16_66, 16_72 respectively. @Begin(Comment) @b(References ) [1] APM 1.1: APM working notes [2] APM 1.5: Motorola M6840 PTM & M6850 ACIA specifications [2] APM 2.1: The Imp-77 Language [3] APM 3.6: i:chario.inc @End(Comment) @SubSection(Standard Video Terminal Interface) @Label(VTLI) The Video Terminal Interface is a software interface designed to make it possible to handle video terminals in a high-level and general-purpose fashion. The objective is to simplify the task of writing programs which make some use of the special capabilities of such terminals. The main aims the approach tries to achieve are: @Begin(Itemize) providing a high-level interface; masking differences among video terminals; adapting to differences in types of communication connection; providing the same interface on a number of operating systems; keeping the number of individual functions manageable. @End(Itemize) The extent to which these advantages are realised in practice depends quite heavily on the way in which the interface is implemented, and, in particular, the facilities which are available from different operating systems and communication networks. The scope of the specification has been deliberately restricted to a small set of primitives which match the hardware capability of a reasonable variety of conventional video terminals and which can be implemented fairly efficiently in terms of network and host resources. It is not intended as a basis for the kind of approach required on more advanced machines with general graphical facilities, where the user may assign arbitrary parts of the screen of a video device to inspect arbitrary data structures within processes in flexible and selectable ways, without requiring the programs being executed by these processes to make any special provision to enable such inspection. @Paragraph(Frames) The package interprets all video related operations in the context of a particular selected region of the screen termed a frame. The inclusion of multiple frames in the specification does not pre-suppose a full capability for window management in the implementation, but reflects the desirability in writing programs of avoiding the assumption that the whole screen is available, or that its dimensions are known. The package allows for the definition of a number of frames, in terms of position and size, and for the selection of one among those which have been defined as the current frame, that is, the one to be used in subsequent video operations until another is selected. Frame selection applies to both input and output. Each frame has an associated set of attributes and a current status. @Paragraph(Basic Operations) The package defines procedures to effect the following five basic video operations: @Begin(Enumerate) Set the cursor to a particular row and column within the frame Clear the whole of the current frame Clear from the current cursor position to the end of the current row Scroll (up or down) a group of rows within the frame Select video attributes (reverse, dimmed, etc) for subsequent operations using this frame @End(Enumerate) The implementation of the package has the task of giving effect to these operations on the particular terminal used, by means of the appropriate control sequences. User programs do not require to take account of the differences in these control sequences from terminal to terminal. The implementation is expected to optimise a number of the operations in appropriate circumstances. For example, it will be noted that there is no primitive to clear the whole screen, just to clear a frame. However, a frame may be co-extensive with the full screen, in which case clearing it is tantamount to clearing the screen, and the implementation may well use a hardware capability to achieve this. All implementations are expected to adopt delayed and optimised cursor movement strategies. However, it is recognised that it may be impossible or unsatisfactory to implement all of the operations in full generality in cases where the physical terminal lacks the necessary capability, and a soft emulation cannot reasonably be provided. For example, the scroll function is not guaranteed to be implemented in the case of terminals which do not support part-screen scrolling, or if the current frame does not extend across the whole screen. Full soft emulation requires that a complete screen image (at least) be maintained by software, and this may be too costly in space or time. Apart from the resource required, the effect achieved may not be a satisfactory substitute for the one desired, and it may be more sensible for application programs to take different courses of action in the light of the capability available. Accordingly, the interface defines a number of capability attributes for each frame, such as the ability to scroll, and programs may enquire about these on a dynamic basis. @Paragraph(Integration with General Input/Output) In addition to the explicit video handling procedures, the interface pre-supposes that ordinary input/output operations, carried out by means of standard language statements, are treated appropriately when they involve the video terminal. This avoids the need to define a complete set of additional transput statements (covering characters, integers, reals, strings, and so on) for this one device type, contrary to the general principle of device-independent I/O procedures. In a few cases, where it is impossible to integrate the video handling into the standard input/output, or to intercept the standard procedures, it may be necessary to introduce separate input/output routines, but this is distinctly second-rate. @Paragraph(Components of the Package) The package is most conveniently presented in terms of an external library of variables and procedures, so that the detailed definition is a set of data and procedural declarations. In the following sections, the system implementation language IMP is used for these declarations. When implemented for languages which lack the capability to have external references to data, it will be necessary to add further procedures instead. @Index(FRAMEINFO) @b[%recordformat FRAMEINFO(%byte TOP, ROWS, LEFT, COLS, ROW, COL, FUN, MODE)] This is used to characterise individual frames. The components TOP, ROWS, LEFT, and COLS define the size and position of the frame on the screen. @Begin(Description) TOP @\The absolute row number of the topmost row in the frame counting from zero at the top of the physical screen. ROWS @\The number of lines in the frame. LEFT @\The absolute column number of the leftmost column in the frame counting from zero at the left of the screen. COLS @\The number of columns across the frame. ROW, COL @\Identify the current position in the frame, with (0,0) corresponding to the top left corner of the frame. (Thus the absolute screen position is given by TOP+ROW and LEFT+COL). FUN @\Set of indicator flags specifying the functionality of the frame in terms of the pre-defined values REVERSE, INTENSE, BLINK, UNDERLINE, FULLSCROLL and ANYSCROLL. The first four of these indicate whether arbitrary characters in the frame may be written with the attribute indicated. The last two are concerned with the ability of the frame to perform a full scroll upwards and a scroll of an arbitrary group of adjacent rows within the frame either up or down. Scrolling is understood to imply a 'shift' operation with rows dropping irretrievably off one end and blank rows introduced at the other. In the absence of data storage associated with the frames, these flags simply reflect hardware capability. MODE @\Represents the currently active attribute selection, in terms of the pre-defined values REVERSE, INTENSE, BLINK, UNDERLINE, AUTOSCROLL and FREEZE. These apply to data transferred through the frame. The first four select the 'shade' to be used to write data to the screen; some 'best endeavour' action is taken for an attribute not specified in FUN. The flag AUTOSCROLL selects whether automatic scrolling of the frame is to take place when a newline is performed on the bottom line; this pre-supposes FULLSCROLL in FUN. The flag FREEZE determines whether output to the frame is to be suspended after reaching the bottom of the frame until the user un-freezes it by hitting a key on the keyboard. @End(Description) @b[%routine SET VIDEO MODE(%integer attributes)] @Index(SET VIDEO MODE) The procedure SET VIDEO MODE is used to establish the mode of operation which will apply to subsequent terminal input. The attributes are specified as the sum of the desired individual attribute mnemonics (since IMP lacks sets and enumerated types). The significance of the individual attributes is as follows: @Begin(FileExample) SINGLE single character input mode (no line buffering) CONTROLTERM treat any control character as terminator for input NOECHO disable automatic echoing of all input NODELECHO disable automatic treatment of DEL PASSDEL pass DEL through NOTERMECHO disable automatic echoing of input terminating character LEAVECONTROLS do not map all controls to NL (LF) LEAVERETURN do not map RETURN to NL (LF) LEAVELF do not map LF to RETURN SPECIALPAD put terminal in special pad mode @End(FileExample) In general, a call will be required to SET VIDEO MODE to initialise the video handling package and other facilities will not operate unless this is done. @b[%record VDU] and @b[%record WIN] These pre-defined frame records identify the full screen (VDU) and the currently selected frame (WIN) respectively. VDU_TOP is zero and VDU_ROWS gives the number of rows on the physical screen. VDU_LEFT is zero and VDU_COLS gives the number of columns on the physical screen. VDU_FUN defines the functionality of the actual terminal. For a typical terminal, VDU_ROWS would be 24 and VDU_COLS would be 80; VDU_FUN would surely include FULLSCROLL and might or might not include AUTOSCROLL. @b[%routine AT(%integer row, col)] @Index(AT) Sets the active position of the currently selected frame according to the parameters ROW and COL. This is not acted upon until data transfer (or CLEAR LINE) requires it; that is, this is simply an assignment to the ROW and COL components of the relevant record. @b[%routine GOTOXY(%integer col, row)] @Index(GOTOXY) This is a variant of AT for those who prefer to present the column (x co-ordinate) first. @b[%routine CLEAR FRAME] @Index(CLEAR FRAME) Causes the whole of the current frame to be cleared. The current position is not relevant and does not change. @b[%routine CLEAR LINE] @Index(CLEAR LINE) Causes the part of the row to the right of the current position to be cleared to blanks. The current position does not change. @b[%routine SCROLL(%integer first, last, n)] @Index(SCROLL) Performs a scroll of the group of rows within the current frame identified by FIRST and LAST. N specifies the number of scrolls; a negative value of N implies reverse scrolling. The current position is not relevant and does not change. @b[%routine SET MODE(%integer m)] @Index(SET MODE) Sets current frame scrolling mode (subset of NOSCROLL, FREEZE) @b[%routine SET SHADE(%integer s)] @Index(SET SHADE) Sets current frame 'shade' attributes (subset of INTENSE, REVERSE, UNDERLINE, BLINK) The following four procedures represent one approach to the management of multiple frames, in which the basic dimensions of a frame are established by imposing them on the currently selected frame, and non-current frames are held on a stack. This is not sufficiently general, and a more satisfactory approach would integrate frames with the standard mechanism for stream selection. @b[%routine SET FRAME(%integer top, rows, left, cols)] @Index(SET FRAME) Imposes the position and dimensions specified on the currently selected frame in place of its existing properties. @b[%routine PUSH FRAME] @Index(PUSH FRAME) @b[%routine POP FRAME] @Index(POP FRAME) @b[%routine SWOP FRAME] @Index(SWOP FRAME) These procedures allow the current frame to be saved on, restored from, and swopped to, a push-down stack. Current status is preserved along with the persistent attributes. @b[%routine DEFINE VIDEO(%integer CODE)] @Index(DEFINE VIDEO) This is an ad hoc procedure used in Edinburgh University implementations to define the terminal type being used. The procedure interprets the parameter CODE as a value in the ERCC enumeration of terminal types and uses it to set up information used by the package for driving the terminal. @Paragraph(Data output) In all cases in which output actually takes place, the cursor is first positioned at the corresponding screen position if it is not already there, and the appropriate shade is selected if it is not already selected. @Begin(Description, LeftMargin +8, Indent -8) 1. @\For a printing character (including space) not following ESC (Escape): 1.1 @\If the current position determined by ROW and COL lies within the frame, the character is output and COL is incremented by one. 1.2 @\If ROW is greater than or equal to ROWS, or COL is greater than or equal to COLS, the character is not output but COL is incremented (max 255). 2. @\For ESC and any single character immediately following ESC, the character is output but COL is not altered. 3. @\For any control character other than NL, RT and BS, the character is output but COL is not altered. 4. @\For RT, COL is set to zero. 5. @\For BS, COL is decremented by one unless it is zero. 6. @\For NL (newline): 6.1 @\If ROW lies within the current frame, the remainder of the row to the right of the current position is cleared. Then: 6.1.1 @\If not at the bottom of the frame (ROW not equal to ROWS-1), ROW is incremented by one and COL is set to zero 6.1.2 @\If at the bottom of the frame, a pause is induced if FREEZE is selected and a scroll is performed if AUTOSCROLL is selected (and scrolling is possible); ROW is not changed and COL is set to zero. 6.2 @\If ROW lies outside the current frame, no action is taken except that ROW is incremented by one (max 255) and COL is set to zero. 7. @\A character code in the range 128-255 designates a printing character from a special graphical set. It is recommended that the encoding of the low order 7 bits should be interpreted according to the systematic conventions for line-drawing and block-drawing characters found on the ICL KDS7632 terminal among others. Where possible, it should be mapped to the nearest equivalent on other terminals. The update action of paragraph 1 applies. @End(Description) Note that the treatment of RT and BS is included largely for pre-video programs; their effect should properly be achieved by a call on the routine AT. The treatment of ESC + one character is included to provide a defined effect in the case that video operations not supported by the package are achieved by explicit output of control sequences. @Paragraph(Data input) The SET VIDEO MODE procedure allows a number of different modes to be established for data input as a combination of individual attributes. Not all combinations are mutually compatible, and not all implementations will support all those that are. In principle, the effect on the screen and the current frame status of each input character should be nil if the character is not echoed and otherwise the same as the effect of outputting the same character through the output routines. There are certain difficulties even in the principle of this definition, there is an argument that a significant character should update frame status even if it is not echoed, for example. Implementation considerations also introduce compromises in practice. These arise from the fact that, particularly in a network environment, the total effect is achieved by operations which are distributed over a number of different processes and devices, and there may be compelling reasons for utilising the capabilities that are available from these even if they do not exactly match the defined functions. For these reasons, the description of treatment of input given below must be regarded as partial and indicative, rather than definitive. Three modes can be isolated as significant levels, likely to be available on most implementations: @Begin(Enumerate) TT mode: printing characters echoed and line-buffered up to RETURN as (only sensible) terminator -- terminator also echoed as newline; Screen mode: printing characters echoed and line-buffered up to any ASCII control character or control sequence as terminator -- terminator not echoed; Raw mode: single character non-echoed operation. @End(Enumerate) In terms of the package, the treatment of a request for character input is as follows: @Begin(Description, LeftMargin +5, Indent -5) 1. @\If no data is available, the cursor is positioned and shade selected as for output and a unit of input is obtained from the terminal (see above). Then (and otherwise) the next character from the available unit of input is extracted: 1.1 @\If the character is a printing character it is returned and COL is incremented by one (max 255). 1.2 @\If the character is a control character other than ESC, it is returned and COL is unchanged 1.3 @\If the character is ESC, a two or three character control sequence is assembled and encoded as a single character value in the range 128-255. These values have no meaning to the package and are not standardised. For a 2-character control sequence ESC K1, the value is K1+128; for a 3-character sequence ESC K1 K2 (K1='?' or 'O'), the value is (K2!!64)+128 ('!!' standing for exclusive or). This encoding distinguishes (a) all 2-character sequences and (b) all ANSII-standard 2- and 3-character sequences. @End(Description) @Paragraph(Prompts) It may be desirable to provide a mechanism which allows prompting for input, in the interests of compatibility with conventional sequential input. This is a standing order for output of a string, conditional upon input being derived interactively. It should not be conditional on whether the user has typed ahead or not, it being axiomatic for proper operation of screen-oriented transput that the correct (and deterministic) sequencing of input and output should be preserved. When the full potential of screen-oriented operation is being exploited, the concept of the iterated prompt becomes somewhat irrelevant. The 'memory' of visual cues is on the screen itself, to be selected by cursor positioning. @Paragraph(Cost) The code which requires to be added to the basic input/output run-time support system to provide the main features of the interface is of the order of one or two kilobytes, and, with care, it should be possible to make it acceptably (ie very) efficient. It is important to bear in mind that video output involves much higher data rates than does hard-copy terminal output, though input volume remains low. The own data requirement for the virtual video aspect is about 40 bytes for defining cursor addressing and the like, 64 bytes for driving shade selection, and 128 bytes for mapping graphical characters. The virtual screen aspect requires about 20 bytes for scalars and n*8 bytes for frame records. @IndexSecondary(Primary="EUSCD Ether", Secondary="Communication across the Ether") @SubSection(Communication across the Ether) Under the current software environment on the APMs the following procedures are available for communicating across the ether: @b[%routine etheropen(%integer localport,remoteport)] @Index(ETHEROPEN) LOCALPORT should be in the range 1 to 31,REMOTEPORT is the sum of a number in the range 0 to 31 (the remote port number) and another number (the remote station address) multiplied by 256 (shifted left 8). Calling ETHEROPEN has the obvious effect of opening port LOCALPORT in this client's station to port REMOTEPORT&31 in remote station numbmer REMOTEPORT>>8. @b[%routine etherwrite(%integer port, %bytename buffer, %integer size)] @Index(ETHERWRITE) PORT must be zero or the number of a local port which has been opened. BUFFER points to the first byte of the message to be transmitted, but if PORT=0 it points to the first byte of the six-byte address field, to be immediately followed by the actual message. SIZE conveys the size of the message (inclusive of address field if PORT=0). It must be in the range 0 to 532 if PORT#0 or 6 to 538 if PORT=0. The effect is to wait until transmission of any packet previously sent on the same port has been acknowleged, then to transmit this packet. @b[%integerfn etherread(%integer port, %bytename buffer, %integer maxsize)] PORT must be zero or the number of a local port which has been opened. BUFFER points to the first byte of a buffer into which a message is to be received. MAXSIZE indicates how big the buffer is. Incoming messages longer than this value will be read but the caller's memory is not overwritten past the end of the buffer. The result of the function is the actual size of the message received (inclusive of the six-or-eight-byte prefix if PORT=0), and may be larger than maxsize. The effect is to wait until a packet arrives on this port, then to read it. @b[%routine enable broadcasts(%integer channel)] @Index(ENABLE BROADCASTS) CHANNEL should be in the range 0 to 63. The effect is to instruct the station to tune in to the specified channel. It does not affect the "tuned-in-ness" to any other channel, i.e. to tell the station to tune in to all channels, this procedure must be called 64 times with CHANNEL taking every value between 0 and 63. @b[%routine disable broadcasts] @Index(DISABLE BROADCASTS) There is no parameter and the effect is to instruct the station to disregard broadcasts on all channels. @b[%integerfn etherstation] The %result is the station address of this client's ether station. @b(NOTE) Unless you know what you're doing, steer clear of attempting to talk to stations 16_70, which is the filestore, and 16_72, which is VAX. Also steer clear of port 16_0F, which is used by the APM system to communicate with the filestore. The standard firmware in the EPROM of the ether station is not up to date and does not work properly with regard to datagrams and broadcasts. To use these services, it is necessary (until such time as the EPROMs can be changed on all machines) to load the up-to-date firmware into your local ether station. This is done by issuing the system command ETHER:LOAD, which will respond by saying "Done" followed by the address of your station. This will have to be repeated if for any reason your station has been reset, such as when you re-load the APM. @IndexSecondary(Primary="EUSCD Ether", Secondary="Facilities") @Paragraph(Advanced Facilities) It is not always convenient to call ETHERREAD or ETHERWRITE because they will wait until it is possible to proceed with the transfer. To allow user programs to determine whether such transfers can proceed there exist a number of integer variables which are treated as boolean arrays (0:31) which indicate whether a particular condition holds for each of the 32 ports. Bit P of variable DTX indicates, when set, that a packet has arrived on port P, and that it is therefore possible to do an ETHERREAD on that port without waiting. In fact what ETHERREAD does is to wait until bit P of DTX becomes set, it then clears that bit and reads the packet. Setting of the bit is done by the interrupt handler in the system. Bit P of variable ACK indicates, when set, that either an acknowledgement for the packet last sent on port P has been received (if bit P of variable NAK is clear) or that the station has given up re-transmitting (if bit P of variable NAK is set). In fact what ETHERWRITE does is to wait until bit P of ACK is set, it then clears it and sends the packet. It ignores NAK. Whenever the station sends an ACK control character to its client, the interrupt handler sets the appropriate bit in variable ACK; when the station sends a NAK character, the interrupt handler sets the appropriate bits in both NAK and ACK. Therefore, to determine whether your transmission has completed, you should wait until the bit in ACK sets, then look at NAK. If the NAK bit is set, the transmission failed (and you should then clear the NAK bit), otherwise the packet sent was accepted by the destination (except in the case of broadcasts, which are never acknowledged by receiving stations, but the transmitting station nevertheless sends a proforma ACK to its client to keep the protocol consistent). In the above, "bit P of XXX is set" means that "XXX&(1<