1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-27 01:09:49 +00:00

Add some missing INFO; files:

-READ- -THIS-, DOCOND 6, LEDIT 5, RMAIL 37, SUPGRF 1, TDEBUG 12.
This commit is contained in:
Lars Brinkhoff
2016-12-23 20:44:22 +01:00
parent 4871f2a8b7
commit 5812ac3c3a
6 changed files with 2277 additions and 0 deletions

2
doc/info/-read-.-this- Executable file
View File

@@ -0,0 +1,2 @@
This directory is used for tree-structured documentation files
by the INFO package of EMACS.

337
doc/info/docond.6 Executable file
View File

@@ -0,0 +1,337 @@
-*-Text-*-

DOCOND Node: Top Up: (EMACS) Next: Flags
DOCOND is a program for putting "assembly conditionals" in text files.
At the beginning of the DOCOND input file go declarations of the names
of various "flags" or assembly switches, Throughout the rest of the
file may appear conditionals which test the state of a flag.
Processing the input file with DOCOND causes the contents of failing
conditionals to be deleted. The contents of successful conditionals
remain, but the conditional syntax itself is deleted, leaving text
which is free of DOCOND commands. In addition to conditionals within
the text, conditional replacements may be specified as declarations,
and macros written in TECO can be called from points in the text.
* Menu:
* Flags:: How to declare flags.
* Relate:: Expressing relationships between flags.
* Condit:: How to put conditionals in the text.
* Macros:: Macro calls in the text.
* Replace:: Conditional global replacements.
* Run:: Running DOCOND.

DOCOND Node: Flags, Previous: Top, Up: Top, Next: Relate
Declaring DOCOND Flags.
DOCOND processing is controlled by binary flags, whose names are
chosen by the user. Each flag has a "setting", which iseither "+" or
"-" (or, in the source file, "?", meaning that the setting is unknown
as yet). A DOCOND conditional always tests the setting of some flag.
The first stage of DOCOND processing asks the user what setting to use
for each flag; when all the settings are known, DOCOND processes the
conditionals in the text according to those settings.
Each DOCOND input file must begin with a DOCOND declarations section
which is terminated with the string "{end}" followed by a CRLF. Each
flag used in the file must be declared in this section. Implications
and conditional replacements are also declared there. Since each
DOCOND construct is enclosed in braces, nothing stops you from having
other sorts of text (such as -*-Text-*-) in the DOCOND declarations
section, but whatever it is will all be deleted when DOCOND is
finished running.
A flag declaration looks like {Flag:?<flagname>}. Notice the "?"!
The "?" is a placeholder which you must specify; it will be replaced
by the setting of the flag, either "+" or "-", when that is known.
Here are some examples:
{Flag:?FOO} {Flag:?DoubleFoo}
You can actually provide a setting for the flag in the source file,
by writing "+" or "-" instead of the "?". This is actually useful,
since you can declare a flag named "Comment" which is always off,
{Flag:-Comment}
and then use conditionals on this flag as comments:
{+Comment: anything at all}
If you have no declarations but Flag declarations, DOCOND will ask
you for the settings of all the flags, in the order they are declared.
The Print declaration allows you to print out an arbitrary string at
declaration processing time (presumably, to give the user directions
on how to decide what flag settings to specify). Here is an example:
{Print:FOO should be "+" if your version can process Lisp code.
}
{Flag:?FOO}

DOCOND Node: Relate, Previous: Flags, Up: Top, Next: Condit
Expressing Relationships between Flags.
Although DOCOND conditionals can be nested, it is often convenient
to have redundant flags which express combinations of other flags.
Or, you might have several mutually exclusive alternatives, with a
flag for each alternative. In that case, it would be a nuisance to be
asked for the setting of each flag separately, when all but one must
be "-". For these situations, DOCOND provides the "relationship
declarations" Implies, Alternatives, and Default. Implies allows you
to set one flag conditional on the setting of another. Alternatives
tells DOCOND that exactly one of a list of flags must be "+" and the
others "-". DOCOND then knows just to ask for the name of the one
which is "+". Default allows you to provide a flag with a default
setting which is used unless overridden by an Implies or Alternative
(or by a manual setting made before doing MM DOCOND).
A DOCOND implication says that if one flag is set on (or off),
another flag should be set automatically. In general, an implication
specifies a flag and setting as the condition, and a flag to be set in
response. The setting always precedes the flagname (it is always
thus, in DOCOND), and no extra spaces are allowed anywhere in the
construct. Here is the general pattern:
{Implies:+FOO=>-BAR}
A default declaration says that rather than ask the user for the
value of a certain flag, a specific default setting should be assumed.
{Default:-FOO}
says that FOO is off by default. This is not the same as giving FOO a
constant value of "-" -- that is, declaring FOO with
{Flag:-FOO}
because implications of flags set earlier can override the default.
The user can also override it using the DOCOND Set Flag command.
For example, you can use Implies and Default together to declare
that the FOO-or-BAR flag should be "+" if either FOO or BAR is "+":
FOO-or-BAR is + if FOO or BAR is:
{Implies:+FOO=>+FOO-or-BAR}
{Implies:+BAR=>+FOO-or-BAR}
{Default:-FOO-or-BAR}
{Flag:?FOO-or-BAR}
Note that text not within brackets in the declaration section is in
effect a comment, since it will be deleted without affecting DOCOND.
That the Implies declarations which can set FOO-or-BAR precede the
Flag declaration for FOO-or-BAR is essential, because both types are
processed in one pass through the declarations section, and if the
Flag declaration were seen first, since the flag would still be unset,
DOCOND would ask the user for the setting. For the same reason, the
above example must come after the declarations of FOO and BAR. The
location of the Default declaration doesn't actually matter, because
it is processed, not by its position, but at the time when the Flag
declaration is processed. However, it is good practise to put it in
the position which would be correct if it were processed in sequence.
The remaining type of relationship declaration is the Alternatives
declaration, which says that, of a list of flags, exactly one should
be "+" and the rest "-". When the Alternatives declaration is
processed (in sequential order, like Implies and Flag), if none of the
flags in the list is set to "+", the user is asked to specify one of
them. The specified one is set to "+", and the rest to "-". If one
is already set to "+", Alternatives just sets the rest to "-" without
having to ask. Thus, an alternative can be selected by an earlier
Implies, or by the MM DOCOND Set Flag command (*Note Run: Run.).
Here is an example of the Alternatives declaration:
{Alternatives:ITS,Twenex,Lispm}
{Flag:?ITS} {Flag:?Twenex} {Flag:?Lispm}
Note that the Alternatives declaration does not eliminate the need to
declare the individual flags in Flag declarations, but the latter must
come after the Alternatives, or else DOCOND would ask about each flag
individually when it came to the Flag declarations.

DOCOND Node: Condit, Previous: Relate, Up: Top, Next: Macros
In-text Conditionals.
The fundamental feature of DOCOND is the conditional which causes a
string of text to appear or not appear in the output according to the
setting of some flag. Each conditional tests only one flag, but
conditionals can be nested to test more than one; in addition, the
Implies and Default constructs can be used to make a new flag
correspond to any Boolean combination of other flag settings.
*Note Boole: Relate.
A conditional must contain the name of the flag, the setting to test
for, and the conditionalized text. Here is an example:
{+FOO: text to appear only if FOO is "on" (or "+")}
A conditional appears vaguely like the other DOCOND constructs, but
note these differences:
1) in a conditional, the "{" is followed by a "+" or a "-".
2) conditionals appear PAST the {end} of the declarations
section, whereas the other constructs appear only WITHIN
the declarations section.
Note that all text not within a conditional will always appear in the
output, so that
I want to
{+FOO:win}
{-FOO:lose}
.
will result, if FOO is +, in
I want to
win
.
or, if FOO is -, in
I want to
lose
.
If you want no spurious CRLFs in the output, put none in the input:
I want to {+FOO:win}{-FOO:lose}.
Note also that there is no difficulty in having braces in
unconditional text, since "{" is recognized as a conditional only when
followed by a "+" or "-", but braces appearing inside a conditional
must be balanced (because nested conditionals work).
Note that conditional global replacements can affect the conditionals,
both the text they contain and the flag names!

DOCOND Node: Macros, Previous: Condit, Up: Top, Next: Replace
In-text Macro Calls.
In addition to conditionals, DOCOND provides a feature for including
macro calls in the text. Unlike most macro processors, DOCOND does
not need to define a macro-writing language, because the macros are
just named EMACS commands written in TECO.
{*macroname:stringarg}
specifies a call to the command named <macroname> with the string
argument <stringarg> provided to it. The macro call is deleted from
the buffer when it is processed, and replaced by the string (if any)
returned by the called macro (in which case, the newly inserted string
is rescanned for conditionals and macro calls). For example, suppose
we have a macro named MM Type Out which takes a string argument and
types it out; then
{*Type Out:FOO}
would print "FOO" when executed.
Macro calls can successfully be included in conditionals; they will
be expanded only if the conditionals succeed. Conditionals can also
be included in a macro call, but the macro call is processed first, so
that the string argument passed to the macro will unconditionally
contain the conditionals. Only if the macro returns those
conditionals to be reinserted and rescanned will those conditionals
actually be processed as such.
One macro provided by DOCOND for just this purpose is called Refill.
Call Refill on the line after the end of a paragraph
... last line of paragraph.
{+FOO:{*Refill:}}
to refill that paragraph, if conditionals or replacements have caused
it not to be properly filled.
To provide a macro FOO for use in DOCOND macro calls, you must
define it yourself. Any method of defining a named EMACS command will
do, including putting a specification of the variable MM FOO in the
source file's local modes, but there is also a special facility called
the Local Variable declaration in DOCOND itself which can be used:
{Local Variable:MM FOO=lots of TECO commands}
which can be used to define the variable MM FOO only during actual
DOCOND processing. Putting "MM FOO:lots of TECO commands" in the
local modes of the source file would define MM FOO at all times when
the file was being edited, not just during DOCOND processing.

DOCOND Node: Replace, Previous: Macros, Up: Top, Next: Run
Conditional Global Replacements.
If one pair of alternatives appears very frequently throughout the
text, it would be painful to replace it with a pair of conditionals
each time it is needed. The alternative is to use a conditional
global replacement declaration. One version can actually be used in
the text and then replaced by the other on the appropriate condition.
A global replacement declaration must appear in the declarations
section, and specifies a flag and setting as the condition, a string
to replace, and a string to replace with. For example,
{Replace:+FOO=>old->new}
says to replace old with new throughout, if FOO is +. Replacement is
done using 1mmReplace Stringoldnew, so that, among other things,
instances of "old" are found only when surrounded by delimiter
characters, and certain control characters must be quoted as described
under Replace String (*Note Repl: (EMACS)Replace.). Spaces are
significant, so don't put in any excess ones. Replacements, like
other declarations, are processed in serial order, but they do not
apply to the declarations section; only to the text after it.
For a more complicated action than just replacing one string with
another, you can direct an arbitrary TECO program to be run to turn
the old string into what you want. Do this by using "-->>" instead of
"->" and writing the TECO code instead of the string to replace with.
The difference between a -> replacement and a -->> replacement is the
difference between MM Query Replace and 1,MM Query Replace. Here is
an example:
{Replace:+FOO=>**-->>fkd fwk}
deletes every instance of "**" together with the following word.

DOCOND Node: Run, Previous: Replace, Up: Top
Running DOCOND.
The previous nodes tell everything about what to put in an input
file for DOCOND. This is how to use DOCOND to process one.
First, visit the input file, and do M-X Load LibDOCOND to load the
DOCOND program itself. Then, in the simplest case, just do M-X DOCOND.
DOCOND will ask you for the setting of each flag, processing
implications of settings as you tell them to it. When it knows all
the flag settings, it will process the buffer and return with
everything done.
To protect you from filing the output back over the input file,
DOCOND clears the visit file names as soon as it starts. Thus, C-X
C-S after DOCOND finishes will not be allowed. In addition, if there
are any changes in the buffer when DOCOND is started, it offers to
save them for you (if you don't save them, they will be lost).
Before starting the complete DOCOND processing, you can set
individual flags by means of the DOCOND Set Flag command present in
the DOCOND library. This command expects an argument which contains a
setting followed by a flag name, as in
M-X DOCOND Set Flag+FOO
The implications of the flags you set in this way will be processed as
soon as you do M-X DOCOND. DOCOND Set Flag is useful primarily for
having a large number of flags which are all normally "-". Rather
than asking you about each of them, you might prefer to have to do
DOCOND Set Flag for any that you wish to have "+", and let the rest be
forced to "-" by Default declarations.

197
doc/info/ledit.5 Executable file
View File

@@ -0,0 +1,197 @@
-*-Text-*-
This file documents the LEDIT package.

File: LEDIT Node: Top Up: (DIR) Next: Basics
LEDIT is a LISP/TECO interface package with the TECO half of the
system written as an EMACS library. The two basic functions of this
package are:
(i) To allow the user to type a command in LISP which will cause
control to be transferred to a TECO job, passing the TECO a string of
commands to be executed.
(ii) To allow the user in TECO to type a command which will cause
control to be transferred to a LISP job, passing to LISP a file of code
to be read.
These functions have been implemented so that both the LISP job and the
TECO job may be conveniently used independently concurrent with
their linking via LEDIT.
In addition, LEDIT is designed to be used with the TAGS package
and the EXPR-HASH feature of LISP .
* Menu:
* Basics:: Basic Instructions on Use of LEDIT
* Tags:: Using LEDIT with Tags
* Extras:: Extra and Advanced Features

File: LEDIT Node: BASICS Up: Top Next: TAGS Previous: Top
This node presents the simplest way to use LEDIT.
The LEDIT package autoloads into the standard LISP.
In your LISP type (LEDIT) or (LEDIT filename1 filename2 dev dir)
or (LEDIT (dev dir) filename1 filename2).
An EMACS job named LEDIT will be started. Your standard init file will
be read in if it exists. In addition, the library EMACS;LEDIT :EJ is
loaded with the following observable effects:
(i) You are in LISP mode.
(ii) The mode line has the extra word "LEDIT" after EMACS.
(iii) There is an empty buffer called *LEDIT* which will be used
to accumulate code to be returned to the LISP.
If in LISP you typed LEDIT with a filename argument, FIND FILE will
automatically be called in EMACS with the filename as argument.
Do your editting. You may treat this as a regular EMACS. You need
not return to the LISP. You may exit to DDT (however, be sure to
use ^R Return to Superior, which is ^Z on TV's and ^X^C otherwise),
proceed the LISP from DDT, and conduct business as usual.
However, if you are in EMACS and want to return directly to LISP,
you may do so by typing ^XZ. This will first call ^R Save File to
save the file in your current buffer, and then ^R Save All Files which
will query you to save any other modified files. It will then
write out the buffer *LEDIT* onto a temporary file and clear the
buffer, and finally pass control to the LISP with instructions to
read in the temporary file. If you want no saving by default
or querying to include the current buffer, there is a a q-register
switch to be set (*Note Extras: Extras.).
If you give a non-zero numeric argument to ^XZ (e.g. ^U^XZ), then
there will be no file saving this time.
A numeric argument of zero to ^XZ inhibits all actions other than
clearing of the *LEDIT* buffer and return to LISP.
There are commands in TECO to move code from the current buffer to the
*LEDIT* buffer, so that it may be sent back to the LISP eventually by
^XZ. These are:
M-Z Copies the current DEFUN (using ^R Mark Defun) to *LEDIT* buffer
M-C-Z Copies the current region to *LEDIT* buffer
If you give a numeric argument (e.g. ctl-U) to M-Z or M-C-Z, The *LEDIT*
buffer will be selected after the code is moved. This is useful for making
temporary editing changes, such as inserting breakpoints. First copy
the code in question to the *LEDIT* buffer, and then add the breakpoints
in the *LEDIT* buffer. This will guarantee that the breakpoints will never
be written into the original source file.
When you are back in the LISP, you may type (LEDIT) or (LEDIT f1 f2 dev dir)
to return to the TECO. Again, if a file name is given as argument,
FIND FILE is run as soon as control is given to the TECO.

File: LEDIT Node: TAGS Up: Top Next: Extras Previous: Basics
This node describes how LEDIT can be used in conjunction with the
TAGS package to allow the user to specify the LISP call to LEDIT
the name of a tag to be editted. The user should first be familiar
with INFO;TAGS > before continuing here.
If LEDIT is called with a single atomic argument e.g. (LEDIT foo),
then when control is passed to TECO, the macro FIND TAG is called
with the atomic argument.
Also, there is a global LISP variable LEDIT-TAGS, which is initially
nil. This can be set to the namestring of a tags file. When control
is first transferred to a LEDIT job from LISP, the macro VISIT TAG
TABLE will be automatically called with the namestring as string
argument.
The value of the global LISP variable LEDIT-TAGS-FIND-FILE is also
provided as the numeric argument to VISIT TAG TABLE. This
variable defaults to 1, which causes FIND TAG to use FIND FILE
instead of VISIT FILE. Set it to 0 to make FIND TAG use VISIT
FILE.

File: LEDIT Node: Extras Up: Top Previous: Tags
This nodes documents some extra and advanced features.
(i) One TECO may be shared by several LISP's. The TECO remembers the
last LISP job it was called from and returns to that one when
you type ^XZ.
(ii) The LISP variable LEDIT-JNAME is initialized to 'LEDIT. This
determines what job name the LISP will look for when it wants
a TECO. If a job exists with this name, it assumes it is an
LEDIT-type TECO (i.e. one which has had the LEDIT macro
library loaded in) and transfers control. If a job with this
name does not exist, one is created as described under node BASICS.
(iii) Any EMACS can be turned into an LEDIT, eligible to be called directly
from a LISP by the following macro call:
MM Load Library  EMACS;LEDIT
For example, you might want to put this in you EMACS init file and
then (if you always start emacs by E^K) you might put in your
LISP init:
(SETQ LEDIT-JNAME 'E)
(iv) If you use a different editor than EMACS, e.g. TME, the LISP
variable LEDIT-LOADFILE can be set to the namestring of the binary
file for the editor. It is initially '|SYS2;TS EMACS|.
(v) If you want to test out a different version of the LEDIT macro
library, the LISP variable LEDIT-LIBRARY may be set to the
namestring of the macro library to be loaded into newly created
LEDIT jobs. IT is initially '|EMACS;LEDIT|.
(vi) The switch LEDIT-DELETEF controls whether the temporary file
read in by LISP from TECO is deleted after. It is initally NIL,
meaning "don't delete".
(vii) The variable LEDIT-PRE-TECO-FUNC (initially nil) may be set
to a function to be called before going to TECO. It is
given one argument which is the list of arguments to LEDIT.
(viii) The variable LEDIT-POST-TECO-FUNC (initially nil) may be set
to a function to be called after return from TECO. It is
given one argument which is the name of the file read in.
(ix) The variable LEDIT-PRE-EVAL-FUNC (initially nil) may be set
to a function which can pre-process forms read in from TECO.
It is given the form read and returns the form LISP should
eval.
(x) The EMACS variable LEDIT SETUP HOOK may be used to cause
different assignment of the LEDIT Library macros to keys.
(xi) There is a macro ^R LEDIT Zap DEFUN to LISP which is currently
assigned to no key. I suggest assigning it to M-Z, since
the effect of the default assignment is easily achieved by
M-C-H M-C-Z. ^R LEDIT Zap DEFUN to LISP marks a DEFUN, copies
it to LEDIT, and then runs ^XZ, passing through its numeric
argument.
(xii) The default action on returning to LISP is to call ^R Save File
on the current buffer and ^R Save All Files to query about
saving all other modified buffers. If you wish no saving
by default, set QLEDIT Save All Files Query to 0
in your EMACS init; if you wish querying for all files
included the current one to be the default, set it to 1.
If you set QLEDIT Auto Save to non-zero, an auto-save
type save (numeric arg to ^R Save File) will be performed
for the current buffer. If you are also in Auto Save Mode,
the usual deleting of old files will occur.
(xiv) For those who like control characters, a function LEDIT-TTYINT
is provided on control-E. If you
follow the control-E with a space, it just does (LEDIT).
Otherwise, it reads an s-expression. If it is an atom,
it is taken as a tag, otherwise it is a filename.
NOTE: there is a bug in the LISP reader which has the
effect that if you type a single letter tag to ^E, the reader
hangs up until another token is typed. Then both
are read.

672
doc/info/rmail.37 Executable file
View File

@@ -0,0 +1,672 @@
-*-Text-*-

File: RMAIL Node: Top Up: (DIR) Next: DEFAULT
RMAIL is a program for reading and editing mail.
As you receive mail, it is put in your "mail file".
When you use RMAIL, the new mail is moved into an "RMAIL file"
which accumulates all your old mail. RMAIL then provides
you with convenient commands for looking at, editing, and
replying to that mail.
* Menu: To learn all about RMAIL, type "2" and then "N"'s.
If you know nothing about it, just start doing "N"'s.
* Default:: Invoking RMAIL to read your own mail
the usual way.
* Peruse:: Using RMAIL to look at someone else's mail.
* Update:: Invoking RMAIL if you don't keep your
mail files in the usual places.
* Options:: Once you are in RMAIL, how to do things.
* Printing:: Using RMAIL on a printing terminal.
* EMACS:: Using RMAIL under EMACS.
* GMSGS:: Using RMAIL to read system announcements as
well as personal mail.
* Insides:: Details for hackers.

File: RMAIL, Node: DEFAULT, Up: Top, Previous: Top, Next: Options
To invoke RMAIL in the usual way, just do
:RMAIL<cr>, or MM RMAIL inside an EMACS.
This will assume that you wish to edit your own mail and that
you keep your mail in the expected places.
If you use RMAIL, you don't have to discard your mail as soon
as you see it. You can save it instead, in what is known as an
"RMAIL file". Any mail that you save will automatically be found
the next time you use RMAIL, after all the new mail you have received.
In fact, every message is saved unless you give RMAIL a command to
delete it. So if you stop editing in RMAIL without looking over all
of your old saved mail, it will continue to be saved. Thus, your
RMAIL file can have new mail added whenever you run RMAIL, but
nothing every disappears from it except when you say so.
The normal place for your RMAIL file to live is under the name
<username> RMAIL on your working directory.
Once you have invoked RMAIL, you can begin reading, editing and
deleting messages. RMAIL uses single-character commands known
as "options". See the next node for how to use them.

File: RMAIL, Node: PERUSE, Up: Top, Next: Update, Previous: Default
Perusal mode:
In perusal mode, RMAIL can be used to look at (but not modify)
any files of mail. It is invoked with a command of this sort:
:RMAIL <file>,<file>,...
where the files listed are those to be examined. The default
for the first filespec is DSK:<hsname>;<xuname> MAIL.
The default for each other filespec is the previous file.
If only one filename is specified, it is the first filename.
"^A" may be used at the beginning of a filespec to represent
the default first filename, in case it is desired to change only the second.
Thus, "^ASENDS" will get the SENDS file for the user whose
name is the default at that moment.
All the files named are read in, concatenated together, in
the order they appear in the command string, and the first
message in the first newmail file is then displayed.
Editing may be done in perusal mode, but RMAIL will not write the
edited string into any file of its own accord. If you try to delete
messages, you will get an error message, on the grounds that you
probably don't realize that your changes will be lost.
The feature that used to exist, where <user>/ would specify that
user's mail file, has been removed temporarily due to the change in
where mail files are stored. When TECO gains tha ability to ask DDT
where a user's mail file is stored, this capability will exist again.

File: RMAIL, Node: UPDATE, Up: Top, Next: Options, Previous: Peruse
Update mode:
Update mode is RMAIL's normal mode, in which RMAIL intends to
write back all the changes you make permanently on disk, into a
file which is called "the RMAIL file". Your RMAIL file is a cumulative
record of all the mail you have received, as you have edited it in all
the times you have run RMAIL. Naturally, you shouldn't keep all the
mail you receive; when a message is no longer interesting, you should
tell RMAIL to delete it.
If you give RMAIL no command string at all when you invoke it, as in
:RMAIL<cr>, then RMAIL will operate in update mode, and it will assume
the standard default values for all the filenames it needs. If you
don't like the defaults, or you want to edit someone else's mail, you
can specify everything explicitly.
An update mode command string must specify the name of the RMAIL
file. In addition, it may specify the names of newmail files, whose
contents are to be read in and merged into the RMAIL file. They may
also be deleted after their contents have been safely written into the
RMAIL file - it depends on what you specify.
The LAST thing in an update mode command string is the RMAIL file
name, followed by an dollarsign. The dollarsign is what tells RMAIL
that you intend to use update mode and not perusal mode. Before the
RMAIL file name come the names of the newmail files if any. They are
specified just as in a perusal mode comand string. The last newmail
file name must be followed by a comma (or a slash), to separate it from
the RMAIL file name. A newmail file whose name is ended with a slash
will be deleted after its contents are merged into the RMAIL file. A
newmail file whose name is ended with a comma will not be deleted.
An example of an RMAIL command string specifying update mode is
:RMAIL <dir>;<user> MAIL/<dir>;<user> RMAIL$
which specifies (assuming that both <user>'s are identical)
that <user>'s mail file should be appended into <dir>;<user> RMAIL
and then deleted. RMAIL then edits the combined contents. After
editing, any results are again written into <dir>;<user> RMAIL.
If you fill your XUNAME in as <user> and your home directory
(HSNAME) in as <dir>, that is precisely what RMAIL does if given no
command string.
The default names for the rmail file are taken from the last newmail
file, except that the default second file name is always RMAIL.
Normally, newmail files are added at the front of the RMAIL
file, but if the RMAIL file starts with "*APPEND*<crlf>" then they are
added at the end instead. People who use R-OPTION APPEND in the
mailer to receive their mail in the order of oldest first should use
this.
In update mode, when you exit RMAIL (with the Q command), the
results of your editing are written back into the RMAIL file. You can
also save your editing so far at any time with the S command.
The I option switches into update mode, asking the user to specify
the name of the new rmail file. If RMAIL was already in update mode,
the old rmail file is written out (as by S).

File: RMAIL, Node: OPTIONS, Up: Top, Next: Printing, Previous: Update
RMAIL Commands ("Options"):
RMAIL is normally in option mode. In that mode, several
single-character commands, called options, are available,
including escapes into other modes.
If an unrecognized option is typed, a statement to that effect
will be typed out. The user then has another chance to type
an option, and is reminded that "?" types documentation.
Unless it says otherwise in the description of a particular
option, after any option is executed, the current message
will be displayed, and a new option will be awaited. In other
words, options normally do not leave option mode.
Some options read input during their operation, using ^R
mode. To quit out of such an option, use ^G or ^], which will
abort the operation and return to option mode.
The options are:
N move to Next message (then display it and read an option)
When looking at the last message, N does nothing but
notify the user of that fact.
N may be preceded by a decimal integer, which will act
as a repeat count. ZN is a good way to go to the last
message in the buffer.
D Delete the message and move to the next.
^D Delete the message and move to the previous.
U Undelete the last message deleted, putting it before
the message now current which had been current, and moving back
to it. Successive undeletes will undelete earlier
messages (the deleted messages live in a stack).
P move to the Previous message.
When looking at the first message, P does nothing but
notify the user of that fact.
P may be preceded by a decimal integer repeat count.
J Jump to message, specified by absolute number.
J goes to the first message, ZJ goes to the last,
and <n>J goes to message <n>.
SPACE move to the next screenful of a long message.
BACKSPACE move to the previous screenful.
. move to the beginning of the current message.
In addition, if more than one message is being looked
at (as, after a W option), "." will select just the
message that the pointer is inside. Thus, "."
is the "inverse" of W, in some ways.
; execute several options with no display between them.
An entire line is read in, with rubouts handled,
and then all the characters in the line are executed
as options with no intervening attempts to display.
Then, at the end, display is done.
R Reply to message. You are shown the skeleton of a message,
into which you can edit the values of the fields. The text of
the message should go below the line of dashes. The fields of
the header should go above them. Each field takes up one
line, and consists of the field name, a colon, and the field
value. You can alter or delete the supplied fields as you
wish, or add fields that are not present. The reply command
will intially fill in the fields it thinks are apropriate.
It tries to do the "right thing" on failed mail messages
returned by the comsat.
Currently recognized fields are:
To: There can be more then one line of To: fields. Each
To: field may have more than one receipient in it.
A copy of the message will go to each receipient in
a To: field and each one will appear in a To: line
in the header of all copies of the message sent out.
(Exception: only a single simple receipient and ITS
format.)
If the reply command is given an argument of 1 (1R),
then it copies all the receipients of the message being
replied to into the To: field of the reply being formed
before presenting it to the user for editing.
Cc: Just like To: except receipients listed under Cc: will
appear under a Cc: line on each copy of the message
sent out. If the reply command is given an argument
of 1 then all the Cc:'s in the message being replied
to will be copied.
Subject:
or S: A line to appear in the subject field of the message,
or the "Re" heading if ITS format. If there is a
subject field in the message being replied to then it
will be copied.
Header-Force:
or H: Values should be RFC733, NET or ITS. Says which type of
header the message being sent out should be formed with.
Replying to a non-ITS header with 1R will automatically
generate a Header-Force:RFC733.
Registered:
or R: Instructs the Comsat on whether to notify the sender
(return a receipt) indicating success or failure of
delivery. Values are N (no receipt), F (receipt on
failure only), or A (always receipt). Default is to
receipt unless mail was sent immediately (not queued),
unless this is overridden by your NAMES database entry.
C-C C-C (C-M-Altmode) (or ^C in TRMAIL) will end the editing
and send the message. RMAIL will return to option mode. C-]
quits out of the R option and returns to option mode without
mailing anything. That is what to do if you change your mind
about the reply. (Note that ^G will no longer perform this
function). The C command to rmail can be used to resume the
reply you quit out of.
While the reply is being edited, the character C-M-Y (^Y in
TRMAIL) is set up to insert the text of the message being
replied to, in case it is desirable to quote part of the
message in the reply. Some of the lines of the message
header will be omitted and the text will be indented by four
spaces unless you give C-M-Y a numeric argument.
C Continue editing a reply. After aborting an R or M
with C-], the C option "re-enters" the R or M where
it was aborted. In between the C-] and the C anything
except another R or M may be done. Note that if
the current message at the time of the C is not the same
as it was at the time of the R, the reply will still
contain the senduer of the message R'd (unless the user
had changed that himself), but C-M-Y will yank whatever
message is current at the time of the C.
M Mail a message. Like R, except that it presents you with
a completely empty message, with only a "From" field.
You must specify any recipients yourself.
O Output the message to a file - good for forwarding a
message to someone else's mail file; also good
for filing messages according to topics.
The filenames to use are read in echoing at the bottom of the
screen. The default names are the names used in the last "O"
option; they are typed out in parentheses.
In your input, a lone filename specifies the first filename
of the file to be written. End the input with a CR to tell
RMAIL to proceed, appending the current message to the front
of the specified file, which will be created if necessary.
However, if the file starts with "*APPEND*<crlf>", the new
message will go at the end instead of the front.
To abort the O command, type ^G.
Q Quit: kill the job and return control to DDT.
If an rmail file was specified, the current buffer
is written out into the rmail file first.
S Save: write the rmail file.
Does nothing if no rmail file was specified.
The RMAIL is NOT killed, so further editing may be
done.
I Inputs a new rmail file, and enters update mode.
If RMAIL was already in update mode, the old rmail
file is written out, as if the S option had been typed.
Then RMAIL reads in the name of the new RMAIL file to read
in, echoing it at the bottom of the screen. Terminate the
name with a CR. The defaults are the names of the old RMAIL
file. To abort the I command, type ^G.
G Gobble new mail. Saves the RMAIL file, if in update mode.
Then reads in any new mail, just as RMAIL does when it is
started up (with a null command string). This is useful if
you receive mail while in RMAIL and want to use RMAIL on it.
^C, ^Z just as in TECO; returns to DDT. When RMAIL is
proceeded, it will redisplay the screen.
^R escape into ^R mode to edit the message.
An altmode will return to option mode.
X eXecute an extended command. This is the same as Meta-X
in EMACS. Type the name of the extended command, an Altmode,
the arguments, and a carriage return.
ALTMODE
escape to the TECO interpreter (actually, the EMACS Minibuffer).
You may then type in one TECO command string, ended by
altmode altmode. After the command string is executed you
will return to option mode. While you are typing in the
command string, you may edit it, since you are in ^R mode.
L Show a List of all messages. This command puts on the
screen text that resembles the mail file except that
every message is truncated to 100 characters at most.
RMAIL then invokes ^R mode, which allows the user to
move the cursor to any message he desires. On exiting
from ^R, RMAIL will show and point at the message
which was selected in that manner.
Typing ^G will abort the L command, leaving the
old current message still current.
W show the Whole buffer. Normally, virtual buffer
boundaries are set up to restrict editing to a
single message. This option flushes them.
After doing a W, the option "." will
go back to the single message that the pointer
is in. P or N will do that and then move back
or forward. A D option is unwise after a W, but
one can recover from it using "$G9$$".
The W option is especially useful before a
^R or altmode.
F reads in a string, terminated by a CR, and searches
through all the remaining messages for the string.
It stops on the first message that contains the
string. To find the same string as last time, give
the null string as the argument (type just a CR).
To abort the F option, type ^G.
F starts searching from the cursor and leaves the
cursor after the string it finds, so it will never find
a single occurrence of the string more than once, but it
may find more than one occurrence in a single message.
^L clears the screen and redisplays.
^A redisplays keeping the cursor on the top line of the screen.
Useful if you're reading multi-screen message and have the
screen messaed up by line noise or getting a :SEND type message.
? shows a brief description of all available options.
The display will remain until a character is typed
in; that character will be used as an option.
RMAIL EXTENDED COMMANDS:
There are some extended commands which are useful within Rmail, and
are therefore loaded as part of the Rmail package. These can be
executed just like any other extended command from within Rmail, by
typing the X command and then the name of the extended command in the
usual fashion in response to the "M-X" prompt. [*Note M-X: (Emacs)M-X.]
The Rmail style arguments to the X command will show up as the
arguments to M-X.
Reformat Tenex Mail
takes the currently selected message as a Tenex format message
file and converts it to ITS format. Ie. the Tenex file probably
contained a lot of messages, but they all looked like one to
Rmail because they weren't separated by ^_'s. Reformating
deletes the header lines that Tenex mail format inserts between
messages and replaces them with ^_'s. Then one can use
normal Rmail commands to select the individual messages,
reaply to them etc.
Undigestify Mesage
Extracts the component messages from a digest message.
Digest messages are usually used on large mailing lists such
as HUMAN-NETS. All messages sent each day to the list are
packaged into one digest which is sent all at once.
This makes mailing more efficient. (*note DigFor: Format of digest.)
Undigestify divides the digest message back into the messages
that were packaged into it, so that Rmail treats them all as
separate messages (instead of treating the whole digest as one
message).
The numeric argument, if nonzero, says to keep a copy of the
digest in addition to the component messages.
The digest copy comes after the components if the arg is
negative; before, if the arg is positive.
If there is no arg at all, the value of the variable
Undigestify Keep Digest is used instead.
If the variable also does not exist, no copy is kept.

File: RMAIL, Node: Format of digest, Up: OPTIONS
For the benefit of those who want to create digests on their own,
here's a partial description of the format:
Date: 1 February 1983 02:00 EST
From: Gail Zacharias <GZ @ MIT-MC>
The digest format that undigestify wants is:
First word of message must be the list name. The topics section ends with
a line of 70 hyphens. The individual messages are separated by a blank line
followed by a line of 30 hyphens.

File: RMAIL, Node: Printing, Up: Top, Previous: Options, Next: EMACS
Using RMAIL on Printing Terminals:
RMAIL can be used on printing terminals, and the options generally
do the same things. However, messages are (by default) not
automatically printed when they are selected, as they are on displays.
Instead, give the T option to print the beginning of a message,
and Space to print the rest or a specified number of lines.
Here are the options provided especially for printing terminals:
T Type the beginning of the current message. Guaranteed
to go far enough to include the subject line, or the
first line of text if there is no subject. If the
message is very short, it will be typed in full;
otherwise, RMAIL will stop and say how many more lines
there are. If the average line length is greater than
the length of the terminal's line, RMAIL will put a star
after the number of lines; if greater than twice the
terminal width, two stars, etc.
Space Type all (the rest) of the current message. Starts
typing where the previous type-out command stopped.
With an argument, types as many lines as specified,
then says how many lines remain and --MORE-- again.
B types a Brief summary of the current message (with arg,
summarizes the next <n> messages). Here is a sample:
# Lines Date From Subject
1: 5 5 OCT 1976 012 [USER@SYSTEM] Ineresting discussions
2: 26 10/04/76 1121- [Pogran@Multics] Proposed RFC on ITS
3: 10 10/04/76 22:24 [RMS@AI] T: Since @ works fine on se
4: 193 10/03/76 19:26 [To: FOO@BAR, Mic] answer to your qu
The number under # is the position of the message in the
file; that number given to J will reselect it.
The Date and Subject fields are truncated to fit the space.
The "T:" in the "Subject" of message #3 shows that it is
actually the first text line, shown since the message has no
subject field. Message 4: was sent by the person reading
the mail, so instead of his name, the recipients' names
are shown (with "To:" to flag them) under "From".
The header line is printed only when B is given an argument.
A Advance to the next message and summarize it, a la B.
If your printing terminal is relatively fast, you might want to have
messages automatically printed when you move to a new one. To request
that, set the TECO variable QRMAIL Auto Type nonzero by doing
Altmode, then 1M.VRMAIL Auto Type. After this, every time you move
to a new message, or delete or undelete a message, an automatic "T"
option will be done.

File: RMAIL, Node: EMACS, Up: Top, Previous: Printing, Next: GMSGS
Using RMAIL under EMACS:
If you are an EMACS user, then you can run RMAIL inside of EMACS.
Then, when you use the M or R option to edit a reply, or the ^R option
to edit a message, you will have your EMACS environment to edit with
instead of the bare TECO environment. To do this, execute M-X Read
Mail<command string> in an EMACS. The command string is exactly as
described in the Peruse and Update mode sections for :RMAIL. Note
that for update mode you must use dollarsign, not altmode, to end the
RMAIL file name.
If you want to use the default files, you can do just M-X Read Mail,
or, even easier, C-X R (in the default EMACS environment).
Having invoked RMAIL in this way, you can get back out to EMACS
with the Q option as usual. You can also get out "temporarily"
with the ^X option, which does not write out the RMAIL file and
does not throw away any of RMAIL's data bases. Then, you can re-enter
RMAIL with a C-X R. You will be back where you were before the ^X.
Inside RMAIL, a buffer named *RMAIL* is always selected. This
buffer's major mode is Text Mode (unless you change it), and it
is visiting the RMAIL file (that's how the RMAIL file is remembered).
The I option is essentially the same as C-X C-V in EMACS.
The S option is essentially C-X C-S.
A few things about RMAIL work differently when RMAIL is run under
EMACS. For one thing, the ^R and L options that call ^R-mode
recursively must be exited with the EMACS command for doing that:
Control-Altmode OR C-C C-C.
The M and R reply-editing options are also different. To exit them
and send the reply, use C-M-C, the standard exit command. C-C does
not exit, so that you can use C-C as the Control-Meta prefix to type
the C-M-C. To yank in the message you are replying to, you must use
C-M-Y instead of simply C-Y - this leaves you the use of C-Y for
yanking back text you have killed. Altmode is not redefined, so you
can use it as a Meta-prefix. If you wish to insert an altmode, you
can use C-M-Altmode or C-Q Altmode.
To abort sending a message, use the C-] command (Abort Recursive
Edit), which is the standard way of getting out of all recursive
edits. To resume again after aborting, the C command is still good.
The M option of RMAIL is available independently from EMACS as
M-X Send Mail, or C-X M. With an argument, they do a C option (resume
editing an aborted or sent message). The C-X M creates a special
EMACS buffer named *Mail* for editing the message to be sent; this is
so that you can be editing the message in Text mode regardless of the
mode you were in when you gave the C-X M command. The M command
inside EMACS normally just uses a TECO buffer, so that the modes are
all inherited from the *RMAIL* buffer, which gives Text mode anyway.
If you want the RMAIL commands R, M and C to store the message to be
sent in a separate EMACS buffer, set the variable RMAIL Reply Buffer
to a string containing the desired EMACS buffer name. Normally RMAIL
Reply Buffer is zero or nonexistent before RMAIL is run, and RMAIL
replaces this with the TECO buffer object when the first R, M or C
command is executed.

File: RMAIL, Node: GMSGS, Up: Top, Previous: EMACS, Next: Insides
Using the GMSGS program to read system announcements.
The GMSGS program copies all system announcements that you have not
yet seen into your mail file as messages. Run GMSGS in your DDT init
file; then you can read the system announcements along with your
mail, using RMAIL or any other mail reading mechanism.
The usual way to invoke GMSGS is to do :GMSGS<cr> in DDT.
All system announcements created since the time you last looked at
them will be added to the front of your mail file in reverse
chronological order.
If you use (R-OPTION APPEND), you should say :GMSGS /R ("Reverse"),
which will add the announcements to the end of your mail file in
forward chronological order.
If there actually are any new announcements, GMSGS prints out
"(There are MSGS)". If you want to suppress this, give GMSGS the /S
(for "Silent") switch. On the other hand, you can give the /N
("Notify") switch and GMSGS will also tell you whether you have any
personal mail, typing "(There is mail)" if you do.
GMSGS can actually mail the messages to you instead of putting them
directly in your mail file. Usually the result is the same, but once
in a while there is some advantage in doing it this way. Give GMSGS
the /M switch to direct this to happen. If you are a real loser, you
can make GMSGS print the announcements on the terminal instead of
putting them in your mail file by using the /T ("Type") switch.
GMSGS usually does not copy the Expires: and Distrib: fields of
announcements. If you want to see them, specify the /D
("Distribution") switch.
Normally, GMSGS shows you only those announcements "addressed"
to the users of the machine you are on. These are the announcements
whose distribution specs include *FOO, where FOO is the machine you
are on. If you wish to see also announcements addressed to other
machines' users, specify in the arguments to GMSGS the names of the
machines you are interested in, with stars. For example,
:GMSGS *AI,*MC
will show you all announcements addressed to users of AI or MC.
:GMSGS * is equivalent to listing all the ITS systems, including
the BBOARD messages. *Note BBoard: (SYSMSG).
Finally, the way to create an announcement is to :MAIL to an
appropriate address, such as *AI or *MAC. RMAIL's and Babyl's options
are not suitable, because the MAIL program requests additional
information when the recipient you specify is an announcement sink.

File: RMAIL, Node: Insides, Up: Top, Previous: GMSGS
Random Information on How RMAIL Works:
RMAIL's messages all live in the buffer named RMAIL.
When RMAIL is entered, it pushes the current EMACS buffer and
selects (or creates) RMAIL. If the buffer is empty, RMAIL
reads in the mail files, etc. Q to exit kills the contents of
the buffer, so that the next invocation will read the files in again.
^X leaves the buffer untouched.
The RMAIL file is remembered as the file the buffer is visiting.
In peruse mode, the buffer isn't visiting any file.
RMAIL keeps data in several Q-registers.
QRMAIL Reply Buffer
The user may put the name of an Emacs buffer in this variable
before entering Rmail, and that buffer will be used for the M or R
commands. This is necessary if the user wants to have special
modes set for this buffer (eg. he might have a reply hook which
sets fill mode, or a particular fill column). If this variable is
not set, or 0, then an ordinary Teco buffer will be created, which
will inheret the modes of the previous buffer (when inside Rmail,
this will usually be text mode). In both cases this buffer stays
around between commands and can be gotten at with the C command,
or by giving a numeric argument to ^XM.
QRMAIL O Filename
holds the default filenames for the O option.
QRMAIL F Default
holds the last string specified in an "F".
QRMAIL Deletions
holds a buffer which holds all messages deleted with "D".
Exiting from RMAIL in any way leaves the O filename and the
F default untouched, so they will be remembered in the next
invocation. They may be preset before the first invocation
if desired. Exiting with Q clears out the RMAIL Deletions buffer
so that undeletion of its contents is not possible in the next
invocation. The RMAIL Reply Buffer always remains available
for re-use with a C command in the same invocation or a later one.
If QRMAIL Reply Hook is nonzero, then the R and M options
macro it. If you would like a few special commands while editing
replies, or you would like to have the normal extra commands on
different characters, you should put a string in this variable
to set them up. Remember to push any characters you change!
If you have a nonzero reply hook, R won't even try to bind
Altmode or ^C. In addition, R won't ever bind C-Y or Altmode
or ^C if they don't have their bare TECO definitions.
The input and output files are not clobbered by RMAIL.
Some options may clobber Q-regs 0 and 1, but I hope by now
those qregs are always saved and restored.
The sources for RMAIL are AI:EMACS1;RMAILX > and AI:EMACS1;RMAILZ >.
RMAILX contains the option-executing loop and the definitions
if the options, while RMAILZ processes the command string and
the input files. They are compiled together into a pure file,
EMACS;[RMAI] >, which is always read via the link EMACS;RMAIL :EJ.
Do MM Generate Library EMACS;[RMAI] > RMAILZ  RMAILX 
in an EMACS with the PURIFY library loaded, to update the
pure file after changing the sources.
See the comments at the front of each file for how to call
them and what they do with and to various qregs.
The stand-alone RMAIL is actually an EJ file which loads in
the RMAIL :EJ library and runs various macros. Changes in
RMAIL usually do not require altering it. When it is necessary
to redump the bootstrap, do ":TECO RMAIL;", if you have a macro
package that will take that to mean "run (INIT);RMAIL .TECO."
(as ALL macro packages morally should). This will write a file
EMACS;TSRMAI >, which SYS1;TS RMAIL is a link to.

825
doc/info/supgrf.1 Executable file
View File

@@ -0,0 +1,825 @@
SUPDUP GRAPHICS information (DCP 26-Aug-81)
Contains:
* Quick reference
* NWG/RFC# 746 SUPDUP Graphics Extension
* Raster bits extension
Quick reference section (numbers in octal):
Graphics mode entered by %TDGRF (231) and exited by anything with
200 bit set (%TDNOP (210) is the prefered way). %TDRST (230)
resets all graphics modes.
DRAW/ERASE commands:
%GO... 100
...D.. + (draw: 000,
...E.. erase: 040)
.....R + (relative: 000,
.....A absolute: 020)
+ function code:
00 undefined
....L. 01 <p> line
....P. 02 <p> point
....R. 03 <p> rectangle
....CH 04 <string> <0> characters (text)
....SC 05 <hairy> Scan lines
....RN 06 <hairy> Run-length encoded lines
07-17 undefined
Miscellaneous Commands:
Symbol Value no modifier modifier (with 020 bit set)
000 no-op
%GOMVR 001 <p> Move relative
%GOMVA 021 <p> Move absolute
%GOXOR 002 XOR mode ON
%GOIOR 022 XOR mode OFF
%GOSET 003 <n> Select set <n>
%GOMSR 004 <p> Move set origin relative
%GOMSA 024 <p> Move set origin absolute
%GOINV 006 Make current set invisisble
%GOVIS 026 Make current set visible
%GOBNK 007 Make current set blink
%GOCLR 010 Erase whole screen
%GOCLS 030 Erase current set
%GOPSH 011 Push status info
%GOVIR 012 Use virtual coordinates
%GOPHY 032 Use physical coordinates
%GOHRD 013 <n> Divert output to subdevice <n>
%GOGIN 014 <n> Request graphic input
%GOLMT 015 <p1> <p2> Limit graphics to subrectangle
<p> is a point; 14-bit two's complement signed number.
relative: <dx> <dy>, low seven bits of each
eg, (logand dx 177)
absolute: <x> <y>, 14 bits of each, low seven first
eg, (logand dx 177) followed by (logand (lsh dx -7) 177)
TTYSMT variable and screen dimensions:
%TQHGT,, 076000,,0 character height in dots
%TQWID,, 001700,,0 character width in dots
%TQVIR,, 000040,,0 terminal implements virtual coordinates
%TQBNK,, 000020,,0 terminal implements blinking
%TQXOR,, 000010,,0 terminal implements XOR mode
%TQREC,, 000004,,0 terminal implements rectangle commands
%TQSET,, 000002,,0 terminal supports multiple sets
%TQGRF,, 000001,,0 terminal understands graphics protocol
%TRGIN 0,,400000 terminal can provide graphics input
%TRGHC 0,,200000 terminal has hard copy device
%TRSCN 0,,040000 terminal implements raster commands (scan and run)
Screen width in dots is <width in chars>*<char width in dots>
Screen height in dots is <height in chars>*<char height in dots>
(0,0) is in the center of the screen.
( -<width/2>, -<height/2>) is lower left
(<width-1>/2,<height-1>/2) is upper right (two's complement fashion)
Following are the SUPDUP GRAPHICS EXTENSION paper written by RMS,
and following that is the RASTER BITS description written by DCP.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Network Working Group Richard Stallman
Request for Comments 746 MIT-AI
NIC 43976 17 March 1978
The SUPDUP Graphics Extension
... extends SUPDUP to permit the display of drawings on the
screen of the terminal, as well as text. We refer constantly to the
documentation of the SUPDUP protocol, described by Crispin in RFC 734
"SUPDUP Protocol".
Since this extension has never been implemented, it presumably
has some problems. It is being published to ask for suggestions, and
to encourage someone to try to bring it up.
The major accomplishments are these:
* It is easy to do simple things.
* Any program on the server host can at any time begin
outputting pictures. No special preparations are needed.
* No additional network connections are needed. Graphics
commands go through the normal text output connection.
* It has nothing really to do with the network. It is suitable
for use with locally connected intelligent display terminals
in a terminal-independent manner, by programs which need not
know whether they are being used locally or remotely. It can be
used as the universal means of expression of graphics output, for
whatever destination. Programs can be written to use it for
non-network terminals, with little loss of convenience, and
automatically be usable over the ARPA network.
* Loss of output (due, perhaps, to a "silence" command typed
by the user) does not leave the user host confused.
* The terminal does not need to be able to remember the
internal "semantic" structure of the picture being
displayed, but just the lines and points, or even just bits
in a bit matrix.
* The server host need not be able to invoke arbitrary
terminal-dependent software to convert a standard language
into one that a terminal can use. Instead, a standard
language is defined which all programmable terminals can
interpret easily. Major differences between terminals are
catered to by conventions for including enough redundant
information in the output stream that all types of terminals
will have the necessary information available when it is
needed, even if they are not able to remember it in usable
form from one command to another.
Those interested in network graphics should read about the
Multics Graphics System, whose fundamental purpose is the same, but
whose particular assumptions are very different (although it did
inspire a few of the features of this proposal).
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
SUPDUP Initial Negotiation:
One new optional variable, the SMARTS variable, is defined. It
should follow the other variables sent by the SUPDUP user process to
the SUPDUP server process. Bits and fields in the left half-word of
this variable are given names starting with "%TQ". Bits and fields in
the right half are given names starting with "%TR". Not all of the
SMARTS variable has to do with the graphics protocol, but most of it
does. The %TQGRF bit should be 1 if the terminal supports graphics
output at all.
Invoking the Graphics Protocol:
Graphics mode is entered by a %TDGRF (octal 231) code in the
output stream. Following characters in the range 0 - 177 are
interpreted according to the graphics protocol. Any character 200 or
larger (a %TD code) leaves graphics mode, and then has its normal
interpretation. Thus, if the server forgets that the terminal in
graphics mode, the terminal will not long remain confused.
Once in graphics mode, the output stream should contain a
sequence of graphics protocol commands, each followed by its
arguments. A zero as a command is a no-op. To leave graphics mode
deliberately, it is best to use a %TDNOP.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Co-ordinates:
Graphics mode uses a cursor position which is remembered from one
graphics command to the next while in graphics mode. The graphics
mode cursor is not the same one used by normal type-out: Graphics
protocol commands have no effect on the normal type-out cursor, and
normal type-out has no effect on the graphics mode cursor. In
addition, the graphics cursor's position is measured in dots rather
than in characters. The relationship between the two units (dots, and
characters) is recorded by the %TQHGT and %TQWID fields of the SMARTS
variable of the terminal, which contain the height and width in dots
of the box occupied by a character. The size of the screen in either
dimension is assumed to be the length of a character box times the
number of characters in that direction on the screen. If the screen
is actually bigger than that, the excess may or may not be part of
the visible area; the program will not know that it exists, in any
case.
Each co-ordinate of the cursor position is a 14-bit signed
number, where zero is at the center of the screen (if the screen
dimension is an even number of dots, then the visible negative points
extend one unit farther than the positive ones, in proper two's
complement fashion). Excessively large values of the co-ordinates
will be off the screen, but are still meaningful.
An alternate mode is defined, which some terminals may support,
in which virtual co-ordinates are used. The specified co-ordinates
are still 14-bit signed numbers, but instead of being in units of
physical dots on the terminal, it is assumed that +4000 octal is the
top of the screen or the right edge, while -4000 octal is the bottom
of the screen or the left edge. The terminal is responsible for
scaling these virtual co-ordinates into units of screen dots. Not all
terminals need have this capability; the %TQVIR bit in the SMARTS
variable indicates that it exists. To use virtual co-ordinates, the
server should send a %GOVIR; to use physical co-ordinates again, it
should send a %GOPHY. These should be repeated at intervals, such as
when graphics mode is entered, even though the terminal must attempt
to remember the state of the switch anyway. This repetition is so
that a loss of some output will not cause unbounded confusion.
The virtual co-ordinates are based on a square. If the visible
area on the terminal is not a square, then the standard virtual range
should correspond to a square around the center of the screen, and the
rest of the visible area should correspond to virtual co-ordinates
just beyond the normally visible range.
Graphics protocol commands take two types of cursor position
arguments, absolute ones and relative ones. Commands that take
address arguments generally have two forms, one for each type of
address. A relative address consists of two offsets, delta-X and
delta-Y, from the old cursor position. Each offset is a 7-bit two's
complement number occupying one character. An absolute address
consists of two co-ordinates, each 14 bits long, occupying two
characters, each of which conveys 7 bits. The X co-ordinate or offset
precedes the Y. Both types of address set the running cursor position
which will be used by the next address, if it is relative. It is
perfectly legitimate for parts of objects to go off the screen. What
happens to them is not terribly important, as long as it is not
disastrous, does not interfere with the reckoning of the cursor
position, and does not cause later objects, drawn after the cursor
moves back onto the screen, to be misdrawn.
Whether a particular spot on the screen is specified with an
absolute or a relative address is of no consequence. The sequence in
which they are drawn is of no consequence. Each object is independent
of all others, and exists at the place which was specified, in one way
or other, by the command that created it. Relative addresses are
provided for the sake of data compression. They are not an attempt to
spare programs the need for the meagre intelligence required to
convert between absolute and relative addresses; more intelligence
than that will surely be required for other aspects of the graphics
protocol. Nor are relative addresses intended to cause several
objects to relocate together if one is "moved" or erased. Terminals
are not expected to remember any relation between objects once they
are drawn. Most will not be able to.
Although the cursor position on entry to graphics mode remains
set from the last exit, it is wise to reinitialize it with a %GOMVA
command before any long transfer, to limit the effects of lost output.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Commands:
Commands to draw an object always have counterparts which erase
the same object. On a bit matrix terminal, erasure and drawing are
almost identical operations. On a display list terminal, erasure
involves searching the display list for an object with the specified
characteristics and deleting it from the list. Thus, on such
terminals you can erase an object only if precisely that object was
drawn, and was specified the same way when drawn as when erased.
(presumably; a very hairy program might allow more). Any terminal
whose %TOERS bit is set must be able to erase to at least that extent.
The commands to draw objects run from 100 to 137, while those to
erase run in a parallel sequence from 140 to 177. Other sorts of
operations have command codes below 100. Meanwhile, the 20 bit in the
command code says which type of addresses are used as arguments: if
the 20 bit is set, absolute addresses are used. Graphics commands are
given names starting with "%GO".
Graphics often uses characters. The %GODCH command is followed
by a string of characters to be output, terminated by a zero. The
characters must be single-position printing characters. On most
terminals, this limits them to ASCII graphic characters. Terminals
with %TOSAI set in the TTYOPT variable allow all characters 0-177.
The characters are output at the current graphics cursor position (the
lower left hand corner of the first character's rectangle being placed
there), which is moved as the characters are drawn. The normal
type-out cursor is not relevant and its position is not changed. The
cursor position at which the characters are drawn may be in between
the lines and columns used for normal type-out. The %GOECH command is
similar to %GODCH but erases the characters specified in it. To clear
out a row of character positions on a bit matrix terminal without
having to respecify the text, a rectangle command may be used.
Example:
The way to send a simple line drawing is this:
%TDRST ;Reset all graphics modes.
%TDGRF ;Enter graphics.
%GOCLR ;Clear the screen.
%GOMVA xx yy ;Set cursor.
%GODLA xx yy ;Draw line from there.
<< repeat last two commands for each line >>
%TDNOP ;Exit graphics.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Graphics Input:
The %TRGIN bit in the right half of the SMARTS variable indicates
that the terminal can supply a graphic input in the form of a cursor
position on request. Sending a %GOGIN command to the terminal asks to
read the cursor position. It should be followed by an argument
character that will be included in the reply, and serve to associate
the reply with the particular request for input that elicited it. The
reply should have the form of a Top-Y character (code 4131), followed
by the reply code character as just described, followed by an absolute
cursor position. Since Top-Y is not normally meaningful as input,
%GOGIN replies can be distinguished reliably from keyboard input.
Unsolicited graphic input should be sent using a Top-X instead of a
Top-Y, so that the program can distinguish them. Instead of a reply
code, for which there is no need, the terminal should send an encoding
of the buttons pressed by the user on his input device, if it has more
than one.
Sets:
Terminals may define the concept of a "set" of objects. There
are up to 200 different sets, each of which can contain arbitrarily
many objects. At any time, one set is selected; objects drawn become
part of that set, and objects erased are removed from it. Objects in
a set other than the selected one cannot be erased without switching
to the sets that contain them. A set can be made temporarily
invisible, as a whole, without being erased or its contents forgotten;
and it can then be made instantly visible again. Also, a whole set
can be moved. A set has at all times a point identified as its
"center", and all objects in it are actually remembered relative to
that center, which can be moved arbitrarily, thus moving all the
objects in the set at once. Before beginning to use a set, therefore,
one should "move" its center to some absolute location. Set center
motion can easily cause objects in the set to move off screen. When
this happens, it does not matter what happens temporarily to those
objects, but their "positions" must not be forgotten, so that undoing
the set center motion will restore them to visibility in their
previous positions. Sets are not easily implemented on bit matrix
terminals, which should therefore ignore all set operations (except,
for a degenerate interpretation in connection with blinking, if that
is implemented). The %TQSET bit in the SMARTS variable of the
terminal indicates that the terminal implements multiple sets of
objects.
On a terminal which supports multiple sets, the %GOCLR command
should empty all sets and mark all sets "visible" (perform a %GOVIS on
each one). So should a %TDCLR SUPDUP command. Thus, any program
which starts by clearing the screen will not have to worry about
initializing the states of all sets.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Blinking:
Some terminals have the ability to blink objects on the screen.
The command %GOBNK meaning make the current set blink. All objects in
it already begin blinking, and any new objects also blink. %GOVIS or
%TOINV cancels the effect of a %GOBNK, making the objects of the set
permanently visible or invisible. %TQBNK indicates that the terminal
supports blinking on the screen.
However, there is a problem: some intelligent bit matrix
terminals may be able to implement blinking a few objects, if they are
told in advance, before the objects are drawn. They will be unable to
support arbitrary use of %GOBNK, however.
The solution to the problem is a convention for the use of %TOBNK
which, together with degenerate definitions for set operations, makes
it possible to give commands which reliably work on any terminal which
supports blinking.
On a terminal which sets %TQBNK but not %TQSET, %GOBNK is defined
to cause objects which are drawn after it to be drawn blinking.
%GOSET cancels this, so following objects will be drawn unblinking.
This is regardless of the argument to the %GOSET.
Thus, the way for a program to work on all terminals with %TQBNK,
whether they know about sets or not, is: to write a bliniking
picture, select some set other than your normal one (set 1 will do),
do %GOBNK, output the picture, and reselect set 0. The picture will
blink, while you draw things in set 0. To draw more blinking objects,
you must reselect set 1 and do another %GOBNK. Simply reselecting set
1 will not work on terminals which don't really support sets, since
they don't remember that the blinking objects are "in set 1" and not
"in set 0".
Erasing a blinking object should make it disappear, on any
terminal which implements blinking. On bit matrix terminals, blinking
MUST always be done by XORing, so that the non-blinking background
is not destroyed.
%GOCLS, on a terminal which supports blinking but not sets,
should delete all blinking objects. Then, the convention for deleting
all blinking objects is to select set 1, do a %GOCLS, and reselect set
0. This has the desired effect on all terminals. This definition of
%GOCLS causes no trouble on non-set terminals, since %GOCLS would
otherwise be meaningless to them.
To make blinking objects stop blinking but remain visible is
possible with a %GOVIS on a terminal which supports sets. But in
general the only way to do it is to delete them and redraw them as
permanent.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Rectangles and XOR Mode:
Bit matrix terminals have their own operations that display list
terminals cannot duplicate. First of all, they have XOR mode, in
which objects drawn cancel existing objects when they overlap. In
this mode, drawing an object and erasing it are identical operations.
All %GOD.. commands act IDENTICALLY to the corresponding %GOE..'s.
XOR mode is entered with a %GOXOR and left with a %GOIOR. Display
list terminals will ignore both commands. For that reason, the
program should continue to distinguish draw commands from erase
commands even in XOR mode. %TQXOR indicates a terminal which
implements XOR mode. XOR mode, when set, remains set even if graphics
mode is left and re-entered. However, it is wise to re-specify it
from time to time, in case output is lost.
Bit matrix terminals can also draw solid rectangles. They can
thus implement the commands %GODRR, %GODRA, %GOERR, and %GOERA. A
rectangle is specified by taking the current cursor position to be one
corner, and providing the address of the opposite corner. That can be
done with either a relative address or an absolute one. The %TQREC
bit indicates that the terminal implements rectangle commands.
Of course, a sufficiently intelligent bit matrix terminal can
provide all the features of a display list terminal by remembering
display lists which are redundant with the bit matrix, and using them
to update the matrix when a %GOMSR or %GOVIS is done. However, most
bit matrix terminals are not expected to go to such lengths.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
How Several Process Can Draw On One Terminal Without Interfering With
Each Other:
If we define "input-stream state" information to be whatever
information which can affect the action of any command, other than
what is contained in the command, then each of the several processes
must have its own set of input-stream state variables.
This is accomplished by providing the %GOPSH command. The %GOPSH
command saves all such input-stream information, to be restored when
graphics mode is exited. If the processes can arrange to output
blocks of characters uninterruptibly, they can begin each block with a
%GOPSH followed by commands to initialize the input-stream state
information as they desire. Each block of graphics output should be
ended by a %TDNOP, leaving the terminal in its "normal" state for all
the other processes, and at the same time popping the what the %GOPSH
pushed.
The input-stream state information consists of:
The cursor position
the state of XOR mode (default is OFF)
the selected set (default is 0)
the co-ordinate unit in use (physical dots, or virtual)
(default is physical)
whether output is going to the display screen or to a hardcopy
device (default is to the screen)
what portion of the screen is in use
(see "Using Only Part of the Screen")
(default is all)
Each unit of input-stream status has a default value for the sake
of programs that do not know that the information exists; the
exception is the cursor position, since all programs must know that it
exists. A %TDINI or %TDRST command should set all of the variables to
their default values.
The state of the current set (whether it is visible, and where
its center is) is not part of the input-stream state information,
since it would be hard to say what it would mean if it were. Besides,
the current set number is part of the input-stream state information,
so different processes can use different sets. The allocation of sets
to processes is the server host's own business.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Using Only Part of the Screen:
It is sometimes desirable to use part of the screen for picture
and part for text. Then one may wish to clear the picture without
clearing the text. On display list terminals, %GOCLR should do this.
On bit matrix terminals, however, %GOCLR can't tell which bits were
set by graphics and which by text display. For their sake, the %GOLMT
command is provided. This command takes two cursor positions as
arguments, specifying a rectangle. It declares that graphics will be
limited to that rectangle, so %GOCLR should clear only that part of
the screen. %GOLMT need not do anything on a terminal which can
remember graphics output as distinct from text output and clear the
former selectively, although it would be a desirable feature to
process it even on those terminals.
%GOLMT can be used to enable one of several processes which
divide up the screen among themselves to clear only the picture that
it has drawn, on a bit matrix terminal. By using both %GOLMT and
distinct sets, it is possible to deal successfully with almost any
terminal, since bit matrix terminals will implement %GOLMT and display
list terminals almost always implement sets.
The %TDCLR command should clear the whole screen, including
graphics output, ignoring %GOLMT.
Errors:
In general, errors in graphics commands should be ignored.
Since the output and input streams are not synchronized unless
trouble is taken, there is no simple way to report an error well
enough for the program that caused it to identify just which command
was invalid. So it is better not to try.
Errors which are not the fault of any individual command, such as
running out of memory for display lists, should also be ignored as
much as possible. This does NOT mean completely ignoring the commands
that cannot be followed; it means following them as much as possible:
moving the cursor, selecting sets, etc. as they specify, so that any
subsequent commands which can be executed are executed as intended.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Extensions:
This protocol does not attempt to specify commands for dealing
with every imaginable feature which a picture-drawing device can have.
Additional features should be left until they are needed and well
understood, so that they can be done right.
Storage of Graphics Commands in Files:
This can certainly be done. Since graphics commands are composed
exclusively of the ASCII characters 0 - 177, any file that can hold
ASCII text can hold the commands to draw a picture. This is less
useful than you might think, however. Any program for editing, in
whatever loose sense, a picture, will have its own internal data which
determine the relationships between the objects depicted, and control
the interpretation of the programs commands, and this data will all be
lost in the SUPDUP graphics commands for displaying the picture.
Thus, each such program will need to have its own format for storing
pictures in files, suitable for that program's internal data
structure. Inclusion of actual graphics commands in a file will be
useful only when the sole purpose of the file is to be displayed.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Note: the values of these commands are represented as 8.-bit octal
bytes. Arguments to the commands are in lower case inside angle
brackets.
The Draw commands are:
Value Name Arguments
101 %GODLR <p>
Draw line relative, from the cursor to <p>.
102 %GODPR <p>
Draw point relative, at <p>.
103 %GODRR <p>
Draw rectangle relative, corners at <p> and at the
current cursor position.
104 %GODCH <string> <0>
Display the chars of <string> starting at the current
graphics cursor position.
121 %GODLA <p>
Draw line absolute, from the cursor to <p>.
The same effect as %GODLR, but the arg is an absolute
address.
122 %GODPA <p>
Draw point absolute, at <p>.
123 %GODRA <p>
Draw rectangle absolute, corners at <p> and at the
current cursor position.
The Erase commands are:
Value Name Arguments
141 %GOELR <p>
Erase line relative, from the cursor to <p>.
142 %GOEPR <p>
Erase point relative, at <p>.
143 %GOERR <p>
Erase rectangle relative, corners at <p> and at the
current cursor position.
144 %GOECH <string> <0>
Erase the chars of <string> starting at the current
graphics cursor position.
161 %GOELA <p>
Erase line absolute, from the cursor to <p>.
162 %GOEPA <p>
Erase point absolute, at <p>.
163 %GOERA <p>
Erase rectangle absolute, corners at <p> and at the
current cursor position.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
The miscellaneous commands are:
Value Name Arguments
001 %GOMVR <p>
Move cursor to point <p>
021 %GOMVA <p>
Move cursor to point <p>, absolute address.
002 %GOXOR
Turn on XOR mode. Bit matrix terminals only.
022 %GOIOR
Turn off XOR mode.
003 %GOSET <n>
Select set. <n> is a 1-character set number, 0 - 177.
004 %GOMSR <p>
Move set origin to <p>. Display list terminals only.
024 %GOMSA <p>
Move set origin to <p>, absolute address.
006 %GOINV
Make current set invisible.
026 %GOVIS
Make current set visible.
007 %GOBNK
Make current set blink. Canceled by %GOINV or %GOVIS.
010 %GOCLR
Erase whole screen.
030 %GOCLS
Erase entire current set (display list terminals).
011 %GOPSH
Push all input-stream status information, to be
restored when graphics mode is exited.
012 %GOVIR
Start using virtual co-ordinates
032 %GOPHY
Resume giving co-ordinates in units of dots.
013 %GOHRD <n>
Divert output to output subdevice <n>.
<n>=0 reselects the main display screen.
014 %GOGIN <n>
Request graphics input (mouse, tablet, etc).
<n> is the reply code to include in the answer.
015 %GOLMT <p1> <p2>
Limits graphics to a subrectangle of the screen.
%GOCLR will clear only that area. This is for those
who would use the rest for text.
NWG/RFC# 746 RMS 17-MAR-78 43976
SUPDUP Graphics Extension
Bits in the SMARTS Variable Related to Graphics:
Note: the values of these bits are represented as octal 36.-bit words,
with the left and right 18.-bit halfword separated by two commas as in
the normal PDP-10 convention.
Name Value Description
%TQGRF 000001,,0 terminal understands graphics protocol.
%TQSET 000002,,0 terminal supports multiple sets.
%TQREC 000004,,0 terminal implements rectangle commands.
%TQXOR 000010,,0 terminal implements XOR mode.
%TQBNK 000020,,0 terminal implements blinking.
%TQVIR 000040,,0 terminal implements virtual co-ordinates.
%TQWID 001700,,0 character width, in dots.
%TQHGT 076000,,0 character height, in dots.
%TRGIN 0,,400000 terminal can provide graphics input.
%TRGHC 0,,200000 terminal has a hard-copy device to which output
can be diverted.
Proposed extensions to the SUPDUP Graphics Extension (NWG/RFC#
746 set forth by RMS 08-MAY-78). Written by DCP, summer 1981.
Objective:
Allow rasters to be sent to terminals that support it --
useful for the transmission of pictures. Rasters can include raw
scan lines and run-length encoding.
Extensions to the SMARTS variable related to graphics:
Name Value Description
%TRSCN 0,,040000 terminal implements raster operations (raw
scan lines being sent to it, as well as run
length encoding).
Extensions to the DRAW and ERASE commands:
Value Name Arguments
105 %GODSC <scan bits> <scan terminator>
Draw scan bits starting at the current graphics
cursor position.
106 %GODRN <run-length-encodings> <0>
Draw bits determined by <run-length-encodings>
starting at the current graphics cursor
position.
145 %GOESC <scan bits> <scan terminator>
Erase scan bits starting at the current graphics
cursor position.
146 %GOERN <run-length-encodings> <0>
Erase bits determined by <run-length-encodings>
starting at the current graphics cursor
position.
Functional description:
Scans:
Nearly all graphics systems in use today that can support
writing bits onto the graphics memory deal with multiples of 8
bits (if they have any such restriction at all). The PDP-11
family normally deals with 16.-bit words. VAXes deal with 16.-bit
or 32.-bit data. The PDP-10 has the capacity to deal with 36.-bit
values, but usually discards the low 4 bits to be compatible with
PDP-11s which often talk with the PDP-10. It is therefore
desirable to send data to graphics terminal in some multiple of
8.-bits.
The graphics protocol does not allow raw 8.-bit data to
be sent, because if the 200 (octal) bit is set graphics mode is
exited and the code is interpreted as a SUPDUP %TD code.
Therefore, a non-8.-bit scheme must be used to transfer the scan
line. The way this is to be done is to use 16.-bits as the basic
unit of data, and send it in chunks of 6-bits 6-bits 4-bits. As
always, if the 200 bit is set, it is a %TD code and should be
interpreted as such. If the 100 bit is set on a character, the
character is gobbled, not used for the scan line, and SCAN mode
is exited. The byte with the 100 bit set is the <scan terminator>
mentioned in the %GODSC and %GOESC commands.
In PDP-10s scans are usually kept in the high 32. bits
of 36. bit words. To convert this to the 6-6-4 scheme the
following works and is believed to be efficient (A must be an
accumulator):
<send %GO(D E)SC to get things started>
<get pointer to beginning of scan line into A>
HRLI A,440600 ;SIX BIT BYTE POINTER FOR NOW
LOOP: ILDB B,A ;GET SIX BITS
<process>
ILDB B,A ;GET ANOTHER 6 BITS
<process>
TLC A,000600#000400 ;CONVERT FROM 6 BITS TO 4
ILDB B,A ;GET 4 BITS
<process>
TLC A,000600#000400 ;CONVERT FROM 4 BITS TO 6
<JRST to LOOP if not finished>
<send byte with 100 or 200 bit set to exit SCAN mode>
Run length encoding:
Run length encoding is an efficient method to draw a long
sequence of OFF bits or ON bits. Its commands are basically draw
<n> dots of OFF bits and draw <n> dots of ON bits. Therefore new
information about a scan line needs to be sent only when the scan
line changes from an OFF bit to an ON bit, or vice versa.
After run-length-encoding mode is entered, a zero byte
will exit, a byte with the 200 bit will exit in the usual fashion
and be reinterpreted as a %TD code -- all other bytes are
run-commands. The low six bits of the byte are a count
determining how many bits to draw. If the 100 bit is on, ON bits
are drawn. If the 100 bit is off, OFF bits are drawn.
Suggestions:
DO NOT use vitual coordinates for setting the graphic
cursor and then sending raster information -- the picture will
probably be wrong. Instead, always use physical coordinates.
Considerations:
OFF (or zero) bits for raster lines should do the same
thing as the OFF bits in characters do. This probably amounts to
nothing, i.e., the bits are not cleared, but rather left alone.
This allows character drawing not to erase a graphic line that
may be under the character. In SCAN mode this means the scan bits
are ORed with the existing bits already on the screen. (Of
course, erase mode does bit clearing (BIC on PDP-11, ANDCAM on
PDP-10) and XOR mode does XORing.) In RUN-LENGTH-ENCODING mode
this means that OFF bits simply skip the corresponding display
bits without affecting them.

244
doc/info/tdebug.12 Executable file
View File

@@ -0,0 +1,244 @@
-*-TEXT-*-

Node: Top Next: Args Up: (DIR)
This describes TDEBUG, a package of Teco macros for debugging
Teco macros. Provision is made for macro stack examination, editing,
stepping, and q-register pdl examination.
By executing MM Debug Mode$, a minibuffer is entered. The commands
typed into this minibuffer will be stepped. The debugger can also be
entered by code hitting a user placed breakpoint. When the debugger is
entered, the screen is split into two windows, with the current buffer
displayed in the top window, and the current macro frame in the bottom
buffer. There is an area between the window, that contains information
about the current macro frame. When loaded, the debugger also becomes
the default error handler, replacing the standard EMACS Backtrace. The
stepper can break at the start of any macro invocation, a succeeding
conditional, or after a control-m <CR>. It cannot break in the middle
of a line unless a breakpoint is explicitly placed there.
*Note Exit: Execution. Whether you will actually see a break, of course,
depends upon what commands you have typed.
* Menu: Minimum abbreviations: A Br S Ed Ex Di Q Do Bu I F
* Args:: Command arguments
* Breakpoints:: Placing and removing Breakpoints
* Stack:: Macro stack manipulation
* Editing:: ^R on the macro frame or buffer
* Execution:: Stepping, etc.
* Display:: Controlling display
* QPdl:: Display of QPdl slots
* Documentation::
* Bugs:: Bugs
* Insides:: Helpful notes about implementation and modification
* Future:: Future features (sigh)

Node: Args Next: Breakpoints Previous: Top Up: Top
Some commands may take prefix arguments which are entered by
typing the digits. Rubout will flush any accumulated argument. An
equals sign "=" will do nothing but type (and flush) its arg. All
arguments default to 1.

Node: Breakpoints Next: Stack Previous: Args Up: Top
There is a facility for placing and removing breakpoints, via
the MM Break$ and MM Unbreak$ commands. The MM Break$ command takes
a string argument, and installs a breakpoint in that macro. The
MM Unbreak$ command, removes the breakpoint from a macro if given a
macro name, or removes all breakpoints if no macro name is given. Both
of these macros try to be clever about not breakpointing a macro that
is already has a breakpoint installed, and not removing breakpoints
from the macro, if it has changed. Thus it is hard to screw yourself
by putting a breakpoint it a macro, recompiling it, and then trying to
unbreakpoint the same macro.
The way a macro is breakpointed is to install a call to
MM & Tdebug Breakpoint$ on the front of the macro. The user can thus
install one of these in a macro to signal an error condition if he
likes.
One problem with breakpoints currently is that if you are not
already in the debugger when you hit a breakpoint, you will not be
able to step past that breakpoint. This is because the step macro will
not be set up outside this explicit call to the debugger. You will end
up in debug mode, and be able to examine the stack however. If you
were previously in the debugger, all facilities will be available when
you hit a break point.

Node: Stack Next: Editing Previous: Breakpoints Up: Top
When inside the debugger, the scope of the stack is normally
all levels of macro invocations since entering the debugger at the
lowest level. Thus recursive entries to the debugger (like hitting a
breakpoint while you are stepping) still allow you to examine the
entire stack. While this is normally true, it is possible to get the
debugger allow access to the entire stack, by way of whole stack mode.
The commands listed here may take prefix arguments as described above.
"D" or <lf> will move down the stack, to earlier macro
invocations.
"U" or "^" will move up the stack, to more recent invocations.
If you go past the end of the stack in either direction, an "out
of range" message will be displayed.
"W" toggles whole stack mode. When in whole stack mode, the
debugger allows examination of the entire macro and q-register stack.
When in non whole stack mode, it limits its displays to only the
macros invoked, and q-registers pushed since entering the debugger.
The exception to this, is when the debugger is entered by a breakpoint
or an error, in which case, since the debugger does not know what part
of the stack is of interest to the user, it enables whole stack mode.

Node: Editing Next: Execution Previous: Stack Up: Top
^R-style editing can be done on the macro frame, the current
buffer, a fresh buffer, or a minibuffer.
"^R" will call ^R on the presently displayed macro frame. This
might be useful in case not all of the frame can be seen in the window,
or else to set point for later use *Note ^R: Execution.
"B" calls ^R on the presently displayed buffer (q..o).
"\" will call ^R on an fresh, empty buffer displayed in the
upper window. This is intended for patching and/or random ^R hacking
where doing it in the "real" buffer or the macro frame might be
inconvenient. When the ^R is exited, its buffer disappears completely.
<Altmode> will cause the familiar minibuffer to appear. Q..O
is set to the "real" buffer, rather than the macro frame" buffer (which
is inaccessable through this minibuffer). If you really want a
minibuffer to hack the macro frame buffer, do "M".
"M" will cause the familiar minibuffer to appear, for hacking
the macro frame buffer.
Node: Execution Next: Display Previous: Editing Up: Top
The available commands for controlling macro execution are:
abort; two flavors of stepping; level exiting; and three (count them, 3)
synonyms for exiting.
"Q" will abort any and all macro levels called since the last
invocation of ^R and exit the debugger.
"^N" (control-N) or space will break at the next opportunity,
whether it be at the current macro level or at another. <Arg>^N,
strangely enough, will break at the <arg>th next opportunity. "^N" is
sort of analogous to DDT's "^N" command.
"N" will break only when the pc is greater than or equal to
point in the currently displayed frame. Thus a succession of "N"s will
step line by line through the current macro level, stepping over called
macros. In this sense, "N" is analogous to DDT's $$^N. <Arg>N will do
"N" <arg> times.
Another use for "N" is to proceed directly to some point other
than the next line in the current frame. This would be done by doing
"D" or "U" to get to the desired macro level, doing "^R" so that point
can be moved around, exiting the "^R", and finally doing the "N".
"L" is used for exiting from <arg> levels of macro invocation,
in analogy to DDT's "P,$$^N". This would be useful in case you ^N'ed
into a macro level but then wanted to get out. The "L" command is
functionally equivalent to "<arg>D N".
"X", and control-altmode all exit from step mode, clearing
the bottom window, and continue macro execution.
At present, don't "N" past the end of a macro, or else you will
invisibly step through untold volumes of macros, finally breaking
inside the next macro that is invoked at that macro level, and has a
line past the current point.

Node: Display Next: QPdl Previous: Execution Up: Top
Since we are trying to display two "buffers" in two windows with
important information in both windows being communicated by the position
of the single console "hardware" cursor, the command "." is provided to
switch the cursor between windows.
In the case of display lossage, "^L" (control-L) will clear the
entire screen, and redisplay both windows.

Node: QPdl Next: Documentation Previous: Display Up: Top
There are two modes in general for displaying the contents of
a teco object. These are toggled by the command "F", which toggles full
display of Q-Vectors, and prints in a slightly more lucid format. This
is the default printing mode. The other mode is slightly more concise,
as it is somewhat a relic of the past.
"<Arg>S" will type some information about the home and contents
of q-register pdl slot <arg>. Just typing "S" will at least tell you
how many slots are presently in use (including those used by the break
macro itself).
"H" displays the same stuff as "S" for all qpdl slots, starting
from the top of the pdl and going down. <Arg>H will display only the
top <arg> slots. The slot contents are displayed with a HV, so if you
see a --MORE-- you can give it a space to see the next screenful. Whole
stack mode controls whether you see the entire qpdl, or just the qpld
pushed since the debugger was entered. *Note Whole: Stack.
"V" will prompt you for a q register name, and display it's
contents in the same format as S. This uses the EMACS macro
MM & Read Q-Reg Name to read the name of the Q-register, and is able
to display single elements of a Q-Vector.

Node: Documentation Next: Bugs Previous: QPdl Up: Top
Typing a "?" when in a breakpoint will print some initial
identification as to what the darn thing's doing, and offer to enter
"documentation" mode if you type another "?". If you do, the macro
& Debug Describe$ will run, entering a loop asking you to type the name
of a debug command character, or else a "*" (to see the list of
available commands). To get out of the loop, type a space when you can.

Node: Bugs Next: Insides Previous: Documentation Up: Top
Present bugs and misfeatures:
1) There still are problems with redisplay of the macro frame when it
is not necessary.
2) Some portions of the debugger does not conform with Emacs
conventions about recursive ^R mode.
3) Stepping off the end of a macro with N should probably cause a
break at the next level up.
4) For some reason moving forward with ^R in the macro buffer, and the
doing an "N" stops at conditionals, before the point where you did the
"N".

Node: Insides Next: Future Previous: Bugs Up: Top
As you might have guessed, this all works by using Teco's
FS Step Macro$ and FS Backtrace$ flags. Each time the step handler (in
& Tdebug Break) runs, it decides whether to break. The decision is made in
terms of four cases:
1) If its arg is negative (as set by MM& Tdebug Breakpoint which
calls it), it always breaks.
2) If it was proceeded by ^N or space the last time, then exit if the
count hasn't expired, otherwise break
3) If it was proceeded by N or L, and we are at or past the point
where we were the last time, check the count, otherwise just exit.
4) If the code we are about to look at is internal Teco code, just return.
The commands are dispatched by doing M(M.MTdebug # <ch>$);
hence user additions or modifications to what the commands do is
straightforward. Hopefully, the documentation stuff will also win for
such additions.

Node: Future Previous: Insides Up: Top
Future Features and mods (sigh...)
1) A way of keying QPdl levels to macro invocation levels.