RFC 292

Graphics Protocol: Level 0 only

๐Ÿ“… published January 1972, from ietf

GRAPHICS PROTOCOL - LEVEL 0 ONLY ๐ŸŽ€

okay bestie, RFC 292 is a vintage ARPANET bop from 12 January 1972 ๐Ÿฆ‹ here's the lowdown on the title block first:

  • RFC number: 292, from the Network Working Group โœจ
  • Date: 12 January 1972
  • Authors: Jim Michener (MAC), Ira Cotton (MITRE), Karl Kelley (U. of Ill.), Dave Liddle (Owens Ill.), and Ed Meyer (MAC) ๐Ÿ’…
  • NIC number: 8302
  • References: RFC 282 and RFC 285
  • Updates: None
  • Obsoletes: None

INTRODUCTION โœจ

okay so this doc is the vibe check from the second meeting of the Network Graphics Group, which happened at the Stanford Artificial Intelligence Laboratory in late November 1971 ๐Ÿ’œ it describes part of a proposed Network Standard Graphics Protocol for sending graphics data around the ARPA network. the main focus is the form and content of graphics info going from a source (like an application program, say, in the "Serving Host") to a display package that outputs to a graphics console (at the "Using Host") ๐Ÿ–ฅ๏ธ it's sent as a sequence of 8-bit bytes, and it's called the graphics output byte stream.

the thing is, only the simplest forms of graphics data are covered here, because this is the first version of the doc. the next version is already in prep and will be WAY more complete ๐ŸŒˆ this is not a finished protocol, though. it's more like a starting point for graphics experimentation on the network ๐Ÿงช

this doc doesn't cover the form or content of graphics input (data going from the Using Host to the Serving Host), and it also doesn't cover how the connection gets set up between the hosts. a proposal for the input side will be made eventually by this committee, and the connection stuff is the job of the Connection Committee (of the Network Graphics Group) ๐Ÿ”—

this RFC describes the commands in the protocol in terms of what they'd do at the receiving end (the Using Host) ๐ŸŽฏ obviously some subroutine package would be super useful at the Serving Host, so applications can send graphics data, but this RFC is not going to say anything about that ๐Ÿ™ˆ

also, no facility is specified in this protocol that lets the Using Host report logical errors in the graphics output byte stream back to the Serving Host. honestly that facility would have to be integrated with the graphics _input_ byte stream, since it's tangled up with the synchrony problems of independent hosts ๐Ÿ˜ญ


BACKGROUND ๐ŸŒธ

the reader should probably peruse RFC 282: "Graphics Meeting Report" by Mike Padlipsky to get the framework around this whole network graphics discussion ๐Ÿ“– it might also be valuable to take note of the model in RFC 285: "Network Graphics" by Donald Huff ๐Ÿ’–


LEVEL AND GROUND RULES PERTAINING THERETO ๐Ÿ‘‘

okay this section is giving structure โœจ functions in the graphics protocol get sorted into a bunch of levels, partly based on how hard they are to implement ๐Ÿงฉ the plan is that any host which claims to implement the functions of level N must implement all lower levels as well. so sites will implement levels incrementally, and implementations will keep improving to add more and more functions ๐Ÿ“ˆ each implementation should be able to identify its own level to a graphics protocol at a remote site that's requesting a graphics interchange. a side result is that each site gets to figure out its own priorities for committing programmers to the graphics protocol versus other efforts ๐Ÿซถ

also, implementing level N requires no knowledge of level N+1. so a site can implement a level with (reasonably) firm knowledge that no changes at higher levels will alter the level it implemented ๐Ÿ”’ at some point the Network Graphics Group might decide to redefine a level that was already firmed up. that's not the plan, but we have to admit the proposed Graphics Protocol is experimental and may have to be changed ๐Ÿงช

one more ground rule, and it's a big one: a stream of commands and data that's valid at a given level, K, shall produce "identical" results on any interpreter of level K or higher. what we mean is that for the defined operations, similar pictures should come out โœจ some stuff is not strictly defined yet, like character size, character position relative to the beam, how control characters in text output affect the terminal, and what happens when the beam is moved or a line is drawn outside the logical screen boundary ๐Ÿ™ˆ this rule forces upward compatibility, so an application written with features from a low-numbered level will still work at sites that have moved on to higher levels ๐Ÿ’… and any aspect of this protocol that's explicitly "left unspecified" in the detailed operations descriptions below shall be explicitly specified in any public description of an actual implementation ๐Ÿ“ฃ

okay, now we describe the framework that's common to all levels ๐ŸŒˆ


BASIC DATA FORMS ๐Ÿงš

everything in the Network Standard Graphics Protocol is expressed as a sequence of 8-bit bytes ๐Ÿ“ a command is a command byte followed by zero or more arguments. the same command byte will always take the same number of arguments in the same form. the length of each argument may be fixed or variable, depending on the argument ๐Ÿ’œ

a simple argument type is a "value," which is an 8-bit integer โœจ another type is a "string," which is a count followed by (count) number of 8-bit bytes. if the count is between 0 and 127, it's sent in a single byte. if the count is between 128 and 2**15-1 (** means exponentiation), it's sent in two bytes with the high order bit of the first byte set to one. the first byte contains the seven high order bits of the number, and the second byte contains the eight low order bits ๐Ÿงฎ a string is the only type of argument for a command that can vary in length ๐ŸŽ€

coordinate data was a whole saga at the second Network Graphics Group meeting ๐Ÿ˜ญ it was decided that a two-dimensional Logical Coordinate System was required, and each interpreter for the graphic command byte stream would be responsible for mapping this coordinate system to physical device coordinates ๐Ÿ—บ๏ธ it was also decided that data in the logical coordinate system would be in twos-complement notation, that it would be fractional, that each edge of the screen would have unit length, and that the origin would correspond to the center of the screen on the output device ๐ŸŽฏ

the vertical (horizontal) edges of the screen of the output device correspond to the lines X (Y) = -1/2 or X=+1/2-e, where e is a small positive number determined by the precision of the fractional data ๐Ÿ“ the points (-1/2,-1/2), (-1/2,1/2-e), (1/2-e, -1/2), and (1/2-e, 1/2-e) shall be visible points at the corners of the logical screen ๐Ÿ‘€ (on a non-square display surface, the implementer may make his own decision, but it is recommended that the largest possible square area be utilized ๐ŸŸฆ) so basically the Logical Coordinate System contains points whose coordinates range from -1/2 to a little less than +1/2 ๐Ÿ’–

commands that take coordinate data will be available in various modes. in absolute mode, a position is specified by giving its coordinates in the Logical Coordinate System ๐Ÿ“ in relative mode, the difference between the coordinates of the position and the coordinates of the current position must be specified ๐Ÿงญ so a coordinate datum that's an argument for an absolute mode operation should be in the range -1/2 to +1/2-e, while one for a relative mode operation should be in the range -1+e to +1-e ๐ŸŒธ

interest came up at the second Graphics Group Meeting in eventually allowing a very large coordinate space (lots of bits of precision in each fractional coordinate) ๐Ÿš€ this is going to happen by letting the length, in 8-bit bytes, of each coordinate datum be set (as a mode). the meeting decided that two bytes per coordinate would suffice for now ๐Ÿซถ so "e" in the above discussion is 2**(15) (one in the least significant bit of a 15-bit plus sign fractional coordinate) ๐Ÿง 

text data gets sent as an argument of various commands for display on the output device ๐Ÿ’ฌ Network ASCII is used to represent characters ๐Ÿ”ค at the lowest levels of the protocol, only one character size will be available: whatever is "normal" on the display device ๐Ÿ“ if the device had no "normal" size, 72 characters per line would be desirable ๐Ÿ™Œ variable character size might be introduced later on ๐Ÿฆ‹

also, at the lowest levels, control characters get passed along to the device for it to do the best it can ๐Ÿคทโ€โ™€๏ธ however, the consensus of the graphics meeting was that at some reasonably low (but non-zero) level, carriage return, line feed, and backspace should be interpreted to do the right thing โœจ


COMMAND CODES ๐ŸŒˆ

each command in the graphics protocol gets assigned a non-negative value that represents this command in the byte stream ๐Ÿ”ข the algorithm for associating values and commands is, it turns out, a super touchy subject ๐Ÿ˜ฌ there are five or ten different criteria for a "best" algorithm, and each criterion has different emphasis ๐Ÿ™ƒ so this Gordian knot gets cut, in this proposal, by ordering the commands approximately according to level, and then just numbering them โœ‚๏ธ if several closely related commands show up at the same level, some attempt will be made to encode variations of meaning in terms of bit configurations ๐Ÿงฉ even if some later consideration causes a change in ordering to be proposed, this committee feels the numbering should not be altered ๐Ÿ”’ until this is firmly settled, though, it is strongly advised that any implementation take into account the possibility of reassignment of command codes โš ๏ธ


PARTICULAR PROPOSAL FOR LEVEL 0 PROTOCOL ๐Ÿฆ‹

level 0 is meant to be kept very simple ๐Ÿ’… so implementation can be done quickly and experimentation with the protocol can begin ๐Ÿš€ another reason is that the least powerful hosts, and even programmable terminals, should be able to implement it ๐Ÿ–ฅ๏ธ with that in mind, the "rule" was made that a command should only be implemented if its output is a function solely of the current command and the "beam position" current at the start of the command ๐ŸŽฏ in other words, the interpreter for level 0 needs no internal storage for "modes" or pushdown stacks ๐Ÿงบ with this restriction it's hoped that a very simple implementation will be possible for level 0 โœจ perhaps one could eventually build a hardware translator from level 0 code to one's own particular terminal's code ๐Ÿค–

one more thing: in the opcode assignment for level 0, bits 4, 2, and 1 have special meaning for the move, line, and dot commands ๐Ÿ” the 1 bit encodes absolute versus relative data mode, the 4 bit encodes whether any visible output occurs, and the 2 bit determines whether the visible output is a line or a dot ๐ŸŒŸ

LEVEL 0: COMMAND SUMMARY โœจ

okay so here's the cheat sheet for every level zero command ๐Ÿ’… the detailed descriptions come right after, but this table is the quick vibe check. new commands for protocol stuff can get added later by the Connection Committee, and they're currently asking for opcodes in the range 128 to 255 ๐Ÿงš

(remember from Basic Data Forms, above: <x>, <y>, <x delta> and <y delta> are two-byte coordinate values, <string> is a count followed by that many bytes, and <value> is an eight bit number ๐ŸŽ€)

   Decimal    Octal        Binary        Format

   0             0         00000000   Null
   1             1         00000001   Erase screen and reset beam
   2             2         00000010   Move Absolute <x> <y>
   3             3         00000011   Move Relative <x> <y>
   4             4         00000100   Draw Absolute <x> <y>
   5             5         00000101   Draw Relative <x delta> <y delta>
   6             8         00000110   Dot Absolute <x> <y>
   7             7         00000111   Dot Relative <x delta> <y delta>
   8            10         00001000   Text <string>
   9            11         00001001   TextR <string>
   10           12         00001010   End of Picture
   11           13         00001011   Escape <value> <string>

LEVEL 0: COMMAND DESCRIPTIONS ๐Ÿฆ‹

0. Null Statement ("null") ๐Ÿซถ

this one is the chill queen of the group: no arguments and no effect, either ๐Ÿ˜Œ

1. Erase screen and reset beam to origin ("Erase") ๐ŸŒธ

this tells the device a brand new picture is about to be drawn ๐ŸŽจ it should always be (eventually) paired with a following End of Picture command, so don't leave it hanging ๐Ÿ’€

2. Move beam invisibly to absolute position ("Move Absolute") <x coordinate> <y coordinate> โœจ

nothing gets drawn here. the beam just teleports quietly to the x,y position you asked for ๐Ÿงš

3. Move beam invisibly by relative amount ("Move Relative") <x delta> <y delta> ๐Ÿฆ‹

again, nothing is drawn ๐Ÿ™ˆ the beam just shifts by the amount you gave in x and y. it's like a little hop, no trace left behind

4. Draw line to absolute position ("Draw Absolute") <x coordinate> <y coordinate> ๐Ÿ’œ

now we're talking ๐Ÿ”ฅ a line gets drawn from wherever the beam currently is to the absolute x, y position

5. Draw line to relative position ("Draw Relative") <x delta> <y delta> ๐ŸŒˆ

same energy as Draw Absolute, but it's relative ๐Ÿ’… the line goes from the current beam position to the spot that's delta x and delta y away

6. Display a Dot at absolute position ("Dot Absolute") <x coordinate> <y coordinate> ๐Ÿ“

the beam moves invisibly over to absolute position x, y, and then a dot shows up right there โœจ tiny but iconic

7. Display a Dot at Relative position ("Dot Relative") <x delta> <y delta> ๐Ÿงš

the beam moves invisibly by the specified amount in x and y, and then a dot appears at that new spot ๐ŸŒธ

8. Display text ("Text") <string> ๐ŸŽ€

okay this one's a little more involved ๐Ÿฅน at the current beam position, some characters get displayed at the normal size for whatever device you're running on. <string> is a <count> followed by count many characters. if there's no "normal size," pick a size that fits seventy-two characters on each line.

the characters are coded in network ASCII, so every code from 0 up to 127 (decimal), inclusive, is allowed. (at level zero, what happens to control characters is left unspecified, so no promises there ๐Ÿ™ƒ) where the beam ends up after this command is also left unspecified, with one exception: if another Text command comes right after, it just tacks its text onto the previous string ๐Ÿ”— the position of the first character relative to the initial beam position is left unspecified too.

โš ๏ธ bestie, the use of the TEXT command is discouraged. use TextR instead ๐Ÿ’–

9. Display text and restore beam ("TextR") <string> ๐Ÿ’œ

same vibe as Text, except the beam goes back to where it was before the command ran ๐Ÿ”„ at the current beam position, a string of characters is displayed at the normal size for the device being operated, and then the beam is repositioned to where it started. <string> is again a <count> followed by count many characters, and if there's no "normal size," choose the size so that seventy-two characters are displayed per line.

the characters are coded in network ASCII, and all codes between 0 and 127 (decimal) inclusive are permitted. (at level zero, control characters are left unspecified, same as before ๐Ÿ™ˆ) the position of the first character relative to the initial beam position is also left unspecified.

10. End of Picture ("Endpic") ๐Ÿ

this one closes out the picture ๐ŸŽฌ it denotes the end of a new picture, and it has to be paired with a preceding Erase command. no Erase, no End of Picture. no End of Picture, no Erase. they're a matched set ๐Ÿซถ

11. Escape to device specifics ("Escdev") <value> <string> ๐Ÿ”ฎ

okay so here's how this works. if <value> is the code that the Protocol Committee assigned to the device you're operating, then the eight-bit bytes in <string> get transmitted to the device without being looked at ๐Ÿ‘€ (<string> starts with a <count> telling you how many bytes there are.) if the value doesn't match, just ignore the command ๐Ÿ™…โ€โ™€๏ธ

if the device doesn't accept 8-bit information, the data gets reformatted in some device specific way. for example, you could throw away the high order bit for a seven bit device, or gather 5 8-bit bytes into one 36-bit word and discard the high order bits, perhaps ๐Ÿงฉ

the bytes in the string should leave alone (or at least restore) any hardware beam position registers in the device that the interpreter might conceivably depend on. this is very important, don't mess up the beam ๐Ÿฅบ

๐Ÿšจ this command really should not be used. it's only at level 0 so that specific applications can do mode setting and other device specific manipulations, which is a whole mood ๐Ÿง 

here's the example that explains why it exists. ARDS terminals may optionally have several, independently addressable output scopes ๐Ÿ–ฅ๏ธ the selection mechanism only changes state when a particular sequence of ASCII characters reaches the terminal. so Escdev is the thing that picks which scopes are affected by the commands that come after it โœจ (the current state is invisible to the graphics package at the Using Host, so it can't peek at it ๐Ÿ‘ป)

now imagine another make of terminal has a similar option, but it responds to a different code sequence ๐Ÿ’… that's the reason behind conditionally ignoring the Escdev command based on the <value> you specify. so if an application will only ever output to an ARDS or to this second make (the one with the multiple scope option), the application could just always send two Escdev commands. one applies only to ARDS terminals, and the other applies only to the second make. solved ๐ŸŽ€๐Ÿ‘‘

APPENDIX 1: BNF FOR THE GRAPHICS PROTOCOL BYTE STREAM ๐ŸŒˆ

okay bestie, here's the grammar ๐Ÿงพ a quick key before you dive in:

  • non-terminals are written in <>
  • terminals that are keywords standing for particular eight-bit values are in capitals
  • terminals whose meaning should be clear to the reader are in lower case
  • note that "empty_string" means "zero bytes," and NOT "a <string> whose <count> is zero" ๐Ÿ™ƒ
   <graphics output byte stream> ::= empty_string
                      | <picture> <graphics output byte stream>
   <picture> ::= <new picture stt> <sttgroup> <end stt>
   <stt group> ::= empty_string | <stt> <stt group>.
   <stt> ::= <control stt> | <display stt>
   <control stt> ::= <escape to device stt>
                      | <null stt>
   <display stt> ::= <move absolute stt>
                      | <move relative stt>
                      | <draw absolute stt>
                      | <draw relative stt>
                      | <dot absolute stt>
                      | <dot relative stt>
                      | <text and restore beam stt>
                      | <text stt>

   <new picture stt> ::= ERASE
   <escape to device stt> ::=ESCDEV <device code> <string>
   <null stt>::= NULL
   <end stt>::= ENDPIC
   <move absolute stt> ::= MOVEA <x coordinate> <y coordinate>
   <move relative stt> ::= MOVER <x delta> <y delta>
   <draw absolute stt> ::= DRAWA <x coordinate> <y coordinate>
   <draw relative stt> ::= DRAWR <x delta> <y delta>
   <dot absolute stt> ::= DOTA <x coordinate> <y coordinate>
   <dot relative stt> ::= DOTR<x delta> <y delta>
   <text and restore beam stt> ::= TEXTR <string>
   <text stt> ::= TEXT <string>
   <x coordinate> ::= <coordinate>
   <y coordinate> ::= <coordinate>
   <x delta> ::= <double coordinate>
   <y delta> ::= <double coordinate>
   <coordinate> ::= singed,_two's-complement,_fraction_in_range
                     -1/2_to_less_than_+1/2
   <double coordinate> ::= signed,_two's_complement,_fraction,
                     range_strictly_between_-1_and_+1

   <count ::= 7-bit_non-negative_integer
                     | 15-bit_non-negative_integer_represented_in
                     "excess_2**15"_notation
   <string> ::= <count> count_8-bit_bytes
   <device code> ::= <value>
   <value> ::= 8-bit_integer

          [This RFC was put into machine readable form for entry]
      [into the online RFC archives by Kelly Tardif, Viag๏ฟฝnie 10/99]
๐Ÿ“ฆ where this page comes from