6502 Assembly

From Wikibooks, open books for an open world
Jump to: navigation, search

This book is a guide to the 6502 Assembly language. This book will teach the different memory addressing modes and instructions of the 8-bit 6502 processor.

You might want to learn 6502 assembly language programming if you want to do Atari 8 Bit Programming, Commodore 64 Programming, NES Programming or Super NES Programming.

Memory Addressing Modes[edit]

These are the thirteen memory addressing modes for the 6502 processor including some examples.

Accumulator: A[edit]

The Accumulator is implied as the operand, so no address needs to be specified.

Example

Using the ASL (Arithmetic Shift Left) instruction with no operands, the Accumulator is always the value being shifted left.

ASL

Implied: i[edit]

The operand is implied, so it does not need to be specified.

Example

The operands being implied here are X, the source of the transfer, and A, the destination of the transfer.

TXA

Immediate: #[edit]

The operand is used directly to perform the computation.

Example

The value $22 is loaded into the Accumulator.

LDA #$22

Absolute: a[edit]

A full 16-bit address is specified and the byte at that address is used to perform the computation.

Example

The value at address $D010 is loaded into the X register.

LDX $D010

Zero Page: zp[edit]

A single byte specifies an address in the first page of memory ($00xx), also known as the zero page, and the byte at that address is used to perform the computation.

Example

The value at address $0002 is loaded into the Y register.

LDY $02

Relative: r[edit]

The offset specified is added to the current address stored in the Program Counter (PC). Offsets can range from -128 to +127.

Example

The offset $2D is added to the address in the Program Counter (say $C100). The destination of the branch (if taken) will be $C12D.

BPL $2D

Absolute Indexed with X: a,x[edit]

The value in X is added to the specified address for a sum address. The value at the sum address is used to perform the computation.

Example

The value $02 in X is added to $C001 for a sum of $C003. The value $5A at address $C003 is used to perform the add with carry (ADC) operation.

ADC $C001,X

Absolute Indexed with Y: a,y[edit]

The value in Y is added to the specified address for a sum address. The value at the sum address is used to perform the computation.

Example

The value $03 in Y is added to $F001 for a sum of $F004. The value $EF at address $F004 is incremented (INC) and $F0 is written back to $F004.

INC $F001,Y

Zero Page Indexed with X: zp,x[edit]

The value in X is added to the specified zero page address for a sum address. The value at the sum address is used to perform the computation.

Example

The value $02 in X is added to $01 for a sum of $03. The value $A5 at address $0003 is loaded into the Accumulator.

LDA $01,X

Zero Page Indexed with Y: zp,y[edit]

The value in Y is added to the specified zero page address for a sum address. The value at the sum address is used to perform the computation.

Example

The value $03 in Y is added to $01 for a sum of $04. The value $E3 at address $0004 is loaded into the Accumulator.

LDA $01,Y

Zero Page Indexed Indirect: (zp,x)[edit]

The value in X is added to the specified zero page address for a sum address. The little-endian address stored at the two-byte pair of sum address (LSB) and sum address plus one (MSB) is loaded and the value at that address is used to perform the computation.

Example

The value $02 in X is added to $15 for a sum of $17. The address $D010 at addresses $0017 and $0018 will be where the value $0F in the accumulator is stored.

STA ($15,X)

Zero Page Indirect Indexed with Y: (zp),y[edit]

The value in Y is added to the address at the little-endian address stored at the two-byte pair of the specified address (LSB) and the specified address plus one (MSB). The value at the sum address is used to perform the computation. Indeed addressing mode actually repeats exactly the accumulator register's digits.

Example

The value $03 in Y is added to the address $C235 at addresses $002A and $002B for a sum of $C238. The value $2F at $C238 is shifted right (yielding $17) and written back to $C238.

LSR ($2A),Y

Instructions[edit]

These are the instructions for the 6502 processor including an ASCII visual, a list of affected flags, and a table of opcodes for acceptable addressing modes.

Load and Store[edit]

Load Accumulator with Memory: LDA

M -> A

Flags: N, Z

Addressing Mode Opcode
a AD
a,x BD
a,y B9
# A9
zp A5
(zp,x) A1
zp,x B5
(zp),y B1

Load Index X with Memory: LDX

M -> X

Flags: N, Z

Addressing Mode Opcode
a AE
a,y BE
# A2
zp A6
zp,y B6

Load Index Y with Memory: LDY

M -> Y

Flags: N, Z

Addressing Mode Opcode
a AC
a,x BC
# A0
zp A4
zp,x B4

Store Accumulator in Memory: STA

A -> M

Flags: none

Addressing Mode Opcode
a 8D
a,x 9D
a,y 99
zp 85
(zp,x) 81
zp,x 95
(zp),y 91

Store Index X in Memory: STX

X -> M

Flags: none

Addressing Mode Opcode
a 8E
zp 86
zp,y 96

Store Index Y in Memory: STY

Y -> M

Flags: none

Addressing Mode Opcode
a 8C
zp 84
zp,x 94

Arithmetic[edit]

Add Memory to Accumulator with Carry: ADC

A + M + C -> A

Flags: N, V, Z, C

Addressing Mode Opcode
a 6D
a,x 7D
a,y 79
# 69
zp 65
(zp,x) 61
zp,x 75
(zp),y 71

Subtract Memory from Accumulator with Borrow: SBC

A - M - ~C -> A

Flags: N, V, Z, C

Addressing Mode Opcode
a ED
a,x FD
a,y F9
# E9
zp E5
(zp,x) E1
zp,x F5
(zp),y F1

Increment and Decrement[edit]

Increment Memory by One: INC

M + 1 -> M

Flags: N, Z

Addressing Mode Opcode
a EE
a,x FE
zp E6
zp,x F6

Increment Index X by One: INX

X + 1 -> X

Flags: N, Z

Addressing Mode Opcode
i E8

Increment Index Y by One: INY

Y + 1 -> Y

Flags: N, Z

Addressing Mode Opcode
i C8

Decrement Memory by One: DEC

M - 1 -> M

Flags: N, Z

Addressing Mode Opcode
a CE
a,x DE
zp C6
zp,x D6

Decrement Index X by One: DEX

X - 1 -> X

Flags: N, Z

Addressing Mode Opcode
i CA

Decrement Index Y by One: DEY

Y - 1 -> Y

Flags: N, Z

Addressing Mode Opcode
i 88

Shift and Rotate[edit]

Arithmetic Shift Left One Bit: ASL

C <- 7 6 5 4 3 2 1 0 <- 0

Flags: N, Z, C

Addressing Mode Opcode
a 0E
a,x 1E
A 0A
zp 06
zp,x 16

Logical Shift Right One Bit: LSR

0 -> 7 6 5 4 3 2 1 0 -> C

Flags: N, Z, C

Addressing Mode Opcode
a 4E
a,x 5E
A 4A
zp 46
zp,x 56

Rotate Left One Bit: ROL

C <- 7 6 5 4 3 2 1 0 <- C

Flags: N, Z, C

Addressing Mode Opcode
a 2E
a,x 3E
A 2A
zp 26
zp,x 36

Rotate Right One Bit: ROR

C -> 7 6 5 4 3 2 1 0 -> C

Flags: N, Z, C

Addressing Mode Opcode
a 6E
a,x 7E
A 6A
zp 66
zp,x 76

Logic[edit]

AND Memory with Accumulator: AND

A & M -> A

Flags: N, Z

Addressing Mode Opcode
a 2D
a,x 3D
a,y 39
# 29
zp 25
(zp,x) 21
zp,x 35
(zp),y 31

OR Memory with Accumulator: ORA

A | M -> A

Flags: N, Z

Addressing Mode Opcode
a 0D
a,x 1D
a,y 19
# 09
zp 05
(zp,x) 01
zp,x 15
(zp),y 11

Exclusive-OR Memory with Accumulator: EOR

A ^ M -> A

Flags: N, Z

Addressing Mode Opcode
a 4D
a,x 5D
a,y 59
# 49
zp 45
(zp,x) 41
zp,x 55
(zp),y 51

Compare and Test Bit[edit]

For all Compare instructions:

Condition N Z C
Register < Memory 1 0 0
Register = Memory 0 1 1
Register > Memory 0 0 1

Compare Memory and Accumulator: CMP

A - M

Flags: N, Z, C

Addressing Mode Opcode
a CD
a,x DD
a,y D9
# C9
zp C5
(zp,x) C1
zp,x D5
(zp),y D1

Compare Memory and Index X: CPX

X - M

Flags: N, Z, C

Addressing Mode Opcode
a EC
# E0
zp E4

Compare Memory with Index Y: CPY

Y - M

Flags: N, Z, C

Addressing Mode Opcode
a CC
# C0
zp C4

Test Bits in Memory with Accumulator: BIT

A & M

Flags: N = M7, V = M6, Z

Addressing Mode Opcode
a 2C
# 89
zp 24

Branch[edit]

Branch on Carry Clear: BCC

Branch if C = 0

Flags: none

Addressing Mode Opcode
r 90


Branch on Carry Set: BCS

Branch if C = 1

Flags: none

Addressing Mode Opcode
r B0


Branch on Result Zero: BEQ

Branch if Z = 1

Flags: none

Addressing Mode Opcode
r F0


Branch on Result Minus: BMI

Branch if N = 1

Flags: none

Addressing Mode Opcode
r 30


Branch on Result not Zero: BNE

Branch if Z = 0

Flags: none

Addressing Mode Opcode
r D0

Branch on Result Plus: BPL

Branch if N = 0

Flags: none

Addressing Mode Opcode
r 10

Branch on Overflow Clear: BVC

Branch if V = 0

Flags: none

Addressing Mode Opcode
r 50

Branch on Overflow Set: BVS

Branch if V = 1

Flags: none

Addressing Mode Opcode
r 70

Transfer[edit]

Transfer Accumulator to Index X: TAX

A -> X

Flags: N, Z

Addressing Mode Opcode
i AA

Transfer Index X to Accumulator: TXA

X -> A

Flags: N, Z

Addressing Mode Opcode
i 8A

Transfer Accumulator to Index Y: TAY

A -> Y

Flags: N, Z

Addressing Mode Opcode
i A8

Transfer Index Y to Accumulator: TYA

Y -> A

Flags: N, Z

Addressing Mode Opcode
i 98

Transfer Stack Pointer to Index X: TSX

S -> X

Flags: N, Z

Addressing Mode Opcode
i BA

Transfer Index X to Stack Pointer: TXS

X -> S

Flags: N, Z

Addressing Mode Opcode
i 9A

Stack[edit]

Push Accumulator on Stack: PHA

A -> S

Flags: none

Addressing Mode Opcode
i 48

Pull Accumulator from Stack: PLA

S -> A

Flags: N, Z

Addressing Mode Opcode
i 68

Push Processor Status on Stack: PHP

P -> S

The processor status is stored as a single byte with the following flags bits from high to low: NV-BDIZC.

Flags: none

Addressing Mode Opcode
i 08

Pull Processor Status from Stack: PLP

S -> P

Setting the processor status from the stack is the only way to clear the B (Break) flag.

Flags: all

Addressing Mode Opcode
i 28

Subroutines and Jump[edit]

Jump to New Location: JMP

Jump to new location

Flags: none

Addressing Mode Opcode
a 4C
(a) 6C

Jump to New Location Saving Return Address: JSR

Jump to Subroutine

Flags: none

Addressing Mode Opcode
a 20

Return from Subroutine: RTS

Return from Subroutine

Flags: none

Addressing Mode Opcode
i 60

Return from Interrupt: RTI

Return from Interrupt

Flags: all

Addressing Mode Opcode
i 40

Set and Clear[edit]

Set Carry Flag: SEC

1 -> C

Flags: C = 1

Addressing Mode Opcode
i 38

Set Decimal Mode: SED

1 -> D

Flags: D = 1

Addressing Mode Opcode
i F8

Set Interrupt Disable Status: SEI

1 -> I

Flags: I = 1

Addressing Mode Opcode
i 78

Clear Carry Flag: CLC

0 -> C

Flags: C = 0

Addressing Mode Opcode
i 18

Clear Decimal Mode: CLD

0 -> D

Flags: D = 0

Addressing Mode Opcode
i D8

Clear Interrupt Disable Status: CLI

0 -> I

Flags: I = 0

Addressing Mode Opcode
i 58

Clear Overflow Flag: CLV

0 -> V

Flags: V = 0

Addressing Mode Opcode
i B8

Miscellaneous[edit]

No Operation: NOP

No Operation

Flags: none

Addressing Mode Opcode
i EA

Break: BRK

Force an Interrupt

Flags: B = 1, I = 1

Addressing Mode Opcode
i 00

Further Reading[edit]