Featured image of post 6502 Assembly Language in a Nutshell

6502 Assembly Language in a Nutshell

6502 Assembly Language in a Nutshell

6502 Assembly Language in a Nutshell

The Glorious History of the 6502

Ah, the 1970s—a time of disco, bell-bottoms, and the birth of the MOS Technology 6502.
Released in 1975, this 8-bit microprocessor powered iconic systems like the Apple II, Commodore 64, Atari 2600, and even the Nintendo Entertainment System (NES).

The 6502 was revolutionary because it was cheap, simple, and fast. Compared to its competitors like the Motorola 6800 and Intel 8080, the 6502 punched above its weight. Even today, it’s beloved in retro computing, classic game emulation, and embedded systems.


6502 Architecture - What’s Inside?

The 6502 is a simple but powerful processor with the following components:

  • Registers:

    • Accumulator (A): The main register for arithmetic and logic operations.
    • Index Registers (X and Y): Used for addressing and loop counters.
    • Stack Pointer (SP): Keeps track of the call stack.
    • Program Counter (PC): Points to the next instruction.
    • Status Register (P): Holds flags that indicate operation results.
  • Memory Addressing:

    • 16-bit address bus, allowing access to 64 KB of memory.
  • Clock Speed:

    • Typically around 1 MHz, but surprisingly efficient for its time!

6502 Instruction Set

MnemonicDescription
ADCAdd with Carry
ANDLogical AND
ASLArithmetic Shift Left
BCCBranch if Carry Clear
BCSBranch if Carry Set
BEQBranch if Equal
BITBit Test
BMIBranch if Minus
BNEBranch if Not Equal
BPLBranch if Positive
BRKForce Interrupt
BVCBranch if Overflow Clear
BVSBranch if Overflow Set
CLCClear Carry Flag
CLDClear Decimal Mode
CLIClear Interrupt Disable
CLVClear Overflow Flag
CMPCompare Accumulator
CPXCompare X Register
CPYCompare Y Register
DECDecrement Memory
DEXDecrement X Register
DEYDecrement Y Register
EORExclusive OR
INCIncrement Memory
INXIncrement X Register
INYIncrement Y Register
JMPJump
JSRJump to Subroutine
LDALoad Accumulator
LDXLoad X Register
LDYLoad Y Register
LSRLogical Shift Right
NOPNo Operation
ORALogical Inclusive OR
PHAPush Accumulator
PHPPush Processor Status
PLAPull Accumulator
PLPPull Processor Status
ROLRotate Left
RORRotate Right
RTIReturn from Interrupt
RTSReturn from Subroutine
SBCSubtract with Carry
SECSet Carry Flag
SEDSet Decimal Flag
SEISet Interrupt Disable
STAStore Accumulator
STXStore X Register
STYStore Y Register
TAXTransfer Accumulator to X
TAYTransfer Accumulator to Y
TSXTransfer Stack Pointer to X
TXATransfer X to Accumulator
TXSTransfer X to Stack Pointer
TYATransfer Y to Accumulator

Example Code

1. Hello World over RS-232

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
        LDX #$00           ; Start at the beginning of the message
        LDY #$00           ; Initialize Y register for indexing

LOOP:   LDA MESSAGE,X      ; Load the next character
        BEQ DONE           ; If zero (end of string), we're done
        JSR SEND_CHAR      ; Otherwise, send the character
        INX                ; Move to the next character
        BNE LOOP           ; Repeat until end of string

DONE:   RTS                ; Return from subroutine

SEND_CHAR:
        ; Assume the character is in A
        ; Code to send A over RS-232 goes here
        RTS                ; Return from subroutine

MESSAGE:
        .BYTE "Hello, World!", $00  ; Null-terminated string

2. Bubble Sort

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
SORT:   
        LDY #$00           ; Outer loop index
OUTER_LOOP:
        LDX #$00           ; Inner loop index
        LDA #$00           ; Flag to check if swapped
        STA SWAPPED

INNER_LOOP:
        LDA ARRAY,X        ; Load current element
        CMP ARRAY+1,X      ; Compare with next element
        BCC NO_SWAP        ; If already sorted, skip swap

        ; Swap elements
        LDA ARRAY,X
        PHA
        LDA ARRAY+1,X
        STA ARRAY,X
        PLA
        STA ARRAY+1,X

        LDA #$01
        STA SWAPPED        ; Mark that we swapped

NO_SWAP:
        INX
        CPX #ARRAY_LENGTH-1
        BNE INNER_LOOP

        LDA SWAPPED
        BEQ DONE_SORTING

        INY
        CPY #ARRAY_LENGTH-1
        BNE OUTER_LOOP

DONE_SORTING:
        RTS

ARRAY:
        .BYTE 5, 3, 8, 4, 2, 7
ARRAY_LENGTH = 6
SWAPPED:
        .BYTE 0

References

Check out this uber cool 6502 Laptop!
https://www.grappendorf.net/projects/6502-home-computer/

and good video
The 6502 CPU Powered a Whole Generation!

https://www.youtube.com/watch?v=acUH4lWe2NQ