NES Emulator: Addressing Modes

In this post, I would like to provide a summary of the different addressing modes on the CPU that our NES emulator is based off: the 8-bit 6502 microprocessor. This CPU utilizes a 16-bit memory address space, meaning there are 2^16 (65,536) bytes available for memory addresses, 0x0000 to 0xFFFF. Every execution cycle, the CPU will fetch an 8-bit operation code (opcode) from this memory space. The opcode will let us know what assembly instruction to execute. Many of these assembly instructions require an operand to work with, and this operand is indicated by the 1 or 2 bytes immediately following the opcode in memory. Some instructions do not require any operands, however, so just having a the opcode is sufficient. Therefore, instructions will either require 1, 2, or 3 bytes of data. When the CPU fetches an opcode, it not only decodes the assembly instruction but also an addressing mode that will determine the number of bytes needed for operands. There are 13 such addressing modes:

  1. Implied
    • 1 byte instruction
    • The operand is implied by the assembly instruction, such as clearing or setting bits in the processor status register.
    • 2-3 cycles
  2. Accumulator
    • Used for instructions that bit shift or rotate the accumulator
    • 1 byte instruction
    • Accumulator register is implied
    • 2 cycles
  3. Immediate
    • 2 byte instruction
      • 1st byte: opcode
      • 2nd byte: constant value often used for testing or comparing
    • 2 cycles
  4. Absolute
    • 3 byte instruction
      • 1st byte: opcode
      • 2nd byte: contains low order byte of address that holds the operand data
      • 3rd byte: contains high order byte of address that holds the operand data
    • 3-4 cycles
  5. Absolute, X
    • variation of Absolute mode where the value in the X register is added to the address that holds the operand data
  6. Absolute, Y
    • variation of Absolute mode where the value in the Y register is added to the address that holds the operand data
  7. Zero Page
    • 2 byte instruction
      • 1st byte: opcode
      • 2nd byte: contains the address in zero page memory that holds the operand
    • Zero page addressing is similar to absolute, but is meant to require one less cycle. Imagine that memory is segmented as blocks (pages) of 256 bytes. Thus, there would be 256 pages in total memory space for this CPU: 256 pages * 256 bytes = 65,536 bytes. What zero page addressing does is tell the CPU that the operand address will be located on the first page, i.e. page zero. All addresses that make up the first 256 bytes of memory have a high order bit of 0x00. The CPU will know it’s a zero page address based on the opcode, and will automatically use 0x00 as the high order bit of the operand address. This saves the CPU one cycle.
    • 3 cycles
  8. Zero Page, X
    • A variation of Zero Page, where the value in the X register is added to the zero page address from the instruction. If adding the X register value to the zero page address causes the address to go beyond the zero page and into the next page, the high bye of the final address is still 0x00. For example, if X = 0x10 and zero page address is 0xFF, adding them together would yield 0x010F. The address used by this instruction would then be 0x000F, ignoring the 0x01 high order bit.
  9. Zero Page, Y
    • Similar to Zero Page, X, but uses the value from the Y register.
  10. Indirect, X
    • Indirect addresses are used when the memory addresses used for instructions are only known at runtime and can’t be hard-coded. For example, they may be calculated at various cycles and change frequently.
    • 2 byte instruction
      • 1st byte: opcode
      • 2nd byte: zero page address
        • The value in the X register is added to the zero page address
        • This new zero page address is not used to fetch the operand, but instead is a pointer to another memory location. The first byte of memory stored at zero page address is the low order byte of a new address, and the byte immediately following is the high order byte. This new address is then what holds the operand data.
        • Note, the zero page address will always remain a zero page address even if it rolls over after adding X.
    • 6 cycles
  11. (Indirect,) Y
    • 2 byte instruction
      • 1st byte: opcode
      • 2nd byte: zero page address
        • This zero page address is not used to fetch the operand, but instead is a pointer to another memory location. The first byte of memory stored at zero page address is the low order byte of a new address, and the byte immediately following is the high order byte.
        • The value in the Y register is added to this new address. This new address is then what holds the operand data.
    • 6 cycles
  12. Absolute Indirect
    • This applies only to the JMP instruction
    • 3 byte instruction
      • 1st byte: opcode
      • 2nd byte: high order byte of address
      • 3rd byte: low order byte of address
    • The value stored at the byte located at this address is the low order byte of a new address, and the next byte is the high order byte of a new address. This new address is then added to the program counter and execution jumps there.
    • 5 cycles
  13. Relative
    • 2 byte instruction
      • 1st byte: opcode
      • 2nd byte: signed value from -128 to 127, i.e. one byte.
        • This byte is then added to or subtracted from the program counter address, thus moving the program counter forwards by 127 or backwards by 128. Program execution then jumps to this new address.
    • This mode is only used in branching instructions.
    • 2 cycle

*Source: http://users.telenet.be/kim1-6502/6502/proman.html#411

Print Friendly, PDF & Email

Leave a comment

Your email address will not be published.