The 6502 processor had quite a few addressing modes for its time.
name            abbr    len time formula for N  example
implied         impl    1   2    ---            tay
immediate       imm     2   2    arg            ora #$f0
zero page       dp      2   3    *arg           cmp $56
zero page,x     d,x     2   4    *(arg+x & $ff) adc $56,x
zero page,y     d,y     2   4    *(arg+y & $ff) ldx $56,y
absolute        abs     3   4    *arg           eor $3456
absolute,x      a,x     3   4i   *(arg+x)       and $3456,x
absolute,y      a,y     3   4i   *(arg+y)       sbc $3456,y
indirect,x      (d,x)   2   6    **(arg+x)      lda ($34,x)
indirect,y      (d),y   2   5i   *(*arg+y)      sta ($34),y
relative        rel     2   2tc  *(PC+arg)      beq loop

Zero page refers to the first 256 bytes of memory. But on later 6502 family processors such as WDC's 65C816, the zero page instructions instead access the "direct page" (thus the abbreviation "dp"), whose base address can be moved anywhere in the first 64 KB of RAM, with a one-cycle penalty if the base of the direct page doesn't lie on a 256-byte boundary.

  • t: add a cycle if the branch is taken
  • c: add a cycle for crossing 256-byte boundaries
  • i: add a cycle except on reads not crossing 256-byte boundaries
  • Always add two cycles for atomic read-modify-write instructions (inc, dec, asl, lsr, rol, ror, 65c02 tsb, and 65c02 trb).

Some instructions have their own addressing modes. These are explained in each instruction's writeup.

Addressing modes d,x d,y (d,x) and (d,y) wrap around inside the zero page. For example:

  ldx #$ff
  lda $80,x
This will load from $007f instead of $017f. If you take advantage of this, please COMMENT IT!

The original 6502 has a small bug (or feature) that wraps the vector that jmp (a) pulls inside a 256-byte area. See 6502 indirect JMP bug for more explanation.

PC-relative instructions count from the END of the instruction they're in.

See also: 6502 instructions
Return to NES programming