Trailing-Edge
-
PDP-10 Archives
-
BB-M836A-BM
-
tools/sed/sed.rno
There are 13 other files named sed.rno in the archive. Click here to see a list.
.ps 57 68 .autop
.VAR OLDTAB A B
.VAR NEWRUN A B
.IF NEWRUN
.HEADER BOTTOM
.ENDIF NEWRUN
.C;INSTALLATION MANUAL
.C;HOW TO ADAPT A TERMINAL TO THE SED SCREEN EDITOR
.C;AND OTHER USEFUL INFORMATION
.C;BY A CHRISTOPHER HALL
.C;June 1981
.S2
.C;MISCELLANEOUS INFORMATION
There are a number of assembly parameters at the beginning of the editor
program:
.s1 .lit
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
.el .s1
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:
.s1 .lit
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
.el
If you set FTSFD, define SFDLVL to be the number of SFD levels you want.
Any number is permissable.
.S3
.c;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.
.S2
.c;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 terminal.
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.
.S2
.c;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 you how.
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.
.PG
.C;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:
.s1 .lit
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)
.el .s1
*#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.
.s1
CURSOR MOVEMENTS
The cursor movements cause the cursor to move in the given direction
(or home).
.s1
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.
.s1
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.
.s1
HIGHLIGHTING
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.
.s1
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 left.
IMPORTANT: if any of these four insert/delete sequences are undefined,
put a 0 in the table, not a CPOPJ.
.S1
CURSOR POSITIONING
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.
.s1
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:
.s1 .lit
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)
.el .s1
Explanations:
(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 subroutine).
(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 omitted).
(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.
.S1
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.
.s1
NULLS
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.
.s1
NOTE
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.
.pg
.c;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.
.s1 .lit
INTERNAL COMMAND "USUAL" FUNCTION
CODE SEQUENCE
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
.EL
.IFNOT OLDTAB
.LIT
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
.EL
.ELSE OLDTAB
.LIT
13 PICK ^K load buffer with text from the file
14 SLIDE-LEFT ^L move viewing window to the left
15 CARRIAGE-RETURN ^M good ol' ASCII carriage return
16 BACKTAB ^N move cursor to the previous tab stop
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 SLIDE-RIGHT ^U move viewing window to the right
26 SWITCH ^V set operating switches, etc.
.EL
.ENDIF OLDTAB
.LIT
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
.EL .S1
Note: all values regarding characters are in octal in this manual.
.S1 .I0
*#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 contain 0.
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 CONTROL-SPACE.
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 sequence.
The 33rd word of the terminal input table would look like:
.s1 .lit
-5,,SUBTAB
.EL .S1
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 looks like:
.s1 .lit
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
.EL
The general format of a subtable pointer is:
.s1 .lit
-SIZE OF SUBTABLE ,, ADDRESS OF SUBTABLE
or -BIG NUMBER ,, ADDRESS OF SUBTABLE
.EL .S1
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:
.s1 .lit
INTERNAL COMMAND ,, CHARACTER
or SUBTABLE POINTER ,, CHARACTER
.el .s1
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
.s1 .lit
SUBTAB: 14,,"A"
33,,"N"
0
.el .s1
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 the subtable
.s1 .lit
SUBTAB: 14,,"A"
33,,0
.el .s1
will map the sequence ending in A to internal command 14 and all others
into internal command 33.
.s1
The sub-subtable
.s1 .lit
SSBTAB: 33,,0
.el .s1
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 contain
.s1 .lit
-2,,SUBTAB ;(ONLY 2 DIFFERENT 2-CHARACTER SEQUENCES)
.el .s1
The subtable would look like
.s1 .lit
SUBTAB: 35,,"A" ;ESCAPE A == CURSOR-UP
SUBTB1,,"$" ;ESCAPE $ NEEDS ONE MORE CHARACTER
.el .s1
And the sub-subtable,
.s1 .lit
SUBTB1: 37,,"+" ;ESCAPE $ + == HOME
33,,"-" ;ESCAPE $ - == ENTER
0 ;END OF TABLE
.EL .S2
.C;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:
.s1 .lit
TERMNL: OONTEL
OVT52
OVT100
.el .s1
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 the instruction
.s1 .lit
MOVE TM,TERMNL(T1)
.el .s1
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 simple.
.s2
.C;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 that.
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.
.pg
.C;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 command sequences.
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 SEDV52,SED). The first step is to set
up the editor's output sequences. Define the terminal output table, OVT52,
as the following:
.s1 .lit
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
MRK ;FLAGS
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
.el .s1
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
command.
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.
.S1
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 each.
Note that the ESCAPE key on the terminal is never expected to
be used for commands.
.pg
The escape sequences are:
.s1 .lit
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
.el .s1
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.
.s1 .lit
0 ;COMMAND FOR RUBOUT (RESET)
IVT52: EXP 40, 1, 2, 3, 4, 5, 6, 7 ;NOTHING SPECIAL
EXP 10,11,12,13,14,15,16,17
EXP 20,21,22,23,24,25,26,27
EXP 30,31,32
-10,,I.VT52 ;ESCAPE NEEDS A SUBTABLE
EXP 34,35,36,37
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
IAVT52: 41,,"M"
0
.el
.pg
.C;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 SEDA2.MAC).
The ADM2 terminal is described to the editor in the file SEDA2.MAC
(SED is loaded with the command .LOAD SEDA2,SED).
The terminal output table is pretty straightforward, the result
of reading the manual that comes with the ADM2.
.s1 .lit
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
.el .s1
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 is set.
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.
.s2
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:
.s1 .lit
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
.el .s1
Each of these is followed by a CARRIAGE-RETURN, making each a
three-character sequence.
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.
.S1 .lit
0 ;COMMAND FOR RUBOUT (RESET)
IADM2: 40
-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 20,21,22,23,24,25,26,27
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
IA1ADM: "A"-100,,0
IA2ADM: "S"-100,,0
IA3ADM: "K"-100,,0
IA4ADM: "L"-100,,0
IA7ADM: 41,,0
IA8ADM: 40,,0
IA9ADM: 33,,0
.el