Instruction reference

From NESdev Wiki
Jump to navigationJump to search
Official 6502 Instructions
ADC AND ASL BCC BCS BEQ BIT BMI BNE BPL BRK BVC BVS CLC
CLD CLI CLV CMP CPX CPY DEC DEX DEY EOR INC INX INY JMP
JSR LDA LDX LDY LSR NOP ORA PHA PHP PLA PLP ROL ROR RTI
RTS SBC SEC SED SEI STA STX STY TAX TAY TSX TXA TXS TYA

Official instructions by type

Type Instructions
Access LDA STA LDX STX LDY STY
Transfer TAX TXA TAY TYA
Arithmetic ADC SBC INC DEC INX DEX INY DEY
Shift ASL LSR ROL ROR
Bitwise AND ORA EOR BIT
Compare CMP CPX CPY
Branch BCC BCS BEQ BNE BPL BMI BVC BVS
Jump JMP JSR RTS BRK RTI
Stack PHA PLA PHP PLP TXS TSX
Flags CLC SEC CLI SEI CLD SED CLV
Other NOP

Official instructions

ADC - Add with Carry

A = A + memory + C

ADC adds the carry flag and a memory value to the accumulator. The carry flag is then set to the carry value coming out of bit 7, allowing values larger than 1 byte to be added together by carrying the 1 into the next byte's addition. This can also be thought of as unsigned overflow. It is common to clear carry with CLC before adding the first byte to ensure it is in a known state, avoiding an off-by-one error. The overflow flag indicates whether signed overflow or underflow occurred. This happens if both inputs are positive and the result is negative, or both are negative and the result is positive.

Flag New value Notes
C - Carry result > $FF If the result overflowed past $FF (wrapping around), unsigned overflow occurred.
Z - Zero result == 0
V - Overflow (result ^ A) & (result ^ memory) & $80 If the result's sign is different from both A's and memory's, signed overflow (or underflow) occurred.
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $69 2 2
Zero Page $65 2 3
Zero Page,X $75 2 4
Absolute $6D 3 4
Absolute,X $7D 3 4 (5 if page crossed)
Absolute,Y $79 3 4 (5 if page crossed)
(Indirect,X) $61 2 6
(Indirect),Y $71 2 5 (6 if page crossed)

See also: SBC, CLC


AND - Bitwise AND

A = A & memory

This ANDs a memory value and the accumulator, bit by bit. If both input bits are 1, the resulting bit is 1. Otherwise, it is 0.

AND truth table
A memory result
0 0 0
0 1 0
1 0 0
1 1 1
Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $29 2 2
Zero Page $25 2 3
Zero Page,X $35 2 4
Absolute $2D 3 4
Absolute,X $3D 3 4 (5 if page crossed)
Absolute,Y $39 3 4 (5 if page crossed)
(Indirect,X) $21 2 6
(Indirect),Y $31 2 5 (6 if page crossed)

See also: ORA, EOR


ASL - Arithmetic Shift Left

value = value << 1, or visually: C <- [76543210] <- 0

ASL shifts all of the bits of a memory value or the accumulator one position to the left, moving the value of each bit into the next bit. Bit 7 is shifted into the carry flag, and 0 is shifted into bit 0. This is equivalent to multiplying an unsigned value by 2, with carry indicating overflow.

This is a read-modify-write instruction, meaning that its addressing modes that operate on memory first write the original value back to memory before the modified value. This extra write can matter if targeting a hardware register.

Flag New value
C - Carry value bit 7
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Accumulator $0A 1 2
Zero Page $06 2 5
Zero Page,X $16 2 6
Absolute $0E 3 6
Absolute,X $1E 3 7

See also: LSR, ROL, ROR


BCC - Branch if Carry Clear

PC = PC + 2 + memory (signed)

If the carry flag is clear, BCC branches to a nearby location by adding the relative offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when carry is set with BCS.

The carry flag has different meanings depending on the context. BCC can be used after a compare to branch if the register is less than the memory value, so it is sometimes called BLT for Branch if Less Than. It can also be used after ADC to branch if the value wrapped around or SBC to branch if it did not.

Addressing mode Opcode Bytes Cycles
Relative $90 2 2 (3 if branch taken, 4 if page crossed)

See also: BCS, JMP


BCS - Branch if Carry Set

PC = PC + 2 + memory (signed)

If the carry flag is set, BCS branches to a nearby location by adding the branch offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when carry is clear with BCC.

The carry flag has different meanings depending on the context. BCS can be used after a compare to branch if the register is greater than or equal to the memory value, so it is sometimes called BGE for Branch if Greater Than or Equal. It can also be used after SBC to branch if the value wrapped around or ADC to branch if it did not.

Addressing mode Opcode Bytes Cycles
Relative $B0 2 2 (3 if branch taken, 4 if page crossed)

See also: BCC, JMP


BEQ - Branch if Equal

PC = PC + 2 + memory (signed)

If the zero flag is set, BEQ branches to a nearby location by adding the branch offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when zero is clear with BNE.

Comparison uses this flag to indicate if the compared values are equal. All instructions that change A, X, or Y also implicitly set or clear the zero flag depending on whether the register becomes 0.

Addressing mode Opcode Bytes Cycles
Relative $F0 2 2 (3 if branch taken, 4 if page crossed)

See also: BNE, JMP


BIT - Bit Test

A & memory

BIT modifies flags, but does not change memory or registers. The zero flag is set depending on the result of the accumulator AND memory value, effectively applying a bitmask and then checking if any bits are set. Bits 7 and 6 of the memory value are loaded directly into the negative and overflow flags, allowing them to be easily checked without having to load a mask into A.

Because BIT only changes CPU flags, it is sometimes used to trigger the read side effects of a hardware register without clobbering any CPU registers, or even to waste cycles as a 3-cycle NOP. As an advanced trick, it is occasionally used to hide a 1- or 2-byte instruction in its operand that is only executed if jumped to directly, allowing two code paths to be interleaved. However, because the instruction in the operand is treated as an address from which to read, this carries risk of triggering side effects if it reads a hardware register. This trick can be useful when working under tight constraints on space, time, or register usage.

Flag New value
Z - Zero result == 0
V - Overflow memory bit 6
N - Negative memory bit 7
Addressing mode Opcode Bytes Cycles
Zero page $24 2 3
Absolute $2C 3 4

See also: AND


BMI - Branch if Minus

PC = PC + 2 + memory (signed)

If the negative flag is set, BMI branches to a nearby location by adding the branch offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when negative is clear with BPL.

All instructions that change A, X, or Y implicitly set or clear the negative flag based on bit 7 (the sign bit).

Addressing mode Opcode Bytes Cycles
Relative $30 2 2 (3 if branch taken, 4 if page crossed)

See also: BPL, JMP


BNE - Branch if Not Equal

PC = PC + 2 + memory (signed)

If the zero flag is clear, BNE branches to a nearby location by adding the branch offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when negative is set with BEQ.

Comparison uses this flag to indicate if the compared values are equal. All instructions that change A, X, or Y also implicitly set or clear the zero flag depending on whether the register becomes 0.

Addressing mode Opcode Bytes Cycles
Relative $D0 2 2 (3 if branch taken, 4 if page crossed)

See also: BEQ, JMP


BPL - Branch if Plus

PC = PC + 2 + memory (signed)

If the negative flag is clear, BPL branches to a nearby location by adding the branch offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when negative is set with BMI.

All instructions that change A, X, or Y implicitly set or clear the negative flag based on bit 7 (the sign bit).

Addressing mode Opcode Bytes Cycles
Relative $10 2 2 (3 if branch taken, 4 if page crossed)

See also: BMI, JMP


BRK - Break (software IRQ)

push PC + 2 to stack
push NV11DIZC flags to stack
PC = ($FFFE)

BRK triggers an interrupt request (IRQ). IRQs are normally triggered by external hardware, and BRK is the only way to do it in software. Like a typical IRQ, it pushes the current program counter and processor flags to the stack, sets the interrupt disable flag, and jumps to the IRQ handler. Unlike a typical IRQ, it sets the break flag in the flags byte that is pushed to the stack (like PHP) and it triggers an interrupt even if the interrupt disable flag is set. Notably, the return address that is pushed to the stack skips the byte after the BRK opcode. For this reason, BRK is often considered a 2-byte instruction with an unused immediate.

Unfortunately, a 6502 bug allows the BRK IRQ to be overridden by an NMI occurring at the same time. In this case, only the NMI handler is called; the IRQ handler is skipped. However, the break flag is still set in the flags byte pushed to the stack, so the NMI handler can detect that this occurred (albeit slowly) by checking this flag.

Because BRK uses the value $00, any byte in a programmable ROM can be overwritten with a BRK instruction to send execution to an IRQ handler. This is useful for patching one-time programmable ROMs. BRK can also be used as a system call mechanism, and the unused byte can be used by software as an argument (although it is inconvenient to access). In the context of NES games, BRK is often most useful as a crash handler, where the unused program space is filled with $00 and the IRQ handler displays debugging information or otherwise handles the crash in a clean way.

Flag New value Notes
I - Interrupt disable 1 This is set to 1 after the old flags are pushed to the stack. The effect of changing this flag is not delayed.
B - Break Pushed as 1 This flag exists only in the flags byte pushed to the stack, not as real state in the CPU.
Addressing mode Opcode Bytes Cycles Notes
Implied $00 1 7 Although BRK only uses 1 byte, its return address skips the following byte.
#Immediate $00 2 7 Because BRK skips the following byte, it is often considered a 2-byte instruction.

See also: RTI, PHP


BVC - Branch if Overflow Clear

PC = PC + 2 + memory (signed)

If the overflow flag is clear, BVC branches to a nearby location by adding the branch offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when overflow is set with BVS.

Unlike zero, negative, and even carry, overflow is modified by very few instructions. It is most often used with the BIT instruction, particularly for polling hardware registers. It is also sometimes used for signed overflow with ADC and SBC. The standard 6502 chip allows an external device to set overflow using a pin, enabling software to poll for that event, but this is not present on the NES' 2A03.

Addressing mode Opcode Bytes Cycles
Relative $50 2 2 (3 if branch taken, 4 if page crossed)

See also: BVS, JMP


BVS - Branch if Overflow Set

PC = PC + 2 + memory (signed)

If the overflow flag is set, BVS branches to a nearby location by adding the branch offset to the program counter. The offset is signed and has a range of [-128, 127] relative to the first byte after the branch instruction. Branching further than that requires using a JMP instruction, instead, and branching over that JMP when overflow is clear with BVC.

Unlike zero, negative, and even carry, overflow is modified by very few instructions. It is most often used with the BIT instruction, particularly for polling hardware registers. It is also sometimes used for signed overflow with ADC and SBC. The standard 6502 chip allows an external device to set overflow using a pin, enabling software to poll for that event, but this is not present on the NES' 2A03 CPU.

Addressing mode Opcode Bytes Cycles
Relative $70 2 2 (3 if branch taken, 4 if page crossed)

See also: BVC, JMP


CLC - Clear Carry

C = 0

CLC clears the carry flag. In particular, this is usually done before adding the low byte of a value with ADC to avoid adding an extra 1.

Flag New value
C - Carry 0
Addressing mode Opcode Bytes Cycles
Implied $18 1 2

See also: SEC


CLD - Clear Decimal

D = 0

CLD clears the decimal flag. The decimal flag normally controls whether binary-coded decimal mode (BCD) is enabled, but this mode is permanently disabled on the NES' 2A03 CPU. However, the flag itself still functions and can be used to store state.

Flag New value
D - Decimal 0
Addressing mode Opcode Bytes Cycles
Implied $D8 1 2

See also: SED


CLI - Clear Interrupt Disable

I = 0

CLI clears the interrupt disable flag, enabling the CPU to handle hardware IRQs. The effect of changing this flag is delayed one instruction because the flag is changed after IRQ is polled, allowing the next instruction to execute before any pending IRQ is detected and serviced. This flag has no effect on NMI, which (as the "non-maskable" name suggests) cannot be ignored by the CPU.

Flag New value Notes
I - Interrupt disable 0 The effect of changing this flag is delayed 1 instruction.
Addressing mode Opcode Bytes Cycles
Implied $58 1 2

See also: SEI


CLV - Clear Overflow

V = 0

CLV clears the overflow flag. There is no corresponding SEV instruction; instead, setting overflow is exposed on the 6502 CPU as a pin controlled by external hardware, and not exposed at all on the NES' 2A03 CPU.

Flag New value
V - Overflow 0
Addressing mode Opcode Bytes Cycles
Implied $B8 1 2

CMP - Compare A

A - memory

CMP compares A to a memory value, setting flags as appropriate but not modifying any registers. The comparison is implemented as a subtraction, setting carry if there is no borrow, zero if the result is 0, and negative if the result is negative. However, carry and zero are often most easily remembered as inequalities.

Note that comparison does not affect overflow.

Flag New value
C - Carry A >= memory
Z - Zero A == memory
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $C9 2 2
Zero Page $C5 2 3
Zero Page,X $D5 2 4
Absolute $CD 3 4
Absolute,X $DD 3 4 (5 if page crossed)
Absolute,Y $D9 3 4 (5 if page crossed)
(Indirect,X) $C1 2 6
(Indirect),Y $D1 2 5 (6 if page crossed)

See also: CPX, CPY


CPX - Compare X

X - memory

CPX compares X to a memory value, setting flags as appropriate but not modifying any registers. The comparison is implemented as a subtraction, setting carry if there is no borrow, zero if the result is 0, and negative if the result is negative. However, carry and zero are often most easily remembered as inequalities.

Note that comparison does not affect overflow.

Flag New value
C - Carry X >= memory
Z - Zero X == memory
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $E0 2 2
Zero Page $E4 2 3
Absolute $EC 3 4

See also: CMP, CPY


CPY - Compare Y

Y - memory

CPY compares Y to a memory value, setting flags as appropriate but not modifying any registers. The comparison is implemented as a subtraction, setting carry if there is no borrow, zero if the result is 0, and negative if the result is negative. However, carry and zero are often most easily remembered as inequalities.

Note that comparison does not affect overflow.

Flag New value
C - Carry Y >= memory
Z - Zero Y == memory
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $C0 2 2
Zero Page $C4 2 3
Absolute $CC 3 4

See also: CMP, CPX


DEC - Decrement Memory

memory = memory - 1

DEC subtracts 1 from a memory location. Notably, there is no version of this instruction for the accumulator; ADC or SBC must be used, instead.

This is a read-modify-write instruction, meaning that it first writes the original value back to memory before the modified value. This extra write can matter if targeting a hardware register.

Note that decrement does not affect carry nor overflow.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Zero Page $C6 2 5
Zero Page,X $D6 2 6
Absolute $CE 3 6
Absolute,X $DE 3 7

See also: INC, ADC, SBC


DEX - Decrement X

X = X - 1

DEX subtracts 1 from the X register. Note that it does not affect carry nor overflow.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $CA 1 2

See also: INX


DEY - Decrement Y

Y = Y - 1

DEY subtracts 1 from the Y register. Note that it does not affect carry nor overflow.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $88 1 2

See also: INY


EOR - Bitwise Exclusive OR

A = A ^ memory

EOR exclusive-ORs a memory value and the accumulator, bit by bit. If the input bits are different, the resulting bit is 1. If they are the same, it is 0. This operation is also known as XOR.

6502 doesn't have bitwise NOT instruction, but using EOR with value $FF has the same behavior, inverting every bit of the other value. In fact, EOR can be thought of as NOT with a bitmask; all of the 1 bits in one value have the effect of inverting the corresponding bit in the other value, while 0 bits do nothing.

EOR truth table
A memory result
0 0 0
0 1 1
1 0 1
1 1 0
Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $49 2 2
Zero Page $45 2 3
Zero Page,X $55 2 4
Absolute $4D 3 4
Absolute,X $5D 3 4 (5 if page crossed)
Absolute,Y $59 3 4 (5 if page crossed)
(Indirect,X) $41 2 6
(Indirect),Y $51 2 5 (6 if page crossed)

See also: AND, ORA


INC - Increment Memory

memory = memory + 1

INC adds 1 to a memory location. Notably, there is no version of this instruction for the accumulator; ADC or SBC must be used, instead.

This is a read-modify-write instruction, meaning that it first writes the original value back to memory before the modified value. This extra write can matter if targeting a hardware register.

Note that increment does not affect carry nor overflow.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Zero Page $E6 2 5
Zero Page,X $F6 2 6
Absolute $EE 3 6
Absolute,X $FE 3 7

See also: DEC, ADC, SBC


INX - Increment X

X = X + 1

INX adds 1 to the X register. Note that it does not affect carry nor overflow.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $E8 1 2

See also: DEX


INY - Increment Y

Y = Y + 1

INY adds 1 to the Y register. Note that it does not affect carry nor overflow.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $C8 1 2

See also: DEY


JMP - Jump

PC = memory

JMP sets the program counter to a new value, allowing code to execute from a new location. If you wish to be able to return from that location, JSR should normally be used, instead.

The indirect addressing mode uses the operand as a pointer, getting the new 2-byte program counter value from the specified address. Unfortunately, because of a CPU bug, if this 2-byte variable has an address ending in $FF and thus crosses a page, then the CPU fails to increment the page when reading the second byte and thus reads the wrong address. For example, JMP ($03FF) reads $03FF and $0300 instead of $0400. Care should be taken to ensure this variable does not cross a page.

Addressing mode Opcode Bytes Cycles
Absolute $4C 3 3
(Indirect) $6C 3 5

See also: JSR


JSR - Jump to Subroutine

push PC + 2 to stack
PC = memory

JSR pushes the current program counter to the stack and then sets the program counter to a new value. This allows code to call a function and return with RTS back to the instruction after the JSR.

Notably, the return address on the stack points 1 byte before the start of the next instruction, rather than directly at the instruction. This is because RTS increments the program counter before the next instruction is fetched. This differs from the return address pushed by interrupts and used by RTI, which points directly at the next instruction.

Addressing mode Opcode Bytes Cycles
Absolute $20 3 6

See also: RTS, JMP, RTI


LDA - Load A

A = memory

LDA loads a memory value into the accumulator.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $A9 2 2
Zero Page $A5 2 3
Zero Page,X $B5 2 4
Absolute $AD 3 4
Absolute,X $BD 3 4 (5 if page crossed)
Absolute,Y $B9 3 4 (5 if page crossed)
(Indirect,X) $A1 2 6
(Indirect),Y $B1 2 5 (6 if page crossed)

See also: STA


LDX - Load X

X = memory

LDX loads a memory value into the X register.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $A2 2 2
Zero Page $A6 2 3
Zero Page,Y $B6 2 4
Absolute $AE 3 4
Absolute,Y $BE 3 4 (5 if page crossed)

See also: STX


LDY - Load Y

Y = memory

LDX loads a memory value into the Y register.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $A0 2 2
Zero Page $A4 2 3
Zero Page,X $B4 2 4
Absolute $AC 3 4
Absolute,X $BC 3 4 (5 if page crossed)

See also: STY


LSR - Logical Shift Right

value = value >> 1, or visually: 0 -> [76543210] -> C

LSR shifts all of the bits of a memory value or the accumulator one position to the right, moving the value of each bit into the next bit. 0 is shifted into bit 7, and bit 0 is shifted into the carry flag. This is equivalent to dividing an unsigned value by 2 and rounding down, with the remainder in carry.

This is a read-modify-write instruction, meaning that its addressing modes that operate on memory first write the original value back to memory before the modified value. This extra write can matter if targeting a hardware register.

Flag New value
C - Carry value bit 0
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Accumulator $4A 1 2
Zero Page $46 2 5
Zero Page,X $56 2 6
Absolute $4E 3 6
Absolute,X $5E 3 7

See also: ASL, ROL, ROR


NOP - No Operation

NOP has no effect; it merely wastes space and CPU cycles. This instruction can be useful when writing timed code to delay for a desired amount of time, as padding to ensure something does or does not cross a page, or to disable code in a binary.

Addressing mode Opcode Bytes Cycles
Implied $EA 1 2

ORA - Bitwise OR

A = A | memory

ORA inclusive-ORs a memory value and the accumulator, bit by bit. If either input bit is 1, the resulting bit is 1. Otherwise, it is 0.

OR truth table
A memory result
0 0 0
0 1 1
1 0 1
1 1 1
Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $09 2 2
Zero Page $05 2 3
Zero Page,X $15 2 4
Absolute $0D 3 4
Absolute,X $1D 3 4 (5 if page crossed)
Absolute,Y $19 3 4 (5 if page crossed)
(Indirect,X) $01 2 6
(Indirect),Y $11 2 5 (6 if page crossed)

See also: AND, EOR


PHA - Push A

($0100 + SP) = A
SP = SP - 1

PHA stores the value of A to the current stack position and then decrements the stack pointer.

Addressing mode Opcode Bytes Cycles
Implied $48 1 3

See also: PLA


PHP - Push Processor Status

($0100 + SP) = NV11DIZC
SP = SP - 1

PHP stores a byte to the stack containing the 6 status flags and B flag and then decrements the stack pointer. The B flag and extra bit are both pushed as 1. The bit order is NV1BDIZC (high to low).

Flag New value Notes
B - Break Pushed as 1 This flag exists only in the flags byte pushed to the stack, not as real state in the CPU.
Addressing mode Opcode Bytes Cycles
Implied $08 1 3

See also: PLP


PLA - Pull A

SP = SP + 1
A = ($0100 + SP)

PLA increments the stack pointer and then loads the value at that stack position into A.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $68 1 4

See also: PHA


PLP - Pull Processor Status

SP = SP + 1
NVxxDIZC = ($0100 + SP)

PLP increments the stack pointer and then loads the value at that stack position into the 6 status flags. The bit order is NVxxDIZC (high to low). The B flag and extra bit are ignored. Note that the effect of changing I is delayed one instruction because the flag is changed after IRQ is polled, delaying the effect until IRQ is polled in the next instruction like with CLI and SEI.

Flag New value Notes
C - Carry result bit 0
Z - Zero result bit 1
I - Interrupt disable result bit 2 The effect of changing this flag is delayed 1 instruction.
D - Decimal result bit 3
V - Overflow result bit 6
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $28 1 4

See also: PHP


ROL - Rotate Left

value = value << 1 through C, or visually: C <- [76543210] <- C

ROL shifts a memory value or the accumulator to the left, moving the value of each bit into the next bit and treating the carry flag as though it is both above bit 7 and below bit 0. Specifically, the value in carry is shifted into bit 0, and bit 7 is shifted into carry. Rotating left 9 times simply returns the value and carry back to their original state.

This is a read-modify-write instruction, meaning that its addressing modes that operate on memory first write the original value back to memory before the modified value. This extra write can matter if targeting a hardware register.

Flag New value
C - Carry value bit 7
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Accumulator $2A 1 2
Zero Page $26 2 5
Zero Page,X $36 2 6
Absolute $2E 3 6
Absolute,X $3E 3 7

See also: ROR, ASL, LSR


ROR - Rotate Right

value = value >> 1 through C, or visually: C -> [76543210] -> C

ROR shifts a memory value or the accumulator to the right, moving the value of each bit into the next bit and treating the carry flag as though it is both above bit 7 and below bit 0. Specifically, the value in carry is shifted into bit 7, and bit 0 is shifted into carry. Rotating right 9 times simply returns the value and carry back to their original state.

This is a read-modify-write instruction, meaning that its addressing modes that operate on memory first write the original value back to memory before the modified value. This extra write can matter if targeting a hardware register.

Flag New value
C - Carry value bit 0
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Accumulator $6A 1 2
Zero Page $66 2 5
Zero Page,X $76 2 6
Absolute $6E 3 6
Absolute,X $7E 3 7

See also: ROL, ASL, LSR


RTI - Return from Interrupt

pull NVxxDIZC flags from stack
pull PC from stack

RTI returns from an interrupt handler, first pulling the 6 status flags from the stack and then pulling the new program counter. The flag pulling behaves like PLP except that changes to the interrupt disable flag apply immediately instead of being delayed 1 instruction. This is because the flags change before IRQs are polled for the instruction, not after. The PC pulling behaves like RTS except that the return address is the exact address of the next instruction instead of 1 byte before it.

Flag New value Notes
C - Carry pulled flags bit 0
Z - Zero pulled flags bit 1
I - Interrupt disable pulled flags bit 2 The effect of changing this flag is not delayed.
D - Decimal pulled flags bit 3
V - Overflow pulled flags bit 6
N - Negative pulled flags bit 7
Addressing mode Opcode Bytes Cycles
Implied $40 1 6

See also: BRK, PLP, RTS


RTS - Return from Subroutine

pull PC from stack
PC = PC + 1

RTS pulls an address from the stack into the program counter and then increments the program counter. It is normally used at the end of a function to return to the instruction after the JSR that called the function. However, RTS is also sometimes used to implement jump tables (see Jump table and RTS Trick).

Addressing mode Opcode Bytes Cycles
Implied $60 1 6

See also: JSR, PLA


SBC - Subtract with Carry

A = A - memory - ~C, or equivalently: A = A + ~memory + C

SBC subtracts a memory value and the bitwise NOT of carry from the accumulator. It does this by adding the bitwise NOT of the memory value using ADC. This implementation detail explains the backward nature of carry; SBC subtracts 1 more when carry is clear, not when it's set, and carry is cleared when it underflows and set otherwise. As with ADC, carry allows the borrow from one subtraction to be carried into the next subtraction, allowing subtraction of values larger than 1 byte. It is common to set carry with SEC before subtracting the first byte to ensure it is in a known state, avoiding an off-by-one error.

Overflow works the same as with ADC, except with an inverted memory value. Therefore, overflow or underflow occur if the result's sign is different from A's and the same as the memory value's.

Flag New value Notes
C - Carry ~(result < $00) If the result underflowed below $00 (wrapping around), unsigned underflow occurred.
Z - Zero result == 0
V - Overflow (result ^ A) & (result ^ ~memory) & $80 If result's sign is different from A's and the same as memory's, signed overflow (or underflow) occurred.
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
#Immediate $E9 2 2
Zero Page $E5 2 3
Zero Page,X $F5 2 4
Absolute $ED 3 4
Absolute,X $FD 3 4 (5 if page crossed)
Absolute,Y $F9 3 4 (5 if page crossed)
(Indirect,X) $E1 2 6
(Indirect),Y $F1 2 5 (6 if page crossed)

See also: ADC, SEC


SEC - Set Carry

C = 1

SEC sets the carry flag. In particular, this is usually done before subtracting the low byte of a value with SBC to avoid subtracting an extra 1.

Flag New value
C - Carry 1
Addressing mode Opcode Bytes Cycles
Implied $38 1 2

See also: CLC


SED - Set Decimal

D = 1

SED sets the decimal flag. The decimal flag normally controls whether binary-coded decimal mode (BCD) is enabled, but this mode is permanently disabled on the NES' 2A03 CPU. However, the flag itself still functions and can be used to store state.

Flag New value
D - Decimal 1
Addressing mode Opcode Bytes Cycles
Implied $F8 1 2

See also: CLD


SEI - Set Interrupt Disable

I = 1

SEI sets the interrupt disable flag, preventing the CPU from handling hardware IRQs. The effect of changing this flag is delayed one instruction because the flag is changed after IRQ is polled, allowing an IRQ to be serviced between this and the next instruction if the flag was previously 0.

Flag New value Notes
I - Interrupt disable 1 The effect of changing this flag is delayed 1 instruction.
Addressing mode Opcode Bytes Cycles
Implied $78 1 2

See also: CLI


STA - Store A

memory = A

STA stores the accumulator value into memory.

Addressing mode Opcode Bytes Cycles
Zero Page $85 2 3
Zero Page,X $95 2 4
Absolute $8D 3 4
Absolute,X $9D 3 5
Absolute,Y $99 3 5
(Indirect,X) $81 2 6
(Indirect),Y $91 2 6

See also: LDA


STX - Store X

memory = X

STX stores the X register value into memory.

Addressing mode Opcode Bytes Cycles
Zero Page $86 2 3
Zero Page,Y $96 2 4
Absolute $8E 3 4

See also: LDX


STY - Store Y

memory = Y

STY stores the Y register value into memory.

Addressing mode Opcode Bytes Cycles
Zero Page $84 2 3
Zero Page,X $94 2 4
Absolute $8C 3 4

See also: LDY


TAX - Transfer A to X

X = A

TAX copies the accumulator value to the X register.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $AA 1 2

See also: TXA, TAY, TYA


TAY - Transfer A to Y

Y = A

TAY copies the accumulator value to the Y register.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $A8 1 2

See also: TYA, TAX, TXA


TSX - Transfer Stack Pointer to X

X = SP

TSX copies the stack pointer value to the X register.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $BA 1 2

See also: TXS


TXA - Transfer X to A

A = X

TXA copies the X register value to the accumulator.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $8A 1 2

See also: TAX, TAY, TYA


TXS - Transfer X to Stack Pointer

SP = X

TXS copies the X register value to the stack pointer.

Addressing mode Opcode Bytes Cycles
Implied $9A 1 2

See also: TXS


TYA - Transfer Y to A

A = Y

TYA copies the Y register value to the accumulator.

Flag New value
Z - Zero result == 0
N - Negative result bit 7
Addressing mode Opcode Bytes Cycles
Implied $98 1 2

See also: TAY, TAX, TXA