<chapter>
  <title>ESC/P2</title>
  <para>
    This is a description of the ESC/P2 raster commands used by the
    Gutenprint printer driver, which is a subset of the complete
    command set.  The full documents are found on <ulink
    url="http://www.ercipd.com/isv/edr_docs.htm">
    <citetitle>http://www.ercipd.com/isv/edr_docs.htm</citetitle></ulink>.
    Note that these are <emphasis>not</emphasis> always correct, and
    are certainly not complete.
  </para>
  <para>
    All ESCP/2 raster commands begin with the <literal>ESC</literal>
    character (0x1b), followed by either one or two command characters
    and arguments where applicable.  Older commands generally have one
    command character.  Newer commands usually have a
    &lsquo;<literal>(</literal>&rsquo; (left parenthesis) followed by
    a command character and a byte count for the arguments that
    follow.  The byte count is a 16-bit (2 byte) binary integer, in
    little endian order.
  </para>
  <para>
    All arguments listed here are of the form
    <literal>name[bytes]</literal> where <literal>[bytes]</literal> is
    the number of bytes that comprise the argument.  The arguments
    themselves are usually one, two, or four byte integers, always
    little endian (the least significant bits come first).  Presumably
    this is to match Intel processors.
  </para>
  <para>
    In some cases, the same command sequence identifies different
    versions of the same command, depending upon the number of bytes
    of arguments.
  </para>
  <sect1>
    <title>Standard commands</title>
    <variablelist>
      <title>ESC/P2 Commands</title>
      <varlistentry>
        <term><literal>ESC @</literal></term>
        <listitem>
          <para>
            Reset the printer.  Discards any output, ejects the
            existing page, returns all settings to their default.
            Always use this before printing a page.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (G <varname>BC</varname>=1
            <varname>ON1</varname></literal></term>
        <listitem>
          <para>
            Turn on graphics mode.  <varname>ON</varname> should be
            <constant>1</constant> (turn on graphics mode).
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (U <varname>BC</varname>=1
            <varname>UNIT1</varname></literal></term>
        <listitem>
          <para>
            Set basic unit of measurement used by printer.  This is
            expressed in multiples of 1/3600".  At 720 DPI,
            <varname>UNIT</varname> is <constant>5</constant>; at
            360 DPI, <varname>UNIT</varname> is
            <constant>10</constant>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (U <varname>BC</varname>=5
            <varname>PAGEUNITS1</varname> <varname>VUNIT1</varname>
            <varname>HUNIT1</varname>
            <varname>BASEUNIT2</varname></literal></term>
        <listitem>
          <para>
            Set basic units of measurement used by the printer.
            <varname>PAGEUNIT</varname> is the unit of page
            measurement (for commands that set page dimensions and
            the like).  <varname>VUNIT</varname> is the unit of
            vertical measurement (for vertical movement commands).
            <varname>HUNIT</varname> is the unit of horizontal
            movement (for horizontal positioning commands).  All of
            these units are expressed in
            <varname>BASEUNIT</varname>, which is in reciprocal
            inches.  Typically, <varname>BASEUNIT</varname> is
            <constant>1440</constant>.  In 720 DPI mode,
            <varname>PAGEUNIT</varname>, <varname>VUNIT</varname>,
            and <varname>HUNIT</varname> are all
            <constant>2</constant>; in 1440&times;720 DPI mode,
            <varname>PAGEUNIT</varname> and <varname>VUNIT</varname>
            are normally set to <constant>2</constant>;
            <varname>HUNIT</varname> is set to
            <constant>1</constant>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (K <varname>BC</varname>=2
            <varname>ZERO1</varname>
            <varname>GRAYMODE1</varname></literal></term>
        <listitem>
          <para>
            Set color or grayscale mode, on printers supporting an
            explicit grayscale mode.  These printers can be
            identified because they are advertised as having more
            black nozzles than nozzles of individual colors.
            Setting grayscale mode allows use of these extra nozzles
            for faster printing.  <varname>GRAYMODE</varname> should
            be <constant>0</constant> or <constant>2</constant> for
            color, <constant>1</constant> for grayscale.
            <varname>ZERO</varname> should always be
            <constant>0</constant>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (i <varname>BC</varname>=1
            <varname>MICROWEAVE1</varname></literal></term>
        <listitem>
          <para>
            If <varname>MICROWEAVE</varname> is
            <constant>1</constant>, use microweave mode.  On older
            printers, this is used to turn on microweave; on newer
            printers, it prints one row at a time.  All printers
            support this mode.  It should only be used at 720 (or
            1440&times;720) DPI.  The Epson Stylus Pro series
            indicates additional modes:
          </para>
          <variablelist>
            <varlistentry>
              <term><constant>2</constant></term>
              <listitem>
                <para>
                  &ldquo;Full-overlap&rdquo;
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><constant>3</constant></term>
              <listitem>
                <para>
                  &ldquo;Four-pass&rdquo;
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><constant>4</constant></term>
              <listitem>
                <para>
                  &ldquo;Full-overlap 2&rdquo;
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
          <para>
            Any of these commands can be used with the high four
            bits set to either <constant>3</constant> or
            <constant>0</constant>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC U
            <varname>DIRECTION1</varname></literal></term>
        <listitem>
          <para>
            If <varname>DIRECTION</varname> is
            <constant>1</constant>, print unidirectionally; if
            <constant>0</constant>, print bidirectionally.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (s <varname>BC</varname>=1
            <varname>SPEED1</varname></literal></term>
        <listitem>
          <para>
            On some older printers, this controls the print head
            speed.  <varname>SPEED</varname> of
            <constant>2</constant> is 10 inches/sec;
            <varname>SPEED</varname> of <constant>0</constant> or 1
            is 20.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (e <varname>BC</varname>=2
            <varname>ZERO1</varname>
            <varname>DOTSIZE1</varname></literal></term>
        <listitem>
          <para>
            Choose print dotsize.  <varname>DOTSIZE</varname> can
            take on various values, depending upon the printer.
            Almost all printers support <constant>0</constant> and
            <constant>2</constant>.  Variable dot size printers
            allow a value of <varname>16</varname>.  Other than the
            value of <varname>16</varname>, this appears to be
            ignored at resolutions of 720 DPI and above.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (C <varname>BC</varname>=2
            <varname>PAGELENGTH2</varname></literal></term>
        <term><literal>ESC (C <varname>BC</varname>=4
            <varname>PAGELENGTH4</varname></literal></term>
        <listitem>
          <para>
            Set the length of the page in &ldquo;pageunits&rdquo;
            (see <literal>ESC (U</literal> above).  The second form
            of the command allows setting of longer page lengths on
            new printers (these happen to be the printers that
            support variable dot size).
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (c <varname>BC</varname>=4
            <varname>TOP2</varname>
            <varname>LENGTH2</varname></literal></term>
        <term><literal>ESC (c <varname>BC</varname>=8
            <varname>TOP4</varname>
            <varname>LENGTH4</varname></literal></term>
        <listitem>
          <para>
            Set the vertical page margins of the page in
            &ldquo;pageunits&rdquo; (see <literal>ESC (U</literal>
            above).  The margins are specified as the top of the
            page and the length of the page.  The second form of the
            command allows setting of longer page lengths on new
            printers (these happen to be the printers that support
            variable dot size).
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (S <varname>BC</varname>=8
            <varname>WIDTH4</varname>
            <varname>LENGTH4</varname></literal></term>
        <listitem>
          <para>
            Set the width and length of the printed page region in
            &ldquo;pageunits&rdquo; (see <literal>ESC (U</literal>
            above).
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (v <varname>BC</varname>=2
            <varname>ADVANCE2</varname></literal></term>
        <term><literal>ESC (v <varname>BC</varname>=4
            <varname>ADVANCE4</varname></literal></term>
        <listitem>
          <para>
            Feed vertically <varname>ADVANCE</varname>
            &ldquo;vertical units&rdquo; (see <literal>ESC
            (U</literal> above) from the current print head
            position.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (V <varname>BC</varname>=2
            <varname>ADVANCE2</varname></literal></term>
        <term><literal>ESC (V <varname>BC</varname>=4
            <varname>ADVANCE4</varname></literal></term>
        <listitem>
          <para>
            Feed vertically <varname>ADVANCE</varname>
            &ldquo;vertical units&rdquo; (see <literal>ESC
            (U</literal> above) from the top margin.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC ($ <varname>BC</varname>=4
            <varname>OFFSET4</varname></literal></term>
        <listitem>
          <para>
            Set horizontal position to <varname>OFFSET</varname>
            from the left margin.  This command operates on printers
            of the 740 class and newer (all printers with variable
            dot size).
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC $
            <varname>OFFSET2</varname></literal></term>
        <listitem>
          <para>
            Set horizontal position to <varname>OFFSET</varname>
            from the left margin.  This command operates on printers
            of the 740 class and newer (all printers with variable
            dot size).
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (\ <varname>BC</varname>=4
            <varname>UNITS2</varname>
            <varname>OFFSET2</varname></literal></term>
        <listitem>
          <para>
            Set horizontal position to <varname>OFFSET</varname>
            from the previous print head position, measured in
            <varname>UNITS</varname>.  <varname>UNITS</varname> is
            measured in inverse inches, and should be set to 1440 in
            all cases.  This operates on all 1440 dpi printers that
            do not support variable dot size.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (/ <varname>BC</varname>=4
            <varname>OFFSET4</varname></literal></term>
        <listitem>
          <para>
            Set horizontal position to <varname>OFFSET</varname>
            from the previous print head position, measured in
            &ldquo;horizontal units&rdquo; (see <literal>ESC
            (U</literal> above).  This operates on all variable dot
            size printers.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC \
            <varname>OFFSET2</varname></literal></term>
        <listitem>
          <para>
            Set horizontal position to <varname>OFFSET</varname>
            from the previous print head position, measured in basic
            unit of measurement (see <literal>ESC (U</literal>
            above). This is used on all 720 dpi printers, and can
            also be used on 1440 dpi printers in lower resolutions
            to save a few bytes.  Note that
            <varname>OFFSET</varname> may be negative.  The range of
            values for this command is between
            <constant>-16384</constant> and
            <constant>16383</constant>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC r
            <varname>COLOR1</varname></literal></term>
        <term><literal>ESC (r <varname>BC</varname>=2
            <varname>DENSITY1</varname>
            <varname>COLOR1</varname></literal></term>
        <listitem>
          <para>
            Set the ink color.  The first form is used on four-color
            printers; the second on six-color printers.
            <varname>DENSITY</varname> is <constant>0</constant> for
            dark inks, <constant>1</constant> for light.
            <varname>COLOR</varname> is
          </para>
          <table>
            <title>Colors</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="id"/>
              <colspec colnum="2" colname="color"/>
              <thead>
                <row>
                  <entry><varname>COLOR</varname></entry>
                  <entry>Color name</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>0</constant></entry>
                  <entry>Black</entry>
                </row>
                <row>
                  <entry><constant>1</constant></entry>
                  <entry>Magenta</entry>
                </row>
                <row>
                  <entry><constant>2</constant></entry>
                  <entry>Cyan</entry>
                </row>
                <row>
                  <entry><constant>4</constant></entry>
                  <entry>Yellow</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            This command is not used on variable dot size printers
            in softweave mode.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC . <varname>COMPRESS1</varname>
            <varname>VSEP1</varname> <varname>HSEP1</varname>
            <varname>LINES1</varname> <varname>WIDTH2</varname>
            data...</literal></term>
        <listitem>
          <para>
            Print data.  <varname>COMPRESS</varname> signifies the
            compression mode.
          </para>
          <table>
            <title>Compression modes</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="id"/>
              <colspec colnum="2" colname="compression"/>
              <thead>
                <row>
                  <entry><varname>COMPRESS</varname></entry>
                  <entry>Compression mode</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>0</constant></entry>
                  <entry>No compression</entry>
                </row>
                <row>
                  <entry><constant>1</constant></entry>
                  <entry>
                    TIFF compression (incorrectly documented as
                    &ldquo;run length encoded&rdquo;)
                  </entry>
                </row>
                <row>
                  <entry><constant>2</constant></entry>
                  <entry>
                    TIFF compression with a special command set.
                  </entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <varname>VSEP</varname> depends upon resolution and
            printer type.  At 360 DPI, it is always
            <constant>10</constant>.  At 720 DPI, it is normally
            <constant>5</constant>5.  On the ESC 600, it is
            <constant>40</constant> (8 &times; 5}).  On some other
            printers, it varies.
          </para>
          <para>
            <varname>HSEP1</varname> is <constant>10</constant> at
            360 DPI and <constant>5</constant> at 720 or 1440 DPI
            (1440 DPI cannot be printed in one pass; it is printed
            in two passes, with the dots separated in each pass by
            1/720").
          </para>
          <para>
            <varname>LINES</varname> is the number of lines to be
            printed.  It should be <constant>1</constant> in
            microweave and 360 DPI.  At 720 DPI softweave, it should
            be the number of lines to be actually printed.
          </para>
          <para>
            <varname>WIDTH</varname> is the number of pixels to be
            printed in each row.  Following this command, a carriage
            return (<constant>13</constant> decimal,
            <literal>0A</literal> hex) should be output to return
            the print head position to the left margin.
          </para>
          <para>
            The basic data format is a string of bytes, with data
            from left to right on the page.  Within each byte, the
            highest bit is first.
          </para>
          <para>
            The TIFF compression is implemented as one count byte
            followed by one or more data bytes.  There are two
            cases:
          </para>
          <orderedlist>
            <listitem>
              <para>
                If the count byte is <constant>128</constant> or
                less, it is followed by ([count] + 1) data bytes.
                So if the count byte is <constant>0</constant>, it
                is followed by 1 data byte; if it is
                <constant>128</constant>, it is followed by 129 data
                bytes.
              </para>
            </listitem>
            <listitem>
              <para>
                If the count byte is greater than 128, it is
                followed by one byte.  This byte is repeated (257 -
                [count]) times.  So if [count] is 129, the next byte
                is treated as though it were repeated 128 times; if
                [count] is 255, it is treated as though it were
                repeated twice.
              </para>
            </listitem>
          </orderedlist>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC i <varname>COLOR1</varname>
            <varname>COMPRESS1</varname> <varname>BITS1</varname>
            <varname>BYTES2</varname> <varname>LINES2</varname>
            data...</literal></term>
        <listitem>
          <para>
            Print data in the newer printers (that support variable
            dot size), and Stylus Pro models.
            <varname>COLOR</varname> is the color.
          </para>
          <table>
            <title>Extended Colors</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="id"/>
              <colspec colnum="2" colname="color"/>
              <thead>
                <row>
                  <entry><varname>COLOR</varname></entry>
                  <entry>Color name</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>0</constant></entry>
                  <entry>Black</entry>
                </row>
                <row>
                  <entry><constant>1</constant></entry>
                  <entry>Magenta</entry>
                </row>
                <row>
                  <entry><constant>2</constant></entry>
                  <entry>Cyan</entry>
                </row>
                <row>
                  <entry><constant>4</constant></entry>
                  <entry>Yellow</entry>
                </row>
                <row>
                  <entry><constant>5</constant></entry>
                  <entry>Alternate black (Stylus C70/C80)</entry>
                </row>
                <row>
                  <entry><constant>6</constant></entry>
                  <entry>Alternate black (Stylus C70/C80)</entry>
                </row>
                <row>
                  <entry><constant>16</constant></entry>
                  <entry>Gray (&ldquo;light black&rdquo;)</entry>
                </row>
                <row>
                  <entry><constant>17</constant></entry>
                  <entry>Light magenta</entry>
                </row>
                <row>
                  <entry><constant>18</constant></entry>
                  <entry>Light cyan</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <varname>COMPRESS</varname> signifies the compression
            mode:
          </para>
          <table>
            <title>Compression modes</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="id"/>
              <colspec colnum="2" colname="compression"/>
              <thead>
                <row>
                  <entry><varname>COMPRESS</varname></entry>
                  <entry>Compression mode</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>0</constant></entry>
                  <entry>No compression</entry>
                </row>
                <row>
                  <entry><constant>1</constant></entry>
                  <entry>
                    TIFF compression (incorrectly documented as
                    &ldquo;run length encoded&rdquo;)
                  </entry>
                </row>
                <row>
                  <entry><constant>2</constant></entry>
                  <entry>
                    TIFF compression with a special command set, or
                    &ldquo;run length encoding 2&rdquo; on some
                    printers.
                  </entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <varname>BITS</varname> is the number of bits per pixel.
          </para>
          <para>
            <varname>BYTES</varname> is the number of bytes wide for
            each row (ceiling(BITS &times; width_of_row, 8)}). Note
            that this is different from the <literal>ESC .</literal>
            command above.
          </para>
          <para>
            <varname>LINES</varname> is the number of lines to be
            printed.  This command is the only way to get variable
            dot size printing.  In variable dot mode, the size of
            the dots increases as the value (<constant>1</constant>,
            <constant>2</constant>, or <constant>3</constant>)
            increases.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (D <varname>BC</varname>=4
            <varname>BASE2</varname> <varname>VERTICAL1</varname>
            <varname>HORIZONTAL1</varname></literal></term>
        <listitem>
          <para>
            Set printer horizontal and vertical spacing.  It only
            applies to variable dot size printers in softweave mode
            (and possibly other high end printers).
          </para>
          <para>
            <varname>BASE</varname> is the base unit for this
            command; it must be <constant>14400</constant>.
          </para>
          <para>
            <varname>VERTICAL</varname> is the distance in these
            units between printed rows; it should be
            ((separation_in_nozzles &times; <varname>BASE</varname>
            &divide; 720).
          </para>
          <para>
            <varname>HORIZONTAL</varname> is the horizontal
            separation between dots in a row.  Depending upon the
            printer, this should be either (14400 &divide; 720) or
            (14400 &divide; 360).  The Stylus Pro 9000 manual
            suggests that the settings should match the chosen
            resolution, but that is apparently not the case (or not
            always the case) on other printers.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC (R <varname>BC</varname>=8 00 R E M O T E
            1</literal></term>
        <listitem>
          <para>
            Enters &ldquo;remote mode&rdquo;.  This is a special,
            undocumented command set that is used to set up various
            printer options, such as paper feed tray, and perform
            utility functions such as head cleaning and alignment.
            It does not appear that anything here is actually
            required to make the printer print.  Our best
            understanding of what is in a remote command sequence is
            described in a separate section below.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>ESC 01 @EJL [sp] ID\r\n</literal></term>
        <listitem>
          <para>
            Return the printer ID.  This is considered a remote mode
            command, although the syntax is that of a conventional
            command.  This returns the following information:
          </para>
          <informalexample>
            <screen>@EJL ID\r
MFG:EPSON;
CMD:ESCPL2,BDC;
MDL:[printer model];
CLS:PRINTER;
DES:EPSON [printer model];
\f</screen>
          </informalexample>
          <para>
            After all data has been sent, a form feed byte should be
            sent.
          </para>
        </listitem>
      </varlistentry>
  </variablelist>
  <para>
     All newer Epson printers (STC 440, STP 750) require the
     following command to be sent at least once to enable printing
     at all.  This command specifically takes the printer out of the
     1284.4 packet mode communication protocol and enables normal
     data transfer.  Sending it multiple times is is not harmful, so
     it is normally sent at the beginning of each job:
  </para>
  <informalexample>
    <screen>ESC 01@EJL[space]1284.4[newline]@EJL[space][space][space][space]
[space][newline]ESC@</screen>
  </informalexample>
  <para>
    The proper sequence of initialization commands is:
  </para>
  <informalexample>
    <screen>magic command
ESC @
remote mode if needed
ESC (G
ESC (U
ESC (K (if appropriate)
ESC (i
ESC U (if needed)
ESC (s (if appropriate)
ESC (e
ESC (C
ESC (c
ESC (S
ESC (D (if needed)
ESC (V (optional -- this can be accomplished with ESC (v)</screen>
  </informalexample>
  <para>
    For printing, the proper sequence is:
  </para>
  <informalexample>
    <screen>ESC (v</screen>
  </informalexample>
  <para>
    and repeat for each color:
  </para>
  <!-- This needs better formatting... -->
  <informalexample>
    <screen>ESC ($ or ESC (\ or ESC \
ESC (r or ESC r (if needed---not used with "ESC i" and not needed if the color
has not changed from the previous printed line)
ESC . or ESC i  ...data... [return] (0A hex)</screen>
  </informalexample>
  <para>
    To terminate a page:
  </para>
  <informalexample>
    <screen>[formfeed] (0C hex)
ESC @</screen>
  </informalexample>
</sect1>
<sect1>
  <title>Remote Mode Commands</title>
  <para>
    The following description of remote commands comes out of an
    examination of the sequences used by the printer utilities
    bundled with the Windows drivers for the ESC740, and from other
    sources (some Epson manuals, experimentation, analysis of print
    files).  It is largely speculative as these commands are not all
    documented in the Epson documentation we have access to.
    Generally, newer manuals provide more thorough documentation.
  </para>
  <para>
    Remote command mode is entered when the printer is sent the
    following sequence:
  </para>
  <informalexample>
    <screen>ESC (R BC=8 00 R E M O T E 1</screen>
  </informalexample>
  <para>
    Remote mode commands are then sent, and terminated with the
    following sequence:
  </para>
  <informalexample>
    <screen>ESC 00 00 00</screen>
  </informalexample>
  <para>
    All remote mode commands must be sent before the initial
    <literal>ESC (G</literal> command is sent.
  </para>
  <para>
    This introductory sequence is then followed by a sequence of
    commands.  Each command is constructed as follows:
  </para>
  <orderedlist>
    <listitem>
      <para>
        Two ASCII bytes indicating the function
      </para>
    </listitem>
    <listitem>
      <para>
        A byte count (two bytes, little-endian) for the parameters
      </para>
    </listitem>
    <listitem>
      <para>
        Binary parameters, if any
      </para>
    </listitem>
  </orderedlist>
  <para>
      This is a list of all remote commands we have seen:
  </para>
  <variablelist>
    <title>ESC/P2 Remote Mode Commands</title>
    <varlistentry>
      <term><literal>NC <varname>BC</varname>=2 00
          00</literal></term>
      <listitem>
        <para>
          Print a nozzle check pattern.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>VI <varname>BC</varname>=2 00
          00</literal></term>
      <listitem>
        <para>
          On my 740, prints the following, probably &ldquo;version
          information&rdquo;:
        </para>
        <informalexample>
          <screen>W01286 I02382\r\n</screen>
        </informalexample>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* AI <varname>BC</varname>=3 00 00 00</literal></term>
      <listitem>
        <para>
          Prints a &ldquo;printer ID&rdquo;.  On one 870, prints the
          following:
        </para>
        <informalexample>
          <screen>51-51-50-51-49-48\r\n</screen>
        </informalexample>
        <para>
          The Windows driver has a text entry field where this
          number can be entered, but its purpose is unknown.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* LD <varname>BC</varname>=0</literal></term>
      <listitem>
        <para>
          Load printer defaults from NVRAM, DIP switches, and/or
          ROM. This apparently does not load factory defaults per
          se, but any settings that are saved.  This is commonly
          used right at the end of each print job after the
          <literal>ESC @</literal> printer reset command.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* CH <varname>BC</varname>=2 00
          <varname>xx</varname></literal></term>
      <listitem>
        <para>
          Perform a head cleaning cycle.  The heads to clean are
          determined by parameter <varname>xx</varname>:
      </para>
        <table>
          <title>Head cleaning parameters</title>
          <tgroup cols="2" align="left">
            <colspec colnum="1" colname="id"/>
            <colspec colnum="2" colname="description"/>
            <thead>
              <row>
                <entry><varname>xx</varname></entry>
                <entry>Description</entry>
              </row>
            </thead>
            <tbody>
              <row>
                <entry><constant>00</constant></entry>
                <entry>Clean all heads</entry>
              </row>
              <row>
                <entry><constant>01</constant></entry>
                <entry>Clean black head</entry>
              </row>
              <row>
                <entry><constant>02</constant></entry>
                <entry>Clean color heads</entry>
              </row>
            </tbody>
          </tgroup>
        </table>
        <para>
          While <varname>xx</varname> = <constant>00</constant> is
          likely supported by all printers, <varname>xx</varname>
          = <constant>01</constant> and <constant>02</constant>
          are not.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* DT <varname>BC</varname>=3 00
          <varname>xx</varname> 00</literal></term>
      <listitem>
        <para>
          Print an alignment pattern.  There are three patterns,
          which are picked via the choice of
          <varname>xx</varname>.  Pattern <constant>0</constant>
          is coarse, pattern <constant>1</constant> is medium, and
          pattern <constant>2</constant> is fine.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* DA <varname>BC</varname>=4 00
          <varname>xx</varname> 00
          <varname>yy</varname></literal></term>
      <listitem>
        <para>
          Set results for the alignment pattern.
          <varname>xx</varname> is the pattern
          (<constant>1</constant>--<constant>3</constant>);
          <varname>yy</varname> is the best choice from the set
          (<constant>1</constant>--<constant>7</constant> or
          <constant>1</constant>--<constant>15</constant>).  This
          does not save to NVRAM, so when the printer is powered
          off, the setting will be lost.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* SV <varname>BC</varname>=0</literal></term>
      <listitem>
        <para>
          Save the current settings to NVRAM.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* RS <varname>BC</varname>=1
          01</literal></term>
      <listitem>
        <para>
          Reset the printer.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* IQ <varname>BC</varname>=1
          01</literal></term>
      <listitem>
        <para>
          Get ink quantity.  This requires direct access to the
          printer port.  The return looks like
        </para>
        <informalexample>
          <screen>IQ:KKCCMMYY</screen>
        </informalexample>
        <para>
          or
        </para>
        <informalexample>
          <screen>IQ:KKCCMMYYccmm</screen>
        </informalexample>
        <para>
          (for 4-color and 6-color printers respectively), where
          each pair of digits are hexadecimal representations of
          percent.
        </para>
      </listitem>
    </varlistentry>
</variablelist>
<para>
  The following two commands have been observed on an STP 870.
</para>
<variablelist>
    <varlistentry>
      <term><literal>* IR <varname>BC</varname>=2 00
          <varname>xx</varname></literal></term>
      <listitem>
        <para>
          <emphasis>Function unknown</emphasis>.  This command has
          been observed on an STP 870 with
          <varname>xx</varname>=<constant>03</constant> at the start
          of a job and <varname>xx</varname>=<constant>02</constant>
          at the end of a job (where it is followed by an
          <literal>LD</literal> command).  When in roll mode, the
          values change to
          <varname>xx</varname>=<constant>01</constant> at the start
          of a job and <varname>xx</varname>=<constant>00</constant>
          at the end of a job.
        </para>
      </listitem>
    </varlistentry>
    <varlistentry>
      <term><literal>* FP <varname>BC</varname>=3 00
          <varname>pos</varname>[2]</literal></term>
      <listitem>
        <para>
          Specify the horizontal left margin in units of 1/360 inch.
          The default value for <varname>pos</varname> is
          <constant>0</constant>.  For borderless printing on
          printers that support it, a value of
          <constant>-80</constant> (<constant>FFB0h</constant>)
          should be used.
        </para>
      </listitem>
    </varlistentry>
  </variablelist>
  <para>
    The commands below are partially documented in the Stylus Pro
    9000 manual.  Much of this information is interpreted; none is
    tested.
  </para>
  <variablelist>
      <varlistentry>
        <term><literal>* SN <varname>BC</varname>=3 00
            <varname>xx</varname> <varname>yy</varname></literal></term>
        <listitem>
          <para>
            Select Mechanism Sequence.  <varname>xx</varname>
            controls which sub-operation is performed.
            <varname>xx</varname>=<constant>00</constant> selects
            the &ldquo;Feed paper sequence setting&rdquo;.
            <varname>yy</varname> can take on the following values
            (on the STP 870, at any rate):
          </para>
          <table>
            <title>Media types</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="id"/>
              <colspec colnum="2" colname="description"/>
              <thead>
                <row>
                  <entry><varname>yy</varname></entry>
                  <entry>Media type</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>0</constant></entry>
                  <entry>Default</entry>
                </row>
                <row>
                  <entry><constant>1</constant></entry>
                  <entry>Plain paper</entry>
                </row>
                <row>
                  <entry><constant>2</constant></entry>
                  <entry>Postcards</entry>
                </row>
                <row>
                  <entry><constant>3</constant></entry>
                  <entry>
                    Film (photo quality glossy film, transparencies)
                  </entry>
                </row>
                <row>
                  <entry><constant>4</constant></entry>
                  <entry>Envelopes</entry>
                </row>
                <row>
                  <entry><constant>5</constant></entry>
                  <entry>Plain paper (fast load)</entry>
                </row>
                <row>
                  <entry><constant>6</constant></entry>
                  <entry>
                    Back light film (although this has been observed
                    with heavyweight matte paper)
                  </entry>
                </row>
                <row>
                  <entry><constant>7</constant></entry>
                  <entry>
                    Matte paper (observed with 360 dpi inkjet paper,
                    and photo quality inkjet paper)
                  </entry>
                </row>
                <row>
                  <entry><constant>8</constant></entry>
                  <entry>Photo paper</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            Experimentation suggests that this setting changes
            details of how the printers' cut sheet feeder works,
            presumably to tune it for different types of paper.
          </para>
          <para>
            <varname>xx</varname>=<constant>01</constant> controls
            the platen gap setting;
            <varname>yy</varname>=<constant>00</constant> is the
            default, <varname>yy</varname>=<constant>1</constant> or
            <constant>2</constant> are higher settings.
          </para>
          <para>
            <varname>xx</varname>=<constant>02</constant> controls
            paper loading speed
            (<varname>yy</varname>=<constant>0</constant> is normal,
            <constant>1</constant> is fast, <constant>2</constant>
            is slow).  It appears that <constant>1</constant> is
            used when printing on &ldquo;plain paper&rdquo;,
            &ldquo;360dpi ink jet paper&rdquo; or &ldquo;ink jet
            transparencies&rdquo;, and
            <varname>yy</varname>=<constant>00</constant> for all
            other paper type settings.
          </para>
          <para>
            <varname>xx</varname>=<constant>07</constant> controls
            duplex printing for printers with that capability
            (<varname>yy</varname>=<varname>0</varname> is default,
            for non-duplex printing; <constant>1</constant> is front
            side of the paper, and <varname>2</varname> is back
            side).
          </para>
          <para>
            <varname>xx</varname>=<constant>09</constant> controls
            zero margin printing on the printers with the capability
            of printing zero-margin on all sides (Stylus Photo
            780/790, 890, and 1280/1290).
            <varname>yy</varname>=<constant>0</constant> is the
            default; <constant>1</constant> enables zero margin
            printing.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* PP <varname>BC</varname>=3 00
            <varname>xx</varname>
            <varname>yy</varname></literal></term>
        <listitem>
          <para>
            Set Paper Path.
            <varname>xx</varname>=<constant>2</constant> indicates
            manual feed,
            <varname>xx</varname>=<constant>3</constant> is for roll
            paper.  <varname>yy</varname> selects &ldquo;paper path
            number&rdquo;.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* AC <varname>BC</varname>=2 00
            <varname>xx</varname></literal></term>
        <listitem>
          <para>
            Set Auto Cutting State.
            <varname>xx</varname>=<constant>0</constant> selects
            auto cutting off,
            <varname>xx</varname>=<constant>1</constant> selects
            auto cutting on, and
            <varname>xx</varname>=<constant>2</constant> indicates
            horizontal print page line on.  It appears that with
            auto cutting on, roll paper is cut automatically at the
            point a formfeed character is sent.  The formfeed
            character is normally used to eject a page; with this
            turned on, it also cuts the roll paper.  Horizontal
            print page line on prints a narrow line of black dots at
            the position the paper should be cut manually.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* DR <varname>BC</varname>=4 00 xx
            <varname>DT2</varname></literal></term>
        <listitem>
          <para>
            Set Drying Time.
            <varname>xx</varname>=<constant>00</constant> sets the
            drying time &ldquo;per scan&rdquo; (per pass?);
            <varname>xx</varname>=<constant>01</constant> sets the
            drying time per page. <varname>DT</varname> indicates
            the drying time, which is in seconds if page mode is
            used and in milliseconds if scan mode is used.
            <varname>DT</varname> must not exceed 3600 seconds in
            per-page mode and 10000 milliseconds in per-scan mode.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* IK <varname>BC</varname>=2 00
            <varname>xx</varname></literal></term>
        <listitem>
          <para>
            Select Ink Type.
            <varname>xx</varname>=<constant>00</constant> selects
            dye ink.  Pigment ink is apparently selected by
            <varname>xx</varname>=<constant>01</constant>.  This
            probably does not apply to the consumer-grade printers.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* PZ BC=2 00 xx</literal></term>
        <listitem>
          <para>
            Set Pause After Printing.
            <varname>xx</varname>=<constant>00</constant> selects no
            pause after printing;
            <varname>xx</varname>=<constant>01</constant> selects
            pause after printing.  If turned on, the printer is
            paused after the page is ejected (by the FF byte).  If
            cutting is turned on, the printer is paused
            <emphasis>after</emphasis> the cutting or printing of
            the horizontal cut line.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* EX <varname>BC</varname>=6 00 00 00 00 0x14
          <varname>xx</varname></literal></term>
        <listitem>
          <para>
            Set Vertical Print Page Line Mode.
            <varname>xx</varname>=<constant>00</constant> is off,
            <varname>xx</varname>=<constant>01</constant> is on.  If
            turned on, this prints vertical trim lines at the left
            and right margins.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* EX <varname>BC</varname>=6 00 00 00 00 0x05
            <varname>xx</varname></literal></term>
        <listitem>
          <para>
            Set Roll Paper Mode.  If <varname>xx</varname> is
            <constant>0</constant>, roll paper mode is off; if
            <varname>xx</varname> is <constant>1</constant>, roll
            paper mode is on.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* EX <varname>BC</varname>=3 00
            <varname>xx</varname> <varname>yy</varname></literal></term>
        <listitem>
          <para>
            Appears to be a synonym for the <literal>SN</literal>
            command described above.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* PH <varname>BC</varname>=2 00
            <varname>xx</varname></literal></term>
        <listitem>
          <para>
            Select Paper Thickness.  Set the paper thickness
            <varname>xx</varname> in .1 mm units.  This must not
            exceed <constant>0x10</constant> (1.6 mm).  If the
            thickness is set &ldquo;more than&rdquo; .6 mm (which
            probably means &ldquo;at least&rdquo; 0.6 mm, since the
            other case reads &ldquo;less than 0.5 mm&rdquo;), the
            platen gap is set high irrespective of the
            <literal>SN</literal> command.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* PM <varname>BC</varname>=2 00
            00</literal></term>
        <listitem>
          <para>
            <emphasis>Function unknown</emphasis>. Used on the STC
            3000 at least when using roll feed, and on the STP 870
            in all print files analysed to date.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* ST <varname>BC</varname>=2 00
            <varname>xx</varname></literal></term>
        <listitem>
          <para>
            Epson's STP 750/1200 programming guide refers to the
            <literal>ST</literal> command as &ldquo;Set printer
            state reply&rdquo;.  If <varname>xx</varname> is
            <constant>0</constant> or <constant>2</constant>, the
            printer will not send status replies.  If
            <varname>xx</varname> is <constant>1</constant> or
            <constant>3</constant>, the printer will send status
            replies.  The status replies consist of state, error
            codes, ink leve, firmware version, and warning status.
          </para>
          <para>
            The actual reply is documented as
          </para>
          <informalexample>
            <screen>@BDC ST\r
ST: xx;
[ER: yy;]
IQ: n1n2n3n4;
[WR: w1,w2...;]
RV: zz;
AI:CW:02kkccmmyy, MI:mm
[TC:tttt;]
INK:...;
\f</screen>
          </informalexample>
          <para>
            (<literal>\r</literal> is carriage return;
            <literal>\n</literal> is newline; <literal>\f</literal>
            is formfeed.)
          </para>
          <para>
            <literal>ST</literal> is the printer status:
          </para>
          <table>
            <title>Printer status codes</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="status"/>
              <colspec colnum="2" colname="description"/>
              <thead>
                <row>
                  <entry>Status code</entry>
                  <entry>Description</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>00</constant></entry>
                  <entry>Error</entry>
                </row>
                <row>
                  <entry><constant>01</constant></entry>
                  <entry>Self-test</entry>
                </row>
                <row>
                  <entry><constant>02</constant></entry>
                  <entry>Busy</entry>
                </row>
                <row>
                  <entry><constant>03</constant></entry>
                  <entry>Waiting while printing</entry>
                </row>
                <row>
                  <entry><constant>04</constant></entry>
                  <entry>Idle</entry>
                </row>
                <row>
                  <entry><constant>07</constant></entry>
                  <entry>Cleaning/filling ink heads</entry>
                </row>
                <row>
                  <entry><constant>08</constant></entry>
                  <entry>Not yet initialized/filling heads</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <literal>ER</literal>, if provided, is the error status:
          </para>
          <table>
            <title>Printer error codes</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="error"/>
              <colspec colnum="2" colname="description"/>
              <thead>
                <row>
                  <entry>Error code</entry>
                  <entry>Description</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>00</constant></entry>
                  <entry>Fatal Error</entry>
                </row>
                <row>
                  <entry><constant>01</constant></entry>
                  <entry>Interface not selected</entry>
                </row>
                <row>
                  <entry><constant>04</constant></entry>
                  <entry>Paper jam</entry>
                </row>
                <row>
                  <entry><constant>05</constant></entry>
                  <entry>Out of ink</entry>
                </row>
                <row>
                  <entry><constant>06</constant></entry>
                  <entry>Paper out</entry>
                </row>
                <row>
                  <entry><constant>0D</constant></entry>
                  <entry>Paper gap error</entry>
                </row>
                <row>
                  <entry><constant>10</constant></entry>
                  <entry>Maintenance request</entry>
                </row>
                <row>
                  <entry><constant>11</constant></entry>
                  <entry>Tear-off mode selected</entry>
                </row>
                <row>
                  <entry><constant>12</constant></entry>
                  <entry>Double feed error</entry>
                </row>
                <row>
                  <entry><constant>1C</constant></entry>
                  <entry>Cutter position error</entry>
                </row>
                <row>
                  <entry><constant>1D</constant></entry>
                  <entry>Cutter jam</entry>
                </row>
                <row>
                  <entry><constant>1E</constant></entry>
                  <entry>Ink color error</entry>
                </row>
                <row>
                  <entry><constant>23</constant></entry>
                  <entry>Ink combination error</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <literal>IQ</literal> is the amount of ink left, as a
            (decimal!)  percentage expressed in hexadecimal.  The
            values are black, cyan, magenta, and yellow.  6 and 7
            color printers usually specify two or three additional
            values for light cyan, light magenta, and gray.
            However, some low end 6-color printers specify only four
            values.
          </para>
          <para>
            For printers with different ink cartridge options, the
            following additional values may appear:
          </para>
          <table>
            <title>Printer additional ink codes</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="code"/>
              <colspec colnum="2" colname="description"/>
              <thead>
                <row>
                  <entry>Ink code</entry>
                  <entry>Description</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>NA</constant></entry>
                  <entry>Ink cartridge is not inserted</entry>
                </row>
                <row>
                  <entry><constant>RE</constant></entry>
                  <entry>
                    Ink cartridge information cannot be read
                  </entry>
                </row>
                <row>
                  <entry><constant>WE</constant></entry>
                  <entry>
                    Ink cartridge information cannot be written
                  </entry>
                </row>
                <row>
                  <entry><constant>CI</constant></entry>
                  <entry>
                    Ink cartridge is inserted, but has not been read
                  </entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <literal>WR</literal>, if provided, is the warning status:
          </para>
          <table>
            <title>Printer warning codes</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="warning"/>
              <colspec colnum="2" colname="description"/>
              <thead>
                <row>
                  <entry>Warning code</entry>
                  <entry>Description</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>10</constant></entry>
                  <entry>
                    Black ink low (Photo black on printers using
                    UltraChrome&reg; ink)
                  </entry>
                </row>
                <row>
                  <entry><constant>11</constant></entry>
                  <entry>Cyan</entry>
                </row>
                <row>
                  <entry><constant>12</constant></entry>
                  <entry>Magenta</entry>
                </row>
                <row>
                  <entry><constant>13</constant></entry>
                  <entry>Yellow</entry>
                </row>
                <row>
                  <entry><constant>14</constant></entry>
                  <entry>Light cyan (presumably)</entry>
                </row>
                <row>
                  <entry><constant>15</constant></entry>
                  <entry>Light magenta (presumably)</entry>
                </row>
                <row>
                  <entry><constant>17</constant></entry>
                  <entry>
                    Gray (with UltraChrome-compatible printers)
                  </entry>
                </row>
                <row>
                  <entry><constant>18</constant></entry>
                  <entry>Matte black 1 (UltraChrome)</entry>
                </row>
                <row>
                  <entry><constant>19</constant></entry>
                  <entry>Matte black 2 (UltraChrome)</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <literal>RV</literal> is the firmware revision (one byte
            ASCII).
          </para>
          <para>
            <literal>AI</literal> is actuator information.  These
            are two byte ASCII codes that indicate ``ink weight rank
            ID'' of KCMY, respectively.
          </para>
          <para>
          <literal>TC</literal>, if provided, is the total time of
          cleaning or ink filling (?).
          </para>
          <para>
            <literal>RC</literal>, if provided, is the firmware
            revision.
          </para>
          <para>
            <literal>INK:</literal> and <literal>MI</literal> are
            <emphasis>not documented</emphasis>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* SM <varname>BC</varname>=2 00
            <varname>xx</varname></literal></term>
        <listitem>
          <para>
            Set Status Reply Rate.  <varname>xx</varname> is the
            repeat interval in seconds.  If <varname>xx</varname> is
            <constant>0</constant>, the status is returned only when
            the printer's state changes.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* ST <varname>BC</varname>=1
            01</literal></term>
        <listitem>
          <para>
            Reply Printer Status.  The reply is formatted as follows:
          </para>
          <informalexample>
            <screen>@BDC PS\r\nST:<varname>xx</varname>;\f</screen>
          </informalexample>
          <para>
            <literal>\r</literal> is carriage return;
            <literal>\n</literal> is newline; <literal>\f</literal> is
            formfeed).  If <varname>xx</varname> (the reply value) is
            <constant>0</constant> or <constant>2</constant>,
            automatic status update is disabled; if
            <constant>1</constant> or <constant>3</constant>, it is
            enabled.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* SM <varname>BC</varname>=1
            01</literal></term>
        <listitem>
          <para>
            Reply Printer Status Rate.  The reply is formatted as
            follows:
          </para>
          <informalexample>
            <screen>@BDC PS\r\nST:xx;\f</screen>
          </informalexample>
          <para>
            <literal>\r</literal> is carriage return;
            <literal>\n</literal> is newline; <literal>\f</literal> is
            formfeed).  See <literal>SM
              <varname>BC</varname>=2</literal> above for the meaning of
            the return value.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* ??
            <varname>BC</varname>=<varname>xx</varname>
            <varname>y</varname>[1] &hellip;
            <varname>y</varname>[xx]</literal></term>
        <listitem>
          <para>
            Echo Parameters (perhaps better described as Echo
            Commands).  The command string is executed (it would
            appear from the documentation), and the string sent is
            returned using a sequence similar to that described in
            the <literal>ST <varname>BC</varname>=1</literal> and
            <literal>SM <varname>BC</varname>=1</literal> commands.
            Note that in this case the number of bytes is variable!
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* SM <varname>BC</varname>=2 00
            02</literal></term>
        <listitem>
          <para>
            <emphasis>Function unknown</emphasis>.  Used on the STC
            3000 at least when using roll feed.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* JE <varname>BC</varname>=1
            00</literal></term>
        <listitem>
          <para>
            <emphasis>Function unknown</emphasis>.  On new printers
            (STC 740 or newer), this command should be sent after
            all data has been sent.  If this command is not sent,
            and the printer is connected to a Windows system, the
            last page of the job will not print completely.  The
            most likely explanation for for this is that the Windows
            driver typically puts the printer in 1284.4 packet mode,
            and this command has the effect of flushing the buffer
            in the printer.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><literal>* CO <varname>BC</varname>=8 00
            <varname>cutter</varname>[1] <varname>page</varname>[1]
            <varname>unit</varname>[1]
            <varname>position</varname>[4]</literal></term>
        <listitem>
          <para>
            Specify paper cutting on Stylus Photo 2200 (and perhaps
            some other printers).  <varname>cutter</varname> must be
            0.  <varname>page</varname> should be one of the
            following:
          </para>
          <table>
            <title>Paper cutting codes</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="code"/>
              <colspec colnum="2" colname="description"/>
              <thead>
                <row>
                  <entry>Code</entry>
                  <entry>Description</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>0</constant></entry>
                  <entry>All pages</entry>
                </row>
                <row>
                  <entry><constant>1</constant></entry>
                  <entry>First page only</entry>
                </row>
                <row>
                  <entry><constant>2</constant></entry>
                  <entry>Last page only</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            <varname>unit</varname> should be one of the following:
          </para>
          <table>
            <title>Paper cutting units</title>
            <tgroup cols="2" align="left">
              <colspec colnum="1" colname="code"/>
              <colspec colnum="2" colname="description"/>
              <thead>
                <row>
                <entry>Code</entry>
                  <entry>Description</entry>
                </row>
              </thead>
              <tbody>
                <row>
                  <entry><constant>0</constant></entry>
                  <entry>1/360 in.</entry>
                </row>
                <row>
                  <entry><constant>1</constant></entry>
                  <entry>1/720 in.</entry>
                </row>
                <row>
                  <entry><constant>2</constant></entry>
                  <entry>1/1440 in.</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
          <para>
            This command should be used twice.  The first
            <literal>CO</literal> command specifies where the page
            will be cut at the top, and the second specifies where
            the page will be cut at the bottom.  This permits
            cutting both the top and the bottom of the page.
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
  </sect1>
  <sect1>
    <title>Appropriate Remote Commands</title>

    <para>
        All of the remote commands described above are wrapped up with
        the usual boilerplate.  The files always start with
        <literal>00 00 00</literal> and the &ldquo;magic&rdquo;
        command described above, then two <literal>ESC @</literal>s to
        reset the printer.  The remote command sequences come next; if
        they print anything that is usually followed by a
        <literal>FF</literal> (<literal>0C</literal> hex) character to
        feed the page, then the file ends with another two
        <literal>ESC @</literal>s to get back to the ground state.
    </para>
    <para>
        An alignment sequence goes like this:
    </para>
    <orderedlist>
        <listitem>
          <para>
            Host uses <literal>DT</literal> to print an alignment
            sheet.
          </para>
        </listitem>
        <listitem>
          <para>
            User eyeballs the sheet to see which is the best aligned
            pattern.
          </para>
        </listitem>
        <listitem>
          <para>
            Host sends a <literal>DA</literal> command indicating
            which pattern the user chose.
          </para>
        </listitem>
        <listitem>
          <para>
            If the user said &ldquo;realign&rdquo;, meaning he isn't
            done yet, go to step 1.
          </para>
        </listitem>
        <listitem>
          <para>
            We are done: host sends a <literal>SV</literal> command
            and exits.
          </para>
        </listitem>
    </orderedlist>

    <para>
        The sequence used (by the STC 3000, at least) to print from
        the roll feed is (with byte count omitted):
    </para>
    <informalexample>
      <screen>PM 00 00
SN 00 00 00
EX 00 00 00 00 05 01
ST 00 01
SM 00 02</screen>
    </informalexample>
    <para>
        The sequence used by the STP 870 to print on plain paper is
    </para>
    <informalexample>
      <screen>PM 00 00
IR 00 03
SN 00 00 01
SN 00 01 00
SN 00 02 01
EX 00 00 00 00 05 00
FP 00 00 00</screen>
    </informalexample>
    <para>
        and the job finishes with
    </para>
    <informalexample>
      <screen>IR 00 02
LD</screen>
    </informalexample>
    <para>
        For different paper type settings on the STP 870, the
        arguments to <literal>SN</literal> vary.  The arguments to the
        first and third <literal>SN</literal> commands are as outlined
        in the description of the <literal>SN</literal> command above;
        the arguments to the second (&ldquo;platen gap&rdquo;) are
        <literal>00 01 01</literal> for thick papers (&ldquo;matte
        paper&mdash;heavyweight&rdquo;, &ldquo;photo paper&rdquo; and
        &ldquo;premium glossy photo paper&rdquo;) and <literal>00 01
        00</literal> for all others.
    </para>
    <para>
        For roll-mode printing, the STP 870's sequence changes as
        follows.  <literal>IR</literal>'s arguments become <literal>00
        01</literal> in the header, and <literal>00 00</literal> after
        the job, and <literal>EX</literal>'s last argument changes
        from <constant>00</constant> to <constant>01</constant>.
    </para>
    <para>
        For zero-margin printing on the STP 870, the arguments to
        <literal>FP</literal> become <literal>00 0xb0 0xff</literal>.
        This moves the origin about 5.5mm to the left, to a point one
        tenth of an inch to the left of the left-hand edge of the
        paper, allowing printing right up to (and beyond) the edge of
        the paper.  Some printers (at least the STP 870) include white
        absorbent pads at the left margin position and other positions
        (89mm and 100mm on the STP 870) to soak up ink which misses
        the edge of the paper.  Printing off the edge of paper of a
        width not aligned with a pad could result in making a mess of
        the inside of the printer and ink getting on the reverse of
        the paper.
    </para>
  </sect1>
</chapter>
