This chapter documents the backend for the MOS/Rockwell 6502 microprocessor family. It also supports the Rockwell/WDC 65C02, the Hudson Soft HuC6280 and the WDC 65802/65816 instruction sets.

Legal
=====

This module is written in 2002,2006,2008-2012,2014-2023 by Frank Wille and is covered by the vasm copyright without modifications.

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

This module provides the following additional options:

-6280
     Recognize all HuC6280 instructions.

-802
     Same as -816. There is no difference in the instruction set.

-816
     Enables the 8/16 bit instruction set for the WDC65816/65802 and additional directives to switch loading of the accumulator and/or the index register between 8 and 16 bits. The target address size is 24 bits.

-bbcade
     Swap meaning of < and > unary operators for compatibility with the BBC ADE assembler.

-c02
     Recognize all 65C02 instructions. This excludes DTV (-dtv) and illegal (-illegal) instructions.

-ce02
     Enables the Commodore CSG65CE02 instruction set, which extends on the WDC02 instruction set.

-dtv
     Recognize the three additional C64-DTV instructions.

-illegal
     Allow 'illegal' 6502 instructions to be recognized.

-mega65
     Enables the 45GS02 instruction set for the MEGA65 computer.

-opt-branch
     Enables translation of B<cc> branches into sequences of B<!cc> *+5 ; JMP label when necessary. BRA (DTV, 65C02) is directly translated into a JMP when out of range. It also performs optimization of JMP to BRA, whenever possible.

-wdc02
     Recognize all 65C02 instructions and the WDC65C02 extensions (RMB,SMB,BBR,BBS,STP,WAI).

General
=======

This backend accepts 6502 family instructions as described in the instruction set reference manuals from MOS and Rockwell, which are valid for the following CPUs: 6502 - 6518, 6570, 6571, 6702, 7501, 8500, 8502.

Optionally accepts 65C02 family instructions as described in the instruction set reference manuals from Rockwell and WDC. Also supports the WDC extensions in the W65C02 and W65C134.

Optionally accepts 65CE02 family instructions as described in the instruction set reference manuals from Commodore Semiconductor Group.

Optionally accepts HuC6280 instructions as described in the instruction set reference manuals from Hudson Soft.

Optionally accepts 45GS02 instructions as defined by the Mega65 project.

Optionally accepts WDC65816 insructions as described in the Programming Manual by The Western Design Center.

The target address type is 16 bits, or 24 bits in WDC65816 mode.

Instructions consist of one up to three bytes for the standard 6502 family (up to 7 bytes for the 6280) and require no alignment. There is also no alignment requirement for sections and data.

All known mnemonics for illegal instructions are optionally recognized (e.g. dcm and dcp refer to the same instruction). Some illegal insructions (e.g. $ab) are known to show unpredictable behaviour, or do not always work the same on different CPUs.

Note that the WDC65816 MVN and MVP block move instructions require a full 24-bit address (or a label) for the source and destination, as documented in WDC's Programming Manual. This assembler additionally allows to specify the bank byte directly, which is triggered by a constant value between 0 and 255.

Extensions
==========

This backend provides the following specific extensions:

  - The parser understands a lo/hi-modifier to select low- or high-byte of a 16-bit word. The character < is used to select the low-byte and > for the high-byte. It has to be the first character before an expression. See also option -bbcade. In WDC65816 mode the character ^ can be used to select the bank-byte (bits 16 to 23) of a full 24 bit address.

  - When applying the operation >>8, /256, %256 or &256 on a label, an appropriate lo/hi-byte relocation will automatically be generated.

  - The hi/lo-modifier can also be used in front of absolute addressing modes, to enforce absolute 16-bit addressing (hi/>) or zero/direct-page 8-bit addressing (lo/<). In WDC65816 mode the > character selects full 24-bit addressing instead, and ! or | may be used to enforce 16-bit addressing.

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

<symbol> ezp <expr>
     Works exactly like the equ directive, but marks <symbol> as a zero page symbol and use zero page addressing whenever <symbol> is used in a memory addressing mode.

a8
     Declares that immediate instructions loading the accumulator read 8 bits (default, WDC65816 only).

a16
     Declares that immediate instructions loading the accumulator read 16 bits (WDC65816 only).

setdp <expr>
     Set the current base address of the zero/direct page for optimizations from absolute to zero-page addressing modes. Example: set it to $2000 for the HuC6280/PC-Engine.

x8
     Declares that immediate instructions loading the index registers read 8 bits (default, WDC65816 only).

x16
     Declares that immediate instructions loading the index registers read 16 bits (WDC65816 only).

zero
     Switch to a zero page section called zero or .zero, which has the type bss with attributes "aurw". Accesses to symbols from this section will default to zero page addressing mode.

zpage <symbol1> [,<symbol2>...]
     Mark symbols as zero page and use zero page addressing for expressions based on this symbol, unless overridden by a hi-modifier (>).

All these directives are also available in the form starting with a dot (.).

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

This backend performs the following operand optimizations and translations:

  - Absolute addressing modes are optimized to zero-page (or direct-page) addressing modes, whenever possible.

  - An absolute addressing mode will be promoted to long addressing (24 bits) for the WDC65816, when needed.

  - Conditional branches, where the destination is out of range, are translated into B<!cc> *+5 and an absolute JMP instruction (-opt-branch).

  - Some CPUs also allow optimization of JMP to BRA, when -opt-branch was given.

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

Some known problems of this module at the moment:

  - None?

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

This module has the following error messages:

  - 2001: instruction not supported on selected architecture

  - 2002: trailing garbage in operand

  - 2003: addressing mode selector ignored

  - 2004: data size %d not supported

  - 2005: relocation does not allow hi/lo modifier

  - 2006: operand doesn't fit into %d bits

  - 2007: branch destination out of range

  - 2008: illegal bit number

  - 2009: identifier expected

  - 2010: multiple hi/lo modifiers

  - 2011: zero/direct-page addressing not available

  - 2012: operand not in zero/direct-page range

  - 2013: absolute-long addressing not available