There are 14 other files named sed.mem in the archive. Click here to see a list.
HOW TO ADAPT A TERMINAL TO THE SED SCREEN EDITOR
AND OTHER USEFUL INFORMATION
BY A CHRISTOPHER HALL
There are a number of assembly parameters at the beginning of
the editor program:
MAXSIZ==^D1000 ;MAXIMUM FILE SIZE (BLOCKS) THAT CAN BE EDITED
PCBSIZ==600 ;SIZE OF PICK AND CLOSE BUFFER
NOBYTE==140 ;LENGTH OF LOOK-AHEAD WHEN SEARCHING FOR NULLS
SQZVAL==100 ;NUMBER OF DELETE COMMANDS BETWEEN SQUEEZES
XBFNUM==10 ;NUMBER OF EXECUTE BUFFERS
XBFSIZ==14 ;SIZE OF EACH EXECUTE BUFFER
TYPSIZ==40 ;SIZE OF TYPE BUFFER
None of these except MAXSIZ, XBFNUM, and XBFSIZ should need to
be modified unless the spirit moves you.
MAXSIZ depends on the amount of memory available to users on
your system. If SED tries to read in a file which is too large to
fit in core it will die horribly (without doing any damage), so set
this parameter to be as large as your memory can hold.
XBFNUM tells how many execute buffers there are, and XBFSIZ
tells how large each execute buffer is. The defaults are 8 buffers
of 12 words (hence 60 characters) each. You have more or fewer,
larger or smaller, buffers (but there must be at least one).
Other switches you may want to set:
TOPS10 1 if TOPS-10; 0 if TOPS-20
FTKA10 1 if KA-10, else 0
FTSFD 1 if you want SFD support, else 0
If you set FTSFD, define SFDLVL to be the number of SFD levels
you want. Any number is permissable.
ADAPTING SED TO A TERMINAL
All terminals which use the ASCII character set use the same
codes for the printing characters. That's the good news. The bad
news is that terminal control commands such as cursor movements and
screen control (clearing the screen, etc.) are done differently
almost everywhere, and the ability of a terminal to do things like
absolute cursor positioning, character highlighting, and other
whiz-bang features, varies even more. The more powerful an editor
is, the more of a demand it places on special terminal functions,
and therefore the more difficult it is to adapt a new terminal to
use that editor.
SED is designed to be as powerful as it can get without
becoming restricted to a small class of terminals which are smart
enough to run it, or needing a large effort to write simulation
subroutines to make it work with dumber terminals.
Adapting SED to run on a new terminal must be done by a person
who knows MACRO assembly language. A handbook describing the
terminal is also necessary, unless you want to do a lot of guessing.
The program SEDECO (as in SED ECHO) can be used to figure out
what character sequences are sent by special terminal keys, and what
effect sequences have on the screen.
THE GENERAL IDEA
Adapting SED to a terminal is a matter of setting up a file
which is loaded with SED.MAC. This file contains two tables which
handle incoming and outgoing character sequences, two subroutines
which perform cursor movement, and perhaps some other routines to do
things like setting up the terminal or simulating functions which
the terminal cannot do in hardware.
All of the files named SED??.MAC adapt SED to some terminal or
other. See SED.DIR to find out which file works with which
If your terminal already has a SED??.MAC file which works with
it, your job is done. Just load SED and edit.
Otherwise you will need to get out your terminal handbook and
write a driver. The file SEDX.MAC is a skeleton terminal file which
you can use as a template.
One of the two tables that needs to be set up (the terminal
output table) contains the character sequences which SED sends to
the terminal to get it to do interesting things (clearing the
screen, rolling, and so on), as well as some terminal-dependent
values. The other table (the terminal input table) maps sequences
of characters sent by the terminal into the values which SED uses
internally to represent its commands. Descriptions of the formats
of these tables make up the bulk of this document.
OVERVIEW OF THE INSIDE OF SED
SED works as follows: when it receives a printing ASCII
character (Octal codes 40-176) from the terminal it puts it in the
file and types it on the screen.
Other characters (Octal 0-37 and 177) are used to signal that a
command is coming. SED converts the user type-in to an internal
command code, and dispatches on the code to perform the command.
Any sequence of characters which starts with a control character or
RUBOUT can be mapped into any command code. Establishing that
relationship is part of the installer's job, and this manual tells
For example, when the user types the CURSOR-UP key the terminal
sends, say, the two characters "ESCAPE A" to the editor. SED must
know that when it receives an ESCAPE it should read the next
character, and if that character is an "A" it should dispatch to
command 36, which is CURSOR-UP.
The internal command codes run from 0 to 61 or so (octal), one
for each command.
The other half of the game is for SED to send the right
character sequences to the terminal to make it do interesting
things, like clearing the screen, absolute cursor positioning, or
rolling the screen up or down. That task will be handled first.
THE TERMINAL OUTPUT TABLE
SED assumes that its terminals can do a number of special
functions. The codes to do these functions are set up in the
terminal output table. Each entry in the table is one word long.
Most entries are command sequences or subroutine calls; some are
flags or values.
The command sequence entries can be either a string of up to 5
characters (which need not end with a null), the address of a longer
string, or the address of a subroutine. The subroutine can be used
to output very long sequences or to do more complex things than just
outputting characters. If your terminal does not have some
capability (like highlighting) put a CPOPJ in the table.
The format of the output command table is:
ITERML: CUP==0 ;CODE TO DO A CURSOR UP
CDN==1 ;CODE TO DO A CURSOR DOWN
CRG==2 ;CODE TO DO A CURSOR RIGHT
CLF==3 ;CODE TO DO A CURSOR LEFT
CHM==4 ;CODE TO DO A CURSOR HOME
CPG==5 ;CLEAR TO END OF PAGE
CLN==6 ;CLEAR TO END OF LINE
RUP==7 ;ROLL SCREEN UP AND CLEAR NEW LINE *
RLD==10 ;ROLL SCREEN DOWN AND CLEAR NEW LINE *
PON==11 ;TURN HIGHLIGHTING ON
POF==12 ;TURN HIGHLIGHTING OFF
ILN==13 ;INSERT A BLANK LINE (0 IF NOT DEFINED)
ISP==14 ;INSERT A SPACE (0 IF NOT DEFINED)
DLN==15 ;DELETE A LINE (0 IF NOT DEFINED)
DSP==16 ;DELETE A CHARACTER (0 IF NOT DEFINED)
MVB==17 ;MOVE TO BOTTOM OF PAGE *
HCP==20 ;MOVE HOME AND CLEAR ENTIRE PAGE *
PSC==21 ;ADDRESS OF ROUTINE TO POS'N TO (RW, CM)
PSL==22 ;ADDRESS OF ROUTINE TO POS'N TO (T4, 1)
LPP==23 ;NUMBER OF LINES PER PAGE
CPL==24 ;NUMBER OF CHARACTERS PER LINE
TCH==25 ;TERMINAL CHARACTERISTICS FLAGS
RTE==26 ;ADDRESS OF ROUTINE TO CALL ON ENTRY
RTX==27 ;ADDRESS OF ROUTINE TO CALL ON EXIT
NUL==30 ;NUMBER OF NULLS TO OUTPUT,,NULL CHARACTER
ITB==31 ;ADDRESS OF TERMINAL INPUT TABLE
MAR==32 ;MARK TO PUT UP ON ENTER (IF NO HIGHLIGHTS)
* These functions usually require more than one command to the
terminal. For example, MOVE TO BOTTOM might be done by HOME
CURSOR-UP, or by absolute positioning.
The cursor movements cause the cursor to move in the given
direction (or home).
CLEAR TO END OF LINE OR PAGE
Note that the clearing sequences are for clearing from the
cursor position to the end of the line or the screen, not the entire
line or screen.
ROLLING THE SCREEN UP OR DOWN
Rolling the screen up means moving every line on the screen up
one line, eliminating the line at the top, and adding a (blank) line
at the bottom. Sometimes that new bottom line will not be blank;
it must then be cleared out. Rolling down is similar. You can
assume that the cursor is at the bottom of the screen (top, for
rolling down) while rolling is being done.
Highlighting (which is often called "protection" in SED, for
historical reasons) means making a string of characters on the
screen stand out from the rest. Half intensity, blinking, and
reverse video are the most common ways of highlighting. The choice
among these is up to the implementor; blinking tends, however, to
be annoying. If your terminal does not have any highlighting, put
CPOPJs in table positions PON and POF and include the MAR table
entry and MRK terminal characteristic flag. Doing this will cause a
mark to be placed on the screen where the cursor used to be when it
is moved temporarily; it helps with the cursor movement commands.
INSERT OR DELETE LINES OR SPACES
Insert and delete lines or spaces are the sequences to do just
that at the terminal. Sending the insert line sequence will make a
blank line where the cursor is and move all lines beneath down. The
bottom line on the screen goes away. Delete line removes the line
at the cursor and moves every line beneath up. The bottom line on
the screen is blank. Insert space puts a space at the cursor
position and moves the rest of the line one character to the right.
If a character goes off the right of the screen, it is lost (the
line does NOT wrap around). Delete character removes the character
at the cursor and moves the rest of the line one character to the
IMPORTANT: if any of these four insert/delete sequences are
undefined, put a 0 in the table, not a CPOPJ.
Absolute cursor positioning is done differently by virtually
every terminal. The only thing the various algorithms have in
common is the general format: they begin with a sequence of
characters which announces that absolute positioning is being done.
Then the row and column are output to the terminal, encoded somehow.
There are a million ways to encode the row and column values.
Older versions of SED contained pre-programmed cursor
positioning routines, but there came to be too many of them, and the
implementation procedure was very awkward. So now the implementor
will need to write his own cursor positioning routines (or copy
them, if they already exist).
A number of routines have been stored in the file SED.POS.
They can be copied directly into your driver program, or as guides
for writing new routines.
Two types of cursor positioning routines are needed. One
positions to the row whose value is in accumulator RW and the column
in AC CM. The other positions to the start of the line given by AC
T4. Simply write these routines in the terminal-dependent file and
put their addresses in slots PSC and PSL of the terminal output
table. The PSC and PSL slots MUST contain subroutine addresses.
TERMINAL CHARACTERISTICS FLAGS
The terminal characteristics flags tell SED about certain
restrictions and shortcuts allowed or required by the terminal.
These operations have already been programmed, so the only thing you
need to do is to set the appropriate flags.
The following flags can be set up:
LSD LINEFEED AND CURSOR DOWN ARE THE SAME CHARACTER
TBS HARDWARE TABS EXIST (AND ARE PRE-SET)
WRP LONG LINES WRAP AROUND TO NEXT LINE OF SCREEN
MRK NO PROTECTED FIELDS; THUS, MARK NEEDED ON ENTER
NEL DON'T BOTHER RE-WRITING LAST LINE OF SCREEN
NLP SEND NULLS AFTER ABSOLUTE CURSOR POSITIONING
SLW SLOW TERMINAL: WRITE ERROR MSGS ON BOTTOM LINE
NPG DON'T SET TTY NO PAGE (^S AND ^Q REMAIN XOFF AND XON)
(LSD) LINEFEED is normally a command which clears out the line
to which the cursor moves. If it and CURSOR-DOWN are
indistinguishable (both code 012, say), then the LINEFEED command is
disabled, and just the CURSOR-DOWN remains.
(TBS) If hardware tabs do not exist they must be simulated
using CURSOR-RIGHT's. Beware: a lot of terminals have hardware
tabs, but they must be set up by someone. If SED expects tabs but
they are not set up it will go bananas, so don't set the TBS flag
for these terminals (or enable the tabs in a terminal-specific entry
(WRP) Lines too long for the screen will either lock on the
right margin or wrap around to the next line, depending on the
terminal. The editor display routine needs to know which will
occur, or else long lines will not display properly. Note: some
terminals, such as the VT100 (in wrap mode) will wrap before the
81st character is typed, rather than after the 80th. Do not set the
WRP flag for those terminals and they will work o.k.
(MRK) A protected field is one which SED wants to highlight.
For example, when you type ENTER SED will highlight the character at
the cursor position (by making it reverse video, for example). It's
useful to mark that cursor location, so if the terminal does not
have any highlighting features, the MRK flag indicates that a
certain mark should be put at the cursor location when ENTER is
typed. The character code for that mark is contained in the last
word of this table (if MRK is not set that mark word can be
(NEL) Make SED not care about keeping the bottom line of the
screen up to date. If your terminal is slow and has enough lines on
the screen that it can afford to give one away, then some re-write
time can be saved by setting the NEL flag.
(SLW) Causes error messages to be written on the bottom line of
the screen. The remainder of the screen is not affected (normally
the whole screen is erased and re-done). If your terminal is slow
you can save a lot of rewriting by setting the SLW flag.
(NLP) If your terminal needs to idle a while after positioning
the cursor, set the NLP flag, and set the NUL word of the table to
the number of nulls to send and the character to use.
(NPG) Some terminals that run at 9600 baud (and others) will
send CONTROL-S (XOFF) to the computer to tell it to stop
transmitting and CONTROL-Q (XON) to tell the computer to resume.
SED cannot tell XOFF and XON from DELETE-SPACES and ROLL-BACK-PAGES,
so if the terminal persists in sending XON's and XOFF's set the NPG
flag and don't use CONTROL-S and CONTROL-Q as editor commands.
ENTRY AND EXIT ROUTINES
If your terminal needs to be initialized (TABS set up, for
example), write a subroutine (in SEDX.MAC) to do whatever is
necessary and put its address in slot RTE. That routine will be
called just before SED reads in the file to be edited. Similarly
for a routine to do things on exiting from SED, in slot RTX. That
routine is called just before exiting. Use CPOPJ if no special
action is desired.
There are a number of situations where SED needs to delay and
let the terminal finish what it is doing. The most reliable delay
tactic is to send some nulls to the terminal. A null is any
character which causes no action from the terminal. 000 is the
classic null, but beware: some terminals or communication lines
ignore 000's, and the desired delay does not occur. Suggestions:
RUBOUT (177) or CONTROL-F (006). Anyway, the situations which need
a delay are set up in the terminal characteristics flags, described
elsewhere, and the number of nulls to output for each delay and the
null character are defined in the NUL word of the terminal output
table. If no delay is ever required (the "usual" case) set the NUL
word to 0 and don't set any of the NL? characteristics flags.
The ASCII backspace (CONTROL-H) is probably the best way to do
a cursor left, even if a separate command sequence exists.
Likewise, LINEFEED is usually a good way of rolling the screen up
and clearing the new line.
THE TERMINAL INPUT TABLE
The terminal input table maps sequences of characters arriving
from the terminal into the internal editor commands. The editor
commands are described below. If the ordering seems strange it is
because the commands are organized with regard to their position on
the typewriter keyboard, and not alphabetically.
INTERNAL COMMAND "USUAL" FUNCTION
1 INSERT-SPACES ^A add some spaces at the cursor
2 SET-FILE ^B set up a new file for editing
3 ABORT ^C exit, forgetting changes
4 INSERT-LINES ^D add some blank lines at the cursor
5 SEARCH-BACK ^E search from cursor to start of file
6 DELETE-LINES ^F remove some lines at the cursor
7 PUT ^G add text to the file
10 CURSOR-LEFT ^H move the cursor to the left
11 TAB ^I move cursor to the next tab stop
12 *CLEAR-LINE ^J erase the line below the cursor
13 SLIDE-LEFT ^K move viewing window to the left
14 SLIDE-RIGHT ^L move viewing window to the right
15 CARRIAGE-RETURN ^M good ol' ASCII carriage return
16 SWITCH ^N set operating switches, etc.
17 ENTER-CTRL-CHAR ^O make the next char typed a ctrl char
20 PERCENT-GOTO ^P move window to a percent of the file
21 ROLL-BACK-PAGES ^Q move window back some pages
22 SEARCH-FORWARD ^R search from cursor to end of file
23 DELETE-SPACES ^S remove some characters from a line
24 ROLL-FORW-LINES ^T move window forward some lines
25 BACKTAB ^U move cursor to the previous tab stop
26 PICK ^V load buffer with text from the file
27 ROLL-BACK-LINES ^W move window back some lines
30 EXECUTE ^X execute a sequence of commands
31 ROLL-FORW-PAGES ^Y move window forward some pages
32 EXIT ^Z save file and exit
33 ENTER ESCAPE set up an argument for a command
34 CURSOR DOWN ^\
35 CURSOR RIGHT ^]
36 CURSOR UP ^^
37 CURSOR HOME ^_
0 RESET RUBOUT rewrite cursor, line, or screen
40 RECALL (NONE) recall latest argument
41 INSERT-MODE (NONE) insert/replace toggle
42 DELETE-CHARACTER (NONE) delete character to the left of cursor
43 REAL-TAB (NONE) type a TAB into the file
44 MARK (NONE) mark position for PICK or DELETE
45 *LINE (NONE) move to start or end of line
46 CASE (NONE) change case of character at cursor
47 WINDOW (NONE) set or clear split-screen window
50 *ERASE-LINE (NONE) erase from cursor to end of line
51 (not used)
52 UP-TAB (NONE) move the cursor up six lines
53 DOWN-TAB (NONE) move the cursor down six lines
54 RE-WRITE (NONE) re-write the screen
55 SAVE-FILE (NONE) saves the current file
56 HELP (NONE) give on-line help
57 *BEGIN-LINE (NONE) move the cursor to beginning of line
60 *END-LINE (NONE) move the cursor to the end of line
61 ERASE-WORD (NONE) erases the word ending at the cursor
Note: all values regarding characters are in octal in this manual.
* The LINE command has been superceded by BEGIN-LINE and END-LINE,
and CLEAR-LINE has been superceded by ERASE-LINE. LINE and
CLEAR-LINE remain for compatability, but do not need to be
implemented at a new site.
For a fuller description of what these commands do, see the
reference manual, SED.DOC.
The command invoked by RUBOUT (octal 177) is set up in the -1
location of the input table (ie, the word before the label).
Nominally RUBOUT invokes the RESET command, so that -1 word should
Normally the command with code n is invoked by typing CONTROL-n
(for example, SEARCH-BACKWARD by CONTROL-E). The commands which
have internal codes above octal 37 have no normal invocations. They
were implemented after all the control characters had been used up.
If your terminal has some user-defineable buttons on it you can make
them invoke those commands. If not, then if your terminal sends
nulls (ASCII 000), then one of those commands can be set up as
The first thing to do is to figure out what input sequences
from the terminal should represent which commands. The decision is
entirely arbitrary, but it is a good idea to set up each command to
be one keystroke (with or without the control key depressed). Most
often the control characters can be used to represent the non-cursor
movement commands. The sequences which define cursor movement will
be those which are sent when the cursor keys are pushed. Undefined
keys can be used in any manner you please.
The terminal input table is indexed by the character input from
the terminal; the values in the table are the internal commands.
So if you want the user to type a CONTROL-B and have a PUT occur,
put 7 in word 2 of the table (the word at the label is word 0).
The preceding discussion is adequate if each editor command is
invoked by a single control character from the terminal. However,
if the terminal sends two or more characters to represent a command
things get a little more complex. Suppose the cursor movement
commands (UP, DOWN, RIGHT, LEFT, and HOME) are invoked by ESCAPE
something (like ESCAPE A for UP, ESCAPE H for HOME, etc). Then word
33 of the table should contain a subtable pointer to tell SED to
read second character, and then how to interpret the two-character
The 33rd word of the terminal input table would look like:
This tells SED to read another character and go reference subtable
SUBTAB (which is 5 words long) to find out what to do. The subtable
SUBTAB: 37,,"H" ;ESCAPE H == HOME
34,,"C" ;ESCAPE C == CURSOR-UP
35,,"B" ;ESCAPE B == CURSOR-RIGHT
36,,"A" ;ESCAPE A == CURSOR-DOWN
10,,"D" ;ESCAPE D == CURSOR-LEFT
The general format of a subtable pointer is:
-SIZE OF SUBTABLE ,, ADDRESS OF SUBTABLE
or -BIG NUMBER ,, ADDRESS OF SUBTABLE
In the latter case, the subtable must end with a zero word.
The subtable consists of one word for every sequence that
begins with the same character (in the above case, 5 words), plus
maybe an extra zero word if the second format above is used.
Entries in the subtable are searched sequentially from first to
last, so any order is all right, but putting the most expected
commands first is a good idea.
Entries in a subtable can take two forms:
INTERNAL COMMAND ,, CHARACTER
or SUBTABLE POINTER ,, CHARACTER
If CHARACTER is zero for either of these formats then any character
input will match. Otherwise characters not found in the subtable
will cause an ILLEGAL COMMAND message.
If your terminal's commands are all one or two characters long,
then the subtables will contain entries of the first form. When SED
receives the first character of the command it will point itself
into the subtable; when it receives the second it will set up the
internal command which is in the same word as that second character.
Now suppose the terminal sends a three-character sequence when
some keys are pressed. When SED receives the first character it
goes to a subtable. When it receives the second it should go to a
sub-subtable, which tells it to input a third character and then
decide what the command is.
Since only the top-level table has room for the size of its
subtable, all sub-subtables must end in either a zero word or a word
with a zero right half. With the former case only characters
explicitly set up in the table will be recognized as legal; in the
latter case, characters not found in the table will be mapped into
the command given by the left half of that word whose right half is
zero. Thus the subtable
will map sequences ending in A to internal command 14, sequences
ending in N to command 33, and give an error for all others, whereas
will map the sequence ending in A to internal command 14 and all
others into internal command 33.
has the effect of ignoring the last character which has been input,
since no matter what that character is the sequence is mapped into
code 33 (See the example dealing with the ADM2 terminal).
Subtables can be stacked as deeply as desired; a command from
the terminal can be any number of characters at all.
As an example, say the terminal uses ESCAPE A for CURSOR-UP
(ie, two characters), ESCAPE $ + for CURSOR-HOME (three characters),
and ESCAPE $ - for ENTER. Then word 33 of the input table would
-2,,SUBTAB ;(ONLY 2 DIFFERENT 2-CHARACTER SEQUENCES)
The subtable would look like
SUBTAB: 35,,"A" ;ESCAPE A == CURSOR-UP
SUBTB1,,"$" ;ESCAPE $ NEEDS ONE MORE CHARACTER
And the sub-subtable,
SUBTB1: 37,,"+" ;ESCAPE $ + == HOME
33,,"-" ;ESCAPE $ - == ENTER
0 ;END OF TABLE
ADAPTING MORE THAN ONE TERMINAL
If SED is to be used on a number of terminals it is up to the
installation to figure out how to tell SED what kind of terminal it
is running on. SEDX.MAC has examples of how to ask the monitor
about the terminal type.
So find out the terminal type somehow, then do the following:
build all your terminal tables in SEDX.MAC. Set up the location
TERMNL with the addresses of the terminal output tables, one after
another. Put the address of a routine to execute on entry in the
first output table. That routine should do whatever is necessary to
pick the right terminal and get a value from 0 to N-1 (if there are
N terminals). Then set up the contents of TERMNL indexed by that
value in accumulator TM.
For example, say you have ONTEL, VT52 and VT100 terminals. Say
the names of their output tables are OONTEL, OVT52 and OVT100. Then
make TERMNL look like:
In the "routine to execute on entry" word of OONTEL set up the
address, say, DECIDE. The DECIDE routine figures out what terminal
the user is on and gets an index. If the terminal is a VT52, DECIDE
would want to get the value 1. Say that value is in AC T1. Then
would make SED use the right set of tables.
Another way to solve the problem is to have a number of editor
programs, each of which runs on its own terminal. The user would
run, say, SEDV on a VT52 and SEDO on an ONTEL. This is klugey, but
ADDING A NEW COMMAND TO THE EDITOR PROGRAM
If you're a MACRO programmer, it's easy to add a new command to
SED. Just write a routine to do whatever-it-is. End it with a JRST
LOOP, which will go get another command. Look at other routines to
find out how to read parameters, erase them from the screen, and all
Once the routine is written, hook it up as a command in the
command table. Add a word to the table which starts at CMDTBL. The
left half of the word is the place to go if that command is typed
along with a parameter; the right half is where to go if no
parameter was typed.
The internal value of the command is its index in the table.
If some terminal character sequence maps into that value, the
command will be invoked.
You must also invent a two-character name for your command and
put it at the end of the CMDNAM command name table.
EXAMPLE 1: HOW THE VT52 LIVES WITH SED
It would be helpful to look at a VT52 terminal manual while
reading this section, unless you want to take my word for the
Note: these examples are examples only. They differ a little
from the actual terminal drivers in order to illustrate additional
features. If you want to know what the VT52 or ADM2 world is really
like, see SEDV52.MAC or SEDA2.MAC.
The VT52 terminal is described to SED in the file SEDV52.MAC
(SED is loaded with the command .LOAD SEDSYM,SEDV52,SED). The first
step is to set up the editor's output sequences. Define the
terminal output table, OVT52, as the following:
OVT52: BYTE (7) 33,"A" ;CURSOR UP
BYTE (7) 33,"B" ; DOWN
BYTE (7) 33,"C" ; RIGHT
BYTE (7) 10 ; LEFT
BYTE (7) 33,"H" ; HOME
BYTE (7) 33,"J" ;CLEAR TO END OF PAGE
BYTE (7) 33,"K" ;CLEAR TO END OF LINE
BYTE (7) 12 ;ROLL UP AND CLEAR LINE
BYTE (7) 33,"I" ;ROLL DOWN AND CLEAR LINE
CPOPJ ;PROTECT ON (NONE)
CPOPJ ;PROTECT OFF
0 ;INSERT LINES (NONE)
0 ;INSERT SPACES (NONE)
0 ;DELETE LINES (NONE)
0 ;DELETE SPACES (NONE)
BYTE (7) 33,"Y","7"," " ;MOVE TO BOTTOM
BYTE (7) 33,"H",33,"J" ;HOME AND CLEAR ENTIRE PAGE
VT5PSC ;ROUTINE TO POSITION TO CHARACTER
VT5PSL ;ROUTINE TO POSITION TO START OF LINE
^D24 ;LINES PER PAGE
^D80 ;CHARACTERS PER LINE
VENTRY ;ROUTINE TO CALL ON ENTRY
VEXIT ;ROUTINE TO CALL ON EXIT
0,,0 ;NO NULLS NEEDED
IVT52 ;ADDRESS OF INPUT TABLE
"*" ;MARK TO DISPLAY ON ENTER
Roll up and clear can usually be done with a linefeed. On the
VT52 roll down automatically clears the line; on some other
terminals the roll must be followed by a clear to end of line.
There are no features like reverse video, blinking, or half
intensity, so the highlighting of the ENTER mark, the FENCE, and
embedded CONTROL characters cannot be done; hence the CPOPJ's.
There are no insert/delete character/line sequences on the
VT52, so there are four 0's in the table. SED will simulate the
insert/delete action in software.
The next three commands are ones which probably cannot be done
with one terminal sequence; for example, home and clear page
consists of the HOME sequence followed by the CLEAR PAGE sequence.
Moving to the bottom of the screen can often be done with a HOME
followed by a CURSOR UP; this will not work on the VT52 since a
CURSOR UP at the top of the screen will not put the cursor at the
bottom. So the sequence in the table is an absolute positioning
The next two table locations give the addresses of routines to
position the cursor to row RW, column CM, and to the start of row
T4. These routines appear at the end of the terminal program.
The number of lines per page and of characters per line follow.
Then comes the word of flags, which indicate features which are
missing and must be simulated by SED. When ENTER is typed, the
character at the cursor position is highlighted. Since the VT52
does not have protected (highlighted, right?) fields, the flag MRK
tells SED to write a certain mark at the cursor position. The code
for that mark is given by the next word of the table, and can be any
printing character. That mark word can be omitted if the MRK flag
is not set.
There is a routine to execute on entry, VENTRY. It sets up the
numeric keypad so it sends different codes from the normal keyboard.
This is so the ENTER key can be used for INSERT-MODE. The exit
routine, VEXIT, restores the keypad to normal mode.
The VT52 has no problem with alphanumerics and most commands.
However, ESCAPE is used to signal cursor movement. Also, there are
three unlabeled keys, which send the sequences ESCAPE P, ESCAPE Q,
and ESCAPE R; but no key to home the cursor. So define the ESCAPE
P key to be the ENTER command and ESCAPE R to be HOME. The RECALL
command can have the ESCAPE Q key. The INSERT-MODE command is
invoked by the key beneath CURSOR-LEFT, which sends ESCAPE ? M.
Thus all commands can be issued from the keyboard using one stroke
Note that the ESCAPE key on the terminal is never expected to
be used for commands.
The escape sequences are:
CHARACTER(S) COMMAND EDITOR
AFTER ESCAPE DESIRED CODE
A CURSOR RIGHT 35
B CURSOR LEFT 10
C CURSOR UP 36
D CURSOR DOWN 34
H HOME 37
P ENTER 33
Q RECALL 40
R HOME 37
? M INSERT-MODE 41
The terminal input table contains value == location (ie, word 7
of the table contains a 7, etc.) except for location 33 (ESCAPE).
When an ESCAPE is received SED wants to read the next character and
do different things depending on what that character is. So the
input table location 33 contains the negative length and the address
of the subtable which interprets the next character. The name of
that subtable is arbitrary.
If the character after the ESCAPE is not found in the subtable
an illegal command message is given. The subtable is searched
sequentially, so the more frequently expected commands, the cursor
movements, appear first.
The codes 34, 35, 36, and 37 are never expected to be received
from the terminal. So any value can be put in those words of the
table; they might as well be the usual values.
0 ;COMMAND FOR RUBOUT (RESET)
IVT52: EXP 40, 1, 2, 3, 4, 5, 6, 7 ;NOTHING SPECIAL
-10,,I.VT52 ;ESCAPE NEEDS A SUBTABLE
I.VT52: 36,,"A" ;ESCAPE A == UP
34,,"B" ;ESCAPE B == DOWN
35,,"C" ;ESCAPE C == RIGHT
10,,"D" ;ESCAPE D == LEFT
33,,"P" ;ESCAPE P == ENTER
37,,"R" ;ESCAPE R == HOME
40,,"Q" ;ESCAPE Q == RECALL
IAVT52!SUB,,"?" ;ESCAPE ? M == INSERT-MODE
EXAMPLE 2: HOW THE ADM2 LIVES WITH SED
The Systematics General ADM2 terminal is a good example of how
detailed things can get (Note: this example has been embellished to
show off some features. If you have an ADM2, see the file
The ADM2 terminal is described to the editor in the file
SEDA2.MAC (SED is loaded with the command .LOAD SEDSYM,SEDA2,SED).
The terminal output table is pretty straightforward, the result of
reading the manual that comes with the ADM2.
OADM2: BYTE (7) 13 ;CURSOR UP
BYTE (7) 12 ; DOWN
BYTE (7) 14 ; RIGHT
BYTE (7) 10 ; LEFT
BYTE (7) 36 ; HOME
BYTE (7) 33,"Y" ;CLEAR TO END OF PAGE
BYTE (7) 33,"T" ;CLEAR TO END OF LINE
BYTE (7) 12 ;ROLL UP AND CLEAR LINE
0 ;ROLL DOWN AND CLEAR LINE
BYTE (7) 33,")" ;PROTECT ON
BYTE (7) 33,"(" ;PROTECT OFF
BYTE (7) 33,"E" ;INSERT A BLANK LINE
BYTE (7) 33,"Q" ;INSERT A SPACE
BYTE (7) 33,"R" ;DELETE LINE
BYTE (7) 33,"W" ;DELETE SPACE
BYTE (7) 36,13 ;MOVE TO BOTTOM
BYTE (7) 36,33,"Y" ;HOME AND CLEAR ENTIRE PAGE
ADMPSC ;ROUTINE TO POSITION TO CHARACTER
ADMPSL ;ROUTINE TO POSITION TO START OF LINE
^D24 ;LINES PER PAGE
^D80 ;CHARACTERS PER LINE
WRP!LSD!NLP ;WRAPAROUND, LF=DOWN, NO ROLL DOWN
CPOPJ ;ROUTINE TO CALL ON ENTRY (NONE)
CPOPJ ;ROUTINE TO CALL ON EXIT (NONE)
2,,6 ;SEND 2 ^F'S AS NULLS
IADM2 ;ADDRESS OF TERMINAL INPUT TABLE
The terminal cannot roll the screen down, so there is a CPOPJ
in the table and the NRD flag is set.
The ADM2 has sequences for inserting and deleting, so SED can
use them. Rewriting only a line or two on an insert or delete,
instead of most of the screen, can really speed things up.
The ADM2 uses a LINEFEED as the CURSOR-DOWN character, so the
LINEFEED command has been disabled by the LSD flag.
Long lines will wrap around to the next line, so the WRP flag
After absolute positioning a little delay is needed, to set the
NLP flag and define the NUL word to say that two CONTROL-F's will be
sent as nulls.
There is no MAR word since highlighting (protection) exists (in
the guise of half intensity), so no special mark is needed.
The ADM2 has a row of 16 undefined buttons which send the codes
CONTROL-A @ CARRIAGE-RETURN through CONTROL-A O CARRIAGE-RETURN,
which can be used for any homeless commands. Which is a good thing,
since the terminal uses CONTROL-K and CONTROL-L for cursor movement,
and ESCAPE is not echoed properly. So SLIDE-LEFT, SLIDE-RIGHT and
ENTER will be set up as three of those undefined buttons.
INSERT-SPACES must also be defined as one of those buttons, since
CONTROL-A now signals that the two characters following it must be
inspected. For symmetry, put DELETE-SPACES in the buttons too, and
define two more of them to be RECALL and INSERT-MODE.
To add insult to injury, the HOME character is 36, not 37.
The CONTROL-A sequences are:
CHARACTER COMMAND EDITOR
AFTER ^A DESIRED CODE
@ INSERT-SPACES 1
A DELETE-SPACES 23
B SLIDE-LEFT 13
C SLIDE-RIGHT 14
M INSERT-MODE 41
N RECALL 40
O ENTER 33
Each of these is followed by a CARRIAGE-RETURN, making each a
Now for the terminal input table itself. There is a subtable
pointer in word 1, for CONTROL-A. Words 13 and 14 contain cursor
movements, and word 36 contains the HOME command. Otherwise the
table is normal.
The subtable contains a number of addresses of other subtables,
since after finding the proper second character, SED wants to pick
up the CARRIAGE-RETURN.
Each of the sub-subtables indicates that any character is
acceptable (given by the 0 in the right half), and maps the three
character sequence received into the proper editor command.
Thus if the user types a SLIDE-LEFT command (third undefined
button from the left), the terminal sends CONTROL-A B
CARRIAGE-RETURN to the editor. SED receives the CONTROL-A, is
directed to the subtable, receives the B, is directed to
sub-subtable IA3ADM, receives the CARRIAGE-RETURN and maps the
sequence into the internal SLIDE-LEFT command, code octal 13.
The codes 23, 33, 34, 35, and 37 are undefined at the moment.
They can be anything, but it is probably best to give them their
usual meanings. So a DELETE-SPACES can be invoked by the user
typing either button F2 or ^S. A little redundancy doesn't hurt.
0 ;COMMAND FOR RUBOUT (RESET)
-7,,IAADM2 ;^A NEEDS A SUBTABLE
EXP 2, 3, 4, 5, 6, 7
EXP 10,11,12,36,35,15,16,17 ;^K AND ^L ALTERED
EXP 30,31,32,33,34,35,37,37 ;36 IS HOME
IAADM2: IA1ADM,,"@" ;^A @ CR == ^A
IA2ADM,,"A" ;^A A CR == ^S
IA3ADM,,"B" ;^A B CR == ^K
IA4ADM,,"C" ;^A C CR == ^L
IA7ADM,,"M" ;^A M CR == INSERT MODE
IA8ADM,,"N" ;^A N CR == RECALL
IA9ADM,,"O" ;^A O CR == ENTER