This chapter documents the backend for the Motorola 6809, 68HC12 and Hitachi 6309.

Legal
=====

This module is written in 2020-2021 by Frank Wille and is covered by the vasm copyright without modifications.

Additional options for this module
==================================

This module provides the following additional options:

-6809
     Generate code for the 6809 CPU (default setting). Also works on the 6309, which is backwards compatible.

-6309
     Generate code for the 6309 CPU.

-68hc12
     Generate code for the 68HC12 CPU.

-opt-branch
     Translate short-branches to long and optimize long-branches to short when required/possible. Also tries to optimize jmp and jsr instructions into short-branches.

-opt-offset
     Delete zero offsets in indexed addressing modes, when possible.

-opt-pc
     Convert all extended addressing modes with local or external labels to indexed, PC-relative addressing. Also translates absolute jmp/jsr instructions into PC-relative lbra/lbsr (or better).

General
=======

This backend accepts 6809/6309 instructions as described in the Motorola 6809 and Hitachi 6309 Programmer's Reference (Copyright 2009 Darren Atkinson). Optionally supports the 68HC12 instruction set as documented in Motorola's CPU12 Reference Manual.

The target address type is 16 bit.

Instructions consist of one up to six bytes and require no alignment. There is also no alignment requirement for sections and data.

Extensions
==========

The backend supports the unary operators < and > to either select the size of an addressing mode or the LSB/MSB of a 16-bit word.

  - When direct or extended addressing modes are applicable, < enforces direct mode and > enforces extended mode.

  - For indexed, PC-relative addressing modes < enforces an 8-bit offset, while > enforces a 16-bit offset.

  - For all other indexed addressing modes with a constant offset < enforces an 8-bit offset and > enforces a 16-bit offset.

  - For immediate addressing modes or data constants < selects the LSB of a word and > selects the MSB.

  - When applying the operation /256, %256 or &256 on a label in immediate addressing modes or data constants, an appropriate lo/hi-byte relocation will automatically be generated.

In absence of < or > vasm selects the best addressing mode possible, i.e. the one which requires the least amount of memory when the symbol value is known, or the one which allows the largest symbol values, when it is unknown at assembly time.

This backend extends the selected syntax module by the following directives:

setdp <expr>
     Set the current base address of the direct page. It is used to decide whether an extended addressing mode can be optimized to direct addressing. No effect for 68HC12.

direct <symbol>
     Tell the assembler to use direct addressing for expressions based on this symbol.

Optimizations
=============

This backend performs the following operand optimizations:

  - Short-branches (Bcc) are optionally translated into long-branches (LBcc) when their destination is undefined, in a different section or out of range. Note that there is no LBSR on the HC12.

  - Long-branches (LBcc) are optionally optimized into short-branches (Bcc) when possible.

  - Optionally optimize JMP into BRA and JSR into BSR when possible (same section, distance representable in 8 bits).

  - Optionally translate JMP into LBRA and JSR into LBSR (-opt-pc).

  - Optionally translate all extended addressing, referring to local or external labels, to an indexed, PC-relative addressing mode (-opt-pc).

  - Optionally optimize indexed addressing modes with a constant zero offset into a no-offset addressing mode, which executes faster. Not possible on the HC12.

  - Always select the shortest indexed addressing mode for constant offsets, unless externally defined.

Known Problems
==============

Some known problems of this module at the moment:

  - PC-relative addressing modes in MOVx instructions may be wrong. Needs testing.

Error Messages
==============

This module has the following error messages:

  - 2001: trailing garbage in operand

  - 2002: ] expected for indirect addressing mode

  - 2003: missing valid index register

  - 2004: pc-relative offset out of range: %ld

  - 2005: constant offset out of range: %ld

  - 2006: bad auto decrement/increment value: %d

  - 2007: indirect addressing not allowed

  - 2008: auto increment/decrement not allowed

  - 2009: short branch out of range: %ld

  - 2010: long branch out of range: %ld

  - 2011: decrement branch out of range: %ld

  - 2012: data size %d not supported

  - 2013: data expression doesn't fit into %d bits

  - 2014: illegal bit number specification: %d

  - 2015: omitted offset taken as 5-bit zero offset

  - 2016: immediate expression doesn't fit into %d bits

  - 2017: directive ignored as selected CPU has no DP register

  - 2018: double size modifier ignored

  - 2019: addressing mode not supported