M68HC11 and M68HC12 Dependent Features
**************************************

M68HC11 and M68HC12 Options
===========================

The Motorola 68HC11 and 68HC12 version of AS have a few machine dependent options.

-m68hc11
     This option switches the assembler in the M68HC11 mode. In this mode, the assembler only accepts 68HC11 operands and mnemonics. It produces code for the 68HC11.

-m68hc12
     This option switches the assembler in the M68HC12 mode. In this mode, the assembler also accepts 68HC12 operands and mnemonics. It produces code for the 68HC12. A few 68HC11 instructions are replaced by some 68HC12 instructions as recommended by Motorola specifications.

-m68hcs12
     This option switches the assembler in the M68HCS12 mode.  This mode is similar to -m68hc12 but specifies to assemble for the 68HCS12 series.  The only difference is on the assembling of the movb and movw instruction when a PC-relative operand is used.

-mshort
     This option controls the ABI and indicates to use a 16-bit integer ABI. It has no effect on the assembled instructions. This is the default.

-mlong
     This option controls the ABI and indicates to use a 32-bit integer ABI.

-mshort-double
     This option controls the ABI and indicates to use a 32-bit float ABI. This is the default.

-mlong-double
     This option controls the ABI and indicates to use a 64-bit float ABI.

--strict-direct-mode
     You can use the --strict-direct-mode option to disable the automatic translation of direct page mode addressing into extended mode when the instruction does not support direct mode. For example, the clr instruction does not support direct page mode addressing. When it is used with the direct page mode, AS will ignore it and generate an absolute addressing. This option prevents AS from doing this, and the wrong usage of the direct page mode will raise an error.

--short-branches
     The --short-branches option turns off the translation of relative branches into absolute branches when the branch offset is out of range. By default AS transforms the relative branch (bsr, bgt, bge, beq, bne, ble, blt, bhi, bcc, bls, bcs, bmi, bvs, bvs, bra) into an absolute branch when the offset is out of the -128 .. 127 range. In that case, the bsr instruction is translated into a jsr, the bra instruction is translated into a jmp and the conditional branches instructions are inverted and followed by a jmp. This option disables these translations and AS will generate an error if a relative branch is out of range. This option does not affect the optimization associated to the jbra, jbsr and jbXX pseudo opcodes.

--force-long-branches
     The --force-long-branches option forces the translation of relative branches into absolute branches. This option does not affect the optimization associated to the jbra, jbsr and jbXX pseudo opcodes.

--print-insn-syntax
     You can use the --print-insn-syntax option to obtain the syntax description of the instruction when an error is detected.

--print-opcodes
     The --print-opcodes option prints the list of all the instructions with their syntax. The first item of each line represents the instruction name and the rest of the line indicates the possible operands for that instruction. The list is printed in alphabetical order. Once the list is printed AS exits.

--generate-example
     The --generate-example option is similar to --print-opcodes but it generates an example for each instruction instead.

Syntax
======

In the M68HC11 syntax, the instruction name comes first and it may be followed by one or several operands (up to three). Operands are separated by comma (,). In the normal mode, AS will complain if too many operands are specified for a given instruction. In the MRI mode (turned on with -M option), it will treat them as comments. Example:

     inx
     lda  #23
     bset 2,x #4
     brclr *bot #8 foo

The presence of a ; character or a ! character anywhere on a line indicates the start of a comment that extends to the end of that line.

A * or a # character at the start of a line also introduces a line comment, but these characters do not work elsewhere on the line.  If the first character of the line is a # then as well as starting a comment, the line could also be logical line number directive (see Comments) or a preprocessor control command (see Preprocessing).

The M68HC11 assembler does not currently support a line separator character.

The following addressing modes are understood for 68HC11 and 68HC12:

Immediate
     #NUMBER

Address Register
     NUMBER,X, NUMBER,Y

     The NUMBER may be omitted in which case 0 is assumed.

Direct Addressing mode
     *SYMBOL, or *DIGITS

Absolute
     SYMBOL, or DIGITS

The M68HC12 has other more complex addressing modes. All of them are supported and they are represented below:

Constant Offset Indexed Addressing Mode
     NUMBER,REG

     The NUMBER may be omitted in which case 0 is assumed. The register can be either X, Y, SP or PC.  The assembler will use the smaller post-byte definition according to the constant value (5-bit constant offset, 9-bit constant offset or 16-bit constant offset).  If the constant is not known by the assembler it will use the 16-bit constant offset post-byte and the value will be resolved at link time.

Offset Indexed Indirect
     [NUMBER,REG]

     The register can be either X, Y, SP or PC.

Auto Pre-Increment/Pre-Decrement/Post-Increment/Post-Decrement
     NUMBER,-REG NUMBER,+REG NUMBER,REG- NUMBER,REG+

     The number must be in the range -8..+8 and must not be 0. The register can be either X, Y, SP or PC.

Accumulator Offset
     ACC,REG

     The accumulator register can be either A, B or D. The register can be either X, Y, SP or PC.

Accumulator D offset indexed-indirect
     [D,REG]

     The register can be either X, Y, SP or PC.

For example:

     ldab 1024,sp
     ldd [10,x]
     orab 3,+x
     stab -2,y-
     ldx a,pc
     sty [d,sp]

Symbolic Operand Modifiers
==========================

The assembler supports several modifiers when using symbol addresses in 68HC11 and 68HC12 instruction operands.  The general syntax is the following:

     %modifier(symbol)

%addr
     This modifier indicates to the assembler and linker to use the 16-bit physical address corresponding to the symbol.  This is intended to be used on memory window systems to map a symbol in the memory bank window. If the symbol is in a memory expansion part, the physical address corresponds to the symbol address within the memory bank window. If the symbol is not in a memory expansion part, this is the symbol address (using or not using the %addr modifier has no effect in that case).

%page
     This modifier indicates to use the memory page number corresponding to the symbol.  If the symbol is in a memory expansion part, its page number is computed by the linker as a number used to map the page containing the symbol in the memory bank window.  If the symbol is not in a memory expansion part, the page number is 0.

%hi
     This modifier indicates to use the 8-bit high part of the physical address of the symbol.

%lo
     This modifier indicates to use the 8-bit low part of the physical address of the symbol.

For example a 68HC12 call to a function foo_example stored in memory expansion part could be written as follows:

     call %addr(foo_example),%page(foo_example)

and this is equivalent to

     call foo_example

And for 68HC11 it could be written as follows:

     ldab #%page(foo_example)
     stab _page_switch
     jsr  %addr(foo_example)

Assembler Directives
====================

The 68HC11 and 68HC12 version of AS have the following specific assembler directives:

.relax
     The relax directive is used by the GNU Compiler to emit a specific relocation to mark a group of instructions for linker relaxation. The sequence of instructions within the group must be known to the linker so that relaxation can be performed.

.mode [mshort|mlong|mshort-double|mlong-double]
     This directive specifies the ABI.  It overrides the -mshort, -mlong, -mshort-double and -mlong-double options.

.far SYMBOL
     This directive marks the symbol as a far symbol meaning that it uses a call/rtc calling convention as opposed to jsr/rts. During a final link, the linker will identify references to the far symbol and will verify the proper calling convention.

.interrupt SYMBOL
     This directive marks the symbol as an interrupt entry point. This information is then used by the debugger to correctly unwind the frame across interrupts.

.xrefb SYMBOL
     This directive is defined for compatibility with the Specification for Motorola 8 and 16-Bit Assembly Language Input Standard and is ignored.

Floating Point
==============

Packed decimal (P) format floating literals are not supported. Feel free to add the code!

The floating point formats generated by directives are these.

.float
     Single precision floating point constants.

.double
     Double precision floating point constants.

.extend
.ldouble
     Extended precision (long double) floating point constants.

Opcodes
=======

Branch Improvement
------------------

Certain pseudo opcodes are permitted for branch instructions. They expand to the shortest branch instruction that reach the target. Generally these mnemonics are made by prepending j to the start of Motorola mnemonic. These pseudo opcodes are not affected by the --short-branches or --force-long-branches options.

The following table summarizes the pseudo-operations.

                             Displacement Width
          +-------------------------------------------------------------+
          |                     Options                                 |
          |    --short-branches           --force-long-branches         |
          +--------------------------+----------------------------------+
       Op |BYTE             WORD     | BYTE          WORD               |
          +--------------------------+----------------------------------+
      bsr | bsr <pc-rel>    <error>  |               jsr <abs>          |
      bra | bra <pc-rel>    <error>  |               jmp <abs>          |
     jbsr | bsr <pc-rel>   jsr <abs> | bsr <pc-rel>  jsr <abs>          |
     jbra | bra <pc-rel>   jmp <abs> | bra <pc-rel>  jmp <abs>          |
      bXX | bXX <pc-rel>    <error>  |               bNX +3; jmp <abs>  |
     jbXX | bXX <pc-rel>   bNX +3;   | bXX <pc-rel>  bNX +3; jmp <abs>  |
          |                jmp <abs> |                                  |
          +--------------------------+----------------------------------+
     XX: condition
     NX: negative of condition XX

jbsr
jbra
     These are the simplest jump pseudo-operations; they always map to one particular machine instruction, depending on the displacement to the branch target.

jbXX
     Here, jbXX stands for an entire family of pseudo-operations, where XX is a conditional branch or condition-code test.  The full list of pseudo-ops in this family is:

           jbcc   jbeq   jbge   jbgt   jbhi   jbvs   jbpl  jblo
           jbcs   jbne   jblt   jble   jbls   jbvc   jbmi

     For the cases of non-PC relative displacements and long displacements, AS issues a longer code fragment in terms of NX, the opposite condition to XX.  For example, for the non-PC relative case:

              jbXX foo

     gives

               bNXs oof
               jmp foo
           oof: