16 Addressing Modes and Registers

16.1 Indexed Addressing

So far the X and Y registers have simply been used as counters, but their most important use is in 'indexed addressing'. We have already met two different addressing modes: absolute addressing, as in:

LDA U

where the instruction loads the accumulator with the contents of location U, and immediate addressing as in:

LDA @#21

where the instruction loads the accumulator with the actual value #21.

In indexed addressing one of the index registers, X or Y, is used as an offset which is added to the address specified in the instruction to give the actual address of the data. For example, we can write:

LDA S,X

If X contains zero this instruction will behave just like LDA S. However, if X contains 1 it will load the accumulator with the contents of 'one location further on from S'. In other words it will behave like LDA S+1. Since X can contain any value from 0 to 255, the instruction LDA S,X gives you access to 256 different memory locations. If you are familiar with BASIC's byte vectors you can think of S as the base of a vector, and of X as containing the subscript.

16.1.1 Print Inverted String

The following program uses indexed addressing to print out a string of characters inverted. Recall that a string is held as a sequence of character codes terminated by a #D byte:

10 DIM LL(2),S(64),P(-1)
20 W=#FFF4
30[
40:LL0 LDX @0
50:LL1 LDA S,X
60 CMP @#D
70 BEQ LL2
80 ORA @#20
90 JSR W
100 INX
110 BNE LL1
120:LL2 RTS
130]
140 END

Assemble the program by typing RUN twice, and then try the program by entering:

$S="TEST STRING"
LINK LL0

16.1.2 Index Subroutine

Another useful operation that can easily be performed in a machine-code routine is to look up a character in a string, and return its position in that string. The following subroutine reads in a character, using a call to the OSRDCH read-character routines, and saves in ?F the position of the first occurrence of that character in $T.

1 REM Index Routine
10 DIM RR(3),T(25),F(0),P(-1)
20 R=#FFE3; $T="ABCDEFGH"
30[
160\Look up A in T
165:RR1 STX F; RTS
180:RR0 JSR R; LDX @LEN(T)-1
190:RR2 CMP T,X; BEQ RR1
210 DEX; BPL RR2; BMI RR0
220]
230 END

The routine is entered at RR0, and as it stands it looks for one of the letters A to H.

16.2 Summary of Addressing Modes

The following sections summarise all the addressing modes that are available on the 6502.

16.3 Immediate

When the data for an instruction is known at the time that the program being written, immediate addressing can be used. In immediate addressing the second byte of the instruction contains the actual 8-bit data to be used by the instruction.

The '@' symbol denotes an immediate operand.

LDA @7   A9 07
      V
    A: 07
       
Examples: LDA @M
CPY @J+2

16.4 Absolute

Absolute addressing is used when the effective address, to be used by the instruction, is known at the time the program is being written. In absolute addressing the two bytes following the op-code contain the 16-bit effective address to be used by the instruction.

            Data:
LDA #3010,X   AD 10 31 #3010: 34
            V
          A: 34
Examples: LDA K
SBC #3010

16.5 Zero Page

Zero page addressing is like absolute addressing in that the instruction specifies the effective address to be used by the instruction, but only the lower byte of the address is specified in the instruction. The upper byte of the address is assumed to be zero, so only addresses in page zero, from #0000 to #00FF, can be addressed. The assembler will automatically produce zero-page instructions when possible.

          Data:
LDA #80   A5 80 #0080: 34
          V
        A: 34
Examples: BIT #80
ASL #9A

16.6 Indexed Addressing

Indexed addressing is used to access a table of memory locations by specifying them in terms of an offset from a base address. The base address is known at the time that the program is written; the offset, which is provided in one of the index registers, can be calculated by the program.

In all indexed addressing modes one of the 8-bit index registers, X and Y, is used in a calculation of the effective address to be used by the instruction. Five different indexed addressing modes are available, and are listed in the following section.

16.6.1 Absolute,X – Absolute,Y

The simplest indexed addressing mode is absolute indexed addressing. In this mode the two bytes following the instruction specify a 16-bit address which is to be added to one of the index registers to form the effective address to be used by the instruction:

LDA #3120,X   BD 20 31   Data:
          + = #3132: 78
      X: 12   V
          A: 78
Examples: LDA M,X 
          LDX J,Y
          INC N,X

16.6.2 Zero,X

In zero,X indexed addressing the second byte of the instruction specifies an 8-bit address which is added to the X-register to give a zero-page address to be used by the instruction.

Note that in the case of the LDX instruction a zero,Y addressing mode is provided instead of the zero,X mode.

LDA #80,X   B6 80   Data:
        + = #0082: 78
    X: 12   V
        A: 78
Examples: LSR #80,X LDX #82,Y

16.7 Indirect Addressing

It is sometimes necessary to use an address which is actually computed when the program runs, rather than being an offset from a base address or a constant address. In this case indirect addressing is used.
The indirect mode of addressing is available for the JMP instruction. Thus control can be transferred to an address calculated at the time that the program is run.

Examples: JMP (#2800)
          JMP (#80)

For the dual-operand instructions ADC, AND, CMP, EOR, LDA, ORA, SEC, and STA, two different modes of indirect addressing are provided: pre-indexed indirect, and post-indexed indirect. Pure indirect addressing can be obtained, using either mode, by first setting the respective index register to zero.

16.7.1 Pre-Indexed Indirect

This mode of addressing is used when a table of effective addresses is provided in page zero; the X index register is used as a pointer to select one of these addresses from the table.

In pre-indexed indirect addressing the second byte of the instruction is added to the X register to give an address in page zero. The two bytes at this page zero address are then used as the effective address for the instruction.

LDA (#70,X)   A1 70           Data:
        + = #0075: 23 30   #3023: AC
    X: 05           V
                A: AC
Examples: STA (J,X) 
          EOR (#60,X)	

16.7.2 Post-Indexed Indirect

This indexed addressing mode is like the absolute,X or absolute,Y indexed addressing modes, except that in this case the base address of the table is provided in page zero, rather than in the bytes following the instruction. The second byte of the instruction specifies the page-zero base address.

In post-indexed indirect addressinq the second byte of the instruction specifies a page zero address. The two bytes at this address are added to the Y index register to give a 16-bit address which is then used as the effective address for the instruction.

LDA (#70),Y   A1 70 #0070: 43 35     Data:
              += #3553: 23
          Y: 10     V
                A: 23
Examples: CMP (J),Y 
          ADC (066),Y	

16.8 Registers

This section gives a short description of all the 6502's registers:

Accumulator – A

8-bit general-purpose register, which forms one operand in all the arithmetic and logical instructions.

Index Register – X

8-bit register used as the offset in indexed and pre-indexed indirect addressing modes, or as a counter.

Index Register – Y

8-bit register used as the offset in indexed and post-indexed indirect addressing modes.

Status Register – S

8-bit register containing status flags and interrupt mask:

Bit    
0 Carry flag (C) Set if a carry occurs during an add operation;
cleared if a borrow occurs during a subtract operation;
used as a ninth bit in the shift and rotate instructions.
1 Zero flag (Z) Set if the result of an operation is zero; cleared otherwise.
2 Interrupt disable (I) If set, disables the effect of the IRQ interrupt.
Is set by the processor during interrupts.
3 Decimal mode flag (0) If set, the add and subtract operations work
in binary-coded-decimal arithmetic;
if clear, the add and subtract operations work
in binary arithmetic.
4 Break command (B) Set by the processor during a BRK interrupt; otherwise cleared.
5 Unused  
6 Overflow flag (V) Set if a carry occurred from bit 6 during an add operation;
cleared if a borrow occurred to bit 6 in a subtract operation.
7 Negative flag (N) Set if bit 7 of the result of an operation is set; otherwise cleared.

Stack Pointer – SP

8-bit register which forms the lower byte of the address of the next free stack location; the upper byte of this address is always #01.

Program Counter – PC

16-bit register which always contains the address of the next instruction to be fetched by the processor.

Next chapter