Register sizes in ca65

When the 65c816's registers switch between being 8-bit and 16-bit, that affects how the processor expects instructions with immediate operands to be stored. For example, when the 65c816 encounters opcode  (which is  ) the current size of the accumulator determines if it will try to read one or two bytes after the opcode. This creates a problem for assemblers - they have to know whether to encode  as   or. If they get it wrong, the processor will misinterpret the instruction, then probably become misaligned with the code and misinterpret following instructions as well.

Because of this, some assemblers require the programmer to explicitly write the size per-instruction. ca65 works differently - the programmer specifies that a section of code uses a particular size. This is done with the,  ,  , and   directives. These tell ca65 that for all instructions after that point, the accumulator ( / ) or index registers ( / ) are the size given in the directive name.

.a8      ; Assembles to... lda #1   ; A9 01 cmp #1   ; C9 01

.a16 lda #1   ; A9 01 00 cmp #1   ; C9 01 00

.i8 ldx #1   ; A2 01 cpx #1   ; E0 01

.i16 ldx #1   ; A2 01 00 cpx #1   ; E0 01 00

It's a good idea to specify the register sizes at the start of a routine, which adds documentation but also means the routine doesn't rely on the registers being sized correctly by previous code.

ca65 has a "smart" mode (enabled with ) which causes   and   instructions to additionally act like the size changing directives. (Smart mode also will attempt to convert /  to  /  for "far" procedures.)

Detecting register sizes in macros
Macros can check the current register size with  and   - which will return 8 or a 16. This lets the programmer avoid having separate 8-bit and 16-bit versions of macros.

.macro neg .if .asize = 8 eor #$ff .else eor #$ffff .endif ina .endmacro
 * Calculate 0-Accumulator