6502 assembly reference
Every legal NMOS 6502 instruction, plus the assembler directives, understood by the built-in assembly editor. This one reference covers every 6502 machine Basically supports — the Commodore 64, VIC-20 and PET, the BBC Micro and Master, the Acorn Atom, the Apple I, the Apple II and II Plus, and the Atari 800 and 400 all share the identical instruction set and assembler syntax. What differs between them is only the memory map (where a block may live and the entry points you call), which stays on each machine's own hardware page.
Use the search box to filter by mnemonic, the buttons to show only Instructions or Directives, and the Name / Kind headers to re-sort. The 151 documented opcodes are listed here; illegal/undocumented opcodes are not assembled and disassemble back as DB data.
Instruction Directive
| Syntax & description | |
|---|---|
ADC | ADC #n / ADC $nn / ADC $nnnn,X …Add memory to the accumulator with carry: A ← A + M + C. Sets N V Z C. There is no add-without-carry, so clear carry (CLC) before the first ADC. |
AND | AND #n / AND $nn …Bitwise AND of memory into the accumulator (A ← A & M). Sets N and Z. |
ASL | ASL A / ASL $nn …Arithmetic shift left of A or memory: bit 7 → carry, 0 → bit 0 (a multiply by two). Sets N Z C. |
BCC | BCC labelBranch if carry clear (C = 0). Relative, −128…+127 bytes from the next instruction. |
BCS | BCS labelBranch if carry set (C = 1). Common after a compare to test "greater or equal" (unsigned). |
BEQ | BEQ labelBranch if equal — taken when the zero flag is set (Z = 1). |
BIT | BIT $nn / BIT $nnnnTest bits: AND A with memory to set Z, and copy memory bits 7 and 6 into N and V. A and the memory are left unchanged. |
BMI | BMI labelBranch if minus — taken when the negative flag is set (N = 1). |
BNE | BNE labelBranch if not equal — taken when the zero flag is clear (Z = 0). |
BPL | BPL labelBranch if plus — taken when the negative flag is clear (N = 0). |
BRK | BRKForce a software interrupt: push PC and status, set the interrupt-disable flag and vector through $FFFE. A one-byte instruction that skips the following byte. |
BVC | BVC labelBranch if overflow clear (V = 0). |
BVS | BVS labelBranch if overflow set (V = 1). |
CLC | CLCClear the carry flag. Do this before the first ADC of a multi-byte addition. |
CLD | CLDClear the decimal-mode flag, returning ADC/SBC to binary arithmetic. |
CLI | CLIClear the interrupt-disable flag, allowing maskable IRQs to be serviced. |
CLV | CLVClear the overflow flag (V ← 0). |
CMP | CMP #n / CMP $nn …Compare the accumulator with memory by computing A − M and setting N Z C (A is unchanged). C set means A ≥ M (unsigned); Z means equal. |
CPX | CPX #n / CPX $nn / CPX $nnnnCompare the X register with memory (X − M), setting N Z C. X is unchanged. |
CPY | CPY #n / CPY $nn / CPY $nnnnCompare the Y register with memory (Y − M), setting N Z C. Y is unchanged. |
DB | DB n[,n…]Define byte(s) — emit each comma-separated operand as a single byte at the current address. Used for data tables and text. |
DEC | DEC $nn / DEC $nnnn,X …Decrement a memory location by one (M ← M − 1). Sets N and Z. The NMOS 6502 has no DEC A. |
DEX | DEXDecrement the X register by one. Sets N and Z. |
DEY | DEYDecrement the Y register by one. Sets N and Z. |
DS | DS nDefine storage — reserve n zero-filled bytes at the current address, advancing the location counter. |
DW | DW nn[,nn…]Define word(s) — emit each operand as a little-endian 16-bit value (low byte first), the way the 6502 stores addresses. |
EOR | EOR #n / EOR $nn …Bitwise exclusive-OR of memory into the accumulator (A ← A ^ M). Sets N and Z. |
INC | INC $nn / INC $nnnn,X …Increment a memory location by one (M ← M + 1). Sets N and Z. The NMOS 6502 has no INC A. |
INX | INXIncrement the X register by one. Sets N and Z. |
INY | INYIncrement the Y register by one. Sets N and Z. |
JMP | JMP $nnnn / JMP ($nnnn)Unconditional jump. The indirect form JMP ($nnnn) reads the target from memory (mind the NMOS page-boundary bug when the pointer ends in $FF). |
JSR | JSR $nnnnJump to a subroutine: push the return address (minus one) and jump. Paired with RTS. |
LDA | LDA #n / LDA $nn …Load the accumulator from memory (or an immediate). Sets N and Z. |
LDX | LDX #n / LDX $nn …Load the X register from memory (or an immediate). Sets N and Z. |
LDY | LDY #n / LDY $nn …Load the Y register from memory (or an immediate). Sets N and Z. |
LSR | LSR A / LSR $nn …Logical shift right of A or memory: bit 0 → carry, 0 → bit 7 (an unsigned divide by two). N is always cleared; sets Z and C. |
NOP | NOPNo operation — two cycles, no effect. Used for timing or to patch out code. |
ORA | ORA #n / ORA $nn …Bitwise OR of memory into the accumulator (A ← A | M). Sets N and Z. |
ORG | ORG $nnnnSet the assembly origin for the code that follows. It must agree with the block's own load address — the block editor fixes that from where the block sits. |
PHA | PHAPush the accumulator onto the stack; the stack pointer decreases. |
PHP | PHPPush the processor status (flags) onto the stack. |
PLA | PLAPull the accumulator from the stack. Sets N and Z. |
PLP | PLPPull the processor status (flags) from the stack. |
ROL | ROL A / ROL $nn …Rotate A or memory left through carry (9-bit rotate: C → bit 0, bit 7 → C). Sets N Z C. |
ROR | ROR A / ROR $nn …Rotate A or memory right through carry (9-bit rotate: C → bit 7, bit 0 → C). Sets N Z C. |
RTI | RTIReturn from an interrupt: pull the status and the program counter back off the stack. |
RTS | RTSReturn from a subroutine: pull the return address and continue after the JSR. |
SBC | SBC #n / SBC $nn …Subtract memory from the accumulator with borrow: A ← A − M − (1 − C). Set carry (SEC) before the first subtract. Sets N V Z C. |
SEC | SECSet the carry flag. Do this before the first SBC of a multi-byte subtraction. |
SED | SEDSet decimal mode, so ADC and SBC do packed binary-coded-decimal arithmetic. |
SEI | SEISet the interrupt-disable flag, masking further IRQs. |
STA | STA $nn / STA $nnnn,X …Store the accumulator to memory. No flags are affected, and there is no immediate mode. |
STX | STX $nn / STX $nnnn …Store the X register to memory. No flags are affected. |
STY | STY $nn / STY $nnnn …Store the Y register to memory. No flags are affected. |
TAX | TAXTransfer the accumulator to X. Sets N and Z. |
TAY | TAYTransfer the accumulator to Y. Sets N and Z. |
TSX | TSXTransfer the stack pointer to X. Sets N and Z. |
TXA | TXATransfer X to the accumulator. Sets N and Z. |
TXS | TXSTransfer X to the stack pointer. No flags are affected. |
TYA | TYATransfer Y to the accumulator. Sets N and Z. |
Showing 60 of 60 keywords
Addressing modes
Most instructions accept several addressing modes; the mode is written into the operand:
| Form | Mode | Meaning |
|---|---|---|
| (none) | implied | no operand — e.g. TAX, RTS |
A | accumulator | acts on A — e.g. ASL A |
#n | immediate | the literal value n |
$nn | zero page | address $00–$FF (shorter, faster) |
$nn,X | zero page,X | zero page indexed by X ($nn,Y for X/Y) |
$nnnn | absolute | full 16-bit address |
$nnnn,X | absolute,X | absolute indexed by X (or ,Y) |
($nn,X) | indexed indirect | pointer at $nn+X in zero page |
($nn),Y | indirect indexed | pointer at $nn, then add Y |
($nnnn) | indirect | JMP only — jump through a pointer |
label | relative | branch target (BNE, BEQ, …) |
A narrow literal ($NN or decimal under 256) selects the zero-page form; a wide one ($00FF, a label, or an expression) selects absolute — so the disassembler and assembler round-trip to the identical bytes.
Numbers, labels & comments
Numbers may be written in any case as:
- Hex —
$FF,0xFF, or a leading-digit0FFh - Binary —
%1010or0b1010 - Decimal —
65535
Disassembly always writes hex with a $ sigil (two digits for a byte, four for a word). A label is a name followed by a colon at the start of a line (loop:); refer to it by name in a branch, jump or address operand. Operands may use simple +/- expressions (sprite+1). Everything after a semicolon (;) is a comment.
Directives
Four pseudo-ops control layout and data:
ORG $nnnn— set the origin. It must match the block's own load address, which the block editor fixes from where the block sits, so you rarely change it by hand.DB n[,n…]— emit literal bytes (data tables, text).DW nn[,nn…]— emit little-endian 16-bit words.DS n— reservenzero-filled bytes.
Where blocks live on each machine
The address ranges a routine may occupy, the default load address, and the entry points you call (SYS, CALL, USR, LINK) are machine-specific — see the Memory section on each machine's hardware page: Commodore 64, VIC-20 & PET, BBC Micro & Master, Acorn Atom, Apple I, Apple II, Apple II Plus and Atari 800 & 400.
See also the machine code guide and the cross-dialect Machine code & data blocks overview.