<appendix id="ref-link">
    <title>Ophis Command Reference</title>
    <section>
      <title>Command Modes</title>
      <para>
        These mostly follow the <emphasis>MOS Technology 6500
        Microprocessor Family Programming Manual</emphasis>, except
        for the Accumulator mode. Accumulator instructions are written
        and interpreted identically to Implied mode instructions.
      </para>
      <itemizedlist>
        <listitem><para><emphasis>Implied:</emphasis> <literal>RTS</literal></para></listitem>
        <listitem><para><emphasis>Accumulator:</emphasis> <literal>LSR</literal></para></listitem>
        <listitem><para><emphasis>Immediate:</emphasis> <literal>LDA #$06</literal></para></listitem>
        <listitem><para><emphasis>Zero Page:</emphasis> <literal>LDA $7C</literal></para></listitem>
        <listitem><para><emphasis>Zero Page, X:</emphasis> <literal>LDA $7C,X</literal></para></listitem>
        <listitem><para><emphasis>Zero Page, Y:</emphasis> <literal>LDA $7C,Y</literal></para></listitem>
        <listitem><para><emphasis>Absolute:</emphasis> <literal>LDA $D020</literal></para></listitem>
        <listitem><para><emphasis>Absolute, X:</emphasis> <literal>LDA $D000,X</literal></para></listitem>
        <listitem><para><emphasis>Absolute, Y:</emphasis> <literal>LDA $D000,Y</literal></para></listitem>
        <listitem><para><emphasis>(Zero Page Indirect, X):</emphasis> <literal>LDA ($80, X)</literal></para></listitem>
        <listitem><para><emphasis>(Zero Page Indirect), Y:</emphasis> <literal>LDA ($80), Y</literal></para></listitem>
        <listitem><para><emphasis>(Absolute Indirect):</emphasis> <literal>JMP ($A000)</literal></para></listitem>
        <listitem><para><emphasis>Relative:</emphasis> <literal>BNE loop</literal></para></listitem>
        <listitem><para><emphasis>(Absolute Indirect, X):</emphasis> <literal>JMP ($A000, X)</literal> &mdash; Only available with 65C02 extensions</para></listitem>
        <listitem><para><emphasis>(Zero Page Indirect):</emphasis> <literal>LDX ($80)</literal> &mdash; Only available with 65C02 extensions</para></listitem>
      </itemizedlist>
    </section>
    <section>
      <title>Basic arguments</title>
      <para>
        Most arguments are just a number or label. The formats for
        these are below.
      </para>
      <section>
        <title>Numeric types</title>
        <itemizedlist>
          <listitem><para><emphasis>Hex:</emphasis> <literal>$41</literal> (Prefixed with $)</para></listitem>
          <listitem><para><emphasis>Decimal:</emphasis> <literal>65</literal> (No markings)</para></listitem>
          <listitem><para><emphasis>Octal:</emphasis> <literal>0101</literal> (Prefixed with zero)</para></listitem>
          <listitem><para><emphasis>Binary:</emphasis> <literal>%01000001</literal> (Prefixed with %)</para></listitem>
          <listitem><para><emphasis>Character:</emphasis> <literal>'A</literal> (Prefixed with single quote)</para></listitem>
        </itemizedlist>
      </section>
      <section>
        <title>Label types</title>
        <para>
          Normal labels are simply referred to by name. Anonymous
          labels may be referenced with strings of - or + signs (the
          label <literal>-</literal> refers to the immediate
          previous anonymous label, <literal>--</literal> the
          one before that, etc., while <literal>+</literal>
          refers to the next anonymous label), and the special
          label <literal>^</literal> refers to the program
          counter at the start of the current instruction or directive.
        </para>
        <para>
          Normal labels are <emphasis>defined</emphasis> by
          prefixing a line with the label name and then a colon
          (e.g., <literal>label:</literal>).  Anonymous labels
          are defined by prefixing a line with an asterisk
          (e.g., <literal>*</literal>).
        </para>
        <para>
          Temporary labels are only reachable from inside the
          innermost enclosing <literal>.scope</literal>
          statement. They are identical to normal labels in every
          way, except that they start with an underscore.
        </para>
      </section>
      <section>
        <title>String types</title>
        <para>
          Strings are enclosed in double quotation marks. Backslashed
          characters (including backslashes and double quotes) are
          treated literally, so the string <literal>"The man said,
          \"The \\ character is the backslash.\""</literal> produces
          the ASCII sequence for <literal>The man said, "The \
          character is the backslash."</literal>
        </para>
        <para>
          Strings are generally only used as arguments to assembler
          directives&mdash;usually for filenames
          (e.g., <literal>.include</literal>) but also for string
          data (in association with <literal>.byte</literal>).
        </para>
        <para>
          It is legal, though unusual, to attempt to pass a string to
          the other data statements.  This will produces a series of
          words/dwords where all bytes that aren't least-significant
          are zero.  Endianness and size will match what the directive
          itself indicated.
        </para>
      </section>
    </section>
    <section>
      <title>Compound Arguments</title>
      <para>
        Compound arguments may be built up from simple ones, using the
        standard +, -, *, and / operators, which carry the usual
        precedence. Also, the unary operators &gt; and &lt;, which
        bind more tightly than anything else, provide the high and low
        bytes of 16-bit values, respectively.
      </para>
      <para>
        Use brackets [ ] instead of parentheses ( ) when grouping
        arithmetic operations, as the parentheses are needed for the
        indirect addressing modes.
      </para>
      <para>
        Examples:
      </para>
      <itemizedlist>
        <listitem><para><literal>$D000</literal> evaluates to $D000</para></listitem>
        <listitem><para><literal>$D000+32</literal> evaluates to $D020</para></listitem>
        <listitem><para><literal>$D000+$20</literal> also evaluates to $D020</para></listitem>
        <listitem><para><literal>&lt;$D000+32</literal> evaluates to $20</para></listitem>
        <listitem><para><literal>&gt;$D000+32</literal> evaluates to $F0</para></listitem>
        <listitem><para><literal>&gt;[$D000+32]</literal> evaluates to $D0</para></listitem>
        <listitem><para><literal>&gt;[$D000-275]</literal> evaluates to $CE</para></listitem>
      </itemizedlist>
    </section>
    <section>
      <title>Memory Model</title>
      <para>
        In order to properly compute the locations of labels and the
        like, Ophis must keep track of where assembled code will
        actually be sitting in memory, and it strives to do this in a
        way that is independent both of the target file and of the
        target machine.
      </para>
      <section>
        <title>Basic PC tracking</title>
        <para>
          The primary technique Ophis uses is <emphasis>program counter
          tracking</emphasis>. As it assembles the code, it keeps
          track of a virtual program counter, and uses that to
          determine where the labels should go.
        </para>
        <para>
          In the absence of an <literal>.org</literal> directive, it
          assumes a starting PC of zero. <literal>.org</literal>
          is a simple directive, setting the PC to the value
          that <literal>.org</literal> specifies. In the simplest
          case, one <literal>.org</literal> directive appears at the
          beginning of the code and sets the location for the rest of
          the code, which is one contiguous block.
        </para>
       </section>
       <section>
         <title>Basic Segmentation simulation</title>
         <para>
           However, this isn't always practical. Often one wishes to
           have a region of memory reserved for data without actually
           mapping that memory to the file. On some systems (typically
           cartridge-based systems where ROM and RAM are seperate, and
           the target file only specifies the ROM image) this is
           mandatory. In order to access these variables symbolically,
           it's necessary to put the values into the label lookup
           table.
         </para>
         <para>
           It is possible, but inconvenient, to do this
           with <literal>.alias</literal>, assigning a specific
           memory location to each variable. This requires careful
           coordination through your code, and makes creating reusable
           libraries all but impossible.
         </para>
         <para>
           A better approach is to reserve a section at the beginning
           or end of your program, put an <literal>.org</literal>
           directive in, then use the <literal>.space</literal>
           directive to divide up the data area.  This is still a bit
           inconvenient, though, because all variables must be
           assigned all at once. What we'd really like is to keep
           multiple PC counters, one for data and one for code.
         </para>
         <para>
           The <literal>.text</literal>
           and <literal>.data</literal> directives do this.  Each
           has its own PC that starts at zero, and you can switch
           between the two at any point without corrupting the other's
           counter. In this way each function can have
           a <literal>.data</literal> section (filled
           with <literal>.space</literal> commands) and
           a <literal>.text</literal> section (that contains the
           actual code). This lets our library routines be almost
           completely self-contained - we can have one source file
           that could be <literal>.included</literal> by multiple
           projects without getting in anything's way.
         </para>
         <para>
           However, any given program may have its own ideas about
           where data and code go, and it's good to ensure with
           a <literal>.checkpc</literal> at the end of your code
           that you haven't accidentally overwritten code with data or
           vice versa. If your <literal>.data</literal>
           segment <emphasis>did</emphasis> start at zero, it's
           probably wise to make sure you aren't smashing the stack,
           too (which is sitting in the region from $0100 to
           $01FF).
         </para>
         <para>
           If you write code with no segment-defining statements in
           it, the default segment
           is <literal>text</literal>.
         </para>
         <para>
           The <literal>data</literal> segment is designed only
           for organizing labels. As such, errors will be flagged if
           you attempt to actually output information into
           a <literal>data</literal> segment.
         </para>
       </section>
       <section>
         <title>General Segmentation Simulation</title>
         <para>
           One text and data segment each is usually sufficient, but
           for the cases where it is not, Ophis allows for user-defined
           segments. Putting a label
           after <literal>.text</literal>
           or <literal>.data</literal> produces a new segment with
           the specified name.
         </para>
         <para>
           Say, for example, that we have access to the RAM at the low
           end of the address space, but want to reserve the zero page
           for truly critical variables, and use the rest of RAM for
           everything else. Let's also assume that this is a 6510
           chip, and locations $00 and $01 are reserved for the I/O
           port. We could start our program off with:
         </para>
<programlisting>
.data
.org $200
.data zp
.org $2
.text
.org $800
</programlisting>
         <para>
           And, to be safe, we would probably want to end our code
           with checks to make sure we aren't overwriting anything:
         </para>
<programlisting>
.data
.checkpc $800
.data zp
.checkpc $100
</programlisting>
       </section>
     </section>
     <section>
       <title>Macros</title>
       <para>
         Assembly language is a powerful tool&mdash;however, there are
         many tasks that need to be done repeatedly, and with
         mind-numbing minor modifications.  Ophis includes a facility
         for <emphasis>macros</emphasis> to allow this.  Ophis macros
         are very similar in form to function calls in higher level
         languages.
       </para>
       <section>
         <title>Defining Macros</title>
         <para>
           Macros are defined with the <literal>.macro</literal>
           and <literal>.macend</literal> commands.  Here's a
           simple one that will clear the screen on a Commodore
           64:
         </para>
<programlisting>
.macro clr'screen
    lda #147
    jsr $FFD2
.macend
</programlisting>
       </section>
       <section>
         <title>Invoking Macros</title>
         <para>
           To invoke a macro, either use
           the <literal>.invoke</literal> command or backquote the
           name of the routine.  The previous macro may be expanded
           out in either of two ways, at any point in the
           source:
         </para>
         <programlisting>.invoke clr'screen</programlisting>
         <para>or</para>
         <programlisting>`clr'screen</programlisting>
         <para>will work equally well.</para>
       </section>
       <section>
         <title>Passing Arguments to Macros</title>
         <para>
           Macros may take arguments.  The arguments to a macro are
           all of the <quote>word</quote> type, though byte values may
           be passed and used as bytes as well.  The first argument in
           an invocation is bound to the label
           <literal>_1</literal>, the second
           to <literal>_2</literal>, and so on.  Here's a macro
           for storing a 16-bit value into a word pointer:
         </para>
<programlisting>
.macro store16   ; `store16 dest, src
        lda #&lt;_2
        sta _1
        lda #&gt;_2
        sta _1+1
.macend
</programlisting>
         <para>
           Macro arguments behave, for the most part, as if they were
           defined by <literal>.alias</literal>
           commands <emphasis>in the calling context</emphasis>.
           (They differ in that they will not produce duplicate-label
           errors if those names already exist in the calling scope,
           and in that they disappear after the call is
           completed.)
         </para>
       </section>
       <section>
         <title>Features and Restrictions of the Ophis Macro Model</title>
         <para>
           Unlike most macro systems (which do textual replacement),
           Ophis macros evaluate their arguments and bind them into the
           symbol table as temporary labels.  This produces some
           benefits, but it also puts some restrictions on what kinds of
           macros may be defined.
         </para>
         <para>
           The primary benefit of this <quote>expand-via-binding</quote>
           discipline is that there are no surprises in the semantics.
           The expression <literal>_1+1</literal> in the macro above
           will always evaluate to one more than the value that was
           passed as the first argument, even if that first argument is
           some immensely complex expression that an
           expand-via-substitution method may accidentally
           mangle.
         </para>
         <para>
           The primary disadvantage of the expand-via-binding
           discipline is that only fixed numbers of words and bytes
           may be passed.  A substitution-based system could define a
           macro including the line <literal>LDA _1</literal> and
           accept as arguments both <literal>$C000</literal>
           (which would put the value of memory location $C000 into
           the accumulator) and <literal>#$40</literal> (which
           would put the immediate value $40 into the accumulator).
           If you <emphasis>really</emphasis> need this kind of
           behavior, a run a C preprocessor over your Ophis source,
           and use <literal>#define</literal> to your heart's
           content.
         </para>
       </section>
     </section>
     <section>
       <title>Assembler directives</title>
       <para>
         Assembler directives are all instructions to the assembler
         that are not actual instructions. Ophis's set of directives
         follow.
       </para>
       <itemizedlist>
         <listitem>
           <para>
             <literal>.outfile</literal> <emphasis>filename</emphasis>:
             Sets the filename for the output binary if one has not
             already been set. If no name is ever set, the output will
             be written to <literal>ophis.bin</literal>.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.advance</literal> <emphasis>address</emphasis>
             [, <emphasis>filler</emphasis>]: Forces the program
             counter to be <emphasis>address</emphasis>. Unlike
             the <literal>.org</literal>
             directive, <literal>.advance</literal> outputs bytes (the
             value of <emphasis>filler</emphasis>, or zeroes if it is
             unspecified) until the program counter reaches a
             specified address. Attempting
             to <literal>.advance</literal> to a point behind the
             current program counter is an assemble-time error.
         </para>
         </listitem>
         <listitem>
           <para>
             <literal>.alias</literal> <emphasis>label</emphasis> <emphasis>value</emphasis>:
             The .alias directive assigns an arbitrary value to a
             label. This value may be an arbitrary argument, but
             cannot reference any label that has not already been
             defined (this prevents recursive label
             dependencies).
         </para>
         </listitem>
         <listitem>
           <para>
             <literal>.byte</literal> <emphasis>arg</emphasis> [
             , <emphasis>arg</emphasis>, ... ]: Specifies a series of
             arguments, which are evaluated, and strings, which are
             included as raw ASCII data. The final results of these
             arguments must be one byte in size. Seperate constants
             are seperated by comments.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.cbmfloat</literal> <emphasis>string</emphasis>
             [ , <emphasis>string</emphasis>, ... ]: Specifies a
             series of strings, which are interpreted as floating
             point constants, and then included in the 5-byte floating
             point format used by the Commodore BASICs. This format is
             8 bits of exponent, followed by a sign bit and a 31-bit
             big-endian mantissa fraction. (The 1 in front of the
             binary point is presumed to be present.) An exponent of 0
             specifies a constant of 0, and the exponent is shifted up
             by 129 before being stored.
           </para>
           <para>
             Because IEEE-754 doesn't perfectly match the Commodore's
             system, if you wish to precisely replicate individual
             constants that cannot be represented exactly you may have
             better luck with the following program, which will run on
             both the Commodore 64 and VIC-20:
           </para>
<programlisting>
10 CLR:V=0:PV=PEEK(45)+256*PEEK(46)+2
20 INPUT "NUMBER (0 TO QUIT)";V
30 IF V=0 THEN END
40 PRINT ".BYTE";
50 FOR I=0 TO 4
60 IF I>0 THEN PRINT CHR$(157);",";
70 PRINT PEEK(PV+I);:NEXT I:PRINT:GOTO 20
</programlisting>
           <para>This program will print out
           a <literal>.byte</literal> directive for you to include in
           your program to represent that number.</para>
         </listitem>
         <listitem>
           <para>
             <literal>.checkpc</literal> <emphasis>address</emphasis>:
             Ensures that the program counter is less than or equal to
             the address specified, and emits an assemble-time error
             if it is not. <emphasis>This produces no code in the
             final binary - it is there to ensure that linking a large
             amount of data together does not overstep memory
             boundaries.</emphasis>
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.data</literal> <emphasis>[label]</emphasis>:
             Sets the segment to the segment name specified and
             disallows output. If no label is given, switches to the
             default data segment.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.incbin</literal> <emphasis>filename</emphasis>
             [, <emphasis>offset</emphasis>
             [, <emphasis>length</emphasis>]]: Inserts the contents of
             the file specified as binary data. Use it to include
             graphics information, precompiled code, or other
             non-assembler data. You may also optionally specify an
             index to start including from, or a length to only
             include a subset.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.include</literal> <emphasis>filename</emphasis>:
             Includes the entirety of the file specified at that point
             in the program.  Use this to order your final sources, if
             you aren't doing it via the command line.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.org</literal> <emphasis>address</emphasis>:
             Sets the program counter to the address
             specified. <emphasis>This does not emit any code in and
             of itself, nor does it overwrite anything that previously
             existed.</emphasis> If you wish to jump ahead in memory,
             use <literal>.advance</literal>.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.require</literal> <emphasis>filename</emphasis>:
             Includes the entirety of the file specified at that point
             in the program.  Unlike <literal>.include</literal>,
             however, code included with <literal>.require</literal>
             will only be inserted once.
             The <literal>.require</literal> directive is useful for
             ensuring that certain code libraries are somewhere in the
             final binary.  They are also very useful for guaranteeing
             that macro libraries are available.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.space</literal> <emphasis>label</emphasis> <emphasis>size</emphasis>:
             This directive is used to organize global variables. It
             defines the label specified to be at the current location
             of the program counter, and then advances the program
             counter <emphasis>size</emphasis> steps ahead. No actual
             code is produced. This is equivalent to <literal>label:
             .org ^+size</literal>.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.text</literal> <emphasis>[label]</emphasis>:
             Sets the segment to the segment name specified and allows
             output. If no label is given, switches to the default
             text segment.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.word</literal> <emphasis>arg</emphasis> [
             , <emphasis>arg</emphasis>, ... ]:
             Like <literal>.byte</literal>, but values are all treated
             as two-byte values and stored low-end first (as is the
             6502's wont). Use this to create jump tables (an
             unadorned label will evaluate to that label's location)
             or otherwise store 16-bit data.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.dword</literal> <emphasis>arg</emphasis> [
             , <emphasis>arg</emphasis>, ...]:
             Like <literal>.word</literal>, but for 32-bit
             values.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.wordbe</literal> <emphasis>arg</emphasis> [
             , <emphasis>arg</emphasis>, ...]:
             Like <literal>.word</literal>, but stores the value in a
             big-endian format (high byte first).
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.dwordbe</literal> <emphasis>arg</emphasis> [
             , <emphasis>arg</emphasis>, ...]:
             Like <literal>.dword</literal>, but stores the value high
             byte first.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.scope</literal>: Starts a new scope
             block. Labels that begin with an underscore are only
             reachable from within their innermost
             enclosing <literal>.scope</literal>
             statement.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.scend</literal>: Ends a scope block. Makes the
             temporary labels defined since the
             last <literal>.scope</literal> statement unreachable, and
             permits them to be redefined in a new
             scope.
           </para>
         </listitem>
         <listitem>
           <para>
             <literal>.macro</literal> <emphasis>name</emphasis>:
             Begins a macro definition block. This is a scope block
             that can be inlined at arbitrary points
             with <literal>.invoke</literal>. Arguments to the macro
             will be bound to temporary labels with names like
             <literal>_1</literal>, <literal>_2</literal>, etc.
           </para>
         </listitem>
      <listitem>
        <para>
          <literal>.macend</literal>: Ends a macro definition block.
        </para>
      </listitem>
      <listitem>
        <para>
          <literal>.invoke</literal> <emphasis>label</emphasis> [<emphasis>argument</emphasis> [,
          <emphasis>argument</emphasis> ...]]: invokes (inlines) the
          specified macro, binding the values of the arguments to the
          ones the macro definition intends to read.  A shorthand
          for <literal>.invoke</literal> is the name of the macro to
          invoke, backquoted.
        </para>
      </listitem>
    </itemizedlist>
  </section>
</appendix>