SNES Development
65816 Reference

Internal Registers

MnemonicFriendly NameDescription
AAccumulatorThe accumulator. This is the math register. It stores one of two operands or the result of most arithmetic and logical operations.
X, YIndexThe index registers. These can be used to reference memory, to pass data to memory, or as counters for loops.
SStack PointerThe stack pointer, points to the next available(unused) location on the stack.
DBR / DBData BankData bank register, holds the default bank for memory transfers.
D / DPDirect PageDirect page register, used for direct page addressing modes. Holds the memory bank address of the data the CPU is accessing.
PB / PBRProgram BankProgram Bank, holds the bank address of all instruction fetches.
PProcessor StatusHolds various important flags, results of tests and 65816 processing states. See below.
PCProgram CounterHolds the memory address of the current CPU instruction

Flags stored in P Register

MnemonicValueBinary ValueDescription
N#$8010000000Negative
V#$4001000000Overflow
Z#$0200000010Zero
C#$0100000001Carry
D#$0800001000Decimal
I#$0400000100IRQ disable
X#$1000010000Index register size (native mode only)
(0 = 16-bit, 1 = 8-bit)
M#$2000100000Accumulator register size (native mode only)
(0 = 16-bit, 1 = 8-bit)
E6502 emulation mode
B#$1000010000Break (emulation mode only)

Addressing Modes

ModeExample
ImpliedPHB
ImmediateMemoryFlagAND #1 or 2 bytes
ImmediateIndexFlagLDX #1 or 2 bytes
Immediate8-BitSEP #byte
RelativeBEQ byte (signed)
Relative longBRL 2 bytes (signed)
DirectAND byte
Direct indexed (with X)AND byte, x
Direct indexed (with Y)AND byte, y
Direct indirectAND (byte)
Direct indexed indirectAND (byte, x)
Direct indirect indexedAND (byte), y
Direct indirect longAND [byte]
Direct indirect indexed longAND [byte], y
AbsoluteAND 2bytes
Absolute indexed (with X)AND 2bytes, x
Absolute indexed (with Y)AND 2bytes, y
Absolute longAND 3bytes
Absolute indexed longAND 3bytes, x
Stack relativeAND byte, s
Stack relative indirect indexedAND (byte, s), y
Absolute indirectJMP (2bytes)
Absolute indirect longJML [2bytes]
Absolute indexed indirectJMP/JSR (2bytes,x)
Implied accumulatorINC
Block moveMVN/MVP byte, byte

Instructions

Instructions are a breakdown of machine code. For the SNES, they consist of a 1-byte opcode followed by a 0-3 byte operand. Full instructions may be known as words. For example, the instruction ADC $3a occupies 2 bytes in memory, and if assembled, it would be stored as E6 3A.

Most instructions that are at least 2 bytes long have more than one addressing mode. Addressing modes are put in place so basic instructions may be interpreted correctly given a wide range of operands.

Assembler ExampleAliasProper NameHEXAddressing ModeFlags SetBytesCycles
ADC (_dp_,X)Add With Carry61DP Indexed Indirect,XNV—-ZC2612
ADC sr,SAdd With Carry63Stack RelativeNV—-ZC24
ADC dpAdd With Carry65Direct PageNV—-ZC23
ADC [_dp_]Add With Carry67DP Indirect LongNV—-ZC26
ADC #constAdd With Carry69ImmediateNV—-ZC232
ADC addrAdd With Carry6DAbsoluteNV—-ZC34
ADC longAdd With Carry6FAbsolute LongNV—-ZC45
ADC ( dp),YAdd With Carry71DP Indirect Indexed, YNV—-ZC254
ADC (_dp_)Add With Carry72DP IndirectNV—-ZC25
ADC (_sr_,S),YAdd With Carry73SR Indirect Indexed,YNV—-ZC27
ADC dp,XAdd With Carry75DP Indexed,XNV—-ZC24
ADC [_dp_],YAdd With Carry77DP Indirect Long Indexed, YNV—-ZC26
ADC addr,YAdd With Carry79Absolute Indexed,YNV—-ZC34
ADC addr,XAdd With Carry7DAbsolute Indexed,XNV—-ZC34
ADC long,XAdd With Carry7FAbsolute Long Indexed,XNV—-ZC45
AND (_dp,_X)AND Accumulator with Memory21DP Indexed Indirect,XN—–Z-26
AND sr,SAND Accumulator with Memory23Stack RelativeN—–Z-24
AND dpAND Accumulator with Memory25Direct PageN—–Z-23
AND [_dp_]AND Accumulator with Memory27DP Indirect LongN—–Z-26
AND #constAND Accumulator with Memory29ImmediateN—–Z-22
AND addrAND Accumulator with Memory2DAbsoluteN—–Z-34
AND longAND Accumulator with Memory2FAbsolute LongN—–Z-45
AND (_dp_),YAND Accumulator with Memory31DP Indirect Indexed, YN—–Z-25
AND (_dp_)AND Accumulator with Memory32DP IndirectN—–Z-25
AND (_sr_,S),YAND Accumulator with Memory33SR Indirect Indexed,YN—–Z-27
AND dp,XAND Accumulator with Memory35DP Indexed,XN—–Z-24
AND [_dp_],YAND Accumulator with Memory37DP Indirect Long Indexed, YN—–Z-26
AND addr,YAND Accumulator with Memory39Absolute Indexed,YN—–Z-34
AND addr,XAND Accumulator with Memory3DAbsolute Indexed,XN—–Z-34
AND long,XAND Accumulator with Memory3FAbsolute Long Indexed,XN—–Z-45
ASL dpArithmetic Shift Left06Direct PageN—–ZC255
ASL AArithmetic Shift Left0AAccumulatorN—–ZC12
ASL addrArithmetic Shift Left0EAbsoluteN—–ZC36
ASL dp,XArithmetic Shift Left16DP Indexed,XN—–ZC26
ASL addr,XArithmetic Shift Left1EAbsolute Indexed,XN—–ZC37
BCC nearlabelBLTBranch if Carry Clear90Program Counter Relative2267
BCS nearlabelBGEBranch if Carry SetB0Program Counter Relative22
BEQ nearlabelBranch if EqualF0Program Counter Relative22
BIT dpTest Bits24Direct PageNV—-Z-23
BIT addrTest Bits2CAbsoluteNV—-Z-34
BIT dp,XTest Bits34DP Indexed,XNV—-Z-24
BIT addr,XTest Bits3CAbsolute Indexed,XNV—-Z-34
BIT #constTest Bits89Immediate——Z-22
BMI nearlabelBranch if Minus30Program Counter Relative22
BNE nearlabelBranch if Not EqualD0Program Counter Relative22
BPL nearlabelBranch if Plus10Program Counter Relative22
BRA nearlabelBranch Always80Program Counter Relative23
BRKBreak00Stack/Interrupt—-DI–2879
BRL labelBranch Long Always82Program Counter Relative Long34
BVC nearlabelBranch if Overflow Clear50Program Counter Relative22
BVS nearlabelBranch if Overflow Set70Program Counter Relative22
CLCClear Carry18Implied——-C12
CLDClear Decimal Mode FlagD8Implied—-D—12
CLIClear Interrupt Disable Flag58Implied—–I–12
CLVClear Overflow FlagB8Implied-V——12
CMP (_dp,_X)Compare Accumulator with MemoryC1DP Indexed Indirect,XN—–ZC26
CMP sr,SCompare Accumulator with MemoryC3Stack RelativeN—–ZC24
CMP dpCompare Accumulator with MemoryC5Direct PageN—–ZC23
CMP [_dp_]Compare Accumulator with MemoryC7DP Indirect LongN—–ZC26
CMP #constCompare Accumulator with MemoryC9ImmediateN—–ZC22
CMP addrCompare Accumulator with MemoryCDAbsoluteN—–ZC34
CMP longCompare Accumulator with MemoryCFAbsolute LongN—–ZC45
CMP (_dp_),YCompare Accumulator with MemoryD1DP Indirect Indexed, YN—–ZC25
CMP (_dp_)Compare Accumulator with MemoryD2DP IndirectN—–ZC25
CMP (_sr_,S),YCompare Accumulator with MemoryD3SR Indirect Indexed,YN—–ZC27
CMP dp,XCompare Accumulator with MemoryD5DP Indexed,XN—–ZC24
CMP [_dp_],YCompare Accumulator with MemoryD7DP Indirect Long Indexed, YN—–ZC26
CMP addr,YCompare Accumulator with MemoryD9Absolute Indexed,YN—–ZC34
CMP addr,XCompare Accumulator with MemoryDDAbsolute Indexed,XN—–ZC34
CMP long,XCompare Accumulator with MemoryDFAbsolute Long Indexed,XN—–ZC45
COP constCo-Processor Enable02Stack/Interrupt—-DI–27
CPX #constCompare Index Register X with MemoryE0ImmediateN—–ZC210211
CPX dpCompare Index Register X with MemoryE4Direct PageN—–ZC23
CPX addrCompare Index Register X with MemoryECAbsoluteN—–ZC34
CPY #constCompare Index Register Y with MemoryC0ImmediateN—–ZC22
CPY dpCompare Index Register Y with MemoryC4Direct PageN—–ZC23
CPY addrCompare Index Register Y with MemoryCCAbsoluteN—–ZC34
DEC ADEADecrement3AAccumulatorN—–Z-12
DEC dpDecrementC6Direct PageN—–Z-25
DEC addrDecrementCEAbsoluteN—–Z-36
DEC dp,XDecrementD6DP Indexed,XN—–Z-26
DEC addr,XDecrementDEAbsolute Indexed,XN—–Z-37
DEXDecrement Index Register XCAImpliedN—–Z-12
DEYDecrement Index Register Y88ImpliedN—–Z-12
EOR (_dp,_X)Exclusive-OR Accumulator with Memory41DP Indexed Indirect,XN—–Z-26
EOR sr,SExclusive-OR Accumulator with Memory43Stack RelativeN—–Z-24
EOR dpExclusive-OR Accumulator with Memory45Direct PageN—–Z-23
EOR [_dp_]Exclusive-OR Accumulator with Memory47DP Indirect LongN—–Z-26
EOR #constExclusive-OR Accumulator with Memory49ImmediateN—–Z-22
EOR addrExclusive-OR Accumulator with Memory4DAbsoluteN—–Z-34
EOR longExclusive-OR Accumulator with Memory4FAbsolute LongN—–Z-45
EOR (_dp_),YExclusive-OR Accumulator with Memory51DP Indirect Indexed, YN—–Z-25
EOR (_dp_)Exclusive-OR Accumulator with Memory52DP IndirectN—–Z-25
EOR (_sr_,S),YExclusive-OR Accumulator with Memory53SR Indirect Indexed,YN—–Z-27
EOR dp,XExclusive-OR Accumulator with Memory55DP Indexed,XN—–Z-24
EOR [_dp_],YExclusive-OR Accumulator with Memory57DP Indirect Long Indexed, YN—–Z-26
EOR addr,YExclusive-OR Accumulator with Memory59Absolute Indexed,YN—–Z-34
EOR addr,XExclusive-OR Accumulator with Memory5DAbsolute Indexed,XN—–Z-34
EOR long,XExclusive-OR Accumulator with Memory5FAbsolute Long Indexed,XN—–Z-45
INC AINAIncrement1AAccumulatorN—–Z-12
INC dpIncrementE6Direct PageN—–Z-25
INC addrIncrementEEAbsoluteN—–Z-36
INC dp,XIncrementF6DP Indexed,XN—–Z-26
INC addr,XIncrementFEAbsolute Indexed,XN—–Z-37
INXIncrement Index Register XE8ImpliedN—–Z-12
INYIncrement Index Register YC8ImpliedN—–Z-12
JMP addrJump4CAbsolute33
JMP longJMLJump5CAbsolute Long44
JMP (_addr_)Jump6CAbsolute Indirect35
JMP (_addr,X_)Jump7CAbsolute Indexed Indirect36
JMP [addr]JMLJumpDCAbsolute Indirect Long36
JSR addrJump to Subroutine20Absolute36
JSR longJSLJump to Subroutine22Absolute Long48
JSR (addr,X))Jump to SubroutineFCAbsolute Indexed Indirect38
LDA (_dp,_X)Load Accumulator from MemoryA1DP Indexed Indirect,XN—–Z-26
LDA sr,SLoad Accumulator from MemoryA3Stack RelativeN—–Z-24
LDA dpLoad Accumulator from MemoryA5Direct PageN—–Z-23
LDA [_dp_]Load Accumulator from MemoryA7DP Indirect LongN—–Z-26
LDA #constLoad Accumulator from MemoryA9ImmediateN—–Z-22
LDA addrLoad Accumulator from MemoryADAbsoluteN—–Z-34
LDA longLoad Accumulator from MemoryAFAbsolute LongN—–Z-45
LDA (_dp_),YLoad Accumulator from MemoryB1DP Indirect Indexed, YN—–Z-25
LDA (_dp_)Load Accumulator from MemoryB2DP IndirectN—–Z-25
LDA (_sr_,S),YLoad Accumulator from MemoryB3SR Indirect Indexed,YN—–Z-27
LDA dp,XLoad Accumulator from MemoryB5DP Indexed,XN—–Z-24
LDA [_dp_],YLoad Accumulator from MemoryB7DP Indirect Long Indexed, YN—–Z-26
LDA addr,YLoad Accumulator from MemoryB9Absolute Indexed,YN—–Z-34
LDA addr,XLoad Accumulator from MemoryBDAbsolute Indexed,XN—–Z-34
LDA long,XLoad Accumulator from MemoryBFAbsolute Long Indexed,XN—–Z-45
LDX #constLoad Index Register X from MemoryA2ImmediateN—–Z-2122
LDX dpLoad Index Register X from MemoryA6Direct PageN—–Z-23
LDX addrLoad Index Register X from MemoryAEAbsoluteN—–Z-34
LDX dp,YLoad Index Register X from MemoryB6DP Indexed,YN—–Z-24
LDX addr,YLoad Index Register X from MemoryBEAbsolute Indexed,YN—–Z-34
LDY #constLoad Index Register Y from MemoryA0ImmediateN—–Z-22
LDY dpLoad Index Register Y from MemoryA4Direct PageN—–Z-23
LDY addrLoad Index Register Y from MemoryACAbsoluteN—–Z-34
LDY dp,XLoad Index Register Y from MemoryB4DP Indexed,XN—–Z-24
LDY addr,XLoad Index Register Y from MemoryBCAbsolute Indexed,XN—–Z-34
LSR dpLogical Shift Memory or Accumulator Right46Direct PageN—–ZC25
LSR ALogical Shift Memory or Accumulator Right4AAccumulatorN—–ZC12
LSR addrLogical Shift Memory or Accumulator Right4EAbsoluteN—–ZC36
LSR dp,XLogical Shift Memory or Accumulator Right56DP Indexed,XN—–ZC26
LSR addr,XLogical Shift Memory or Accumulator Right5EAbsolute Indexed,XN—–ZC37
MVN srcbk,destbkBlock Move Negative54Block Move31
MVP srcbk,destbkBlock Move Positive44Block Move31
NOPNo OperationEAImplied12
ORA (_dp,_X)OR Accumulator with Memory01DP Indexed Indirect,XN—–Z-26
ORA sr,SOR Accumulator with Memory03Stack RelativeN—–Z-24
ORA dpOR Accumulator with Memory05Direct PageN—–Z-23
ORA [_dp_]OR Accumulator with Memory07DP Indirect LongN—–Z-26
ORA #constOR Accumulator with Memory09ImmediateN—–Z-22
ORA addrOR Accumulator with Memory0DAbsoluteN—–Z-34
ORA longOR Accumulator with Memory0FAbsolute LongN—–Z-45
ORA (_dp_),YOR Accumulator with Memory11DP Indirect Indexed, YN—–Z-25
ORA (_dp_)OR Accumulator with Memory12DP IndirectN—–Z-25
ORA (_sr_,S),YOR Accumulator with Memory13SR Indirect Indexed,YN—–Z-27
ORA dp,XOR Accumulator with Memory15DP Indexed,XN—–Z-24
ORA [_dp_],YOR Accumulator with Memory17DP Indirect Long Indexed, YN—–Z-26
ORA addr,YOR Accumulator with Memory19Absolute Indexed,YN—–Z-34
ORA addr,XOR Accumulator with Memory1DAbsolute Indexed,XN—–Z-34
ORA long,XOR Accumulator with Memory1FAbsolute Long Indexed,XN—–Z-45
PEA addrPush Effective Absolute AddressF4Stack (Absolute)35
PEI (dp)Push Effective Indirect AddressD4Stack (DP Indirect)26
PER labelPush Effective PC Relative Indirect Address62Stack (PC Relative Long)36
PHAPush Accumulator48Stack (Push)13
PHBPush Data Bank Register8BStack (Push)13
PHDPush Direct Page Register0BStack (Push)14
PHKPush Program Bank Register4BStack (Push)13
PHPPush Processor Status Register08Stack (Push)13
PHXPush Index Register XDAStack (Push)13
PHYPush Index Register Y5AStack (Push)13
PLAPull Accumulator68Stack (Pull)N—–Z-14
PLBPull Data Bank RegisterABStack (Pull)N—–Z-14
PLDPull Direct Page Register2BStack (Pull)N—–Z-15
PLPPull Processor Status Register28Stack (Pull)N—–Z-14
PLXPull Index Register XFAStack (Pull)N—–Z-14
PLYPull Index Register Y7AStack (Pull)N—–Z-14
REP #constReset Processor Status BitsC2ImmediateNVMXDIZC23
ROL dpRotate Memory or Accumulator Left26Direct PageN—–ZC25
ROL ARotate Memory or Accumulator Left2AAccumulatorN—–ZC12
ROL addrRotate Memory or Accumulator Left2EAbsoluteN—–ZC36
ROL dp,XRotate Memory or Accumulator Left36DP Indexed,XN—–ZC26
ROL addr,XRotate Memory or Accumulator Left3EAbsolute Indexed,XN—–ZC37
ROR dpRotate Memory or Accumulator Right66Direct PageN—–ZC25
ROR ARotate Memory or Accumulator Right6AAccumulatorN—–ZC12
ROR addrRotate Memory or Accumulator Right6EAbsoluteN—–ZC36
ROR dp,XRotate Memory or Accumulator Right76DP Indexed,XN—–ZC26
ROR addr,XRotate Memory or Accumulator Right7EAbsolute Indexed,XN—–ZC37
RTIReturn from Interrupt40Stack (RTI)NVMXDIZC16
RTLReturn from Subroutine Long6BStack (RTL)16
RTSReturn from Subroutine60Stack (RTS)16
SBC (_dp,_X)Subtract with Borrow from AccumulatorE1DP Indexed Indirect,XNV—-ZC26
SBC sr,SSubtract with Borrow from AccumulatorE3Stack RelativeNV—-ZC24
SBC dpSubtract with Borrow from AccumulatorE5Direct PageNV—-ZC23
SBC [_dp_]Subtract with Borrow from AccumulatorE7DP Indirect LongNV—-ZC26
SBC #constSubtract with Borrow from AccumulatorE9ImmediateNV—-ZC22
SBC addrSubtract with Borrow from AccumulatorEDAbsoluteNV—-ZC34
SBC longSubtract with Borrow from AccumulatorEFAbsolute LongNV—-ZC45
SBC (_dp_),YSubtract with Borrow from AccumulatorF1DP Indirect Indexed, YNV—-ZC25
SBC (_dp_)Subtract with Borrow from AccumulatorF2DP IndirectNV—-ZC25
SBC (_sr_,S),YSubtract with Borrow from AccumulatorF3SR Indirect Indexed,YNV—-ZC27
SBC dp,XSubtract with Borrow from AccumulatorF5DP Indexed,XNV—-ZC24
SBC [_dp_],YSubtract with Borrow from AccumulatorF7DP Indirect Long Indexed, YNV—-ZC26
SBC addr,YSubtract with Borrow from AccumulatorF9Absolute Indexed,YNV—-ZC34
SBC addr,XSubtract with Borrow from AccumulatorFDAbsolute Indexed,XNV—-ZC34
SBC long,XSubtract with Borrow from AccumulatorFFAbsolute Long Indexed,XNV—-ZC45
SECSet Carry Flag38Implied——-C12
SEDSet Decimal FlagF8Implied—-D—12
SEISet Interrupt Disable Flag78Implied—–I–12
SEP #constReset Processor Status BitsE2ImmediateNVMXDIZC23
STA (_dp,_X)Store Accumulator to Memory81DP Indexed Indirect,X26
STA sr,SStore Accumulator to Memory83Stack Relative24
STA dpStore Accumulator to Memory85Direct Page23
STA [_dp_]Store Accumulator to Memory87DP Indirect Long26
STA addrStore Accumulator to Memory8DAbsolute34
STA longStore Accumulator to Memory8FAbsolute Long45
STA (_dp_),YStore Accumulator to Memory91DP Indirect Indexed, Y26
STA (_dp_)Store Accumulator to Memory92DP Indirect25
STA (_sr_,S),YStore Accumulator to Memory93SR Indirect Indexed,Y27
STA dpXStore Accumulator to Memory95DP Indexed,X24
STA [_dp_],YStore Accumulator to Memory97DP Indirect Long Indexed, Y26
STA addr,YStore Accumulator to Memory99Absolute Indexed,Y35
STA addr,XStore Accumulator to Memory9DAbsolute Indexed,X35
STA long,XStore Accumulator to Memory9FAbsolute Long Indexed,X45
STPStop ProcessorDBImplied1313
STX dpStore Index Register X to Memory86Direct Page23
STX addrStore Index Register X to Memory8EAbsolute34
STX dp,YStore Index Register X to Memory96DP Indexed,Y24
STY dpStore Index Register Y to Memory84Direct Page23
STY addrStore Index Register Y to Memory8CAbsolute34
STY dp,XStore Index Register Y to Memory94DP Indexed,X24
STZ dpStore Zero to Memory64Direct Page23
STZ dp,XStore Zero to Memory74DP Indexed,X24
STZ addrStore Zero to Memory9CAbsolute34
STZ addr,XStore Zero to Memory9EAbsolute Indexed,X35
TAXTransfer Accumulator to Index Register XAAImpliedN—–Z-12
TAYTransfer Accumulator to Index Register YA8ImpliedN—–Z-12
TCDTransfer 16-bit Accumulator to Direct Page Register5BImpliedN—–Z-12
TCSTransfer 16-bit Accumulator to Stack Pointer1BImplied12
TDCTransfer Direct Page Register to 16-bit Accumulator7BImpliedN—–Z-12
TRB dpTest and Reset Memory Bits Against Accumulator14Direct Page——Z-25
TRB addrTest and Reset Memory Bits Against Accumulator1CAbsolute——Z-36
TSB dpTest and Set Memory Bits Against Accumulator04Direct Page——Z-25
TSB addrTest and Set Memory Bits Against Accumulator0CAbsolute——Z-36
TSCTransfer Stack Pointer to 16-bit Accumulator3BImpliedN—–Z-12
TSXTransfer Stack Pointer to Index Register XBAImpliedN—–Z-12
TXATransfer Index Register X to Accumulator8AImpliedN—–Z-12
TXSTransfer Index Register X to Stack Pointer9AImplied12
TXYTransfer Index Register X to Index Register Y9BImpliedN—–Z-12
TYATransfer Index Register Y to Accumulator98ImpliedN—–Z-12
TYXTransfer Index Register Y to Index Register XBBImpliedN—–Z-12
WAIWait for InterruptCBImplied13
WDMReserved for Future Expansion422014
XBAExchange B and A 8-bit AccumulatorsEBImpliedN—–Z-13
XCEExchange Carry and Emulation FlagsFBImplied–MX—CE12

Instruction Usage

ADC - Add with carry

Adds operand to the Accumulator; adds an additional 1 if carry is set.

A: 0010    adc #$50    ; adds $50 to accumulator or 51 if carry is set
A: 0060            ; result
AND - Perform AND to Accumulator

The operand is “AND”ed to the Accumulator. eg.

A: 0010    and #$80    ; "AND"s $80 to accumulator
A: 0000
ASL - Left shifts Accumulator, Memory

Shifts Memory or Accumulator left one bit. eg.

A: 0010    asl A    ; Shift left by 1: 0x10 << 1
A: 0020
BCC - Branch if carry clear

Jump to a new location within the -128 to 127 range if the carry flag is clear. Useful for comparing two numbers, branching if the second number less than the first. eg.

P: --mxdi--        bcc next    ; since the carry flag is clear, it'll jump to next
                   lda #$00    ; this will not be executed
          next:    lda #$40
BCS - Branch if carry set

Like BCC, but only when carry is set. Good for branching “if greater than or equal to” in a comparison.

BEQ - Branch if equal

Branches is zero flag is set. This is useful for comparing numbers. eg.

 cpx #$50    ; if X is = $50, the zero flag is set
 beq next    ; branches to next if X = $50
 lda #$44
next:
 lda #$00
BIT - Bit Test

Performs AND except only the flags are modified. eg.

A: 0010    bit #$80    ; "AND"s $80 to accumulator but result not stored
A: 0010
BMI - Branch if Minus

Branches if negative flag is set.

BNE - Branch if not equal

Branches if zero flag clear. Good when used with comparison. You can branch if the number it not equal to.

BPL - Branch if plus

Branches if negative flag clear.

BRA - Branch always

Branch to location PC + n where n is the difference between the current PC and the label we want to branch to.

BRK - Break to instruction

Causes a software break. The PC is loaded from a vector table from somewhere around $FFE6.

BRL - Branch Relative Long

Like BRA but with longer range (-32768 to 32767).

BVC - Branch if Overflow Clear

Branches if overflow flag is clear.

BVS - Branch if Overflow Set

Opposite of BVC.

CLC - Clear Carry Flag

Clears the carry flag.

CLD - Clear Decimal Flag

Clears the decimal flag.

CLI - Clear Interrupt Flag

Clears the interrupt Flag.

CLV - Clear Overflow Flag

Clears the Overflow flag.

CMP - Compare Accumulator with memory
CPX - Compare X with memory
CPY - Compare Y with memory

Compares Accumulator, X or Y with the operand. The n-----zc flags are affected by the comparison. If the result is negative, the n flag is set. If the result is zero (or equal), the z flag is set. Carry is clear when borrow is required; that is, if the register is less than the operand. eg.

A: 0020 P: --mx-i--        cmp #$20    ; compare accumulator with $20, if equal, z flag is set
A: 0020 P: --mx-iz-        beq next    ; branch if equal
COP - Coprocessor Empowerment

Causes a software interrupt using a vector.

DEC - Decrement Accumulator
DEX - Decrement X
DEY - Decrement Y

Subtracts 1 from A, X or Y. eg.

Y: 0001    dey
Y: 0000
EOR - Exclusive OR accumulator

Also known as “XOR”. Performs XOR to the Accumulator. eg.

A: FFFF    eor #$DDDD
A: 2222
INC - Increment Accumulator
INX - Increment X
INY - Increment Y

Adds 1 to A, X or Y. eg.

A: 0000    inc
A: 0001
JMP - Jump to location
JML - Jump long

The JMP command will jump to a location within the bank. The JML will jump to places out of the current bank. eg.

PBR: $80    jmp $5500      ; jumps to $80:5500
PBR: $80    jml $908000    ; jumps to $90:8000
PBR: $90                   ; the PBR is updated in long jump
JSR - Jump Subroutine
JSL - Jump Subroutine Long

If you already know a programming language, this is basically calling a function. This performs the same as JMP except the address of the current program counter is saved. In subroutines, the RTS and RTL are used to return back to the saved address.

LDA - Load Accumulator with memory
LDX - Load X with memory
LDY - Load Y with memory

Loads the Accumulator, X, Y with a value.

LSR - Shift Right Accumulator, Memory

Shifts Memory or Accumulator right one bit. eg.

A: 0080    lsr A    ; Shift right by 1: 0x80 >> 1
A: 0040
MVN - Block move negative
MVP - Block move positive

A should hold the number of bytes to transfer minus one, meaning that a value of zero will transfer one byte. X and Y are the source and destination addresses, respectively, leaving out the banks. The banks are passed as the two operands of the instruction.

In MVN, X and Y are the bottom bytes of the source and destination blocks. After a byte is copied, both X and Y are incremented and A is decremented until A reaches FFFF (after decrementing 0000), meaning that bytes from X to X + A were copied to the range from Y to Y + A.

In MVP, X and Y are the top bytes of the source and destination blocks. X, Y and A are decremented after each byte is copied, until A reaches $FFFF, so bytes from X to X - A are copied to the range from Y to Y - A.

Usually, MVN is used when the destination range is in a lower address than the source, otherwise MVP is used. This is a rule that avoids problems when the two address ranges overlap, assuring that every overlapping byte is read before being overwritten. However, as long as the programmer is aware of the consequences, it is possible to get useful results using the instructions the other way.

                           ; This example follows the rule of thumb: (src < dest) -> mvp
                           ; So it copies the memory as expected
X: ???? Y: ???? A: ????    rep #$30     ; Make Accumulator and index 16-bit
X: ???? Y: ???? A: ????    ldx #$1100   ; Set X to $1100
X: 1100 Y: ???? A: ????    ldy #$1180   ; Set Y to $1180
X: 1100 Y: 1180 A: ????    lda #$00FF   ; Set A to $00FF
X: 1100 Y: 1180 A: 00FF    mvp $7E,$7E  ; Block move $100 bytes from $7E:1001-1100 -> $7E:1081-1180
X: 1000 Y: 1080 A: FFFF    ...

                           ; This example does not follow the rule
                           ; (taken from Bushi Seiryuuden, 808B2F-808B3A)
                           ; In this case, two bytes are repeated over and over
X: ???? Y: ???? A: ????    ldx #$28C0   ; Set X to $28C0
X: 28C0 Y: ???? A: ????    ldy #$28C2   ; Set Y to $28C2
X: 28C0 Y: 28C2 A: ????    lda #$013D   ; Set A to $013D
X: 28C0 Y: 28C2 A: 013D    mvn $7E,$7E  ; The values at $7E:28C0-28C1 are repeated for $013E bytes
X: 29FE Y: 2A00 A: FFFF    ...
NOP - No operation

Does nothing but take up 2 cycles.

ORA - “OR” Accumulator with memory

Performs “OR” to Accumulator. eg.

A: 005F    ora #$7F    ; 0x5F | 0x7F
A: 007F
PEA - Push Effective Address

Pushes a 16-bit operand onto the stack. The instruction is very misleading because you are really pushing an immediate onto the stack. eg.

S: 1FFF    pea $FFFF    ; Pushes $FFFF onto the stack
S: 1FFD                 ; stack decrements by 2
PEI - Push Effective Indirect Address

Pushes a 16-bit value from the indirect address of the operand. eg.

Memory Dump:
0000: 23 33 45 22 DD C7 FF 8D
0001: 99 99 90 88 DD FF CC 67
S: 1FFF    pei ($01)    ; push $4533 on the stack
S: 1FFD
PER - Push Program Counter Relative

Pushes a 16-bit from that address taken by the current PC added to the operand. The range must be within (0-65535).

PHA - Push Accumulator
PHD - Push Direct Page Register
PHK - Push Program Bank
PHX - Push X
PHY - Push Y

Pushes the operand onto the stack.

PLA - Pull Accumulator
PLD - Pull Direct Page Register
PLP - Pull Flags
PLX - Pull X
PLY - Pull Y

Pops a value off the stack and stores it in the operand.

REP - Reset Flag

Clears the bits specified in the operands of the flag. eg.

rep #$30    ; Clears bit 4 & 5 to make A, X, Y 16-bits
ROL - Rotate Bit Left

Equivalent to ASL, except the carry flag rather than a zero is shifted into the least significant bit. This operation acts as a 9-bit rotation in 8-bit mode or a 17-bit rotation in 16-bit mode.

A: 8000    rol A    ; rotate 1 left
A: 0001
ROR - Rotate Bit Right

Equivalent to LSR, except the carry flag rather than a zero is shifted into the most significant bit rather than a zero. This operation acts as a 9-bit rotation in 8-bit mode or a 17-bit rotation in 16-bit mode.

A: 0001    ror A    ; rotate 1 right
A: 8000
RTI - Return from Interrupt

Used to return from a interrupt handler.

RTS - Return from Subroutine
RTL - Return from Subroutine Long

Return the PC to the saved address caused by the JSR and JSL command. eg.

    jsl sub    ; jump to subroutine at label "sub"
    .
    .
    .
sub:
    lda #$0000    ; some code
    rtl        ; return
SBC - Subtract with Carry

Subtracts operand from the Accumulator; subtracts an additional 1 if carry is clear.

SEC - Set Carry Flag

Sets the carry flag.

SED - Set Decimal Flag

Sets the decimal flag.

SEI - Set Interrupt flag

Sets the interrupt flag.

SEP - Set Flag

Sets certain bits of the flag depending on the operand. eg.

sep #$20    ; set bit 5 of P to make A 8-bits
STA - Store Accumulator to memory
STX - Store X to memory
STY - Store Y to memory

Stores the Accumulator, X or Y to a memory location. eg.

A: 000F    sep #$20    ; 8-bit A
A: 000F    sta $2100    ; Stores $0F to $2100
STP - Stop the clock

Dies.

STZ - Store zero to memory

Stores zero to a memory location. eg.

stz $2101    ; store 0 to $2101
TAX - Transfer Accumulator to X
TAY - Transfer Accumulator to Y
TCD - Transfer Accumulator to Direct Page

sets the direct page to whatever is in A

lda #$0000    ;the C refers to 16bit A
tcd
lda $34       ;same as lda $0034
TCS - Transfer Accumulator to Stack
TDC - Transfer Direct Page to Accumulator

if direct page is 0 then this functions to clear out 16bit A

lda.w #$0000  ;3 bytes, 3 cycles
tdc           ;1 byte, 2 cycles
TSC - Transfer Stack to Accumulator
TSX - Transfer stack to X
TXA - Transfer X to Accumulator
TXS - Transfer X to Stack
TXY - Transfer X to Y
TYA - Transfer Y to Accumulator
TYX - Transfer Y to X

Copies the content of one register to another. eg.

A: 0099 X: 1FFF Y:5656 D:0020 S: FFFF    rep #$30
A: 0099 X: 1FFF Y:5656 D:0020 S: FFFF    lda #$0000    ; load A with 0
A: 0000 X: 1FFF Y:5656 D:0020 S: FFFF    tcd           ; transfer A -> D
A: 0000 X: 1FFF Y:5656 D:0000 S: FFFF    txa           ; X -> A
A: 1FFF X: 1FFF Y:5656 D:0000 S: FFFF    tcs           ; A -> S
A: 1FFF X: 1FFF Y:5656 D:0000 S: 1FFF

You get the idea.

TRB - Test and Reset Bit

Tests the bit similarly to “AND”, and clears it, while affecting the flags.

TSB - Test and Set Bit

Tests the bit similarly to “AND”, and sets it, while affecting the flags.

WAI - Wait for Interrupt

Waits until a hardware interrupt is triggered.

XCE - Exchange Carry with Emulation

Well, the 65816 has actually 2 modes. Native and (6502) emulation mode. This tutorial deals with native only. The emulation bit shares the same bit as the carry flag so to put ourselves in native mode, we can only set the emulation flag via the carry and exchanging it. For native mode, the emulation flag must be off. To switch to native mode, we must clear the carry and exchange it. eg.

clc
xce

Instruction usage adapted from Jay's ASM Tutorial

Datasheets, Manuals etc.

Western Design Center Inc. has documentation on the 65816 here.

Of particular interest would be the Assembly Language Programming Manual for the W65C02 and W65C816 aka “Programming the 65816 including the 6502, 65C02, and 65802” by David Eyes and Ron Lichty.


  1. Add 1 cycle if m=0 (16-bit memory/accumulator)

  2. Add 1 cycle if low byte of Direct Page Register is non-zero

  3. Add 1 byte if m=0 (16-bit memory/accumulator)

  4. Add 1 cycle if adding index crosses a page boundary

  5. Add 2 cycles if m=0 (16-bit memory/accumulator)

  6. Add 1 cycle if branch is taken

  7. Add 1 cycle if branch taken crosses page boundary in emulation mode (e=1)

  8. Opcode is 1 byte, but program counter value pushed onto stack is incremented by 2 allowing for optional signature byte

  9. Add 1 cycle for 65816 native mode (e=0)

  10. Add 1 byte if x=0 (16-bit index registers)

  11. Add 1 cycle if x=0 (16-bit index registers)

  12. Uses 3 cycles to shut the processor down: additional cycles are required by interrupt to restart it

  13. Uses 3 cycles to shut the processor down: additional cycles are required by reset to restart it

  14. Byte and cycle counts subject to change in future processors which expand WDM into 2-byte opcode portions of instructions of varying lengths