6502 Opcodes

Posted on

Table of contents

1 Overview

2 Positive and negative numbers

Bytes can hold 256 values: $00 to $FF. If we directly translate that to decimal numbers, we can say a byte can contain the numbers 0 to 255.

For some operations we need negative numbers. This means we now have two kinds of numbers: positive numbers and negative numbers.

To store whether or not a number is negative, we use bit 7. This means that we have one less bit to use for the number itself, which also means that the highest number is no longer 255, but 127, $7F or %01111111.

The good thing is that we now also have negative numbers, the lowest being -128, $80 or %10000000.

3 Flags

P, the processor status register, holds six flags.

N
Negative flag
P-bit 7
Gets set when the last opcode resulted in a negative result or in a result where the last bit got set to 1.
V
Overflow flag
P-bit 6
Gets set when the last bit of a number gets changed while decreasing a negative number or increasing a positive number.
D
Decimal flag
P-bit 3
Can be set with sed or cleared with cld. When set a byte will be used to save 2 decimal digits. The NES does not support this.
I
Interrupt flag
P-bit 2
When set all interrupts other than the non-maskable interrupts are suppressed.
Z
Zero flag
P-bit 1
Gets set when the last opcode resulted in zero.
C
Carry flag
P-bit 0
Gets set when a number over- or underflows, except when the over- or underflow got caused by an increment- or decrement-instruction. It also gets set when bits are shifted.

Bits 4 and 5 are not used.

Some will say there is also a B-flag, on bit 4. This is not true. When P gets pushed to the stack, bit 4 of what is pushed to the stack will be set to 1 if it was pushed on the stack via PHP or BRK and otherwise it will be set to 0. This does not mean that P itself stores anything in bit 4.

When P gets pushed to the stack, bit 5 will always be equal to 1.

The structure of what gets on the stack can be visualised as follows: %NV1BDIZC.

4 Addressing modes

Accumulator
The accumulator is the target. The structure is: OPC A.
Immediate
A static, or immediate, value is the target. The structure is: OPC #$7F.
Implied
There is no target. The structure is: OPC.
Relative
When a singed byte is the target and is used as a relative offset. This is only used for branching. The structure is: OPC $7F.
Absolute, non-indexed
A 16-bit memory-address is the target. The structure is: OPC $7F00.
Absolute, indexed
A 16-bit memory-address is the target. The unsinged value of X or Y will be added to that address to get the used address. The structure is: OPC $7F00, X or OPC $7F00, Y.
Zero page, non-indexed
An 8-bit value is the target. This value will be used as an index for a memory-address in page 0. The structure is: OPC $7F.
Zero page, indexed
An 8-bit value is the target. The unsinged value of X will be added to the value and be used as an index for a memory-address in page 0. The structure is: OPC $7F, X.
Indirect, non-indexed
A 16-bit memory-address is the target. The address given will be used to fetch another address. That new address will be used. The structure is: OPC ($7F00).
Indirect, indexed

A 8-bit value it the target. The behaviour is different based on if X or Y are given.

  • If X is given, X will be added to the value and the result will be used as an index in page 0 for the memory-address to use. The structure is: OPC ($7F, X).
  • If Y is given, The value will be used as an index in page 0 for the stored memory-address. Y will be added to that address to get the memory-address to use. The structure is: OPC ($7F), Y.

5 Sources