% -*-LaTeX-*-
% <BEEBE.TEX.DVI.DOC>DVIDRIVER.LTX.314, 13-Apr-87 15:50:11, Edit by BEEBE
% Reduce from 12pt Version 2.0 to 11pt Version 2.07
 \documentstyle[titlepage,11pt,twoside,texindex,dvidriver]{article}

% Bug report rewards ($0.64 each):
% dispchar.h section -- ``previous'' --> ``later'' (John Wilkes, HP labs)
% initglob.h section -- ``Allow'' --> ``although'' (John Wilkes, HP labs)
% dvijet.c section -- no such ``enhanced'' LaserJet (John Wilkes, HP labs)

 \title{A \protect\TeX{} DVI Driver Family}

 \author{Nelson H.F. Beebe\\
Center for Scientific Computation\\
220 South Physics Building\\
University of Utah\\
Salt Lake City, UT 84112\\
USA\\
 \medskip
Tel: (801) 581-5254\\
 \medskip
EMAIL: Beebe@Science.Utah.Edu (Internet)
}

% Previous editions:
%       26 March 1986 --- Revision 2.0
 \date{15 April 1987 --- Revision 2.07}

 \makeindex

 \begin{document}
 \sloppy                         % because of lots of file names here
 \pagenumbering{roman}

 \maketitle

 \tableofcontents

% \listoftables

% \listoffigures

 \newpage

 \pagenumbering{arabic}
 \pagestyle{headings}

% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 \makeatletter
% \renewcommand{\@oddfoot}{{\rm Draft \hfil Draft \hfil Draft}}
% \renewcommand{\@evenfoot}{{\rm Draft \hfil Draft \hfil Draft}}
 \renewcommand{\@oddfoot}{{\rm 13 April 1987 \hfil Version 2.07}}
 \renewcommand{\@evenfoot}{{\rm Version 2.07 \hfil 13 April 1987}}
 \makeatother
% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 \section{Introduction}

    This document describes a family of driver programs
which translate the \TeX{} device-independent (DVI) output
file to a device-specific file for a particular output
device, such as a dot matrix printer, a laser printer, a CRT
display, or a phototypesetter.

    These programs grew out of a DVI driver for the \BG{}
terminal%
\footnote{\INDEX{footnotes}{footnotes}%
        This fine terminal, which is almost unique in having
        support for variable sized downloaded fonts, is no longer
        made by BBN.  It has been licensed by BBN to \X{EastMark,
        Inc.} (240 Smith Street, Lowell, MA 01851, Tel:
        (617)\-453-9150), who have improved the documentation and
        packaging and sell it as the \X{GTR01} model.  Unit list
        price is about \$2950 (spring 1986).  The screen
        resolution is $1024 \times 780$ in a portrait orientation
        nicely matching the printed page.
}
developed by Mark Senn
\INDEX{senn, mark}{Senn, Mark}
at Purdue University.  This was further
worked on at the University of Washington by
Stephen Bechtolsheim,\INDEX{Bechtolsheim, Stephen}{Bechtolsheim, Stephen}
Bob Brown,\INDEX{Brown, Bob}{Brown, Bob}
Richard Furuta,\INDEX{Furuta, Richard}{Furuta, Richard}
Jim Schaad,\INDEX{Schaad, Jim}{Schaad, Jim}
and
Robert Wells,\INDEX{Wells, Robert}{Wells, Robert}
with
contributions for \POSTSCRIPT{} devices by
Neal Holtz \INDEX{Holtz, Neal}{Holtz, Neal}
at Carleton
University.
Simon Barnes \INDEX{Barnes, Simon}{Barnes, Simon}
of Schlumberger Cambridge Research Ltd., and
Robin Rohlicek \INDEX{Rohlicek, Robin}{Rohlicek, Robin}
at BBN provided useful additions to the
\BG{} driver which have been generalized and
incorporated in Version 2.07.

In the winter of 1986/87,
John Sauter \INDEX{Sauter, John}{Sauter, John}
adapted one of the dot
matrix drivers to produce \CN{dvil75} for the DEC LA75 printer.
Lon Willett \INDEX{Willett, Lon}{Willett, Lon}
at Utah adapted a laser printer driver to produce
\CN{dviimp} for the \IMAGEN{} laser printer family.

  The transformation to about  ten other device drivers,  plus
the massive code rearrangement for many new features as well as easy
identification of host- and  device-dependent sections, was  carried
out at the University of Utah by the present author.  The code has
undergone such extensive modification that there remains little in
common with the original version, which no doubt has spawned other
families of drivers at various institutions.

    What makes this driver family unique is the author's
commitment to its support on a wide variety of host
architectures and operating systems, and to {\em its
remaining entirely in the public domain\/}.  Recipients are
encouraged to install it, use it, improve, and in the spirit
of the \N{Emacs} community, return the improvements to
this author for further distribution.
Don Knuth,\INDEX{Knuth, Donald}{Knuth, Donald}
Leslie Lamport,\INDEX{Lamport, Leslie}{Lamport, Leslie}
and
Mike Spivak\INDEX{Spivak, Michael}{Spivak, Michael}
have given us \TeX{} and \MF,
\LaTeX{}, and \AmSTeX{}, which are enormous contributions to
the world of typesetting, and we should emulate them in
giving away our own work.  Many of us work at universities
and to a large extent are supported by public educational
funding; we owe them something back.  Someone who
commercializes
\INDEX{commercialization policy}{commercialization policy}
these DVI drivers is on his own; I shall
continue to give the family away to anyone who asks for it.

In January 1986 the availability of the family was announced on
the \CN{TeXHaX} bulletin board, and repeated again in the March
1987 issue of the
\TeX{} Users Group \INDEX{TeX Users Group}{\TeX{} Users Group}
newsletter, \X{TUGBoat}.  In the
first two months after the announcement, about 60 copies were
shipped by mail, and based on file \X{reference count}s,
a roughly equal number of Internet \X{ANONYMOUS FTP}\INDEX{FTP}{FTP}
retrievals were done from sites unknown.  An electronic mailing
\INDEX{electronic mail}{electronic mail}
list is maintained to inform recipients of changes and updates.

 \section{The DVI Driver Software}

  \TeX{} is written in a subset of \X{ISO Standard \string\PASCAL{}}
which was chosen both to enhance its portability, and to
facilitate translations to other languages.  For example, it
avoids nested procedures, and use of enumeration variables.
This author is aware of at least five%
\footnote{\INDEX{footnotes}{footnotes}%
        (1) old \TeX{}78 port to 16-bit workstation;
        (2) D.R. Fuchs' Micro\TeX{} (available from Addison-Wesley);
            \INDEX{Fuchs, David}{Fuchs, David}
        (3) N. Naugle and T. Rokicki at Texas A\&M;
            \INDEX{Naugle, Norman}{Naugle, Norman}
            \INDEX{Rokicki, Tom}{Rokicki, Tom}
        (4) P. Monardo's Common \TeX{} at UC Berkeley;
            \INDEX{Monardo, Pat}{Monardo, Pat}
        (5) Per Bergsten at Chalmers Institute of Technology,
            G\"{o}teborg, Sweden.
            \INDEX{Bergsten, Per}{Bergsten, Per}
}
translations of \TeX{} to \C{}, and one of \MF{} to \N{Tal} and
another to \N{Fortran}.
The \TeX{} software system is actually written in the \WEB{}
language, and translated into a \PASCAL{} program by \TANGLE{}
and into a \TeX{} document by \WEAVE{}.  \WEB{} supports change
files which contain local modifications to the source code, so
that all sites can work off a common master source file.

  Despite its many fine features which support the development of
reliable and correct software, regrettably, \PASCAL{} is
completely unsuited for the writing of DVI driver programs.  The
two serious omissions in this area are the lack of bit
operations, and random-access I/O.  The former are critical for
efficient support of low-cost dot matrix printers, and the latter
for efficient access to the many files which the driver requires.

Niklaus Wirth's\INDEX{Wirth, Niklaus}{Wirth, Niklaus}
second popular language, \N{Modula-2},
remedies both these problems, but is not yet
widely-enough available, and lacks a standard I/O library.  Because of
its strong similarity to \PASCAL{}, it should not be difficult to
prepare a version of the \WEB{} system to support it.

  \N{Ada} would also be a good possibility, but compilers again are
either not available, or too expensive in many environments.

  Since \TeX{} now runs on many different computer systems,
including the \IBMPC{} and the \MAC{}, there is a
need for DVI driver programs which can be used on all of
them.  There is really only one language choice, and that is
the \C{} language originally developed at Bell Laboratories
for the support of the \UNIX{} operating system.  It is even
more widely available than \PASCAL{}, and it contains the
necessary support for bit operations, random I/O, and
hands-on access to files without  having the
operating system throwing in extra garbage which ruins
them.

  Because \C{} is a ``low-level'' high-level language, it is
close to common computer architectures, and in most
implementations, compiles into reasonably efficient machine
code, provided some care is taken at the source level.  The
major weaknesses of \C{} are its general lack of type and
bounds checking, and its lax syntax which allows programming
errors to be accepted as legal code.  Two particularly
noxious examples of the syntax problems are illustrated by
the following program fragments:

\begin{verbatim}
for (k = 1; k <= n; ++k);
    foo(k);                /* foo is called once */

for (k = 1; k <= n; ++k)
    foo(k);                /* foo is called n times */
\end{verbatim}
The indentation here implies to the reader that \CF{foo} is
controlled by the \CN{for} loop.
\begin{verbatim}
if (avar = bvar);   /* this sets avar */
    foo();          /* foo is called once */

if (avar = bvar)    /* this sets avar */
    foo();          /* foo is called if bvar is non-zero */

if (avar == bvar);  /* this leaves avar intact */
    foo();          /* foo is called once */

if (avar == bvar)
       foo();       /* foo is called if avar equals bvar */
\end{verbatim}
The indentation again implies that \CF{foo} is controlled by
the \CN{if} statement.  You must look closely to spot the
tiny differences which give the very different effects noted
in the comments.

Although the coming ANSI \C{} Standard extends the language to
support type checking of function arguments, arrays carry no
bounds information unless the programmer arranges to create
composite data types or pass dimension variables, and the
majority of the standard library routines that have array or
pointer arguments simply assume that adequate space is available
when they are stored into.

Two versions of \WEB{} in C have been reported in
\X{TUGBoat}, %
\footnote{\INDEX{footnotes}{footnotes}%
        Klaus Guntermann and Joachim Schrod, {\em WEB Adapted to C},
        TUGBoat {\bf 7}, {No. 3}, 134--137 (1986).
}%
$^,$%
\footnote{\INDEX{footnotes}{footnotes}%
        Silvio Levy,  {\em WEB Adapted to C, Another Approach\/},
        TUGBoat {\bf 8}, {No. 1}, 12--13 (1987).
}%
but I have not had an opportunity yet to obtain either of them.
The extensive variable and code section cross-referencing
provided automatically by \WEB{} are exceedingly useful
features, and good grounds for Don Knuth's
\INDEX{Knuth, Donald}{Knuth, Donald}
calling \WEB{}
programming {\em literate programming\/}.%
\footnote{\INDEX{footnotes}{footnotes}%
        {\em Computer Journal\/}, {\bf 27}, 97-111 (1984)
        \INDEX{Computer Journal}{\string\em\space Computer Journal\/}
}
Without these cross-references, we have to make do with string
search utilities like the \UNIX{} \CN{grep} program.

  Fortunately, the \C{} preprocessor provides most of the
facilities that \WEB{} change files do.  The fact that all
versions exist inside the source code encapsulated by
\CNNX{\#if}\INDEX{#if}{\CNNX{\#if}}
\ldots
\CNNX{\#endif}\INDEX{#endif}{\CNNX{\#endif}}
sequences is both an advantage and
a disadvantage.  One source file has all implementations
contained in it, but it is rarely possible for an
implementor to completely test all versions when
modifications are made to the version-specific sections.

Nevertheless, the use of \C{} for this driver family has
proved quite satisfactory, and development work on the
\DEC{} \TOPS{} operating system is supported by the
availability of
Richard Stallman's\INDEX{Stallman, Richard}{Stallman, Richard}
wonderful \N{Emacs} from MIT, and many of the most useful \UNIX{}
utilities implemented with the portable \C{} compiler and
library, \PCC{}, ported to \TOPS{} by
Jay Lepreau,\INDEX{Lepreau, Jay}{Lepreau, Jay}
at the University
of Utah.  In February, 1987, I installed the \KCC{} compiler
which is under active maintenance and development at SRI-NIC, and
the driver family has been implemented with it as well.  It has
proved to be a fine compiler, and is being updated to conform to
the draft ANSI \C{} Standard.

 \section{Outline of the DVI Drivers}

  The DVI drivers follow to some extent David Fuch's
\INDEX{Fuchs, David}{Fuchs, David}
\CN{dvitype} program, which defines the standard DVI file format and
how to process it.  In simple terms, the DVI file is a sequential
8-bit byte command stream produced by \TeX{} as it processes a
document, and consists mostly of compactly-encoded commands to
move to a specific page position and typeset a character there.
It is further embellished with version numbers, page pointers,
checksums, font names, magic numbers to identify the file as a
DVI file, and the like.  The DVI driver must be able to read this
file, processing all, or user-selected, pages, and produce an
output file in a device-specific format which can produce typeset
pages on some particular device.  Although the output is
device-specific, much of the processing done by the DVI driver is
concerned with interpreting user run time command options,
decoding the DVI commands, finding font files, and extracting
character bitmaps from them.  All of this part of the drivers is
common across devices, and accounts for quite substantial code
sharing.

  Each driver consists of a single \C{} source file,
\FN{dvixxx.c}, where \FN{xxx} is a mnemonic abbreviation of the
device, such as \FN{alw} for \ALW{}.  This file contains \C{}
preprocessor
\CNNX{\#include}\INDEX{#include}{\CNNX{\#include}}
directives to obtain a standard
header file, \FN{dvihead.h}, which in turn
\CNNX{\#include}'s\INDEX{#include}{\CNNX{\#include}}
a header file, \FN{machdefs.h}, containing machine constants, and
another, \FN{typedefs.h}, containing type definitions.

Originally, \FN{dvihead.h} also contained the definitive revision
history of the driver family in its extensive initial comments.
This practice has been discontinued, and the \X{maintenance history}
is now stored in a separate file, \FN{00revhst.txt}.  This avoids
unnecessary recompilations when the \UNIX{} \CN{make} utility is
used to manage the software.

  \C{} has only a limited number of primitive data types,
but it does have \CN{struct} and \CN{typedef} statements
permitting the creation of new data types.  These do not
particularly enhance the type checking possibilities, at
least not until the coming ANSI \C{} Standard has been widely
implemented, but they do inform the compiler of storage
requirements, which permits efficient code generation.  This
is of particular importance on the segmented memory
architectures of the \N{Intel iAPX} microprocessor family used
in the \IBMPC{} and clones, because there is an enormous
execution-time penalty for processing objects bigger than
the base architecture easily supports.  Two  examples of these
are the need for subroutine calls to perform 32-bit integer
arithmetic, and around 30 instructions to compute the
address of an element in a vector larger than 64 Kbytes in
extent, compared to one instruction when the vector is
smaller than that size.  Many compilers for these architectures
have provided no support whatever for addressing objects larger
than one segment.

  Objects in the DVI file consist of one-, two-, and four-byte integers,
both signed and unsigned, and character strings.  It is important to
identify the exact space requirements of these to obtain an efficient
implementation.  Consequently, \FN{typedefs.h} defines new types called
\CN{BOOLEAN}, \CN{BYTE}, \CN{COORDINATE}, \CN{INT8}, \CN{INT16},
\CN{INT32}, \CN{UNSIGN16}, \CN{UNSIGN32}, and \CN{void}.

  The \CN{void} type is available only in some \C{}
implementations, although it will be in the ANSI \C{} Standard;
it is used to signify the absence of a value, particularly for
function values which are discarded.  All \C{} procedures are in
fact functions which may or may not return a value.  A common
programming error is to return inconsistent values from inside a
function, or to return a value from one part, and none from
another.  One of the sloppy habits of many \C{} programmers is to
ignore a returned function value, particularly with library
procedures, most of which return error indicators of some sort
when they cannot return a valid pointer or primitive value.  The
type cast \CNNX{(void)}\INDEX{void}{\CNNX{(void)}}
in front of a function call then tells both
the compiler and the reader that the function may in fact be
returning something, but the result is intentionally being
discarded.

  The \CN{COORDINATE} type is used for device coordinates (usually dots
or pixels), and it is defined because the precision required may depend
on the output device and on the size of the available integer types
provided by the compiler.

    \C{} is quite permissive about type conversion by
assignment; almost any object can be assigned to another and
the compiler will accept it and generate code for it.  One
of the commonest misuses of this feature is the assignment
of pointers to integers, and vice versa.  While this may be
reasonable on some architectures, there is no good reason to
assume that both are interchangeable.  Indeed, on \X{segmented
memory} architectures, such as the widely-used \N{Intel iAPX} family
mentioned earlier, this is definitely not the case.  An
integer may be a 16-bit quantity, while a pointer may be a
composite 32-bit (or larger) value made up of segment
number, memory offset in the segment, access rights, and
type information.  Another common error is the passing of
integers of different sizes through the same argument of a
function.  On the \N{PDP-11} and  \VAX{}
architectures where \C{} was first implemented, this may
work, but it definitely does not on the \N{Intel} and \N{Motorola}
processors.  Consequently, in the DVI driver family,
extensive use is made of type casts in assignments,
expressions, and function arguments.  Null pointers are
always cast as such; they are {\em never\/} assumed to be
zero.%
\footnote{\INDEX{footnotes}{footnotes}%
        If you find such an instance, it is a bug, so
        please inform me of it so it can be fixed.
}

  After \FN{machdefs.h}, the next file included by \FN{dvixxx.c}
is \FN{main.h}, which is the function \CF{main} required to
prepare an executable \C{} program.  It immediately includes all
the standard system header files which are required for use of
system library functions, plus four additional header files,
\FN{commands.h}, \FN{gblprocs.h}, \FN{gblvars.h}, and
\FN{gendefs.h}.  For drivers for interactive displays, it will
also include \FN{keydef.h}.

  \FN{commands.h} defines mnemonics for the commands in the DVI
file, such as \CN{BOP} ({\em Beginning Of Page}),
\CN{SET_RULE},
\CN{FNT_DEF1} ({\em Font Definition}), and so on.

  \FN{gendefs.h} is a
catch-all for general \X{macro definitions} and assorted constants.

\FN{gblprocs.h} defines all of the global functions.  With the
availability of a compiler anticipating the coming ANSI Standard,
the \MICROSOFT{} Versions 3.0 and 4.0 compilers on the \IBMPC{}, this
file has been revised so that the data types of arguments are
defined; this was not previously possible in \C{}.  The alternate
declaration forms are selected under control of the preprocessor
symbol \CN{ANSI}, which is set in \FN{machdefs.h}.

\FN{gblvars.h}  defines all the scalars, vectors, arrays, and
structures which must be known globally.
\INDEX{global data}{global data}
These are analogous to
\CN{EXTERNAL} variables in languages like
\N{PL/1}.  They
represent one of the weakest areas in \C{}, in that no control exists
over which functions reference or modify them; the packages of
\N{Modula-2} and \N{Ada} were introduced
specifically to deal with
this problem.  The names of these global variables reside in a single
name space, so it is important that they be chosen carefully so as to be
unlikely choices for local variables inside a function.  Otherwise, an
omitted type declaration in the function will use the global variable,
producing a hard-to-find side effect (a fashionable word for {\em bug\/}).

\FN{keydef.h} contains flag definitions and function
declarations for the \X{keyboard input} package, \FN{keybrd.c}.

There are presently about 70 files with extension \FN{.h},
and 9 have now been presented.  The others
are functions, most of which are required by all the
drivers.  By inclusion of all 5 of the standard top-level header
files at the beginning of each of the remaining ones, they
could be turned into separately-compiled functions.
However, since several of them contain operating-system or
device-dependent code sections delimited by preprocessor
directives, extreme care would be required in building
executable versions of the drivers to avoid inclusion of
object files compiled with the wrong code segments selected.
We have found it more reliable to use the
\CNNX{\#include}\INDEX{#include}{\CNNX{\#include}}
directive to insert each of these functions into the
\FN{dvixxx.c} modules so that a only a single file need be
presented to the compiler and linker.  The recompilation
time has so far not proved to be objectionable,%
\footnote{\INDEX{footnotes}{footnotes}%
        7 to 10 minutes on a standard \IBMPC{} \N{XT} (4.77MHz
        8088 CPU) with the \MICROSOFT{} Version 3 \C{} compiler, and
        under two minutes on mainframes.
}
while the
possibly more economic alternative of separate compilation
would be exceedingly likely to cause problems.

To summarize then, here is the general structure of the file nesting:
\begin{verbatim}
dvixxx.c --> dvihead.h   --> machdefs.h
                         --> typedefs.h

         --> main.h      --> commands.h
                         --> gendefs.h
                         --> gblprocs.h
                         --> gblvars.h
                         --> keydef.h

         --> other function .h files
\end{verbatim}
\INDEX{nesting of files}{nesting of files}
There is {\em no\/} further nesting of files than this.  Each of the
functions may call other ones, but the \FN{.h} files do not include any
additional program text.

In some of the function files, preprocessor directives select
minor variations in code.  When significant differences would be
required, then \FN{dvixxx.c} does not use the
\CNNX{\#include}\INDEX{#include}{\CNNX{\#include}}
mechanism, but instead has a private version of the function
embedded in itself.  All functions following \CF{main} are in
\X{alphabetical order}, and are readily identifiable on the terminal
screen or in a program listing by a standard function header.

 \section{The Grubby Details}

 We shall now descend into subsections to discuss each of these
header files separately.  Like their invocations in
\FN{dvixxx.c}, these too will be given in alphabetical order.
Since \C{} permits letter case distinctions, many of the names
were historically chosen to be in mixed case for readability
(e.g. \CF{AbortRun} instead of \CF{abortrun} or
\CF{abort_run}).
This proved to be a nuisance as the code has been moved from
machine to machine, so I have applied the \UNIX{} \CN{sed}
utility to replace all mixed-case names with lower-case ones.
For portability, function names must be unique in the first six
characters, and file names in the first eight, so all function
names have been shortened to eight or fewer characters.
\INDEX{naming conventions}{naming conventions}

 \subsection{\protect\FN{abortrun.h}}

  \CF{abortrun} is called to terminate the DVI driver execution, both
normally, and in the event of errors.  It closes any open files,
issues an error message if called with a non-zero completion code, and
then returns to the operating system with the normal \CF{exit} call.

 \subsection{\protect\FN{actfact.h}}

  \CF{actfact} takes a font magnification factor and
adjusts it to match the nearest one in an internal table of
standard \TeX{} \X{font magnification}s.  That way, a user
request for, say, magnification 1094, will get adjusted to
the expected value, 1095.  Correct adjustments to an integer
value are critical, because font files contain this value as
part of their names or directory path.

 \subsection{\protect\FN{alldone.h}}

  \CF{alldone} is the routine called for normal termination.  It
closes any error \X{log file} and copies it to \CN{stderr}, tells the
user if a log file was created, and then calls \CF{abortrun} to
finish the job.

 \subsection{\protect\FN{bitmap.h}}

  This file is included by all the \FN{dvixxx.c} files which
create page bitmaps in memory for dot-matrix printers.  It
defines macros and functions for accessing the bitmap; this is
necessitated by the constraints of \X{segmented memory} on the
\N{Intel iAPX} architecture.

 \subsection{\protect\FN{bopact.h}}
\CF{bopact} is called from \CF{prtpage} to handle
beginning-of-page action for interactive displays.  For
\CN{dvibit}, it writes the command and status window.

 \subsection{\protect\FN{chargf.h}}

  The functions \CF{chargf}, \CF{charpk}, and \CF{charpxl} are
called from \CF{readfont}, as well as from \CF{setchar} in
\FN{dvibit.c}, and \CF{loadchar} in \FN{dvialw.c},
\FN{dvican.c},
\FN{dviimp.c}, and
\FN{dvijep.c}.  They have the job of extracting the raster
description, and possibly, character metrics, of a single
character from the corresponding \FN{.gf}, \FN{.pk}, or \FN{.pxl}
font file, and decoding it to produce a simple bitmap which can
be easily painted into the page bitmap by \CF{dispchar}, or
formatted for downloading to a more intelligent output device,
such as the \BG{}, \POSTSCRIPT{} printers, and the
\HPLJ{} \N{Plus}.

  For most devices, the character bitmap is quite small, and
there would be no difficulty in storing the full bitmap.
However, printers of much higher resolution are likely to become
available over the next few years, while host computer memories
will probably not increase substantially.  For example, a 10pt
character at 2400 dots/inch would require about 8 Kbytes for the
entire image, but fewer than 25 bytes for a single row.  A 72pt
character, such as in the {\em aminch\/} font, would need about 430
Kbytes for the image, but only about 200 bytes for a row.  Since
all three font formats store character bitmaps in row order, it
seemed expedient to have \CF{chargf}, \CF{charpk}, and
\CF{charpxl} build up the character description a row at a time,
calling another routine, \CF{outrow}, each time a row is
completed.  They then require no knowledge of what is to be done
with the character bitmap, and no duplication of code for this is
necessary, since it can be entirely hidden in \CF{outrow}.

 The \FN{.gf} font file format produced by the new \MF{} is
reasonably complex, sharing much in design with \FN{.dvi} files.
Instead of being stored as a full bitmap, with each row rounded
up to a multiple of 32 bits to achieve word alignment on 32-bit
hosts, as they are in a \FN{.pxl} file, character bitmaps in a
\FN{.gf} file are stored in a run-length encoded
\INDEX{run-length encoding}{run-length encoding}
form with counts
of white and black pixels in each row, and commands to skip
repeated white rows.  This gives a compression of only a few
percent for normal size characters, but \FN{.gf} font files for
very large characters may be up to 30\% smaller than the
corresponding \FN{.pxl} files.

  The \FN{.pxl} file format has a 2K-byte directory at the end
containing all necessary character metrics, plus pointers to
their raster descriptions which are
scattered throughout the file.  This
means that a relatively small block of data is all that is
initially required from the file, and random access can be later
used to retrieve needed character bitmaps.  The \FN{.gf} file
also has a directory at the end, but it contains only character
escapements and widths, plus pointers to encoded character
packets which are scattered throughout the file.  The escapements and
widths are required for updating coordinates when a character is
set, but the offsets of the character bitmap from the character
reference point, which are required in clipping decisions when a
character is to be set, are stored in the character packets.
Their availability is desirable, because off-page characters need
never be set.  This deficiency is unfortunate, because to
retrieve them, it is
necessary to read through the entire font file, causing
unnecessary file page mapping.  For many fonts used in a typical
\TeX{} document, only a very few of the 128 possible characters
in the file will ever be used, so this design flaw in the
\FN{.gf} file format could in the worst case almost double the
amount of font file input, compared to use of \FN{.pxl} files.
Although it would be possible to carry a flag for each character
indicating whether or not the offsets were available, I decided
not to do so, because this would be needed only for one of the
three font file formats.

  The code in \CF{chargf} follows that in \CN{GFtoPXL} fairly
closely, although some duplication of code fragments was
permitted to avoid the \CN{goto} statements present in the
latter.  Most of the approximately 340 lines of code in
\CF{chargf} are part of a large \CN{switch} statement inside a
loop, dispatching on the value of the next input byte.

 \subsection{\protect\FN{charpk.h}}

  As discussed in the preceding section, \CF{charpk} is called to
handle the retrieval and decoding of the raster description of a
single character from the \FN{.pk} form of a font file.

  The \FN{.pk} font file format was defined by Tom Rokicki,
\INDEX{Rokicki, Tom}{Rokicki, Tom}
formerly at Texas A\&M University, now at Stanford University.
He has provided support programs \CN{GFtoPK}, \CN{PKtoPX}, and
\CN{PXtoPK} for converting between the various font file formats.
Combined with the Stanford \TeX{} Project's  \CN{GFtoPXL}, only
\CN{PXLtoGF} or \CN{PKtoGF} yet need to be written to allow going
from any one of the three font file formats to the other.

  The \FN{.pk} format is even more complex than the \FN{.gf}
format.  Instead of \X{run-length encoding} character bitmaps by
rows, it first recognizes repeated rows,%
\footnote{\INDEX{footnotes}{footnotes}%
        About 37\% of the bitmap rows in the standard fonts
        required by \FN{plain.tex} are repeated!
}
then treats the remaining bitmap as a single bitstring to be
run-length compressed.  In addition, run-length counts are based
on 4-bit nybbles, rather than 8-bit bytes.  For the standard
fonts, the \FN{.pk} files occupy slightly less than half the disk
space of the \FN{.gf} files.  This will clearly be of importance
on small machines, particularly personal computers.

  The \FN{.pk} font file lacks a character directory, so to
retrieve character metrics, the entire font file must be mapped
in from disk.  Each character is contained in a single packet,
beginning with its number and metrics, and followed by its packed
raster encoding.  A stored packet length allows skipping over the
rasters on the first pass by  \CF{readpk} as the metrics are
collected.

  The code in \CF{charpk} follows that in \CN{PKtoPX} fairly
closely, although some duplication of code fragments was
permitted to avoid the \CN{goto} statements present in the
latter.   There are approximately 350 lines of code in
\CF{charpk}, but the processing is more complex than that
required in \CF{chargf}.  Consequently,  the file \FN{charpk.h}
departs from the convention of one function per file, and it
contains three private functions,
\CF{get_bit},
\CF{get_nybble},
and
\CF{pk_packed_num},
plus several private globals known only
within this file.  For historical reasons, the \C{} data type
\CN{static}
\INDEX{private modules}{private modules}
when used for objects declared outside a function
body, really means {\em private to this file\/}, and we therefore
have introduced a preprocessor symbol \CN{PRIVATE} for this
purpose.   A \CN{typedef} cannot be used, because \CN{static} is
a type {\em modifier\/}, not a pure data type.

 \subsection{\protect\FN{charpxl.h}}

 \CF{charpxl} is quite short---about 55 lines.  It retrieves a
single character bitmap from a \FN{.pxl} file, and sends each row
to \CF{outrow} for processing.  Since there is no raster decoding
necessary, once argument checking has been done and the font file
successfully positioned to read the character bitmap, only eight
lines of code are needed to do the whole job.  Before the support
for \FN{.pk} and \FN{.gf} font files was added, this operation
was performed in a half-dozen different functions.  Now, it is
totally isolated in this one routine.

 \subsection{\protect\FN{clrbmap.h}}

 \CF{clrbmap} has the rather simple job of clearing a
bitmap array to zero for those devices, such as dot matrix
printers, which actually require one.  Although it is a
simple loop in \C{}, it has to be done for every page, and
accounts for a surprisingly large portion of the run time
when the driver execution is monitored with a program
counter histogramming utility.  For some machines, we have
prepared a more efficient
\INDEX{efficiency}{efficiency}
assembly language version,
\CF{zerom}, which it calls instead.  This can take advantage
of basic hardware facilities like \X{block move} to do it as
fast as the machine is capable of.  For \X{segmented memory}
bitmaps, where
the bitmap is allocated as a vector of pointers to raster lines,
rather than as one large array, special code is
required to clear individual  raster lines.  The preprocessor
symbol \CN{SEGMEM} identifies these code sections.  Details can
be found later in the section on \CF{getbmap}.

 \subsection{\protect\FN{clrrow.h}}

  \CF{clrrow} is called from \CF{chargf}, \CF{charpk}, and
\CF{charpxl} to clear the global array
\CN{img_row[]}
before
collection of each character bitmap row begins.  Although the
code is a single loop, it is required frequently enough that it
warranted encapsulation in a separate function.

 \subsection{\protect\FN{commands.h}}

  This file contains symbolic definitions of all of the DVI commands
which are required in the driver program.  These are fixed with the
freezing of \TeX{}, but no program should ever contain magic constants
where symbolic names would make the code more readable.

 \subsection{\protect\HCF{devinit}}

  \CF{devinit} has the job  of carrying out any startup
initializations required by the output device for the processing
of a single DVI file.  It is called from  \CF{dvifile}.
For most dot-matrix printers, there is little to do, but
terminals and laser printers may require considerably more.

 \subsection{\protect\HCF{devterm}}

  \CF{devterm} is called from  \CF{dvifile} to perform any device
termination following the processing of a single DVI file.
Comments made about \CF{devinit} apply to this function as well.

 \subsection{\protect\FN{dispchar.h}}

 \CF{dispchar} has the delicate job of painting
\INDEX{character painting}{character painting}
the current
character onto the display surface.  For downloaded font devices, this
job may involve little more than output of a few command bytes, once the
character rasters have been sent to the device.  For bitmapped devices,
it is fairly tricky, since the character bitmap will rarely be
aligned on a word boundary in the output bitmap, and the code must be
both  efficient,
\INDEX{efficiency}{efficiency}
since it is done several thousand times per page, and
independent of the host computer word size.  It is further complicated
by the fact that the right shift operator in \C{}  may or may not
propagate a sign bit; the \CN{unsigned} integer type attribute which
should suppress  this propagation is not available in all compiler
implementations.  The preprocessor symbol \CN{ARITHRSHIFT} is used to
select the appropriate code section.

  Although the body of this function is less than 60
lines long, it is about the most complex function in the
entire driver family, and also the one likely to require the
most execution time.  If code optimization is worthwhile, it
surely will be here.

  For \X{segmented memory} machines, the bitmap is allocated as a
vector of pointers to raster lines, rather than as one large
array.  Code which accesses the bitmap must take care to not step
pointers across raster lines.  The \CN{BITMAP(y,x)} macro
otherwise hides the bitmap addressing.  Since \CF{dispchar} fills
in raster line order anyway, there is no penalty for this.
Further details may be found in a later section on \CF{getbmap}.

 \subsection{\protect\FN{dumpchar.h}}

  This is a debugging routine used to dump character raster
representations to the \CN{stderr} file.  It is not normally required
or included in the drivers.

 \subsection{\protect\FN{dvifile.h}}

 \CF{dvifile} is called from \CF{main} once for each DVI file to
be processed.    It calls \CF{dviinit} and \CF{devinit} for
initializations, \CF{readpost} to read in the DVI postamble, then
loops calling \CF{prtpage} for each page to be printed, and
finally calls \CF{devterm} and \CF{dviterm} for termination chores.

 \subsection{\protect\FN{dvihead.h}}

 This file is the only non-function header file included directly
by the \FN{dvixxx.c} files.  It is the repository of old revision
and development history of the family (current history is stored
\INDEX{maintenance history}{maintenance history}
in \FN{00revhst.txt} instead), and does nothing more than
possibly define a debug symbol, and then include \FN{machdefs.h}
and \FN{typedefs.h}, plus some system header files.  The rest are
included in \FN{machdefs.h} and \FN{main.h}.

 \subsection{\protect\FN{dviinit.h}}

 \CF{dviinit} is called from \CF{dvifile} for the initial DVI
file processing.  After defining some global variables, it does a
simple parse on the DVI file name specified on  the command line  to
identify the file's directory, if any, and its name and
extension.  The path and name are saved in global variables, and
a name for the output file is constructed.  The DVI file and
output file are opened, and the magic identifying bytes in the
DVI file are read to make sure this is really a proper DVI file.
If it is not, \CF{fatal} is called to terminate the job.
Otherwise, control returns to its caller.

If opening of the output and \X{log file}s
fails, then the file path
of the DVI file is discarded, and these files are opened in the
current directory.  This allows processing of DVI files which
reside in directories for which the user does not have write
access.

 \subsection{\protect\FN{dviterm.h}}

 \CF{dviterm} is called from \CF{dvifile} to complete processing
of the current DVI file.  It closes all open files and frees all
dynamically-allocated font memory.

 \subsection{\protect\FN{eopact.h}}

 \CF{eopact} is called from \CF{prtpage} to handle end-of-page
action on interactive displays.  It currently supports only the
\BG{}, but should be straightforward to adapt to new displays.
It consists of a single command loop which runs as long as
keyboard input is available.  All input commands are processed,
but the display is not updated until there is no more input.
The \X{keyboard input} support package in \FN{keybrd.c} supports this.

 \subsection{\protect\FN{f20open.h}}

  This section has a little story behind it, so in case you are
interested, read the next four paragraphs; otherwise, skip to the
last paragraph.

  Most modern computer architectures are based on memory
built up of 8-bit chunks, called {\em bytes\/}, which are then
assembled into larger units like {\em half words\/}, {\em
words\/}, {\em long words\/}, and so on.  The 8-bit byte size is
convenient in that it is large enough to contain both the
7-bit ASCII and ISO character sets, and the 8-bit EBCDIC,
and extended ASCII and ISO sets.

    The \TWENTY{} architecture dates from the 1960's when
word-addressed memory was common, and like the original IBM 70x and 70xx
machines, its word size is 36 bits.  With early BCD, \N{CDC}, and
Fieldata 6-bit character sets, this was not an unreasonable size,
and the fact that six such characters fit exactly into a word is
still with us in \N{Fortran}'s six-character name limits and
the size of external names on many operating systems.  On many of
these machines, character access required awkward masking and
shifting operations, one exception being the \N{Univac 1100} machines
which have quarter-word instructions, and therefore use 9-bit
ASCII.

    The \TWENTY{} is unusual in that it supports any byte size
from 1 to 36 bits with equal ease.%
\footnote{\INDEX{footnotes}{footnotes}%
        At DECUS meetings, you can see folks walking around
        with T-shirts reading ``I don't care what they say, 36
        bits are here to stay''.
}
Conventionally, text files are stored in 7-bit ASCII, five per
word, leaving one bit left over in the low-order position of the
word.%
\footnote{\INDEX{footnotes}{footnotes}%
        That bit is normally zero; when it is not, it
        signifies that the word contains a line number instead of text.
}
When 8-bit bytes are stored, they could be packed in groups of
six bytes in a word pair, as \N{Univac} does, but on the \TWENTY{},
they are generally placed in four-byte groups in the high-order
32 bits of a word, with the four low-order bits zero, where they
are amenable to efficient
\INDEX{efficiency}{efficiency}
access with the byte instructions.

  Unfortunately, the standard \CF{fopen} function does not know about
byte sizes; it just assumes text bytes are wanted and opens the file in
7-bit mode.  The DVI file, however, has 8-bit bytes, so on the
\TWENTY{}, we have this special version, \CF{f20open}, which stoops
to a lower level in the I/O library to twiddle the right flags to get
the open done  for 8-bit bytes.

  Nobody outside the \TWENTY{} has to care about this routine, because
the preprocessor symbol \CN{BINARYOPEN} is set automatically in
\FN{machdefs.h} to either \CF{f20open} for the \TWENTY{}, or \CF{fopen}
for everyone else.

 \subsection{\protect\FN{fatal.h}}

  When necessary files cannot be found or read, or the disk
storage fills up, execution must be terminated.  This routine
writes out an error message, resets the terminal characteristics
if they were changed, tells the user if a \X{log file}
was created, and then calls \CF{abortrun} to terminate the job.  The name of
the function issuing the call to \CF{fatal} is included as part
of the message.

 \subsection{\protect\FN{fillrect.h}}

  When \TeX{} sets a horizontal or vertical rule, the output
device probably simulates this by drawing a black
solid-filled rectangle.  For typesetters, this may be an
available primitive, and so needs only the output of a few
command bytes.  For most others, we have to actually fill in
bits in the bitmap.  This job is only marginally easier than
the one \CF{dispchar} has to do, and many of the same
comments made in that section apply here.

  There usually are not a great many rules to typeset in a
typical document, so efficiency in \CF{fillrect} is of little
concern.  However, the new \X{Bezier curve} option supported by
\LaTeX{} draws lots of little rules (e.g. 2 dots by 2 dots on a
laser printer), so you might want to give it some attention.
\INDEX{efficiency}{efficiency}
When many small rules are set like this, it might be valuable to
have special case code for them, particular for the dot-matrix
printer drivers.  Only this function needs to know if you do.
\CN{dvialw}, \CN{dvican},  \CN{dviimp}, and
\CN{dvijep} arrange to avoid sending rule
sizes to the device when they have not changed from the last use,
and this has helped to reduce the output volume considerably.

  For \X{segmented memory} machines, the bitmap is allocated as a
vector of pointers to raster lines, rather than as one large
array.  Code which accesses the bitmap must take care not to step
pointers across raster lines.  The \CN{BITMAP(y,x)} macro
otherwise hides the bitmap addressing.  Since \CF{fillrect} fills
in raster line order anyway, there is no penalty for this.
More details about this will be found in the later section on
\CF{getbmap}.

 \subsection{\protect\FN{findpost.h}}

  When \TeX{} sets a document, it does not know until it gets
done where all the pages are, and what fonts are needed.
Consequently, the DVI file stores this information in a postamble
section which the DVI driver probably wants to make use of.
Because the postamble size is clearly variable, in its last eight
bytes, the DVI file has a four-byte magic number that tells the
driver that \TeX{} actually finished writing the file, and a
four-byte pointer to the beginning of the postamble.
\CF{findpost} has the job of reading this little trailer,
validating it, exiting via \CF{fatal} if it is bad, and otherwise
using the random I/O positioning standardly available in \C{} to
set the file pointer at the beginning of the postamble.

 \subsection{\protect\FN{fixpos.h}}

  \TeX{} works in tiny units which do not match any output device, but
still let it position characters accurately for even the most exacting
photo\-type\-setters.

  The font designer works in device units (dots or
pixels), because high quality demands attention to device resolution,
particularly for the common low- and medium-resolution devices such as
dot matrix printers and laser printers.   The font designer specifies
character widths in such a way as to provide for the most pleasing
juxtaposition of characters into words, and \TeX{} follows this
specification precisely.

  The problem is, \TeX{} does not know what the
output device resolution will be (remember that DVI means
{\em device
independent\/}), so it may ask for a character to be positioned at what
will probably not be an exact device coordinate.  If the driver just
rounds each precise \TeX{} coordinate to the device
coordinate system, the chances are that characters in a word may not be
positioned relative to one another as the font designer intended.

The effect of incorrect rounding can be glaringly obvious---a line of 60
asterisks followed by a line of two asterisks separated by 58 spaces set
in a fixed-width font may be off by as much as one character position on
a 300-dot/inch laser printer.

Considerable thought has gone into this problem, and it was not until
Version 2.06 of \CN{dvitype} that the folks in the \TeX{} project got
it right (at least until we see an example to the contrary).
\CF{fixpos} implements the algorithm directly from \CN{dvitype}.

 \subsection{\protect\FN{fontfile.h}}

  Although most of the code in the DVI drivers is completely
portable across \C{} implementations, operating system
features like file names obviously are not.  In particular,
the drivers need to be able to take a \X{font name}, like {\em
cmr10\/}, and a \X{font magnification}, say 1500 (normal 10pt type
on a 300-dot/inch laser printer), and from them, construct a
name of the file containing the character raster
descriptions.  On the \TWENTY{}, this file would usually be
called \FN{texfonts:\-cmr10.1500pxl}.  Under \UNIX{}, it
might be \FN{/usr\-/lib\-/tex\-/fonts\-/1500\-/cmr10.\-pxl}.
On the \IBMPC{}, it could be
\FN{d:\bs{}tex\-\bs{}fonts\-\bs{}1500\-\bs{}cmr10.\-pxl}.

Three different font file formats are now supported, and
\CF{fontfile} has the job of figuring out just what the file names
should be, and returning a list of them.  For example, it
might return for {\em Computer Modern 10pt\/} the names
\FN{texfonts:\-cmr10.\-300pk},
\FN{texfonts:\-cmr10.\-300gf}, and
\FN{texfonts:\-cmr10.\-1500pxl}.  Note that the naming
convention for \FN{.gf} and \FN{.pk} files has changed from
that used for \FN{.pxl} files---standard magnification is
\INDEX{font magnification}{font magnification}
now 200 instead of 1000.

The directory paths supplied are determined by the preprocessor
symbol \CN{TEXFONTS} defined in \FN{machdefs.h}.
In order not to permanently bind directory paths into the
compiled programs, the default directory names for these files
may be overridden at run time by \CF{initglob} with values of
\X{environment variable}s.

 \subsection{\protect\FN{fontsub.c}}

  Sometimes, a DVI file references fonts  which are not available
in the requested magnification,
\INDEX{font magnification}{font magnification}
or perhaps even in the entire family.
Calling \CF{fatal} if this happens is hardly user-friendly---it may
be that only one character in a fifty-page document belongs to this
missing font.

  The DVI drivers therefore offer the user the possibility of providing
a file of font substitutions which can be tried in turn until one is
found.  If none can be, then the drivers consult a built-in
table%
\footnote{\INDEX{footnotes}{footnotes}%
        This table is defined by \FN{gblvars.h}.  It contains
        values for devices of resolution 144, 200, and 300 dots/inch;
        if the family is extended to higher-resolution devices,
        this table should be extended.
}
of standard magnifications
\INDEX{font magnification table}{font magnification table}
to find the nearest one in the
requested family; surely a character from {\em cmr10\/} at 1440
magnification instead of 1500 magnification is better than none
at all!  If even that fails, then execution continues with the
missing character metrics all assumed to be zero; with luck, this
will affect only a few lines in the output.

   Presumably, the \FN{.tfm} file was available to \TeX {} when
it created the DVI file, so \CF{fontsub} could be extended to try
to obtain the information from that file instead, and perhaps
recover.  A second possibility would be to supply some arbitrary,
but reasonable, character width, and just set blank space for the
missing characters.  Neither of these has yet been implemented.%
\SUBINDEX{to-do list}{to-do list}{handling missing fonts}

    A message is issued to the \X{log file} if a substitution is made
according to the requests in the substitution file, or if a
neighboring magnification
\INDEX{font magnification}{font magnification}
was chosen in the same family, so the
user can still find out it happened.

   The format of the \X{font substitution file}, and the mechanism for
finding it, has been chosen to simplify its use.  First of all, an
explicit font substitution file can be specified by a driver
command-line option at run time.  If this is not done, then the name of
the DVI file is used to construct a default name with a different
extension.   For example, on \UNIX{}, the DVI file
\FN{/usr\-/jones\-/book\-/hornets.\-dvi}
would select a substitution file
\FN{/usr\-/jones\-/book\-/hornets.\-sub}.
This gives a document-specific choice of substitution files.

  If this
one is not found, then a standard name, such as \FN{texfonts.sub}, is
looked for in the same directory.  In our example, this would be
\FN{/usr\-/jones\-/book\-/texfonts.\-sub}.
This second choice is
therefore a directory-specific solution.

  If this file is not found either, then as a last resort,
\CF{fontsub} looks for a system-wide file, usually stored in
the same directory \TeX{} gets its input files from.  The
example file would therefore be something like
\FN{/usr\-/lib\-/texinputs\-/texfonts.\-sub}.

  The format of the substitution file is simple to prepare, and can be
parsed (almost) unambiguously by the standard \C{}  input routine,
\CF{sscanf}.  It is also operating-system independent, so that
substitution files can be moved from machine to machine if necessary.

    Font substitution lines have the forms:
\begin{verbatim}
% comment
oldname.oldmag  ->      subname.submag  % comment
oldname oldmag  ->      subname submag  % comment
oldname         ->      subname         % comment
\end{verbatim}
The first  two forms  request
substitution of a  particular font  and magnification.
\INDEX{font magnification}{font magnification}
The third  form
substitutes an entire font  family; the closest available  magnification
to the required one will be  used.  Any dots in the non-comment  portion
will be converted  to spaces, and  therefore, cannot be  part of a  name
field.  Examples are:
\begin{verbatim}
% These provide replacements for some LaTeX invisible fonts:
iamr10 1500     ->      amr10 1500      % comment
iamr10.1500     ->      amr10.1500      % comment
iamssb8         ->      amssb8          % comment
\end{verbatim}

  The first matching substitution will be selected, so
magnification-specific substitutions should be  given first,
before family substitutions.

\hyphenation{white-space}
Comments are introduced by percent and continue to end-of-line, just as
for \TeX{}.  One whitespace character is equivalent to any amount of
whitespace.  Whitespace and comments are optional.

Anything which follows the substitution font will be ignored, so a line
like
\begin{verbatim}
iamr10 1500     ->      amr10 1500 long live TeX!   % comment
\end{verbatim}
will be parsed successfully.  It is not {\em de rigueur\/} in computer
science to accept sloppy parsing, but in this case, a simple workable
solution was provided by a standard library facility, \CF{sscanf},
with one line of code to call it; doing a better job would involve
at least a few hundred lines of code.

 \subsection{\protect\FN{gblprocs.h}}

  This file contains definitions of all of the functions
referenced by the DVI driver family.  \CF{main} includes it.  For
compilers which support the additional function argument type
syntax of the coming ANSI \C{} Standard, it has been updated to
include these declarations.  They are selected by a new
preprocessor symbol, \CN{ANSI}, defined in \FN{machdefs.h}, in
order to preserve compatibility with existing compilers.

 \subsection{\protect\FN{gblvars.h}}

  This file contains definitions of all the global scalars,
vectors, arrays, and structures required by the drivers.  This is
also where the \X{font magnification} table used by \CF{fontsub} is
defined.

 \subsection{\protect\FN{gendefs.h}}

  This file is included by \FN{main.h} and serves to collect
assorted macro and constant definitions.  It should normally not
require modification on any new host computer.

 \subsection{\protect\FN{getbmap.h}}

    Some output devices require the construction of a bitmap
containing the page image.  Originally, the bitmap was simply
statically allocated as a single global array.  However, the
\INDEX{segmented memory}{segmented memory}
segmented memories of the \N{Intel iAPX} microprocessors pose a
problem, because the bitmap is almost always larger than one
memory segment.  If all compilers supported accessing of objects
larger than one segment, this problem could be ignored at the
expense of efficiency
\INDEX{efficiency}{efficiency}
(recall that a large array indexing
operation takes about 30 iAPX instructions).  None of the four
\C{} compilers I have tried permit compile-time allocation of
objects larger than one segment.  Three of them provide alternate
memory allocation library functions which can be used at run time
to create large objects, but unfortunately, \MICROSOFT{} Version 3.0
permits {\em no\/} addressing of large objects, even when the large
memory model compile option is selected; Version 4.0 remedies
this problem.

  After giving the matter some thought, I decided to implement
the bitmap as a run-time allocated object, which on large
machines is a single array, and on the \N{Intel} family, is a vector
of large-memory pointers to raster lines.  The allocation is
performed by \CF{getbmap}.  These two different representations
pose a usage problem, because addressing of a particular word in
a given raster line is different in the two cases.  The bitmap is
accessed frequently, so function call overhead to get at it
cannot be tolerated.  Fortunately, the \C{} preprocessor comes to
the rescue, and the \CN{BITMAP(y,x)} macro has been defined to
return the address of the requisite word with in-line code.  This
can be assigned to a scalar pointer variable, which is then
incremented as the scan steps through the raster line.  The only
precaution necessary here is to avoid stepping the pointer from
one raster line to another, since this is certain to fail with
the vector-of-pointers representation.  The only function which
needed to be changed for this purpose is \CF{clrbmap}.  Use of
the scalar pointer variable reduces the bitmap addressing
overhead to once per raster line, which is acceptable.

 The preprocessor symbol \CN{SEGMEM} is used to select appropriate
code fragments in \CF{clrbmap}, \CF{getbmap}, \FN{machdefs.h},
\CF{main}, and several of the \FN{dvixxx.c} files.

  Changes were also necessary in \CF{makechar} and in some of the
\CF{prtbmap} variants which appear in several of the
\FN{dvixxx.c} files to handle vectors of raster pointers, rather
than scalar pointers, but this again has been hidden from the
code by appropriate preprocessor macro definitions.

 \subsection{\protect\FN{getbytes.h}}

  This function retrieves the next $n$ bytes from a file (usually
the DVI file), returning them in a character array.  It is short
enough, and used often enough, that it could profitably be
redefined as a macro for in-line expansion in some future
version of the code.
\SUBINDEX{to-do list}{to-do list}{functions into macros}
 \subsection{\protect\FN{getfntdf.h}}

 This function uses \CF{readfont} to collect all the font
definitions stored in the DVI file postamble.  It is called  from
\CF{readpost} when font preloading has been requested.

 \subsection{\protect\FN{getpgtab.h}}

  This function uses the {\em last page\/} pointer stored in the
DVI file postamble to follow the chain of pointers to page
beginnings right back to the first page set by \TeX{}.  It uses
the random I/O facilities of \C{} to accomplish this.  The page
table constructed contains byte position pointers to each of the
pages for the output document; it is used in \CF{main} to
find and process the pages requested by the user.  \TeX{}
stores  ten counters
\INDEX{page counters}{page counters}
for each page; currently, only the
first of these is collected and saved.  This is conventionally
the page number.

 \subsection{\protect\FN{inch.h}}

  In order to support run-time option values with attached units,
the function \CF{inch} is provided.  It converts a string
containing a fractional number followed by a two-letter unit
designator to a floating-point return value in inches.  My
apologies for the name of this function to the rest of the world
which uses the metric system---our paper sizes are still in
inches.  The units recognized are given in the following table:
 \begin{center}
 \begin{tabular}{|l|l|}
 \hline
        value &                 units implied \\
 \hline
        \#.\#\#bp       &       big point (1in = 72bp)\\
        \#.\#\#cc       &       cicero (1cc = 12dd)\\
        \#.\#\#cm       &       centimeter\\
        \#.\#\#dd       &       didot point (1157dd = 1238pt)\\
        \#.\#\#in       &       inch (1in = 2.54cm)\\
        \#.\#\#mm       &       millimeter (10mm = 1cm)\\
        \#.\#\#pc       &       pica (1pc = 12pt)\\
        \#.\#\#pt       &       point (72.27pt = 1in)\\
        \#.\#\#sp       &       scaled point (65536sp = 1pt)\\
 \hline
 \end{tabular}
 \end{center}
A leading plus or minus sign is optional, and the letter case of
the dimension name is ignored.  No space is permitted between
the number and the dimension.

 \subsection{\protect\FN{initglob.h}}

  \CF{initglob} is called once at the beginning of \CF{main} to
handle all initializations of global variables.  Although \C{}
permits declaration-time variable initializations by constants,
this is not always convenient when machine-dependent actions,
such as construction of word-size dependent bit masks, are
required.  \CF{initglob} uses the standard library function,
\CF{getenv}, to obtain any run-time definitions of the
\X{environment variable}s \CN{DVIHELP}, \CN{FONTLIST}, \CN{TEXINPUTS} and
\CN{TEXFONTS} which are to override the internal defaults.  See
the sections on \CF{fontfile}, \CF{fontsub}, \FN{machdefs.h}, and
\CF{usage} for further remarks.

  The driver family will accept \FN{.gf}, \FN{.pk}, and
\FN{.pxl} font file variants, but not all sites may be
expected to have all of these.  A default font file type
search path is therefore established internally, with font
types in the order \FN{.pk}, \FN{.gf}, and \FN{.pxl}, which
corresponds to increasing file size, and places new \MF{}
fonts before old \MF{} fonts.  This search path can be
overridden at run time by definition of an alternate path in
the \CN{FONTLIST} \X{environment variable} (\X{logical name} in
\DEC{} operating systems).  Because operating systems may
impose a particular syntax on environment variables,
\CF{initglob} will ignore letter case and any other
characters except the three strings \CN{GF}, \CN{PK}, and
\CN{PXL}; only the order, and presence or absence, of these
in the definition is significant.  Acceptable strings
equivalent to the default search path could therefore be
\CN{PKGFPXL}, \CN{pk/gf/pxl}, \CN{pk GF pxl},
\CN{pk-gf.pxl}, and so on.

    There is absolutely no harm in using the default value
of \CN{FONTLIST}, even if some of the font file types are
not available, since all that will happen is that a file
open will fail and another will be tried.  Redefinition of
\CN{FONTLIST} to avoid open attempts on files which are
known not to exist is only for efficiency.
\INDEX{efficiency}{efficiency}
It is of course also useful during debugging to be able to force
the use of a particular font type.

 \subsection{\protect\FN{keydef.h}}

\FN{keydef.h} contains flag definitions and function
declarations for the \X{keyboard input} package, \FN{keybrd.c}.
It is included by \FN{main.h} only for those devices which need
it.

 \subsection{\protect\FN{keybrd.c}}

In order to support better control of screen display for
interactive DVI drivers, I developed a set of \X{keyboard input}
primitives defined in \FN{keybrd.c}.  These are analogous to
\C{}'s standard input functions, but guarantee (if the host
supports it) immediate access to keyboard characters without
blocking in a wait for a carriage return, and also provide a
function for testing if input is available.  The code necessary
to do this is ugly on all the operating systems supported for this
DVI driver family, and is best hidden away in a separate module.

Because it is likely to be useful in other applications, this
package must be separately compiled and linked with each
interactive DVI driver, instead of being included in the source
with a preprocessor directive.

The extensive initial comments in \FN{keybrd.c} describe the
package in detail.  The header file \FN{keydef.h} must be
included in modules which use the package in order to obtain flag
definitions and function declarations.

 \subsection{\protect\FN{loadchar.h}}

  As new characters are referenced by the DVI file, the driver
must keep track of them, retrieving character metrics and
bitmaps  from the font files.  With the exception of  the main
body font in a document, only  a few characters from each font
are likely to be used, so it would make no sense whatever to
load an entire font in just because one character from it was
used.  Instead, space for character definitions is allocated
dynamically, and a \X{reference count} for each character is
maintained.  When space is no longer available, which is discovered
when \CF{malloc} begins to return null pointers, garbage
collection is in order.  This is a topic of continuing interest
in computer science, particularly in the Lisp language family.

David Fuchs and Don Knuth
\INDEX{Fuchs, David}{Fuchs, David}
\INDEX{Knuth, Donald}{Knuth, Donald}
wrote an interesting Stanford
report in 1981 entitled {\em Optimal Prepaging and Font
Caching\/}%
\footnote{\INDEX{footnotes}{footnotes}%
        Later published in {\em ACM Transactions on Programming
        Languages and Systems\/}, {\bf 7}, No. 1, 62-79 (1985).
}
which treats the problem from the point of view of a
\TeX{} DVI driver.  They point out that in this case, the
job is somewhat easier, because it is possible for the
driver to look ahead to see what characters are needed next,
rather than using \X{reference count}s which reflect past
history of character usage.  One of the surprising results
they found was that with proper implementation of their
algorithm, relatively little storage is actually needed on
the output device to keep it always supplied with the needed
fonts.

  The scheme used in our DVI drivers is more modest.  No
lookahead is done, so the \X{reference count}s can be used to
identify characters, and even entire fonts, which are
candidates for storage reclamation.  Actually, most
implementations of the driver family so far have been on
hosts with a large address space, and we have been able to
get by without even having to do garbage collection.
Nevertheless, the \X{reference count}s are there for use, or
some ambitious implementor can go and study {\it Optimal
Prepaging and Font Caching} to figure out how to do the job
right.
\SUBINDEX{to-do list}{to-do list}{optimal font handling}

  \FN{loadchar.h} is the version used for the bitmapped
output devices; it retrieves character rasters and leaves
them in a dynamically-allocated memory block located by
a pointer in the
\CN{char_entry}
structure.  Private
versions of \CF{loadchar} for downloaded font devices send
the rasters directly to the device, rather than preserving
them in memory.  In either case, \CF{loadchar} does not
itself actually retrieve the rasters from the font file; it
calls \CF{charxx} to do the job.  \CF{charxx} is declared in
the \CN{font_entry} structure as
\begin{verbatim}
    void (*charxx)();
\end{verbatim}
and was stored in the font structure by \CF{readfont} with
a statement like
\begin{verbatim}
    fontptr->charxx = (void(*)())charpk;
\end{verbatim}
which saves the address of the function required to read the
character rasters.  It is more convenient, and more
efficient, to do it this way, than to use the font type to
index a \CN{switch} statement every time one of these
functions must be called.  \CF{loadchar} should be able to
call it by
\begin{verbatim}
    (void)(*fontptr->charxx)(c,outrow);
\end{verbatim}
since the pointer operator, \verb|->|, has higher precedence
than the indirection operator, \verb|*|.  In fact, Kernighan
\INDEX{Kernighan, Brian}{Kernighan, Brian}
and Pike,
\INDEX{Pike, Rob}{Pike, Rob}
in their book {\em The Unix Programming
Environment\/}, use precisely this construction on p. 250.
They also use the more complex, but equivalent, variant
\begin{verbatim}
    (void)(*(void (*)())(*fontptr->charxx))(c,outrow);
\end{verbatim}
on p. 264.  These work as expected with the \LATTICE{},
\MICROSOFT{}, and \WIZARD{} \C{} compilers on the
\IBMPC{}, but on
both \PCC{} and \N{4.1BSD} \CN{cc}, these generate a jump to the
word {\em containing\/} the address of the function, rather
than to the function itself!
%
% Original formulation works fine with KCC [18-Apr-87]
%
It took some experimentation to find that a workaround was
possible:
\begin{verbatim}
    void (*charyy)();
    ...
    charyy = fontptr->charxx;
    (void)(*charyy)(c,outrow);
\end{verbatim}
This results in correct code with all compilers used so far for
the DVI driver family, so
\CF{loadchar} adopts it as the standard way to do things, in
the expectation that the bug is likely to be found in other
\UNIX{} compilers derived from the \N{Portable} \C{} compiler.
I have not had time to dig into the compiler sources to
track down the source of the problem.
\SUBINDEX{to-do list}{to-do list}{track down compiler error}

 \subsection{\protect\CF{loadbmap}}

 \CF{loadbmap} is used to download large characters as raster
bitmaps, instead of as downloaded fonts.  It is used in those
drivers which have a limitation on downloaded font sizes.
Private definitions exist in \FN{dvican.c} and \FN{dvijep.c}.

 \subsection{\protect\FN{machdefs.h}}

  This file is included by \FN{dvihead.h}, which in turn is
included by \FN{dvixxx.c}.  It contains almost all of the
machine-specific definitions; the only other ones are already
bracketed by preprocessor conditional directives using symbols
defined in this module.  Unless you are developing a new
implementation, {\em it should not be necessary to change more
than this single file\/} when you install any one of the dozen or
so drivers in the family.

   Comments in this file describe each of the flags, and they will
not be repeated here.  The important things to change are
 \begin{itemize}
 \item
      the \X{operating system flag}, currently one of
      \CN{OS_PCDOS},
      \CN{OS_TOPS20},
      \CN{OS_UNIX},
      or
      \CN{OS_VAXVMS};
 \item
      the \X{implementation flag}, either none at all, or one of
      \CN{ATT},
      \CN{BSD41},
      \CN{BSD42},
      \CN{HPUX},
      \CN{PCC_20},
      \CN{KCC_20},
      \CN{IBM_PC_LATTICE},
      \CN{IBM_PC_MICROSOFT},
      or \CN{IBM_PC_WIZARD};
 \item
      the default file pathnames, \CN{FONTPATH} and \CN{SUBPATH};
 \item
      the default \X{environment variable}s, \CN{TEXFONTS} and
      \CN{TEXINPUTS}.
 \end{itemize}
The last two of these are already encapsulated in code selected
by the current
\CN{OS_xxxx} flag, but
they may differ from
site to site, even with the same operating system and compilers.
In order to minimize the dependence of the programs on specific
file path names, in most implementations, the \X{environment
variable}s (\X{logical name}s in \DEC{} operating systems) are tested
at run time in \CF{initglob}, and any values they have replace
the default file paths.  Thus, even though a driver compiled on
one \IBMPC{} might have been built with the assumption that the
fonts are found in the directory \FN{d:\-\bs{}tex\-\bs{}fonts},
it still may be usable on another system where the fonts have
been installed in the directory
\FN{c:\-\bs{}usr\-\bs{}pctex\-\bs{}texfonts}.  All the user need
do is define the name \CN{TEXFONTS} before running \TeX{}:
\begin{verbatim}
SET TEXFONTS=C:\USR\PCTEX\TEXFONTS\
\end{verbatim}
Note the final backslash---\CF{fontfile} will assume it can
simply prefix the definition of \CN{TEXFONTS} to a file name.

There are several other parameters defined in \FN{machdefs.h};
the best thing to do is examine each of them in turn, and change
them to suit the local environment, before compiling any of the
drivers.

 \subsection{\protect\FN{main.h}}

  This is the main program for all of the DVI drivers.  It had
become large enough to cause problems with some
compilers, so most of the code has been split out into seven
other functions.  It
contains
\CNNX{\#include}'s\INDEX{#include}{\CNNX{\#include}}
for \FN{commands.h}, \FN{gendefs.h},
\FN{gblprocs.h}, and \FN{gblvars.h}, as well as for several
standard system header files.  Following this, it defines the
\CN{BITMAP(y,x)} macro for bitmap addressing

  The code body then checks the argument count, and calls
\CF{usage} and \CF{exit} if none are given, and then goes on to
call \CF{initglob} for initialization, \CF{option} to process
run-time options, \CF{dvifile} once for each command-line argument
which is not an option, and finally terminates with a call to
\CF{alldone}.

 \subsection{\protect\HCF{makechar}}

 For those dot-matrix printers which require bitmap
encodings of vertical bit columns, it has proved convenient to
hide the messiness of this in a separate function, \CF{makechar},
which is defined in several of the \FN{dvixxx.c} files.  Because
it must deal with bits in several raster lines, this function is
sensitive to the bitmap representation, as discussed in the
section on \CF{getbmap}.

 \subsection{\protect\FN{movedown.h}}

   This function is called in response to a vertical movement
command from the DVI file.  It updates the current vertical page
position,
\CN{v}, in \TeX{} units, and computes a new rounded position,
\CN{vv}, in device units, using \CF{fixpos} to get it right.
Efficiency
\INDEX{efficiency}{efficiency}
buffs might want to turn this into a preprocessor
macro, since it is used often.
\SUBINDEX{to-do list}{to-do list}{functions into macros}

 \subsection{\protect\FN{moveover.h}}

   This function is called in response to a horizontal movement
command from the DVI file.  It updates the current horizontal
page position, \CN{h}, in \TeX{} units, and computes a new
rounded position, \CN{hh}, in device units, using \CF{fixpos}
to get it right.  Like \CF{movedown}, it is often used, and
is a candidate for macro metamorphosis.
\SUBINDEX{to-do list}{to-do list}{functions into macros}

 \subsection{\protect\FN{moveto.h}}

  This function should really be a macro; it just records the
new current point (in device coordinates) in the global
variables (\CN{xcp},\CN{ycp}).
\SUBINDEX{to-do list}{to-do list}{functions into macros}


 \subsection{\protect\HCF{newfont}}

 When \CF{readgf}, \CF{readpk}, and \CF{readpxl} have retrieved
necessary font information, they call \CF{newfont}, currently
defined only in \FN{dvialw.c}, \FN{dvibit.c},
\FN{dvican.c},
\FN{dviimp.c},
and \FN{dvijep.c}.
It has the job of outputting whatever is necessary to the device
to define the use of a new font.

 \subsection{\protect\FN{nosignex.h}}

  In the interests of compactness of the DVI file, when \TeX{}
writes an integer, it usually tries to use the fewest number of
bytes possible.  The integer may be a signed or an unsigned
value.  This function collects the next $n$ bytes from the file
and returns them as a single $n$-byte {\em unsigned\/} integer
value, where $n$ is in 1 \ldots 4.  \CF{nosignex}, like its
twin \CF{signex}, is heavily used, and is a good candidate
for special loopless code and in-line expansion.
\SUBINDEX{to-do list}{to-do list}{functions into macros}

 \subsection{\protect\FN{openfont.h}}

  Whenever a font switch is called for by the DVI file, it may
be necessary to find and open a new font file; \CF{openfont}
is called to handle the operation.  It uses \CF{fontfile} to
obtain lists of possible file names, and if none of these
can be opened, it will first ask \CF{fontsub} for a possible
font substitution, and if that too fails, it will try
neighboring members in the magnification family.
\INDEX{font magnification}{font magnification}

  In typical \TeX{} documents,
font switching occurs {\em often\/} (three times in this very
sentence).  On all operating systems, file opening is a relatively
expensive operation,%
\footnote{\INDEX{footnotes}{footnotes}%
        On a large university \N{IBM} mainframe where I did my
        graduate work, each file opening cost us \$0.50, except
        at night, when it dropped to \$0.25.  I'm glad those days
        are gone!  I probably spent more money doing that, than I
        did for the \IBMPC{} on which I'm now writing this document.
}
and the drivers therefore take care to avoid
unnecessary openings.

  The number of open files allowed is
\INDEX{open file limit}{open file limit}
usually dependent on fixed tables in the operating system, which
in practice are much too small.  You have to set special
parameters in your \FN{config.sys} file to get more than the default
of 8  open files with  \PCDOS{}, and 5 of these are already
used by the  operating system; 20 is the absolute limit.
\TOPS{} allows more than 70 open files per process, but
\PCC{} follows the \UNIX{} practice of limiting the number to
20, at least 3 of which are in use when the process begins.
Also, buffer space is required for each open file, and since \PCC{}
does not support \TOPS{} extended addressing, one tends to run out
of memory for buffers before one runs out of file handles for
new file openings.  \KCC{} permits 32 open files, and its support
for extended addressing eliminates the buffer space problem.

The number of open files that the drivers will use is determined
by the constant \CN{MAXOPEN} set in \FN{machdefs.h}, and the
ones currently open are maintained in a cache.  Each open
request for a file in the cache increments an open reference
count.  When the \CN{MAXOPEN} limit is reached, the font file
which has the lowest open \X{reference count} is closed, but any
characters cached from it are retained in memory for further
use.   The new file is then opened and a cache entry created for
it.

   The \X{font cache search} is a simple sequential search; since
\CN{MAXOPEN} in practice is quite small (5 to 15), there would
likely be little benefit in implementing a more sophisticated
associative cache table using hashing or binary search.
However, it should be considered if an implementation is made
which permits much larger numbers of open files; all that needs
to be changed is the first \CN{for} loop in \CF{openfont}.
\TeX{} is prepared to have up to 64 active fonts, so
\CN{MAXOPEN} could potentially be as large as that.
\SUBINDEX{to-do list}{to-do list}{fast font cache search}

 \subsection{\protect\FN{option.h}}

  All run-time command-line \X{option parsing} is handled by this
function.  After \CF{initglob} has done global initializations,
\CF{option} is called once for each option found in the
\CN{argv[]} array passed to \CF{main} by the \C{} run-time
library startup routine.  \CF{option} is just a big \CN{switch}
statement with cases selected by the second character of its
string argument.  A bad argument results in a call to
\CF{usage} followed by a termination call to \CF{fatal}.

  All of the variables which can be set by run-time options are
global, so \CF{option} only has a single argument.  New options
can be easily added merely by introducing a new global variable
in \FN{gblvars.h}, a new \CN{case} pair in the \CN{switch}
statement in \CF{option}, and code selected by the option
wherever else it is required.

  The available options will not be repeated here; they are
completely described in \FN{dvihead.h}, and in the separate help
file, \FN{dviman.ltx}.  That help file also exists in a more
useful format, \FN{dviman.texinfo}, which can be converted by
\N{Gnu Emacs} to a \FN{.info} file.

   The option parsing is simple, involving little more than
noting the presence of an argument, or collecting its string or
integer value, or calling \CF{inch} to convert a number
followed by a unit specifier.  Similar code is present in
almost all \C{} programs.  The one difference here is that
{\em option letter case is not significant\/}.

  In my view, one of the design flaws of \UNIX{} and \C{}
was to make letter case significant in names.  This means
that every $n$-character identifier has $2^n$ different
variants, all pronounced the same.  The code therefore
cannot pass the ``\X{telephone test}'' (dictate your favorite
program over the telephone to a friend without excessive
spelling of words).%
\footnote{\INDEX{footnotes}{footnotes}%
        The situation is not unlike Japanese, for which the 600
        or so commonest Kanji (Chinese) characters used in
        \INDEX{Kanji characters}{Kanji characters}%
        \INDEX{Japanese characters}{Japanese characters}%
        \INDEX{Chinese characters}{Chinese characters}%
        written Japanese share only about 25 different
        pronunciations, resulting in the necessity of speakers
        writing characters in the air or on their palms to
        distinguish which one is really meant when the choice is
        not clear from context.  This homonymic situation also
        poses a problem for phonetic Roman character computer and
        word processor input schemes with \X{oriental languages}; see
        the January 1985 issue of {\em IEEE Computer\/}
        \INDEX{IEEE Computer}{\string\em\space IEEE Computer\/}
        for several interesting articles.
}

  All user command-line input to the DVI drivers is letter-case {\em
insensitive\/}, except possibly for file names, which must conform
to the host operating system conventions.  Internally,
compiled-in file names are represented in lower case letters,
since that works for both \UNIX{} and most case-insensitive
operating systems.  The \UNIX{} \X{environment variable}s are in
upper-case, since that is conventional, though not required, in
\UNIX{}, similar to the common practice of \C{} programmers of
specifying variables with lower-case names, and preprocessor
constants with upper-case names.

  This practice, incidentally, is {\em rigorously\/} adhered to in
the DVI driver family.  When you see a name entirely in
upper-case
\INDEX{letter case}{letter case}
in the source code, you can be sure it is a
preprocessor constant, and not a variable or function name.  The
reverse is also true.  No names are spelled in mixed letter
case.%
\footnote{\INDEX{footnotes}{footnotes}%
        Except \TeX{}, when for lack of it, you have to write it {\tt TeX}!
}

 \subsection{\protect\FN{outrow.h}}

  Once a single row of a character bitmap has been retrieved,
decoded, and stored in the global array
\CN{img_row[]},
\CF{outrow} is called from \CF{chargf}, \CF{charpk}, and
\CF{charpxl}, to prepare it for output.  The public version in
\FN{outrow.h} is used by most of the family; it merely copies the
row from its global storage location to the dynamically-allocated
raster storage for that character.  Private versions of
\CF{outrow} in \FN{dvialw.c}, \FN{dvibit.c},
\FN{dvican.c},
\FN{dviimp.c},
and \FN{dvijep.c},
handle the formatting and output of the row for their particular
device.

 \subsection{\protect\HCF{prtbmap}}

  This function is not stored in a separate include file,
because it is sufficiently different from device to device to
warrant inclusion inside the \FN{dvixxx.c} routines as a private
function.  Nevertheless, it is an important one, because it has
the job of formatting a completed bitmap for output to the
device.

  The bitmap cleared by \CF{clrbmap}, and written by
\CF{dispchar}, is conceptually a simple rectangular array of
bits, consecutive bits in memory corresponding to consecutive
dots on the output rasters.  For addressing \X{efficiency}, however,
each scanline begins on a new word or byte boundary, depending on
the host architecture, and if the host has \X{segmented memory}, it
may be stored as a separately-allocated raster lines, as
described in the earlier section on \CF{getbmap}.  This format
allows efficient operation by \CF{dispchar}, which can do its
important job oblivious to the peculiarities of output device
expectations.

\CF{prtbmap} must take this rectangular array of bits
and reformat it for the output device.  For some devices,
like the \HPLJ{}, this is straightforward
---only some escape sequences at the start and end of each
raster line have to be attached, but otherwise, the raster
bytes can be dumped directly to the output file.

The \N{Printronix} printers are almost straightforward---they want
horizontal raster lines encoded six bits per character; the
peculiarity is that the bits must be reversed in the byte!  It
looks like some designer got his wires crossed.  This
unpleasantness is most easily handled by table lookup, and that
is just what \CF{prtbmap} in \FN{dviprx.c} does.

Other printers are more obnoxious---they want 6, 7, 8, or 24 bits
in a {\em vertical\/} column to be reordered into consecutive
bytes, because then the print head pins can be matched to the
input bits and fired or not.  For those that place fewer than 8
bits in a byte, most do so by biasing by 64 or 128, which can be
done by a logical {\em or\/} operation.  The \DEC{} \N{LA} family
printers use a bias of 63, which requires a slower addition for
each output byte.  Printer designers have apparently not
understood that input buffers of horizontal raster lines would be
so much easier for the user, and also offer better possibilities
for run-length compression of rasters.
\INDEX{run-length encoding}{run-length encoding}

  This routine is probably the most tedious to code in the
drivers, and it must be redone for each new bitmap format.
It typically requires 50 to 100 lines of code (excluding
translation tables).  It is a fairly time-consuming
operation, so the code goes to some length to be efficient,
\INDEX{efficiency}{efficiency}
using tricks like scanning over zero words in a raster line,
trimming empty top and bottom raster lines before starting
the encoding, and unrolling inner loops.  The code is also
likely to be dependent on host word size, and for a few
lines in the inner loops, portability may well be sacrificed
to efficiency.

  Some of the dot matrix printers support run-length compression
\INDEX{run-length encoding}{run-length encoding}
of rasters, wherein consecutive identical bytes are collapsed
into a count field and a single data byte.  This is a little
tricky to get right, and is less effective with the vertical
encodings than it would be with horizontal encodings, but it
usually does reduce the output file size somewhat.  The
disappointing feature is that the printer is likely to run
{\em slower\/}, rather than faster, because of inefficient decoding of
the compression.  If you have such a printer, try it both ways
before you decide which method to use.

 \subsection{\protect\FN{prtpage.h}}

   \CF{prtpage} is one of the largest functions in the family.
Its job is to typeset a single page selected by its caller.  It
has nearly 400 lines of code, but is really just a single loop
containing a giant \CN{switch} statement which selects code
fragments corresponding to each one of the 256 different byte
codes which can be found in a DVI file.  The loop exits when an
end-of-page command is reached.

For interactive displays (e.g.  \CN{dvibit}), it also calls the
end-of-page routine, \CF{eopact}, whenever \X{keyboard input} is
available.  This permits instant response of the screen display
to user commands to reposition the display, go to a new page, or
change the display magnification;
\INDEX{font magnification}{font magnification}
no time is wasted finishing the
page display if it is just going to be changed anyway.

Fortunately, the first 128 DVI codes are just ordinary character
typesetting requests, and another 64 are font change commands, so
$3/4$ of the cases can be handled by four lines of code.

  Almost all of the DVI driver run time is spent in
\CF{prtpage} and the functions it calls, but because its
structure is so simple, there is little one can do to improve it,
short of in-line expansion of code for some of the more
commonly-used command codes.

Implementation of the {\em Optimal Prepaging and Font Caching\/} algorithm
discussed earlier in the  \FN{loadchar.h} section  would
probably involve converting this into a two-pass operation, one
to collect commands and font requirements for a single page,
caching the commands in memory to reduce I/O requirements,
followed by a similar loop to process them, with font preloading
happening at appropriate times as determined by the \X{Fuchs-Knuth
algorithm}.
\SUBINDEX{to-do list}{to-do list}{optimal font handling}

 \subsection{\protect\FN{readfont.h}}

  This function is called by \CF{getfntdf} to read in a
single font definition sequence in the DVI file postamble, or the
first time a font definition is encountered, if preloading has
been suppressed.  It initializes the  \CN{font_entry}
structure with parameters from the DVI file, then calls
\CF{reldfont} to direct the loading of additional information
from the font file.

 \subsection{\protect\FN{readgf.h}}

  \CF{readgf} is called from \CF{readfont} to initialize all
font parameters for a \FN{.gf} font file, and retrieve the
character metrics.  As noted in the earlier section on
\CF{chargf}, the entire file must be read to collect all of
the metrics.  For the several drivers currently supporting
downloaded fonts, \CF{newfont} is called to do whatever is
required to start a new font.

 \subsection{\protect\FN{readpk.h}}

  \CF{readpk} is called from \CF{readfont} to initialize all
font parameters for a \FN{.pk} font file, and retrieve the
character metrics.  Just as for \CF{readgf}, the entire file
must be read to collect all of the metrics, and for the
drivers currently supporting downloaded fonts,
\CF{newfont} must be called to do whatever is required to
start a new font.

 \subsection{\protect\FN{readpost.h}}

  This function is called near the start of \CF{main} after
command-line options have been processed.  It coordinates the
reading and checking of the DVI file postamble, using function
\CF{findpost}, calls \CF{getfntdf} if font
preloading has been requested, and finally calls \CF{getpgtab} to
retrieve the document page table.

 \subsection{\protect\FN{readpxl.h}}

  \CF{readpxl} is called from \CF{readfont} to initialize
all font parameters for a \FN{.pxl} font file, and retrieve
the character metrics.  Since these are all available in a
2-Kbyte directory at the end of the file, minimal file
activity is needed to retrieve them.  \CF{newfont} is then
called to do whatever is required to start a new font.

 \subsection{\protect\FN{reldfont.h}}

This function was split out of \FN{readfont.h} to separate the
retrieval of font information from the DVI and font files, in
order to support dynamic unloading of fonts required by the zoom
option in \CN{dvibit}.  It is called from \FN{readfont.h} and
from the private function
\INDEX{private modules}{private modules}
\CF{unload_fonts} in \FN{eopact.h}.
\CF{openfont} is used to find and open the font file, and
then \CF{getfntdf} dynamically allocates a font entry
containing basic character metrics for all characters in the
font, but none of the potentially voluminous raster information.
That portion is left in the font file for later retrieval and
memory caching only when it is really needed.

  If font preloading has been suppressed (this is a run-time
option), then \CF{getfntdf} will not be invoked at startup for
all fonts found in the postamble, but only dynamically as each
font is required.  Preloading is forced if selected pages are
printed, or pages are printed in reverse order (e.g. \CANON{}
\N{LBP-CX}
laser print engines without additional paper handling
mechanisms).  This is necessary because \TeX{} outputs a font
definition command the first time a font is used, and then never
again until the postamble is written.  The code in \CF{newfont}
ensures that the device receives the proper font definition
sequences, and must be executed before any character in the font
can be used.

  With the addition in late April, 1986, of support for the new
\FN{.gf} and \FN{.pk} font file formats, a considerable revision
of font handling became necessary, and resulted in the
introduction of 11 new functions:
\CF{chargf},
\CF{charpk},
\CF{charpxl},
\CF{clrrow},
\CF{outrow},
\CF{readgf},
\CF{readpk},
\CF{readpxl},
\CF{skgfspec},
\CF{skpkspec}, and
\CF{strid2}.
The goal in this was to make the source of font data known
to only a small number of routines.  After opening a font
file successfully, \CF{reldfont} examines the bytes at the
start of the file which uniquely identify which of the three
font file types it is.  It saves the font type and character
retrieval function (\CF{chargf}, \CF{charpk}, or
\CF{charpxl}) in the
\CN{font_entry}
structure, then calls
\CF{readgf}, \CF{readpk}, or \CF{readpxl} to actually read
the character metric data from the file.

  Should a new font file format be introduced, all that
is necessary to support it is to add code to \CF{reldfont}
to recognize it, and provide analogues of \CF{chargf} and
\CF{readgf} to retrieve character rasters and metrics.

 \subsection{\protect\FN{rulepxl.h}}

  This short function converts a dimension of a horizontal or
vertical rule measured in high-precision \TeX{} units to output
device units.  It is a good candidate for macro replacement.
\SUBINDEX{to-do list}{to-do list}{functions into macros}

 \subsection{\protect\FN{setchar.h}}

  Apart from positioning commands, {\em Set Character\/} commands
make up the bulk of the commands in the DVI file.  \CF{setchar}
is called for each of them.%
\footnote{\INDEX{footnotes}{footnotes}%
        Except in some drivers; see \CF{setstr} in a later section.
}

  First of all, it determines whether or not the character
is visible on the current page.  If it is, then it calls
\CF{moveto} to update the current position, and then
\CF{dispchar} to paint
\INDEX{character painting}{character painting}
the character.

Then, depending on the particular DVI file command that invoked
it, it may update the current horizontal position in both \TeX{}
coordinates and device units.  \CF{fixpos} again is used to
do it right.

 \subsection{\protect\FN{setfntnm.h}}

  There are 64 DVI file commands which request font
changes, and \CF{setfntnm} is called for each of them.  It
defines the font to be used for future printing until another
{\em Set Font\/} command is encountered.

   Because actual font definitions are handled by another DVI
command,%
\footnote{\INDEX{footnotes}{footnotes}%
        See \CF{getfntdf}.
}
when this function is
invoked, the font is already expected to have been loaded into
the cache.  A sequential search%
\footnote{\INDEX{footnotes}{footnotes}%
        See the remarks in the subsection on \CF{openfont}.
}
of the cache is made to find the
font pointer for the requested font; if it is not found, \CF{fatal}
is called to terminate the job.
\SUBINDEX{to-do list}{to-do list}{fast font cache search}

 \subsection{\protect\FN{setrule.h}}

  When \TeX{} sets a horizontal or vertical rule, it generates a
DVI command which results in \CF{setrule} being called.  It
in turn calls \CF{fillrect}, then updates the horizontal
positions, \CN{h} and \CN{hh}, relying again on \CF{fixpos}
for help.

 \subsection{\protect\HCF{setstr}}

  \TeX{} does not insert glue between letters of a word,
only between words.  Consequently, words appear in a DVI
file as consecutive {\em Set Character\/} requests, possibly
interspersed by {\em Set Font\/} commands.  For devices on
which characters must be set by the DVI driver, such as dot
matrix devices, there is no advantage to be taken of this.
For devices with downloaded fonts but relatively low
resolution, such as the \BG{}, not much can be done
either, because character widths must be rounded to pixel
boundaries, and within three or four characters, the
cumulative string position would be incorrect.

  For downloaded characters in \N{Adobe} \POSTSCRIPT{}, it is
possible to define precise widths which are not rounded to pixel
boundaries.  Several characters can be therefore be set by a
single command, reducing the output volume considerably.
\POSTSCRIPT{} has been licensed by several manufacturers, but the
most widely available product using it at present is the \ALW{},
about which we shall later have more to say.

  \CF{setstr} is currently used in the \CN{dvialw}, \CN{dvican},
\CN{dviimp}, and \CN{dvijep} drivers.  It functions similarly to
\CF{setchar}, except that it loops collecting consecutive
characters to be set, then outputs them all as a single string.
The string is interrupted and a positioning command is issued if
\CF{fixpos} produces a different horizontal position than the
device would otherwise have from its character width information.
Similarly, if a character is encountered which is too large to be
definable as a single character on the device, the string is
interrupted, and the large character is sent as a raster image.
To conserve font memory on the \ALW{}, ``large''
characters%
\footnote{\INDEX{footnotes}{footnotes}%
        The size limit can be set by a run-time option.
}
are downloaded each time they are required, bracketed by
\POSTSCRIPT{} {\em save\/} and {\em restore\/} commands which
cause them to be discarded after use.

  Because it is quite likely that a character encountered will
not yet have been downloaded, the initial version just completed
the current string, downloaded the new character definition by a
call to \CF{loadchar}, and resumed the string collection.  This
entails some extra output overhead, so to reduce it, the latest
version has two sets of loops.  The first collects the characters
into an internal array, and downloads any new ones.  The second
loop then processes the characters from the array, outputting
them as a single string.  There is a little extra run-time
overhead because of the second loop, but it is minor compared to
the reduction in the output volume.

 \subsection{\protect\FN{signex.h}}

  This is the twin to the function \CF{nosignex} discussed
earlier.  \CF{signex} collects the next $n$ bytes from the
file and returns them as a single $n$-byte {\em signed\/} integer
value, where $n$ is in 1 \ldots 4.  Negative values are represented
in {\em two's complement\/} form; implementors on one's-complement
machines (\N{CDC}, \N{Univac}) must revise the code here.

 \subsection{\protect\FN{skgfspec.h}}

  \CF{skgfspec} is called by \CF{chargf} to skip over any
\MF{} {\em numspecial\/} and {\em special\/} commands embedded
in the font file.  These are not currently used in the {\em
Computer Modern\/} fonts.

 \subsection{\protect\FN{skipfont.h}}

  If fonts have been preloaded, then when \CF{prtpage} encounters
a {\em Define Font\/} command, the font definition which
immediately follows in the DVI file must be discarded.  This
function performs that task.  If font preloading has not been
selected, \CF{prtpage} calls \CF{readfont} instead.

 \subsection{\protect\FN{skpkspec.h}}

  \CF{skpkspec} is called by \CF{charpk} to skip over any
\MF{} {\em numspecial\/} and {\em special\/} commands embedded
in the font file.  These are not currently used in the {\em
Computer Modern\/} fonts, but \CN{GFtoPK} will copy any it
finds in the input \FN{.gf} file to the output \FN{.pk}
file.

 \subsection{\protect\FN{special.h}}

  The \TeX{} \verb|\special| command provides a means for inserting
arbitrary text into the DVI file.  The  intention is to allow the DVI
driver to provide support for features, like insertion of bitmap
images, which \TeX{} cannot easily or efficiently offer.  Such strings
necessarily depend on the implementation, operating system, and output
device, and therefore detract from document portability.  Nevertheless,
the feature can be exceedingly useful.  The \TeX{} User's Group has
twice had sessions on the subject of \verb|\special| commands with a
view to coming to some consensus for what forms the command string
should take, but no definite proposal has yet been put forward.

  When \CF{prtpage} meets a DVI file {\em XXXn\/} command, which
is what \TeX{} produces in response to a \verb|\special|, it
collects the following string and passes it to \CF{special},
which has the job of interpreting it.  For most dot matrix
printers, providing useful support for insertion of bitmap images
is at best awkward, because the usually bizarre formatting
required by the device would require reconstruction of a bitmap
array from the encoding, then re-encoding it for output at the
current position.  However, it would not be difficult to add
support for vector graphics files, such as the ubiquitous
\TEKTRONIX{} format which is both compact and relatively easy to
decode.  The vectors could be suitably scaled and translated,
then written directly into the bitmap which \CF{dispchar} has
been updating.  So far, for these devices, \CF{special} just
raises a warning message containing its argument string, and then
returns without further action.
\SUBINDEX{to-do list}{to-do list}{\TEKTRONIX{} graphics file support}

  For the more intelligent laser printers, particularly
those using the \POSTSCRIPT{} language, considerably more is
possible, and the implementations of \CF{special} are still
in their infancy.  In \FN{dvialw.c} for the \ALW{}, I have
brazenly copied the format used by
David Kellerman\INDEX{Kellerman, David}{Kellerman, David}
and
Barry Smith\INDEX{Smith, Barry}{Smith, Barry}
in their driver for the \IMAGEN{} laser printers.
The \TeX{} \verb|\special| command is expected to look like
one of the following:
\begin{verbatim}
\special{overlay filename}              % absolute positioning

\special{include filename}              % relative positioning

\special{insert filename}               % relative positioning
\end{verbatim}
In the first case, the \POSTSCRIPT{} file to be included
will be mapped onto the page at precisely the coordinates it
specifies.  In the other two cases, the upper-left corner of
the bounding box will be placed at the current point.  The
\POSTSCRIPT{} file must then contain (usually near the
start) a comment of the form
\begin{verbatim}
%%BoundingBox: llx lly urx ury
\end{verbatim}
specifying the bounding box lower-left and upper-right
coordinates in standard \POSTSCRIPT{} units (big points, 1/72 inch).
Alternatively, if the comment
\begin{verbatim}
%%BoundingBox: (atend)
\end{verbatim}
is found in  the file,  the last  1000 characters  of the  file will  be
searched to find a comment of the form:
\begin{verbatim}
%%BoundingBox: llx lly urx ury
\end{verbatim}
If the \POSTSCRIPT{} file cannot be opened, or the \verb|\special|
command string cannot be recognized, or for relative positioning, the
bounding box cannot be determined, a warning message is issued and the
\verb|\special| command is ignored.

Otherwise, the section of the \POSTSCRIPT{} file between the
comment lines
\begin{verbatim}
%begin(plot)
%end(plot)
\end{verbatim}
is copied to the output file surrounded by
\begin{verbatim}
save
% revert to standard 1/72 inch units
300 72 div 300 72 div scale
% if relative positioning
(xcp(in 1/72in)-llx) (ycp(in 1/72in)-ury) translate
...PostScript file contents...
restore
\end{verbatim}

This format nicely supports  \POSTSCRIPT{} output from my \PLOT{}
graphics system and has received considerable use locally.

As we get more experience with \POSTSCRIPT{}, \CF{special} will
no doubt be expanded to support fancier operations, like
insertion of \N{MacPaint} and \N{MacDraw} images from the
\MAC{}.

\N{Adobe} Systems is aware of this problem of incorporating
\POSTSCRIPT{} files in other \POSTSCRIPT{} documents, and in
December, 1986, published a short document {\em Encapsulated
PostScript File Format, EPSF Version 1.2\/}
\INDEX{EPSF}{EPSF ({\em Encapsulated PostScript File Format\/})}
describing conventions
for doing this cleanly.  Future changes to \CF{special} in
\FN{dvialw.c} should adopt these.

 \subsection{\protect\FN{strchr.h}}

   \C{} is a sparse language, and contains no built-in functions or I/O
facilities.  The inventors of \C{} defined an extensive set of library
functions, but implementors since have not always adhered to the
original library conventions.  Besides introducing new names for the
same functions, implementors have sometimes committed the even worse sin
of defining the same functions, but with changed function return types.
This is certainly a detriment to portability.  The string support
functions are one area where significant differences exist.  I have
therefore
chosen to implement some functions which are defined in the coming
ANSI Standard \C{} library.

  \CF{strchr} searches a string for a single character,
returning a pointer to the {\em first\/} matching character,
or a null pointer if the character is not found.  It is
permissible to search for the \CN{NUL} character which
terminates the string; the returned value minus the address
of the string is the length of the string, excluding the
\CN{NUL} terminator.%
\footnote{\INDEX{footnotes}{footnotes}%
        Pointer subtraction in \C{} is defined to return the
        number of objects between the two addresses, not the
        number of memory units.
}

 \subsection{\protect\FN{strcm2.h}}

  \CF{strcm2} compares two strings, ignoring case differences,
and returns a negative number if the first is less than the
second, zero if they match, and otherwise a positive number.  It
is analogous to the usual \CF{strcmp} function which does not
ignore case differences.  \MICROSOFT{} \C{} on the \IBMPC{}
calls this function \CF{strcmpl}, but this violates our rule of
uniqueness in the first six characters of a function name.
The October 1986 draft of the proposed ANSI \C{} Standard has
no equivalent function.

 \subsection{\protect\FN{strid2.h}}
  \CF{strid2} searches for the first occurrence of a substring
in another string, returning -1 if it is not found, or else
its index 0, 1, \ldots{} if it is found.  Letter case is {\em
ignored\/}.  It is used by \CF{initglob} in the parsing of the
\CN{FONTLIST} \X{environment variable}.
The October 1986 draft of the proposed ANSI \C{} Standard has
no equivalent function.

 \subsection{\protect\FN{strrchr.h}}

  \CF{strrchr} is the counterpart to \CF{strchr}.  It searches a string
for a single character, returning a pointer to the {\em last\/} matching
character.  It is permissible to search for the \CN{NUL} terminator.

 \subsection{\protect\FN{tctos.h}}
\CF{tctos} converts a global list of \TeX{} page counters,
\INDEX{page counters}{page counters}
\CN{tex_counter[]},
to  a character string, with counters
separated by dots, and trailing zeroes dropped.  It is used by
the \FN{dvixxx.c} programs to format them for printing.

 \subsection{\protect\FN{typedefs.h}}

  This file is included by \FN{dvihead.h} after it includes
\FN{machdefs.h}.  As noted earlier, it contains \CN{typedef}
declarations for \CN{BOOLEAN}, \CN{BYTE}, \CN{COORDINATE},
\CN{INT8}, \CN{INT16}, \CN{INT32}, \CN{UNSIGN16}, \CN{UNSIGN32},
and \CN{void}.

If the implementation supports the \CN{void} type, then the \CN{typedef}
for it is suppressed.

The symbols \CN{TRUE} and \CN{FALSE} are also defined for use with
objects of type \CN{BOOLEAN}.

Dennis Ritchie's original  definition of \C{} did not clearly indicate
whether  \CN{unsigned} is a {\em distinct\/} integer type, or a {\em
modifier\/} of the integer types \CN{char}, \CN{short}, \CN{int}, and
\CN{long}.  Reasonable compilers implement it as a modifier, since one
can quite reasonably require unsigned values in a variety of sizes,
particularly in systems programming and graphics programming, where the
integers being manipulated are really bit patterns, not numbers.

Unfortunately, some compilers have chosen to make
\CN{unsigned} a distinct type meaning \CN{unsigned int}; the
\LATTICE{} \C{} compiler on the \IBMPC{} is one such
example.  This complicates programming, and special
attention must be given to those parts of the code which use
the \CN{UNSIGN16} and \CN{UNSIGN32} types.  The most
important example is the bitmap array used for the dot
matrix printer drivers.

 \subsection{\protect\FN{usage.h}}

  \CN{usage} is called from \CF{main} whenever \CN{dvixxx} is
invoked without arguments, and from \CF{option} in response to a
bad argument.  On the file defined by its single argument, it
displays a short message illustrating the expected command line,
followed by a suggestion of where to find detailed documentation
(set by the preprocessor constant \CN{HELPCMD} defined in
\FN{machdefs.h}, and possibly overridden at run time by the
\X{environment variable} \CN{DVIHELP}), then returns to its caller.

 \subsection{\protect\FN{warning.h}}

  When situations arise which warrant the issuing of a warning
message, such as a font substitution performed by \CF{fontsub},
\CF{warning} is called.  If no \X{log file} is open, it tries to open
one.  If this succeeds, the message is written to the log file,
possibly adorned by additional text.  The name of the function
issuing the call to \CF{warning} is included as part of the
message.

  For example, the \TOPS{} operating system uses the convention
that text written to the primary output file (terminal, or batch
job log file) which begins with a percent sign is a warning, and
text which begins with a query is an error message.  The batch
controller recognizes these and raises an error flag if a query
is written first.  These two characters are usually sufficiently
rare in text files that they make convenient search targets when
one is examining a \X{log file} with a text editor or string search
utility.  Consequently, when the symbols
\CN{OS_TOPS20} or
\CN{OS_VAXVMS} are
defined, \CF{warning} and \CF{fatal}
prefix these characters to the message.

 \section{DVI Driver Device Support}

  The preceding sections have given a comprehensive survey of the
structure of the DVI drivers.  In the following subsections, we
shall briefly discuss each of the currently-supported devices,
mostly in \X{alphabetical order} by filename.

  If you intend to implement a driver for a new device, you can profit
by choosing the existing driver  which most closely resembles your
target device, then modifying it appropriately.  Please send your
implementation back to this author for inclusion in the collection.

% Need italic correction after underscore to avoid it
% running into the following punctuation
  You can quickly get an idea of just which functions are
likely to require modification by using a string search
utility to find processor conditionals
``\CNNX{\#if}''\INDEX{#if}{\CNNX{\#if}}
in the
source files.  A listing will not be given here, because it
would be difficult to keep up-to-date.  You can similarly
find operating system dependencies by searching for the
string ``\CN{OS_}\/'', and implementation dependencies by
searching for any of the flags discussed earlier in the
section on \FN{machdefs.h}.

  \UNIX{} makes it easy to combine programs so that the output of
one becomes the input of the other, with both running
simultaneously.  Consequently, many \UNIX{} programs are designed
to read their input from \CN{stdin} and write their normal output to
\CN{stdout}, and error messages to \CN{stderr}.  These three files
are automatically open when a process begins to execute.  \PCC{}
supports this model as well.  I therefore had to make a design
choice of whether the DVI drivers would adopt this model or not.
In a pure \UNIX{} environment, this would be quite satisfactory,
and conform well to the notion of a {\em filter\/} program.
\UNIX{} users can quite reasonably expect to issue a command
like
\begin{verbatim}
% tex myfile | dvixxx | xxxspool
\end{verbatim}
to have the file \FN{myfile.tex} processed by \TeX{}, translated
by \CN{dvixxx}, and spooled to the output device by
\CN{xxxspool}, all in one concurrent step.

I chose not to use this model, because on the \TWENTY{}, where
all my development work is done, the output of the \CN{dvixxx}
program may not be a standard text file.  Since \PCC{} supports
only 7-bit I/O for \CN{stdin}, \CN{stdout}, and \CN{stderr},
while the output may require an 8-bit file, it is necessary to
create an intermediate disk file.  The convention adopted is that
the suffix of the driver name becomes a suffix of the DVI file
name.  Thus, on the \TWENTY{} or under \UNIX{}, \FN{myfile.tex}
is transformed by \TeX{} to \FN{myfile.dvi}, then by \CN{dvixxx}
to \FN{myfile.dvi-xxx}.  For operating systems which do not
permit long file extensions, the driver may output it as
\FN{myfile.xxx}.  This has proved to be a wise choice even in the
8-bit world, where record-structured file systems like \VAX{}
\VMS{} conflict with the byte-stream output of \CN{stdout}.

 \subsection{\protect\FN{dvialw.c}}

  This driver for the \ALW{} is the most recent addition to the
family.  It was developed starting from the \BG{} driver,
\CN{dvibit}, since this was the only other driver with downloaded
font support at the time.

  \N{Adobe} \POSTSCRIPT{} is a complete programming language
designed for the support of intelligent printer drivers.  Like
the popular%
\footnote{\INDEX{footnotes}{footnotes}%
        in some circles
}
\N{Forth} language, it is written in reverse Polish notation,
which some claim is easier to parse because operands can be
simply stacked until an operation is found, which then pops its
operands off the stack, performs its job, and places the result,
if any, back on the stack.

  Reverse Polish notation  is certainly not easy to read
without extensive practice.  For example, to set a string at a
particular page position, one writes
\begin{verbatim}
250 300 moveto
(Hello there) show
\end{verbatim}
This example shows the main problem with \POSTSCRIPT{} ---
it is verbose.  The compact \TEKTRONIX{} vector format
would encode the first command in 5 or fewer characters,
instead of 14.  Perhaps someday there will be
efficient \POSTSCRIPT{} compilers.  In the meantime, one can
only try to reduce the \POSTSCRIPT{} volume by definition of
compact macros; \CN{dvialw} produces
\begin{verbatim}
(Hello there)250 300 S
\end{verbatim}
for the above.  A space after the right parenthesis is
discarded, and the two command words are collapsed into a
single letter.

  This verbosity drastically reduces the potential performance of
the \ALW{}.  The \CANON{} print engine is capable of printing 8
pages per minute, and the \IMAGEN{} \N{8/300}
which uses it too
will output \TeX{} at 7 pages per minute.  The best we have
been able to do on the \ALW{} is about 2 per minute, and that
represents an average serial transmission rate of about 750
characters per second, close to the limit of 960 at the 9600 baud
limit.   The printer may perhaps run faster with the 29 Kbaud
\N{AppleTalk} connection.

  \POSTSCRIPT{} timing experiments showed that the \ALW{} performs
about one arithmetic operation per millisecond, and further
experiments revealed the fact that the arithmetic conforms to a
single-precision subset of the \X{IEEE floating-point} format.  This
is not surprising, because
Jerome Coonan,\INDEX{Coonan, Jerome}{Coonan, Jerome}
one of the principal
designers of the IEEE  standard, works for \N{Apple} and did the
software for the floating-point emulator for the \MAC{}.  The
printer and the computer both use the
\N{Motorola 68000}
microprocessor, and neither have floating-point
hardware.  Rumors of an advance to the faster
\N{68020}
CPU and \N{68881} hardware
floating-point chip with the
newly released \N{Enhanced} \ALW{}  were wrong; it only has more
internal fonts and more memory.

  I bought an \ALW{} in June, 1985, and although I was able to
prepare a device driver for my \PLOT{} graphics systems and have
it operational in under a day, the \TeX{} DVI driver has proved
much more difficult.  This is due to two reasons.  First of all,
the documentation and examples in the {\em PostScript User's
Manual\/} (September 1984 printing) for downloaded fonts are
incorrect; the examples simply do not work at all.  Second, the
\POSTSCRIPT{} Version 23.0 interpreter has two serious bugs.

  One of these is a flow-control bug which is documented in the
\N{Apple} {\em Inside the LaserWriter\/} manual---the printer on
occasion will send out an \CN{XOFF} character to stop host
transmission, then never send the \CN{XON} character to resume
it.  Eventually, the printer times out and aborts the job after
issuing an error message.  Initially, this seemed to happen on
almost every page, and it took several weeks of experimentation
during the summer before I was able to write a transfer program
which reduced the incidence.  In December, 1985, I obtained a
proposed fix for this bug from ARPANET correspondence, and it
seems to have helped, although the problem still does arise.

  The second bug has to do with virtual memory management,
which comes into play primarily with downloaded fonts, which
neither the \MAC{} nor graphics applications make use of.  At
random intervals, the printer issues a {\em VM error\/} message and
flushes the job.  It is usually completely irreproducible; the
same document will raise the error twice, and print on the third
try.  The longer the printer has been running, the slower it
seems to get, until cycling the power reboots it.  We have often found
it necessary to do this several times a day, hardly a
satisfactory situation for a printer which is
expected to be a spooled output device.

  Because of the flow control bug, and because the printer sends
back all kinds of messages, such as {\em
\%\%[ PrinterError: out of paper ]\%\%\/}, it is necessary to have an
intelligent file copy utility for it.  Some people have
gone to the trouble of handling \CN{XON} and \CN{XOFF} characters
themselves, establishing a real-time interrupt when an \CN{XOFF} is
received, and then resuming output either after receipt of an
\CN{XON}, or when the timer interrupts.  My copy utility, \FN{lw78.c},
lets the operating system handle flow control, but carries on a
dialog with the printer before starting each job to make sure it
is idle.  It periodically monitors the printer input  stream to
see if any message is waiting, and if so, collects it, decodes
it, and attempts to handle the commoner ones.  Status messages
do not always arrive complete, perhaps because of data loss at
the serial interface on the host computer.  Consequently, the
copy utility cannot just collect two percents and an open
bracket to start a message, then gobble characters until a close
bracket and two more percents terminate it, because this might
block the process completely.    Instead, it alternates periods
of sleep and tests for input data until about ten seconds have
elapsed without receiving a complete message.  At that point, the
message is assumed to be garbled and a flag is set which causes
later input attempts to flush data until a new start of message
is recognized.  This is clearly nothing but hackery; I am not
proud of it, and it wasted weeks of work which could have been
much more profitably spent.

  The \POSTSCRIPT{} font mechanism is complex and difficult to
understand, and much better documentation and many examples are
badly needed in the manuals.  It centers around the idea that in
the current font, for each character there is a collection of
numbers defining the bounding box and displacement to the next
character, plus a procedure which is invoked to draw the
character whenever the character appears in a {\em Set String\/}
command.  This is a powerful mechanism which is also fundamental
to the \N{Emacs} text editor.  The character procedure is free
to utilize the entire language to create a picture at the current
point.  The built-in fonts use proprietary outline encoding
mechanisms which provide arbitrary scaling.  For \TeX{}, we just
send character bitmaps down encoded as hexadecimal strings.

  After all of the work on \CN{dvialw} had been completed,
Addison-Wesley published the {\em PostScript Language
Reference Manual\/} and the {\em PostScript Language
Tutorial and Cookbook\/} in the spring of 1986.  These offer
much improved documentation, and remove my criticisms of
that aspect.  The font examples in the {\em Tutorial and
Cookbook\/} now work as advertised, and the problems with the
\ALW{} are discussed in Appendix D of the {\em Language
Reference Manual\/}.  These two books are essential for any
\POSTSCRIPT{} programmer.

    To facilitate a certain amount of extensibility of the \TeX{}
\POSTSCRIPT{} driver, macro references, rather than raw
\POSTSCRIPT{}, are written to the output file.  The macros are
defined in a standard file named \FN{dvialw.ps} which is searched
for in the current file directory, then in a standard system
directory defined by the preprocessor symbol \CN{TEXINPUTS}.
Like the font substitution file, the definition of this symbol
may be overridden by the user at run time, allowing personal
customizations.  The standard \FN{dvialw.ps} file which goes with
this driver is heavily commented to assist customization.  The
comments, and excess whitespace, are all stripped by function
\CF{cppsfile} during the copy to the beginning of the output
file, so they never have to be transferred to the printer.  The
driver is careful never to produce any unnecessary whitespace, in
order to reduce the output volume.  Even so, on large documents,
the \POSTSCRIPT{} file is usually 4 to 6 times larger than
the DVI file, and on short ones, up to 20 times longer.

  \FN{dvialw.c} supports the \TeX{} \verb|\special| command to a
limited extent; see the section on function \CF{special} for
details.

  While it is in principle possible for \FN{dvialw.ps} to support
\POSTSCRIPT{} built-in fonts, this would require preparation of
\TeX{} font metric (\FN{.tfm}) files for them.  \TeX{} needs this
information to use a font.    At present, there is insufficient
font metric information available for the built-in fonts, and
the character repertoire is inadequate for mathematical
typesetting.    Some members of the Stanford \TeX{} project have
been consulting with \N{Adobe}, so we may hope that this situation
will improve.

  For non-\TeX{} printing on the \ALW{}, we have used a utility
program I wrote, \FN{lptops.c}, to convert line printer files to
\POSTSCRIPT{}.  It has options to access all of the built-in
fonts at arbitrary sizes, as well as support for multi-column
printing, page numbering, overstriking, margin setting, multiple
copies, page outlining, and manual paper feed selection.  The
help file, \FN{lptops.hlp}, describes these further.

    The \N{Enhanced} \ALW{} was announced in February 1986, at
a list price of \$7995.  Ordinary \N{LaserWriter}'s can be
upgraded to it for about \$1000.  This new model contains
version 38.0 of the  \POSTSCRIPT{} interpreter, and offers
several new features:
 \begin{itemize}
   \item many internal performance improvements;
   \item expanded communications options, including baud
         rates to 57.6 Kbaud and hardware flow control;
         this is important for the IBM PC, which without additional
         software does not support software flow control;
   \item several new language features;
   \item correction of nearly all the known problems in the
         \ALW{}, including the flow-control bug;
   \item new resident fonts: Avant\-Garde, Bookman,
         Helvetica-Narrow, New\-Century\-School\-Book,
         Palatino, Zapf\-Chancery, and Zapf\-Dingbats;
   \item additional memory
 \end{itemize}
One of the important performance improvements is the overlap
of page output with input processing; previously, the
\POSTSCRIPT{} interpreter waited up to 6 seconds per page
before resuming input processing.  Initial user experience
with this printer is reported to be quite favorable; I
personally have not yet had any.

  \N{Adobe} has recently made available accurate font metric and
ligature information for the resident fonts.  Kerning
specifications are not yet available, but have been promised.
Unfortunately, this information is not available in the new
\POSTSCRIPT{} books, but font metric files are distributed with
\N{Adobe}'s \N{TranScript} software for \UNIX{} systems, and probably
also with \N{Pipeline Associates}' \N{devps} competing software.
This should make it possible to augment \CN{dvialw} to support
use of resident \POSTSCRIPT{} fonts with \TeX{}.  This will be
even more important for the \N{Mergenthaler Linotype Linotronic
300}, which is the first photo\-type\-setter to use
\POSTSCRIPT{}.

 \subsection{\protect\FN{dvibit.c}}

  This driver is the first in the family, but has undergone the
same extensive modifications as the rest of the members.  It is
the only one which provides a form of \TeX{} preview mechanism,
but we unfortunately have only one \BG{} terminal on
campus, so it has not received the use I would have liked to see.
With laser printers increasingly available, the need has
declined.  Although the display speed is satisfactory, the
resolution is coarse ($1024 \times 768$), and small characters are often
indistinguishable.  \TeX{}  previewers on the \IBMPC{} have an
even more severe limitation of half this resolution.

  In order to reduce the number of fonts required, the default
size with Mark Senn's original version has been changed to 603
magnification.
\INDEX{font magnification}{font magnification}
This is in the standard magnification family for
300-dot/inch devices (magstep -5).  Since we have \MF{} on the
\TWENTY{}, production of arbitrary sizes for all of the \TeX{}
fonts has been trivial; only disk space requirements limit our
enthusiasm.

  In order to write commands to the BitGraph, it is necessary to
be able to send ASCII \CN{ESC} characters, and to make the display
easily controllable, character-at-a-time input without echo is
desirable.  Under \UNIX{} systems, this is straightforward---you
just put the terminal in {\em half-cooked\/} or {\em raw\/} mode, and
twiddle a couple of \CF{ioctl} flags.  On the \TWENTY{}, it is
quite possible, but somewhat convoluted, so there are large code
sections under control of the \CN{OS_TOPS20} flag.  When the
driver exits, care has to be taken to reset the terminal
characteristics properly.

With Version 2.07 of the family, a major change was made in
\CN{dvibit}.  Keyboard input
\INDEX{keyboard input}{keyboard input}
with \CF{getc} has been replaced
with a more powerful package, \FN{keybrd.c}, described earlier.
This package supports immediate return of characters as they are
typed, and also provides a primitive for checking if input is
available, without blocking like \CF{getc} normally does.  This
makes it possible for the main command loop in \FN{prtpage.h} to
check for \X{keyboard input} before processing each DVI command,
which in turn avoids unnecessary screen redisplay, and
facilitates rapid skimming through a document, as well as rapid
page repositioning.

  In addition, the font handling mechanism was revised with the
introduction of \FN{reldfont.h}, so that \CF{unload_fonts} in
\FN{eopact.h} can dynamically change the \X{font magnification} to
support a \X{zoom command}.

  Drawing of the command and status window is now done at
page beginning by \FN{bopact.h}, and the display has been made
larger and more informative.

 The size limit at which downloaded fonts are abandoned in favor
of sending large character bitmaps each time they are needed has
been substantially increased, so that any reasonable document and
magnification
\INDEX{font magnification}{font magnification}
should be able to use downloaded fonts exclusively,
giving much faster screen display.

  The display now works correctly with both black and white
screen backgrounds (they are selectable in terminal setup mode);
previously, large characters were displayed incorrectly on a
black background.

 \subsection{\protect\FN{dvican.c}}

This driver is for the \CANON{}
\N{LBP-8 A2} laser
printer, which
uses \CANON{}'s own controller with their \N{LBP-CX} engine.
The \N{LBP-8 A2}
supports 300 dot/inch raster
graphics, vector
graphics, and, according to its documentation, downloaded fonts.

After seeing this printer offered at under \$3000 from a local
vendor, I obtained one on trial in late December, 1986, expecting
to have a graphics interface and a DVI driver completed before
the New Year.  To make a long story short, in despair, it was
returned to the dealer in March, 1987.

The documentation for the printer is abysmal, and it was only
through the help of a local laser printer development firm that I
got sufficient detail on the printer to write any software at all
for it.  Eventually, I obtained a  Subsystem Manual from
\CANON{} headquarters in New York, but this seemed to only
confirm that what \CN{dvican} is doing is correct according to
the documentation.  Downloaded fonts just do not work properly,
and to get any \TeX{} output, it is necessary to send raster
bitmaps for each character, which drastically increases the
output file size, and slows the printer to about 1 page every 3
or 4 minutes.

Correspondence with a site in Holland that had obtained another
DVI driver for this printer from Japan resulted in their sending
me a hexadecimal dump of the DVI output for the standard \TeX{}
sample file, \FN{story.tex}.  To my surprise, it too handles
characters as bitmaps, instead of using downloaded fonts.  This
tends to confirm my experience.

I have spent a great many frustrating hours with this printer; if
anyone reading this has used the printer successfully with
downloaded fonts, I would like to hear about it.  Otherwise, I am
inclined to blacklist it, and exclude it from further
consideration.

 \subsection{\protect\FN{dvigd.c}}

  This driver was adapted for the {\em Golden Dawn Golden Laser
100\/} printer developed by a local Salt Lake City firm.  This printer
has not reached the commercial market, so the driver will not be
of interest outside our local installation.

 \subsection{\protect\FN{dviimp.c}}

 This driver for the \IMAGEN{} laser printer family was
produced by Lon Willett at Utah, starting from \FN{dvijep.c},
using the Stanford University \IMAGEN{} driver in \WEB{} as a
guide.  It has been working quite satisfactorily with both our
\IMAGEN{} \N{8/300} and \N{3320} printers on \TWENTY{} and \VAX{}
\VMS{}.  The major work left to do is the addition of support
for  \verb|\special| commands.

 \subsection{\protect\FN{dvijet.c}}

  The \HPLJ{} printer has taken the
low-cost page printer market by storm, and was claimed in one
trade magazine survey to be the largest selling printer of all
time.  Like the \ALW{} and the \IMAGEN{} \N{8/300}, and
several others on the market, it uses the 8 page/minute \CANON{}
print engine.  It appeared on the market in the late summer of
1984 at a list price of \$3495, and I got one in late November.
There is a built-in Courier font, and additional fonts are
provided by plug-in cartridges.  There is no downloadable font
capability, but fortunately, there is support for bitmap display,
so it is treated very much like a dot matrix printer by the
\FN{dvijet.c} \TeX{} driver.  It has only about 55 Kbytes of
raster memory, far less than the 900 Kbytes needed for the
printable portion of a standard American page.  Fortunately, it
is possible to request the printing of a bitmap at 300, 150, 100,
or 75 dots/inch, and the latter size is close to a full page.
Each bit is imaged as a square 1 to 4 dots on edge for these
resolutions.

  In the fall of 1985, the \N{LaserJet Plus} was announced
at a list price of \$3995 and the regular \N{LaserJet} was
reduced to \$3495.  The latter can be upgraded to the \N{Plus},
which has quite decent support for downloaded fonts
and larger bitmaps (but still limited---to 512 Kbytes).  In
late March, 1986, an \N{Enhanced LaserJet Plus}, the
\N{HP 2686d}, was announced.
It has a list price of \$4995 and
offers two 250-sheet paper trays and in-order output
stacking, but apparently still lacks sufficient memory for a
full page bitmap.

 This printer has been aggressively marketed, and universities
have seen discounts of 30\% or more.   It could well become the
most common \TeX{} output device.

 \subsection{\protect\FN{dvijep.c}}

  I was able to secure the loan of a \HPLJ{} \N{Plus}
printer in late March, 1986, for the development
of a DVI driver, and \CN{dvijep} is the result of that work.
I lost about a day's work fiddling with trying to get downloaded
characters to work, because of unclear documentation in the
reference manual, but apart from that, conversion of \CN{dvialw}
to \CN{dvijep} took less than a day.  \CN{dvialw} was chosen as
the starting point, rather than \CN{dvijet}, because it supports
downloadable characters, and the translation of \POSTSCRIPT{}
sequences required by \CN{dvialw}  to \N{HP} printer sequences
seemed straightforward.  Some of the improvements made in
\CN{dvijep} for output compression, including not outputting
unchanged rule sizes, and remembering the current string {\em y\/}
coordinate in a global variable for \CF{setstr}, have been
carried back into \CN{dvialw}.

  The printer language used to control the \N{Hewlett-Packard}
printers consists of escape sequences, most of which require a
three-character prefix, and a single upper-case letter
terminator, possibly separated by a digit string.  For example,
to move to a particular (x,y) coordinate position, one sends
something like
\begin{verbatim}
<ESC>p*1234X
<ESC>p*3214Y
\end{verbatim}
and to draw a solid-filled rule 200 dots wide by 50 dots high,
with its upper-left corner at the current point, one sends
\begin{verbatim}
<ESC>*c200A
<ESC>*c50B
<ESC>*c0P
\end{verbatim}
Characters outside of escape sequences are simply set in the
current font, so in these examples, the sequences would be run
together, for otherwise the newlines between them would
generate blank lines in the output.  Signed numbers can be
specified for coordinates to get relative moves, instead of
absolute moves.

Consecutive control sequences with common three-character
prefixes can be collapsed by omitting the prefix on all but the
first, and changing all but the last terminator to lower-case.
In addition, if a digit string is zero, it may be omitted
entirely.  Thus, the above examples can be reduced to
\begin{verbatim}
<ESC>p*1234x3214Y
\end{verbatim}
and
\begin{verbatim}
<ESC>*c200a50bP
\end{verbatim}
a savings of almost half.  \CN{dvijep} takes great care to use
these compact forms in order to decrease the output size, and the
reduction has proved quite significant.

To avoid scattering these control sequences throughout the
various \FN{.h} files, they are entirely encapsulated in
preprocessor macros defined at the beginning of \FN{dvijep.c}.
This proved valuable in making optimizations of them.

There is absolutely no error indication if a control sequence is
bad---it is simply discarded by the printer.  In the case of
downloaded fonts, this means that characters whose downloaded
description is incorrect, or garbled, will either be missing from
the output, or will appear, but in a different font.  This
features makes debugging at times frustrating, since the printer
cannot tell you what is wrong.  It would be nice to have a mode
wherein you could ask it to {\em print\/} error messages on the
output page.  Except for font downloading, most of the sequences
are simple, and cause little difficulty.

Communicating with the printer requires nothing more than obeying
its \CN{XON}/\CN{XOFF} flow-control protocol, so standard
operating system \CN{copy} commands usually suffice, and the pain
and suffering I went through with \CN{lw78} for the \ALW{} did
not have to be repeated.

Character raster descriptions are sent as 8-bit binary data, and
therefore require half the output volume that \POSTSCRIPT{}
needs.  With some large test DVI files, the \CN{dvijep} output is
about 30\% shorter than the \CN{dvialw} output, and timing tests
with 9600-baud communication show that the \N{LaserJet Plus}
will output \TeX{} at 3 to 3.5 pages per minute.  Once again, the
serial communication seems to be the limiting factor, and it may
be that with  19200 baud, or with the Centronix parallel
interface, it may be able to produce 6 or 7 per minute.  The
\CANON{} \N{LBP-CX} engine is capable of 8 pages per minute.

Only the dummy \CF{special} function is presently used in
\CN{dvijep}.  Support for  insertion of raster images should not
be difficult to add.  As with the regular \N{LaserJet}, images
can be displayed at 75, 100, 150, or 300 dots/inch, and the extra
memory of the \N{Plus}  permits a full page at 150 dots/inch,
or a 5-inch square at 300 dots/inch.

Besides having support for larger bitmaps and downloaded fonts,
the \N{Plus} adds one useful extension over the regular {\sc
laserjet}.  All coordinates can be specified in dots, as well as
the decipoints  used by the latter.  This makes it easy to
position characters precisely, without worrying about conversions
of units of 1/720 inch to ones of 1/300 inch.

The printer permits origin resetting, but only to positions on
the page, because  positive coordinates are required.
Experimenting with the output positioning showed that the
upper-left page corner was  actually at  (0.1in, -0.07in) on the
printer I have.  Consequently, two new preprocessor symbols,
\CN{XORIGIN} and \CN{YORIGIN}, have been introduced in
\CN{dvijep} which are used in \CF{dviinit} to bias the left and
top margin values specified by default, or by command-line options.

Some remarks about the downloaded font capability are in
order here.  The \N{Plus} identifies fonts by numbers in 0
\ldots 32767, and fonts may be defined in any order and with any
font numbers, provided that no more than 32 are resident in the
printer at one time, and further, that no more than 16 are
used on one page.  It is not at all obvious why this page
limitation should exist.  Code has been inserted in \CF{readfont}
to check for the possibility of more than 32 being defined; if
this happens, it issues a warning indicating that the current
page may be incomplete, and then deletes the last 16 and frees
their font space.  So far, this message has not been issued.  No
check is made to see if more than 16 fonts are in use on a single
page, but this would not be hard to add.  I am inclined to leave
the changes  until, and if, a problem arises from this limitation.

So far, only one document has been encountered locally which
reached this limit.  The printer then imaged some characters as
blanks, and used the wrong font for others.  The author decided
to accept the printer limitation, and revised his document to
reduce the number of fonts per page.

Fonts can be of two types---7-bit fonts, allowing characters 33
\ldots 127 to be downloaded, and 8-bit fonts, allowing characters
33 \ldots 127 and 160 \ldots 255 to be defined.  The latter
require double the internal storage.  The size limitation on the
characters is the same in both---255 dots high or wide; only the
number of characters is different.  \TeX{} fonts use all
characters in 0 \ldots 127,%
\footnote{\INDEX{footnotes}{footnotes}%
        The DVI file allows 0 \ldots 255.
}
so in order to keep the font mapping one-to-one, a macro
\CN{MAPCHAR} is defined which remaps \TeX{} characters in 0 \ldots
32 onto 160 \ldots 192, so that this peculiarity is hidden from
the code in \CF{loadchar}, \CF{setchar}, and \CF{setstr}.

The descriptions of the {\em Create Font\/} command in the {\em
Hewlett-Packard  LaserJet Printer Technical Reference Manual\/}
caused me considerably confusion and the loss of time noted
earlier.  The discussion and examples are oriented toward using
the command to link cartridge-resident fonts with a user-defined numbered
font, and the command has fields for {\em font type\/}, {\em symbol
set\/}, {\em pitch\/},  {\em style\/}, {\em stroke weight\/}, and {\em
typeface\/}, which are attributes settable with other printer
commands which the \N{LaserJet} somehow (i.e. completely
non-intuitively) relates to particular fonts.  This is the only
way fonts can be selected on the regular \N{LaserJet}, and it
has previously cost me a good deal of frustration, since it is
impossible to just tell it ``give me 10pt Courier bold''.  When
my tests at downloading a simple character failed, I assumed that
the problem was with the values I had chosen for all of these
attributes, and I spent  several hours experimenting with them,
each time getting blank output pages.

The problem turned out to be none of these parameters, and their
values are apparently arbitrary when one is downloading character
descriptions.   The {\em Create Font\/} command has four 16-bit fields
called {\em cell width\/}, {\em cell height\/}, {\em baseline
position\/}, and {\em font height\/}.  Since the {\em Download
Character\/} command defines its own character metrics, I had
arbitrarily given these fields zero values.  Later  experiments
with these revealed that {\em font height\/} is arbitrary, but the
other three must be defined large enough to encompass the
biggest enclosing box of any downloaded character.  Downloaded   characters
with smaller metrics will print, but the larger ones are just
discarded without error indication.  The solution therefore was
to have \CF{readfont} compute the requisite values for these from
the metrics it retrieves from the font file, and output these in
the {\em Create Font\/} command.  I presume that the {\em cell height\/}
and {\em cell width\/} parameters are used by the \N{Plus} for
internal memory allocation, although there is no reason why it
could not do this on receipt of the sizes specified in the {\em
Download Character\/} commands.  With sophisticated fonts used in
typesetting, there is no reason whatever to assume any
commonality of character sizes within a font, and neither is
there any reason to store more than just the minimal bitmap for
each character.

The {\em Download Character\/} instruction contains some fixed
magic bytes, followed by {\em left offset\/}, {\em top offset\/},
{\em character width\/}, {\em character height\/}, {\em delta x\/}, and
finally the binary character bitmap as a byte stream, each raster
line being rounded up to the next higher byte boundary.  The {\em
left offset\/} is the distance from the character reference point
(the same one \TeX{} calls the character position) to the
leftmost edge of the character bitmap; this is just the negative
of the \CN{xoffp} parameter in the \TeX{} font file.  The {\em
top offset\/} is the distance from the reference point to the top
of the character pattern, and is identical to the \CN{yoffp}
parameter in the font file.  Although both of these are specified
as 16-bit numbers in the {\em Download Character\/} instruction,
they are apparently stored internally as one-byte signed values,
because they are restricted to the range -128 \ldots 127.
\CF{loadchar} enforces these limits when it issues the download
sequence, and \CF{readfont} prints a warning message when it
finds any character which violates this restriction.  Eventually,
such characters should be sent as an ordinary raster image
instead.  The {\em delta x\/} value is four times the (possibly
fractional) dot spacing to the next character reference point,
and therefore is equivalent, except for scale and precision, to
the \TeX{} \CN{tfm} character width.  At present, no advantage is
taken in \CF{setstr} of the higher precision of this spacing
parameter; when \CF{fixpos} changes the horizontal position, a
new string is started.

 The \N{LaserJet} supports landscape page orientation as well
as portrait orientation, but unlike \POSTSCRIPT{} which requires
only a very simple transformation matrix to get landscape mode,
on the \N{Plus}, font definitions must be completely changed,
and raster images (including character bitmaps) sent with
vertical rasters, since these will be parallel to the engine
scanning direction.  This is a considerable inconvenience, with
all the complications and host overhead noted earlier in the section
on \CF{makechar}, so \CN{dvijet} does not yet offer this option.

  A final remark should be made here about the compactness of the
output file.  The {\em Create Font\/} and {\em Download Character\/}
commands are encoded about as compactly as could be expected,
although support for \X{run-length encoding} of raster images would
be valuable.   Once most of the required characters have been
downloaded in the early pages of the document, the remainder of
the file looks something like the following, taken from an actual
test file:
\begin{verbatim}
<ESC>*p323x1584Yplicit             <--new line
<ESC>*p434Xexcitation
<ESC>*p631Xof
<ESC>*p683Xeac
<ESC>*p740Xh
<ESC>*p782Xquasi-normal
<ESC>*p1035Xmo
<ESC>*p1092Xde.
<ESC>*p1178XP
<ESC>*p1206Xo
<ESC>*p1226Xw
<ESC>*p1255Xer-la
<ESC>*p1335Xw
<ESC>*p1382Xtails
<ESC>*p1477Xpro
<ESC>*p1538Xduced
<ESC>*p1663Xb
<ESC>*p1686Xy
<ESC>*p1725Xthe
<ESC>*p1802Xv
<ESC>*p1823Xarious
<ESC>*p1949Xsources
<ESC>*p323x1634Yare                <--new line
<ESC>*p394Xdiscussed.
<ESC>*p596XIn
<ESC>*p649Xparticular,
\end{verbatim}
Newlines have been inserted after each escape sequence to make
them readable.  Otherwise, the entire output file is one single
stream of 8-bit bytes.  Note that at the beginning of each new
line, marked by the arrows in the example, there is a {\em y\/}
coordinate specified, but for the remainder of the line, only
{\em x\/} coordinates are given.  When words are broken, it is
usually an indication that \CF{fixpos} found a position
discrepancy, so \CF{setstr} began a new output string.  It is
evident that in these cases, and between words, there is a
typical overhead of eight extra characters.  In fact, for this
example, there are 314 total characters, of which 208 are in
escape sequences, and the other 106 are to be displayed on the
typeset page.  This means that about $2/3$ of the file consists
of overhead characters, and if this proportion could be reduced,
the total savings, and speed-up in printing, would be
substantial.

  Some repositioning is of course necessary at the start of each
word, and using relative coordinates would reduce each sequence
by one character, giving 16 fewer characters in this 16-word
example, which is not a large saving.

  It would therefore appear valuable to define some of the
currently unused font positions 193 \ldots 255 in each font as
spaces of various sizes, then output the minimal number of these
to obtain the required spacing.  Since the interword spacing
required is rarely more than 50 dots, or 200 quarter dots in the
units defined for the {\em delta x\/} character parameter, if ten
space characters of widths of 1, 2, 4, \ldots, 1024 quarter dots
were defined, then by simple bit shifting of the required
horizontal space value, we could output the required space with
probably an average of three, instead of the eight characters in
the above example.  Care will of course have to be given to
getting this precisely correct, because the danger of relative
spacing is always that the small errors can accumulate to large
ones, while using absolute coordinates for each word will repair
small errors made in individual character positions.
\SUBINDEX{to-do list}{to-do list}{fonts for small space characters}

 \subsection{\protect\FN{dvil75.c}}

 This driver is for the \N{DEC LA75}
dot matrix printer in
144-dot/inch mode.  It was contributed by John Sauter, and has
not been tested locally.

 \subsection{\protect\FN{dvim72.c}}

  This driver is for the \N{Apple ImageWriter} dot matrix
printer in 72-dot/inch mode.  This printer has the same command
set as the popular \N{Epson} printers, so the driver should work
with both.  Because these are low-cost printers, paper
registration is poor, and high quality cannot be expected.  Each
pass of the print head may lay down 8 raster lines, but when
the next group of 8 is printed after scrolling the paper, a
thin white space is commonly seen.  Expect times of 2 to 6
minutes per page.

 \subsection{\protect\FN{dvimac.c}}

  This driver is for the \N{Apple ImageWriter} dot matrix
printer in 144-dot/inch mode.  Except for code changes to double
the printer bitmap size and to support the encoding of the higher
resolution, it is identical to \CN{dvim72}.  The higher
resolution is achieved by encoding a 16-bit raster column
into two 8-bit bytes, odd rows into the first byte, and even
into the second.  All odd bytes are then sent to the printer and
printed, the carriage scrolls the paper up one dot, and then the
even bytes are sent and printed.  This suffers from even worse
registration problems than the 72-dot/inch mode, and since it
requires four times the data volume, it  is hardly worthwhile.
It may prove to be of better quality with the
\N{ImageWriter Plus}, but I have not tried it.

 \subsection{\protect\FN{dvimpi.c}}

  \CN{dvimpi} is the DVI translator for the portable
\N{MPI Sprinter} dot matrix printer, which was made here in Salt Lake
City.  Despite considerable popularity, low cost, and
typewriter-like portability of the \N{Sprinter}, \N{MPI} went
out of business in late 1985.

  The driver can be compiled for either 72- or 144-dot/inch
printing, according to the preprocessor variable \CN{HIRES} in
\FN{dvimpi.c}.  The bitmap encoding is a 6-bit column per
character, and in 144-dot/inch mode, printing takes four passes
with intervening half-dot right and down motions.

  The \N{Sprinter} has no reset command, so it is not possible
to restore it to a guaranteed state on completion.

 \subsection{\protect\FN{dvio72.c}}

  \CN{dvio72} is for the
\N{Okidata Pacemark 2410}
dot matrix printer at 72 dots/inch.  Along with the more
expensive \N{Printronix} printers, this is one of the sturdiest dot
matrix printers on the market, and has been quite popular as a
replacement for 200 to 600 line/minute band and drum printers.

  The bitmap encoding puts a 7-bit column into an 8-bit
byte, but no bias is applied, so all 128 ASCII byte values are
possible graphics data.  This poses a problem discussed in the
next paragraph, and necessitates a second pass by function
\CF{outline} through the encoded bitmap data before it can be
output.  There is some problem in getting the print head to
return to the same left margin position after each pass of the
heads across the page, so the driver sends several
carriage-return characters at the end of each line.

The printer has a serious design flaw in that it lacks a
command to reset to power-on state.  This is serious,
because it uses \CN{ETX} to enter graphics mode, \CN{ETX}
\CN{STX} to exit graphics mode, and \CN{ETX} \CN{ETX} to
mean \CN{ETX} as graphics data.  This means that a single
\CN{ETX} sent from the host may cause it to enter graphics
mode, or generate an error if it is already in graphics
mode.  Similarly, an \CN{ETX} \CN{STX} will enter graphics
mode if it is not already in it, instead of exiting graphics
mode.  We therefore turn on graphics mode for each line,
then turn it off again.  That way, there may be some remote
hope of resynchronizing if we lose an \CN{ETX} due to line
errors along the way.

From an efficiency
\INDEX{efficiency}{efficiency}
standpoint, it is regrettable that it has no
\X{run-length encoding} of graphics data.  The output quality and
speed are otherwise quite reasonable as medium-cost dot matrix
printers go.

 \subsection{\protect\FN{dvioki.c}}

\CN{dvioki} supports the
\N{Okidata Pacemark 2410} in
144-dot/inch mode, but is otherwise very similar to \CN{dvio72}.
This printer does not require awkward encoding of raster lines
for high-resolution mode
like the \N{Apple ImageWriter} and \N{MPI Sprinter} do, and
printing is not done by half-line overlap, so the quality is
higher.  The printer takes care of whatever bit rearrangements
are necessary; the bitmap is just four times as big.

 \subsection{\protect\FN{dviprx.c}}

  \CN{dviprx} is the second member of this family, and has formed
the basis for all the other dot matrix printer development.  The
\N{Printronix} printer family is one of the sturdiest on the market.
It has been emulated by \N{C-Itoh}, and remarketed by many computer
manufacturers under their own names.  It has been on the market
for at least ten years, and one outside my door has been in
regular use since 1978.  List price, depending on
speeds of 200 to 600 lines/minute, ranges from \$3000 to \$7000.

   Almost all the other dot matrix printers on the market have a
moving head of vertically-aligned pins which impact the ribbon to
print a dot.  One firing of all the pins in the head prints one
column of dots, and this operation must be repeated from 72 to
180 times per inch, depending on the printer resolution,  with
incremental head movement each time.  Uniform print registration on
successive passes is directly related to the cost of the printer,
and most of the low-cost ones do a poor job.

  The \N{Printronix} mechanism has a shuttle of 44 horizontal
hammer banks (in the 600 model; the number is model-dependent).
Oscillation of the shuttle carries each
hammer bank across only 3 character positions to obtain
standard 132 character/line printing, with a resolution of
60 dots/inch.  In graphics mode, one line of data bytes with
6 data bits per character, biased by 64, produces one
raster line.  The paper then moves up 1/72 inch, and the
next raster line is printed.  Since much less mechanical
movement is involved, speed and print quality are much
better than with the other types of printers.  The primary
complaint is that it results in a non-unit aspect ratio of
$60/72 = 5/6$ which \TeX{} users must put up with.  I have
not felt it worthwhile to ask \MF{} to generate special
fonts to compensate for this.  As noted earlier in the
section on \CF{prtbmap}, the bit encoding is backwards,
so a table-lookup translation of each output byte is
necessary.

  A modification of the \N{Printronix} mechanism for 100-dot/inch
printing with unit aspect ratio was licensed by \N{Trilog} and
marketed.  One model could support color printing with a special
multicolor ribbon, using three complete passes over the page.
Unfortunately, the higher resolution came with a considerably
higher price and speed of under 200 lines/minute, so I do not
believe this was a great market success.

 \subsection{\protect\FN{dvitos.c}}

  Several Japanese printer companies, including Toshiba,
NEC, Fujitsu, and Epson, and one American company, AMT, have
developed 24-pin dot matrix printers capable of 180-dot/inch
printing.  The impetus for this came from the need to
support the Japanese Kanji, Katakana, and Hierogana symbol
\INDEX{Hierogana characters}{Hierogana characters}
\INDEX{Japanese characters}{Japanese characters}
\INDEX{Kanji characters}{Kanji characters}
\INDEX{Katakana characters}{Katakana characters}
sets.  The JISCII (Japanese Industrial Standard Code for
Information Interchange)
\INDEX{JISCII character set}{JISCII character set}
character set is based on a 128 by
128 character matrix, containing ISO/ASCII in the first row,
\X{Greek} and \X{Cyrillic} in the next rows, and about 6000
characters divided into two levels according to frequency of
use in the remaining rows.  Two ASCII characters then can
effectively represent one Japanese character.  These
characters can be quite complex, but the Japan Standards
Institute has developed a collection of about 10000
characters which can all be represented in a 24 by 24
matrix.  This size led to the pin configuration of these
high-resolution dot matrix printers.

  As a side effect, 180 dots/inch is a great improvement
over the resolution of most other dot matrix printers, and
produces print quality which is not far from that of
daisy-wheel printers, but at higher speed and with more
versatility.

  These printers hit the market in late 1983, with the {\sc
toshiba p-\small\sc1351} being one of the first.  At that
time, electrostatic printers were still expensive, and
printed on unpleasant paper, and laser printers cost
\$20,000 and up.  Although the existence of a new low-cost
print engine with a disposable drum cartridge from \CANON{} was
rumored, there was nothing else on the market of comparable
resolution, so I bought a
\N{P-1351} about February 1984 for \$1950 (after academic discount).

  The \HPLJ{} was announced only three
months later, and I was able to get one delivered in late
November.  It appeared then that the superior speed (8
pages/minute versus perhaps a half-page/minute), print quality,
and quietness of the laser printer would be attractive, and
despite a cost of at least \$1500 more, the business community at
least might buy it.  The enormous market success of low-cost
laser printers has proven this view correct, and the 24-pin
printers clearly have an extremely limited market life.

  Nevertheless, if you happen to own a
\N{Toshiba P-1351},
\CN{dvitos} will produce \TeX{} output on it for you.

  The initial comments in \FN{dvitos.c} give some
performance statistics.  At 180 dots/inch, a reasonable size
page requires over 200 Kbytes for the bitmap.  The
\N{P-1351} supports \X{run-length encoding} which can
reduce the output volume somewhat, but in practice, it runs
2 to 3 times slower, and produces terrible print
quality due to inaccurate positioning of the print head
during horizontal skips.  I do not know whether this is a
mechanical problem with my particular printer, or
symptomatic of all Toshiba printers in this class.

    The bitmap encoding puts a 24-bit column into 6 bits each of
4 successive bytes, biased by 64.  About 120 lines of code are
required in   \CF{prtbmap} to handle this.  The printer has
the additional restriction that in any two adjacent bit columns,
no two horizontally-adjacent bits can be set.   Rather than deal
with this complication during the encoding, \CF{prtbmap}
ignores
the rule and hands each byte stream representing 24 raster
lines off to \CF{outline}, which makes a second pass through it,
turning off adjacent bits, before sending it to the output file.

Run-length encoding
\INDEX{run-length encoding}{run-length encoding}
is selectable by a run-time  option, and is
handled by \CF{outline} in a further 55 lines of code.  The
printer supports only encoding of successive whitespace, and
since at least 12 consecutive 24-dot columns must be white
for the encoding to save space, the chances of this happening are
not large.  Horizontal raster line encoding of both blank and white
would do much better.   The space reduction on two test files
was less than 30\%, with  print times of 1 to 6 minutes
per page.

At hardly double the cost, laser printers give much higher
quality, silent printing, up to 40 times the speed, and twice the
resolution, so these dot-matrix printers do not fare well as
\TeX{} output devices.

\section{Setting up the Environment}

Someone setting up \TeX{} for the first time is likely to find it
difficult to get an overview of just how things should be set up.
A \TeX{} distribution tape is likely to fill about 30Mb of disk
space with thousands of files in dozens of directories, and in
order for the software to work properly and find its way around
the file system, some naming conventions
are necessary.  To illustrate this,  the layout we use
on  the \IBMPC{} ,   \TOPS{}, and \VAX{} \VMS{},
is sketched in the next three subsections.

\subsection{\protect\IBMPC{} Setup}

On my \IBMPC{}, I maintain \TeX{} and the DVI driver family on
two dismountable 10Mb Bernouilli disk cartridges.  For
Personal \TeX{}'s PC{}\TeX{}, the directory layout looks as
follows:
\begin{verbatim}
D:\PCTEX              ! TeX.EXE, LaTeX.EXE, et al
D:\PCTEX\TEXFMTS      ! TeX .FMT files
D:\PCTEX\TEXTFMS      ! TeX .TFM files
D:\PCTEX\TEXINPUT     ! TeX input files
\end{verbatim}
For Micro{}\TeX{}, the structure is similar, and I chose to store
the font files in its directory tree:
\begin{verbatim}
D:\TEX                ! TeX.EXE, LaTeX.EXE, et al
D:\TEX\INPUTS         ! TeX input files
D:\TEX\FONTS\180      ! *.pk font files
D:\TEX\FONTS\240      ! *.pk font files
...
D:\TEX\FONTS\1548     ! *.pk font files
\end{verbatim}
The DVI family files reside in the directories
\begin{verbatim}
D:\DVI
D:\DVI\DOC
\end{verbatim}
The environment variables required by the DVI family are the ones
chosen by default in \FN{machdefs.h}.  They could be set in a
startup file (typically \FN{AUTOEXEC.BAT}):
\begin{verbatim}
set FONTPATH  d:\tex\fonts\
set PATH      c:\bin;d:\dvi;d:\pctex
set SUBPATH   d:\tex\inputs\
set TEXFONTS  d:\tex\fonts\
set TEXINPUTS d:\tex\inputs\
\end{verbatim}
The \PCDOS{} \CN{PATH} variable should include all the directories
that contain executable programs you require.  Although you can
copy programs into a common directory, I find it preferable to
keep them in the directories where they originate, and just have
a long \CN{PATH} search list.

If you use \CN{dvialw}, its macro file, \FN{dvialw.ps}, should be
copied into the directory defined by the \CN{TEXINPUTS} variable.

\subsection{\protect\TOPS{} Setup}

The main \TeX{} directory structure is identical to that
maintained by the Stanford \TeX{} Project, but we have numerous
additional local directories.

In \FN{SYSTEM:n-m-CONFIG.CMD} (where system-wide \X{logical name}s
are conventionally defined, and \FN{n} and \FN{m} are major and
minor Monitor release numbers), we have

 \begin{footnotesize}
\begin{verbatim}
define DVISPOOL:   tex:nospool.exe         !Dummy .DVI file spooler

define TEX:        aps:<tex>               ! *.EXE files for TeX,
                                           ! TeXware and DVI drivers
define TEXFORMATS: aps:<tex.formats>       ! TeX and LaTeX *.FMT files

define TEXFONTS:   aps:<tex.cm>,-          ! CM fonts in .TFM and .PK form
                   scrtch:<tex.pxl>,-      ! AM fonts in .PXL form
                   scrtch:<tex.fonts>      ! AM*.TFM files

define TEXINPUTS:  aps:<tex.inputs>,-
                   aps:<tex.latex>,-
                   aps:<tex.amstex>

define TEXSPOOL:   tex:nospool.exe         !Dummy .DVI file spooler
\end{verbatim}
 \end{footnotesize}

Users can individually redefine \FN{TEXSPOOL:} to be
\FN{TEX:\-DVIxxx.\-EXE} for their preferred DVI file translator, and
\FN{DVISPOOL:} to be \FN{TEX:\-IMSPOOL.\-EXE} (\IMAGEN{}) or
\FN{TEX:\-PSSPOOL.EXE} (\POSTSCRIPT{}).

Both laser printers are driven by spooler jobs running under
\CN{SYSJOB} (started by \CN{@DO OPR:--START-IM-SPOOL} and \CN{@DO
OPR:--START-PS-SPOOL}); these use PCL command procedures to poll
the spooler directory contents, print any files found there, and
then sleep awhile.  This approach is considerably simpler
than modifying \CN{LPTSPL}, although is does have a certain
amount of polling overhead which can be reduced by making the
sleep time longer.  We have not found it objectionable in many
months of use.

Here is what the main part of our \TeX{} directory structure
looks like:
\begin{verbatim}
APS:<TEX>
APS:<TEX.AMSFONTS>
APS:<TEX.AMSTEX>
APS:<TEX.BIBTEX>
APS:<TEX.CM>
APS:<TEX.DVI>
APS:<TEX.DVI.DOC>
APS:<TEX.FORMATS>
APS:<TEX.INPUTS>
APS:<TEX.LATEX>
APS:<TEX.LATEX.LOCAL-GUIDE>
APS:<TEX.MF>
APS:<TEX.PUB>
APS:<TEX.WEB>
SCRTCH:<TEX.CM>
SCRTCH:<TEX.DOC>
SCRTCH:<TEX.FONTS>
SCRTCH:<TEX.MF>
SCRTCH:<TEX.PXL>
SCRTCH:<TEX.PXLHEX>
SCRTCH:<TEX.WEB>
\end{verbatim}

\subsection{\protect\VMS{} Setup}

Our \VAX{} \VMS{} directory structure follows the Kellerman and
Smith distribution, again with additional directories.
\INDEX{Kellerman, David}{Kellerman, David}
\INDEX{Smith, Barry}{Smith, Barry}

The DVI driver family needs to have foreign command symbols
created for each \FN{.exe} file.  For example, you might put
lines like this
\begin{verbatim}
$ DVIALW :== $SYS$TEX:[TEX]DVIALW.EXE
\end{verbatim}
in a command file referenced in \FNNX{SYS\$MANAGER:SYLOGIN.COM}.
\INDEX{SYS$MANAGER:SYLOGIN.COM}{\FNNX{SYS\$MANAGER:SYLOGIN.COM}}

Here is a display of the important command files, a directory
tree, and the contents of two of the font directories.

\begin{footnotesize}
\begin{verbatim}
type lib:[tex]define.com

$ ! SYS$LIBROOT:[TEX]DEFINE.COM, Thu Dec 18 11:03:33 1986, Edit by BEEBE (at VAX
-VMS)
$ ! Make define/system after installation complete
$ defsys :== define/nolog/system
$
$ ! New version on PS:
$ defsys sys$tex        sys$libroot:
$
$ ! Put [.amstex] and [.latex] first to override old stuff in [.inputs]
$ defsys tex_inputs     sys$tex:[tex.latex], -
                        sys$tex:[tex.amstex], -
                        sys$tex:[tex.inputs]
$ defsys tex_fonts      sys$tex:[tex.cm]
$ defsys tex_formats    sys$tex:[tex.formats]
$ defsys tex_output     texput

type lib:[imprint]*.com

SYS$LIBROOT:[IMPRINT]INSTALL.COM;6

$ !=====================================================================
$ ! Install IMPRINT spooler on system (do only once)
$ !=====================================================================
$ define imp sys$libroot:[imprint]
$ set command   /tables=sys$library:dcltables -
                /output=sys$library:dcltables -
                imp:imprint.cld
$ set process/privilege=cmkrnl
$ library/replace/help sys$help:helplib imp:imprint.hlp
$ run sys$system:install
sys$library:dcltables/replace
/exit
$ define/system imp_formats     sys$libroot:[imprint]
$ define/system imp_fonts       sys$libroot:[imprint.fonts]

SYS$LIBROOT:[IMPRINT]SHUTIMAGEN.COM;2

$ !=====================================================================
$ ! Shutdown the Imagen 8/300 queue
$ !=====================================================================
$ set noon
$ stop /next /queue sys$imagen
$ delete/queue sys$imagen
$ set device /nospooled sys$imagen

SYS$LIBROOT:[IMPRINT]STARTIMAGEN.COM;6

$ !=====================================================================
$ ! Start IMPRINT spooler
$ !=====================================================================
$ define/system sys$imagen      txa0:
$ define/system imp_formats     sys$libroot:[imprint]
$ define/system imp_fonts       sys$libroot:[imprint.fonts]
$ reply/enable=printer
$ set term sys$imagen -
        /permanent -
        /nowrap -
        /speed=19200
$ set device/spooled sys$imagen
$ initialize /queue -
        /term -
        /proc=imprint -
        /default=(feed,flag) -
        /start -
        sys$imagen


$ cd lib:[imprint]
$ @mgr:dirtree
Output File: tt:

   Your Directory Structure.     One moment please...

        IMPRINT
                ^-----FONTS
                        ^-----1200
                        ^-----1440

$ cd lib:[tex]
$ @mgr:dirtree
Output File: tt:

   Your Directory Structure.     One moment please...

        TEX
                ^-----AM
                        ^-----1000
                        ^-----1095
                        ^-----1200
                        ^-----1315
                        ^-----1440
                        ^-----1500
                        ^-----1643
                        ^-----1728
                        ^-----1800
                        ^-----2074
                        ^-----2160
                        ^-----2400
                        ^-----2488
                        ^-----2592
                        ^-----2628
                        ^-----2880
                        ^-----2986
                        ^-----3110
                        ^-----3456
                        ^-----3732
                        ^-----4479
                ^-----AMSTEX
                ^-----BIBTEX
                ^-----CM
                        ^-----100
                        ^-----1075
                        ^-----121
                        ^-----1290
                        ^-----145
                        ^-----1548
                        ^-----174
                        ^-----208
                        ^-----240
                        ^-----250
                        ^-----274
                        ^-----300
                        ^-----329
                        ^-----360
                        ^-----432
                        ^-----518
                        ^-----622
                        ^-----746
                        ^-----896
                ^-----DOC
                ^-----FORMATS
                ^-----HP
                ^-----INPUTS
                ^-----LATEX
                        ^-----LTXGDE
                        ^-----ROCHESTER
                ^-----SVI
                ^-----TEX
                ^-----TEXWARE
                ^-----TRIP
                ^-----WEB

$ dir tex_fonts

Directory SYS$LIBROOT:[TEX.CM]

00HEXBIN.COM;3      00HEXCHK.COM;2      00RENAME.COM;2      00TEST.COM;2
100.DIR;1           1075.DIR;1          121.DIR;1           1290.DIR;1
145.DIR;1           1548.DIR;1          174.DIR;1           208.DIR;1
240.DIR;1           250.DIR;1           274.DIR;1           300.DIR;1
329.DIR;1           360.DIR;1           432.DIR;1           518.DIR;1
622.DIR;1           746.DIR;1           896.DIR;1           AMR10.TFM;1
CIRCLE10.TFM;1      CIRCLEW10.TFM;1     CMB10.TFM;1         CMBSY10.TFM;1
CMBX10.TFM;1        CMBX12.TFM;1        CMBX5.TFM;1         CMBX6.TFM;1
CMBX7.TFM;1         CMBX8.TFM;1         CMBX9.TFM;1         CMBXSL10.TFM;1
CMBXTI10.TFM;1      CMCSC10.TFM;1       CMDUNH10.TFM;1      CMDUNH10.TFMHEX;1
CMEX10.TFM;1        CMFF10.TFM;1        CMFIB8.TFM;1        CMINCH.TFM;1
CMMI10.TFM;1        CMMI12.TFM;1        CMMI5.TFM;1         CMMI6.TFM;1
CMMI7.TFM;1         CMMI8.TFM;1         CMMI9.TFM;1         CMMIB10.TFM;1
CMR10.TFM;1         CMR12.TFM;1         CMR17.TFM;1         CMR5.TFM;1
CMR6.TFM;1          CMR7.TFM;1          CMR8.TFM;1          CMR9.TFM;1
CMSL10.TFM;1        CMSL12.TFM;1        CMSL8.TFM;1         CMSL9.TFM;1
CMSLTT10.TFM;1      CMSS10.TFM;1        CMSS12.TFM;1        CMSS17.TFM;1
CMSS8.TFM;1         CMSS9.TFM;1         CMSSBX10.TFM;1      CMSSDC10.TFM;1
CMSSI10.TFM;1       CMSSI12.TFM;1       CMSSI17.TFM;1       CMSSI8.TFM;1
CMSSI9.TFM;1        CMSSQ8.TFM;1        CMSSQI8.TFM;1       CMSY10.TFM;1
CMSY5.TFM;1         CMSY6.TFM;1         CMSY7.TFM;1         CMSY8.TFM;1
CMSY9.TFM;1         CMTCSC10.TFM;1      CMTEX10.TFM;1       CMTEX8.TFM;1
CMTEX9.TFM;1        CMTI10.TFM;1        CMTI12.TFM;1        CMTI7.TFM;1
CMTI8.TFM;1         CMTI9.TFM;1         CMTT10.TFM;1        CMTT12.TFM;1
CMTT8.TFM;1         CMTT9.TFM;1         CMU10.TFM;1         CMVTT10.TFM;1
DOC.TFM;1           DUMMY.TFM;1         FONTTEST.COM;2      FONTTEST.LOG;1
FONTTEST.TEX;1      ICMEX10.TFM;1       ICMMI8.TFM;1        ICMSY8.TFM;1
ICMTT8.TFM;1        ILASY8.TFM;1        ILCMSS8.TFM;1       ILCMSSB8.TFM;1
ILCMSSI8.TFM;1      LASY10.TFM;1        LASY5.TFM;1         LASY6.TFM;1
LASY7.TFM;1         LASY8.TFM;1         LASY9.TFM;1         LASYB10.TFM;1
LCMSS8.TFM;1        LCMSSB8.TFM;2       LCMSSI8.TFM;1       LINE10.TFM;1
LINEW10.TFM;1       LOGO10.TFM;1        LOGO8.TFM;1         LOGO9.TFM;1
LOGOBF10.TFM;1      LOGOSL10.TFM;1      MANFNT.TFM;1        TESTFONT.COM;11
TESTFONT.LIS;1

Total of 133 files.

$ dir sys$tex:[tex.cm.300]

Directory SYS$LIBROOT:[TEX.CM.300]

CIRCLE10.PK;2       CIRCLEW10.PK;2      CMB10.PK;2          CMBSY10.PK;2
CMBX10.PK;4         CMBX12.PK;2         CMBX5.PK;2          CMBX6.PK;2
CMBX7.PK;2          CMBX8.PK;2          CMBX9.PK;2          CMBXSL10.PK;2
CMBXTI10.PK;2       CMCSC10.PK;2        CMDUNH10.PK;2       CMEX10.PK;2
CMFF10.PK;2         CMFIB8.PK;2         CMINCH.PK;2         CMMI10.PK;2
CMMI12.PK;2         CMMI5.PK;2          CMMI6.PK;2          CMMI7.PK;2
CMMI8.PK;2          CMMI9.PK;2          CMMIB10.PK;2        CMR10.300GFHEX;1
CMR10.GF;1          CMR10.PK;3          CMR12.PK;2          CMR17.PK;2
CMR5.PK;2           CMR6.PK;2           CMR7.PK;2           CMR8.PK;2
CMR9.PK;2           CMSL10.PK;3         CMSL12.PK;2         CMSL8.PK;2
CMSL9.PK;2          CMSLTT10.PK;2       CMSS10.PK;2         CMSS12.PK;2
CMSS17.PK;2         CMSS8.PK;2          CMSS9.PK;2          CMSSBX10.PK;2
CMSSDC10.PK;2       CMSSI10.PK;2        CMSSI12.PK;2        CMSSI17.PK;2
CMSSI8.PK;2         CMSSI9.PK;2         CMSSQ8.PK;2         CMSSQI8.PK;2
CMSY10.PK;2         CMSY5.PK;2          CMSY6.PK;2          CMSY7.PK;2
CMSY8.PK;2          CMSY9.PK;2          CMTCSC10.PK;2       CMTEX10.PK;2
CMTEX8.PK;2         CMTEX9.PK;2         CMTI10.PK;2         CMTI12.PK;2
CMTI7.PK;2          CMTI8.PK;2          CMTI9.PK;2          CMTT10.PK;2
CMTT12.PK;2         CMTT8.PK;2          CMTT9.PK;2          CMU10.PK;2
CMVTT10.PK;2        LASY10.PK;2         LASY5.PK;4          LASY6.PK;2
LASY7.PK;2          LASY8.PK;2          LASY9.PK;2          LASYB10.PK;2
LINE10.PK;1         LINEW10.PK;1        LOGO10.PK;1         LOGO8.PK;1
LOGO9.PK;1          LOGOBF10.PK;1       LOGOSL10.PK;1       MANFNT.PK;1

Total of 92 files.
\end{verbatim}
\end{footnotesize}

\section{Building the Drivers}

With Version 2.07 of the DVI drivers, a public-domain
implementation of the \UNIX{} \CN{make} utility is included with
the distribution.  This version of \CN{make} runs on all the
operating systems currently supported for the DVI driver family,
plus some others.

In my view, \CN{make} ranks right next to compilers in importance.
\UNIX{} users should usually be introduced to it at an early
stage, but people unfamiliar with \UNIX{} may be unaware of it.

The essential idea behind \CN{make} is that a user should not have
to issue routine compile and link commands to build software, but
instead, should be able to describe in a \FN{makefile}
dependencies of files on other files, and rules for producing
one file from another file, or group of files.  For example,
an object files depends on its corresponding source file, since if
the source file is changed, the object file must be replaced by
one from a fresh source compilation.  The object file also
depends on all the header files included by the source file,
since if these are changed, recompilation is also in general
necessary.   However, a source file does {\em not\/} depend on its
included files, since if they are changed, no changes to the
source file are required.

Supplementing the file dependency lists in the \FN{makefile} are
a set of rules for converting one file type to another.  The
commoner ones are built-in to \CN{make} itself, but additional
ones (or replacements for built-in rules) can be provided in the
\FN{makefile}, both as defaults, and as specific rules to be used
for certain files.

By default, \CN{make} finds the first target file in the
\FN{makefile}, then executes all the necessary rules to bring it
up to date.  Thus, as Stu Feldman,
\INDEX{Feldman, Stu}{Feldman, Stu}
the author of the original \CN{make} says,
 \begin{quote}
It is usually easier to type the make command than to issue even
one of the needed operations, so the typical cycle of program
development operations becomes
 \begin{quote}
         think - edit - make - test  . . .
 \end{quote}
 \end{quote}
\FN{makefile}'s in general contain multiple targets, and one or
more of these can be selected by name when \CN{make}
is run.  This makes it possible to store the commands for making
all of the files in a given directory in a single file.  For
software stored in a directory tree, the \FN{makefile} at the top
level can run \CN{make} in each of its subdirectories, and these
in turn can run \CN{make} in their subdirectories, so a single
top-level \CN{make} command can build an entire software system,
like the complete \UNIX{} operating system.

\FN{makefile}'s have been prepared for each of the host computers
supported in the DVI family, and they are given filenames
\FN{makefile.xxx}, where \FN{xxx} is the host name.  You can just
copy the desired one into \FN{makefile}, and type \CN{make} to
build all of the drivers.

The leading comments in each \FN{makefile} list all the targets
that can be made by executing \CN{make}, and should be consulted
for details.

Here is the \FN{makefile} which typesets this document:

 \begin{footnotesize}
\begin{verbatim}
#-----------------------------------------------------------------------
# Usage:
#
#       make dviman
# or
#       make dvidriver
# or
#       make clean
#
# [17-Apr-87]
#-----------------------------------------------------------------------

LATEX = LaTeX \batchmode \input

CP = copy

.SUFFIXES:

.SUFFIXES:      .dvi .ltx .ids .idx

.idx.ids:
        $(CP) $*.idx $*.id
        texidx $*.id
        $(RM) $*.id.*

dviman: dviman.ltx
        $(LATEX) dviman.ltx

dvidriver:      dvidriver.ltx dvidriver.sty
        $(LATEX) dvidriver.ltx
        $(RM) dvidriver.dvi.*
        make dvidriver.ids
        $(LATEX) dvidriver.ltx
        make dvidriver.ids

dvidriver.ids:  dvidriver.idx

clean:
        $(RM) *.dvi*.*
        $(RM) *.lst.*
        $(RM) *.aux.*
\end{verbatim}
 \end{footnotesize}
The first \verb|.SUFFIXES| clears the default file suffix list, and
the second installs four suffixes in it.  The rule for converting
the output \FN{.idx} file from \LaTeX{} into the sorted input
\FN{.ids} file  is given following the line
beginning \verb|.idx.ids|.  It tells \CN{make} to copy the
\FN{.idx} file to one with extension \FN{.id},
run the indexing program, and then delete the temporary copy.
This rule is used when the target \verb|dvidriver.ids| is
needed, as happens when the rules for \verb|dvidriver| are
executed.

By default, \CN{make} will process the \FN{dviman.ltx} file, since that
target occurs first.  The string \verb|$(LATEX)| requests a macro
substitution of the symbol \verb|LATEX| which is defined earlier
to run \LaTeX{} in batch mode.

The \verb|clean| target is conventional in \FN{makefile}'s; it
contains commands to delete unnecessary files in the directory,
and is usually executed when work is completed.

\section{Programming Conventions}

\INDEX{programming conventions}{programming conventions}
  I am quite particular about readability and appearance of
computer programs, because I spend much of my time reading
and writing them.  The previous sections have mentioned
certain programming conventions, but it is useful to
summarize them here, in the hope that they may prove a guide
to implementors.  Some of these rules are designed to
facilitate code portability across compiler implementations
and operating systems.  They are usually not written down in
books, though {\em A C Reference Manual\/}, Prentice-Hall(1985),
by Samuel Harbison and Guy Steele, Jr., is a
valuable work which every serious \C{} programmer should
study and use.  A second edition
incorporating much of the proposed draft ANSI \C{} Standard
was published in early 1987,
 \begin{itemize}
   \item
         Compound statements begin and end  on separate lines,
         with opening and closing braces in the same column, and
         on their own lines.  This makes visual brace matching
         much easier than it is with the common practice of
         placing the opening brace at the end of a previous line.
   \item
         Indentation nesting increases 4 spaces for each level.
         Spaces and tabs may be used for indentation, and
         tabs fill up to the next column which is a multiple of
         8.
   \item
         Only one statement appears per line, with preprocessor
         macro definitions exempted from the rule, since a
         definition is required to fit on one line, even if
         it expands into several \C{} statements.
   \item
         Lines must never exceed 80 characters in length, in
         order that the software can be distributed as
         80-character line images on magnetic tape.  It is
         expected that software transported in this manner will
         be blank-trimmed on reading from the tape.  The standard
         \C{} backslash-newline sequence can be used to break a
         long line; continuation occurs in column 1 of the next
         line if a string constant has been broken, and otherwise
         4 characters right of the leftmost character of the first
         line of the continued statement.
   \item
         Type declarations should declare only one variable per
         statement, and that statement should have a brief
         comment describing the variable.
   \item
         Single statements controlled by a \C{} conditional,
         looping, or switch statement appear on separate lines, and
         are indented 4 characters
         to the right of the controlling statement.  Complicated
         statements in this context should be converted to
         brace-delimited compound statements to enhance readability.
   \item
         Preprocessor symbols  are entirely in upper-case
         letters.  Variables are entirely in lower-case letters.
   \item
         If definition of a macro for some code sequence
         simplifies it, do so.
   \item
         Labels and \CN{goto} statements are not to be used.
   \item
         Preprocessor \CNNX{\#if}\INDEX{#if}{\CNNX{\#if}}
         constant expressions should
         be avoided if possible.  If you require
         expressions, do not use the operators \verb=!=,
         \verb=||=, and \verb=&&=.  This rule is occasioned
         by a \LATTICE{} \C{} misfeature.
   \item
         The only \C{} preprocessor statements to be used are
         \CNNX{\#include}\INDEX{#include}{\CNNX{\#include}},
         \CNNX{\#define}\INDEX{#define}{\CNNX{\#define}},
         \CNNX{\#undef}\INDEX{#undef}{\CNNX{\#undef}},
         \CNNX{\#if}\INDEX{#if}{\CNNX{\#if}},
         \CNNX{\#else}\INDEX{#else}{\CNNX{\#else}},
         and
         \CNNX{\#endif}\INDEX{#endif}{\CNNX{\#endif}}.
         In particular, the useful, but commonly absent,
         \CNNX{\#elif}\INDEX{#elif}{\CNNX{\#elif}}
         may not be used, nor may
         \CNNX{\#if defined(var)}.
         \INDEX{#if defined(var)}{\CNNX{\#if defined(var)}}%
         \CNNX{\#ifdef}\INDEX{#ifdef}{\CNNX{\#ifdef}},
         \CNNX{\#ifndef}\INDEX{#ifndef}{\CNNX{\#ifndef}},
         and
         \CNNX{\#undef}\INDEX{#undef}{\CNNX{\#undef}}
         are discouraged.  In the driver family, they are restricted
         to \FN{machdefs.h} where they are used to eliminate
         compiler ``macro redefinition'' warning messages.    When
         \CNNX{\#undef}\INDEX{#undef}{\CNNX{\#undef}}
         is used, the programmer must be aware
         that this may not make the symbol undefined; only
         its most recent definition may disappear, with a
         previous definition now visible.  \LATTICE{} \C{} uses
         this scheme.  Fortunately, the draft ANSI \C{} Standard
         forbids this interpretation.
   \item
         Preprocessor statements must begin in column 1, and
         have no whitespace between the
         \CNNX{\#} and the
         following keyword.
   \item
         Tricks, like empty comments,  for preprocessor symbol
         concatenation are forbidden; until the ANSI \C{}
         Standard becomes a reality and is widely implemented,
         there is no way to do this on many implementations.
   \item
         Substitution of preprocessor
         \CNNX{\#define}\INDEX{#define}{\CNNX{\#define}}
         arguments in quoted strings is forbidden, and no
         \CNNX{\#define}
         argument name may appear as a character string inside a
         quoted string.
   \item
         Type casts must be used for all assignments where the
         data types of the left and right sides differ, and for
         function arguments which do not match formal parameters.
   \item
         Function values which are discarded must be cast as
         \CNNX{(void)},\INDEX{void}{\CNNX{void}}
         unless the function has already been
         declared that way.
   \item
         All functions should be declared before the \CF{main}
         function.
   \item
         All functions must be {\em explicitly\/} typed, with
         \CN{void} used for those which do not return a value.
   \item
         The \CF{main} function should be given first,
         followed by  function definitions in \X{alphabetical order}.
   \item
         Alphabetical ordering, with letter case ignored, should
         be adhered to in macro, variable, and function
         declarations, and in long sequences of independent
         assignment statements.
   \item
         Equivalence of pointers and integers must not be
         assumed; type casts must be employed on assignment.
   \item
         The standard \CN{NULL} pointer declared in \FN{stdio.h}
         should be cast to the requisite type and compared
         against, rather than assuming null pointers are zero.
         That is, write \CN{while (s != (char *)NULL)}, rather
         than \CN{while (s)}.
   \item
         Use preprocessor symbols instead of magic constants.
         \CN{if (c == ESC)} is more readable than \CN{if (c == 27)}.
   \item
        If a function returns a yes/no or true/false value,
        declare it as \CN{BOOLEAN} and use the symbols
        \CN{TRUE} and \CN{FALSE} instead of constants 1 and 0.
   \item
        Avoid the generic \CN{int} type when a more restricted
        type could be used instead, or when the result might
        require more than 16-bit precision.
    \item
        Follow the conventions for visible function headers
        used in the DVI driver family.
    \item
         \C{} has  at least 28 precedence levels in
         expressions, which is far too many for a programmer to
         remember accurately.  Use parentheses instead to say
         what you mean, and don't be afraid to use whitespace
         to improve readability.
    \item
         Use long variable names freely, but keep external
         symbols unique in their first {\em six\/} characters.  File
         names, variable names, and preprocessor variables
         should be unique in their first {\em eight\/} characters.
   \item
        Avoid features of \C{} which are not widely implemented.
         These include the \CN{enum} type (preprocessor constants
         can simulate this), and functions returning
         \CN{struct}'s (return pointers to \CN{struct}'s instead).
   \item
        Functions with variable numbers of arguments are {\em
        not\/} to be used.
   \item
        If you have to resort to machine-dependent coding, use
        the \C{} preprocessor to select it.
   \item
         When possible, use compiler options and tools like the
         \UNIX{} \CN{lint} program to help track down potential problems
         in code.
   \item
         Finally, use comments regularly to document what the
         code is doing.  A recent letter to the editor of the
         {\em Communications of the ACM\/} reported  that fewer than 5\%
         of the lines of code in the entire \UNIX{} system are
         commented!   \C{} is most definitely not a
         self-documenting language; in fact, Philippe Kahn, the
         developer of the fine Turbo Pascal system on the
         \IBMPC{}, calls \C{} a {\em write only\/} language.
 \end{itemize}

\section{Implementation Problems}

We have in several earlier sections remarked on problems
encountered with particular operating systems and compilers.
These are summarized in the following subsections.  After
insertion of included files by the \C{} Preprocessor, these
drivers each amount to between 6500 and 8000 lines of code.
Since this is contained in a single file, it tends to tax the
\IBMPC{} compilers severely.

\subsection{\protect\TOPS{}}

  Text files on \TOPS{} are stored as simple byte streams
as they are in \UNIX{}, except that \CN{CR} \CN{LF} terminates a
line, instead of just \CN{LF}.  The \C{} run-time library will
take care of translation between these two, but in order to be
able to suppress the translation to compress \POSTSCRIPT{}
output, which does not require the \CN{CR}, text files are opened
in binary mode, and the \CF{NEWLINE} preprocessor macro is used
to output the desired end-of-line sequence.

  ASCII is a 7-bit character set, and \TOPS{} normally stores
text files as five 7-bit characters in each 36-bit word, with the
rightmost (low-order) bit set to zero.  In order to obtain 8-bit
I/O, it is necessary to use \CF{open} instead of \CF{fopen}, so
this is encapsulated in the function \CF{f20open}.  The code
references this only through the preprocessor macro
\CN{BINARYOPEN}.  With a little more thought in the
implementation of the I/O library, it should have been possible
to extend the arguments to \CF{fopen} to achieve this, so that
\CN{stdin} and \CN{stdout} could be chosen to be 8-bit streams if
desired.  \KCC{} accepts an extended mode argument to \CF{fopen}
to obtain binary files of particular byte sizes, but it does not
permit binary I/O on the files \CN{stderr}, \CN{stdin}, and
\CN{stdout}.

  External names in \TOPS{} are normally limited to 6 upper-case
characters.  Although the linker supports long case-insensitive
external names, and both the \PASCAL{} and \N{Algol} compilers
use them, \PCC{} does not.  Consequently, \C{} programmers must
take care to avoid long external names which are not unique in
the first 6 characters, ignoring case.  Neither does \PCC{}
provide support for extended addressing in a 23-bit address
space, instead of an 18-bit address space, like \N{Fortran} and
\PASCAL{} do.  The compiler does not store function traceback
information, or generate a symbol table for local variables, nor
does it employ the linker argument type blocks which have proved
enormously useful in catching argument type and count mismatches
at link time with other languages.  This makes debugging tedious,
and I admit to having become fairly adapt at visually uncompiling
assembly code back into \C{} inside the \N{DDT} debugger.

  By default, the compiler splits the 18-bit address space into
two, half for code and half for data.  With the large bitmaps
required by some of the drivers, this provided insufficient space
for data, so I created some alternate library routines which
increase the data space to $3/4$ of the address space.

  \PCC{} does not permit members of different structures to be
given the same names; this was a minor annoyance in the
definition of the \CN{font_entry} and \CN{font_list} structures
which both contain the same object, but are forced to name it
differently.

  The ugliest piece of code occasioned by \PCC{}'s deficiencies
is the saving and restoring of the terminal state in functions
\CF{initterm} and \CF{rsetterm} in \FN{dvibit.c}.

The \CN{void} data type is not recognized by \PCC{}, but is so
useful that I simply inserted a statement \CN{typedef int void;}
in \FN{stdio.h}, making it available to everyone.

As noted in the section on \FN{loadchar.h},
the compiler did not correctly handle a function reference of the
type
\begin{verbatim}
    (void)(*fontptr->charxx)(c,outrow);
\end{verbatim}
It also generated incorrect code for functions returning a
\CN{struct}, but I was able to fix that problem in the compiler.
It does not apply to the DVI driver family, but the \UNIX{} {\sc
awk} utility makes heavy use of this feature.

The \C{} preprocessor had a  symbol table for only  1000
symbols,  which  is  much  too  low  for  a  file  the  size  of
\FN{monsym.h}, which defines all the symbols for operating
system calls.  For the DVI driver family, I merely selected a
subset of these and installed them in \FN{machdefs.h}.  However,
for convenience in other programs, I rebuilt the preprocessor
with a table size of 20000 to eliminate this problem.

The maximum \CN{switch} table size was increased from 250 to 513.
This makes it possible to compile \CN{switch} statements indexed
by 8-bit and 9-bit bytes.  This was essential to avoid ugly
workarounds in \FN{prtpage.h}.

Availability of the compiler and library source code has been
essential in overcoming some of these problems, and in tracking
down questionable behavior in the run-time library.

Adding support for \KCC{} was straightforward, and the compiler
has proved to be reliable, and the library quite close to \UNIX{}.
As of April, 1987, it does not implement the Berkeley terminal
handling facility provided by \CF{ioctl} and \CF{sgtty}.

The \TWENTY{} \X{JSYS interface} provided by \KCC{} is similar to
\PCC{}'s, but the symbol names are closer to the assembly
language definitions.  To reduce code duplication, one set of
symbols is defined explicitly in terms of the others.  Like
\PCC{}, a complete \FN{monsym.h} proved to have too many symbols
for \KCC{}, so for the DVI driver family, the needed values are
defined explicitly in \FN{machdefs.h}.  The \KCC{} developers
have since linked an extended addressing version of the compiler
which happily handles \FN{monsym.h}, and we now use that version
for systems programming.

One caveat for \KCC{} must be issued here.  It stores character
data as 9-bit values, and short integers as 18-bit values, both
accessed with \TWENTY{} byte instructions.  This produces compact
data, but the current hardware microcode implementation of these
instructions is slower than the fullword integer instructions, so
the drivers compiled with \KCC{} run considerably slower than
when compiled with \PCC{}, despite the generally superior code
generation of the former.  The well-known \CN{sieve} benchmark
is about 4 times slower with byte instructions than with
fullword integer instructions.

\subsection{\protect\UNIX{} \protect\N{4.1BSD}}

Like \PCC{}, \CN{cc} under \N{4.1BSD} \UNIX{} does not correctly
handle the case of function reference to a structure member.

Filenames are restricted to 14 characters in length, so output file
extensions are \FN{.xxx} instead of \FN{.dvi-xxx}.

Otherwise, the drivers compile without problems.
We found that after completion of execution, and production
of correct output, they die with a stack error in \CF{exit}.
Attempts to debug this with \CN{sdb} were unsuccessful, because
the debugger would step right into the stack error and crash.
When the drivers are run under control of the assembly-level
debugger, \CN{adb}, they complete normally!

In February, 1987, we traced this to a \N{4.1BSD} \UNIX{} system bug.
\CF{fclose} is called in \CF{abortrun} to close all font files,
and it turned out that whenever one of the files passed to
\CF{fclose} was already closed, the library would install a time
bomb which blew up the code at exit.  According to the manual
page for \CF{fclose}, no action should be taken if the file is
not already open.  \CF{abortrun} has been revised to avoid calls
to \CF{fclose} for such files, and the problem was been solved.

\subsection{\protect\HPUX{}}

No problems were encountered with \HPUX{} which is based on
\N{AT\&T System V} \UNIX{}, with \N{4.2BSD} extensions.  The version I
used ran on a \N{Hewlett-Packard 9000/350}
workstation.  File
names up to 1024 characters in length are supported, and up to 60
open files are permitted, so the only change was the addition of
a preprocessor symbol \CN{HPUX} in \FN{machdefs.h} to select code
defining the larger limits.

% Future section:
% SUN-OS (V.3) 1024 byte names, 30 open files

\subsection{\protect\IBMPC{} \protect\LATTICE{} C}

I have both versions 2.15a and 3.0 of the \LATTICE{} \C{}
compiler running under \PCDOS{}, and have used version 2.15a
extensively for graphics work.  The major problem with this
version is the limited overlap with the standard \UNIX{} run-time
library.  This has been largely remedied with version 3.0.
However, both versions have proved singularly incapable of producing
working versions of any of the drivers---the executable programs
die with errors.

Version 2.15a implements \CN{unsigned} as a type, meaning a
16-bit unsigned integer, rather than a type modifier.  The
original Kernighan
\INDEX{Kernighan, Brian}{Kernighan, Brian}
and Ritchie
\INDEX{Ritchie, Dennis}{Ritchie, Dennis}
definition is unclear, but the
ANSI \C{} standard committee has made it clear that it is a legal
modifier on any integer data type.  I expect that this would have
posed a problem in the drivers, particularly those parts which
twiddle bits in the character rasters and output bitmaps.  Type
\CN{void} is not recognized, either, but that can be solved with
a simple \CN{typedef} in \FN{typedefs.h}.

Version 3.0 raises a fatal error when
\CNNX{(void)}\INDEX{void}{\CNNX{void}} is used as a
typecast on a function previously declared to be of type
\CN{void}; it does not do so if \CN{void} is replaced by any
other data type.  This particular use occurs extensively
throughout the drivers, so I have shelved further work with this
version until \LATTICE{} fixes it.  One attractive feature of
version 3.0 is the addition of support for argument type checking
according to the prescription in the coming ANSI \C{} standard.

The \LATTICE{} compilers correctly handle large arrays, but in
the interests of \X{efficiency}, the driver code  selects a bitmap
implementation using a vector of raster pointers for all \IBMPC{}
compilers.

\subsection{\protect\IBMPC{} \protect\WIZARD{} C}

The \WIZARD{} \C{} compiler was attractive because of its
claim to a high degree of compatibility with the \UNIX{} run-time
library.

The \WIZARD{} compiler correctly handles large arrays, but in
the interests of \X{efficiency}, the driver code selects a bitmap
implementation using a vector of raster pointers for all \IBMPC{}
compilers.

Unfortunately, it has been unable to compile any of the drivers
without getting internal table overflows.  Its diagnostics about
variables possibly used before definition, or declared but not
used, and about suspicious statements, like \CN{if (a = b)
foo();} have nevertheless been quite useful as an alternative to
the \UNIX{} \CN{lint} utility.

With Version 3.0 of the \WIZARD{} compiler, the drivers will
compile, but they run incorrectly.  For example, the trivial loop
in \CF{cppsfile()} in \FN{dvialw.c} which copies the macro header
file to the output file returns random characters with \CF{getc}
(as determined by setting an assembly level breakpoint
immediately after the call to that function).

\subsection{\protect\IBMPC{} \protect\MICROSOFT{} C}

Version 3.0 of the \MICROSOFT{} \C{} compiler is claimed to be
a completely new release, sharing a very high degree of
compatibility with the \MICROSOFT{}
\N{Xenix} compiler, and the
\UNIX{} run-time library.  The compiler implements the ANSI
argument type checking  language extensions and will even
generate a set of function type declarations from a source file.

The 600 or so pages of documentation is thorough and, at least in
the library reference volume, quite readable.  The volume of the
use of the compiler could be improved---it is quite difficult to
track down precisely what compiler options to use, because they
are spread across dozens of pages of the manual.  There is an
on-line one-page summary available if you invoke the compiler
with the help option.

Error diagnostics are about as good (or bad) as any other \C{}
compiler---generally just the line number and a short message.
Unfortunately, the error recovery techniques are abysmal, and a
single error is likely to propagate dozens,  or even hundreds, of
other errors, even across function boundaries, so it is
frequently quite difficult to find the sick tree in the forest of
output.   Version 4.0 of the compiler does not have this problem.

Like most \C{} compilers for the \N{Intel} microprocessor family,
this compiler supports several memory models.  However, its large
memory model support, which is essential for this driver family,
is fatally flawed.  Unlike the \LATTICE{} and \WIZARD{}
compilers, which provide alternatives to \CF{malloc} for the case
of large memory allocations,%
\footnote{\INDEX{footnotes}{footnotes}%
        Recall that \CF{malloc} is defined to have the memory
        size argument be an \CN{int}, rather than a \CN{long},
        introducing a 32-Kbyte limitation when an \CN{int} is
        only 16 bits.  The draft ANSI \C{} Standard defines the
        argument to \CF{malloc} to be of a new type,
        \CN{size_t},
        which is returned by the \CN{sizeof}
        operator; this should provide a clean work-around.
}
\MICROSOFT{}  provides no such
function.  Even worse, 32-bit   pointers consisting of a 16-bit
segment and 16-bit offset, are {\em by design handled
incorrectly\/}.  Arithmetic on such pointers operates only on the
offset portion.  This makes it impossible to reliably use the
\CN{++} or \CN{-{}-}  operators on such a pointer, because it could
result in segment wrap.  Version 4.0 of the compiler introduced a
{\em huge\/} memory model which does not have this limitation.

For these reasons, the bitmap representation as a vector of
raster pointers had to be introduced, and a special function
\CF{normaddr} defined in \FN{bitmap.h} to allow arithmetic on
pointers.

This design flaw in the compiler, which is quite intentional
because it is documented in the manuals, is frankly
unforgivable.

Perfectly decent code in \CF{openfont} generated a fatal compiler
error, and a workaround under control of the preprocessor had to
be installed.

Getting around these flaws has occasioned considerable extra
work, but the compiler does succeed in producing compiled code,
and Version 4.0 has provided a reliable implementation of the DVI
driver family which has received heavy use locally.  The one
library bug that we have noted with Version 4.0 is incorrect
handling of formats to \CF{sscanf}; for the page number range
switch parsed in \FN{option.h}, it is necessary to supply a
trailing colon (i.e. use {\tt -o7:9:} instead of {\tt -o7:9}).

\section{Implementation Efficiency}
\INDEX{efficiency}{efficiency}
As the driver family has undergone continued development,
virtually all of the code has been reexamined with a view to its
run-time efficiency.  Where reasonable, in-line code is generated
by macros, pointer arithmetic is used in preference to array
indexing, and heavily used variables are declared with the
\CN{register} attribute.  Since not much computation is required
in any of the processing, one might expect the drivers to be I/O
bound, and this indeed proves to be the case.

As a sample of what might be expected, the \FN{dvitype.web} file
was selected for processing.  This file will be available at
every \TeX{} site.  Application of \WEAVE{} generates a .TEX
file which produces 53 printed pages, and the following run-time
results for the \PCC{} implementation on our DEC-20/60 may be of
interest.

\begin{center}
  \begin{tabular}{|l|r|r|}
    \hline
    Operation & CPU & Output Filesize\\
              & (sec) & (kbytes)\\
    \hline
    weave dvitype.web            &    22 & 149\\
    tex dvitype.tex              &  127 & 239\\
    dvialw dvitype (PXL fonts)   &   65 & 818\\
    dvialw dvitype (GF fonts)    &   79 & \\
    dvialw dvitype (PK fonts)    &   70 & 817\\
    dviprx dvitype (PXL fonts)   &  114 & 2608\\
    dviprx dvitype (GF fonts)    &    & \\
    dviprx dvitype (PK fonts)    &  290 & 2379\\
    \hline
  \end{tabular}
\end{center}

The \CN{dvialw} results are the average of 3 runs which had a
variance of about 5 sec.  Clearly, the penalty for the more
complex \FN{.gf} and \FN{.pk} font formats is not large -- about
20\% for \FN{.gf} fonts, and 8\% for \FN{.pk} fonts.  Since the
\FN{.pk} fonts average about half the disk space of the \FN{.gf}
fonts, and \CN{dvialw} runs faster with \FN{.pk} fonts than with
\FN{.gf} fonts, there is no reason to keep \FN{.gf} fonts on-line
once they have been generated by \MF{} and converted by
\CN{GFtoPK}.

To further investigate the CPU usage inside the driver, I ran
\CN{dvialw} and \CN{dviprx} under control of the run-time
PC-histogram utility, \CN{pclook}.  This produces a histogram of
where the program is spending its time, based on samples of the
\X{program counter} taken
every 25 msec.  The total number of samples taken ranged from
1600 to 2000.  In general, the time was distributed in small
percentages throughout most of the functions in \CN{dvialw}, but
the following results are of interest:
\begin{center}
  \begin{tabular}{|l|r|r|r|}
    \hline
dvialw test                   & \FN{.pxl} & \FN{.pk} & \FN{.gf}\\
    \hline
JSYS (TOPS-20 Monitor)        &  52\% & 55\% & 47\%\\
C run-time library            &  15\% & 16\% & 16\%\\
\CN{printf}                   &  11\% & 10\% & 11\%\\
\CN{dvialw} (all functions)   &     27\% & 25\% & 31\%\\
\CN{chargf}                   &  &  & 3\%\\
\CN{charpk}                   &  & 1\% &  \\
\CN{charpxl}                  & 0.2\% &  &  \\
\CN{setstr}                   &  10\% & 8\% & 8\%\\
    \hline
  \end{tabular}
\end{center}

\begin{center}
  \begin{tabular}{|l|r|r|r|}
    \hline
dviprx test & \FN{.pxl} & \FN{.pk} & \FN{.gf}\\
    \hline
JSYS (TOPS-20 Monitor)        &  48\% & 61\% & \\
C run-time library            &   4\% & 21\% & \\
\CN{printf}                   & 0.1\% &  1\% & \\
\CN{dviprx} (all functions)   & 46\%  & 18\% & \\
\CN{chargf}                   &       &      &\\
\CN{charpk}                   &       & 0.1\% &\\
\CN{charpxl}                  & 0.1\% &      & \\
\CN{dispchar}                 & 17\%  & 5\% & \\
\CN{fontsub}                  &       & 2\% & \\
\CN{prtbmap}                  & 17\%  & 4\% & \\
\CN{setchar}                  &  3\%  & 1\% & \\
    \hline
  \end{tabular}
\end{center}
The time for \CN{printf} is included in the run-time library
total, but for \CN{dvialw} it represents the largest use of any
library function.   \CN{dviprx} uses \CF{putc} for the output of
its bitmap, rather than \CF{printf}.

The \CF{charxx} functions are the ones which actually read the
font raster information and unpack it for output to the device.
It is surprising that so little of the total time is spent doing
this work.

\CF{setstr} accounts for the largest fraction of time
of any function in \CN{dvialw}; it loops reading characters from
the DVI file, calling \CF{charxx} to output them.  Similarly,
\CF{dispchar} and  \CF{setchar} in \CN{dviprx} together account
for 20\% of the time, and an almost equal amount of time is spent
by \CF{prtbmap} converting the page bitmap into a character
stream for the printer.

From 50\%  to 70\%  of  the total  time  is spent  inside  the
run-times and  the  \TOPS{}  operating  system,  putting  it
beyond control of the ordinary programmer.  Since the  major
reason for calling the operating system and run-time library
is for I/O, it  is evident that host  I/O efficiency is  the
dominant factor in the DVI  translator, and few source  code
changes in DVI driver family  could be made that would  have
any significant effect on the overall efficiency.


\section{Implementation Summary}

   You will no doubt encounter problems I have not documented
here if you implement this driver family under a new operating
system or with a new compiler.  As you make changes, remember
that the goal is to reduce all future changes to settings of
preprocessor variables in {\em one\/} file, {\tt machdefs.h}.
Look there first, and make sure that the operating system and
implementation symbols are properly defined for your system.

Find out whether your compiler generates sign-propagating
arithmetic right shifts,
\INDEX{shifts}{shifts}
or uses logical right shifts, and set
\CN{ARITHRSHIFT} accordingly.  According to the proposed
ANSI \C{} Standard, right shifts of signed integers should
propagate the sign bit, and right shifts of unsigned
integers should propagate leading zero bits.  This was
implementation dependent in the original \C{} definition.
The file \FN{00ARIT.C} can be compiled and run to test the
behavior of shifts.

 Check the file name, extension,
and directory path specifications, and modify them if necessary,
preferably under control of a preprocessor
\CNNX{\#if}\INDEX{#if}{\CNNX{\#if}}
statement.

   Finally, document all problems and send your comments back to
me.  You can complain all you like about something I have done,
but if you do not tell me, I cannot fix it, or explain why I did
it that way.
\newpage
 \begin{theindex}
 \renewcommand{\INDEX}[2]{}
 \renewcommand{\SUBINDEX}[3]{}
\input{dvidriver.ids}
 \end{theindex}
 \end{document}
